#41 少々しやぅ修正
このコミットが含まれているのは:
+90
-11
@@ -35,6 +35,7 @@ export type GekanatorQuestionCondition =
|
||||
| { type: 'original-year'; year: number }
|
||||
| { type: 'original-month'; month: number }
|
||||
| { type: 'original-month-day'; monthDay: string }
|
||||
| { type: 'title-length-at-least'; length: number }
|
||||
| { type: 'title-length-greater-than'; length: number }
|
||||
| { type: 'title-has-ascii' }
|
||||
| {
|
||||
@@ -44,6 +45,12 @@ export type GekanatorQuestionCondition =
|
||||
threshold: number
|
||||
}
|
||||
|
||||
|
||||
type NonPostSimilarityCondition = Exclude<
|
||||
GekanatorQuestionCondition,
|
||||
{ type: 'post-similarity' }
|
||||
>
|
||||
|
||||
export type GekanatorExtraQuestion = {
|
||||
id: number
|
||||
text: string
|
||||
@@ -70,10 +77,67 @@ export type GekanatorQuestion = {
|
||||
test: (post: Post) => boolean }
|
||||
|
||||
|
||||
export const normalizeTitleLengthCondition = (
|
||||
condition: GekanatorQuestionCondition,
|
||||
): GekanatorQuestionCondition => {
|
||||
switch (condition.type)
|
||||
{
|
||||
case 'title-length-greater-than':
|
||||
return {
|
||||
type: 'title-length-at-least',
|
||||
length: condition.length + 1 }
|
||||
default:
|
||||
return condition
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const titleLengthMinimumForCondition = (
|
||||
condition: GekanatorQuestionCondition,
|
||||
): number | null => {
|
||||
switch (condition.type)
|
||||
{
|
||||
case 'title-length-at-least':
|
||||
return condition.length
|
||||
case 'title-length-greater-than':
|
||||
return condition.length + 1
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const questionIdForCondition = (
|
||||
condition: NonPostSimilarityCondition,
|
||||
): string => {
|
||||
switch (condition.type)
|
||||
{
|
||||
case 'tag':
|
||||
return `tag:${ condition.key }`
|
||||
case 'source':
|
||||
return `source:${ condition.host }`
|
||||
case 'original-year':
|
||||
return `original-year:${ condition.year }`
|
||||
case 'original-month':
|
||||
return `original-month:${ condition.month }`
|
||||
case 'original-month-day':
|
||||
return `original-month-day:${ condition.monthDay }`
|
||||
case 'title-length-at-least':
|
||||
case 'title-length-greater-than':
|
||||
return `title:length-at-least:${ titleLengthMinimumForCondition (condition) }`
|
||||
case 'title-has-ascii':
|
||||
return 'title:ascii'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const directExampleAnswerFor = (
|
||||
question: StoredGekanatorQuestion,
|
||||
post: Post,
|
||||
): GekanatorAnswerValue | null => {
|
||||
if (question.kind !== 'post_similarity')
|
||||
return null
|
||||
|
||||
const direct = question.exampleAnswers?.[String (post.id) as `${ number }`]
|
||||
if (direct)
|
||||
return direct
|
||||
@@ -222,6 +286,8 @@ const questionMatches = (
|
||||
return originalMonthOf (post) === question.condition.month
|
||||
case 'original-month-day':
|
||||
return originalMonthDayOf (post) === question.condition.monthDay
|
||||
case 'title-length-at-least':
|
||||
return (post.title?.length ?? 0) >= question.condition.length
|
||||
case 'title-length-greater-than':
|
||||
return (post.title?.length ?? 0) > question.condition.length
|
||||
case 'title-has-ascii':
|
||||
@@ -250,6 +316,7 @@ export const expectedAnswerForQuestion = (
|
||||
case 'original-year':
|
||||
case 'original-month':
|
||||
case 'original-month-day':
|
||||
case 'title-length-at-least':
|
||||
case 'title-length-greater-than':
|
||||
case 'title-has-ascii':
|
||||
return questionMatches (post, question) ? 'yes' : 'no'
|
||||
@@ -261,20 +328,32 @@ export const expectedAnswerForQuestion = (
|
||||
|
||||
export const restoreGekanatorQuestion = (
|
||||
question: StoredGekanatorQuestion,
|
||||
): GekanatorQuestion => ({
|
||||
...question,
|
||||
source: question.source ?? 'default',
|
||||
priorityWeight: question.priorityWeight ?? 1,
|
||||
test: (post: Post) => questionMatches (post, question) })
|
||||
): GekanatorQuestion => {
|
||||
const normalizedCondition = normalizeTitleLengthCondition (question.condition)
|
||||
const normalizedQuestion = {
|
||||
...question,
|
||||
id: normalizedCondition.type === 'title-length-at-least'
|
||||
? `title:length-at-least:${ normalizedCondition.length }`
|
||||
: question.id,
|
||||
condition: normalizedCondition,
|
||||
source: question.source ?? 'default',
|
||||
priorityWeight: question.priorityWeight ?? 1 }
|
||||
|
||||
return {
|
||||
...normalizedQuestion,
|
||||
test: (post: Post) => questionMatches (post, normalizedQuestion) }
|
||||
}
|
||||
|
||||
|
||||
export const storeGekanatorQuestion = (
|
||||
question: GekanatorQuestion,
|
||||
): StoredGekanatorQuestion => ({
|
||||
id: question.id,
|
||||
id: question.condition.type === 'title-length-greater-than'
|
||||
? `title:length-at-least:${ question.condition.length + 1 }`
|
||||
: question.id,
|
||||
text: question.text,
|
||||
kind: question.kind,
|
||||
condition: question.condition,
|
||||
condition: normalizeTitleLengthCondition (question.condition),
|
||||
source: question.source,
|
||||
priorityWeight: question.priorityWeight,
|
||||
exampleAnswers: question.exampleAnswers })
|
||||
@@ -402,15 +481,15 @@ export const buildGekanatorQuestions = (posts: Post[]): GekanatorQuestion[] => {
|
||||
|
||||
const titleQuestions = [
|
||||
{
|
||||
id: 'title:long',
|
||||
text: '題名が長めの投稿?',
|
||||
id: `title:length-at-least:${ titleLengthMedian }`,
|
||||
text: `タイトルは ${ titleLengthMedian } 文字以上?`,
|
||||
kind: 'title' as const,
|
||||
condition: {
|
||||
type: 'title-length-greater-than' as const,
|
||||
type: 'title-length-at-least' as const,
|
||||
length: titleLengthMedian },
|
||||
source: 'default' as const,
|
||||
priorityWeight: 1,
|
||||
test: (post: Post) => (post.title?.length ?? 0) > titleLengthMedian },
|
||||
test: (post: Post) => (post.title?.length ?? 0) >= titleLengthMedian },
|
||||
{
|
||||
id: 'title:ascii',
|
||||
text: '題名に英数字が混じってゐる?',
|
||||
|
||||
新しい課題から参照
ユーザをブロックする