feat: add projectjav actress (#21698)
This commit is contained in:
parent
d375d79d8b
commit
72d4ee7ab4
|
|
@ -0,0 +1,36 @@
|
|||
import type { Route } from '@/types';
|
||||
|
||||
import { processItems, rootUrl } from './utils';
|
||||
|
||||
export const route: Route = {
|
||||
path: '/actress/:id',
|
||||
categories: ['multimedia'],
|
||||
example: '/projectjav/actress/rima-arai-22198',
|
||||
parameters: { id: 'Actress ID or slug, can be found in the actress page URL' },
|
||||
features: {
|
||||
requireConfig: false,
|
||||
requirePuppeteer: false,
|
||||
antiCrawler: false,
|
||||
supportBT: false,
|
||||
supportPodcast: false,
|
||||
supportScihub: false,
|
||||
nsfw: true,
|
||||
},
|
||||
radar: [
|
||||
{
|
||||
source: ['projectjav.com/actress/:id'],
|
||||
target: '/actress/:id',
|
||||
},
|
||||
],
|
||||
name: 'Actress',
|
||||
maintainers: ['Exat1979'],
|
||||
handler,
|
||||
url: 'projectjav.com/',
|
||||
description: 'Fetches the latest movies from a specific actress page on ProjectJAV.',
|
||||
};
|
||||
|
||||
async function handler(ctx) {
|
||||
const id = ctx.req.param('id').replace(/\/$/, '');
|
||||
const currentUrl = `${rootUrl}/actress/${id}`;
|
||||
return await processItems(currentUrl);
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import type { Namespace } from '@/types';
|
||||
|
||||
export const namespace: Namespace = {
|
||||
name: 'ProjectJAV',
|
||||
url: 'projectjav.com',
|
||||
description: 'ProjectJAV provides adult video content information and streaming.',
|
||||
lang: 'en',
|
||||
};
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
import { load } from 'cheerio';
|
||||
|
||||
import type { DataItem } from '@/types';
|
||||
import cache from '@/utils/cache';
|
||||
import got from '@/utils/got';
|
||||
import { parseDate } from '@/utils/parse-date';
|
||||
|
||||
const rootUrl = 'https://projectjav.com';
|
||||
const processItems = async (currentUrl: string) => {
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: currentUrl,
|
||||
});
|
||||
|
||||
const $ = load(response.data);
|
||||
|
||||
let items: DataItem[] = $('div.video-item')
|
||||
.toArray()
|
||||
.map((element) => {
|
||||
const item = $(element);
|
||||
const link = item.find('a').attr('href');
|
||||
return {
|
||||
title: item.find('div.name span').text() || '',
|
||||
link: link?.startsWith('http') ? link : `${rootUrl}${link}`,
|
||||
};
|
||||
})
|
||||
.filter((item) => item.link && /\/movie\/.*/.test(item.link));
|
||||
|
||||
items = await Promise.all(
|
||||
items.map((item) =>
|
||||
cache.tryGet(item.link!, async () => {
|
||||
const detailResponse = await got({
|
||||
method: 'get',
|
||||
url: item.link,
|
||||
});
|
||||
|
||||
const content = load(detailResponse.data);
|
||||
|
||||
// Remove ads
|
||||
content('div.top-banner-ads, div.bottom-content-ads').remove();
|
||||
|
||||
// Get main content
|
||||
const mainContent = content('main');
|
||||
|
||||
// Extract title
|
||||
const h1Title = mainContent.find('h1').text().trim();
|
||||
if (h1Title) {
|
||||
item.title = h1Title;
|
||||
}
|
||||
|
||||
// Extract categories
|
||||
const categories = mainContent
|
||||
.find('div.badge a')
|
||||
.toArray()
|
||||
.map((v) => content(v).text().trim())
|
||||
.filter(Boolean);
|
||||
if (categories.length > 0) {
|
||||
item.category = categories;
|
||||
}
|
||||
|
||||
// Extract author/actress (support multiple actresses)
|
||||
const actresses = mainContent
|
||||
.find('div.actress-item a')
|
||||
.toArray()
|
||||
.map((v) => content(v).text().trim())
|
||||
.filter(Boolean);
|
||||
if (actresses.length > 0) {
|
||||
item.author = actresses.join(', ');
|
||||
}
|
||||
|
||||
// Extract date
|
||||
const dateEl = mainContent
|
||||
.find('div.second-main~div.row>div.col-3')
|
||||
.toArray()
|
||||
.find((el) => content(el).text().includes('Date added'));
|
||||
const dateText = dateEl ? content(dateEl).next().text().trim() : null;
|
||||
if (dateText) {
|
||||
// ProjectJAV uses DD/MM/YYYY format
|
||||
item.pubDate = parseDate(dateText, 'DD/MM/YYYY');
|
||||
}
|
||||
|
||||
// Get description
|
||||
item.description = mainContent.html() || '';
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
return {
|
||||
title: $('title').text() || 'ProjectJAV',
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
||||
export { processItems, rootUrl };
|
||||
Loading…
Reference in New Issue