Fix track data import, clean up code

This commit is contained in:
Cadence Ember 2025-04-04 20:39:04 +13:00
parent cf6310b89a
commit 6fb5a943db
2 changed files with 33 additions and 24 deletions

View file

@ -8,24 +8,33 @@ const {sync, db, from, router} = require("../passthrough")
const pugSync = sync.require("../pug-sync")
const insertTag = db.prepare("INSERT OR IGNORE INTO item_tag (account, item_id, tag) VALUES (?, ?, ?)")
const insertTrack = db.prepare("INSERT OR IGNORE INTO track (account, item_id, track_id, title, artist, track_number, duration) VALUES (?, ?, ?, ?, ?, ?, ?)")
const insertTrack = db.prepare("INSERT OR IGNORE INTO track (account, item_id, track_id, title, artist, track_number, duration) VALUES (@account, @item_id, @track_id, @title, @artist, @track_number, @duration)")
class TagDownloader extends sync.reloadClassMethods(() => TagDownloader) {
constructor(account) {
super()
this.account = account
this.processed = 0
this.untaggedItems = db.prepare("SELECT account, item_id, item_title, item_url, band_name FROM item LEFT JOIN item_tag USING (account, item_id) WHERE account = ? AND tag IS NULL").all(account)
this.untaggedItems = []
this.total = this.untaggedItems.length
this.running = false
this.outcome = null
this.check()
}
check() {
if (this.running) return // don't reduce the total while items are being processed, this will break the progress bar
this.untaggedItems = db.prepare("SELECT account, item_id, item_title, item_url, band_name FROM item LEFT JOIN item_tag USING (account, item_id) WHERE account = ? AND tag IS NULL").all(this.account)
this.total = this.untaggedItems.length
}
async _start() {
if (this.running) return
this.running = true
this.outcome = null
this.processed = 0
try {
for (const {account, item_id, item_title, item_url, band_name} of this.untaggedItems) {
for (const {account, item_id, item_type, item_title, item_url, band_name} of this.untaggedItems) {
const res = await fetch(item_url)
// delete unreachable items, otherwise it will perpetually try to download tags for them
@ -47,21 +56,18 @@ class TagDownloader extends sync.reloadClassMethods(() => TagDownloader) {
})()
// @ts-ignore
const tracks = [...doc.querySelectorAll(".track_row_view").cache]
const tracklist = JSON.parse(doc.querySelector("script[data-tralbum]").getAttribute("data-tralbum")).trackinfo
db.transaction(() => {
for (const track of tracks) {
const track_number = parseInt(track.querySelector(".track_number").textContent)
let title = track.querySelector(".track-title").textContent
let artist = band_name
const match = title.match(/^([^-]*) - (.*)$/)
if (match) {
artist = match[1]
title = match[2]
}
const duration = track.querySelector(".time").textContent.split(":").reverse().reduce((a, c, i) => 60**i * c + a, 0)
console.log(track_number, title, artist, duration)
if (!track_number || !title || !artist || !duration) continue
insertTrack.run(account, item_id, track_number, title, artist, track_number, duration)
for (const track of tracklist) {
insertTrack.run({
account,
item_id,
track_id: track.id,
title: track.title,
artist: track.artist || band_name,
track_number: track.track_num,
duration: track.duration
})
}
})()
@ -75,6 +81,10 @@ class TagDownloader extends sync.reloadClassMethods(() => TagDownloader) {
this.running = false
}
}
resolve() {
this.outcome = null
}
}
const downloadManager = new class {
@ -83,14 +93,13 @@ const downloadManager = new class {
/** @param {string} account */
check(account) {
return this.inProgressTagDownloads.get(account) || (() => {
const downloader = this.inProgressTagDownloads.get(account) || (() => {
const downloader = new TagDownloader(account)
this.inProgressTagDownloads.set(account, downloader)
setTimeout(() => {
this.resolve(account)
})
return downloader
})()
downloader.check()
return downloader
}
/** @param {string} account */
@ -116,13 +125,13 @@ const schema = z.object({
router.get("/api/tag-download", defineEventHandler(async event => {
const {account} = await getValidatedQuery(event, schema.parse)
const downloader = downloadManager.check(account)
return pugSync.render(event, "includes/tag-status.pug", {downloadManager, downloader, account})
return pugSync.render(event, "includes/tag-status.pug", {downloader, account})
}))
router.post("/api/tag-download", defineEventHandler(async event => {
const {account} = await readValidatedBody(event, schema.parse)
const downloader = downloadManager.start(account)
return pugSync.render(event, "includes/tag-status.pug", {downloadManager, downloader, account})
return pugSync.render(event, "includes/tag-status.pug", {downloader, account})
}))
module.exports.downloadManager = downloadManager