KHIDownloader-Astro/src/utils/search.ts
2025-03-10 18:11:13 -06:00

77 lines
2.5 KiB
TypeScript

import * as cheerio from 'cheerio'
import { USER_AGENTS } from './consts'
import type { AlbumRow } from './types'
function getRandom(list: any[]) {
return list[Math.floor(Math.random() * list.length)]
}
export function politeFetch(url: string, lastReqRef: React.RefObject<number>) {
const elapsed = Date.now() - lastReqRef.current
const corsUrl = `https://cors.chitowarlock.com/${url}`
const headers = {
'User-Agent': getRandom(USER_AGENTS),
Referer: 'https://downloads.khinsider.com/',
'Accept-Language': 'en-US,en;q=0.5',
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*//**;q=0.8',
'Accept-Encoding': 'gzip, deflate, br'
}
return fetch(corsUrl, { headers, signal: AbortSignal.timeout(10 * 1000) }).finally(() => {
lastReqRef.current = Date.now()
})
}
export async function searchAlbums(query: string, lastReqRef: React.RefObject<number>) {
const searchUrl = `https://downloads.khinsider.com/search?search=${query}`
const searchHtml = await (await politeFetch(searchUrl, lastReqRef)).text()
const $ = cheerio.load(searchHtml)
const albumRows = $('table.albumList tr:not(:first-child)')
const albums: AlbumRow[] = []
albumRows.each((index, row) => {
const albumLink = $(row).find('td:nth-of-type(2) a')
if (albumLink.length === 0) return
const albumName = albumLink.text().trim()
const albumUrl = `https://downloads.khinsider.com${albumLink.attr('href')}`
albums.push({ name: albumName, url: albumUrl })
})
const seen = new Set()
const uniqueAlbums = albums.filter((album) => {
if (seen.has(album.url)) return false
seen.add(album.url)
return true
})
return uniqueAlbums
}
export async function getTracks(url: string, lastReqRef: React.RefObject<number>) {
const albumHtml = await (await politeFetch(url, lastReqRef)).text()
const $ = cheerio.load(albumHtml)
const tracks: { name: string; url: string; format: string }[] = []
$('table#songlist tr:has(a[href$=".mp3"]), table#songlist tr:has(a[href$=".flac"])').each((index, row) => {
const link = $(row).find('a[href$=".mp3"], a[href$=".flac"]')
if (link.length === 0) return
const trackUrl = link.attr('href')!.startsWith('http')
? link.attr('href')!
: `https://downloads.khinsider.com${link.attr('href')}`
tracks.push({
name: link.text().trim(),
url: trackUrl,
format: link.attr('href')!.toLowerCase().endsWith('.flac') ? 'flac' : 'mp3'
})
})
return tracks
}