import Auth from "./src/helpers/auth"; import Utils from "./src/helpers/utils"; import { utimes } from "fs/promises"; const utils = new Utils(await Auth()); Bun.serve({ routes: { "/api/track/:id": async req => { const trackId = parseInt(req.params.id) const file = Bun.file(`downloaded/${trackId}.flac`) if (await file.exists()) { return new Response(await file.arrayBuffer(), { headers: { "Content-Type": "audio/flac", "Content-Disposition": `attachment; filename="${trackId}.flac"`, "Cache-Control": "public, max-age=31536000", "ETag": trackId.toString(), } }) } const { manifestMimeType, manifest } = await utils.fetchTrack(trackId) const audio = await utils.tagFlac(trackId, await utils.downloadFlac(manifestMimeType, manifest)) //await Bun.write(`downloaded/${trackId}.flac`, audio) return new Response(audio, { headers: { "Content-Type": "audio/flac", //"Content-Disposition": `attachment; filename="${trackId}.flac"`, "Cache-Control": "public, max-age=31536000", "ETag": trackId.toString(), } }) }, "/api/@me/tracks": async () => { const tracks = await utils.fetchTracks(); return new Response(Bun.gzipSync(JSON.stringify(tracks)), { headers: { "Content-Type": "application/json", "Content-Encoding": "gzip", } }) } }, development: true }) const tracks = await utils.fetchTracks(); let i = 1; for await (const track of tracks.items) { const { id } = track.item const createdAt = new Date(track.created) const trackId = parseInt(id) if (await Bun.file(`downloaded/${trackId}.flac`).exists() || await Bun.file(`downloaded/${trackId}.m4a`).exists() || await Bun.file(`downloaded/${trackId}.unknown`).exists()) { //console.log(`Already downloaded ${trackId}.flac`) i++; continue } const trackData = await utils.fetchTrack(trackId) if (trackData?.status === 404 || trackData === null) { console.error(`track ${trackId} not available`) i++; continue } try { const audio = await utils.downloadFlac(trackData.manifestMimeType, trackData.manifest) const format = audio.mimeType.split("/")[1]; const name = `downloaded/${trackId}.${format}` if (audio.mimeType === "audio/flac") { const taggedAudio = await utils.tagFlac(trackId, audio.buffer) await Bun.write(name, taggedAudio) } else { await Bun.write(name, audio.buffer) } await utimes(name, createdAt, createdAt) //console.log(`Downloaded ${trackId}.flac`) } catch (e) { console.error(`Failed to download ${trackId}.flac`, e) } // Downloaded track 1 of 10, etc console.log(`Downloaded track ${i} of ${tracks.items.length}`) i++; } console.log("Done")