From 6a86a6aca6215cb4d464b814c34233b001575cd9 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 12 Mar 2022 19:07:22 -0400 Subject: simple data serialization & random pages fixes --- src/data/serialize.js | 38 ++++++++++++++++++++ src/data/things.js | 78 +++++++++++++++++++++++++++++++++++++++- src/static/client.js | 6 +++- src/upd8.js | 99 ++++----------------------------------------------- src/util/wiki-data.js | 2 +- 5 files changed, 128 insertions(+), 95 deletions(-) create mode 100644 src/data/serialize.js (limited to 'src') diff --git a/src/data/serialize.js b/src/data/serialize.js new file mode 100644 index 00000000..9d4e8885 --- /dev/null +++ b/src/data/serialize.js @@ -0,0 +1,38 @@ +// serialize-util.js: simple interface and utility functions for converting +// Things into a directly serializeable format + +// Utility functions + +export function id(x) { + return x; +} + +export function toRef(thing) { + return thing?.constructor.getReference(thing); +} + +export function toRefs(things) { + return things?.map(toRef); +} + +export function toContribRefs(contribs) { + return contribs?.map(({ who, what }) => ({who: toRef(who), what})); +} + +// Interface + +export const serializeDescriptors = Symbol(); + +export function serializeThing(thing) { + const descriptors = thing.constructor[serializeDescriptors]; + if (!descriptors) { + throw new Error(`Constructor ${thing.constructor.name} does not provide serialize descriptors`); + } + + return Object.fromEntries(Object.entries(descriptors) + .map(([ property, transform ]) => [property, transform(thing[property])])); +} + +export function serializeThings(things) { + return things.map(serializeThing); +} diff --git a/src/data/things.js b/src/data/things.js index 5889b119..2d199c10 100644 --- a/src/data/things.js +++ b/src/data/things.js @@ -28,6 +28,8 @@ import { validateReferenceList, } from './validators.js'; +import * as S from './serialize.js'; + import { getKebabCase, } from '../util/wiki-data.js'; @@ -508,6 +510,43 @@ Album.propertyDescriptors = { artTags: Thing.common.dynamicThingsFromReferenceList('artTagsByRef', 'artTagData', find.artTag), }; +Album[S.serializeDescriptors] = { + name: S.id, + color: S.id, + directory: S.id, + urls: S.id, + + date: S.id, + coverArtDate: S.id, + trackArtDate: S.id, + dateAddedToWiki: S.id, + + artistContribs: S.toContribRefs, + coverArtistContribs: S.toContribRefs, + trackCoverArtistContribs: S.toContribRefs, + wallpaperArtistContribs: S.toContribRefs, + bannerArtistContribs: S.toContribRefs, + + coverArtFileExtension: S.id, + trackCoverArtFileExtension: S.id, + wallpaperStyle: S.id, + wallpaperFileExtension: S.id, + bannerStyle: S.id, + bannerFileExtension: S.id, + bannerDimensions: S.id, + + hasTrackArt: S.id, + isMajorRelease: S.id, + isListedOnHomepage: S.id, + + commentary: S.id, + + tracks: S.toRefs, + groups: S.toRefs, + artTags: S.toRefs, + commentatorArtists: S.toRefs, +}; + TrackGroup.propertyDescriptors = { // Update & expose @@ -781,7 +820,7 @@ Track.prototype[inspect.custom] = function() { return (albumName ? base + ` (${color.yellow(trackNum)} in ${color.green(albumName)})` : base); -} +}; // -> Artist @@ -871,6 +910,7 @@ Artist.propertyDescriptors = { } }, + albumsAsAlbumArtist: Artist.filterByContrib('albumData', 'artistContribs'), albumsAsCoverArtist: Artist.filterByContrib('albumData', 'coverArtistContribs'), albumsAsWallpaperArtist: Artist.filterByContrib('albumData', 'wallpaperArtistContribs'), albumsAsBannerArtist: Artist.filterByContrib('albumData', 'bannerArtistContribs'), @@ -889,6 +929,31 @@ Artist.propertyDescriptors = { flashesAsContributor: Artist.filterByContrib('flashData', 'contributorContribs'), }; +Artist[S.serializeDescriptors] = { + name: S.id, + directory: S.id, + urls: S.id, + contextNotes: S.id, + + hasAvatar: S.id, + avatarFileExtension: S.id, + + aliasNames: S.id, + + tracksAsArtist: S.toRefs, + tracksAsContributor: S.toRefs, + tracksAsCoverArtist: S.toRefs, + tracksAsCommentator: S.toRefs, + + albumsAsAlbumArtist: S.toRefs, + albumsAsCoverArtist: S.toRefs, + albumsAsWallpaperArtist: S.toRefs, + albumsAsBannerArtist: S.toRefs, + albumsAsCommentator: S.toRefs, + + flashesAsContributor: S.toRefs, +}; + // -> Group Group.propertyDescriptors = { @@ -1202,6 +1267,17 @@ Flash.propertyDescriptors = { }, }; +Flash[S.serializeDescriptors] = { + name: S.id, + page: S.id, + directory: S.id, + date: S.id, + contributors: S.toContribRefs, + tracks: S.toRefs, + urls: S.id, + color: S.id, +}; + FlashAct.propertyDescriptors = { // Update & expose diff --git a/src/static/client.js b/src/static/client.js index c12ff355..7397735c 100644 --- a/src/static/client.js +++ b/src/static/client.js @@ -9,6 +9,10 @@ import { getColors } from '../util/colors.js'; +import { + getArtistNumContributions +} from '../util/wiki-data.js'; + let albumData, artistData, flashData; let officialAlbumData, fandomAlbumData, artistNames; @@ -137,7 +141,7 @@ for (const a of document.body.querySelectorAll('[data-random]')) { case 'track-in-fandom': return a.href = openTrack(getRefDirectory(pick(fandomAlbumData.reduce((acc, album) => acc.concat(album.tracks), [])))); case 'track-in-official': return a.href = openTrack(getRefDirectory(pick(officialAlbumData.reduce((acc, album) => acc.concat(album.tracks), [])))); case 'artist': return a.href = openArtist(pick(artistData).directory); - case 'artist-more-than-one-contrib': return a.href = openArtist(pick(artistData.filter(artist => C.getArtistNumContributions(artist) > 1)).directory); + case 'artist-more-than-one-contrib': return a.href = openArtist(pick(artistData.filter(artist => getArtistNumContributions(artist) > 1)).directory); } }); } diff --git a/src/upd8.js b/src/upd8.js index 0d5a3ecb..34e0466e 100755 --- a/src/upd8.js +++ b/src/upd8.js @@ -112,6 +112,8 @@ import { WikiInfo, } from './data/things.js'; +import { serializeThings } from './data/serialize.js'; + import { fancifyFlashURL, fancifyURL, @@ -1273,95 +1275,10 @@ function getDurationInSeconds(string) { } } -/* -const stringifyIndent = 0; - -const toRefs = (label, objectOrArray) => { - if (Array.isArray(objectOrArray)) { - return objectOrArray.filter(Boolean).map(x => `${label}:${x.directory}`); - } else if (objectOrArray.directory) { - throw new Error('toRefs should not be passed a single object with directory'); - } else if (typeof objectOrArray === 'object') { - return Object.fromEntries(Object.entries(objectOrArray) - .map(([ key, value ]) => [key, toRefs(key, value)])); - } else { - throw new Error('toRefs should be passed an array or object of arrays'); - } -}; - -function stringifyRefs(key, value) { - switch (key) { - case 'tracks': - case 'references': - case 'referencedBy': - return toRefs('track', value); - case 'artists': - case 'contributors': - case 'coverArtists': - case 'trackCoverArtists': - return value && value.map(({ who, what }) => ({who: `artist:${who.directory}`, what})); - case 'albums': return toRefs('album', value); - case 'flashes': return toRefs('flash', value); - case 'groups': return toRefs('group', value); - case 'artTags': return toRefs('tag', value); - case 'aka': return value && `track:${value.directory}`; - default: - return value; - } -} - -function stringifyAlbumData({wikiData}) { - return JSON.stringify(wikiData.albumData, (key, value) => { - switch (key) { - case 'commentary': - return ''; - default: - return stringifyRefs(key, value); - } - }, stringifyIndent); -} - -function stringifyTrackData({wikiData}) { - return JSON.stringify(wikiData.trackData, (key, value) => { - switch (key) { - case 'album': - case 'commentary': - case 'otherReleases': - return undefined; - default: - return stringifyRefs(key, value); - } - }, stringifyIndent); -} - -function stringifyFlashData({wikiData}) { - return JSON.stringify(wikiData.flashData, (key, value) => { - switch (key) { - case 'act': - case 'commentary': - return undefined; - default: - return stringifyRefs(key, value); - } - }, stringifyIndent); +function stringifyThings(thingData) { + return JSON.stringify(serializeThings(thingData)); } -function stringifyArtistData({wikiData}) { - return JSON.stringify(wikiData.artistData, (key, value) => { - switch (key) { - case 'asAny': - return; - case 'asArtist': - case 'asContributor': - case 'asCoverArtist': - return toRefs('track', value); - default: - return stringifyRefs(key, value); - } - }, stringifyIndent); -} -*/ - function img({ src, alt, @@ -1933,15 +1850,13 @@ function writeSharedFilesAndPages({strings, wikiData}) { wikiInfo.enableListings && redirect('Album Commentary', 'list/all-commentary', 'localized.commentaryIndex', ''), - /* writeFile(path.join(outputPath, 'data.json'), fixWS` { - "albumData": ${stringifyAlbumData({wikiData})}, - ${wikiInfo.enableFlashesAndGames && `"flashData": ${stringifyFlashData({wikiData})},`} - "artistData": ${stringifyArtistData({wikiData})} + "albumData": ${stringifyThings(wikiData.albumData)}, + ${wikiInfo.enableFlashesAndGames && `"flashData": ${stringifyThings(wikiData.flashData)},`} + "artistData": ${stringifyThings(wikiData.artistData)} } `) - */ ].filter(Boolean)); } diff --git a/src/util/wiki-data.js b/src/util/wiki-data.js index 870c0b0e..76018313 100644 --- a/src/util/wiki-data.js +++ b/src/util/wiki-data.js @@ -2,7 +2,7 @@ import { UNRELEASED_TRACKS_DIRECTORY -} from '../util/magic-constants.js'; +} from './magic-constants.js'; // Generic value operations -- cgit 1.3.0-6-gf8a5