Refactor collection stats to beforeInclude
This commit is contained in:
parent
8b8eb09372
commit
5cda6a1687
7 changed files with 166 additions and 108 deletions
|
@ -8,19 +8,6 @@ const pugSync = sync.require("../pug-sync")
|
|||
/** @type {import("./load-tags")} */
|
||||
const loadTags = sync.require("./load-tags")
|
||||
|
||||
const currencyExchange = new Map([
|
||||
["AUD", 0.63],
|
||||
["BRL", 0.17],
|
||||
["CAD", 0.7],
|
||||
["CHF", 1.13],
|
||||
["EUR", 1.08],
|
||||
["GBP", 1.3],
|
||||
["JPY", 0.0067],
|
||||
["NOK", 0.1],
|
||||
["NZD", 0.57],
|
||||
["USD", 1],
|
||||
])
|
||||
|
||||
const sqls = {
|
||||
album_grid: "SELECT item.*, count(*) AS track_count, iif(sum(duration) > 3600, cast(total(duration)/3600 AS INTEGER) || 'h ' || cast(total(duration)/60%60 AS INTEGER) || 'm', cast(total(duration)/60 AS INTEGER) || 'm') AS total_duration FROM item INNER JOIN track USING (account, item_id) {JOIN TAG} WHERE account = ? {WHERE} GROUP BY item_id {ORDER}",
|
||||
album_list: "SELECT item.*, count(*) AS track_count, iif(sum(duration) > 3600, cast(total(duration)/3600 AS INTEGER) || 'h ' || cast(total(duration)/60%60 AS INTEGER) || 'm', cast(total(duration)/60 AS INTEGER) || 'm') AS total_duration FROM item INNER JOIN track USING (account, item_id) {JOIN TAG} WHERE account = ? {WHERE} GROUP BY item_id ORDER BY band_url, band_name COLLATE NOCASE, item_title COLLATE NOCASE",
|
||||
|
@ -150,33 +137,10 @@ router.get("/:account/", defineEventHandler({
|
|||
throw e
|
||||
}
|
||||
|
||||
let displayCurrency = getCookie(event, "bcex-currency") || ""
|
||||
if (!currencyExchange.has(displayCurrency)) displayCurrency = "NZD"
|
||||
const currencyRoundTo = displayCurrency === "JPY" ? 1000 : 10
|
||||
|
||||
const locals = {
|
||||
items,
|
||||
account,
|
||||
query,
|
||||
count: {
|
||||
total: db.prepare("SELECT count(*) FROM item WHERE account = ?").pluck().get(account),
|
||||
runtime: db.prepare("SELECT iif(sum(duration) > 86400, cast(total(duration)/86400 AS INTEGER) || 'd ' || cast(total(duration)/3600%24 AS INTEGER) || 'h', cast(total(duration)/3600 AS INTEGER) || 'h') FROM track WHERE account = ?").pluck().get(account),
|
||||
albums: db.prepare("SELECT count(*) FROM item WHERE item_type = 'album' AND account = ?").pluck().get(account),
|
||||
singles: db.prepare("SELECT count(*) FROM item WHERE item_type = 'track' AND account = ?").pluck().get(account),
|
||||
free: db.prepare("SELECT count(*) FROM item WHERE price = 0 AND account = ?").pluck().get(account),
|
||||
paid: db.prepare("SELECT count(*) FROM item WHERE price > 0 AND account = ?").pluck().get(account),
|
||||
tracks: db.prepare("SELECT count(*) FROM track WHERE account = ?").pluck().get(account),
|
||||
avgTracks: Math.round(db.prepare("SELECT avg(count) FROM (SELECT count(*) AS count FROM track INNER JOIN item USING (account, item_id) WHERE item_type = 'album' AND account = ? GROUP BY item_id)").pluck().get(account)*10)/10,
|
||||
tags: db.prepare("SELECT count(*) FROM item_tag WHERE account = ?").pluck().get(account),
|
||||
avgTags: Math.round(db.prepare("SELECT avg(count) FROM (SELECT count(*) AS count FROM item_tag WHERE account = ? GROUP BY item_id)").pluck().get(account)*10)/10,
|
||||
lonelyTags: db.prepare("SELECT count(*) FROM (SELECT tag FROM item_tag WHERE account = ? GROUP BY tag HAVING count(*) = 1)").pluck().get(account),
|
||||
value: Math.round(select("item", ["currency", "price"], {account}).all().map(c => {
|
||||
return (currencyExchange.get(c.currency) || 0.6) * c.price / (currencyExchange.get(displayCurrency) || 1) / currencyRoundTo
|
||||
}).reduce((a, c) => a + c, 0)) * currencyRoundTo,
|
||||
displayCurrency,
|
||||
taste: db.prepare("with popularity (a) as (select avg(also_collected_count) from item WHERE account = ? group by band_url) select sum(iif(a >= 0 and a < 20, 1, 0)) as cold, sum(iif(a >= 20 and a < 200, 1, 0)) as warm, sum(iif(a >= 200 and a < 2000, 1, 0)) as hot, sum(iif(a >= 2000, 1, 0)) as supernova from popularity").raw().get(account)
|
||||
},
|
||||
currencies: [...currencyExchange.keys()]
|
||||
}
|
||||
if (mode === "artist_grid") {
|
||||
loadPreviews(locals, "band_name", 4, whereClause, account, filter_field, filter, filter_fuzzy)
|
||||
|
@ -186,7 +150,8 @@ router.get("/:account/", defineEventHandler({
|
|||
locals.downloadManager = loadTags.downloadManager
|
||||
locals.downloader = loadTags.downloadManager.check(account)
|
||||
}
|
||||
locals.hasFullTrackData = locals.count.tracks > locals.count.total
|
||||
// if there are any untagged items then we don't have full track data
|
||||
locals.hasFullTrackData = !db.prepare("SELECT * FROM item LEFT JOIN item_tag USING (account, item_id) WHERE account = ? AND item_id = NULL").get(account)
|
||||
return pugSync.render(event, `${arrange}_${shape}.pug`, locals)
|
||||
}
|
||||
}))
|
||||
|
|
63
routes/collection-stats.js
Normal file
63
routes/collection-stats.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
// @ts-check
|
||||
|
||||
const {getCookie, defineEventHandler, readValidatedBody, setCookie} = require("h3")
|
||||
const {z} = require("zod")
|
||||
const {sync, select, db, router} = require("../passthrough")
|
||||
|
||||
/** @type {import("../pug-sync")} */
|
||||
const pugSync = sync.require("../pug-sync")
|
||||
|
||||
const currencyExchange = new Map([
|
||||
["AUD", 0.63],
|
||||
["BRL", 0.17],
|
||||
["CAD", 0.7],
|
||||
["CHF", 1.13],
|
||||
["EUR", 1.08],
|
||||
["GBP", 1.3],
|
||||
["JPY", 0.0067],
|
||||
["NOK", 0.1],
|
||||
["NZD", 0.57],
|
||||
["USD", 1],
|
||||
])
|
||||
const currencies = [...currencyExchange.keys()]
|
||||
|
||||
pugSync.beforeInclude("includes/collection-stats.pug", async (from, event, {account, currency}) => {
|
||||
let displayCurrency = currency || getCookie(event, "bcex-currency") || ""
|
||||
if (!currencyExchange.has(displayCurrency)) displayCurrency = "NZD"
|
||||
const currencyRoundTo = displayCurrency === "JPY" ? 1000 : 10
|
||||
|
||||
return {
|
||||
count: {
|
||||
total: db.prepare("SELECT count(*) FROM item WHERE account = ?").pluck().get(account),
|
||||
runtime: db.prepare("SELECT iif(sum(duration) > 86400, cast(total(duration)/86400 AS INTEGER) || 'd ' || cast(total(duration)/3600%24 AS INTEGER) || 'h', cast(total(duration)/3600 AS INTEGER) || 'h') FROM track WHERE account = ?").pluck().get(account),
|
||||
albums: db.prepare("SELECT count(*) FROM item WHERE item_type = 'album' AND account = ?").pluck().get(account),
|
||||
singles: db.prepare("SELECT count(*) FROM item WHERE item_type = 'track' AND account = ?").pluck().get(account),
|
||||
free: db.prepare("SELECT count(*) FROM item WHERE price = 0 AND account = ?").pluck().get(account),
|
||||
paid: db.prepare("SELECT count(*) FROM item WHERE price > 0 AND account = ?").pluck().get(account),
|
||||
tracks: db.prepare("SELECT count(*) FROM track WHERE account = ?").pluck().get(account),
|
||||
avgTracks: Math.round(db.prepare("SELECT avg(count) FROM (SELECT count(*) AS count FROM track INNER JOIN item USING (account, item_id) WHERE item_type = 'album' AND account = ? GROUP BY item_id)").pluck().get(account)*10)/10,
|
||||
tags: db.prepare("SELECT count(*) FROM item_tag WHERE account = ?").pluck().get(account),
|
||||
avgTags: Math.round(db.prepare("SELECT avg(count) FROM (SELECT count(*) AS count FROM item_tag WHERE account = ? GROUP BY item_id)").pluck().get(account)*10)/10,
|
||||
lonelyTags: db.prepare("SELECT count(*) FROM (SELECT tag FROM item_tag WHERE account = ? GROUP BY tag HAVING count(*) = 1)").pluck().get(account),
|
||||
value: Math.round(select("item", ["currency", "price"], {account}).all().map(c => {
|
||||
return (currencyExchange.get(c.currency) || 0.6) * c.price / (currencyExchange.get(displayCurrency) || 1) / currencyRoundTo
|
||||
}).reduce((a, c) => a + c, 0)) * currencyRoundTo,
|
||||
displayCurrency,
|
||||
taste: db.prepare("with popularity (a) as (select avg(also_collected_count) from item WHERE account = ? group by band_url) select sum(iif(a >= 0 and a < 20, 1, 0)) as cold, sum(iif(a >= 20 and a < 200, 1, 0)) as warm, sum(iif(a >= 200 and a < 2000, 1, 0)) as hot, sum(iif(a >= 2000, 1, 0)) as supernova from popularity").raw().get(account)
|
||||
},
|
||||
currencies
|
||||
}
|
||||
})
|
||||
|
||||
const schema = {
|
||||
currency: z.object({
|
||||
currency: z.string().regex(/^[A-Z]{3}$/),
|
||||
account: z.string()
|
||||
})
|
||||
}
|
||||
|
||||
router.post("/api/settings/currency", defineEventHandler(async event => {
|
||||
const {currency, account} = await readValidatedBody(event, schema.currency.parse)
|
||||
setCookie(event, "bcex-currency", currency)
|
||||
return pugSync.render(event, "includes/collection-stats.pug", {account, currency})
|
||||
}))
|
|
@ -2,15 +2,11 @@
|
|||
|
||||
const {z} = require("zod")
|
||||
const {router} = require("../passthrough")
|
||||
const {defineEventHandler, readValidatedBody, setCookie, setResponseHeader, sendRedirect} = require("h3")
|
||||
const {defineEventHandler, readValidatedBody, setCookie, setResponseHeader} = require("h3")
|
||||
|
||||
const schema = {
|
||||
inline_player: z.object({
|
||||
inline_player: z.string().optional()
|
||||
}),
|
||||
currency: z.object({
|
||||
currency: z.string().regex(/^[A-Z]{3}$/),
|
||||
account: z.string()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -20,9 +16,3 @@ router.post("/api/settings/inline-player", defineEventHandler(async event => {
|
|||
setResponseHeader(event, "HX-Refresh", "true")
|
||||
return null
|
||||
}))
|
||||
|
||||
router.post("/api/settings/currency", defineEventHandler(async event => {
|
||||
const {currency, account} = await readValidatedBody(event, schema.currency.parse)
|
||||
setCookie(event, "bcex-currency", currency)
|
||||
return sendRedirect(event, `/${account}/?arrange=tag&shape=grid`, 302)
|
||||
}))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue