diff options
author | (quasar) nebula <qznebula@protonmail.com> | 2024-07-25 16:35:02 -0300 |
---|---|---|
committer | (quasar) nebula <qznebula@protonmail.com> | 2025-04-13 22:54:14 -0300 |
commit | 48dde4a388fd4c31dd5680f7535419874124e554 (patch) | |
tree | 50c0fce8ef19f3bae856e79b1dc92e257e0db4ab /src/data | |
parent | b1ff1444c47f6bd8c532e3a76eb2a5b92ed82a0e (diff) |
wip
Diffstat (limited to 'src/data')
-rw-r--r-- | src/data/composite/wiki-data/index.js | 2 | ||||
-rw-r--r-- | src/data/composite/wiki-data/processContentEntryDates.js | 181 | ||||
-rw-r--r-- | src/data/composite/wiki-data/withParsedCommentaryEntries.js | 77 | ||||
-rw-r--r-- | src/data/composite/wiki-data/withParsedLyricsEntries.js | 130 | ||||
-rw-r--r-- | src/data/composite/wiki-properties/commentary.js | 6 | ||||
-rw-r--r-- | src/data/composite/wiki-properties/index.js | 1 | ||||
-rw-r--r-- | src/data/composite/wiki-properties/lyrics.js | 36 | ||||
-rw-r--r-- | src/data/things/track.js | 3 |
8 files changed, 359 insertions, 77 deletions
diff --git a/src/data/composite/wiki-data/index.js b/src/data/composite/wiki-data/index.js index d2a60935..1d94f74b 100644 --- a/src/data/composite/wiki-data/index.js +++ b/src/data/composite/wiki-data/index.js @@ -11,6 +11,7 @@ export {default as inputNotFoundMode} from './inputNotFoundMode.js'; export {default as inputSoupyFind} from './inputSoupyFind.js'; export {default as inputSoupyReverse} from './inputSoupyReverse.js'; export {default as inputWikiData} from './inputWikiData.js'; +export {default as processContentEntryDates} from './processContentEntryDates.js'; export {default as withClonedThings} from './withClonedThings.js'; export {default as withConstitutedArtwork} from './withConstitutedArtwork.js'; export {default as withContributionListSums} from './withContributionListSums.js'; @@ -18,6 +19,7 @@ export {default as withCoverArtDate} from './withCoverArtDate.js'; export {default as withDirectory} from './withDirectory.js'; export {default as withParsedCommentaryEntries} from './withParsedCommentaryEntries.js'; export {default as withParsedContentEntries} from './withParsedContentEntries.js'; +export {default as withParsedLyricsEntries} from './withParsedLyricsEntries.js'; export {default as withRecontextualizedContributionList} from './withRecontextualizedContributionList.js'; export {default as withRedatedContributionList} from './withRedatedContributionList.js'; export {default as withResolvedAnnotatedReferenceList} from './withResolvedAnnotatedReferenceList.js'; diff --git a/src/data/composite/wiki-data/processContentEntryDates.js b/src/data/composite/wiki-data/processContentEntryDates.js new file mode 100644 index 00000000..e418a121 --- /dev/null +++ b/src/data/composite/wiki-data/processContentEntryDates.js @@ -0,0 +1,181 @@ +import {input, templateCompositeFrom} from '#composite'; +import {stitchArrays} from '#sugar'; +import {isContentString, isString, looseArrayOf} from '#validators'; + +import {fillMissingListItems} from '#composite/data'; + +// Important note: These two kinds of inputs have the exact same shape!! +// This isn't on purpose (besides that they *are* both supposed to be strings). +// They just don't have any more particular validation, yet. + +const inputDateList = defaultDependency => + input({ + validate: looseArrayOf(isString), + defaultDependency, + }); + +const inputKindList = defaultDependency => + input.staticDependency({ + validate: looseArrayOf(isString), + defaultDependency: defaultDependency, + }); + +export default templateCompositeFrom({ + annotation: `processContentEntryDates`, + + inputs: { + annotations: input({ + validate: looseArrayOf(isContentString), + defaultDependency: '#entries.annotation', + }), + + dates: inputDateList('#entries.date'), + secondDates: inputDateList('#entries.secondDate'), + accessDates: inputDateList('#entries.accessDate'), + + dateKinds: inputKindList('#entries.dateKind'), + accessKinds: inputKindList('#entries.accessKind'), + }, + + outputs: ({ + [input.staticDependency('dates')]: dates, + [input.staticDependency('secondDates')]: secondDates, + [input.staticDependency('accessDates')]: accessDates, + [input.staticDependency('dateKinds')]: dateKinds, + [input.staticDependency('accessKinds')]: accessKinds, + }) => [ + dates ?? '#processedContentEntryDates', + secondDates ?? '#processedContentEntrySecondDates', + accessDates ?? '#processedContentEntryAccessDates', + dateKinds ?? '#processedContentEntryDateKinds', + accessKinds ?? '#processedContentEntryAccessKinds', + ], + + steps: () => [ + { + dependencies: [input('annotations')], + compute: (continuation, { + [input('annotations')]: annotations, + }) => continuation({ + ['#webArchiveDates']: + annotations + .map(text => text?.match(/https?:\/\/web.archive.org\/web\/([0-9]{8,8})[0-9]*\//)) + .map(match => match?.[1]) + .map(dateText => + (dateText + ? dateText.slice(0, 4) + '/' + + dateText.slice(4, 6) + '/' + + dateText.slice(6, 8) + : null)), + }), + }, + + { + dependencies: [input('dates')], + compute: (continuation, { + [input('dates')]: dates, + }) => continuation({ + ['#processedContentEntryDates']: + dates + .map(date => date ? new Date(date) : null), + }), + }, + + { + dependencies: [input('secondDates')], + compute: (continuation, { + [input('secondDates')]: secondDates, + }) => continuation({ + ['#processedContentEntrySecondDates']: + secondDates + .map(date => date ? new Date(date) : null), + }), + }, + + fillMissingListItems({ + list: input('dateKinds'), + fill: input.value(null), + }).outputs({ + '#list': '#processedContentEntryDateKinds', + }), + + { + dependencies: [input('accessDates'), '#webArchiveDates'], + compute: (continuation, { + [input('accessDates')]: accessDates, + ['#webArchiveDates']: webArchiveDates, + }) => continuation({ + ['#processedContentEntryAccessDates']: + stitchArrays({ + accessDate: accessDates, + webArchiveDate: webArchiveDates + }).map(({accessDate, webArchiveDate}) => + accessDate ?? + webArchiveDate ?? + null) + .map(date => date ? new Date(date) : date), + }), + }, + + { + dependencies: [input('accessKinds'), '#webArchiveDates'], + compute: (continuation, { + [input('accessKinds')]: accessKinds, + ['#webArchiveDates']: webArchiveDates, + }) => continuation({ + ['#processedContentEntryAccessKinds']: + stitchArrays({ + accessKind: accessKinds, + webArchiveDate: webArchiveDates, + }).map(({accessKind, webArchiveDate}) => + accessKind ?? + (webArchiveDate && 'captured') ?? + null), + }), + }, + + // TODO: Annoying conversion step for outputs, would be nice to avoid. + { + dependencies: [ + '#processedContentEntryDates', + '#processedContentEntrySecondDates', + '#processedContentEntryAccessDates', + '#processedContentEntryDateKinds', + '#processedContentEntryAccessKinds', + input.staticDependency('dates'), + input.staticDependency('secondDates'), + input.staticDependency('accessDates'), + input.staticDependency('dateKinds'), + input.staticDependency('accessKinds'), + ], + + compute: (continuation, { + ['#processedContentEntryDates']: processedContentEntryDates, + ['#processedContentEntrySecondDates']: processedContentEntrySecondDates, + ['#processedContentEntryAccessDates']: processedContentEntryAccessDates, + ['#processedContentEntryDateKinds']: processedContentEntryDateKinds, + ['#processedContentEntryAccessKinds']: processedContentEntryAccessKinds, + [input.staticDependency('dates')]: dates, + [input.staticDependency('secondDates')]: secondDates, + [input.staticDependency('accessDates')]: accessDates, + [input.staticDependency('dateKinds')]: dateKinds, + [input.staticDependency('accessKinds')]: accessKinds, + }) => continuation({ + [dates ?? '#processedContentEntryDates']: + processedContentEntryDates, + + [secondDates ?? '#processedContentEntrySecondDates']: + processedContentEntrySecondDates, + + [accessDates ?? '#processedContentEntryAccessDates']: + processedContentEntryAccessDates, + + [dateKinds ?? '#processedContentEntryDateKinds']: + processedContentEntryDateKinds, + + [accessKinds ?? '#processedContentEntryAccessKinds']: + processedContentEntryAccessKinds, + }), + }, + ], +}); diff --git a/src/data/composite/wiki-data/withParsedCommentaryEntries.js b/src/data/composite/wiki-data/withParsedCommentaryEntries.js index 885ea28d..6794c479 100644 --- a/src/data/composite/wiki-data/withParsedCommentaryEntries.js +++ b/src/data/composite/wiki-data/withParsedCommentaryEntries.js @@ -11,6 +11,7 @@ import { } from '#composite/data'; import inputSoupyFind from './inputSoupyFind.js'; +import processContentEntryDates from './processContentEntryDates.js'; import withParsedContentEntries from './withParsedContentEntries.js'; import withResolvedReferenceList from './withResolvedReferenceList.js'; @@ -84,81 +85,7 @@ export default templateCompositeFrom({ fill: input.value(null), }), - { - dependencies: ['#entries.annotation'], - compute: (continuation, { - ['#entries.annotation']: annotation, - }) => continuation({ - ['#entries.webArchiveDate']: - annotation - .map(text => text?.match(/https?:\/\/web.archive.org\/web\/([0-9]{8,8})[0-9]*\//)) - .map(match => match?.[1]) - .map(dateText => - (dateText - ? dateText.slice(0, 4) + '/' + - dateText.slice(4, 6) + '/' + - dateText.slice(6, 8) - : null)), - }), - }, - - { - dependencies: ['#entries.date'], - compute: (continuation, { - ['#entries.date']: date, - }) => continuation({ - ['#entries.date']: - date - .map(date => date ? new Date(date) : null), - }), - }, - - { - dependencies: ['#entries.secondDate'], - compute: (continuation, { - ['#entries.secondDate']: secondDate, - }) => continuation({ - ['#entries.secondDate']: - secondDate - .map(date => date ? new Date(date) : null), - }), - }, - - fillMissingListItems({ - list: '#entries.dateKind', - fill: input.value(null), - }), - - { - dependencies: ['#entries.accessDate', '#entries.webArchiveDate'], - compute: (continuation, { - ['#entries.accessDate']: accessDate, - ['#entries.webArchiveDate']: webArchiveDate, - }) => continuation({ - ['#entries.accessDate']: - stitchArrays({accessDate, webArchiveDate}) - .map(({accessDate, webArchiveDate}) => - accessDate ?? - webArchiveDate ?? - null) - .map(date => date ? new Date(date) : date), - }), - }, - - { - dependencies: ['#entries.accessKind', '#entries.webArchiveDate'], - compute: (continuation, { - ['#entries.accessKind']: accessKind, - ['#entries.webArchiveDate']: webArchiveDate, - }) => continuation({ - ['#entries.accessKind']: - stitchArrays({accessKind, webArchiveDate}) - .map(({accessKind, webArchiveDate}) => - accessKind ?? - (webArchiveDate && 'captured') ?? - null), - }), - }, + processContentEntryDates(), { dependencies: [ diff --git a/src/data/composite/wiki-data/withParsedLyricsEntries.js b/src/data/composite/wiki-data/withParsedLyricsEntries.js new file mode 100644 index 00000000..28e4c9b5 --- /dev/null +++ b/src/data/composite/wiki-data/withParsedLyricsEntries.js @@ -0,0 +1,130 @@ +import {input, templateCompositeFrom} from '#composite'; +import find from '#find'; +import {stitchArrays} from '#sugar'; +import {isLyrics} from '#validators'; +import {commentaryRegexCaseSensitive} from '#wiki-data'; + +import { + fillMissingListItems, + withFlattenedList, + withPropertiesFromList, + withUnflattenedList, +} from '#composite/data'; + +import processContentEntryDates from './processContentEntryDates.js'; +import withParsedContentEntries from './withParsedContentEntries.js'; +import withResolvedReferenceList from './withResolvedReferenceList.js'; + +export default templateCompositeFrom({ + annotation: `withParsedLyricsEntries`, + + inputs: { + from: input({validate: isLyrics}), + }, + + outputs: ['#parsedLyricsEntries'], + + steps: () => [ + withParsedContentEntries({ + from: input('from'), + caseSensitiveRegex: input.value(commentaryRegexCaseSensitive), + }), + + withPropertiesFromList({ + list: '#parsedContentEntryHeadings', + prefix: input.value('#entries'), + properties: input.value([ + 'artistReferences', + 'artistDisplayText', + 'annotation', + 'date', + 'secondDate', + 'dateKind', + 'accessDate', + 'accessKind', + ]), + }), + + // The artistReferences group will always have a value, since it's required + // for the line to match in the first place. + + { + dependencies: ['#entries.artistReferences'], + compute: (continuation, { + ['#entries.artistReferences']: artistReferenceTexts, + }) => continuation({ + ['#entries.artistReferences']: + artistReferenceTexts + .map(text => text.split(',').map(ref => ref.trim())), + }), + }, + + withFlattenedList({ + list: '#entries.artistReferences', + }), + + withResolvedReferenceList({ + list: '#flattenedList', + data: 'artistData', + find: input.value(find.artist), + notFoundMode: input.value('null'), + }), + + withUnflattenedList({ + list: '#resolvedReferenceList', + }).outputs({ + '#unflattenedList': '#entries.artists', + }), + + fillMissingListItems({ + list: '#entries.artistDisplayText', + fill: input.value(null), + }), + + fillMissingListItems({ + list: '#entries.annotation', + fill: input.value(null), + }), + + processContentEntryDates(), + + { + dependencies: [ + '#entries.artists', + '#entries.artistDisplayText', + '#entries.annotation', + '#entries.date', + '#entries.secondDate', + '#entries.dateKind', + '#entries.accessDate', + '#entries.accessKind', + '#parsedContentEntryBodies', + ], + + compute: (continuation, { + ['#entries.artists']: artists, + ['#entries.artistDisplayText']: artistDisplayText, + ['#entries.annotation']: annotation, + ['#entries.date']: date, + ['#entries.secondDate']: secondDate, + ['#entries.dateKind']: dateKind, + ['#entries.accessDate']: accessDate, + ['#entries.accessKind']: accessKind, + ['#parsedContentEntryBodies']: body, + }) => continuation({ + ['#parsedLyricsEntries']: + stitchArrays({ + artists, + artistDisplayText, + annotation, + date, + secondDate, + dateKind, + accessDate, + accessKind, + body, + }), + }), + }, + ], +}); diff --git a/src/data/composite/wiki-properties/commentary.js b/src/data/composite/wiki-properties/commentary.js index 9625278d..928bbd1b 100644 --- a/src/data/composite/wiki-properties/commentary.js +++ b/src/data/composite/wiki-properties/commentary.js @@ -12,9 +12,13 @@ export default templateCompositeFrom({ compose: false, + update: { + validate: isCommentary, + }, + steps: () => [ exitWithoutDependency({ - dependency: input.updateValue({validate: isCommentary}), + dependency: input.updateValue(), mode: input.value('falsy'), value: input.value([]), }), diff --git a/src/data/composite/wiki-properties/index.js b/src/data/composite/wiki-properties/index.js index 06a627ec..892fc44a 100644 --- a/src/data/composite/wiki-properties/index.js +++ b/src/data/composite/wiki-properties/index.js @@ -20,6 +20,7 @@ export {default as duration} from './duration.js'; export {default as externalFunction} from './externalFunction.js'; export {default as fileExtension} from './fileExtension.js'; export {default as flag} from './flag.js'; +export {default as lyrics} from './lyrics.js'; export {default as name} from './name.js'; export {default as referenceList} from './referenceList.js'; export {default as referencedArtworkList} from './referencedArtworkList.js'; diff --git a/src/data/composite/wiki-properties/lyrics.js b/src/data/composite/wiki-properties/lyrics.js new file mode 100644 index 00000000..eb5e524a --- /dev/null +++ b/src/data/composite/wiki-properties/lyrics.js @@ -0,0 +1,36 @@ +// Lyrics! This comes in two styles - "old", where there's just one set of +// lyrics, or the newer/standard one, with multiple sets that are each +// annotated, credited, etc. + +import {input, templateCompositeFrom} from '#composite'; +import {isLyrics} from '#validators'; + +import {exitWithoutDependency, exposeDependency} + from '#composite/control-flow'; +import {withParsedLyricsEntries} from '#composite/wiki-data'; + +export default templateCompositeFrom({ + annotation: `lyrics`, + + compose: false, + + update: { + validate: isLyrics, + }, + + steps: () => [ + exitWithoutDependency({ + dependency: input.updateValue(), + mode: input.value('falsy'), + value: input.value([]), + }), + + withParsedLyricsEntries({ + from: input.updateValue(), + }), + + exposeDependency({ + dependency: '#parsedLyricsEntries', + }), + ], +}); diff --git a/src/data/things/track.js b/src/data/things/track.js index ca1d69af..bcf84aa8 100644 --- a/src/data/things/track.js +++ b/src/data/things/track.js @@ -46,6 +46,7 @@ import { directory, duration, flag, + lyrics, name, referenceList, referencedArtworkList, @@ -220,7 +221,7 @@ export class Track extends Thing { lyrics: [ inheritFromMainRelease(), - contentString(), + lyrics(), ], additionalFiles: additionalFiles(), |