diff options
Diffstat (limited to 'src/data/things')
-rw-r--r-- | src/data/things/album.js | 73 | ||||
-rw-r--r-- | src/data/things/art-tag.js | 21 | ||||
-rw-r--r-- | src/data/things/artwork.js | 51 | ||||
-rw-r--r-- | src/data/things/content.js | 122 | ||||
-rw-r--r-- | src/data/things/flash.js | 40 | ||||
-rw-r--r-- | src/data/things/index.js | 2 | ||||
-rw-r--r-- | src/data/things/track.js | 44 |
7 files changed, 306 insertions, 47 deletions
diff --git a/src/data/things/album.js b/src/data/things/album.js index 7c85366a..8a25a8ac 100644 --- a/src/data/things/album.js +++ b/src/data/things/album.js @@ -3,6 +3,7 @@ export const DATA_ALBUM_DIRECTORY = 'album'; import * as path from 'node:path'; import {inspect} from 'node:util'; +import CacheableObject from '#cacheable-object'; import {colors} from '#cli'; import {input} from '#composite'; import {traverse} from '#node-utils'; @@ -16,7 +17,9 @@ import { parseAdditionalNames, parseAnnotatedReferences, parseArtwork, + parseCommentary, parseContributors, + parseCreditingSources, parseDate, parseDimensions, parseWallpaperParts, @@ -32,7 +35,6 @@ import {exitWithoutContribs, withDirectory, withCoverArtDate} import { additionalFiles, additionalNameList, - commentary, color, commentatorArtists, constitutibleArtwork, @@ -59,7 +61,7 @@ import { wikiData, } from '#composite/wiki-properties'; -import {withTracks} from '#composite/things/album'; +import {withHasCoverArt, withTracks} from '#composite/things/album'; import {withAlbum, withContinueCountingFrom, withStartCountingFrom} from '#composite/things/track-section'; @@ -69,6 +71,8 @@ export class Album extends Thing { static [Thing.getPropertyDescriptors] = ({ ArtTag, Artwork, + CommentaryEntry, + CreditingSourcesEntry, Group, Track, TrackSection, @@ -188,9 +192,11 @@ export class Album extends Thing { ], coverArtworks: [ + withHasCoverArt(), + exitWithoutDependency({ - dependency: 'coverArtistContribs', - mode: input.value('empty'), + dependency: '#hasCoverArt', + mode: input.value('falsy'), value: input.value([]), }), @@ -202,8 +208,14 @@ export class Album extends Thing { isListedOnHomepage: flag(true), isListedInGalleries: flag(true), - commentary: commentary(), - creditSources: commentary(), + commentary: thingList({ + class: input.value(CommentaryEntry), + }), + + creditSources: thingList({ + class: input.value(CreditingSourcesEntry), + }), + additionalFiles: additionalFiles(), trackSections: thingList({ @@ -297,7 +309,11 @@ export class Album extends Thing { commentatorArtists: commentatorArtists(), - hasCoverArt: contribsPresent({contribs: 'coverArtistContribs'}), + hasCoverArt: [ + withHasCoverArt(), + exposeDependency({dependency: '#hasCoverArt'}), + ], + hasWallpaperArt: contribsPresent({contribs: 'wallpaperArtistContribs'}), hasBannerArt: contribsPresent({contribs: 'bannerArtistContribs'}), @@ -505,6 +521,8 @@ export class Album extends Thing { dateFromThingProperty: 'coverArtDate', artistContribsFromThingProperty: 'coverArtistContribs', artistContribsArtistProperty: 'albumCoverArtistContributions', + artTagsFromThingProperty: 'artTags', + referencedArtworksFromThingProperty: 'referencedArtworks', }), }, @@ -588,8 +606,15 @@ export class Album extends Thing { transform: parseDimensions, }, - 'Commentary': {property: 'commentary'}, - 'Credit Sources': {property: 'creditSources'}, + 'Commentary': { + property: 'commentary', + transform: parseCommentary, + }, + + 'Credit Sources': { + property: 'creditSources', + transform: parseCreditingSources, + }, 'Additional Files': { property: 'additionalFiles', @@ -660,7 +685,11 @@ export class Album extends Thing { const albumData = []; const trackSectionData = []; const trackData = []; + const artworkData = []; + const commentaryData = []; + const creditingSourceData = []; + const lyricsData = []; for (const {header: album, entries} of results) { const trackSections = []; @@ -707,6 +736,13 @@ export class Album extends Thing { entry.album = album; artworkData.push(...entry.trackArtworks); + commentaryData.push(...entry.commentary); + creditingSourceData.push(...entry.creditSources); + + // TODO: As exposed, Track.lyrics tries to inherit from the main + // release, which is impossible before the data's been linked. + // We just use the update value here. But it's icky! + lyricsData.push(...CacheableObject.getUpdateValue(entry, 'lyrics') ?? []); } closeCurrentTrackSection(); @@ -723,6 +759,9 @@ export class Album extends Thing { artworkData.push(album.wallpaperArtwork); } + commentaryData.push(...album.commentary); + creditingSourceData.push(...album.creditSources); + album.trackSections = trackSections; } @@ -730,7 +769,11 @@ export class Album extends Thing { albumData, trackSectionData, trackData, + artworkData, + commentaryData, + creditingSourceData, + lyricsData, }; }, @@ -761,12 +804,18 @@ export class Album extends Thing { ]; } + // TODO: using trackCover here is obviously, badly wrong + // but we ought to refactor banners and wallpapers similarly + // (i.e. depend on those intrinsic artwork paths rather than + // accessing media.{albumBanner,albumWallpaper} from content + // or other code directly) return [ - 'media.albumCover', + 'media.trackCover', + this.directory, (artwork.unqualifiedDirectory - ? this.directory + '-' + artwork.unqualifiedDirectory - : this.directory), + ? 'cover-' + artwork.unqualifiedDirectory + : 'cover'), artwork.fileExtension, ]; diff --git a/src/data/things/art-tag.js b/src/data/things/art-tag.js index 7944beb0..57e156ee 100644 --- a/src/data/things/art-tag.js +++ b/src/data/things/art-tag.js @@ -92,22 +92,11 @@ export class ArtTag extends Thing { }, ], - directlyTaggedInThings: { - flags: {expose: true}, - - expose: { - dependencies: ['this', 'reverse'], - compute: ({this: artTag, reverse}) => - sortAlbumsTracksChronologically( - [ - ...reverse.albumsWhoseArtworksFeature(artTag), - ...reverse.tracksWhoseArtworksFeature(artTag), - ], - {getDate: thing => thing.coverArtDate}), - }, - }, + directlyFeaturedInArtworks: reverseReferenceList({ + reverse: soupyReverse.input('artworksWhichFeature'), + }), - indirectlyTaggedInThings: [ + indirectlyFeaturedInArtworks: [ withAllDescendantArtTags(), { @@ -115,7 +104,7 @@ export class ArtTag extends Thing { compute: ({'#allDescendantArtTags': allDescendantArtTags}) => unique( allDescendantArtTags - .flatMap(artTag => artTag.directlyTaggedInThings)), + .flatMap(artTag => artTag.directlyFeaturedInArtworks)), }, ], diff --git a/src/data/things/artwork.js b/src/data/things/artwork.js index 65032d86..2a97fd6d 100644 --- a/src/data/things/artwork.js +++ b/src/data/things/artwork.js @@ -3,7 +3,6 @@ import {inspect} from 'node:util'; import {input} from '#composite'; import find from '#find'; import Thing from '#thing'; -import {parseAnnotatedReferences, parseContributors, parseDate} from '#yaml'; import { isContentString, @@ -18,6 +17,13 @@ import { validateReferenceList, } from '#validators'; +import { + parseAnnotatedReferences, + parseContributors, + parseDate, + parseDimensions, +} from '#yaml'; + import {withPropertyFromObject} from '#composite/data'; import { @@ -132,6 +138,11 @@ export class Artwork extends Thing { ['#value']: '#dimensionsFromThing', }), + exitWithoutDependency({ + dependency: 'dimensionsFromThingProperty', + value: input.value(null), + }), + exposeDependencyOrContinue({ dependency: '#dimensionsFromThing', }), @@ -179,6 +190,8 @@ export class Artwork extends Thing { }), ], + artTagsFromThingProperty: simpleString(), + artTags: [ withResolvedReferenceList({ list: input.updateValue({ @@ -194,13 +207,20 @@ export class Artwork extends Thing { mode: input.value('empty'), }), + exitWithoutDependency({ + dependency: 'artTagsFromThingProperty', + value: input.value([]), + }), + withPropertyFromObject({ object: 'thing', - property: input.value('artTags'), + property: 'artTagsFromThingProperty', + }).outputs({ + ['#value']: '#artTags', }), exposeDependencyOrContinue({ - dependency: '#thing.artTags', + dependency: '#artTags', }), exposeConstant({ @@ -208,6 +228,8 @@ export class Artwork extends Thing { }), ], + referencedArtworksFromThingProperty: simpleString(), + referencedArtworks: [ { compute: (continuation) => continuation({ @@ -244,13 +266,20 @@ export class Artwork extends Thing { mode: input.value('empty'), }), + exitWithoutDependency({ + dependency: 'referencedArtworksFromThingProperty', + value: input.value([]), + }), + withPropertyFromObject({ object: 'thing', - property: input.value('referencedArtworks'), + property: 'referencedArtworksFromThingProperty', + }).outputs({ + ['#value']: '#referencedArtworks', }), exposeDependencyOrContinue({ - dependency: '#thing.referencedArtworks', + dependency: '#referencedArtworks', }), exposeConstant({ @@ -280,6 +309,11 @@ export class Artwork extends Thing { 'Directory': {property: 'unqualifiedDirectory'}, 'File Extension': {property: 'fileExtension'}, + 'Dimensions': { + property: 'dimensions', + transform: parseDimensions, + }, + 'Label': {property: 'label'}, 'Source': {property: 'source'}, @@ -323,6 +357,13 @@ export class Artwork extends Thing { date: ({artwork}) => artwork.date, }, + + artworksWhichFeature: { + bindTo: 'artworkData', + + referencing: artwork => [artwork], + referenced: artwork => artwork.artTags, + }, }; get path() { diff --git a/src/data/things/content.js b/src/data/things/content.js new file mode 100644 index 00000000..7f352795 --- /dev/null +++ b/src/data/things/content.js @@ -0,0 +1,122 @@ +import {input} from '#composite'; +import find from '#find'; +import Thing from '#thing'; +import {is, isDate} from '#validators'; +import {parseDate} from '#yaml'; + +import {contentString, referenceList, simpleDate, soupyFind, thing} + from '#composite/wiki-properties'; + +import { + exposeConstant, + exposeDependencyOrContinue, + exposeUpdateValueOrContinue, + withResultOfAvailabilityCheck, +} from '#composite/control-flow'; + +import {withWebArchiveDate} from '#composite/things/commentary-entry'; + +export class ContentEntry extends Thing { + static [Thing.getPropertyDescriptors] = ({Artist}) => ({ + // Update & expose + + thing: thing(), + + artists: referenceList({ + class: input.value(Artist), + find: soupyFind.input('artist'), + }), + + artistText: contentString(), + + annotation: contentString(), + + dateKind: { + flags: {update: true, expose: true}, + + update: { + validate: is(...[ + 'sometime', + 'throughout', + 'around', + ]), + }, + }, + + accessKind: [ + exposeUpdateValueOrContinue({ + validate: input.value( + is(...[ + 'captured', + 'accessed', + ])), + }), + + withWebArchiveDate(), + + withResultOfAvailabilityCheck({ + from: '#webArchiveDate', + }), + + { + dependencies: ['#availability'], + compute: (continuation, {['#availability']: availability}) => + (availability + ? continuation.exit('captured') + : continuation()), + }, + + exposeConstant({ + value: input.value(null), + }), + ], + + date: simpleDate(), + + secondDate: simpleDate(), + + accessDate: [ + exposeUpdateValueOrContinue({ + validate: input.value(isDate), + }), + + withWebArchiveDate(), + + exposeDependencyOrContinue({ + dependency: '#webArchiveDate', + }), + + exposeConstant({ + value: input.value(null), + }), + ], + + body: contentString(), + + // Update only + + find: soupyFind(), + }); + + static [Thing.yamlDocumentSpec] = { + fields: { + 'Artists': {property: 'artists'}, + 'Artist Text': {property: 'artistText'}, + + 'Annotation': {property: 'annotation'}, + + 'Date Kind': {property: 'dateKind'}, + 'Access Kind': {property: 'accessKind'}, + + 'Date': {property: 'date', transform: parseDate}, + 'Second Date': {property: 'secondDate', transform: parseDate}, + 'Access Date': {property: 'accessDate', transform: parseDate}, + + 'Body': {property: 'body'}, + }, + }; +} + +export class CommentaryEntry extends ContentEntry {} +export class LyricsEntry extends ContentEntry {} +export class CreditingSourcesEntry extends ContentEntry {} diff --git a/src/data/things/flash.js b/src/data/things/flash.js index ace18af9..dac674dd 100644 --- a/src/data/things/flash.js +++ b/src/data/things/flash.js @@ -10,7 +10,9 @@ import {anyOf, isColor, isContentString, isDirectory, isNumber, isString} import { parseArtwork, parseAdditionalNames, + parseCommentary, parseContributors, + parseCreditingSources, parseDate, parseDimensions, } from '#yaml'; @@ -27,7 +29,6 @@ import { import { additionalNameList, color, - commentary, commentatorArtists, constitutibleArtwork, contentString, @@ -41,6 +42,7 @@ import { soupyFind, soupyReverse, thing, + thingList, urls, wikiData, } from '#composite/wiki-properties'; @@ -52,6 +54,8 @@ export class Flash extends Thing { static [Thing.referenceType] = 'flash'; static [Thing.getPropertyDescriptors] = ({ + CommentaryEntry, + CreditingSourcesEntry, Track, FlashAct, WikiInfo, @@ -125,8 +129,13 @@ export class Flash extends Thing { additionalNames: additionalNameList(), - commentary: commentary(), - creditSources: commentary(), + commentary: thingList({ + class: input.value(CommentaryEntry), + }), + + creditSources: thingList({ + class: input.value(CreditingSourcesEntry), + }), // Update only @@ -240,8 +249,15 @@ export class Flash extends Thing { transform: parseContributors, }, - 'Commentary': {property: 'commentary'}, - 'Credit Sources': {property: 'creditSources'}, + 'Commentary': { + property: 'commentary', + transform: parseCommentary, + }, + + 'Credit Sources': { + property: 'creditSources', + transform: parseCreditingSources, + }, 'Review Points': {ignore: true}, }, @@ -441,8 +457,18 @@ export class FlashSide extends Thing { const flashSideData = results.filter(x => x instanceof FlashSide); const artworkData = flashData.map(flash => flash.coverArtwork); - - return {flashData, flashActData, flashSideData, artworkData}; + const commentaryData = flashData.flatMap(flash => flash.commentary); + const creditingSourceData = flashData.flatMap(flash => flash.creditSources); + + return { + flashData, + flashActData, + flashSideData, + + artworkData, + commentaryData, + creditingSourceData, + }; }, sort({flashData}) { diff --git a/src/data/things/index.js b/src/data/things/index.js index 96cec88e..b832ab75 100644 --- a/src/data/things/index.js +++ b/src/data/things/index.js @@ -13,6 +13,7 @@ import * as albumClasses from './album.js'; import * as artTagClasses from './art-tag.js'; import * as artistClasses from './artist.js'; import * as artworkClasses from './artwork.js'; +import * as contentClasses from './content.js'; import * as contributionClasses from './contribution.js'; import * as flashClasses from './flash.js'; import * as groupClasses from './group.js'; @@ -29,6 +30,7 @@ const allClassLists = { 'art-tag.js': artTagClasses, 'artist.js': artistClasses, 'artwork.js': artworkClasses, + 'content.js': contentClasses, 'contribution.js': contributionClasses, 'flash.js': flashClasses, 'group.js': groupClasses, diff --git a/src/data/things/track.js b/src/data/things/track.js index 2d2cc002..ae7be170 100644 --- a/src/data/things/track.js +++ b/src/data/things/track.js @@ -12,10 +12,13 @@ import { parseAdditionalNames, parseAnnotatedReferences, parseArtwork, + parseCommentary, parseContributors, + parseCreditingSources, parseDate, parseDimensions, parseDuration, + parseLyrics, } from '#yaml'; import {withPropertyFromObject} from '#composite/data'; @@ -37,7 +40,6 @@ import { import { additionalFiles, additionalNameList, - commentary, commentatorArtists, constitutibleArtworkList, contentString, @@ -56,6 +58,7 @@ import { soupyFind, soupyReverse, thing, + thingList, urls, wikiData, } from '#composite/wiki-properties'; @@ -86,7 +89,10 @@ export class Track extends Thing { Album, ArtTag, Artwork, + CommentaryEntry, + CreditingSourcesEntry, Flash, + LyricsEntry, TrackSection, WikiInfo, }) => ({ @@ -215,12 +221,23 @@ export class Track extends Thing { dimensions(), ], - commentary: commentary(), - creditSources: commentary(), + commentary: thingList({ + class: input.value(CommentaryEntry), + }), + + creditSources: thingList({ + class: input.value(CreditingSourcesEntry), + }), lyrics: [ + // TODO: Inherited lyrics are literally the same objects, so of course + // their .thing properties aren't going to point back to this one, and + // certainly couldn't be recontextualized... inheritFromMainRelease(), - contentString(), + + thingList({ + class: input.value(LyricsEntry), + }), ], additionalFiles: additionalFiles(), @@ -480,9 +497,20 @@ export class Track extends Thing { 'Always Reference By Directory': {property: 'alwaysReferenceByDirectory'}, - 'Lyrics': {property: 'lyrics'}, - 'Commentary': {property: 'commentary'}, - 'Credit Sources': {property: 'creditSources'}, + 'Lyrics': { + property: 'lyrics', + transform: parseLyrics, + }, + + 'Commentary': { + property: 'commentary', + transform: parseCommentary, + }, + + 'Credit Sources': { + property: 'creditSources', + transform: parseCreditingSources, + }, 'Additional Files': { property: 'additionalFiles', @@ -533,6 +561,8 @@ export class Track extends Thing { dimensionsFromThingProperty: 'coverArtDimensions', fileExtensionFromThingProperty: 'coverArtFileExtension', dateFromThingProperty: 'coverArtDate', + artTagsFromThingProperty: 'artTags', + referencedArtworksFromThingProperty: 'referencedArtworks', artistContribsFromThingProperty: 'coverArtistContribs', artistContribsArtistProperty: 'trackCoverArtistContributions', }), |