动漫磁力搜索增加nyaa;动漫磁力搜索前可选站点

This commit is contained in:
mtvpls
2026-06-20 12:43:16 +08:00
parent 20c073430b
commit ec71a252c9
12 changed files with 364 additions and 46 deletions
+2 -1
View File
@@ -42,6 +42,7 @@ export interface AdminConfig {
MagnetMikanReverseProxy?: string;
MagnetDmhyReverseProxy?: string;
MagnetAcgripReverseProxy?: string;
MagnetNyaaReverseProxy?: string;
// 评论功能开关
EnableComments: boolean;
// 自定义去广告代码
@@ -358,7 +359,7 @@ export interface AdminConfig {
id: string;
title: string;
filterText: string;
source: 'acgrip' | 'mikan' | 'dmhy';
source: 'acgrip' | 'mikan' | 'dmhy' | 'nyaa';
enabled: boolean;
lastCheckTime: number;
lastEpisode: number;
+56 -16
View File
@@ -3,6 +3,7 @@ import parseTorrentName from 'parse-torrent-name';
import { parseStringPromise } from 'xml2js';
import { getConfig, setCachedConfig } from '@/lib/config';
import { getMagnetBaseUrl, universalMagnetFetch } from '@/lib/magnet.client';
import { db, getStorage } from '@/lib/db';
import { EmailService } from '@/lib/email.service';
import {
@@ -14,6 +15,14 @@ import { AnimeSubscription, AnimeSubscriptionDownloadTool } from '@/types/anime-
const downloadTools: AnimeSubscriptionDownloadTool[] = ['aria2', 'qBittorrent', 'Transmission'];
const pickRssText = (value: any): string => {
if (value === undefined || value === null) return '';
const first = Array.isArray(value) ? value[0] : value;
if (first === undefined || first === null) return '';
if (typeof first === 'object') return String(first._ ?? first.$?.url ?? first.$?.href ?? '');
return String(first);
};
function getAnimeSubscriptionDownloadTool(tool: unknown): AnimeSubscriptionDownloadTool {
return typeof tool === 'string' && downloadTools.includes(tool as AnimeSubscriptionDownloadTool)
? tool as AnimeSubscriptionDownloadTool
@@ -65,26 +74,50 @@ export function matchesFilter(title: string, filterText: string): boolean {
*/
export async function searchACG(
keyword: string,
source: 'acgrip' | 'mikan' | 'dmhy'
source: 'acgrip' | 'mikan' | 'dmhy' | 'nyaa'
) {
const trimmedKeyword = keyword.trim();
const config = await getConfig();
let searchUrl: string;
switch (source) {
case 'mikan':
searchUrl = `https://mikanani.me/RSS/Search?searchstr=${encodeURIComponent(trimmedKeyword)}`;
case 'mikan': {
const baseUrl = getMagnetBaseUrl(
'https://mikanani.me',
config.SiteConfig.MagnetMikanReverseProxy
);
searchUrl = `${baseUrl}/RSS/Search?searchstr=${encodeURIComponent(trimmedKeyword)}`;
break;
case 'dmhy':
searchUrl = `http://share.dmhy.org/topics/rss/rss.xml?keyword=${encodeURIComponent(trimmedKeyword)}`;
}
case 'dmhy': {
const baseUrl = getMagnetBaseUrl(
'http://share.dmhy.org',
config.SiteConfig.MagnetDmhyReverseProxy
);
searchUrl = `${baseUrl}/topics/rss/rss.xml?keyword=${encodeURIComponent(trimmedKeyword)}`;
break;
}
case 'nyaa': {
const baseUrl = getMagnetBaseUrl(
'https://nyaa.si',
config.SiteConfig.MagnetNyaaReverseProxy
);
searchUrl = `${baseUrl}/?page=rss&q=${encodeURIComponent(trimmedKeyword)}&c=1_0&f=0`;
break;
}
case 'acgrip':
default:
searchUrl = `https://acg.rip/page/1.xml?term=${encodeURIComponent(trimmedKeyword)}`;
default: {
const baseUrl = getMagnetBaseUrl(
'https://acg.rip',
config.SiteConfig.MagnetAcgripReverseProxy
);
searchUrl = `${baseUrl}/page/1.xml?term=${encodeURIComponent(trimmedKeyword)}`;
break;
}
}
const response = await fetch(searchUrl, {
const response = await universalMagnetFetch(searchUrl, config.SiteConfig.MagnetProxy, {
headers: {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
@@ -104,14 +137,21 @@ export async function searchACG(
const items = parsed.rss.channel[0].item;
// 统一格式
// 统一格式。注意:Nyaa RSS 的 link 是 .torrent 下载地址,guid 才是详情页。
return items.map((item: any) => {
const title = item.title?.[0] || '';
const link = item.link?.[0] || '';
const guid = item.guid?.[0] || link || `${title}-${item.pubDate?.[0] || ''}`;
const pubDate = item.pubDate?.[0] || '';
const torrentUrl = item.enclosure?.[0]?.$?.url || '';
const description = item.description?.[0] || '';
const title = pickRssText(item.title);
const rawLink = pickRssText(item.link);
const rawGuid = pickRssText(item.guid);
const pubDate = pickRssText(item.pubDate);
const description = pickRssText(item.description) || pickRssText(item['content:encoded']);
const enclosureUrl =
pickRssText(item.enclosure?.[0]?.$?.url) ||
pickRssText(item.enclosure?.[0]?.$?.href);
const isNyaa = source === 'nyaa';
const link = isNyaa ? (rawGuid || rawLink) : rawLink;
const torrentUrl = isNyaa ? rawLink : enclosureUrl;
const guid = rawGuid || link || torrentUrl || `${title}-${pubDate}`;
return {
title,
@@ -237,7 +277,7 @@ async function sendAnimeUpdateNotifications(
<div style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; margin: 20px 0;">
<h3 style="margin-top: 0; color: #2563eb;">${subscription.title}</h3>
<p style="margin: 10px 0;">新增集数:第 ${episodeList} 集</p>
<p style="margin: 10px 0; color: #666;">搜索源:${subscription.source === 'acgrip' ? 'ACG.RIP' : subscription.source === 'mikan' ? '蜜柑' : '动漫花园'}</p>
<p style="margin: 10px 0; color: #666;">搜索源:${subscription.source === 'acgrip' ? 'ACG.RIP' : subscription.source === 'mikan' ? '蜜柑' : subscription.source === 'nyaa' ? 'Nyaa' : '动漫花园'}</p>
</div>
<p style="color: #666; font-size: 14px;">这些集数已自动添加到 OpenList 离线下载队列。</p>
<hr style="border: none; border-top: 1px solid #eee; margin: 20px 0;">
+5
View File
@@ -313,6 +313,7 @@ async function getInitConfig(
MagnetMikanReverseProxy: '',
MagnetDmhyReverseProxy: '',
MagnetAcgripReverseProxy: '',
MagnetNyaaReverseProxy: '',
// 评论功能开关
EnableComments: false,
EnableRegistration: false,
@@ -509,6 +510,7 @@ export function configSelfCheck(adminConfig: AdminConfig): AdminConfig {
MagnetMikanReverseProxy: '',
MagnetDmhyReverseProxy: '',
MagnetAcgripReverseProxy: '',
MagnetNyaaReverseProxy: '',
EnableComments: false,
EnableRegistration: false,
RequireRegistrationInviteCode: false,
@@ -579,6 +581,9 @@ export function configSelfCheck(adminConfig: AdminConfig): AdminConfig {
if (adminConfig.SiteConfig.MagnetAcgripReverseProxy === undefined) {
adminConfig.SiteConfig.MagnetAcgripReverseProxy = '';
}
if (adminConfig.SiteConfig.MagnetNyaaReverseProxy === undefined) {
adminConfig.SiteConfig.MagnetNyaaReverseProxy = '';
}
if (!adminConfig.UserConfig) {
adminConfig.UserConfig = { Users: [] };
}