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) { 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) { 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) { 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 }