align with metadata standard
Build and Push Docker Image / build (push) Failing after 14s

This commit is contained in:
Worph
2026-09-13 15:53:27 +02:00
parent fbadf53c8e
commit 2d5bef71fd
3 changed files with 31 additions and 11 deletions
+2 -2
View File
@@ -16,8 +16,8 @@ This plugin analyzes video files to determine if they are anime content. Detecti
| Field | Description | | Field | Description |
|-------|-------------| |-------|-------------|
| `anime` | Boolean indicating if content is anime | | `anime` | Boolean indicating if content is anime |
| `titles/jpn` | Japanese title (if detected) | | `titles/jpn/{name}` | `"true"` — Japanese title (if detected) |
| `titles/rom` | Romanized title | | `titles/jpl/{name}` | `"true"` — romaji title |
| `genres` | Adds "Anime" to genres set | | `genres` | Adds "Anime" to genres set |
## Dependencies ## Dependencies
+19 -8
View File
@@ -8,8 +8,8 @@
* - "anime" in file path * - "anime" in file path
* *
* Matches old AnimeDetector output: * Matches old AnimeDetector output:
* - titles/jpn (if kana) * - titles/jpn/<name> (if kana) — key-set member, METADATA_KEYS.md §3
* - titles/{romajiIsoCode} (if romaji) * - titles/{romajiIsoCode}/<name> (if romaji)
* - anime * - anime
* - genres (add "Anime") * - genres (add "Anime")
*/ */
@@ -22,6 +22,16 @@ import { MetaCoreClient } from './meta-core-client.js';
// romajiIsoCode from @metazla/meta-interface is just 'jpl' // romajiIsoCode from @metazla/meta-interface is just 'jpl'
const romajiIsoCode = 'jpl'; const romajiIsoCode = 'jpl';
/**
* `titles/<lang3>/<name>` key-set member key (METADATA_KEYS.md §3): trimmed,
* whitespace collapsed, `/` (the key-set separator) written as U+2215 `∕`.
* `undefined` when nothing is left to name.
*/
export function titleMemberKey(lang3: string, name: string | undefined | null): string | undefined {
const clean = (name ?? '').trim().replace(/\s+/g, ' ').replace(/\//g, '\u2215');
return clean ? `titles/${lang3}/${clean}` : undefined;
}
export const manifest: PluginManifest = { export const manifest: PluginManifest = {
id: 'anime-detector', id: 'anime-detector',
name: 'Anime Detector', name: 'Anime Detector',
@@ -35,8 +45,9 @@ export const manifest: PluginManifest = {
timeout: 30000, timeout: 30000,
schema: { schema: {
anime: { label: 'Is Anime', type: 'boolean', readonly: true }, anime: { label: 'Is Anime', type: 'boolean', readonly: true },
'titles/jpn': { label: 'Japanese Title', type: 'string' }, // Key-set members `titles/<lang3>/<name> = "true"` (METADATA_KEYS.md §3).
[`titles/${romajiIsoCode}`]: { label: 'Romaji Title', type: 'string' }, 'titles/jpn/*': { label: 'Japanese Titles', type: 'boolean', readonly: true },
[`titles/${romajiIsoCode}/*`]: { label: 'Romaji Titles', type: 'boolean', readonly: true },
}, },
config: {}, config: {},
}; };
@@ -110,10 +121,10 @@ export async function process(
// Set Japanese title appropriately // Set Japanese title appropriately
if (isJpn && originalTitle) { if (isJpn && originalTitle) {
if (isKana(originalTitle)) { const lang3 = isKana(originalTitle) ? 'jpn' : romajiIsoCode;
await metaCore.setProperty(cid, 'titles/jpn', originalTitle); const key = titleMemberKey(lang3, originalTitle);
} else { if (key) {
await metaCore.setProperty(cid, `titles/${romajiIsoCode}`, originalTitle); await metaCore.mergeMetadata(cid, { [key]: 'true' });
} }
} }
+10 -1
View File
@@ -12,6 +12,7 @@ import { animeKeywords } from '@metazla/filename-tools';
// Dynamic import of plugin module // Dynamic import of plugin module
let manifest: typeof import('../src/plugin.js').manifest; let manifest: typeof import('../src/plugin.js').manifest;
let processFile: typeof import('../src/plugin.js').process; let processFile: typeof import('../src/plugin.js').process;
let titleMemberKey: typeof import('../src/plugin.js').titleMemberKey;
// Mock callback collector // Mock callback collector
interface CallbackResult { interface CallbackResult {
@@ -33,6 +34,7 @@ describe('Anime Detector Plugin Integration Tests', () => {
const plugin = await import('../src/plugin.js'); const plugin = await import('../src/plugin.js');
manifest = plugin.manifest; manifest = plugin.manifest;
processFile = plugin.process; processFile = plugin.process;
titleMemberKey = plugin.titleMemberKey;
}); });
describe('Manifest', () => { describe('Manifest', () => {
@@ -48,7 +50,14 @@ describe('Anime Detector Plugin Integration Tests', () => {
it('declares correct schema', () => { it('declares correct schema', () => {
expect(manifest.schema).toHaveProperty('anime'); expect(manifest.schema).toHaveProperty('anime');
expect(manifest.schema).toHaveProperty('titles/jpn'); expect(manifest.schema).toHaveProperty(['titles/jpn/*']);
});
it('builds titles key-set member keys', () => {
expect(titleMemberKey('jpn', ' ナルト ')).toBe('titles/jpn/ナルト');
expect(titleMemberKey('eng', 'Fate/Zero')).toBe('titles/eng/Fate\u2215Zero');
expect(titleMemberKey('jpl', 'Sousou no\tFrieren')).toBe('titles/jpl/Sousou no Frieren');
expect(titleMemberKey('jpn', ' ')).toBeUndefined();
}); });
}); });