« get me outta code hell

search: first try at artist groups - 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:
author(quasar) nebula <qznebula@protonmail.com>2025-11-03 14:20:54 -0400
committer(quasar) nebula <qznebula@protonmail.com>2025-11-03 14:20:54 -0400
commita2a4b8b566114cecb2fd9d3d5a9e0351e521f0f9 (patch)
tree7dd777add5d1ec5715bc764c49df958ac0d24ce0 /src/search-select.js
parenta7337c4fcf988e3fc9015d3fc43895b6e516a25b (diff)
search: first try at artist groups
Diffstat (limited to 'src/search-select.js')
-rw-r--r--src/search-select.js50
1 files changed, 47 insertions, 3 deletions
diff --git a/src/search-select.js b/src/search-select.js
index 4d4ed63e..db347914 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,48 @@ function prepareArtwork(artwork, thing, {
   return serializeSrc;
 }
 
+function determineArtistGroups(artist, opts) {
+  const contributions = [
+    ...artist.musicContributions,
+    ...artist.artworkContributions,
+  ];
+
+  const contributionGroups =
+    contributions.flatMap(contrib => contrib.groups);
+
+  const artistNamesish =
+    unique(
+      [artist.name, ...artist.artistAliases.map(alias => alias.name)]
+        .map(name => getKebabCase(name)));
+
+  const interestingGroups =
+    unique(contributionGroups)
+      .filter(group => !artistNamesish.includes(getKebabCase(group.name)));
+
+  if (contributions.length < 50) {
+    return interestingGroups;
+  }
+
+  const dividingGroups =
+    opts.wikiInfo.divideTrackListsByGroups;
+
+  const scores =
+    new Map(interestingGroups.map(group => [group, 0]));
+
+  for (const group of contributionGroups) {
+    scores.set(group, scores.get(group) + 1 / contributions.length);
+  }
+
+  for (const group of interestingGroups) {
+    if (dividingGroups.includes(group)) continue;
+    if (scores.get(group) < 0.12) {
+      scores.delete(group);
+    }
+  }
+
+  return Array.from(scores.keys());
+}
+
 function baselineProcess(thing, _opts) {
   const fields = {};
 
@@ -173,9 +216,10 @@ function genericProcess(thing, opts) {
       ]);
 
   const groups =
-     thing.groups ??
-     thing.album?.groups ??
-     [];
+    (thing.isAlbum ? thing.groups
+   : thing.isTrack ? thing.album.groups
+   : thing.isArtist ? determineArtistGroups(thing, opts)
+   : []);
 
   const mainContributorNames =
     contributions