diff --git a/docs/anime.md b/docs/anime.md index 9cf2940fd3..0f08540cfa 100644 --- a/docs/anime.md +++ b/docs/anime.md @@ -307,7 +307,7 @@ pageClass: routes ::: warning 注意 -用户动态需要 iwara 登录后的 Cookie 值,所以只能自建,详情见[部署页面](/install/#route-specific-configurations)的配置模块。 +用户动态需要 iwara 用户名和密码,所以只能自建,详情见[部署页面](/install/#route-specific-configurations)的配置模块。 ::: diff --git a/docs/en/anime.md b/docs/en/anime.md index af522d96ad..74269e150d 100644 --- a/docs/en/anime.md +++ b/docs/en/anime.md @@ -90,7 +90,7 @@ If you subscribe to [Discounted works Latest Discounts - Newest to Oldest](https ::: warning -This route requires Cookie, therefore it's only available when self-hosting, refer to the [Deploy Guide](/en/install/#route-specific-configurations) for route-specific configurations. +This route requires username and password, therefore it's only available when self-hosting, refer to the [Deploy Guide](/en/install/#route-specific-configurations) for route-specific configurations. ::: diff --git a/docs/en/install/README.md b/docs/en/install/README.md index 38973b09b8..727dbf0e59 100644 --- a/docs/en/install/README.md +++ b/docs/en/install/README.md @@ -699,7 +699,8 @@ See docs of the specified route and `lib/config.js` for detailed information. - Iwara: - - `IWARA_COOKIE`: Cookie of Iwara User + - `IWARA_USERNAME`: username of Iwara User + - `IWARA_PASSWORD`: password of Iwara User - Last.fm diff --git a/docs/install/README.md b/docs/install/README.md index 39acc4f689..5f3c81653a 100644 --- a/docs/install/README.md +++ b/docs/install/README.md @@ -730,7 +730,8 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行 - Iwara: - - `IWARA_COOKIE`: Iwara 登录后的 Cookie 值 + - `IWARA_USERNAME`: Iwara 用户名 + - `IWARA_PASSWORD`: Iwara 密码 - Last.fm 全部路由:[申请地址](https://www.last.fm/api/) diff --git a/lib/config.js b/lib/config.js index 9ef27560de..82f32d87e3 100644 --- a/lib/config.js +++ b/lib/config.js @@ -194,7 +194,8 @@ const calculateValue = () => { cookie: envs.IG_COOKIE, }, iwara: { - cookie: envs.IWARA_COOKIE, + username: envs.IWARA_USERNAME, + password: envs.IWARA_PASSWORD, }, lastfm: { api_key: envs.LASTFM_API_KEY, diff --git a/lib/v2/iwara/subscriptions.js b/lib/v2/iwara/subscriptions.js index 497036093d..001c38f184 100644 --- a/lib/v2/iwara/subscriptions.js +++ b/lib/v2/iwara/subscriptions.js @@ -8,33 +8,73 @@ const md = require('markdown-it')({ }); module.exports = async (ctx) => { - const rootUrl = `https://www.iwara.tv`; - 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'; - const cookie = config.iwara.cookie; - - if (cookie === undefined) { + if (!config.iwara || !config.iwara.username || !config.iwara.password) { throw Error('Iwara subscription RSS is disabled due to the lack of relevant config'); } + const rootUrl = `https://www.iwara.tv`; + const username = config.iwara.username; + const password = config.iwara.password; + + // get refresh token + const refreshHeaders = await ctx.cache.tryGet( + 'iwara:token', + async () => { + const loginResponse = await got({ + method: 'post', + url: 'https://api.iwara.tv/user/login', + headers: { + 'content-type': 'application/json', + }, + data: 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: { - Cookie: cookie, - }, + headers: authHeaders, }); const imageResponse = await got({ method: 'get', url: imageSubUrl, - headers: { - Cookie: cookie, - }, + headers: authHeaders, }); const videoList = videoResponse.data.results.map((item) => { - const imageUrl = item.file ? 'https://i.iwara.tv/image/original/' + item.file.id.toString().padStart(2, '0') + '/thumbnail-' + item.thumbnail.toString().padStart(2, '0') + '.jpg' : ''; + let img_path; + if (item.private === true) { + img_path = 'https://i.iwara.tv/image/original/'; + } else { + img_path = '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, @@ -42,6 +82,7 @@ module.exports = async (ctx) => { category: 'Video', imageUrl, pubDate: parseDate(item.createdAt), + private: item.private, }; }); @@ -57,30 +98,44 @@ module.exports = async (ctx) => { }; }); + // fulltext const list = videoList.concat(imageList); - const items = await Promise.all( list.map((item) => ctx.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: { - Cookie: cookie, - }, + headers: authHeaders, }); - const type = item.category; - const imageUrl = item.imageUrl; const body = response.data.body ? md.render(response.data.body) : ''; + description += body; - item.description = art(path.join(__dirname, 'templates/subscriptions.art'), { - type, - imageUrl, - }); - item.description += body; - - return item; + return { + title: item.title, + author: item.author, + link: item.link, + category: item.category, + pubDate: item.pubDate, + description, + }; }) ) );