From 75505899c70594e250bdcb582fd2f5c40a971639 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 4 Mar 2024 20:27:24 -0400 Subject: data: WikiInfo: contributionPresets --- src/data/things/wiki-info.js | 21 +++++++++++++- src/data/validators.js | 52 ++++++++++++++++++++++++++++++++++ src/data/yaml.js | 67 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+), 1 deletion(-) (limited to 'src/data') diff --git a/src/data/things/wiki-info.js b/src/data/things/wiki-info.js index 2a2c9986..b7b7b01c 100644 --- a/src/data/things/wiki-info.js +++ b/src/data/things/wiki-info.js @@ -3,7 +3,16 @@ export const WIKI_INFO_FILE = 'wiki-info.yaml'; import {input} from '#composite'; import find from '#find'; import Thing from '#thing'; -import {isBoolean, isColor, isLanguageCode, isName, isURL} from '#validators'; +import {parseContributionPresets} from '#yaml'; + +import { + isBoolean, + isColor, + isContributionPresetList, + isLanguageCode, + isName, + isURL, +} from '#validators'; import {exitWithoutDependency} from '#composite/control-flow'; import {contentString, flag, name, referenceList, wikiData} @@ -58,6 +67,11 @@ export class WikiInfo extends Thing { data: 'groupData', }), + contributionPresets: { + flags: {update: true, expose: true}, + update: {validate: isContributionPresetList}, + }, + // Feature toggles enableFlashesAndGames: flag(false), enableListings: flag(false), @@ -105,6 +119,11 @@ export class WikiInfo extends Thing { 'Enable News': {property: 'enableNews'}, 'Enable Art Tag UI': {property: 'enableArtTagUI'}, 'Enable Group UI': {property: 'enableGroupUI'}, + + 'Contribution Presets': { + property: 'contributionPresets', + transform: parseContributionPresets, + }, }, }; diff --git a/src/data/validators.js b/src/data/validators.js index 5d681311..0f1d2e62 100644 --- a/src/data/validators.js +++ b/src/data/validators.js @@ -640,6 +640,58 @@ export const isContribution = validateProperties({ export const isContributionList = validateArrayItems(isContribution); +export const contributionPresetPropertySpec = { + album: [ + 'artistContribs', + ], + + flash: [ + 'contributorContribs', + ], + + track: [ + 'artistContribs', + 'contributorContribs', + ], +}; + +// TODO: This validator basically constructs itself as it goes. +// This is definitely some shenanigans! +export function isContributionPresetContext(list) { + isArray(list); + + if (empty(list)) { + throw new TypeError(`Expected at least one item`); + } + + const isTarget = + is(...Object.keys(contributionPresetPropertySpec)); + + const [target, ...properties] = list; + + isTarget(target); + + const isProperty = + is(...contributionPresetPropertySpec[target]); + + const isPropertyList = + validateArrayItems(isProperty); + + isPropertyList(properties); + + return true; +} + +export const isContributionPreset = validateProperties({ + annotation: isStringNonEmpty, + context: isContributionPresetContext, + + countInDurationTotals: optional(isBoolean), + countInContributionTotals: optional(isBoolean), +}); + +export const isContributionPresetList = validateArrayItems(isContributionPreset); + export const isAdditionalFile = validateProperties({ title: isName, description: optional(isContentString), diff --git a/src/data/yaml.js b/src/data/yaml.js index 7e470531..d3c77b9e 100644 --- a/src/data/yaml.js +++ b/src/data/yaml.js @@ -482,6 +482,73 @@ export function parseDimensions(string) { return nums; } +export const contributionPresetYAMLSpec = [ + {from: 'Album', to: 'album', fields: [ + {from: 'Artists', to: 'artistContribs'}, + ]}, + + {from: 'Flash', to: 'flash', fields: [ + {from: 'Contributors', to: 'contributorContribs'}, + ]}, + + {from: 'Track', to: 'track', fields: [ + {from: 'Artists', to: 'artistContribs'}, + {from: 'Contributors', to: 'contributorContribs'}, + ]}, +]; + +export function parseContributionPresetContext(context) { + if (!Array.isArray(context)) { + return context; + } + + const [target, ...fields] = context; + + const targetEntry = + contributionPresetYAMLSpec + .find(({from}) => from === target); + + if (!targetEntry) { + return context; + } + + const properties = + fields.map(field => { + const fieldEntry = + targetEntry.fields + .find(({from}) => from === field); + + if (!fieldEntry) return field; + + return fieldEntry.to; + }); + + return [targetEntry.to, ...properties]; +} + +export function parseContributionPresets(list) { + if (!Array.isArray(list)) return list; + + return list.map(item => { + if (typeof item !== 'object') return item; + + return { + annotation: + item['Annotation'] ?? null, + + context: + parseContributionPresetContext( + item['Context'] ?? null), + + countInContributionTotals: + item['Count In Contribution Totals'] ?? null, + + countInDurationTotals: + item['Count In Duration Totals'] ?? null, + }; + }); +} + // documentModes: Symbols indicating sets of behavior for loading and processing // data files. export const documentModes = { -- cgit 1.3.0-6-gf8a5