From 5408d6660b22b9ddee8c4a297c89fca92ae2d505 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 3 Jul 2023 23:12:03 -0300 Subject: content: listArtistsBy{CommentaryEntries,Name} + syntax changes --- src/content/dependencies/listAlbumsByDuration.js | 20 +++---- src/content/dependencies/listAlbumsByTracks.js | 20 +++---- .../dependencies/listArtistsByCommentaryEntries.js | 55 +++++++++++++++++ .../dependencies/listArtistsByContributions.js | 68 ++++++++++++---------- src/content/dependencies/listArtistsByName.js | 55 +++++++++++++++++ src/listing-spec.js | 34 +---------- src/util/wiki-data.js | 39 +++++++++++++ 7 files changed, 203 insertions(+), 88 deletions(-) create mode 100644 src/content/dependencies/listArtistsByCommentaryEntries.js create mode 100644 src/content/dependencies/listArtistsByName.js diff --git a/src/content/dependencies/listAlbumsByDuration.js b/src/content/dependencies/listAlbumsByDuration.js index e922ebc9..650a5d1e 100644 --- a/src/content/dependencies/listAlbumsByDuration.js +++ b/src/content/dependencies/listAlbumsByDuration.js @@ -1,5 +1,5 @@ import {stitchArrays} from '../../util/sugar.js'; -import {getTotalDuration} from '../../util/wiki-data.js'; +import {filterByCount, getTotalDuration, sortByCount} from '../../util/wiki-data.js'; export default { contentDependencies: ['generateListingPage', 'linkAlbum'], @@ -10,17 +10,13 @@ export default { }, query({albumData}, spec) { - const albumToDuration = - new Map(albumData.map(album => [album, getTotalDuration(album.tracks)])); + const albums = albumData.slice(); + const durations = albums.map(album => getTotalDuration(album.tracks)); - return { - spec, + filterByCount(albums, durations); + sortByCount(albums, durations, {greatestFirst: true}); - albums: - albumData - .filter(album => albumToDuration.get(album) > 0) - .sort((a, b) => albumToDuration.get(b) - albumToDuration.get(a)), - }; + return {spec, albums, durations}; }, relations(relation, query) { @@ -35,9 +31,7 @@ export default { data(query) { return { - durations: - query.albums - .map(album => getTotalDuration(album.tracks)), + durations: query.durations, }; }, diff --git a/src/content/dependencies/listAlbumsByTracks.js b/src/content/dependencies/listAlbumsByTracks.js index acec5da4..c31609bd 100644 --- a/src/content/dependencies/listAlbumsByTracks.js +++ b/src/content/dependencies/listAlbumsByTracks.js @@ -1,4 +1,5 @@ -import {empty, stitchArrays} from '../../util/sugar.js'; +import {stitchArrays} from '../../util/sugar.js'; +import {filterByCount, sortByCount} from '../../util/wiki-data.js'; export default { contentDependencies: ['generateListingPage', 'linkAlbum'], @@ -9,14 +10,13 @@ export default { }, query({albumData}, spec) { - return { - spec, + const albums = albumData.slice(); + const counts = albums.map(album => album.tracks.length); - albums: - albumData - .filter(album => !empty(album.tracks)) - .sort((a, b) => b.tracks.length - a.tracks.length), - }; + filterByCount(albums, counts); + sortByCount(albums, counts, {greatestFirst: true}); + + return {spec, albums, counts}; }, relations(relation, query) { @@ -31,9 +31,7 @@ export default { data(query) { return { - counts: - query.albums - .map(album => album.tracks.length), + counts: query.counts, }; }, diff --git a/src/content/dependencies/listArtistsByCommentaryEntries.js b/src/content/dependencies/listArtistsByCommentaryEntries.js new file mode 100644 index 00000000..eae6dd6e --- /dev/null +++ b/src/content/dependencies/listArtistsByCommentaryEntries.js @@ -0,0 +1,55 @@ +import {stitchArrays} from '../../util/sugar.js'; +import {filterByCount, sortByCount} from '../../util/wiki-data.js'; + +export default { + contentDependencies: ['generateListingPage', 'linkArtist'], + extraDependencies: ['language', 'wikiData'], + + sprawl({artistData}) { + return {artistData}; + }, + + query({artistData}, spec) { + const artists = artistData.slice(); + const counts = + artists.map(artist => + artist.tracksAsCommentator.length + + artist.albumsAsCommentator.length); + + filterByCount(artists, counts); + sortByCount(artists, counts, {greatestFirst: true}); + + return {artists, counts, spec}; + }, + + relations(relation, query) { + return { + page: + relation('generateListingPage', query.spec), + + artistLinks: + query.artists + .map(artist => relation('linkArtist', artist)), + }; + }, + + data(query) { + return { + counts: query.counts, + }; + }, + + generate(data, relations, {language}) { + return relations.page.slots({ + type: 'rows', + rows: + stitchArrays({ + link: relations.artistLinks, + count: data.counts, + }).map(({link, count}) => ({ + artist: link, + entries: language.countCommentaryEntries(count, {unit: true}), + })), + }); + }, +}; diff --git a/src/content/dependencies/listArtistsByContributions.js b/src/content/dependencies/listArtistsByContributions.js index 78c8c1aa..ae00fc63 100644 --- a/src/content/dependencies/listArtistsByContributions.js +++ b/src/content/dependencies/listArtistsByContributions.js @@ -1,4 +1,5 @@ import {stitchArrays, unique} from '../../util/sugar.js'; +import {filterByCount, sortByCount} from '../../util/wiki-data.js'; export default { contentDependencies: ['generateListingPage', 'linkArtist'], @@ -12,34 +13,45 @@ export default { }, query(sprawl, spec) { - const query = {spec}; + const query = { + spec, + enableFlashesAndGames: sprawl.enableFlashesAndGames, + }; + + const queryContributionInfo = (artistsKey, countsKey, fn) => { + const artists = sprawl.artistData.slice(); + const counts = artists.map(artist => fn(artist)); - const queryContributionInfo = fn => - sprawl.artistData - .map(artist => ({artist, contributions: fn(artist)})) - .filter(({contributions}) => contributions) - .sort((a, b) => b.contributions - a.contributions); + filterByCount(artists, counts); + sortByCount(artists, counts, {greatestFirst: true}); - query.enableFlashesAndGames = - sprawl.enableFlashesAndGames; + query[artistsKey] = artists; + query[countsKey] = counts; + }; - query.trackContributionInfo = - queryContributionInfo(artist => + queryContributionInfo( + 'artistsByTrackContributions', + 'countsByTrackContributions', + artist => unique([ ...artist.tracksAsContributor, ...artist.tracksAsArtist, ]).length); - query.artworkContributionInfo = - queryContributionInfo(artist => + queryContributionInfo( + 'artistsByArtworkContributions', + 'countsByArtworkContributions', + artist => artist.tracksAsCoverArtist.length + artist.albumsAsCoverArtist.length + artist.albumsAsWallpaperArtist.length + artist.albumsAsBannerArtist.length); if (sprawl.enableFlashesAndGames) { - query.flashContributionInfo = - queryContributionInfo(artist => + queryContributionInfo( + 'artistsByFlashContributions', + 'countsByFlashContributions', + artist => artist.flashesAsContributor.length); } @@ -53,17 +65,17 @@ export default { relation('generateListingPage', query.spec); relations.artistLinksByTrackContributions = - query.trackContributionInfo - .map(({artist}) => relation('linkArtist', artist)); + query.artistsByTrackContributions + .map(artist => relation('linkArtist', artist)); relations.artistLinksByArtworkContributions = - query.artworkContributionInfo - .map(({artist}) => relation('linkArtist', artist)); + query.artistsByArtworkContributions + .map(artist => relation('linkArtist', artist)); if (query.enableFlashesAndGames) { relations.artistLinksByFlashContributions = - query.flashContributionInfo - .map(({artist}) => relation('linkArtist', artist)); + query.artistsByFlashContributions + .map(artist => relation('linkArtist', artist)); } return relations; @@ -72,21 +84,13 @@ export default { data(query) { const data = {}; - data.enableFlashesAndGames = - query.enableFlashesAndGames; - - data.countsByTrackContributions = - query.trackContributionInfo - .map(({contributions}) => contributions); + data.enableFlashesAndGames = query.enableFlashesAndGames; - data.countsByArtworkContributions = - query.artworkContributionInfo - .map(({contributions}) => contributions); + data.countsByTrackContributions = query.countsByTrackContributions; + data.countsByArtworkContributions = query.countsByArtworkContributions; if (query.enableFlashesAndGames) { - data.countsByFlashContributions = - query.flashContributionInfo - .map(({contributions}) => contributions); + data.countsByFlashContributions = query.countsByFlashContributions; } return data; diff --git a/src/content/dependencies/listArtistsByName.js b/src/content/dependencies/listArtistsByName.js new file mode 100644 index 00000000..1b93eca8 --- /dev/null +++ b/src/content/dependencies/listArtistsByName.js @@ -0,0 +1,55 @@ +import {stitchArrays} from '../../util/sugar.js'; + +import { + getArtistNumContributions, + sortAlphabetically, +} from '../../util/wiki-data.js'; + +export default { + contentDependencies: ['generateListingPage', 'linkArtist'], + extraDependencies: ['language', 'wikiData'], + + sprawl({artistData}) { + return {artistData}; + }, + + query({artistData}, spec) { + return { + spec, + + artists: sortAlphabetically(artistData.slice()), + }; + }, + + relations(relation, query) { + return { + page: relation('generateListingPage', query.spec), + + artistLinks: + query.artists + .map(album => relation('linkArtist', album)), + }; + }, + + data(query) { + return { + counts: + query.artists + .map(artist => getArtistNumContributions(artist)), + }; + }, + + generate(data, relations, {language}) { + return relations.page.slots({ + type: 'rows', + rows: + stitchArrays({ + link: relations.artistLinks, + count: data.counts, + }).map(({link, count}) => ({ + artist: link, + contributions: language.countContributions(count, {unit: true}), + })), + }); + }, +}; diff --git a/src/listing-spec.js b/src/listing-spec.js index f0f2c8e8..1b0fe978 100644 --- a/src/listing-spec.js +++ b/src/listing-spec.js @@ -59,21 +59,7 @@ listingSpec.push({ listingSpec.push({ directory: 'artists/by-name', stringsKey: 'listArtists.byName', - - data: ({wikiData: {artistData}}) => - sortAlphabetically(artistData.slice()) - .map(artist => ({ - artist, - contributions: getArtistNumContributions(artist), - })), - - row: ({artist, contributions}, {language, link}) => - language.$('listingPage.listArtists.byName.item', { - artist: link.artist(artist), - contributions: language.countContributions(contributions, { - unit: true, - }), - }), + contentFunction: 'listArtistsByName', }); listingSpec.push({ @@ -85,23 +71,7 @@ listingSpec.push({ listingSpec.push({ directory: 'artists/by-commentary', stringsKey: 'listArtists.byCommentary', - - data: ({wikiData: {artistData}}) => - artistData - .map(artist => ({ - artist, - entries: - artist.tracksAsCommentator.length + - artist.albumsAsCommentator.length, - })) - .filter(({entries}) => entries) - .sort((a, b) => b.entries - a.entries), - - row: ({artist, entries}, {language, link}) => - language.$('listingPage.listArtists.byCommentary.item', { - artist: link.artist(artist), - entries: language.countCommentaryEntries(entries, {unit: true}), - }), + contentFunction: 'listArtistsByCommentaryEntries', }); listingSpec.push({ diff --git a/src/util/wiki-data.js b/src/util/wiki-data.js index da8312f9..0ee474a7 100644 --- a/src/util/wiki-data.js +++ b/src/util/wiki-data.js @@ -3,6 +3,7 @@ import { accumulateSum, empty, + stitchArrays, unique, } from './sugar.js'; @@ -208,6 +209,44 @@ export function sortByDate(data, { }); } +// Funky sort which takes a data set and a corresponding list of "counts", +// which are really arbitrary numbers representing some property of each data +// object defined by the caller. It sorts and mutates *both* of these, so the +// sorted data will still correspond to the same indexed count. +export function sortByCount(data, counts, { + greatestFirst = false, +} = {}) { + const thingToCount = new Map( + stitchArrays({thing: data, count: counts}) + .map(({thing, count}) => [thing, count])); + + data.sort((a, b) => + (greatestFirst + ? thingToCount.get(b) - thingToCount.get(a) + : thingToCount.get(a) - thingToCount.get(b))); + + counts.sort((a, b) => + (greatestFirst + ? b - a + : a - b)); + + return data; +} + +// Corresponding filter function for the above sort. By default, items whose +// corresponding count is zero will be removed. +export function filterByCount(data, counts, { + min = 1, + max = Infinity, +} = {}) { + for (let i = counts.length - 1; i >= 0; i--) { + if (counts[i] < min || counts[i] > max) { + data.splice(i, 1); + counts.splice(i, 1); + } + } +} + export function sortByPositionInParent(data, { getParent, getChildren, -- cgit 1.3.0-6-gf8a5