diff --git a/backend/src/module/api/search.py b/backend/src/module/api/search.py index beaa18fb..570e944b 100644 --- a/backend/src/module/api/search.py +++ b/backend/src/module/api/search.py @@ -1,7 +1,7 @@ from fastapi import APIRouter, Query, Depends from fastapi.responses import StreamingResponse -from module.searcher import SearchTorrent +from module.searcher import SearchTorrent, SEARCH_CONFIG from module.security.api import get_current_user, UNAUTHORIZED from module.models import Torrent @@ -25,3 +25,10 @@ async def search_torrents( content=st.analyse_keyword(keywords=keywords, site=site), media_type="application/json", ) + + +@router.get("/provider", response_model=list[str]) +async def search_provider(current_user=Depends(get_current_user)): + if not current_user: + raise UNAUTHORIZED + return list(SEARCH_CONFIG.keys()) diff --git a/backend/src/module/searcher/__init__.py b/backend/src/module/searcher/__init__.py index 534573fe..9630e420 100644 --- a/backend/src/module/searcher/__init__.py +++ b/backend/src/module/searcher/__init__.py @@ -1 +1,2 @@ from .searcher import SearchTorrent +from .provider import SEARCH_CONFIG diff --git a/backend/src/module/searcher/plugin/__init__.py b/backend/src/module/searcher/plugin/__init__.py deleted file mode 100644 index 49ca7df0..00000000 --- a/backend/src/module/searcher/plugin/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -from .mikan import mikan_url -from .nyaa import nyaa_url -from .dmhy import dmhy_url - - -def search_url(site: str, keywords: list[str]): - if site == "mikan": - return mikan_url(keywords) - elif site == "nyaa": - return nyaa_url(keywords) - elif site == "dmhy": - return dmhy_url(keywords) - else: - raise NotImplementedError(f"site {site} is not supported") diff --git a/backend/src/module/searcher/plugin/dmhy.py b/backend/src/module/searcher/plugin/dmhy.py deleted file mode 100644 index c8323feb..00000000 --- a/backend/src/module/searcher/plugin/dmhy.py +++ /dev/null @@ -1,8 +0,0 @@ -import re - - -def dmhy_url(keywords: list[str]): - keyword = "+".join(keywords) - search_str = re.sub(r"[\W_ ]", "+", keyword) - url = f"http://dmhy.org/topics/rss/rss.xml?keyword={search_str}" - return url diff --git a/backend/src/module/searcher/plugin/mikan.py b/backend/src/module/searcher/plugin/mikan.py deleted file mode 100644 index 0c2b7b3a..00000000 --- a/backend/src/module/searcher/plugin/mikan.py +++ /dev/null @@ -1,8 +0,0 @@ -import re - - -def mikan_url(keywords: list[str]): - keyword = "+".join(keywords) - search_str = re.sub(r"[\W_ ]", "+", keyword) - url = f"https://mikanani.me/RSS/Search?searchstr={search_str}" - return url diff --git a/backend/src/module/searcher/plugin/nyaa.py b/backend/src/module/searcher/plugin/nyaa.py deleted file mode 100644 index 83686192..00000000 --- a/backend/src/module/searcher/plugin/nyaa.py +++ /dev/null @@ -1,8 +0,0 @@ -import re - - -def nyaa_url(keywords: list[str]): - keyword = "+".join(keywords) - search_str = re.sub(r"[\W_ ]", "+", keyword) - url = f"https://nyaa.si/?page=rss&q={search_str}&c=0_0&f=0" - return url diff --git a/backend/src/module/searcher/provider.py b/backend/src/module/searcher/provider.py new file mode 100644 index 00000000..25e20287 --- /dev/null +++ b/backend/src/module/searcher/provider.py @@ -0,0 +1,21 @@ +import re + +from module.utils import json_config +from module.models import RSSItem + + +SEARCH_CONFIG = json_config.load("config/search_provider.json") + + +def search_url(site: str, keywords: list[str]) -> RSSItem: + keyword = "+".join(keywords) + search_str = re.sub(r"[\W_ ]", "+", keyword) + if site in SEARCH_CONFIG.keys(): + url = re.sub(r"%s", search_str, SEARCH_CONFIG[site]) + rss_item = RSSItem( + url=url, + parser="mikan" + ) + return rss_item + else: + raise ValueError(f"Site {site} is not supported") \ No newline at end of file diff --git a/backend/src/module/searcher/searcher.py b/backend/src/module/searcher/searcher.py index 4a4c388e..363e97f4 100644 --- a/backend/src/module/searcher/searcher.py +++ b/backend/src/module/searcher/searcher.py @@ -1,10 +1,10 @@ import json -from module.models import Bangumi, Torrent +from module.models import Bangumi, Torrent, RSSItem from module.network import RequestContent from module.rss import RSSAnalyser -from module.searcher.plugin import search_url +from .provider import search_url SEARCH_KEY = [ "group_name", @@ -18,29 +18,28 @@ SEARCH_KEY = [ class SearchTorrent(RequestContent, RSSAnalyser): def search_torrents( - self, keywords: list[str], site: str = "mikan", limit: int = 5 + self, rss_item: RSSItem, limit: int = 5 ) -> list[Torrent]: - url = search_url(site, keywords) - torrents = self.get_torrents(url, limit=limit) + torrents = self.get_torrents(rss_item.url, limit=limit) return torrents def analyse_keyword(self, keywords: list[str], site: str = "mikan"): - bangumis = [] - torrents = self.search_torrents(keywords, site) + rss_item = search_url(site, keywords) + torrents = self.search_torrents(rss_item) # Generate a list of json yield "[" for idx, torrent in enumerate(torrents): - bangumi = self.torrent_to_data(torrent) + bangumi = self.torrent_to_data(torrent=torrent, rss=rss_item) if bangumi: yield json.dumps(bangumi.dict()) if idx != len(torrents) - 1: yield "," yield "]" - # Analyse bangumis def search_season(self, data: Bangumi): keywords = [getattr(data, key) for key in SEARCH_KEY if getattr(data, key)] - torrents = self.search_torrents(keywords) + url = search_url("mikan", keywords) + torrents = self.search_torrents(url) return [torrent for torrent in torrents if data.title_raw in torrent.name] diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 235baf96..596351a1 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -16,7 +16,9 @@ export default defineConfig({ ['meta', { property: 'og:image', content: '/social.png' }], ['meta', { property: 'og:site_name', content: 'AutoBangumi' }], ['meta', { property: 'og:url', content: 'https://www.autobangumi.org' }], - ["script", { src: '/_vercel/insights/script.js' }] + ["script", { src: '/_vercel/insights/script.js' }], + ["script", { src: 'https://www.googletagmanager.com/gtag/js?id=G-3Z8W6WMN7J' }], + ["script", {}, "window.dataLayer = window.dataLayer || [];\nfunction gtag(){dataLayer.push(arguments);}\ngtag('js', new Date());\ngtag('config', 'G-3Z8W6WMN7J');"], ], themeConfig: { diff --git a/docs/deploy/dsm.md b/docs/deploy/dsm.md index 430425cb..1c075a18 100644 --- a/docs/deploy/dsm.md +++ b/docs/deploy/dsm.md @@ -40,5 +40,84 @@ services: 完成创建之后进入 `http://:7892` 即可进入 AB 并进行配置。 +## 通过 Docker compose 安装配置 AB 和 qBittorrent +在同时拥有代理和ipv6的情况下,群晖nas提供的docker配置ipv6极为复杂,推荐直接将AB和qBittorrent安装到host网络下,降低工作量。 + +以下内容的使用条件为:在docker上已经部署好了一个clash代理,并能够通过本地ip的指定端口进行访问。 + +参考上一节的内容,将以下内容经过调整填入 **Docker Compose** 中。 + +```yaml +version: "3.2" +services: + qbittorrent: + container_name: qBittorrent + environment: + - TZ=Asia/Shanghai + - TemPath=/downloads + - SavePath=/downloads + - PGID=1000 #需要自行修改填入 + - PUID=1000 #需要自行修改填入 + - WEBUI_PORT=8080 #建议自行修改端口号 + volumes: + - /volume1/docker/qb/config:/config + - /volume1/docker/qb/downloads:/downloads # 填入下载路径 + ports: + - 8080:8080 # 建议自行修改端口号 + - "6881:6881" + - "6881:6881/udp" + network_mode: + host + restart: unless-stopped + image: superng6/qbittorrent + + auto_bangumi: + container_name: AutoBangumi + environment: + - TZ=Asia/Shanghai + - PGID=1000 #需要自行修改填入 + - PUID=1000 #需要自行修改填入 + - AB_DOWNLOADER_HOST=127.0.0.1:8080 #建议自行修改端口号 + volumes: + - /volume1/docker/ab/config:/app/config + - /volume1/docker/ab/data:/app/data + network_mode: + host + ports: + - '7892:7892' + dns: + - 8.8.8.8 + - 223.5.5.5 + restart: unless-stopped + image: estrellaxd/auto_bangumi:latest + depends_on: + - qbittorrent + +``` + +## 补充说明 + +其中的 PGID 与 PUID 需要自行寻找,群晖的新 NAS 通常应该是:`PUID=1026,PGID=100`,qBittorrent 对应的端口号在修改时注意保证所有位置全部修改完成。 + +如果需要设置代理,请参考: [设置代理](../config/proxy) + +如果使用较低性能的机器,默认的配置有概率会大量占用 **CPU**,使得 AB 无法链接 qB 且 qB 的 WebUI 无法正常登陆的情况。 + +以 220+ 为例,qB 参考配置如下,减少下载与上传的连接数,降低 CPU 占用。 + +- 设置 -> 链接 -> 链接限制 + - 全局最大连接数: 300 + - 每torrent最大连接数: 60 + - 全局上传窗口数上限: 15 + - 每个torrent上传窗口数上限: 4 +- BitTorrent + - 最大活跃检查种子数 1 + - Torrent排队 + - 最大活动的下载数: 3 + - 最大活动的上传数: 5 + - 最大活动的torrent数: 10 +- RSS +- RSS阅读器 + - 每个订阅源文章数目最大值: 50 diff --git a/webui/public/images/apple-touch-icon-180x180.png b/webui/public/images/apple-touch-icon-180x180.png index c945839a..9464d94f 100644 Binary files a/webui/public/images/apple-touch-icon-180x180.png and b/webui/public/images/apple-touch-icon-180x180.png differ diff --git a/webui/public/images/pwa-192.png b/webui/public/images/pwa-192.png new file mode 100644 index 00000000..1c97fdd0 Binary files /dev/null and b/webui/public/images/pwa-192.png differ diff --git a/webui/public/images/pwa-512.png b/webui/public/images/pwa-512.png index b26959f7..3235fada 100644 Binary files a/webui/public/images/pwa-512.png and b/webui/public/images/pwa-512.png differ diff --git a/webui/src/pages/login.vue b/webui/src/pages/login.vue index fdaa6211..55d4c43d 100644 --- a/webui/src/pages/login.vue +++ b/webui/src/pages/login.vue @@ -39,8 +39,8 @@ definePage({ -
-
{{ $t('login.default') }}: admin adminadmin
-
+ + + diff --git a/webui/vite.config.ts b/webui/vite.config.ts index 5de8be04..f9992373 100644 --- a/webui/vite.config.ts +++ b/webui/vite.config.ts @@ -56,8 +56,9 @@ export default defineConfig({ globPatterns: ['**/*.{js,css,html,ico,png,svg}'], }, manifest: { - name: 'Auto_Bangumi', - short_name: 'Auto_Bangumi', + name: 'AutoBangumi', + display: 'standalone', + short_name: 'AutoBangumi', description: 'Automated Bangumi Download Tool', theme_color: '#ffffff', icons: [ @@ -67,6 +68,11 @@ export default defineConfig({ type: 'image/svg+xml', purpose: 'any', }, + { + src: '/images/pwa-192.png', + sizes: '192x192', + type: 'image/png', + }, { src: '/images/pwa-512.png', sizes: '512x512',