« get me outta code hell

pre-writes: listings - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2022-02-17 23:23:35 -0400
committer(quasar) nebula <qznebula@protonmail.com>2022-02-17 23:25:59 -0400
commitf26ad2e27e9c7ca61b6ae5e9b3587786d911a2df (patch)
treea611d91cab993d84cda1dd81af7be741295e248a
parentf8557485ac06a7b2527c50dcf638497212678a16 (diff)
pre-writes: listings
-rw-r--r--src/data/things.js142
-rw-r--r--src/listing-spec.js59
-rw-r--r--src/page/tag.js2
-rwxr-xr-xsrc/upd8.js17
-rw-r--r--src/util/find.js6
-rw-r--r--src/util/wiki-data.js6
6 files changed, 175 insertions, 57 deletions
diff --git a/src/data/things.js b/src/data/things.js
index 92763c14..4f4c2908 100644
--- a/src/data/things.js
+++ b/src/data/things.js
@@ -210,6 +210,46 @@ Thing.common = {
         };
     },
 
+    // Corresponding dynamic property to referenceList, which takes the values
+    // in the provided property and searches the specified wiki data for
+    // matching actual Thing-subclass objects.
+    dynamicThingsFromReferenceList: (
+        referenceListProperty,
+        wikiDataProperty,
+        findFn
+    ) => ({
+        flags: {expose: true},
+
+        expose: {
+            dependencies: [referenceListProperty, wikiDataProperty],
+            compute: ({ [referenceListProperty]: refs, [wikiDataProperty]: wikiData }) => (
+                (refs && wikiData
+                    ? (refs
+                        .map(ref => findFn(ref, {wikiData: {[wikiDataProperty]: wikiData}}))
+                        .filter(Boolean))
+                    : [])
+            )
+        }
+    }),
+
+    // Corresponding function for a single reference.
+    dynamicThingFromSingleReference: (
+        singleReferenceProperty,
+        wikiDataProperty,
+        findFn
+    ) => ({
+        flags: {expose: true},
+
+        expose: {
+            dependencies: [singleReferenceProperty, wikiDataProperty],
+            compute: ({ [singleReferenceProperyt]: ref, [wikiDataProperty]: wikiData }) => (
+                (ref && wikiData
+                    ? findFn(ref, {wikiData: {[wikiDataProperty]: wikiData}})
+                    : [])
+            )
+        }
+    }),
+
     // Corresponding dynamic property to contribsByRef, which takes the values
     // in the provided property and searches the object's artistData for
     // matching actual Artist objects. The computed structure has the same form
@@ -277,6 +317,36 @@ Thing.common = {
         }
     }),
 
+    // Neat little shortcut for "reversing" the reference lists stored on other
+    // things - for example, tracks specify a "referenced tracks" property, and
+    // you would use this to compute a corresponding "referenced *by* tracks"
+    // property. Naturally, the passed ref list property is of the things in the
+    // wiki data provided, not the requesting Thing itself.
+    reverseReferenceList: (wikiDataProperty, referencerRefListProperty) => ({
+        flags: {expose: true},
+
+        expose: {
+            dependencies: [wikiDataProperty],
+
+            compute: ({ [wikiDataProperty]: wikiData, [Thing.instance]: thing }) => (
+                wikiData?.filter(t => t[referencerRefListProperty]?.includes(thing)))
+        }
+    }),
+
+    // Corresponding function for single references. Note that the return value
+    // is still a list - this is for matching all the objects whose single
+    // reference (in the given property) matches this Thing.
+    reverseSingleReference: (wikiDataProperty, referencerRefListProperty) => ({
+        flags: {expose: true},
+
+        expose: {
+            dependencies: [wikiDataProperty],
+
+            compute: ({ [wikiDataProperty]: wikiData, [Thing.instance]: thing }) => (
+                wikiData?.filter(t => t[referencerRefListProperty] === thing))
+        }
+    }),
+
     // General purpose wiki data constructor, for properties like artistData,
     // trackData, etc.
     wikiData: (thingClass) => ({
@@ -387,20 +457,9 @@ Album.propertyDescriptors = {
         }
     },
 
-    groups: {
-        flags: {expose: true},
+    groups: Thing.common.dynamicThingsFromReferenceList('groupsByRef', 'groupData', find.group),
 
-        expose: {
-            dependencies: ['groupsByRef', 'groupData'],
-            compute: ({ groupsByRef, groupData }) => (
-                (groupsByRef && groupData
-                    ? (groupsByRef
-                        .map(ref => find.group(ref, {wikiData: {groupData}}))
-                        .filter(Boolean))
-                    : [])
-            )
-        }
-    },
+    artTags: Thing.common.dynamicThingsFromReferenceList('artTagsByRef', 'artTagData', find.artTag),
 };
 
 TrackGroup.propertyDescriptors = {
@@ -485,6 +544,7 @@ Track.propertyDescriptors = {
     albumData: Thing.common.wikiData(Album),
     artistData: Thing.common.wikiData(Artist),
     artTagData: Thing.common.wikiData(ArtTag),
+    trackData: Thing.common.wikiData(Track),
 
     // Expose only
 
@@ -537,21 +597,16 @@ Track.propertyDescriptors = {
     // Previously known as: (track).coverArtists
     coverArtistContribs: Thing.common.dynamicInheritContribs('coverArtistContribsByRef', 'trackCoverArtistContribsByRef', 'albumData', Track.findAlbum),
 
-    artTags: {
-        flags: {expose: true},
+    // Previously known as: (track).references
+    referencedTracks: Thing.common.dynamicThingsFromReferenceList('referencedTracksByRef', 'trackData', find.track),
 
-        expose: {
-            dependencies: ['artTagsByRef', 'artTagData'],
+    // Previously known as: (track).referencedBy
+    referencedByTracks: Thing.common.reverseReferenceList('trackData', 'referencedTracks'),
 
-            compute: ({ artTagsByRef, artTagData }) => (
-                (artTagsByRef && artTagData
-                    ? (artTagsByRef
-                        .map(ref => find.tag(ref, {wikiData: {artTagData}}))
-                        .filter(Boolean))
-                    : [])
-            )
-        }
-    }
+    // Previously known as: (track).flashes
+    featuredInFlashes: Thing.common.reverseReferenceList('flashData', 'featuredTracks'),
+
+    artTags: Thing.common.dynamicThingsFromReferenceList('artTagsByRef', 'artTagData', find.artTag),
 };
 
 // -> Artist
@@ -598,6 +653,7 @@ Artist.propertyDescriptors = {
     // albumsAsBannerArtist
     // albumsAsCommentator
 
+    // tracksAsAny
     // tracksAsArtist
     // tracksAsContributor
     // tracksAsCoverArtist
@@ -618,6 +674,10 @@ Group.propertyDescriptors = {
 
     urls: Thing.common.urls(),
 
+    // Update only
+
+    albumData: Thing.common.wikiData(Album),
+
     // Expose only
 
     descriptionShort: {
@@ -627,7 +687,17 @@ Group.propertyDescriptors = {
             dependencies: ['description'],
             compute: ({ description }) => description.split('<hr class="split">')[0]
         }
-    }
+    },
+
+    albums: {
+        flags: {expose: true},
+
+        expose: {
+            dependencies: ['albumData'],
+            compute: ({ albumData, [Group.instance]: group }) => (
+                albumData?.filter(album => album.groups.includes(group)) ?? [])
+        }
+    },
 };
 
 GroupCategory.propertyDescriptors = {
@@ -648,6 +718,24 @@ ArtTag.propertyDescriptors = {
     directory: Thing.common.directory(),
     color: Thing.common.color(),
     isContentWarning: Thing.common.flag(false),
+
+    // Update only
+
+    albumData: Thing.common.wikiData(Album),
+    trackData: Thing.common.wikiData(Track),
+
+    // Expose only
+
+    // Previously known as: (tag).things
+    taggedInThings: {
+        flags: {expose: true},
+
+        expose: {
+            dependencies: ['albumData', 'trackData'],
+            compute: ({ albumData, trackData, [ArtTag.instance]: artTag }) => (
+                [...albumData, ...trackData].filter(thing => thing.artTags?.includes(artTag)))
+        }
+    }
 };
 
 // -> NewsEntry
diff --git a/src/listing-spec.js b/src/listing-spec.js
index cf0dc09c..97498ba6 100644
--- a/src/listing-spec.js
+++ b/src/listing-spec.js
@@ -142,8 +142,8 @@ const listingSpec = [
                     .map(artist => ({
                         artist,
                         contributions: (
-                            artist.tracks.asContributor.length +
-                            artist.tracks.asArtist.length
+                            (artist.tracksAsContributor?.length ?? 0) +
+                            (artist.tracksAsArtist?.length ?? 0)
                         )
                     }))
                     .sort((a, b) => b.contributions - a.contributions)
@@ -153,12 +153,12 @@ const listingSpec = [
                     .map(artist => ({
                         artist,
                         contributions: (
-                            artist.tracks.asCoverArtist.length +
-                            artist.albums.asCoverArtist.length +
-                            artist.albums.asWallpaperArtist.length +
-                            artist.albums.asBannerArtist.length +
+                            (artist.tracksAsCoverArtist?.length ?? 0) +
+                            (artist.albumsAsCoverArtist?.length ?? 0) +
+                            (artist.albumsAsWallpaperArtist?.length ?? 0) +
+                            (artist.albumsAsBannerArtist?.length ?? 0) +
                             (wikiData.wikiInfo.enableFlashesAndGames
-                                ? artist.flashes.asContributor.length
+                                ? (artist.flashesAsContributor?.length ?? 0)
                                 : 0)
                         )
                     }))
@@ -213,7 +213,10 @@ const listingSpec = [
 
         data({wikiData}) {
             return wikiData.artistData
-                .map(artist => ({artist, entries: artist.tracks.asCommentator.length + artist.albums.asCommentator.length}))
+                .map(artist => ({artist, entries: (
+                    (artist.tracksAsCommentator?.length ?? 0) +
+                    (artist.albumsAsCommentator?.length ?? 0)
+                )}))
                 .filter(({ entries }) => entries)
                 .sort((a, b) => b.entries - a.entries);
         },
@@ -232,8 +235,12 @@ const listingSpec = [
 
         data({wikiData}) {
             return wikiData.artistData
-                .map(artist => ({artist, duration: getTotalDuration(
-                    [...artist.tracks.asArtist, ...artist.tracks.asContributor].filter(track => track.album.directory !== UNRELEASED_TRACKS_DIRECTORY))
+                .map(artist => ({
+                    artist,
+                    duration: getTotalDuration([
+                        ...artist.tracksAsArtist ?? [],
+                        ...artist.tracksAsContributor ?? []
+                    ].filter(track => track.album.directory !== UNRELEASED_TRACKS_DIRECTORY))
                 }))
                 .filter(({ duration }) => duration > 0)
                 .sort((a, b) => b.duration - a.duration);
@@ -260,9 +267,12 @@ const listingSpec = [
                     .filter(artist => !artist.alias)
                     .map(artist => ({
                         artist,
-                        date: reversedTracks.find(({ album, artists, contributors }) => (
-                            album.directory !== UNRELEASED_TRACKS_DIRECTORY &&
-                            [...artists, ...contributors].some(({ who }) => who === artist)
+                        date: reversedTracks.find(track => (
+                            track.album?.directory !== UNRELEASED_TRACKS_DIRECTORY &&
+                            [
+                                ...track.artistContribs ?? [],
+                                ...track.contributorContribs ?? []
+                            ].some(({ who }) => who === artist)
                         ))?.date
                     }))
                     .filter(({ date }) => date)
@@ -271,13 +281,16 @@ const listingSpec = [
                 toArtAndFlashes: sortByDate(wikiData.artistData
                     .filter(artist => !artist.alias)
                     .map(artist => {
-                        const thing = reversedArtThings.find(({ album, coverArtists, contributors }) => (
-                            album?.directory !== UNRELEASED_TRACKS_DIRECTORY &&
-                            [...coverArtists || [], ...!album && contributors || []].some(({ who }) => who === artist)
+                        const thing = reversedArtThings.find(thing => (
+                            thing.album?.directory !== UNRELEASED_TRACKS_DIRECTORY &&
+                            [
+                                ...thing.coverArtistContribs ?? [],
+                                ...!thing.album && thing.contributorContribs || []
+                            ].some(({ who }) => who === artist)
                         ));
                         return thing && {
                             artist,
-                            date: (thing.coverArtists?.some(({ who }) => who === artist)
+                            date: (thing.coverArtistContribs?.some(({ who }) => who === artist)
                                 ? thing.coverArtDate
                                 : thing.date)
                         };
@@ -438,7 +451,7 @@ const listingSpec = [
 
         data({wikiData}) {
             return sortByDate(wikiData.groupData
-                .map(group => ({group, date: group.albums[group.albums.length - 1].date}))
+                .map(group => ({group, date: group.albums[group.albums.length - 1]?.date}))
                 // So this is kinda tough to explain, 8ut 8asically, when we
                 // reverse the list after sorting it 8y d8te (so that the latest
                 // d8tes come first), it also flips the order of groups which
@@ -598,7 +611,7 @@ const listingSpec = [
 
         data({wikiData}) {
             return wikiData.trackData
-                .map(track => ({track, timesReferenced: track.referencedBy.length}))
+                .map(track => ({track, timesReferenced: track.referencedByTracks.length}))
                 .filter(({ timesReferenced }) => timesReferenced > 0)
                 .sort((a, b) => b.timesReferenced - a.timesReferenced);
         },
@@ -618,7 +631,7 @@ const listingSpec = [
 
         data({wikiData}) {
             return chunkByProperties(wikiData.trackData
-                .filter(t => t.flashes.length > 0), ['album'])
+                .filter(t => t.featuredInFlashes?.length > 0), ['album'])
                 .filter(({ album }) => album.directory !== UNRELEASED_TRACKS_DIRECTORY);
         },
 
@@ -634,7 +647,7 @@ const listingSpec = [
                             ${(tracks
                                 .map(track => strings('listingPage.listTracks.inFlashes.byAlbum.track', {
                                     track: link.track(track),
-                                    flashes: strings.list.and(track.flashes.map(link.flash))
+                                    flashes: strings.list.and(track.featuredInFlashes.map(link.flash))
                                 }))
                                 .map(row => `<li>${row}</li>`)
                                 .join('\n'))}
@@ -713,7 +726,7 @@ const listingSpec = [
             return wikiData.artTagData
                 .filter(tag => !tag.isCW)
                 .sort(sortByName)
-                .map(tag => ({tag, timesUsed: tag.things.length}));
+                .map(tag => ({tag, timesUsed: tag.taggedInThings?.length}));
         },
 
         row({tag, timesUsed}, {link, strings}) {
@@ -732,7 +745,7 @@ const listingSpec = [
         data({wikiData}) {
             return wikiData.artTagData
                 .filter(tag => !tag.isCW)
-                .map(tag => ({tag, timesUsed: tag.things.length}))
+                .map(tag => ({tag, timesUsed: tag.taggedInThings?.length}))
                 .sort((a, b) => b.timesUsed - a.timesUsed);
         },
 
diff --git a/src/page/tag.js b/src/page/tag.js
index 6090cb08..d7706458 100644
--- a/src/page/tag.js
+++ b/src/page/tag.js
@@ -16,7 +16,7 @@ export function targets({wikiData}) {
 
 export function write(tag, {wikiData}) {
     const { wikiInfo } = wikiData;
-    const { things } = tag;
+    const { taggedInThings: things } = tag;
 
     // Display things featuring this art tag in reverse chronological order,
     // sticking the most recent additions near the top!
diff --git a/src/upd8.js b/src/upd8.js
index d7d9e5ce..2769d42a 100755
--- a/src/upd8.js
+++ b/src/upd8.js
@@ -415,7 +415,7 @@ const replacerSpec = {
         html: (ref, {strings, args}) => strings(ref, args)
     },
     'tag': {
-        find: 'tag',
+        find: 'artTag',
         link: 'tag'
     },
     'track': {
@@ -2792,12 +2792,22 @@ async function main() {
         track.albumData = WD.albumData;
         track.artistData = WD.artistData;
         track.artTagData = WD.artTagData;
+        track.trackData = WD.trackData;
     }
 
     for (const artist of WD.artistData) {
         artist.artistData = WD.artistData;
     }
 
+    for (const group of WD.groupData) {
+        group.albumData = WD.albumData;
+    }
+
+    for (const artTag of WD.artTagData) {
+        artTag.albumData = WD.albumData;
+        artTag.trackData = WD.trackData;
+    }
+
     // Extra organization stuff needed for listings and the like.
 
     Object.assign(wikiData, {
@@ -2805,6 +2815,9 @@ async function main() {
         trackData: sortByDate(WD.trackData.slice())
     });
 
+    // console.log(WD.trackData.find(t => t.name === 'Aggrievance').artTags[0].taggedInThings.map(thing => thing.name));
+    // return;
+
     // Update languages o8ject with the wiki-specified default language!
     // This will make page files for that language 8e gener8ted at the root
     // directory, instead of the language-specific su8directory.
@@ -2828,7 +2841,7 @@ async function main() {
         const tagRefs = new Set([...WD.trackData, ...WD.albumData].flatMap(thing => thing.artTagsByRef ?? []));
 
         for (const ref of tagRefs) {
-            if (find.tag(ref, {wikiData})) {
+            if (find.artTag(ref, {wikiData})) {
                 tagRefs.delete(ref);
             }
         }
diff --git a/src/util/find.js b/src/util/find.js
index a9af2384..872b3b7a 100644
--- a/src/util/find.js
+++ b/src/util/find.js
@@ -25,6 +25,10 @@ function findHelper(keys, dataProp, findFns = {}) {
 
         const data = wikiData[dataProp];
 
+        if (!data) {
+            throw new Error(`Expected data to be present`);
+        }
+
         const found = (key
             ? byDirectory(ref, data, quiet)
             : byName(ref, data, quiet));
@@ -76,12 +80,12 @@ function matchTagName(ref, data, quiet) {
 const find = {
     album: findHelper(['album', 'album-commentary'], 'albumData'),
     artist: findHelper(['artist', 'artist-gallery'], 'artistData'),
+    artTag: findHelper(['tag'], 'artTagData', {byName: matchTagName}),
     flash: findHelper(['flash'], 'flashData'),
     group: findHelper(['group', 'group-gallery'], 'groupData'),
     listing: findHelper(['listing'], 'listingSpec'),
     newsEntry: findHelper(['news-entry'], 'newsData'),
     staticPage: findHelper(['static'], 'staticPageData'),
-    tag: findHelper(['tag'], 'artTagData', {byName: matchTagName}),
     track: findHelper(['track'], 'trackData')
 };
 
diff --git a/src/util/wiki-data.js b/src/util/wiki-data.js
index 2f705f91..41071d17 100644
--- a/src/util/wiki-data.js
+++ b/src/util/wiki-data.js
@@ -129,9 +129,9 @@ export function getAllTracks(albumData) {
 
 export function getArtistNumContributions(artist) {
     return (
-        artist.tracks.asAny.length +
-        artist.albums.asCoverArtist.length +
-        (artist.flashes ? artist.flashes.asContributor.length : 0)
+        (artist.tracksAsAny?.length ?? 0) +
+        (artist.albumsAsCoverArtist?.length ?? 0) +
+        (artist.flashesAsContributor?.length ?? 0)
     );
 }