feat(route): add route "BaoBua" (#18762)

* feat(route): add route "BaoBua"

* perf(route/baobua): cache paginated content to reduce API requests

* Revert "perf(route/baobua): cache paginated content to reduce API requests"

This reverts commit 200616c15a.

* feat(route): add route "BaoBua"
This commit is contained in:
AiraNadih
2025-04-04 18:44:05 +08:00
committed by GitHub
parent 7dbb6ccfd7
commit d75bedb50b
6 changed files with 240 additions and 0 deletions
+51
View File
@@ -0,0 +1,51 @@
import { load } from 'cheerio';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
async function loadArticle(link) {
const resp = await got(link);
const article = load(resp.body);
const title = article('title')
.text()
.replace('BaoBua.Com:', '')
.replace(/\| Page \d+\/\d+/, '')
.trim();
const totalPagesRegex = /Page \d+\/(\d+)/;
const totalPagesMatch = totalPagesRegex.exec(article('title').text());
const totalPages = totalPagesMatch ? Number.parseInt(totalPagesMatch[1]) : 1;
let pubDate;
const blogPostingScript = article('script:contains("BlogPosting")').first();
if (blogPostingScript) {
const jsonData = JSON.parse(blogPostingScript.text());
pubDate = parseDate(jsonData.datePublished);
}
const contentDiv = article('.contentme2');
let description = contentDiv.html() ?? '';
if (totalPages > 1) {
const additionalContents = await Promise.all(
Array.from({ length: totalPages - 1 }, async (_, i) => {
try {
const response = await got(`${link}?page=${i + 2}`);
const pageDom = load(response.body);
return pageDom('.contentme2').html() ?? '';
} catch {
return '';
}
})
);
description += additionalContents.join('');
}
return {
title,
description,
pubDate,
link,
};
}
export default loadArticle;
+60
View File
@@ -0,0 +1,60 @@
import { Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { load } from 'cheerio';
import { SUB_NAME_PREFIX, SUB_URL } from './const';
import loadArticle from './article';
export const route: Route = {
path: '/category/:category',
categories: ['picture'],
example: '/baobua/category/network',
parameters: { category: 'Category' },
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
radar: [
{
source: ['baobua.com/cat/:category'],
target: '/category/:category',
},
],
name: 'Category',
maintainers: ['AiraNadih'],
handler,
url: 'baobua.com/',
};
async function handler(ctx) {
const category = ctx.req.param('category');
const url = `${SUB_URL}cat/${category}/`;
const response = await got(url);
const $ = load(response.body);
const itemRaw = $('.thcovering-video').toArray();
return {
title: `${SUB_NAME_PREFIX} - Category: ${category}`,
link: url,
item: await Promise.all(
itemRaw
.map((e) => {
const item = $(e);
let link = item.find('a').attr('href');
if (!link) {
return null;
}
if (link.startsWith('/')) {
link = new URL(link, SUB_URL).href;
}
return cache.tryGet(link, () => loadArticle(link));
})
.filter(Boolean)
),
};
}
+4
View File
@@ -0,0 +1,4 @@
const SUB_NAME_PREFIX = 'BaoBua';
const SUB_URL = 'https://baobua.com/';
export { SUB_NAME_PREFIX, SUB_URL };
+57
View File
@@ -0,0 +1,57 @@
import { Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { load } from 'cheerio';
import { SUB_NAME_PREFIX, SUB_URL } from './const';
import loadArticle from './article';
export const route: Route = {
path: '/',
categories: ['picture'],
example: '/baobua',
parameters: {},
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
radar: [
{
source: ['baobua.com/'],
target: '',
},
],
name: 'Latest',
maintainers: ['AiraNadih'],
handler,
url: 'baobua.com/',
};
async function handler() {
const response = await got(SUB_URL);
const $ = load(response.body);
const itemRaw = $('.thcovering-video').toArray();
return {
title: `${SUB_NAME_PREFIX} - Latest`,
link: SUB_URL,
item: await Promise.all(
itemRaw
.map((e) => {
const item = $(e);
let link = item.find('a').attr('href');
if (!link) {
return null;
}
if (link.startsWith('/')) {
link = new URL(link, SUB_URL).href;
}
return cache.tryGet(link, () => loadArticle(link));
})
.filter(Boolean)
),
};
}
+8
View File
@@ -0,0 +1,8 @@
import type { Namespace } from '@/types';
export const namespace: Namespace = {
name: 'BaoBua',
url: 'baobua.com',
description: 'BaoBua.Com - Hot beauty girl pics, girls photos, free watch online hd photo sets',
lang: 'en',
};
+60
View File
@@ -0,0 +1,60 @@
import { Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { load } from 'cheerio';
import { SUB_NAME_PREFIX, SUB_URL } from './const';
import loadArticle from './article';
export const route: Route = {
path: '/search/:keyword',
categories: ['picture'],
example: '/baobua/search/cos',
parameters: { keyword: 'Keyword' },
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
radar: [
{
source: ['baobua.com/search'],
target: '/search/:keyword',
},
],
name: 'Search',
maintainers: ['AiraNadih'],
handler,
url: 'baobua.com/',
};
async function handler(ctx) {
const keyword = ctx.req.param('keyword');
const url = `${SUB_URL}search?q=${keyword}`;
const response = await got(url);
const $ = load(response.body);
const itemRaw = $('.thcovering-video').toArray();
return {
title: `${SUB_NAME_PREFIX} - Search: ${keyword}`,
link: url,
item: await Promise.all(
itemRaw
.map((e) => {
const item = $(e);
let link = item.find('a').attr('href');
if (!link) {
return null;
}
if (link.startsWith('/')) {
link = new URL(link, SUB_URL).href;
}
return cache.tryGet(link, () => loadArticle(link));
})
.filter(Boolean)
),
};
}