« get me outta code hell

data: Artwork, constitutibleArtwork, etc - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/data
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2025-03-31 15:04:20 -0300
committer(quasar) nebula <qznebula@protonmail.com>2025-04-10 16:02:35 -0300
commite8964d7a9f9dc787d4d84c0554d22149bb2daa0c (patch)
tree460944e7a5417ee8a998e37d7cbd05364398fd4f /src/data
parent964273f8cb26c6d9df8ec827126167dc5b58ae27 (diff)
data: Artwork, constitutibleArtwork, etc
Not used in content yet.
Diffstat (limited to 'src/data')
-rw-r--r--src/data/composite/things/artwork/index.js1
-rw-r--r--src/data/composite/things/artwork/withDate.js35
-rw-r--r--src/data/composite/wiki-data/index.js1
-rw-r--r--src/data/composite/wiki-data/withConstitutedArtwork.js44
-rw-r--r--src/data/composite/wiki-properties/constitutibleArtwork.js67
-rw-r--r--src/data/composite/wiki-properties/index.js1
-rw-r--r--src/data/things/album.js30
-rw-r--r--src/data/things/artwork.js97
-rw-r--r--src/data/things/index.js2
-rw-r--r--src/data/things/track.js24
-rw-r--r--src/data/yaml.js18
11 files changed, 313 insertions, 7 deletions
diff --git a/src/data/composite/things/artwork/index.js b/src/data/composite/things/artwork/index.js
new file mode 100644
index 00000000..b92bff72
--- /dev/null
+++ b/src/data/composite/things/artwork/index.js
@@ -0,0 +1 @@
+export {default as withDate} from './withDate.js';
diff --git a/src/data/composite/things/artwork/withDate.js b/src/data/composite/things/artwork/withDate.js
new file mode 100644
index 00000000..08f1427c
--- /dev/null
+++ b/src/data/composite/things/artwork/withDate.js
@@ -0,0 +1,35 @@
+import {input, templateCompositeFrom} from '#composite';
+
+import {withPropertyFromObject} from '#composite/data';
+
+export default templateCompositeFrom({
+  annotation: `withDate`,
+
+  inputs: {
+    from: input({
+      defaultDependency: 'date',
+      acceptsNull: true,
+    }),
+  },
+
+  outputs: ['#date'],
+
+  steps: () => [
+    {
+      dependencies: [input('from')],
+      compute: (continuation, {
+        [input('from')]: date,
+      }) =>
+        (date
+          ? continuation.raiseOutput({'#date': date})
+          : continuation()),
+    },
+
+    withPropertyFromObject({
+      object: 'thing',
+      property: 'dateFromThingProperty',
+    }).outputs({
+      ['#value']: '#date',
+    }),
+  ],
+})
diff --git a/src/data/composite/wiki-data/index.js b/src/data/composite/wiki-data/index.js
index be83e4c9..ee7411f2 100644
--- a/src/data/composite/wiki-data/index.js
+++ b/src/data/composite/wiki-data/index.js
@@ -12,6 +12,7 @@ export {default as inputSoupyFind} from './inputSoupyFind.js';
 export {default as inputSoupyReverse} from './inputSoupyReverse.js';
 export {default as inputWikiData} from './inputWikiData.js';
 export {default as withClonedThings} from './withClonedThings.js';
+export {default as withConstitutedArtwork} from './withConstitutedArtwork.js';
 export {default as withContributionListSums} from './withContributionListSums.js';
 export {default as withCoverArtDate} from './withCoverArtDate.js';
 export {default as withDirectory} from './withDirectory.js';
diff --git a/src/data/composite/wiki-data/withConstitutedArtwork.js b/src/data/composite/wiki-data/withConstitutedArtwork.js
new file mode 100644
index 00000000..9843588a
--- /dev/null
+++ b/src/data/composite/wiki-data/withConstitutedArtwork.js
@@ -0,0 +1,44 @@
+import {input, templateCompositeFrom} from '#composite';
+import thingConstructors from '#things';
+import {isContributionList} from '#validators';
+
+export default templateCompositeFrom({
+  annotation: `withConstitutedArtwork`,
+
+  inputs: {
+    contribsProperty: input({type: 'string'}),
+    artistProperty: input({type: 'string'}),
+    dateProperty: input({type: 'string'}),
+  },
+
+  outputs: ['#constitutedArtwork'],
+
+  steps: () => [
+    {
+      dependencies: [
+        input.myself(),
+        'find',
+
+        input('contribsProperty'),
+        input('dateProperty'),
+      ],
+
+      compute: (continuation, {
+        [input.myself()]: myself,
+        ['find']: find,
+
+        [input('contribsProperty')]: contribsProperty,
+        [input('dateProperty')]: dateProperty,
+      }) => continuation({
+        ['#constitutedArtwork']:
+          Object.assign(new thingConstructors.Artwork, {
+            thing: myself,
+            find: find,
+
+            artistContribsFromThingProperty: contribsProperty,
+            dateFromThingProperty: dateProperty,
+          }),
+      }),
+    },
+  ],
+});
diff --git a/src/data/composite/wiki-properties/constitutibleArtwork.js b/src/data/composite/wiki-properties/constitutibleArtwork.js
new file mode 100644
index 00000000..e0f0f521
--- /dev/null
+++ b/src/data/composite/wiki-properties/constitutibleArtwork.js
@@ -0,0 +1,67 @@
+import {input, templateCompositeFrom} from '#composite';
+import {isContributionList, isDate, validateThing} from '#validators';
+
+import {exitWithoutDependency, exposeDependency, exposeUpdateValueOrContinue}
+  from '#composite/control-flow';
+import {withConstitutedArtwork} from '#composite/wiki-data';
+
+export default templateCompositeFrom({
+  annotation: `constitutibleArtwork`,
+
+  compose: false,
+
+  inputs: {
+    contribs: input.staticDependency({
+      validate: isContributionList,
+      acceptsNull: true,
+    }),
+
+    date: input.staticDependency({
+      validate: isDate,
+      acceptsNull: true,
+    }),
+
+    artistProperty: input.staticValue({
+      type: 'string',
+    }),
+  },
+
+  steps: () => [
+    exposeUpdateValueOrContinue({
+      validate: input.value(
+        validateThing({
+          referenceType: 'artwork',
+        })),
+    }),
+
+    exitWithoutDependency({
+      dependency: input('contribs'),
+      value: input.value(null),
+    }),
+
+    {
+      dependencies: [
+        input.staticDependency('contribs'),
+        input.staticDependency('date'),
+      ],
+
+      compute: (continuation, {
+        [input.staticDependency('contribs')]: contribsProperty,
+        [input.staticDependency('date')]: dateProperty,
+      }) => continuation({
+        ['#contribsProperty']: contribsProperty,
+        ['#dateProperty']: dateProperty,
+      })
+    },
+
+    withConstitutedArtwork({
+      contribsProperty: '#contribsProperty',
+      artistProperty: input('artistProperty'),
+      dateProperty: '#dateProperty',
+    }),
+
+    exposeDependency({
+      dependency: '#constitutedArtwork',
+    }),
+  ],
+});
diff --git a/src/data/composite/wiki-properties/index.js b/src/data/composite/wiki-properties/index.js
index 4aaaeb72..7583630d 100644
--- a/src/data/composite/wiki-properties/index.js
+++ b/src/data/composite/wiki-properties/index.js
@@ -9,6 +9,7 @@ export {default as annotatedReferenceList} from './annotatedReferenceList.js';
 export {default as color} from './color.js';
 export {default as commentary} from './commentary.js';
 export {default as commentatorArtists} from './commentatorArtists.js';
+export {default as constitutibleArtwork} from './constitutibleArtwork.js';
 export {default as contentString} from './contentString.js';
 export {default as contribsPresent} from './contribsPresent.js';
 export {default as contributionList} from './contributionList.js';
diff --git a/src/data/things/album.js b/src/data/things/album.js
index e7ab9def..1c13ef16 100644
--- a/src/data/things/album.js
+++ b/src/data/things/album.js
@@ -15,6 +15,7 @@ import {
   parseAdditionalFiles,
   parseAdditionalNames,
   parseAnnotatedReferences,
+  parseArtwork,
   parseContributors,
   parseDate,
   parseDimensions,
@@ -34,6 +35,7 @@ import {
   commentary,
   color,
   commentatorArtists,
+  constitutibleArtwork,
   contentString,
   contribsPresent,
   contributionList,
@@ -157,6 +159,12 @@ export class Album extends Thing {
       dimensions(),
     ],
 
+    coverArtwork: constitutibleArtwork({
+      contribs: 'coverArtistContribs',
+      date: 'coverArtDate',
+      artistProperty: input.value('albumCoverArtistContributions'),
+    }),
+
     hasTrackNumbers: flag(true),
     isListedOnHomepage: flag(true),
     isListedInGalleries: flag(true),
@@ -459,6 +467,16 @@ export class Album extends Thing {
       'Listed on Homepage': {property: 'isListedOnHomepage'},
       'Listed in Galleries': {property: 'isListedInGalleries'},
 
+      'Cover Artwork': {
+        property: 'coverArtwork',
+        transform:
+          parseArtwork({
+            dateFromThingProperty: 'coverArtDate',
+            artistContribsFromThingProperty: 'coverArtistContribs',
+            artistContribsArtistProperty: 'albumCoverArtistContributions',
+          }),
+      },
+
       'Cover Art Date': {
         property: 'coverArtDate',
         transform: parseDate,
@@ -585,6 +603,7 @@ export class Album extends Thing {
       const albumData = [];
       const trackSectionData = [];
       const trackData = [];
+      const artworkData = [];
 
       for (const {header: album, entries} of results) {
         const trackSections = [];
@@ -625,6 +644,10 @@ export class Album extends Thing {
           currentTrackSectionTracks.push(entry);
           trackData.push(entry);
 
+          if (entry.trackArtwork) {
+            artworkData.push(entry.trackArtwork);
+          }
+
           entry.dataSourceAlbum = albumRef;
         }
 
@@ -635,7 +658,12 @@ export class Album extends Thing {
         album.trackSections = trackSections;
       }
 
-      return {albumData, trackSectionData, trackData};
+      return {
+        albumData,
+        trackSectionData,
+        trackData,
+        artworkData,
+      };
     },
 
     sort({albumData, trackData}) {
diff --git a/src/data/things/artwork.js b/src/data/things/artwork.js
new file mode 100644
index 00000000..86cf6c8a
--- /dev/null
+++ b/src/data/things/artwork.js
@@ -0,0 +1,97 @@
+import {input} from '#composite';
+import Thing from '#thing';
+import {isContributionList, isDate} from '#validators';
+import {parseContributors} from '#yaml';
+
+import {withRecontextualizedContributionList, withResolvedContribs}
+  from '#composite/wiki-data';
+import {referenceList, simpleString, soupyFind, thing}
+  from '#composite/wiki-properties';
+
+import {
+  exposeDependency,
+  exposeDependencyOrContinue,
+  exposeUpdateValueOrContinue,
+} from '#composite/control-flow';
+
+import {withDate} from '#composite/things/artwork';
+
+export class Artwork extends Thing {
+  static [Thing.referenceType] = 'artwork';
+
+  static [Thing.getPropertyDescriptors] = ({
+    ArtTag,
+    Contribution,
+  }) => ({
+    // Update & expose
+
+    thing: thing(),
+
+    artTags: referenceList({
+      class: input.value(ArtTag),
+      find: soupyFind.input('artTag'),
+    }),
+
+    artistContribsFromThingProperty: simpleString(),
+    artistContribsArtistProperty: simpleString(),
+
+    artistContribs: [
+      withDate(),
+
+      withResolvedContribs({
+        from: input.updateValue({validate: isContributionList}),
+        date: '#date',
+        artistProperty: 'artistContribsArtistProperty',
+      }),
+
+      exposeDependencyOrContinue({
+        dependency: '#resolvedContribs',
+        mode: input.value('empty'),
+      }),
+
+      {
+        dependencies: ['thing', 'artistContribsFromThingProperty'],
+        compute: (continuation, {thing, artistContribsFromThingProperty}) =>
+          (artistContribsFromThingProperty
+            ? continuation({
+                '#artistContribs':
+                  thing[artistContribsFromThingProperty],
+              })
+            : continuation.exit(null)),
+      },
+
+      withRecontextualizedContributionList({
+        list: '#artistContribs',
+      }),
+
+      exposeDependency({
+        dependency: '#artistContribs',
+      }),
+    ],
+
+    dateFromThingProperty: simpleString(),
+
+    date: [
+      withDate({
+        from: input.updateValue({validate: isDate}),
+      }),
+
+      exposeDependency({dependency: '#date'}),
+    ],
+
+    // Update only
+
+    find: soupyFind(),
+  });
+
+  static [Thing.yamlDocumentSpec] = {
+    fields: {
+      'Artists': {
+        property: 'artistContribs',
+        transform: parseContributors,
+      },
+
+      'Art Tags': {property: 'artTags'},
+    },
+  };
+}
diff --git a/src/data/things/index.js b/src/data/things/index.js
index 17471f31..96cec88e 100644
--- a/src/data/things/index.js
+++ b/src/data/things/index.js
@@ -12,6 +12,7 @@ import Thing from '#thing';
 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 contributionClasses from './contribution.js';
 import * as flashClasses from './flash.js';
 import * as groupClasses from './group.js';
@@ -27,6 +28,7 @@ const allClassLists = {
   'album.js': albumClasses,
   'art-tag.js': artTagClasses,
   'artist.js': artistClasses,
+  'artwork.js': artworkClasses,
   'contribution.js': contributionClasses,
   'flash.js': flashClasses,
   'group.js': groupClasses,
diff --git a/src/data/things/track.js b/src/data/things/track.js
index afb2197d..84e36d95 100644
--- a/src/data/things/track.js
+++ b/src/data/things/track.js
@@ -11,6 +11,7 @@ import {
   parseAdditionalFiles,
   parseAdditionalNames,
   parseAnnotatedReferences,
+  parseArtwork,
   parseContributors,
   parseDate,
   parseDimensions,
@@ -38,6 +39,7 @@ import {
   additionalNameList,
   commentary,
   commentatorArtists,
+  constitutibleArtwork,
   contentString,
   contributionList,
   dimensions,
@@ -83,6 +85,7 @@ export class Track extends Thing {
   static [Thing.getPropertyDescriptors] = ({
     Album,
     ArtTag,
+    Artwork,
     Flash,
     TrackSection,
     WikiInfo,
@@ -338,12 +341,11 @@ export class Track extends Thing {
       }),
     ],
 
-    trackArtwork: [
-      constitutibleArtwork({
-        contribs: 'coverArtistContribs',
-        date: 'coverArtDate',
-      }),
-    ],
+    trackArtwork: constitutibleArtwork({
+      contribs: 'coverArtistContribs',
+      date: 'coverArtDate',
+      artistProperty: input.value('trackCoverArtistContributions'),
+    }),
 
     artTags: [
       exitWithoutUniqueCoverArt({
@@ -570,6 +572,16 @@ export class Track extends Thing {
         transform: parseContributors,
       },
 
+      'Track Artwork': {
+        property: 'trackArtwork',
+        transform:
+          parseArtwork({
+            dateFromThingProperty: 'coverArtDate',
+            artistContribsFromThingProperty: 'coverArtistContribs',
+            artistContribsArtistProperty: 'trackCoverArtistContributions',
+          }),
+      },
+
       'Art Tags': {property: 'artTags'},
 
       'Review Points': {ignore: true},
diff --git a/src/data/yaml.js b/src/data/yaml.js
index d7acdbc0..c2bdc69a 100644
--- a/src/data/yaml.js
+++ b/src/data/yaml.js
@@ -733,6 +733,22 @@ export function parseAnnotatedReferences(entries, {
   });
 }
 
+export function parseArtwork({
+  dateFromThingProperty,
+  artistContribsFromThingProperty,
+  artistContribsArtistProperty,
+}) {
+  return (entry, {subdoc, Artwork}) =>
+    subdoc(Artwork, entry, {
+      bindInto: 'thing',
+      provide: {
+        dateFromThingProperty,
+        artistContribsFromThingProperty,
+        artistContribsArtistProperty,
+      },
+    });
+}
+
 // documentModes: Symbols indicating sets of behavior for loading and processing
 // data files.
 export const documentModes = {
@@ -1407,6 +1423,8 @@ export function linkWikiDataArrays(wikiData, {bindFind, bindReverse}) {
 
     ['artistData', [/* find, reverse */]],
 
+    ['artworkData', [/* find */]],
+
     ['flashData', [
       'wikiInfo',
     ]],