diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/thing/static-page.js | 2 | ||||
-rw-r--r-- | src/thing/validators.js | 9 | ||||
-rw-r--r-- | src/thing/wiki-info.js | 90 | ||||
-rwxr-xr-x | src/upd8.js | 132 |
4 files changed, 159 insertions, 74 deletions
diff --git a/src/thing/static-page.js b/src/thing/static-page.js index 18e9d142..e2b51507 100644 --- a/src/thing/static-page.js +++ b/src/thing/static-page.js @@ -15,7 +15,7 @@ export default class StaticPage extends Thing { name: { flags: {update: true, expose: true}, - update: {validate: isName} + update: {validate: isName, default: 'Unnamed Static Page'} }, nameShort: { diff --git a/src/thing/validators.js b/src/thing/validators.js index 49463473..1bc7fd72 100644 --- a/src/thing/validators.js +++ b/src/thing/validators.js @@ -241,6 +241,15 @@ export function isFileExtension(string) { return true; } +export function isLanguageCode(string) { + // TODO: This is a stub function because really we don't need a detailed + // is-language-code parser right now. + + isString(string); + + return true; +} + export function isName(name) { return isString(name); } diff --git a/src/thing/wiki-info.js b/src/thing/wiki-info.js new file mode 100644 index 00000000..b805bf76 --- /dev/null +++ b/src/thing/wiki-info.js @@ -0,0 +1,90 @@ +import CacheableObject from './cacheable-object.js'; + +import { + isBoolean, + isColor, + isLanguageCode, + isName, + isString, + isURL, +} from './validators.js'; + +export default class WikiInfo extends CacheableObject { + static propertyDescriptors = { + // Update & expose + + name: { + flags: {update: true, expose: true}, + update: {validate: isName, default: 'Unnamed Wiki'} + }, + + // Displayed in nav bar. + shortName: { + flags: {update: true, expose: true}, + update: {validate: isName}, + + expose: { + dependencies: ['name'], + transform: (value, { name }) => value ?? name + } + }, + + color: { + flags: {update: true, expose: true}, + update: {validate: isColor} + }, + + // One-line description used for <meta rel="description"> tag. + description: { + flags: {update: true, expose: true}, + update: {validate: isString} + }, + + footerContent: { + flags: {update: true, expose: true}, + update: {validate: isString} + }, + + defaultLanguage: { + flags: {update: true, expose: true}, + update: {validate: isLanguageCode} + }, + + canonicalBase: { + flags: {update: true, expose: true}, + update: {validate: isURL} + }, + + // Feature toggles + + enableArtistAvatars: { + flags: {update: true, expose: true}, + update: {validate: isBoolean, default: false} + }, + + enableFlashesAndGames: { + flags: {update: true, expose: true}, + update: {validate: isBoolean, default: false} + }, + + enableListings: { + flags: {update: true, expose: true}, + update: {validate: isBoolean, default: false} + }, + + enableNews: { + flags: {update: true, expose: true}, + update: {validate: isBoolean, default: false} + }, + + enableArtTagUI: { + flags: {update: true, expose: true}, + update: {validate: isBoolean, default: false} + }, + + enableGroupUI: { + flags: {update: true, expose: true}, + update: {validate: isBoolean, default: false} + }, + }; +} diff --git a/src/upd8.js b/src/upd8.js index e9c582cd..ae69a7d9 100755 --- a/src/upd8.js +++ b/src/upd8.js @@ -103,6 +103,7 @@ import NewsEntry from './thing/news-entry.js'; import StaticPage from './thing/static-page.js'; import Thing from './thing/thing.js'; import Track from './thing/track.js'; +import WikiInfo from './thing/wiki-info.js'; import { fancifyFlashURL, @@ -202,8 +203,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); const CACHEBUST = 7; -// MAKE THESE END IN YAML -const WIKI_INFO_FILE = 'wiki-info.txt'; +const WIKI_INFO_FILE = 'wiki-info.yaml'; const HOMEPAGE_LAYOUT_DATA_FILE = 'homepage.yaml'; const ARTIST_DATA_FILE = 'artists.yaml'; const FLASH_DATA_FILE = 'flashes.yaml'; @@ -1250,71 +1250,23 @@ async function processStaticPageDataFile(file) { }); } -async function processWikiInfoFile(file) { - let contents; - try { - contents = await readFile(file, 'utf-8'); - } catch (error) { - return {error: `Could not read ${file} (${error.code}).`}; - } - - // Unlike other data files, the site info data file isn't 8roken up into - // more than one entry. So we operate on the plain old contentLines array, - // rather than dividing into sections like we usually do! - const contentLines = splitLines(contents); - - const name = getBasicField(contentLines, 'Name'); - if (!name) { - return {error: 'Expected "Name" field!'}; +const processWikiInfoDocument = makeProcessDocument(WikiInfo, { + propertyFieldMapping: { + name: 'Name', + shortName: 'Short Name', + color: 'Color', + description: 'Description', + footerContent: 'Footer Content', + defaultLanguage: 'Default Language', + canonicalBase: 'Canonical Base', + enableArtistAvatars: 'Enable Artist Avatars', + enableFlashesAndGames: 'Enable Flashes & Games', + enableListings: 'Enable Listings', + enableNews: 'Enable News', + enableArtTagUI: 'Enable Art Tag UI', + enableGroupUI: 'Enable Group UI', } - - const shortName = getBasicField(contentLines, 'Short Name') || name; - - const color = getBasicField(contentLines, 'Color') || '#0088ff'; - - // This is optional! Without it, <meta rel="canonical"> tags won't 8e - // gener8ted. - const canonicalBase = getBasicField(contentLines, 'Canonical Base'); - - // This is optional! Without it, the site will default to 8uilding in - // English. (This is only really relevant if you've provided string files - // for non-English languages.) - const defaultLanguage = getBasicField(contentLines, 'Default Language'); - - // Also optional! In charge of <meta rel="description">. - const description = getBasicField(contentLines, 'Description'); - - const footer = getMultilineField(contentLines, 'Footer') || ''; - - // We've had a comment lying around for ages, just reading: - // "Might ena8le this later... we'll see! Eventually. May8e." - // We still haven't! 8ut hey, the option's here. - const enableArtistAvatars = getBooleanField(contentLines, 'Enable Artist Avatars') ?? false; - - const enableFlashesAndGames = getBooleanField(contentLines, 'Enable Flashes & Games') ?? false; - const enableListings = getBooleanField(contentLines, 'Enable Listings') ?? false; - const enableNews = getBooleanField(contentLines, 'Enable News') ?? false; - const enableArtTagUI = getBooleanField(contentLines, 'Enable Art Tag UI') ?? false; - const enableGroupUI = getBooleanField(contentLines, 'Enable Group UI') ?? false; - - return { - name, - shortName, - color, - canonicalBase, - defaultLanguage, - description, - footer, - features: { - artistAvatars: enableArtistAvatars, - flashesAndGames: enableFlashesAndGames, - listings: enableListings, - news: enableNews, - artTagUI: enableArtTagUI, - groupUI: enableGroupUI - } - }; -} +}); const processHomepageLayoutDocument = makeProcessDocument(HomepageLayout, { propertyFieldMapping: { @@ -2303,12 +2255,6 @@ async function main() { } /* - WD.wikiInfo = await processWikiInfoFile(path.join(dataPath, WIKI_INFO_FILE)); - if (WD.wikiInfo.error) { - console.log(`\x1b[31;1m${WD.wikiInfo.error}\x1b[0m`); - 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. @@ -2363,6 +2309,22 @@ async function main() { const dataSteps = [ { + title: `Process wiki info file`, + files: [path.join(dataPath, WIKI_INFO_FILE)], + + documentMode: documentModes.onePerFile, + processDocument: processWikiInfoDocument, + + save(results) { + if (!results[0]) { + return; + } + + wikiData.wikiInfo = results[0]; + } + }, + + { title: `Process album files`, files: albumDataFiles, @@ -2720,7 +2682,29 @@ async function main() { } if (documentMode === documentModes.onePerFile) { - throw new Error('TODO: onePerFile not yet implemented'); + nest({message: `Errors processing data files as valid documents`}, ({ call, map }) => { + processResults = []; + + yamlResults.forEach(({ file, documents }) => { + if (documents.length > 1) { + call(decorateErrorWithFile(() => { + throw new Error(`Only expected one document to be present per file`); + })); + return; + } + + const result = call( + decorateErrorWithFile( + ({ document }) => dataStep.processDocument(document)), + {file, document: documents[0]}); + + if (!result) { + return; + } + + processResults.push(result); + }); + }); } dataStep.save(processResults); @@ -2742,6 +2726,8 @@ async function main() { logInfo` - ${wikiData.staticPageData.length} static pages`; if (wikiData.homepageLayout) logInfo` - ${1} homepage layout (${wikiData.homepageLayout.rows.length} rows)`; + if (wikiData.wikiInfo) + logInfo` - ${1} wiki config file`; } catch (error) { console.error(`Error showing data summary:`, error); } |