UNPKG

rsshub

Version:
185 lines (167 loc) 5.94 kB
import { Route } from '@/types'; import cache from '@/utils/cache'; import got from '@/utils/got'; import { config } from '@/config'; import { art } from '@/utils/render'; import { parseDate } from '@/utils/parse-date'; import path from 'node:path'; import MarkdownIt from 'markdown-it'; import ConfigNotFoundError from '@/errors/types/config-not-found'; const md = MarkdownIt({ html: true, }); export const route: Route = { path: '/subscriptions', categories: ['anime'], example: '/iwara/subscriptions', parameters: {}, features: { requireConfig: [ { name: 'IWARA_USERNAME', description: '', }, { name: 'IWARA_PASSWORD', description: '', }, ], requirePuppeteer: false, antiCrawler: false, supportBT: false, supportPodcast: false, supportScihub: false, }, radar: [ { source: ['ecchi.iwara.tv/'], }, ], name: 'User Subscriptions', maintainers: ['FeCCC'], handler, url: 'ecchi.iwara.tv/', description: `::: warning This route requires username and password, therefore it's only available when self-hosting, refer to the [Deploy Guide](https://docs.rsshub.app/deploy/config#route-specific-configurations) for route-specific configurations. :::`, }; async function handler() { if (!config.iwara || !config.iwara.username || !config.iwara.password) { throw new ConfigNotFoundError('Iwara subscription RSS is disabled due to the lack of <a href="https://docs.rsshub.app/deploy/config#route-specific-configurations">relevant config</a>'); } const rootUrl = `https://www.iwara.tv`; const username = config.iwara.username; const password = config.iwara.password; // get refresh token const refreshHeaders = await cache.tryGet( 'iwara:token', async () => { const loginResponse = await got({ method: 'post', url: 'https://api.iwara.tv/user/login', headers: { 'content-type': 'application/json', }, body: JSON.stringify({ email: username, password, }), }); return { authorization: 'Bearer ' + loginResponse.data.token, }; }, 30 * 24 * 60 * 60, false ); // get subscription list const videoSubUrl = 'https://api.iwara.tv/videos?page=0&limit=30&subscribed=true'; const imageSubUrl = 'https://api.iwara.tv/images?page=0&limit=30&subscribed=true'; // get access token const accessResponse = await got({ method: 'post', url: 'https://api.iwara.tv/user/token', headers: refreshHeaders, }); const authHeaders = { authorization: 'Bearer ' + accessResponse.data.accessToken, }; const videoResponse = await got({ method: 'get', url: videoSubUrl, headers: authHeaders, }); const imageResponse = await got({ method: 'get', url: imageSubUrl, headers: authHeaders, }); const videoList = videoResponse.data.results.map((item) => { const img_path = item.private === true ? 'https://i.iwara.tv/image/original/' : 'https://i.iwara.tv/image/thumbnail/'; const imageUrl = item.file ? img_path + item.file.id.toString().padStart(2, '0') + '/thumbnail-' + item.thumbnail.toString().padStart(2, '0') + '.jpg' : ''; return { title: item.title, author: item.user.name, link: rootUrl + '/video/' + item.id, category: 'Video', imageUrl, pubDate: parseDate(item.createdAt), private: item.private, }; }); const imageList = imageResponse.data.results.map((item) => { const imageUrl = item.thumbnail ? 'https://i.iwara.tv/image/thumbnail/' + item.thumbnail.id + '/' + item.thumbnail.id + '.jpg' : ''; return { title: item.title, author: item.user.name, link: rootUrl + '/image/' + item.id, category: 'Image', imageUrl, pubDate: parseDate(item.createdAt), }; }); // fulltext const list = [...videoList, ...imageList]; const items = await Promise.all( list.map((item) => cache.tryGet(item.link, async () => { let description = art(path.join(__dirname, 'templates/subscriptions.art'), { type: item.category, imageUrl: item.imageUrl, }); if (item.private === true) { description += 'private'; return { title: item.title, author: item.author, link: item.link, category: item.category, pubDate: item.pubDate, description, }; } const link = item.link.replace('www.iwara.tv', 'api.iwara.tv'); const response = await got({ method: 'get', url: link, headers: authHeaders, }); const body = response.data.body ? md.render(response.data.body) : ''; description += body; return { title: item.title, author: item.author, link: item.link, category: item.category, pubDate: item.pubDate, description, }; }) ) ); return { title: `Iwara Subscription`, link: rootUrl, item: items, }; }