Download server.js from ReikerXx/bani: direct link, hf CLI and curl.
- Browser
- Download file 4.9 kB
-
https://huggingface.co/spaces/ReikerXx/bani/resolve/main/server.js
- Command line
-
hf download hf://spaces/ReikerXx/bani/server.js
-
curl -L -o server.js https://huggingface.co/spaces/ReikerXx/bani/resolve/main/server.js
4.9 kB
| const express = require("express"); | |
| const axios = require("axios"); | |
| const cheerio = require("cheerio"); | |
| const stringSimilarity = require("string-similarity"); | |
| const app = express(); | |
| const PORT = 7860; | |
| const baseURL = "https://www.tokyoinsider.com/anime/"; | |
| app.get("/anime/:name/:episode", async (req, res) => { | |
| const animeName = decodeURIComponent(req.params.name).replace(/\s+/g, " ").trim(); | |
| const episodeNumber = req.params.episode; | |
| const firstLetter = animeName[0].toUpperCase(); | |
| const categoryURL = `${baseURL}${firstLetter}`; | |
| console.log(`Fetching: ${categoryURL}`); | |
| try { | |
| let response = await axios.get(categoryURL); | |
| let html = response.data; | |
| let $ = cheerio.load(html); | |
| let animeLinks = {}; | |
| $("a[href*='/anime/']").each((i, link) => { | |
| let title = $(link).text().replace(/\s+/g, " ").trim(); | |
| let href = $(link).attr("href"); | |
| if (title && href) { | |
| animeLinks[title] = `https://www.tokyoinsider.com${href}`; | |
| } | |
| }); | |
| if (Object.keys(animeLinks).length === 0) { | |
| return res.status(404).json({ error: "No anime found." }); | |
| } | |
| let bestMatch = findClosestMatch(animeName, Object.keys(animeLinks)); | |
| if (bestMatch) { | |
| let baseAnimeURL = animeLinks[bestMatch].replace(/\/episode\/\d+$/, ""); | |
| let episodeURL = `${baseAnimeURL}/episode/${episodeNumber}`; | |
| console.log(`Anime Found: ${bestMatch}`); | |
| console.log(`Episode URL: ${episodeURL}`); | |
| let downloads = await getEpisodeDownloads(episodeURL); | |
| if (downloads.length === 0) { | |
| console.log("No downloads found, retrying alternative URL..."); | |
| let alternativeURL = `${baseAnimeURL}/ep/${episodeNumber}`; | |
| downloads = await getEpisodeDownloads(alternativeURL); | |
| if (downloads.length === 0) { | |
| return res.status(404).json({ error: "No download links found." }); | |
| } | |
| episodeURL = alternativeURL; | |
| } | |
| let categorizedDownloads = categorizeDownloads(downloads); | |
| let responseObj = { | |
| anime: bestMatch, | |
| episode: episodeNumber, | |
| episodeURL, | |
| ...categorizedDownloads | |
| }; | |
| return res.json(responseObj); | |
| } else { | |
| return res.status(404).json({ error: "No close match found." }); | |
| } | |
| } catch (error) { | |
| console.error("Error:", error.message); | |
| return res.status(500).json({ error: "Server error." }); | |
| } | |
| }); | |
| async function getEpisodeDownloads(episodeURL) { | |
| console.log(`Fetching Episode Page: ${episodeURL}`); | |
| try { | |
| let response = await axios.get(episodeURL); | |
| let html = response.data; | |
| let $ = cheerio.load(html); | |
| let downloads = []; | |
| $(".c_h2, .c_h2b").each((i, div) => { | |
| let linkElement = $(div).find("a[href*='media.tokyoinsider.com']"); | |
| let infoElement = $(div).find(".finfo"); | |
| if (linkElement.length > 0 && infoElement.length > 0) { | |
| let title = linkElement.text().trim(); | |
| let url = linkElement.attr("href"); | |
| let sizeText = infoElement.find("b").eq(0).text(); | |
| let downloadsCount = infoElement.find("b").eq(1).text(); | |
| let uploader = infoElement.find("b").eq(2).text(); | |
| let addedOn = infoElement.find("b").eq(3).text(); | |
| let size = parseSize(sizeText); | |
| if (size > 0) { | |
| downloads.push({ title, url, size, downloadsCount, uploader, addedOn }); | |
| } | |
| } | |
| }); | |
| return downloads; | |
| } catch (error) { | |
| console.error("Error fetching episode page:", error.message); | |
| return []; | |
| } | |
| } | |
| function categorizeDownloads(downloads) { | |
| let resolutions = { "360p": null, "720p": null, "1080p": null }; | |
| downloads.forEach(d => { | |
| if (d.size >= 25 && d.size < 100 && !resolutions["360p"]) { | |
| resolutions["360p"] = d; | |
| } else if (d.size >= 100 && d.size < 400 && !resolutions["720p"]) { | |
| resolutions["720p"] = d; | |
| } else if (d.size >= 400 && !resolutions["1080p"]) { | |
| resolutions["1080p"] = d; | |
| } | |
| }); | |
| return resolutions; | |
| } | |
| function parseSize(sizeText) { | |
| let size = parseFloat(sizeText); | |
| if (sizeText.includes("GB")) { | |
| size *= 1024; | |
| } | |
| return isNaN(size) ? 0 : size; | |
| } | |
| function findClosestMatch(query, animeList) { | |
| let bestMatch = stringSimilarity.findBestMatch(query, animeList); | |
| return bestMatch.bestMatch.rating > 0.5 ? bestMatch.bestMatch.target : null; | |
| } | |
| app.listen(PORT, () => { | |
| console.log(`Server running on http://localhost:${PORT}`); | |
| }); |