« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/search-select.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/search-select.js')
-rw-r--r--src/search-select.js91
1 files changed, 68 insertions, 23 deletions
diff --git a/src/search-select.js b/src/search-select.js
index 24532cbb..36b9e98a 100644
--- a/src/search-select.js
+++ b/src/search-select.js
@@ -3,6 +3,7 @@
 // These files totally go together, so read them side by side, okay?
 
 import baseSearchSpec from '#search-shape';
+import {unique} from '#sugar';
 import {getKebabCase} from '#wiki-data';
 
 function prepareArtwork(artwork, thing, {
@@ -52,6 +53,58 @@ function prepareArtwork(artwork, thing, {
   return serializeSrc;
 }
 
+function determineArtistGroups(artist, opts) {
+  const contributions = [
+    artist.musicContributions,
+    artist.artworkContributions
+      .filter(contrib => !contrib.annotation?.includes('edits for wiki')),
+  ].flat();
+
+  const contributionGroups =
+    contributions.flatMap(contrib => contrib.groups);
+
+  const scores =
+    new Map(
+      unique(contributionGroups).map(group => [group, 0]));
+
+  const artistNamesish =
+    unique(
+      [artist.name, ...artist.artistAliases.map(alias => alias.name)]
+        .map(name => getKebabCase(name)));
+
+  for (const group of scores.keys()) {
+    if (artistNamesish.includes(getKebabCase(group.name))) {
+      scores.delete(group);
+    }
+  }
+
+  for (const group of contributionGroups) {
+    scores.set(group, scores.get(group) + 1 / contributions.length);
+  }
+
+  const dividingGroups =
+    opts.wikiInfo.divideTrackListsByGroups;
+
+  const dividingGroupThreshold =
+    (contributions.length < 50 ? 0.08 : 0.16);
+
+  const generalGroupThreshold =
+    (contributions.length < 50 ? 0.00 : 0.12);
+
+  for (const group of scores.keys()) {
+    const threshold =
+      (dividingGroups.includes(group)
+        ? dividingGroupThreshold
+        : generalGroupThreshold);
+
+    if (scores.get(group) < threshold) {
+      scores.delete(group);
+    }
+  }
+
+  return Array.from(scores.keys());
+}
+
 function baselineProcess(thing, _opts) {
   const fields = {};
 
@@ -116,30 +169,24 @@ function genericSelect(wikiData) {
 function genericProcess(thing, opts) {
   const fields = baselineProcess(thing, opts);
 
-  const kind =
-    thing.constructor[Symbol.for('Thing.referenceType')];
-
   const boundPrepareArtwork = artwork =>
     prepareArtwork(artwork, thing, opts);
 
   fields.artwork =
-    (kind === 'track' && thing.hasUniqueCoverArt
+    (thing.isTrack && thing.hasUniqueCoverArt
       ? boundPrepareArtwork(thing.trackArtworks[0])
-   : kind === 'track'
+   : thing.isTrack
       ? boundPrepareArtwork(thing.album.coverArtworks[0])
-   : kind === 'album'
+   : thing.isAlbum
       ? boundPrepareArtwork(thing.coverArtworks[0])
-   : kind === 'flash'
+   : thing.isFlash
       ? boundPrepareArtwork(thing.coverArtwork)
       : null);
 
   fields.parentName =
-    (kind === 'track'
-      ? thing.album.name
-   : kind === 'group'
-      ? thing.category.name
-   : kind === 'flash'
-      ? thing.act.name
+    (thing.isTrack ? thing.album.name
+   : thing.isGroup ? thing.category.name
+   : thing.isFlash ? thing.act.name
       : null);
 
   fields.disambiguator =
@@ -147,9 +194,9 @@ function genericProcess(thing, opts) {
 
   fields.artTags =
     (Array.from(new Set(
-      (kind === 'track'
+      (thing.isTrack
         ? thing.trackArtworks.flatMap(artwork => artwork.artTags)
-     : kind === 'album'
+     : thing.isAlbum
         ? thing.coverArtworks.flatMap(artwork => artwork.artTags)
         : []))))
 
@@ -169,22 +216,20 @@ function genericProcess(thing, opts) {
 
   const contributions =
     contribKeys
-      .filter(key => Object.hasOwn(thing, key))
-      .flatMap(key => thing[key]);
+      .flatMap(key => thing[key] ?? []);
 
   fields.contributors =
     contributions
       .flatMap(({artist}) => [
         artist.name,
-        ...artist.aliasNames,
+        ...artist.artistAliases.map(alias => alias.name),
       ]);
 
   const groups =
-     (Object.hasOwn(thing, 'groups')
-       ? thing.groups
-    : Object.hasOwn(thing, 'album')
-       ? thing.album.groups
-       : []);
+    (thing.isAlbum ? thing.groups
+   : thing.isTrack ? thing.album.groups
+   : thing.isArtist ? determineArtistGroups(thing, opts)
+   : []);
 
   const mainContributorNames =
     contributions