feat(route): add themoviedb (#12308)
* feat(route): add tmdb * refactor(route): rename parameter * fix(route): themoviedb
This commit is contained in:
parent
cf1fe23d7c
commit
d6162ae973
|
|
@ -523,6 +523,46 @@ Refer to [Pornhub F.A.Qs](https://help.pornhub.com/hc/en-us/articles/36004432703
|
|||
|
||||
<RouteEn author="outloudvi" example="/spotify/top/artists" path="/spotify/top/artists" />
|
||||
|
||||
## The Movie Database
|
||||
|
||||
::: tip Tips
|
||||
Refer to <https://developers.themoviedb.org/3/getting-started/languages> for the language parameter in the route.
|
||||
:::
|
||||
|
||||
### Collection
|
||||
|
||||
<RouteEn author="x2cf" example="/themoviedb/collection/131292/en-US" path="/themoviedb/collection/:id/:lang?" :paramsDesc="['Collection ID', 'Language']" radar="1" rssbud="1" />
|
||||
|
||||
### Trending
|
||||
|
||||
<RouteEn author="x2cf" example="/themoviedb/trending/tv/day/en-US" path="/themoviedb/trending/:mediaType/:timeWindow/:lang?" :paramsDesc="['`movie` or `tv`', '`day` or `week`', 'Language']" radar="1" rssbud="1" />
|
||||
|
||||
### TV Show Seasons
|
||||
|
||||
<RouteEn author="x2cf" example="/themoviedb/tv/70593/seasons/en-US" path="/themoviedb/tv/:id/seasons/:lang?" :paramsDesc="['TV show ID', 'Language']" radar="1" rssbud="1" />
|
||||
|
||||
### TV Show Episodes
|
||||
|
||||
<RouteEn author="x2cf" example="/themoviedb/tv/70593/seasons/1/episodes/en-US" path="/themoviedb/tv/:id/seasons/:seasonNumber/episodes/:lang?" :paramsDesc="['TV show ID', 'Season number', 'Language']" radar="1" rssbud="1" />
|
||||
|
||||
### Sheet
|
||||
|
||||
<RouteEn author="x2cf" example="/themoviedb/tv/top-rated/en-US" path="/themoviedb/:mediaType/:sheet/:lang?" :paramsDesc="['`movie` or `tv`', 'Sheet, see below', 'Language']" radar="1" rssbud="1">
|
||||
|
||||
When `mediaType` is `tv`, `sheet` should be:
|
||||
|
||||
| Airing Today | On TV | Top Rated |
|
||||
| ------------ | ---------- | --------- |
|
||||
| airing-today | on-the-air | top-rated |
|
||||
|
||||
When `mediaType` is `movie`, `sheet` should be:
|
||||
|
||||
| Now Playing | Upcoming | Top Rated |
|
||||
| ----------- | -------- | --------- |
|
||||
| now-playing | upcoming | top-rated |
|
||||
|
||||
</RouteEn>
|
||||
|
||||
## Trakt.tv
|
||||
|
||||
### User Collection
|
||||
|
|
|
|||
|
|
@ -1179,6 +1179,46 @@ JavDB 有多个备用域名,本路由默认使用永久域名 <https://javdb.c
|
|||
|
||||
</Route>
|
||||
|
||||
## The Movie Database
|
||||
|
||||
::: tip 提示
|
||||
路由中的语言参数可参考 <https://developers.themoviedb.org/3/getting-started/languages>。
|
||||
:::
|
||||
|
||||
### 系列
|
||||
|
||||
<Route author="x2cf" example="/themoviedb/collection/131292/zh" path="/themoviedb/collection/:id/:lang?" :paramsDesc="['系列 ID', '语言']" radar="1" rssbud="1" />
|
||||
|
||||
### 热门
|
||||
|
||||
<Route author="x2cf" example="/themoviedb/trending/tv/day/zh" path="/themoviedb/trending/:mediaType/:timeWindow/:lang?" :paramsDesc="['`movie` 或 `tv`', '`day` 或 `week`', '语言']" radar="1" rssbud="1" />
|
||||
|
||||
### 剧集系列
|
||||
|
||||
<Route author="x2cf" example="/themoviedb/tv/70593/seasons/zh" path="/themoviedb/tv/:id/seasons/:lang?" :paramsDesc="['剧集 ID', '语言']" radar="1" rssbud="1" />
|
||||
|
||||
### 剧集章节
|
||||
|
||||
<Route author="x2cf" example="/themoviedb/tv/70593/seasons/1/episodes/zh" path="/themoviedb/tv/:id/seasons/:seasonNumber/episodes/:lang?" :paramsDesc="['剧集 ID', '季号', '语言']" radar="1" rssbud="1" />
|
||||
|
||||
### 片单
|
||||
|
||||
<Route author="x2cf" example="/themoviedb/tv/top-rated/zh" path="/themoviedb/:mediaType/:sheet/:lang?" :paramsDesc="['`movie` 或 `tv`', '片单,见下表', '语言']" radar="1" rssbud="1">
|
||||
|
||||
当 `mediaType` 为 `tv` 时,`sheet` 的值如下:
|
||||
|
||||
| 今日播出 | 电视播出中 | 高分 |
|
||||
| ------------ | ---------- | --------- |
|
||||
| airing-today | on-the-air | top-rated |
|
||||
|
||||
当 `mediaType` 为 `movie` 时,`sheet` 的值如下:
|
||||
|
||||
| 正在上映 | 即将上映 | 高分 |
|
||||
| ----------- | -------- | --------- |
|
||||
| now-playing | upcoming | top-rated |
|
||||
|
||||
</Route>
|
||||
|
||||
## Trakt.tv
|
||||
|
||||
### 用户收藏
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
// https://github.com/rickylawson/freekeys/blob/master/index.js
|
||||
const KEYS = [
|
||||
'fb7bb23f03b6994dafc674c074d01761',
|
||||
'e55425032d3d0f371fc776f302e7c09b',
|
||||
'8301a21598f8b45668d5711a814f01f6',
|
||||
'8cf43ad9c085135b9479ad5cf6bbcbda',
|
||||
'da63548086e399ffc910fbc08526df05',
|
||||
'13e53ff644a8bd4ba37b3e1044ad24f3',
|
||||
'269890f657dddf4635473cf4cf456576',
|
||||
'a2f888b27315e62e471b2d587048f32e',
|
||||
'8476a7ab80ad76f0936744df0430e67c',
|
||||
'5622cafbfe8f8cfe358a29c53e19bba0',
|
||||
'ae4bd1b6fce2a5648671bfc171d15ba4',
|
||||
'257654f35e3dff105574f97fb4b97035',
|
||||
'2f4038e83265214a0dcd6ec2eb3276f5',
|
||||
'9e43f45f94705cc8e1d5a0400d19a7b7',
|
||||
'af6887753365e14160254ac7f4345dd2',
|
||||
'06f10fc8741a672af455421c239a1ffc',
|
||||
'fb7bb23f03b6994dafc674c074d01761',
|
||||
'09ad8ace66eec34302943272db0e8d2c',
|
||||
];
|
||||
|
||||
module.exports = () => KEYS[Math.floor(Math.random() * KEYS.length)];
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
const got = require('@/utils/got');
|
||||
const apiKey = require('./api-key');
|
||||
const { handleMovieItem } = require('./utils');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { id, lang } = ctx.params;
|
||||
const { data } = await got(`https://api.themoviedb.org/3/collection/${id}`, {
|
||||
searchParams: {
|
||||
language: lang,
|
||||
api_key: apiKey(),
|
||||
},
|
||||
});
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${data.name} — TMDB`,
|
||||
description: data.overview.trim(),
|
||||
image: `https://image.tmdb.org/t/p/original${data.poster_path}`,
|
||||
link: `https://www.themoviedb.org/collection/${data.id}`,
|
||||
item: data.parts.map((item) => handleMovieItem(item, lang)),
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
const got = require('@/utils/got');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const apiKey = require('./api-key');
|
||||
const { handleDescription } = require('./utils');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { id, seasonNumber, lang } = ctx.params;
|
||||
const searchParams = {
|
||||
language: lang,
|
||||
api_key: apiKey(),
|
||||
};
|
||||
const { data: tvShowDetails } = await got(`https://api.themoviedb.org/3/tv/${id}`, { searchParams });
|
||||
const { data: seasonDetails } = await got(`https://api.themoviedb.org/3/tv/${id}/season/${seasonNumber}`, { searchParams });
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${tvShowDetails.name} ${seasonDetails.name} — TMDB`,
|
||||
description: seasonDetails.overview.trim(),
|
||||
image: `https://image.tmdb.org/t/p/original${seasonDetails.poster_path}`,
|
||||
link: `https://www.themoviedb.org/tv/${tvShowDetails.id}/season/${seasonDetails.season_number}`,
|
||||
item: seasonDetails.episodes.reverse().map((item) => ({
|
||||
title: `${item.episode_number} ${item.name}`,
|
||||
link: `https://www.themoviedb.org/tv/${tvShowDetails.id}/season/${item.season_number}/episode/${item.episode_number}`,
|
||||
description: handleDescription(item),
|
||||
pubDate: parseDate(item.air_date),
|
||||
})),
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
module.exports = {
|
||||
'/collection/:id/:lang?': ['x2cf'],
|
||||
'/trending/:mediaType/:timeWindow/:lang?': ['x2cf'],
|
||||
'/tv/:id/seasons/:lang?': ['x2cf'],
|
||||
'/tv/:id/seasons/:seasonNumber/episodes/:lang?': ['x2cf'],
|
||||
'/:mediaType/:sheet/:lang?': ['x2cf'],
|
||||
};
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
module.exports = {
|
||||
'themoviedb.org': {
|
||||
_name: 'The Movie Database',
|
||||
'.': [
|
||||
{
|
||||
title: 'Collection',
|
||||
docs: 'https://docs.rsshub.app/multimedia.html#the-movie-database',
|
||||
source: ['/collection/:name'],
|
||||
target: (params) => `/themoviedb/collection/${params.name.split('-')[0]}`,
|
||||
},
|
||||
{
|
||||
title: 'Popular Movies',
|
||||
docs: 'https://docs.rsshub.app/multimedia.html#the-movie-database',
|
||||
source: ['/movie'],
|
||||
target: '/themoviedb/trending/movie/week',
|
||||
},
|
||||
{
|
||||
title: 'Popular TV Shows',
|
||||
docs: 'https://docs.rsshub.app/multimedia.html#the-movie-database',
|
||||
source: ['/tv'],
|
||||
target: '/themoviedb/trending/tv/week',
|
||||
},
|
||||
{
|
||||
title: 'TV Show Seasons',
|
||||
docs: 'https://docs.rsshub.app/multimedia.html#the-movie-database',
|
||||
source: ['/tv/:id/seasons', '/tv/:id'],
|
||||
target: (params) => `/themoviedb/tv/${params.id.split('-')[0]}/seasons`,
|
||||
},
|
||||
{
|
||||
title: 'TV Show Episodes',
|
||||
docs: 'https://docs.rsshub.app/multimedia.html#the-movie-database',
|
||||
source: ['/tv/:id/season/:seasonNumber'],
|
||||
target: (params) => `/themoviedb/tv/${params.id.split('-')[0]}/seasons/${params.seasonNumber}/episodes`,
|
||||
},
|
||||
{
|
||||
title: 'TV Shows Airing Today',
|
||||
docs: 'https://docs.rsshub.app/multimedia.html#the-movie-database',
|
||||
source: ['/tv/airing-today'],
|
||||
target: '/themoviedb/tv/airing-today',
|
||||
},
|
||||
{
|
||||
title: 'Currently Airing TV Shows',
|
||||
docs: 'https://docs.rsshub.app/multimedia.html#the-movie-database',
|
||||
source: ['/tv/on-the-air'],
|
||||
target: '/themoviedb/tv/on-the-air',
|
||||
},
|
||||
{
|
||||
title: 'Top Rated TV Shows',
|
||||
docs: 'https://docs.rsshub.app/multimedia.html#the-movie-database',
|
||||
source: ['/tv/top-rated'],
|
||||
target: '/themoviedb/tv/top-rated',
|
||||
},
|
||||
{
|
||||
title: 'Now Playing Movies',
|
||||
docs: 'https://docs.rsshub.app/multimedia.html#the-movie-database',
|
||||
source: ['/movie/now-playing'],
|
||||
target: '/themoviedb/movie/now-playing',
|
||||
},
|
||||
{
|
||||
title: 'Upcoming Movies',
|
||||
docs: 'https://docs.rsshub.app/multimedia.html#the-movie-database',
|
||||
source: ['/movie/upcoming'],
|
||||
target: '/themoviedb/movie/upcoming',
|
||||
},
|
||||
{
|
||||
title: 'Top Rated Movies',
|
||||
docs: 'https://docs.rsshub.app/multimedia.html#the-movie-database',
|
||||
source: ['/movie/top-rated'],
|
||||
target: '/themoviedb/movie/top-rated',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
module.exports = (router) => {
|
||||
router.get('/collection/:id/:lang?', require('./collection'));
|
||||
router.get('/trending/:mediaType/:timeWindow/:lang?', require('./trending'));
|
||||
router.get('/tv/:id/seasons/:lang?', require('./seasons'));
|
||||
router.get('/tv/:id/seasons/:seasonNumber/episodes/:lang?', require('./episodes'));
|
||||
router.get('/:mediaType/:sheet/:lang?', require('./sheet'));
|
||||
};
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
const got = require('@/utils/got');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const apiKey = require('./api-key');
|
||||
const { handleDescription } = require('./utils');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { id, lang } = ctx.params;
|
||||
const { data } = await got(`https://api.themoviedb.org/3/tv/${id}`, {
|
||||
searchParams: {
|
||||
language: lang,
|
||||
api_key: apiKey(),
|
||||
},
|
||||
});
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${data.name} - Seasons — TMDB`,
|
||||
description: data.overview.trim(),
|
||||
image: `https://image.tmdb.org/t/p/original${data.poster_path}`,
|
||||
link: `https://www.themoviedb.org/tv/${data.id}/seasons`,
|
||||
item: data.seasons.map((item) => {
|
||||
item.vote_average = data.vote_average;
|
||||
item.vote_count = data.vote_count;
|
||||
return {
|
||||
title: item.name,
|
||||
link: `https://www.themoviedb.org/tv/${data.id}/season/${item.season_number}`,
|
||||
description: handleDescription(item),
|
||||
pubDate: parseDate(item.air_date),
|
||||
};
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
const got = require('@/utils/got');
|
||||
const apiKey = require('./api-key');
|
||||
const { MEDIA_TYPE_TO_ITEM_HANDLE } = require('./utils');
|
||||
|
||||
const API_PATH = {
|
||||
movie: {
|
||||
'now-playing': 'movie/now_playing',
|
||||
upcoming: 'movie/upcoming',
|
||||
'top-rated': 'movie/top_rated',
|
||||
},
|
||||
tv: {
|
||||
'airing-today': 'tv/airing_today',
|
||||
'on-the-air': 'tv/on_the_air',
|
||||
'top-rated': 'tv/top_rated',
|
||||
},
|
||||
};
|
||||
|
||||
const TITLE = {
|
||||
movie: {
|
||||
'now-playing': 'Now Playing Movies',
|
||||
upcoming: 'Upcoming Movies',
|
||||
'top-rated': 'Top Rated Movies',
|
||||
},
|
||||
tv: {
|
||||
'airing-today': 'TV Shows Airing Today',
|
||||
'on-the-air': 'Currently Airing TV Shows',
|
||||
'top-rated': 'Top Rated TV Shows',
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { mediaType, sheet, lang } = ctx.params;
|
||||
const { data } = await got(`https://api.themoviedb.org/3/${API_PATH[mediaType][sheet]}`, {
|
||||
searchParams: {
|
||||
language: lang,
|
||||
api_key: apiKey(),
|
||||
},
|
||||
});
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${TITLE[mediaType][sheet]} — TMDB`,
|
||||
link: `https://www.themoviedb.org/${mediaType}/${sheet}`,
|
||||
item: data.results.map((item) => MEDIA_TYPE_TO_ITEM_HANDLE[mediaType](item, lang)),
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<img src="{{poster}}" />
|
||||
<p>
|
||||
User Score: {{vote_average}}<br/>
|
||||
Vote Count: {{vote_count}}<br/>
|
||||
</p>
|
||||
<p>{{description}}</p>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
const got = require('@/utils/got');
|
||||
const apiKey = require('./api-key');
|
||||
const { MEDIA_TYPE_TO_ITEM_HANDLE } = require('./utils');
|
||||
|
||||
const MEDIA_TYPE_TO_TITLE = {
|
||||
tv: 'TV Shows',
|
||||
movie: 'Movies',
|
||||
};
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { mediaType, timeWindow, lang } = ctx.params;
|
||||
const { data } = await got(`https://api.themoviedb.org/3/trending/${mediaType}/${timeWindow}`, {
|
||||
searchParams: {
|
||||
language: lang,
|
||||
api_key: apiKey(),
|
||||
},
|
||||
});
|
||||
|
||||
ctx.state.data = {
|
||||
title: `Popular ${MEDIA_TYPE_TO_TITLE[mediaType]} — TMDB`,
|
||||
link: `https://www.themoviedb.org/${mediaType}`,
|
||||
item: data.results.map((item) => MEDIA_TYPE_TO_ITEM_HANDLE[mediaType](item, lang)),
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
const path = require('path');
|
||||
const { art } = require('@/utils/render');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
const handleDescription = (item) =>
|
||||
art(path.join(__dirname, 'templates/description.art'), {
|
||||
poster: `https://image.tmdb.org/t/p/original${item.poster_path ?? item.still_path}`,
|
||||
description: item.overview.trim(),
|
||||
vote_average: item.vote_average,
|
||||
vote_count: item.vote_count,
|
||||
});
|
||||
|
||||
const handleMovieItem = (item, lang) => ({
|
||||
title: lang ? item.title : item.original_title,
|
||||
link: `https://www.themoviedb.org/movie/${item.id}`,
|
||||
description: handleDescription(item),
|
||||
pubDate: parseDate(item.release_date),
|
||||
});
|
||||
|
||||
const handleTVShowItem = (item, lang) => ({
|
||||
title: lang ? item.name : item.original_name,
|
||||
link: `https://www.themoviedb.org/tv/${item.id}`,
|
||||
description: handleDescription(item),
|
||||
pubDate: parseDate(item.first_air_date),
|
||||
});
|
||||
|
||||
const MEDIA_TYPE_TO_ITEM_HANDLE = {
|
||||
tv: handleTVShowItem,
|
||||
movie: handleMovieItem,
|
||||
};
|
||||
|
||||
module.exports = { handleDescription, handleMovieItem, handleTVShowItem, MEDIA_TYPE_TO_ITEM_HANDLE };
|
||||
Loading…
Reference in New Issue