Skip to content

Commit

Permalink
Merge pull request #472 from EstrellaXD/3.1-dev
Browse files Browse the repository at this point in the history
3.1.2
  • Loading branch information
EstrellaXD authored Sep 26, 2023
2 parents 6161b5a + bf6fda7 commit 95400b6
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 199 deletions.
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

0 comments on commit 95400b6

Please sign in to comment.