Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.1.2 #472

Merged
merged 3 commits into from
Sep 26, 2023
Merged

3.1.2 #472

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions backend/src/module/api/bangumi.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ async def enable_rule(bangumi_id: str):
return u_response(resp)


@router.get(path="/refresh/poster/all", response_model=APIResponse, dependencies=[Depends(get_current_user)])
async def refresh_poster():
with TorrentManager() as manager:
resp = manager.refresh_poster()
return u_response(resp)


@router.get("/reset/all", response_model=APIResponse, dependencies=[Depends(get_current_user)])
async def reset_all():
with TorrentManager() as manager:
Expand Down
9 changes: 5 additions & 4 deletions backend/src/module/manager/collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@


class SeasonCollector(DownloadClient):
def collect_season(self, bangumi: Bangumi, link: str = None):
def collect_season(self, bangumi: Bangumi, link: str = None, limit: int = None):
logger.info(
f"Start collecting {bangumi.official_title} Season {bangumi.season}..."
)
with SearchTorrent() as st:
if not link:
torrents = st.search_season(bangumi)
torrents = st.search_season(bangumi, limit=limit)
else:
torrents = st.get_torrents(link, bangumi.filter.replace(",", "|"))
if self.add_torrent(torrents, bangumi):
logger.info(f"Collections of {bangumi.official_title} Season {bangumi.season} completed.")
bangumi.eps_collect = True
with RSSEngine() as engine:
engine.bangumi.update(bangumi)
engine.torrent.add_all(torrents)
return ResponseModel(
status=True,
status_code=200,
Expand Down Expand Up @@ -57,7 +58,7 @@ def eps_complete():
logger.info("Start collecting full season...")
for data in datas:
if not data.eps_collect:
with SeasonCollector() as sc:
sc.collect_season(data)
with SeasonCollector() as collector:
collector.collect_season(data)
data.eps_collect = True
engine.bangumi.update_all(datas)
18 changes: 17 additions & 1 deletion backend/src/module/manager/torrent.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import logging

from fastapi.responses import JSONResponse

from module.database import Database
from module.downloader import DownloadClient
from module.models import Bangumi, BangumiUpdate, ResponseModel
from module.parser import TitleParser

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -133,6 +133,18 @@ def update_rule(self, bangumi_id, data: BangumiUpdate):
msg_zh=f"无法找到 id {bangumi_id} 的数据",
)

def refresh_poster(self):
bangumis = self.bangumi.search_all()
for bangumi in bangumis:
if not bangumi.poster_link:
TitleParser().tmdb_poster_parser(bangumi)
self.bangumi.update_all(bangumis)
return ResponseModel(
status_code=200,
status=True,
msg_en=f"Refresh poster link successfully.",
msg_zh=f"刷新海报链接成功。",
)

def search_all_bangumi(self):
datas = self.bangumi.search_all()
Expand All @@ -152,3 +164,7 @@ def search_one(self, _id: int | str):
)
else:
return data

if __name__ == '__main__':
with TorrentManager() as manager:
manager.refresh_poster()
5 changes: 3 additions & 2 deletions backend/src/module/network/request_contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ def get_torrents(
torrents.append(
Torrent(name=_title, url=torrent_url, homepage=homepage)
)
if len(torrents) >= limit:
break
if isinstance(limit, int):
if len(torrents) >= limit:
break
return torrents
else:
logger.warning(f"[Network] Failed to get torrents: {_url}")
Expand Down
10 changes: 10 additions & 0 deletions backend/src/module/parser/title_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ def tmdb_parser(title: str, season: int, language: str):
logger.warning("Please change bangumi info manually.")
return title, season, None, None

@staticmethod
def tmdb_poster_parser(bangumi: Bangumi):
tmdb_info = tmdb_parser(bangumi.official_title, settings.rss_parser.language)
if tmdb_info:
logger.debug(f"TMDB Matched, official title is {tmdb_info.title}")
bangumi.poster_link = tmdb_info.poster_link
else:
logger.warning(f"Cannot match {bangumi.official_title} in TMDB. Use raw title instead.")
logger.warning("Please change bangumi info manually.")

@staticmethod
def raw_parser(raw: str) -> Bangumi | None:
language = settings.rss_parser.language
Expand Down
4 changes: 2 additions & 2 deletions backend/src/module/searcher/searcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def special_url(data: Bangumi, site: str) -> RSSItem:
url = search_url(site, keywords)
return url

def search_season(self, data: Bangumi, site: str = "mikan") -> list[Torrent]:
def search_season(self, data: Bangumi, site: str = "mikan", limit: int = None) -> list[Torrent]:
rss_item = self.special_url(data, site)
torrents = self.search_torrents(rss_item)
torrents = self.search_torrents(rss_item, limit=limit)
return [torrent for torrent in torrents if data.title_raw in torrent.name]
236 changes: 122 additions & 114 deletions webui/src/api/bangumi.ts
Original file line number Diff line number Diff line change
@@ -1,129 +1,137 @@
import type { BangumiAPI, BangumiRule } from '#/bangumi';
import type { ApiSuccess } from '#/api';
import type {BangumiAPI, BangumiRule} from '#/bangumi';
import type {ApiSuccess} from '#/api';


export const apiBangumi = {
/**
* 获取所有 bangumi 数据
* @returns 所有 bangumi 数据
*/
async getAll() {
const { data } = await axios.get<BangumiAPI[]>('api/v1/bangumi/get/all');
const result: BangumiRule[] = data.map((bangumi) => (
{
...bangumi,
filter: bangumi.filter.split(','),
rss_link: bangumi.rss_link.split(','),
/**
* 获取所有 bangumi 数据
* @returns 所有 bangumi 数据
*/
async getAll() {
const {data} = await axios.get<BangumiAPI[]>('api/v1/bangumi/get/all');
const result: BangumiRule[] = data.map((bangumi) => (
{
...bangumi,
filter: bangumi.filter.split(','),
rss_link: bangumi.rss_link.split(','),
}
));
return result;
},

/**
* 获取指定 bangumiId 的规则
* @param bangumiId bangumi id
* @returns 指定 bangumi 的规则
*/
async getRule(bangumiId: number) {
const {data} = await axios.get<BangumiAPI>(
`api/v1/bangumi/get/${bangumiId}`
);
const result: BangumiRule = {
...data,
filter: data.filter.split(','),
rss_link: data.rss_link.split(','),
}
));
return result;
},
return result;
},

/**
* 获取指定 bangumiId 的规则
* @param bangumiId bangumi id
* @returns 指定 bangumi 的规则
*/
async getRule(bangumiId: number) {
const { data } = await axios.get<BangumiAPI>(
`api/v1/bangumi/get/${bangumiId}`
);
const result: BangumiRule = {
...data,
filter: data.filter.split(','),
rss_link: data.rss_link.split(','),
}
return result;
},
/**
* 更新指定 bangumiId 的规则
* @param bangumiId - 需要更新的 bangumi 的 id
* @param bangumiRule
* @returns axios 请求返回的数据
*/
async updateRule(bangumiId: number, bangumiRule: BangumiRule) {
const rule: BangumiAPI = {
...bangumiRule,
filter: bangumiRule.filter.join(','),
rss_link: bangumiRule.rss_link.join(','),
}
const post = omit(rule, ['id'])
const {data} = await axios.patch<ApiSuccess>(
`api/v1/bangumi/update/${bangumiId}`,
post
);
return data;
},

/**
* 更新指定 bangumiId 的规则
* @param bangumiId - 需要更新的 bangumi 的 id
* @param bangumiRule
* @returns axios 请求返回的数据
*/
async updateRule(bangumiId: number, bangumiRule: BangumiRule) {
const rule: BangumiAPI = {
...bangumiRule,
filter: bangumiRule.filter.join(','),
rss_link: bangumiRule.rss_link.join(','),
}
const post = omit(rule, ['id'])
const { data } = await axios.patch< ApiSuccess >(
`api/v1/bangumi/update/${bangumiId}`,
post
);
return data;
},
/**
* 删除指定 bangumiId 的数据库规则,会在重新匹配到后重建
* @param bangumiId - 需要删除的 bangumi 的 id
* @param file - 是否同时删除关联文件。
* @returns axios 请求返回的数据
*/
async deleteRule(bangumiId: number | number[], file: boolean) {
let url = 'api/v1/bangumi/delete';
let ids: undefined | number[];

/**
* 删除指定 bangumiId 的数据库规则,会在重新匹配到后重建
* @param bangumiId - 需要删除的 bangumi 的 id
* @param file - 是否同时删除关联文件。
* @returns axios 请求返回的数据
*/
async deleteRule(bangumiId: number | number[], file: boolean) {
let url = 'api/v1/bangumi/delete';
let ids: undefined | number[];
if (typeof bangumiId === 'number') {
url = `${url}/${bangumiId}`;
} else {
url = `${url}/many`;
ids = bangumiId;
}

if (typeof bangumiId === 'number') {
url = `${url}/${bangumiId}`;
} else {
url = `${url}/many`;
ids = bangumiId;
}
const {data} = await axios.delete<ApiSuccess>(url, {
data: ids,
params: {
file,
},
});
return data;
},

const { data } = await axios.delete< ApiSuccess >(url, {
data: ids,
params: {
file,
},
});
return data;
},
/**
* 删除指定 bangumiId 的规则。如果 file 为 true,则同时删除关联文件。
* @param bangumiId - 需要删除规则的 bangumi 的 id。
* @param file - 是否同时删除关联文件。
* @returns axios 请求返回的数据
*/
async disableRule(bangumiId: number | number[], file: boolean) {
let url = 'api/v1/bangumi/disable';
let ids: undefined | number[];

/**
* 删除指定 bangumiId 的规则。如果 file 为 true,则同时删除关联文件。
* @param bangumiId - 需要删除规则的 bangumi 的 id。
* @param file - 是否同时删除关联文件。
* @returns axios 请求返回的数据
*/
async disableRule(bangumiId: number | number[], file: boolean) {
let url = 'api/v1/bangumi/disable';
let ids: undefined | number[];
if (typeof bangumiId === 'number') {
url = `${url}/${bangumiId}`;
} else {
url = `${url}/many`;
ids = bangumiId;
}

if (typeof bangumiId === 'number') {
url = `${url}/${bangumiId}`;
} else {
url = `${url}/many`;
ids = bangumiId;
}
const {data} = await axios.delete<ApiSuccess>(url, {
data: ids,
params: {
file,
},
});
return data;
},

const { data } = await axios.delete< ApiSuccess >(url, {
data: ids,
params: {
file,
},
});
return data;
},
/**
* 启用指定 bangumiId 的规则
* @param bangumiId - 需要启用的 bangumi 的 id
*/
async enableRule(bangumiId: number) {
const {data} = await axios.get<ApiSuccess>(
`api/v1/bangumi/enable/${bangumiId}`
);
return data;
},

/**
* 启用指定 bangumiId 的规则
* @param bangumiId - 需要启用的 bangumi 的 id
*/
async enableRule(bangumiId: number) {
const { data } = await axios.get< ApiSuccess >(
`api/v1/bangumi/enable/${bangumiId}`
);
return data;
},
/**
* 重置所有 bangumi 数据
*/
async resetAll() {
const {data} = await axios.get<ApiSuccess>('api/v1/bangumi/reset/all');
return data;
},

/**
* 重置所有 bangumi 数据
*/
async resetAll() {
const { data } = await axios.get< ApiSuccess >('api/v1/bangumi/reset/all');
return data;
},
/**
* 刷新所有没有海报的 bangumi 海报
*/
async refreshPoster() {
const {data} = await axios.get<ApiSuccess>('api/v1/bangumi/refresh/poster/all');
return data;
}
};
4 changes: 2 additions & 2 deletions webui/src/components/ab-status-bar.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" setup>
import {Menu, MenuButton, MenuItem, MenuItems} from '@headlessui/vue';
import {AddOne, International, More} from '@icon-park/vue-next';
import {AddOne, International, More, System} from '@icon-park/vue-next';

withDefaults(
defineProps<{
Expand Down Expand Up @@ -54,7 +54,7 @@ function abLabel(label: string | (() => string)) {
/>

<MenuButton bg-transparent is-btn btn-click>
<More theme="outline" size="24" fill="#fff"/>
<System theme="outline" size="24" fill="#fff"/>
</MenuButton>

<ab-status :running="running"/>
Expand Down
Loading