refactor: Smarter contentMap checking

This commit is contained in:
Essem 2024-02-05 20:47:15 -06:00
parent 212aaab5b7
commit f1be178b52
No known key found for this signature in database
GPG key ID: 7D497397CC3A2A8C
3 changed files with 66 additions and 54 deletions

View file

@ -451,12 +451,15 @@ export class ApRendererService {
_misskey_content: text, _misskey_content: text,
source: { source: {
content: text, content: text,
contentMap: note.lang ? {
[note.lang]: text,
} : undefined,
mediaType: 'text/x.misskeymarkdown', mediaType: 'text/x.misskeymarkdown',
}, },
}), }),
contentMap: note.lang ? { contentMap: note.lang ? {
[note.lang]: content, [note.lang]: content,
} : null, } : undefined,
_misskey_quote: quote, _misskey_quote: quote,
quoteUrl: quote, quoteUrl: quote,
quoteUri: quote, quoteUri: quote,
@ -746,12 +749,15 @@ export class ApRendererService {
_misskey_content: text, _misskey_content: text,
source: { source: {
content: text, content: text,
contentMap: note.lang ? {
[note.lang]: text,
} : undefined,
mediaType: 'text/x.misskeymarkdown', mediaType: 'text/x.misskeymarkdown',
}, },
}), }),
contentMap: note.lang ? { contentMap: note.lang ? {
[note.lang]: content, [note.lang]: content,
} : null, } : undefined,
_misskey_quote: quote, _misskey_quote: quote,
quoteUrl: quote, quoteUrl: quote,
quoteUri: quote, quoteUri: quote,

View file

@ -26,6 +26,7 @@ import { UtilityService } from '@/core/UtilityService.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { checkHttps } from '@/misc/check-https.js'; import { checkHttps } from '@/misc/check-https.js';
import { langs } from '@/misc/langmap.js'; import { langs } from '@/misc/langmap.js';
import { isNotNull } from '@/misc/is-not-null.js';
import { getOneApId, getApId, getOneApHrefNullable, validPost, isEmoji, getApType } from '../type.js'; import { getOneApId, getApId, getOneApHrefNullable, validPost, isEmoji, getApType } from '../type.js';
import { ApLoggerService } from '../ApLoggerService.js'; import { ApLoggerService } from '../ApLoggerService.js';
import { ApMfmService } from '../ApMfmService.js'; import { ApMfmService } from '../ApMfmService.js';
@ -38,8 +39,7 @@ import { ApMentionService } from './ApMentionService.js';
import { ApQuestionService } from './ApQuestionService.js'; import { ApQuestionService } from './ApQuestionService.js';
import { ApImageService } from './ApImageService.js'; import { ApImageService } from './ApImageService.js';
import type { Resolver } from '../ApResolverService.js'; import type { Resolver } from '../ApResolverService.js';
import type { IObject, IPost } from '../type.js'; import type { IObject, IPost, Obj } from '../type.js';
import { isNotNull } from '@/misc/is-not-null.js';
@Injectable() @Injectable()
export class ApNoteService { export class ApNoteService {
@ -241,35 +241,19 @@ export class ApNoteService {
const cw = note.summary === '' ? null : note.summary; const cw = note.summary === '' ? null : note.summary;
let lang: string | null = null;
if (note.contentMap != null) {
for (const preferredLang of this.config.langPref) {
if (note.contentMap[preferredLang]) {
lang = preferredLang;
break;
}
}
if (!lang) lang = Object.keys(note.contentMap)[0];
if (!langs.includes(lang)) lang = null;
}
// テキストのパース // テキストのパース
let text: string | null = null; let text: string | null = null;
if (note.source?.mediaType === 'text/x.misskeymarkdown' && typeof note.source.content === 'string') { let lang: string | null = null;
text = note.source.content; if (note.source?.mediaType === 'text/x.misskeymarkdown' && (typeof note.source.content === 'string' || note.source.contentMap)) {
} else if (note.contentMap != null && Object.keys(note.contentMap).length !== 0) { const guessed = this.guessLang(note.source);
let content: string; text = guessed.text;
if (lang) { lang = guessed.lang;
content = note.contentMap[lang];
} else {
content = Object.values(note.contentMap)[0];
}
text = this.apMfmService.htmlToMfm(content, note.tag);
} else if (typeof note._misskey_content !== 'undefined') { } else if (typeof note._misskey_content !== 'undefined') {
text = note._misskey_content; text = note._misskey_content;
} else if (typeof note.content === 'string') { } else if (typeof note.content === 'string' || note.contentMap) {
text = this.apMfmService.htmlToMfm(note.content, note.tag); const guessed = this.guessLang(note);
lang = guessed.lang;
if (guessed.text) text = this.apMfmService.htmlToMfm(guessed.text, note.tag);
} }
// vote // vote
@ -471,35 +455,19 @@ export class ApNoteService {
const cw = note.summary === '' ? null : note.summary; const cw = note.summary === '' ? null : note.summary;
let lang: string | null = null;
if (note.contentMap != null) {
for (const preferredLang of this.config.langPref) {
if (note.contentMap[preferredLang]) {
lang = preferredLang;
break;
}
}
if (!lang) lang = Object.keys(note.contentMap)[0];
if (!langs.includes(lang)) lang = null;
}
// テキストのパース // テキストのパース
let text: string | null = null; let text: string | null = null;
if (note.source?.mediaType === 'text/x.misskeymarkdown' && typeof note.source.content === 'string') { let lang: string | null = null;
text = note.source.content; if (note.source?.mediaType === 'text/x.misskeymarkdown' && (typeof note.source.content === 'string' || note.source.contentMap)) {
} else if (note.contentMap != null && Object.keys(note.contentMap).length !== 0) { const guessed = this.guessLang(note.source);
let content: string; text = guessed.text;
if (lang) { lang = guessed.lang;
content = note.contentMap[lang];
} else {
content = Object.values(note.contentMap)[0];
}
text = this.apMfmService.htmlToMfm(content, note.tag);
} else if (typeof note._misskey_content !== 'undefined') { } else if (typeof note._misskey_content !== 'undefined') {
text = note._misskey_content; text = note._misskey_content;
} else if (typeof note.content === 'string') { } else if (typeof note.content === 'string' || note.contentMap) {
text = this.apMfmService.htmlToMfm(note.content, note.tag); const guessed = this.guessLang(note);
lang = guessed.lang;
if (guessed.text) text = this.apMfmService.htmlToMfm(guessed.text, note.tag);
} }
// vote // vote
@ -660,4 +628,40 @@ export class ApNoteService {
}).then(x => this.emojisRepository.findOneByOrFail(x.identifiers[0])); }).then(x => this.emojisRepository.findOneByOrFail(x.identifiers[0]));
})); }));
} }
@bindThis
private guessLang(source: { contentMap?: Obj | null, content?: string | null }): { lang: string | null, text: string | null } {
// do we have a map?
if (source.contentMap) {
const entries = Object.entries(source.contentMap);
// only one entry: take that
if (entries.length === 1) {
return { lang: entries[0][0], text: entries[0][1] };
}
// did the sender indicate a preferred language?
if (source.content) {
for (const e of entries) {
if (e[1] === source.content) {
return { lang: e[0], text: e[1] };
}
}
}
// can we find one of *our* preferred languages?
for (const prefLang of this.config.langPref) {
if (source.contentMap[prefLang]) {
return { lang: prefLang, text: source.contentMap[prefLang] };
}
}
// bah, just pick one
return { lang: entries[0][0], text: entries[0][1] };
}
// no map, so we don't know the language, just take whatever
// content we got
return { lang: null, text: source.content ?? null };
}
} }

View file

@ -115,6 +115,7 @@ export interface IPost extends IObject {
type: 'Note' | 'Question' | 'Article' | 'Audio' | 'Document' | 'Image' | 'Page' | 'Video' | 'Event'; type: 'Note' | 'Question' | 'Article' | 'Audio' | 'Document' | 'Image' | 'Page' | 'Video' | 'Event';
source?: { source?: {
content: string; content: string;
contentMap?: Obj | null;
mediaType: string; mediaType: string;
}; };
_misskey_quote?: string; _misskey_quote?: string;
@ -129,6 +130,7 @@ export interface IQuestion extends IObject {
actor: string; actor: string;
source?: { source?: {
content: string; content: string;
contentMap?: Obj | null;
mediaType: string; mediaType: string;
}; };
_misskey_quote?: string; _misskey_quote?: string;