Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
316db6ad03 | ||
|
|
c82a931a8c |
+22
-3
@@ -477,9 +477,21 @@ export function videoSubtitleKeys(produced: ProducedSubtitle[]): Record<string,
|
|||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Keys on the subtitle file's own record. */
|
/**
|
||||||
|
* Keys on the subtitle file's own record.
|
||||||
|
*
|
||||||
|
* `source/extract` (METADATA_KEYS.md §5) says the bytes came out of a video
|
||||||
|
* container. The video record already implies it through `extractedSubtitles/`,
|
||||||
|
* but that is the wrong side of the relation to store it on: a subtitle fetched
|
||||||
|
* over the swarm by CID arrives WITHOUT its video record, so a reader holding
|
||||||
|
* only the file would have no way to tell an extracted track from a sidecar
|
||||||
|
* someone dropped next to the video.
|
||||||
|
*/
|
||||||
export function subtitleRecordKeys(videoCid: string, lang3: string): Record<string, string> {
|
export function subtitleRecordKeys(videoCid: string, lang3: string): Record<string, string> {
|
||||||
const keys: Record<string, string> = { [`videos/${videoCid}`]: 'true' };
|
const keys: Record<string, string> = {
|
||||||
|
[`videos/${videoCid}`]: 'true',
|
||||||
|
'source/extract': 'true',
|
||||||
|
};
|
||||||
if (lang3 !== 'und') keys.subtitleLanguage = lang3;
|
if (lang3 !== 'und') keys.subtitleLanguage = lang3;
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
@@ -499,7 +511,14 @@ export function legacySubtitleMigration(existingMeta: Record<string, unknown> |
|
|||||||
const langs = legacyCsvMembers(existingMeta, 'subtitleLanguages');
|
const langs = legacyCsvMembers(existingMeta, 'subtitleLanguages');
|
||||||
if (langs) {
|
if (langs) {
|
||||||
deletes.push('subtitleLanguages');
|
deletes.push('subtitleLanguages');
|
||||||
for (const l of langs.map(toLang3)) if (l !== 'und') sets[`subtitleLanguages/${l}`] = 'true';
|
for (const l of langs.map(toLang3)) {
|
||||||
|
if (l === 'und') continue;
|
||||||
|
sets[`subtitleLanguages/${l}`] = 'true';
|
||||||
|
// …and the union (§9 rule #7). The live write path below already
|
||||||
|
// does this; the migration path did not, so records that only ever
|
||||||
|
// went through it were left half-written.
|
||||||
|
sets[`languages/${l}`] = 'true';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const subs = legacyCsvMembers(existingMeta, 'subtitles');
|
const subs = legacyCsvMembers(existingMeta, 'subtitles');
|
||||||
|
|||||||
+28
-6
@@ -284,9 +284,16 @@ describe('record keys (METADATA_KEYS.md §8)', () => {
|
|||||||
expect(keys.every((k) => k.split('/').length === 3)).toBe(true);
|
expect(keys.every((k) => k.split('/').length === 3)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('subtitle record carries the back-pointer and a determined language only', () => {
|
it('subtitle record carries the back-pointer, its origin, and a determined language only', () => {
|
||||||
expect(subtitleRecordKeys('bagvideo', 'fre')).toEqual({ 'videos/bagvideo': 'true', subtitleLanguage: 'fre' });
|
expect(subtitleRecordKeys('bagvideo', 'fre')).toEqual({
|
||||||
expect(subtitleRecordKeys('bagvideo', 'und')).toEqual({ 'videos/bagvideo': 'true' });
|
'videos/bagvideo': 'true',
|
||||||
|
'source/extract': 'true',
|
||||||
|
subtitleLanguage: 'fre',
|
||||||
|
});
|
||||||
|
expect(subtitleRecordKeys('bagvideo', 'und')).toEqual({
|
||||||
|
'videos/bagvideo': 'true',
|
||||||
|
'source/extract': 'true',
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -310,7 +317,13 @@ describe('legacySubtitleMigration', () => {
|
|||||||
subtitles: 'cidS',
|
subtitles: 'cidS',
|
||||||
})).toEqual({
|
})).toEqual({
|
||||||
deletes: ['extractedSubtitles', 'subtitleLanguages', 'subtitles'],
|
deletes: ['extractedSubtitles', 'subtitleLanguages', 'subtitles'],
|
||||||
sets: { 'subtitleLanguages/eng': 'true', 'subtitleLanguages/fre': 'true', 'subtitles/und/cidS': 'true' },
|
sets: {
|
||||||
|
'subtitleLanguages/eng': 'true',
|
||||||
|
'languages/eng': 'true',
|
||||||
|
'subtitleLanguages/fre': 'true',
|
||||||
|
'languages/fre': 'true',
|
||||||
|
'subtitles/und/cidS': 'true',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -495,8 +508,17 @@ describe.skipIf(!ffmpegReady)('process — end to end against a fake core', () =
|
|||||||
expect(video.subtitleLanguages).toBeUndefined();
|
expect(video.subtitleLanguages).toBeUndefined();
|
||||||
expect(video['subtitleLanguages/und']).toBeUndefined();
|
expect(video['subtitleLanguages/und']).toBeUndefined();
|
||||||
|
|
||||||
expect(core.records.get(fre)).toEqual({ [`videos/${VIDEO_CID}`]: 'true', subtitleLanguage: 'fre' });
|
// `source/extract` rides on the subtitle's OWN record, so a peer that
|
||||||
expect(core.records.get(und)).toEqual({ [`videos/${VIDEO_CID}`]: 'true' });
|
// fetched only the file can still tell it came out of a container.
|
||||||
|
expect(core.records.get(fre)).toEqual({
|
||||||
|
[`videos/${VIDEO_CID}`]: 'true',
|
||||||
|
'source/extract': 'true',
|
||||||
|
subtitleLanguage: 'fre',
|
||||||
|
});
|
||||||
|
expect(core.records.get(und)).toEqual({
|
||||||
|
[`videos/${VIDEO_CID}`]: 'true',
|
||||||
|
'source/extract': 'true',
|
||||||
|
});
|
||||||
|
|
||||||
// The video PATCH carried only new keys — nothing the record already had.
|
// The video PATCH carried only new keys — nothing the record already had.
|
||||||
const patch = writesTo(core, VIDEO_CID).find((c) => c.method === 'PATCH')!;
|
const patch = writesTo(core, VIDEO_CID).find((c) => c.method === 'PATCH')!;
|
||||||
|
|||||||
Reference in New Issue
Block a user