« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/thing/group.js73
-rwxr-xr-xsrc/upd8.js61
2 files changed, 133 insertions, 1 deletions
diff --git a/src/thing/group.js b/src/thing/group.js
new file mode 100644
index 00000000..3b92e957
--- /dev/null
+++ b/src/thing/group.js
@@ -0,0 +1,73 @@
+import CacheableObject from './cacheable-object.js';
+import Thing from './thing.js';
+
+import {
+    isColor,
+    isDirectory,
+    isName,
+    isString,
+    isURL,
+    validateArrayItems,
+    validateReferenceList,
+} from './validators.js';
+
+export class GroupCategory extends CacheableObject {
+    static propertyDescriptors = {
+        // Update & expose
+
+        name: {
+            flags: {update: true, expose: true},
+            update: {default: 'Unnamed Group Category', validate: isName}
+        },
+
+        color: {
+            flags: {update: true, expose: true},
+            update: {validate: isColor}
+        },
+
+        groupsByRef: {
+            flags: {update: true, expose: true},
+            update: {validate: validateReferenceList('group')}
+        },
+    };
+}
+
+export default class Group extends Thing {
+    static [Thing.referenceType] = 'group';
+
+    static propertyDescriptors = {
+        // Update & expose
+
+        name: {
+            flags: {update: true, expose: true},
+            update: {default: 'Unnamed Group', validate: isName}
+        },
+
+        directory: {
+            flags: {update: true, expose: true},
+            update: {validate: isDirectory},
+            expose: Thing.directoryExpose
+        },
+
+        description: {
+            flags: {update: true, expose: true},
+            update: {validate: isString}
+        },
+
+        urls: {
+            flags: {update: true, expose: true},
+            update: {validate: validateArrayItems(isURL)}
+        },
+
+        // Expose only
+
+        descriptionShort: {
+            flags: {expose: true},
+
+            expose: {
+                dependencies: ['description'],
+                compute: ({ description }) => description.split('<hr class="split">')[0]
+            }
+        }
+    };
+}
diff --git a/src/upd8.js b/src/upd8.js
index f2777ec6..001aaa5f 100755
--- a/src/upd8.js
+++ b/src/upd8.js
@@ -94,6 +94,7 @@ import unbound_link, {getLinkThemeString} from './util/link.js';
 import Album, { TrackGroup } from './thing/album.js';
 import Artist from './thing/artist.js';
 import Flash, { FlashAct } from './thing/flash.js';
+import Group, { GroupCategory } from './thing/group.js';
 import Thing from './thing/thing.js';
 import Track from './thing/track.js';
 
@@ -202,7 +203,7 @@ const ARTIST_DATA_FILE = 'artists.yaml';
 const FLASH_DATA_FILE = 'flashes.yaml';
 const NEWS_DATA_FILE = 'news.txt';
 const TAG_DATA_FILE = 'tags.txt';
-const GROUP_DATA_FILE = 'groups.txt';
+const GROUP_DATA_FILE = 'groups.yaml';
 const STATIC_PAGE_DATA_FILE = 'static-pages.txt';
 const DEFAULT_STRINGS_FILE = 'strings-default.json';
 
@@ -1183,6 +1184,22 @@ async function processTagDataFile(file) {
     });
 }
 
+const processGroupDocument = makeProcessDocument(Group, {
+    propertyFieldMapping: {
+        name: 'Group',
+        directory: 'Directory',
+        description: 'Description',
+        urls: 'URLs',
+    }
+});
+
+const processGroupCategoryDocument = makeProcessDocument(GroupCategory, {
+    propertyFieldMapping: {
+        name: 'Category',
+        color: 'Color',
+    }
+});
+
 async function processGroupDataFile(file) {
     let contents;
     try {
@@ -2565,6 +2582,47 @@ async function main() {
                 wikiData.flashActData = results.filter(x => x instanceof FlashAct);
             }
         },
+
+        {
+            title: `Process group file`,
+            files: [path.join(dataPath, GROUP_DATA_FILE)],
+
+            documentMode: documentModes.allInOne,
+            processDocument(document) {
+                return ('Category' in document
+                    ? processGroupCategoryDocument(document)
+                    : processGroupDocument(document));
+            },
+
+            save(results) {
+                let groupCategory;
+                let groupsByRef = [];
+
+                if (results[0] && !(results[0] instanceof GroupCategory)) {
+                    throw new Error(`Expected a category at top of group data file`);
+                }
+
+                for (const thing of results) {
+                    if (thing instanceof GroupCategory) {
+                        if (groupCategory) {
+                            Object.assign(groupCategory, {groupsByRef});
+                        }
+
+                        groupCategory = thing;
+                        groupsByRef = [];
+                    } else {
+                        groupsByRef.push(Thing.getReference(thing));
+                    }
+                }
+
+                if (groupCategory) {
+                    Object.assign(groupCategory, {groupsByRef});
+                }
+
+                wikiData.groupData = results.filter(x => x instanceof Group);
+                wikiData.groupCategoryData = results.filter(x => x instanceof GroupCategory);
+            }
+        },
     ];
 
     const processDataAggregate = openAggregate({message: `Errors processing data files`});
@@ -2708,6 +2766,7 @@ async function main() {
             logInfo` - ${wikiData.artistData.length} artists`;
             if (wikiData.flashData)
                 logInfo` - ${wikiData.flashData.length} flashes (${wikiData.flashActData.length} acts)`;
+            logInfo` - ${wikiData.groupData.length} groups (${wikiData.groupCategoryData.length} categories)`;
         } catch (error) {
             console.error(`Error showing data summary:`, error);
         }