UNPKG

rsshub

Version:
129 lines (107 loc) • 4.65 kB
import { Route } from '@/types'; import cache from '@/utils/cache'; import got from '@/utils/got'; import { load } from 'cheerio'; import path from 'node:path'; import { art } from '@/utils/render'; import { parseDate } from '@/utils/parse-date'; export const route: Route = { path: '/:what?/:id?/:needTorrents?/:needImages?', name: 'Unknown', maintainers: [], features: { nsfw: true, }, handler, }; async function handler(ctx) { const id = ctx.req.param('id') ?? ''; const what = ctx.req.param('what') ?? ''; const needTorrents = /t|y/i.test(ctx.req.param('needTorrents') ?? 'true'); const needImages = /t|y/i.test(ctx.req.param('needImages') ?? 'true'); const rootUrl = 'https://e-hentai.org'; const currentUrl = `${rootUrl}/${id ? (what === 'search' ? `?${id}` : what === 'category' ? id : `${what}/${id}`) : what}`; const response = await got({ method: 'get', url: currentUrl, }); const $ = load(response.data); $('.itd').parent().remove(); let items = $('table.gltc tbody tr') .slice(1, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) + 1 : (needImages ? 16 : 26)) .toArray() .map((item) => { item = $(item); return { title: item.find('div.glink').text(), author: item.find('td.glhide div a').text(), link: item.find('td.glname a').attr('href'), pubDate: parseDate(item.find('div.ir').prev().text()), category: item .find('div.gt') .toArray() .map((tag) => $(tag).attr('title').replace(/^:/, '')), description: needImages ? '' : `<img src="${item.find('div.glthumb div img').attr('data-src') ?? item.find('div.glthumb div img').attr('src')}">`, enclosure_url: needTorrents ? (item.find('div.gldown a img[title="Show torrents"]').length > 0 ? item.find('.gldown a').attr('href') : undefined) : undefined, }; }); items = await Promise.all( items.map(async (item) => { if (item.enclosure_url) { let forms = '', torrents = await cache.get(item.enclosure_url); if (!torrents) { const torrentResponse = await got({ method: 'get', url: item.enclosure_url, }); const torrent = load(torrentResponse.data); torrent('h1, input[name="torrent_info"]').remove(); forms = torrent('form').parent().html(); torrents = torrent('table tbody tr td a') .toArray() .map((t) => { t = torrent(t); return { link: t.attr('href'), title: t.text() }; }); cache.set(item.enclosure_url, torrents); } item.description += forms; item.enclosure_url = torrents[0].link; item.enclosure_type = 'application/x-bittorrent'; } if (needImages) { let images = await cache.get(item.link); if (!images) { const imageResponse = await got({ method: 'get', url: item.link, }); const content = load(imageResponse.data); images = await Promise.all( content('.gdtm a') .toArray() .map((i) => cache.tryGet(content(i).attr('href'), async () => { const imageResponse = await got({ method: 'get', url: content(i).attr('href'), }); const image = load(imageResponse.data); return image('#img').attr('src'); }) ) ); cache.set(item.link, images); } item.description += art(path.join(__dirname, 'templates/images.art'), { images }); } return item; }) ); return { title: `${id || what || 'Front Page'} - E-Hentai Galleries`, link: currentUrl, item: items, }; }