filehost-meta
Version:
Fetch basic file information from download links
107 lines (88 loc) • 3.25 kB
JavaScript
const { connectBrowser } = require('../browser')
const File = require('../classes/File')
const { sizeToBytes } = require('../utils')
exports.domains = ['akirabox.com', 'akirabox.to']
exports.get = async (url, proxy) => {
let cleanup
try {
const connectOptions = { turnstile: true }
if (proxy) {
const parsed = new URL(proxy)
connectOptions.proxy = {
host: parsed.hostname,
port: parsed.port,
username: parsed.username || undefined,
password: parsed.password || undefined,
}
}
const result = await connectBrowser(connectOptions)
cleanup = result.cleanup
const page = result.page
await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 })
// Wait for Cloudflare challenge to resolve
const startTime = Date.now()
while (Date.now() - startTime < 30000) {
const title = await page.title()
if (title !== 'Just a moment...') break
await new Promise(r => setTimeout(r, 1000))
}
// Wait for page content to render after Cloudflare redirect
await page.waitForSelector('h1.text-break, .file-request', { timeout: 15000 }).catch(() => {})
// Extra settle time for dynamic content
await new Promise(r => setTimeout(r, 2000))
const fileData = await page.evaluate(() => {
const name = document.querySelector('h1.text-break')?.textContent?.trim()
|| document.querySelector('h1')?.textContent?.trim()
// Parse size from "(530.92 MB)" in the file-request section
let size = null
const spans = document.querySelectorAll('.file-request span')
for (const span of spans) {
const match = span.textContent.match(/\(([\d.]+\s*[KMGT]?B)\)/)
if (match) { size = match[1]; break }
}
// Also try the gray info text pattern
if (!size) {
const allText = document.body.innerText
const sizeMatch = allText.match(/([\d.]+\s*[KMGT]?B)\s*\)/)
if (sizeMatch) size = sizeMatch[1]
}
// Parse date and stats from info table
let date = null, views = null, downloads = null
const rows = document.querySelectorAll('table tr')
for (const row of rows) {
const cells = row.querySelectorAll('td')
if (cells.length < 2) continue
const label = cells[0].textContent.trim()
const value = cells[1].textContent.trim()
if (label.includes('Date')) date = value
if (label.includes('Stats')) {
const parts = value.split('|').map(s => parseInt(s.replace(/\D/g, ''), 10))
views = parts[0] || 0
downloads = parts[1] || 0
}
}
return { name, size, date, views, downloads }
})
if (!fileData?.name) {
throw new Error('Could not extract file name from page')
}
let createdAt = null
if (fileData.date) {
createdAt = new Date(fileData.date)
if (isNaN(createdAt.getTime())) createdAt = null
}
return [
new File({
name: fileData.name,
size: fileData.size ? sizeToBytes(fileData.size) : 0,
views: fileData.views || 0,
downloads: fileData.downloads || 0,
createdAt,
})
]
} finally {
if (cleanup) {
await cleanup()
}
}
}