#41 少々しやぅ修正

このコミットが含まれているのは:
2026-06-11 23:18:23 +09:00
コミット 4caea6213a
3個のファイルの変更204行の追加22行の削除
+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: '題名に英数字が混じってゐる?',