diff --git a/lib/routes/pornhub/category-url.ts b/lib/routes/pornhub/category-url.ts index ae583e23f..d1a43df4d 100644 --- a/lib/routes/pornhub/category-url.ts +++ b/lib/routes/pornhub/category-url.ts @@ -8,10 +8,10 @@ import { isValidHost } from '@/utils/valid-host'; import { headers, parseItems } from './utils'; export const route: Route = { - path: '/category_url/:url?/:language?', + path: '/category_url/:url?/:language?/:img?', categories: ['multimedia'], example: '/pornhub/category_url/video%3Fc%3D15%26o%3Dmv%26t%3Dw%26cc%3Djp', - parameters: { language: 'language, see below', url: 'relative path after `pornhub.com/`, need to be URL encoded' }, + parameters: { language: 'language, see below. defaults to `www` (English)', url: 'relative path after `pornhub.com/`, need to be URL encoded', img: 'show images, set to `img=1` to enable' }, features: { requireConfig: false, requirePuppeteer: false, @@ -34,7 +34,7 @@ export const route: Route = { }; async function handler(ctx) { - const { language = 'www', url = 'video' } = ctx.req.param(); + const { language = 'www', url = 'video', img } = ctx.req.param(); const link = `https://${language}.pornhub.com/${url}`; if (!isValidHost(language)) { throw new InvalidParameterError('Invalid language'); @@ -42,14 +42,15 @@ async function handler(ctx) { const { data: response } = await got(link, { headers }); const $ = load(response); + const showImages = img === 'img=1'; const items = $('#videoCategory .videoBox') .toArray() - .map((e) => parseItems($(e))); + .map((e) => parseItems($(e), showImages)); return { title: $('title').first().text(), link, - language: $('html').attr('lang'), + language: $('html').attr('lang') as any, item: items, }; } diff --git a/lib/routes/pornhub/category.ts b/lib/routes/pornhub/category.ts index 46d1103e7..bb671e3a4 100644 --- a/lib/routes/pornhub/category.ts +++ b/lib/routes/pornhub/category.ts @@ -8,11 +8,11 @@ import { parseDate } from '@/utils/parse-date'; import { defaultDomain, renderDescription } from './utils'; export const route: Route = { - path: '/category/:caty', + path: '/category/:caty/:img?', categories: ['multimedia'], view: ViewType.Videos, example: '/pornhub/category/popular-with-women', - parameters: { caty: 'category, see [categories](https://www.pornhub.com/webmasters/categories)' }, + parameters: { caty: 'category, see [categories](https://www.pornhub.com/webmasters/categories)', img: 'show images, set to `img=1` to enable' }, features: { requireConfig: false, requirePuppeteer: false, @@ -28,7 +28,7 @@ export const route: Route = { }; async function handler(ctx) { - const category = ctx.req.param('caty'); + const { caty: category, img } = ctx.req.param(); const categories = await cache.tryGet('pornhub:categories', async () => { const { data } = await got(`${defaultDomain}/webmasters/categories`); @@ -52,10 +52,12 @@ async function handler(ctx) { throw new Error(response.message); } + const showImages = img === 'img=1'; + const list = response.videos.map((item) => ({ title: item.title, link: item.url, - description: renderDescription({ thumbs: item.thumbs }), + description: renderDescription({ thumbs: item.thumbs }, showImages), pubDate: parseDate(item.publish_date), category: [...new Set([...item.tags.map((t) => t.tag_name), ...item.categories.map((c) => c.category)])], })); diff --git a/lib/routes/pornhub/model.ts b/lib/routes/pornhub/model.ts index cb53a52c4..a55ea8ff9 100644 --- a/lib/routes/pornhub/model.ts +++ b/lib/routes/pornhub/model.ts @@ -9,11 +9,16 @@ import { isValidHost } from '@/utils/valid-host'; import { getRadarDomin, headers, parseItems } from './utils'; export const route: Route = { - path: '/model/:username/:language?/:sort?', + path: '/model/:username/:language?/:sort?/:img?', categories: ['multimedia'], view: ViewType.Videos, example: '/pornhub/model/stacy-starando', - parameters: { language: 'language, see below', username: 'username, part of the url e.g. `pornhub.com/model/stacy-starando`', sort: 'sorting method, see below' }, + parameters: { + language: 'language, see below. defaults to www', + username: 'username, part of the url e.g. `pornhub.com/model/stacy-starando`', + sort: 'sorting method, see below. Defaults to mr (most recent)', + img: 'show images, set to `img=1` to enable', + }, features: { requireConfig: false, requirePuppeteer: false, @@ -30,7 +35,7 @@ export const route: Route = { }; async function handler(ctx): Promise { - const { language = 'www', username, sort = '' } = ctx.req.param(); + const { language = 'www', username, sort = '', img } = ctx.req.param(); const link = `https://${language}.pornhub.com/model/${username}/videos${sort ? `?o=${sort}` : ''}`; if (!isValidHost(language)) { throw new InvalidParameterError('Invalid language'); @@ -38,16 +43,17 @@ async function handler(ctx): Promise { const { data: response } = await got(link, { headers }); const $ = load(response); + const showImages = img === 'img=1'; const items = $('#mostRecentVideosSection .videoBox') .toArray() - .map((e) => parseItems($(e))); + .map((e) => parseItems($(e), showImages)); return { title: $('h1').first().text(), description: $('section.aboutMeSection').text().trim(), link, image: $('#getAvatar').attr('src'), - language: $('html').attr('lang'), + language: $('html').attr('lang') as any, item: items, }; } diff --git a/lib/routes/pornhub/pornstar.ts b/lib/routes/pornhub/pornstar.ts index 06489745e..6c83d8486 100644 --- a/lib/routes/pornhub/pornstar.ts +++ b/lib/routes/pornhub/pornstar.ts @@ -9,7 +9,7 @@ import { isValidHost } from '@/utils/valid-host'; import { getRadarDomin, headers, parseItems } from './utils'; export const route: Route = { - path: '/pornstar/:username/:language?/:sort?', + path: '/pornstar/:username/:language?/:sort?/:img?', categories: ['multimedia'], view: ViewType.Videos, example: '/pornhub/pornstar/june-liu/www/mr', @@ -18,7 +18,7 @@ export const route: Route = { description: 'username, part of the url e.g. `pornhub.com/pornstar/june-liu`', }, language: { - description: 'language', + description: 'language, defaults to `www` (English)', options: [ { value: 'www', label: 'English' }, { value: 'de', label: 'Deutsch' }, @@ -36,7 +36,7 @@ export const route: Route = { default: 'www', }, sort: { - description: 'sorting method, leave empty for `Best`', + description: 'sorting method, defaults to `mr` (Most Recent)', options: [ { label: 'Most Recent', @@ -56,6 +56,7 @@ export const route: Route = { }, ], }, + img: 'show images, set to `img=1` to enable', }, features: { requireConfig: false, @@ -73,7 +74,7 @@ export const route: Route = { }; async function handler(ctx): Promise { - const { language = 'www', username, sort = 'mr' } = ctx.req.param(); + const { language = 'www', username, sort = 'mr', img } = ctx.req.param(); let link = `https://${language}.pornhub.com/pornstar/${username}?o=${sort}`; if (!isValidHost(language)) { throw new InvalidParameterError('Invalid language'); @@ -83,17 +84,19 @@ async function handler(ctx): Promise { let $ = load(response); let items; + const showImages = img === 'img=1'; + if ($('.withBio').length === 0) { link = `https://${language}.pornhub.com/pornstar/${username}/videos?o=${sort}`; const { data: response } = await got(link, { headers }); $ = load(response); items = $('#mostRecentVideosSection .videoBox') .toArray() - .map((e) => parseItems($(e))); + .map((e) => parseItems($(e), showImages)); } else { items = $('#pornstarsVideoSection .videoBox') .toArray() - .map((e) => parseItems($(e))); + .map((e) => parseItems($(e), showImages)); } return { @@ -101,7 +104,7 @@ async function handler(ctx): Promise { description: $('section.aboutMeSection').text().trim(), link, image: $('#getAvatar').attr('src'), - language: $('html').attr('lang'), + language: $('html').attr('lang') as any, item: items, }; } diff --git a/lib/routes/pornhub/search.ts b/lib/routes/pornhub/search.ts index 62f2ebcf0..79e22f468 100644 --- a/lib/routes/pornhub/search.ts +++ b/lib/routes/pornhub/search.ts @@ -6,11 +6,11 @@ import { parseDate } from '@/utils/parse-date'; import { defaultDomain, renderDescription } from './utils'; export const route: Route = { - path: '/search/:keyword', + path: '/search/:keyword/:img?', categories: ['multimedia'], view: ViewType.Videos, example: '/pornhub/search/stepsister', - parameters: { keyword: 'keyword' }, + parameters: { keyword: 'keyword', img: 'show images, set to `img=1` to enable' }, features: { requireConfig: false, requirePuppeteer: false, @@ -26,14 +26,16 @@ export const route: Route = { }; async function handler(ctx) { - const keyword = ctx.req.param('keyword'); + const { keyword, img } = ctx.req.param(); const currentUrl = `${defaultDomain}/webmasters/search?search=${keyword}`; const response = await got(currentUrl); + const showImages = img === 'img=1'; + const list = response.data.videos.map((item) => ({ title: item.title, link: item.url, - description: renderDescription({ thumbs: item.thumbs }), + description: renderDescription({ thumbs: item.thumbs }, showImages), pubDate: parseDate(item.publish_date), category: [...new Set([...item.tags.map((t) => t.tag_name), ...item.categories.map((c) => c.category)])], })); diff --git a/lib/routes/pornhub/users.ts b/lib/routes/pornhub/users.ts index b14991ac5..03426ac34 100644 --- a/lib/routes/pornhub/users.ts +++ b/lib/routes/pornhub/users.ts @@ -8,10 +8,10 @@ import { isValidHost } from '@/utils/valid-host'; import { getRadarDomin, headers, parseItems } from './utils'; export const route: Route = { - path: '/users/:username/:language?', + path: '/users/:username/:language?/:img?', categories: ['multimedia'], example: '/pornhub/users/pornhubmodels', - parameters: { language: 'language, see below', username: 'username, part of the url e.g. `pornhub.com/users/pornhubmodels`' }, + parameters: { language: 'language, see below. defaults to `www` (English)', username: 'username, part of the url e.g. `pornhub.com/users/pornhubmodels`', img: 'show images, set to `img=1` to enable' }, features: { requireConfig: false, requirePuppeteer: false, @@ -28,7 +28,7 @@ export const route: Route = { }; async function handler(ctx): Promise { - const { language = 'www', username } = ctx.req.param(); + const { language = 'www', username, img } = ctx.req.param(); const link = `https://${language}.pornhub.com/users/${username}/videos`; if (!isValidHost(language)) { throw new InvalidParameterError('Invalid language'); @@ -36,16 +36,17 @@ async function handler(ctx): Promise { const { data: response } = await got(link, { headers }); const $ = load(response); + const showImages = img === 'img=1'; const items = $('.videoUList .videoBox') .toArray() - .map((e) => parseItems($(e))); + .map((e) => parseItems($(e), showImages)); return { title: $('.profileUserName a').text(), description: $('.aboutMeText').text().trim(), link, image: $('#getAvatar').attr('src'), - language: $('html').attr('lang'), + language: $('html').attr('lang') as any, allowEmpty: true, item: items, }; diff --git a/lib/routes/pornhub/utils.tsx b/lib/routes/pornhub/utils.tsx index 51607f380..9c5b6c640 100644 --- a/lib/routes/pornhub/utils.tsx +++ b/lib/routes/pornhub/utils.tsx @@ -10,7 +10,7 @@ const headers = { hasVisited: 1, }; -const renderDescription = (data): string => +const renderDescription = (data, showImages = false): string => renderToString( <> {data.previewVideo ? ( @@ -18,9 +18,12 @@ const renderDescription = (data): string => ) : null} - {data.thumbs?.map((thumb, index) => ( - - ))} + {showImages && + (data.thumbs ? ( + data.thumbs.map((thumb, index) => ) + ) : ( + + ))} ); const extractDateFromImageUrl = (imageUrl) => { @@ -28,13 +31,16 @@ const extractDateFromImageUrl = (imageUrl) => { return matchResult ? matchResult.slice(1, 3).join('') : null; }; -const parseItems = (e) => ({ +const parseItems = (e, showImages = false) => ({ title: e.find('span.title a').text().trim(), link: defaultDomain + e.find('span.title a').attr('href'), - description: renderDescription({ - poster: e.find('img').data('mediumthumb'), - previewVideo: e.find('img').data('mediabook'), - }), + description: renderDescription( + { + poster: e.find('img').data('mediumthumb'), + previewVideo: e.find('img').data('mediabook'), + }, + showImages + ), author: e.find('.usernameWrap a').text(), pubDate: dayjs(extractDateFromImageUrl(e.find('img').data('mediumthumb'))).toDate() || parseRelativeDate(e.find('.added').text()), });