diff options
| -rw-r--r-- | src/data/things/album/Album.js (renamed from src/data/things/album.js) | 264 | ||||
| -rw-r--r-- | src/data/things/album/TrackSection.js | 267 | ||||
| -rw-r--r-- | src/data/things/album/index.js | 2 | ||||
| -rw-r--r-- | src/data/things/index.js | 2 |
4 files changed, 274 insertions, 261 deletions
diff --git a/src/data/things/album.js b/src/data/things/album/Album.js index b93c7479..d5fd1682 100644 --- a/src/data/things/album.js +++ b/src/data/things/album/Album.js @@ -1,24 +1,14 @@ export const DATA_ALBUM_DIRECTORY = 'album'; import * as path from 'node:path'; -import {inspect} from 'node:util'; -import {colors} from '#cli'; import {input, V} from '#composite'; import {traverse} from '#node-utils'; import {sortAlbumsTracksChronologically, sortChronologically} from '#sort'; import {empty} from '#sugar'; import Thing from '#thing'; - -import { - is, - isBoolean, - isColor, - isContributionList, - isDate, - isDirectory, - isNumber, -} from '#validators'; +import {is, isContributionList, isDate, isDirectory, isNumber} + from '#validators'; import { parseAdditionalFiles, @@ -33,6 +23,7 @@ import { parseWallpaperParts, } from '#yaml'; +import {withFlattenedList, withPropertyFromList} from '#composite/data'; import {withRecontextualizedContributionList, withResolvedContribs} from '#composite/wiki-data'; @@ -45,14 +36,6 @@ import { } from '#composite/control-flow'; import { - withFlattenedList, - withLengthOfList, - withNearbyItemFromList, - withPropertyFromList, - withPropertyFromObject, -} from '#composite/data'; - -import { color, commentatorArtists, constitutibleArtwork, @@ -813,7 +796,7 @@ export class Album extends Thing { static [Thing.getYamlLoadingSpec] = ({ documentModes: {headerAndEntries}, - thingConstructors: {Album, Track}, + thingConstructors: {Album, Track, TrackSection}, }) => ({ title: `Process album files`, @@ -932,242 +915,3 @@ export class Album extends Thing { return false; } } - -export class TrackSection extends Thing { - static [Thing.friendlyName] = `Track Section`; - static [Thing.referenceType] = `track-section`; - static [Thing.wikiData] = 'trackSectionData'; - - static [Thing.getPropertyDescriptors] = ({Track}) => ({ - // Update & expose - - album: thing(V(Album)), - - name: name(V('Unnamed Track Section')), - - unqualifiedDirectory: directory(), - - directorySuffix: [ - exposeUpdateValueOrContinue({ - validate: input.value(isDirectory), - }), - - withPropertyFromObject({ - object: 'album', - property: input.value('directorySuffix'), - }), - - exposeDependency({dependency: '#album.directorySuffix'}), - ], - - suffixTrackDirectories: [ - exposeUpdateValueOrContinue({ - validate: input.value(isBoolean), - }), - - withPropertyFromObject({ - object: 'album', - property: input.value('suffixTrackDirectories'), - }), - - exposeDependency({dependency: '#album.suffixTrackDirectories'}), - ], - - color: [ - exposeUpdateValueOrContinue({ - validate: input.value(isColor), - }), - - withPropertyFromObject({ - object: 'album', - property: input.value('color'), - }), - - exposeDependency({dependency: '#album.color'}), - ], - - hasTrackNumbers: [ - exposeUpdateValueOrContinue({ - validate: input.value(isBoolean), - }), - - withPropertyFromObject('album', V('hasTrackNumbers')), - exposeDependency('#album.hasTrackNumbers'), - ], - - startCountingFrom: [ - exposeUpdateValueOrContinue({ - validate: input.value(isNumber), - }), - - withPropertyFromObject('album', V('hasTrackNumbers')), - exitWithoutDependency('#album.hasTrackNumbers', V(1), V('falsy')), - - withPropertyFromObject('album', V('trackSections')), - - withNearbyItemFromList({ - list: '#album.trackSections', - item: input.myself(), - offset: input.value(-1), - }).outputs({ - '#nearbyItem': '#previousTrackSection', - }), - - exitWithoutDependency('#previousTrackSection', V(1)), - - withPropertyFromObject('#previousTrackSection', V('continueCountingFrom')), - exposeDependency('#previousTrackSection.continueCountingFrom'), - ], - - dateOriginallyReleased: simpleDate(), - - countTracksInArtistTotals: [ - exposeUpdateValueOrContinue({ - validate: input.value(isBoolean), - }), - - withPropertyFromObject({ - object: 'album', - property: input.value('countTracksInArtistTotals'), - }), - - exposeDependency({dependency: '#album.countTracksInArtistTotals'}), - ], - - isDefaultTrackSection: flag(V(false)), - - description: contentString(), - - tracks: thingList(V(Track)), - - // Update only - - reverse: soupyReverse(), - - // Expose only - - isTrackSection: [ - exposeConstant({ - value: input.value(true), - }), - ], - - directory: [ - exitWithoutDependency({ - dependency: 'album', - }), - - withPropertyFromObject({ - object: 'album', - property: input.value('directory'), - }), - - { - dependencies: ['#album.directory', 'unqualifiedDirectory'], - compute: ({ - ['#album.directory']: albumDirectory, - ['unqualifiedDirectory']: unqualifiedDirectory, - }) => - albumDirectory + '/' + unqualifiedDirectory, - }, - ], - - continueCountingFrom: [ - withPropertyFromObject('album', V('hasTrackNumbers')), - exitWithoutDependency('#album.hasTrackNumbers', V(null), V('falsy')), - - { - dependencies: ['hasTrackNumbers', 'startCountingFrom'], - compute: (continuation, {hasTrackNumbers, startCountingFrom}) => - (hasTrackNumbers - ? continuation() - : continuation.exit(startCountingFrom)), - }, - - withLengthOfList('tracks'), - - { - dependencies: ['startCountingFrom', '#tracks.length'], - compute: ({startCountingFrom, '#tracks.length': tracks}) => - startCountingFrom + tracks, - }, - ], - }); - - static [Thing.findSpecs] = { - trackSection: { - referenceTypes: ['track-section'], - bindTo: 'trackSectionData', - }, - - unqualifiedTrackSection: { - referenceTypes: ['unqualified-track-section'], - - getMatchableDirectories: trackSection => - [trackSection.unqualifiedDirectory], - }, - }; - - static [Thing.yamlDocumentSpec] = { - fields: { - 'Section': {property: 'name'}, - 'Directory Suffix': {property: 'directorySuffix'}, - 'Suffix Track Directories': {property: 'suffixTrackDirectories'}, - - 'Color': {property: 'color'}, - 'Has Track Numbers': {property: 'hasTrackNumbers'}, - 'Start Counting From': {property: 'startCountingFrom'}, - - 'Date Originally Released': { - property: 'dateOriginallyReleased', - transform: parseDate, - }, - - 'Count Tracks In Artist Totals': {property: 'countTracksInArtistTotals'}, - - 'Description': {property: 'description'}, - }, - }; - - [inspect.custom](depth) { - const parts = []; - - parts.push(Thing.prototype[inspect.custom].apply(this)); - - if (depth >= 0) showAlbum: { - let album = null; - try { - album = this.album; - } catch { - break showAlbum; - } - - let first = null; - try { - first = this.tracks.at(0).trackNumber; - } catch {} - - let last = null; - try { - last = this.tracks.at(-1).trackNumber; - } catch {} - - const albumName = album.name; - const albumIndex = album.trackSections.indexOf(this); - - const num = - (albumIndex === -1 - ? 'indeterminate position' - : `#${albumIndex + 1}`); - - const range = - (albumIndex >= 0 && first !== null && last !== null - ? `: ${first}-${last}` - : ''); - - parts.push(` (${colors.yellow(num + range)} in ${colors.green(`"${albumName}"`)})`); - } - - return parts.join(''); - } -} diff --git a/src/data/things/album/TrackSection.js b/src/data/things/album/TrackSection.js new file mode 100644 index 00000000..4bc43a3c --- /dev/null +++ b/src/data/things/album/TrackSection.js @@ -0,0 +1,267 @@ +import {inspect} from 'node:util'; + +import {colors} from '#cli'; +import {input, V} from '#composite'; +import Thing from '#thing'; +import {isBoolean, isColor, isDirectory, isNumber} from '#validators'; +import {parseDate} from '#yaml'; + +import {withLengthOfList, withNearbyItemFromList, withPropertyFromObject} + from '#composite/data'; + +import { + exitWithoutDependency, + exposeConstant, + exposeDependency, + exposeUpdateValueOrContinue, +} from '#composite/control-flow'; + +import { + contentString, + directory, + flag, + name, + simpleDate, + soupyReverse, + thing, + thingList, +} from '#composite/wiki-properties'; + +export class TrackSection extends Thing { + static [Thing.friendlyName] = `Track Section`; + static [Thing.referenceType] = `track-section`; + static [Thing.wikiData] = 'trackSectionData'; + + static [Thing.getPropertyDescriptors] = ({Album, Track}) => ({ + // Update & expose + + album: thing(V(Album)), + + name: name(V('Unnamed Track Section')), + + unqualifiedDirectory: directory(), + + directorySuffix: [ + exposeUpdateValueOrContinue({ + validate: input.value(isDirectory), + }), + + withPropertyFromObject({ + object: 'album', + property: input.value('directorySuffix'), + }), + + exposeDependency({dependency: '#album.directorySuffix'}), + ], + + suffixTrackDirectories: [ + exposeUpdateValueOrContinue({ + validate: input.value(isBoolean), + }), + + withPropertyFromObject({ + object: 'album', + property: input.value('suffixTrackDirectories'), + }), + + exposeDependency({dependency: '#album.suffixTrackDirectories'}), + ], + + color: [ + exposeUpdateValueOrContinue({ + validate: input.value(isColor), + }), + + withPropertyFromObject({ + object: 'album', + property: input.value('color'), + }), + + exposeDependency({dependency: '#album.color'}), + ], + + hasTrackNumbers: [ + exposeUpdateValueOrContinue({ + validate: input.value(isBoolean), + }), + + withPropertyFromObject('album', V('hasTrackNumbers')), + exposeDependency('#album.hasTrackNumbers'), + ], + + startCountingFrom: [ + exposeUpdateValueOrContinue({ + validate: input.value(isNumber), + }), + + withPropertyFromObject('album', V('hasTrackNumbers')), + exitWithoutDependency('#album.hasTrackNumbers', V(1), V('falsy')), + + withPropertyFromObject('album', V('trackSections')), + + withNearbyItemFromList({ + list: '#album.trackSections', + item: input.myself(), + offset: input.value(-1), + }).outputs({ + '#nearbyItem': '#previousTrackSection', + }), + + exitWithoutDependency('#previousTrackSection', V(1)), + + withPropertyFromObject('#previousTrackSection', V('continueCountingFrom')), + exposeDependency('#previousTrackSection.continueCountingFrom'), + ], + + dateOriginallyReleased: simpleDate(), + + countTracksInArtistTotals: [ + exposeUpdateValueOrContinue({ + validate: input.value(isBoolean), + }), + + withPropertyFromObject({ + object: 'album', + property: input.value('countTracksInArtistTotals'), + }), + + exposeDependency({dependency: '#album.countTracksInArtistTotals'}), + ], + + isDefaultTrackSection: flag(V(false)), + + description: contentString(), + + tracks: thingList(V(Track)), + + // Update only + + reverse: soupyReverse(), + + // Expose only + + isTrackSection: [ + exposeConstant({ + value: input.value(true), + }), + ], + + directory: [ + exitWithoutDependency({ + dependency: 'album', + }), + + withPropertyFromObject({ + object: 'album', + property: input.value('directory'), + }), + + { + dependencies: ['#album.directory', 'unqualifiedDirectory'], + compute: ({ + ['#album.directory']: albumDirectory, + ['unqualifiedDirectory']: unqualifiedDirectory, + }) => + albumDirectory + '/' + unqualifiedDirectory, + }, + ], + + continueCountingFrom: [ + withPropertyFromObject('album', V('hasTrackNumbers')), + exitWithoutDependency('#album.hasTrackNumbers', V(null), V('falsy')), + + { + dependencies: ['hasTrackNumbers', 'startCountingFrom'], + compute: (continuation, {hasTrackNumbers, startCountingFrom}) => + (hasTrackNumbers + ? continuation() + : continuation.exit(startCountingFrom)), + }, + + withLengthOfList('tracks'), + + { + dependencies: ['startCountingFrom', '#tracks.length'], + compute: ({startCountingFrom, '#tracks.length': tracks}) => + startCountingFrom + tracks, + }, + ], + }); + + static [Thing.findSpecs] = { + trackSection: { + referenceTypes: ['track-section'], + bindTo: 'trackSectionData', + }, + + unqualifiedTrackSection: { + referenceTypes: ['unqualified-track-section'], + + getMatchableDirectories: trackSection => + [trackSection.unqualifiedDirectory], + }, + }; + + static [Thing.yamlDocumentSpec] = { + fields: { + 'Section': {property: 'name'}, + 'Directory Suffix': {property: 'directorySuffix'}, + 'Suffix Track Directories': {property: 'suffixTrackDirectories'}, + + 'Color': {property: 'color'}, + 'Has Track Numbers': {property: 'hasTrackNumbers'}, + 'Start Counting From': {property: 'startCountingFrom'}, + + 'Date Originally Released': { + property: 'dateOriginallyReleased', + transform: parseDate, + }, + + 'Count Tracks In Artist Totals': {property: 'countTracksInArtistTotals'}, + + 'Description': {property: 'description'}, + }, + }; + + [inspect.custom](depth) { + const parts = []; + + parts.push(Thing.prototype[inspect.custom].apply(this)); + + if (depth >= 0) showAlbum: { + let album = null; + try { + album = this.album; + } catch { + break showAlbum; + } + + let first = null; + try { + first = this.tracks.at(0).trackNumber; + } catch {} + + let last = null; + try { + last = this.tracks.at(-1).trackNumber; + } catch {} + + const albumName = album.name; + const albumIndex = album.trackSections.indexOf(this); + + const num = + (albumIndex === -1 + ? 'indeterminate position' + : `#${albumIndex + 1}`); + + const range = + (albumIndex >= 0 && first !== null && last !== null + ? `: ${first}-${last}` + : ''); + + parts.push(` (${colors.yellow(num + range)} in ${colors.green(`"${albumName}"`)})`); + } + + return parts.join(''); + } +} diff --git a/src/data/things/album/index.js b/src/data/things/album/index.js new file mode 100644 index 00000000..67bf47ab --- /dev/null +++ b/src/data/things/album/index.js @@ -0,0 +1,2 @@ +export * from './Album.js'; +export * from './TrackSection.js'; diff --git a/src/data/things/index.js b/src/data/things/index.js index aeaecf0e..74c6f1e4 100644 --- a/src/data/things/index.js +++ b/src/data/things/index.js @@ -1,5 +1,6 @@ // Not actually the entry point for #things - that's init.js in this folder. +export * from './album/index.js'; export * from './homepage-layout/index.js'; export * from './AdditionalFile.js'; @@ -15,7 +16,6 @@ export * from './StaticPage.js'; export * from './Track.js'; export * from './WikiInfo.js'; -export * from './album.js'; export * from './content.js'; export * from './flash.js'; export * from './group.js'; |