77 lines
2.5 KiB
TypeScript
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
|
|
}
|