mirror of
https://git.stupid.fish/teidesu/scripts.git
synced 2025-07-27 18:22:10 +10:00
64 lines
1.7 KiB
TypeScript
64 lines
1.7 KiB
TypeScript
import { z } from 'zod'
|
|
import { ffetch as ffetchBase } from './fetch.ts'
|
|
import { getEnv } from './misc.ts'
|
|
|
|
let _cachedFfetch: typeof ffetchBase | undefined
|
|
export async function getNavidromeFfetch() {
|
|
if (_cachedFfetch) return _cachedFfetch
|
|
const baseUrl = getEnv('NAVIDROME_ENDPOINT')
|
|
const authRes = await ffetchBase.post('/auth/login', {
|
|
baseUrl,
|
|
json: {
|
|
username: getEnv('NAVIDROME_USERNAME'),
|
|
password: getEnv('NAVIDROME_PASSWORD'),
|
|
},
|
|
}).parsedJson(z.object({ token: z.string() }))
|
|
|
|
_cachedFfetch = ffetchBase.extend({
|
|
baseUrl,
|
|
headers: {
|
|
'x-nd-authorization': `Bearer ${authRes.token}`,
|
|
},
|
|
})
|
|
return _cachedFfetch
|
|
}
|
|
|
|
export const NavidromeSong = z.object({
|
|
id: z.string(),
|
|
title: z.string(),
|
|
album: z.string(),
|
|
albumArtist: z.string(),
|
|
artist: z.string(),
|
|
path: z.string(),
|
|
libraryPath: z.string(),
|
|
duration: z.number(),
|
|
size: z.number(),
|
|
})
|
|
export type NavidromeSong = z.infer<typeof NavidromeSong>
|
|
|
|
export async function fetchSongs(offset: number, pageSize: number) {
|
|
const api = await getNavidromeFfetch()
|
|
return api('/api/song', {
|
|
query: {
|
|
_start: offset,
|
|
_end: offset + pageSize,
|
|
_order: 'ASC',
|
|
_sort: 'title',
|
|
},
|
|
}).parsedJson(z.array(NavidromeSong))
|
|
}
|
|
|
|
export async function* fetchSongsIter(params?: {
|
|
chunkSize?: number
|
|
onChunkProcessed?: (page: number, items: number) => void
|
|
}) {
|
|
const { chunkSize = 1000, onChunkProcessed } = params ?? {}
|
|
for (let offset = 0; ; offset += chunkSize) {
|
|
const songs = await fetchSongs(offset, chunkSize)
|
|
if (songs.length === 0) return
|
|
|
|
yield * songs
|
|
|
|
onChunkProcessed?.(Math.floor(offset / chunkSize), songs.length)
|
|
}
|
|
}
|