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

Refactor: Migrating backend from synchronous functions to asynchronous functions #567

Draft
wants to merge 92 commits into
base: 3.2-dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
b2d3c89
Merge pull request #550 from EstrellaXD/3.1-dev
EstrellaXD Oct 8, 2023
b20d546
docs(experimental): add microsoft azure openai docs
100gle Oct 9, 2023
f91af96
Merge pull request #552 from 100gle/experimental-openai-docs
EstrellaXD Oct 9, 2023
8acd09e
docs: update CONTRIBUTING.md
EstrellaXD Oct 9, 2023
2a4e7af
docs: update local deploy.
EstrellaXD Oct 9, 2023
3dfcba7
docs: update documate ai func
EstrellaXD Oct 9, 2023
3961da4
docs: update build command to integrate with ask ai.
EstrellaXD Oct 9, 2023
8b134aa
docs: faq.
EstrellaXD Oct 10, 2023
4ba0a7f
docs: rss icon.
EstrellaXD Oct 10, 2023
e966f0d
docs: warning format.
EstrellaXD Oct 10, 2023
e3281a6
docs: move resource. Add rename feature explain.
EstrellaXD Oct 10, 2023
1fb8938
Merge pull request #555 from EstrellaXD/docs-update
EstrellaXD Oct 10, 2023
d472a08
feat: replace requests with httpx.
EstrellaXD Oct 10, 2023
6819704
refactor: trans qb client to aio.
EstrellaXD Oct 10, 2023
d45bb68
fix: test.
EstrellaXD Oct 10, 2023
bf83ab0
refactor: async RSSEngine.
EstrellaXD Oct 10, 2023
de63a5b
fix: analyser log error.
EstrellaXD Oct 11, 2023
f5d8790
change: remove season info in mikan parser.
EstrellaXD Oct 11, 2023
bed3757
fix: 通过订阅获得的番剧后续下载出现问题的情况。
EstrellaXD Oct 11, 2023
cf7424b
fix: bug of delete bangumi.
EstrellaXD Oct 11, 2023
49b497c
Merge pull request #566 from EstrellaXD/3.1-dev
EstrellaXD Oct 11, 2023
a1f2dc9
refactor: change downloader action,
EstrellaXD Oct 12, 2023
9521686
fix: mikan official title encode problem.
EstrellaXD Oct 12, 2023
c7c1cac
feat: add refresh poster api.
EstrellaXD Oct 12, 2023
155496f
webui: change delete/disable button style.
EstrellaXD Oct 12, 2023
6396c42
feat: Local deployment files are provided requirements.txt
DDSDerek Oct 13, 2023
4ea205b
docs: docker & docker-compose & local deploy
DDSRem Oct 13, 2023
51fe380
docs: fix bind mount directory error
DDSRem Oct 13, 2023
1d8c399
docs: add tz env & update unraid template
DDSRem Oct 13, 2023
a81d93f
Merge pull request #572 from DDS-Derek/3.1-dev
EstrellaXD Oct 14, 2023
a544ef1
Merge pull request #574 from DDS-Derek/deploy_docs
EstrellaXD Oct 14, 2023
6a8aa0a
Merge pull request #570 from EstrellaXD/3.1-dev
EstrellaXD Oct 14, 2023
9c107f7
feat: add lang type & add returnUserLangText func
Rewrite0 Oct 15, 2023
2553855
fix: return returnUserLangText
Rewrite0 Oct 15, 2023
67a1949
change: change logic in qbdownloader class.
EstrellaXD Oct 15, 2023
fa595b9
emove token from Window.localStorage​
maikirakiwi Oct 15, 2023
d1bcce0
condense to isloggedin
maikirakiwi Oct 15, 2023
6964ac9
修了一些feature
maikirakiwi Oct 15, 2023
66eb514
pr requested changes
maikirakiwi Oct 16, 2023
454b77c
fix: determine
Rewrite0 Oct 16, 2023
361eb1a
fix: determine
Rewrite0 Oct 16, 2023
7cf8cd5
fix: determine
Rewrite0 Oct 16, 2023
cf1ff79
Merge pull request #579 from maikirakiwi/main
Rewrite0 Oct 16, 2023
c837f47
fix: tmdb aio parser.
EstrellaXD Oct 23, 2023
d06e6b7
docs: update bangumi manage.
EstrellaXD Oct 23, 2023
ffff690
docs: update index.
EstrellaXD Oct 23, 2023
abd946b
feat: add qb iframe page
Rewrite0 Oct 24, 2023
6951c6a
feat(transmission): add transmission downloader and model
codycjy Oct 25, 2023
7ef8d29
feat(transmission): complete check_host and __aenter__ func
codycjy Oct 25, 2023
99ba203
docs: fix docker compose deploy problem close #599
EstrellaXD Oct 27, 2023
24aa033
Update manager.md
HellSakura Oct 28, 2023
856aaf9
Update config.ts
HellSakura Oct 28, 2023
f3cf32c
Merge pull request #606 from HellSakura/main
EstrellaXD Oct 28, 2023
f296021
fix: analyser api error.
EstrellaXD Oct 30, 2023
410b4c2
fix: rss parser problem.
EstrellaXD Oct 31, 2023
7bee913
change: change network connect err log level.
EstrellaXD Oct 31, 2023
b9474dc
Merge pull request #611 from EstrellaXD/3.1-dev
EstrellaXD Oct 31, 2023
6cdf9b0
docs: fix docs error in local deployment.
EstrellaXD Oct 31, 2023
890d5e8
Add information of default username and password to Quick Start
karuboniru Nov 14, 2023
e350950
Merge pull request #620 from karuboniru/patch-1
EstrellaXD Nov 14, 2023
550bb4e
docs: add back google analytic
EstrellaXD Nov 16, 2023
8e4b35b
add decorator to RequestURL
Dec 28, 2023
a7c2d81
Merge remote-tracking branch 'origin/aio-refactor' into aio-refactor
EstrellaXD Jan 1, 2024
f1f6175
Merge pull request #657 from shininome/aio-refactor
EstrellaXD Jan 1, 2024
c14e40b
Merge remote-tracking branch 'origin/aio-refactor' into aio-refactor
EstrellaXD Jan 1, 2024
196ff2c
chore: optimize request code
EstrellaXD Jan 2, 2024
d5570f2
fix: some part of async test
EstrellaXD Jan 2, 2024
96aaae9
Merge remote-tracking branch 'origin/aio-refactor' into aio-refactor
EstrellaXD Jan 2, 2024
1ba77fa
remove: retry decorator, fix test bug.
EstrellaXD Jan 2, 2024
8e96e3c
Merge pull request #598 from codycjy/aio-refactor-tr
EstrellaXD Jan 2, 2024
07efbac
feat: replace requests with httpx.
EstrellaXD Oct 10, 2023
0b6314e
refactor: trans qb client to aio.
EstrellaXD Oct 10, 2023
8fe8332
fix: test.
EstrellaXD Oct 10, 2023
18ccc11
refactor: change downloader action,
EstrellaXD Oct 12, 2023
c624cb2
change: change logic in qbdownloader class.
EstrellaXD Oct 15, 2023
8c8ec40
fix: tmdb aio parser.
EstrellaXD Oct 23, 2023
8d52564
refactor: async RSSEngine.
EstrellaXD Oct 10, 2023
f1a9d1c
add decorator to RequestURL
Dec 28, 2023
9cb59df
chore: optimize request code
EstrellaXD Jan 2, 2024
983ab50
fix: some part of async test
EstrellaXD Jan 2, 2024
ee95f82
remove: retry decorator, fix test bug.
EstrellaXD Jan 2, 2024
e310e5c
feat(transmission): add transmission downloader and model
codycjy Oct 25, 2023
6a7f800
feat(transmission): complete check_host and __aenter__ func
codycjy Oct 25, 2023
6c26c53
Merge remote-tracking branch 'origin/aio-refactor' into aio-refactor
EstrellaXD Jan 2, 2024
8142299
fix: download config bug.
EstrellaXD Jan 2, 2024
b3f801f
format: black.
EstrellaXD Jan 3, 2024
b1707e6
fix: rss test.
EstrellaXD Jan 3, 2024
62d99eb
feat: new async rss poller.
EstrellaXD Jan 3, 2024
77cc7a4
feat: async torrent downloader.
EstrellaXD Jan 3, 2024
92526ac
chore: update aiocore.
EstrellaXD Jan 4, 2024
258c922
feat: async renamer.
EstrellaXD Jan 4, 2024
cf9a3ab
refactor: rename module little refactor.
EstrellaXD Jan 4, 2024
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
6 changes: 6 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,11 @@ jobs:
run: |
echo ${{ needs.version-info.outputs.version }}
echo "VERSION='${{ needs.version-info.outputs.version }}'" >> module/__version__.py

- name: Copy requirements.txt
working-directory: ./backend
run:
cp requirements.txt src/requirements.txt

- name: Zip app
run: |
Expand All @@ -262,6 +267,7 @@ jobs:
echo "version=🌟${{ needs.version-info.outputs.version }}" >> $GITHUB_OUTPUT
echo "pre_release=false" >> $GITHUB_OUTPUT
fi

- name: Release
id: release
uses: softprops/action-gh-release@v1
Expand Down
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,13 @@ gitGraph:

而新功能的发版时间则会更长而且不定,你可以在我们的 [GitHub Project](https://github.com/EstrellaXD/Auto_Bangumi/projects?query=is%3Aopen) 看板中看到开发进度,一个版本规划的新功能都开发完备后就会发版。

## 贡献文档

如果要为文档做贡献,请注意以下几点:

- 更新分支为 `docs-update`,并基于它做修改.
- 请确保你的 PR 标题和描述中包含了你的修改的目的和意图。

撰写文档请尽量使用规范的书面化用语,遵照 Markdown 语法,以及 [中文文案排版指北](https://github.com/sparanoid/chinese-copywriting-guidelines) 中的规范。


1 change: 0 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ RUN set -ex && \
shadow \
tini \
openssl \
busybox-suid \
tzdata && \
python3 -m pip install --no-cache-dir --upgrade pip && \
sed -i '/bcrypt/d' requirements.txt && \
Expand Down
3 changes: 2 additions & 1 deletion backend/requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
ruff
black
pre-commit
pytest
pytest
pytest-asyncio
4 changes: 1 addition & 3 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ fastapi==0.97.0
h11==0.14.0
idna==3.4
pydantic~=1.10
PySocks==1.7.1
qbittorrent-api==2023.9.53
requests==2.31.0
httpx[http2,socks]==0.25.0
six==1.16.0
sniffio==1.3.0
soupsieve==2.4.1
Expand Down
2 changes: 2 additions & 0 deletions backend/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ def html(request: Request, path: str):
else:
context = {"request": request}
return templates.TemplateResponse("index.html", context)

else:

@app.get("/", status_code=302, tags=["html"])
def index():
return RedirectResponse("/docs")
Expand Down
11 changes: 11 additions & 0 deletions backend/src/module/api/bangumi.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,17 @@ async def refresh_poster():
return u_response(resp)


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


@router.get(
"/reset/all", response_model=APIResponse, dependencies=[Depends(get_current_user)]
)
Expand Down
52 changes: 25 additions & 27 deletions backend/src/module/api/rss.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,30 @@
from module.downloader import DownloadClient
from module.manager import SeasonCollector
from module.models import APIResponse, Bangumi, RSSItem, RSSUpdate, Torrent
from module.rss import RSSAnalyser, RSSEngine
from module.rss import RSSAnalyser, RSSEngine, RSSManager
from module.security.api import UNAUTHORIZED, get_current_user

from .response import u_response

router = APIRouter(prefix="/rss", tags=["rss"])
engine = RSSEngine()
analyser = RSSAnalyser()


@router.get(
path="", response_model=list[RSSItem], dependencies=[Depends(get_current_user)]
)
async def get_rss():
with RSSEngine() as engine:
return engine.rss.search_all()
with RSSManager() as manager:
return manager.rss.search_all()


@router.post(
path="/add", response_model=APIResponse, dependencies=[Depends(get_current_user)]
)
async def add_rss(rss: RSSItem):
with RSSEngine() as engine:
result = engine.add_rss(rss.url, rss.name, rss.aggregate, rss.parser)
with RSSManager() as manager:
result = await manager.add_rss(rss.url, rss.name, rss.aggregate, rss.parser)
return u_response(result)


Expand All @@ -37,8 +39,8 @@ async def add_rss(rss: RSSItem):
async def enable_many_rss(
rss_ids: list[int],
):
with RSSEngine() as engine:
result = engine.enable_list(rss_ids)
with RSSManager() as manager:
result = manager.enable_list(rss_ids)
return u_response(result)


Expand All @@ -48,8 +50,8 @@ async def enable_many_rss(
dependencies=[Depends(get_current_user)],
)
async def delete_rss(rss_id: int):
with RSSEngine() as engine:
if engine.rss.delete(rss_id):
with RSSManager() as manager:
if manager.rss.delete(rss_id):
return JSONResponse(
status_code=200,
content={"msg_en": "Delete RSS successfully.", "msg_zh": "删除 RSS 成功。"},
Expand All @@ -69,8 +71,8 @@ async def delete_rss(rss_id: int):
async def delete_many_rss(
rss_ids: list[int],
):
with RSSEngine() as engine:
result = engine.delete_list(rss_ids)
with RSSManager() as manager:
result = manager.delete_list(rss_ids)
return u_response(result)


Expand All @@ -80,8 +82,8 @@ async def delete_many_rss(
dependencies=[Depends(get_current_user)],
)
async def disable_rss(rss_id: int):
with RSSEngine() as engine:
if engine.rss.disable(rss_id):
with RSSManager() as manager:
if manager.rss.disable(rss_id):
return JSONResponse(
status_code=200,
content={"msg_en": "Disable RSS successfully.", "msg_zh": "禁用 RSS 成功。"},
Expand All @@ -99,8 +101,8 @@ async def disable_rss(rss_id: int):
dependencies=[Depends(get_current_user)],
)
async def disable_many_rss(rss_ids: list[int]):
with RSSEngine() as engine:
result = engine.disable_list(rss_ids)
with RSSManager() as manager:
result = manager.disable_list(rss_ids)
return u_response(result)


Expand All @@ -114,8 +116,8 @@ async def update_rss(
):
if not current_user:
raise UNAUTHORIZED
with RSSEngine() as engine:
if engine.rss.update(rss_id, data):
with RSSManager() as manager:
if manager.rss.update(rss_id, data):
return JSONResponse(
status_code=200,
content={"msg_en": "Update RSS successfully.", "msg_zh": "更新 RSS 成功。"},
Expand All @@ -133,8 +135,8 @@ async def update_rss(
dependencies=[Depends(get_current_user)],
)
async def refresh_all():
with RSSEngine() as engine, DownloadClient() as client:
engine.refresh_rss(client)
async with DownloadClient() as client:
await engine.refresh_rss(client)
return JSONResponse(
status_code=200,
content={"msg_en": "Refresh all RSS successfully.", "msg_zh": "刷新 RSS 成功。"},
Expand All @@ -147,8 +149,8 @@ async def refresh_all():
dependencies=[Depends(get_current_user)],
)
async def refresh_rss(rss_id: int):
with RSSEngine() as engine, DownloadClient() as client:
engine.refresh_rss(client, rss_id)
async with DownloadClient() as client:
await engine.refresh_rss(client=client, rss_id=rss_id)
return JSONResponse(
status_code=200,
content={"msg_en": "Refresh RSS successfully.", "msg_zh": "刷新 RSS 成功。"},
Expand All @@ -163,12 +165,8 @@ async def refresh_rss(rss_id: int):
async def get_torrent(
rss_id: int,
):
with RSSEngine() as engine:
return engine.get_rss_torrents(rss_id)


# Old API
analyser = RSSAnalyser()
with RSSManager() as manager:
return manager.get_rss_torrents(rss_id)


@router.post(
Expand Down
64 changes: 64 additions & 0 deletions backend/src/module/core/aiocore.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import asyncio

from module.downloader import DownloadClient
from module.manager import Renamer
from module.conf import settings
from module.rss import RSSEngine
from module.database import Database
from module.models import Bangumi, RSSItem, Torrent



rss_item_pool = []
torrent_pool: list[tuple[Bangumi, list[Torrent]]] = []


class AsyncProgram:
def __init__(self):
self.renamer = Renamer()
self.engine = RSSEngine()
self.event = asyncio.Event()

async def run(self):
self.event.clear()
task = []
if settings.bangumi_manage.enable:
task.append(self.rename_task())
if settings.rss_parser.enable:
task.append(self.rss_task())
await asyncio.gather(*task)

async def rename_task(self):
while not self.event.is_set():
async with DownloadClient() as client:
await self.check_downloader(client)
await self.renamer.rename(client)
await asyncio.sleep(settings.program.rename_time)

async def rss_task(self):
while not self.event.is_set():
await self.engine.rss_poller(process_rss)
await asyncio.sleep(settings.program.rss_time)


async def rename_task():
connected = False
renamer = Renamer()
async with DownloadClient() as client:
while not connected:
connected = await client.auth()
if not connected:
await asyncio.sleep(30)
for bangumi, torrents in torrent_pool:
client.add_torrent(torrents, bangumi)
renamer.rename(client)
await asyncio.sleep(settings.program.rename_time)


async def rss_task():
# GET RSS FROM DATABASE
with Database() as db:
rss_items = db.rss.search_active()
for rss_item in rss_items:
rss_item_pool.append(rss_item)
pass
8 changes: 7 additions & 1 deletion backend/src/module/core/program.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

from module.conf import VERSION, settings
from module.models import ResponseModel
from module.update import data_migration, first_run, from_30_to_31, start_up, cache_image
from module.update import (
data_migration,
first_run,
from_30_to_31,
start_up,
cache_image,
)

from .sub_thread import RenameThread, RSSThread

Expand Down
34 changes: 4 additions & 30 deletions backend/src/module/core/sub_thread.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import threading
import time
import asyncio

from module.conf import settings
from module.downloader import DownloadClient
Expand All @@ -13,38 +14,11 @@
class RSSThread(ProgramStatus):
def __init__(self):
super().__init__()
self._rss_thread = threading.Thread(
target=self.rss_loop,
)
self._rss_loop = asyncio.new_event_loop()
self.analyser = RSSAnalyser()

def rss_loop(self):
while not self.stop_event.is_set():
with DownloadClient() as client, RSSEngine() as engine:
# Analyse RSS
rss_list = engine.rss.search_aggregate()
for rss in rss_list:
self.analyser.rss_to_data(rss, engine)
# Run RSS Engine
engine.refresh_rss(client)
if settings.bangumi_manage.eps_complete:
eps_complete()
self.stop_event.wait(settings.program.rss_time)

def rss_start(self):
self.rss_thread.start()

def rss_stop(self):
if self._rss_thread.is_alive():
self._rss_thread.join()

@property
def rss_thread(self):
if not self._rss_thread.is_alive():
self._rss_thread = threading.Thread(
target=self.rss_loop,
)
return self._rss_thread
async def rss_loop(self):
pass


class RenameThread(ProgramStatus):
Expand Down
7 changes: 5 additions & 2 deletions backend/src/module/database/bangumi.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,11 @@ def match_list(self, torrent_list: list, rss_link: str) -> list:
i += 1
return torrent_list

def match_torrent(self, torrent_name: str) -> Optional[Bangumi]:
def match_torrent(self, torrent_name: str, rss_link: str) -> Optional[Bangumi]:
statement = select(Bangumi).where(
and_(
func.instr(torrent_name, Bangumi.title_raw) > 0,
func.instr(Bangumi.rss_link, rss_link),
# use `false()` to avoid E712 checking
# see: https://docs.astral.sh/ruff/rules/true-false-comparison/
Bangumi.deleted == false(),
Expand All @@ -144,7 +145,9 @@ def not_complete(self) -> list[Bangumi]:
# Find eps_complete = False
# use `false()` to avoid E712 checking
# see: https://docs.astral.sh/ruff/rules/true-false-comparison/
condition = select(Bangumi).where(Bangumi.eps_collect == false())
condition = select(Bangumi).where(
and_(Bangumi.eps_collect == false(), Bangumi.deleted == false())
)
datas = self.session.exec(condition).all()
return datas

Expand Down
Loading