chore: move Auto_Bangumi/src -> Auto_Bangumi/backend/src, prepare for merge WebUI repo

This commit is contained in:
zthxxx
2023-06-06 22:33:00 +08:00
parent f8411f9c8a
commit 069a86faa0
99 changed files with 179 additions and 0 deletions

View File

@@ -0,0 +1 @@
from .web import router

View File

@@ -0,0 +1,63 @@
from datetime import timedelta
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from module.models.user import User
from module.security import (
auth_user,
create_access_token,
get_current_user,
update_user_info,
)
from .program import router
@router.post("/api/v1/auth/login", response_model=dict, tags=["auth"])
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
username = form_data.username
password = form_data.password
auth_user(username, password)
token = create_access_token(
data={"sub": username}, expires_delta=timedelta(days=1)
)
return {"access_token": token, "token_type": "bearer", "expire": 86400}
@router.get("/api/v1/auth/refresh_token", response_model=dict, tags=["auth"])
async def refresh(current_user: User = Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
token = create_access_token(
data = {"sub": current_user.username}
)
return {"access_token": token, "token_type": "bearer", "expire": 86400}
@router.get("/api/v1/auth/logout", response_model=dict, tags=["auth"])
async def logout(current_user: User = Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
return {"message": "logout success"}
@router.post("/api/v1/auth/update", response_model=dict, tags=["auth"])
async def update_user(user_data: User, current_user: User = Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
if update_user_info(user_data, current_user):
return {
"message": "update success",
"access_token": create_access_token({"sub": user_data.username}),
"token_type": "bearer",
"expire": 86400,
}

View File

@@ -0,0 +1,85 @@
from fastapi import Depends, HTTPException, status
from fastapi.responses import JSONResponse
from module.manager import TorrentManager
from module.models import BangumiData
from module.security import get_current_user
from .log import router
@router.get(
"/api/v1/bangumi/getAll", tags=["bangumi"], response_model=list[BangumiData]
)
async def get_all_data(current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
with TorrentManager() as torrent:
return torrent.search_all()
@router.get(
"/api/v1/bangumi/getData/{bangumi_id}", tags=["bangumi"], response_model=BangumiData
)
async def get_data(bangumi_id: str, current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
with TorrentManager() as torrent:
return torrent.search_one(bangumi_id)
@router.post("/api/v1/bangumi/updateRule", tags=["bangumi"])
async def update_rule(data: BangumiData, current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
with TorrentManager() as torrent:
return torrent.update_rule(data)
@router.delete("/api/v1/bangumi/deleteRule/{bangumi_id}", tags=["bangumi"])
async def delete_rule(bangumi_id: str, file: bool = False, current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
with TorrentManager() as torrent:
return torrent.delete_rule(bangumi_id, file)
@router.delete("/api/v1/bangumi/disableRule/{bangumi_id}", tags=["bangumi"])
async def disable_rule(
bangumi_id: str, file: bool = False, current_user=Depends(get_current_user)
):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
with TorrentManager() as torrent:
return torrent.disable_rule(bangumi_id, file)
@router.get("/api/v1/bangumi/enableRule/{bangumi_id}", tags=["bangumi"])
async def enable_rule(bangumi_id: str, current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
with TorrentManager() as torrent:
return torrent.enable_rule(bangumi_id)
@router.get("/api/v1/bangumi/resetAll", tags=["bangumi"])
async def reset_all(current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
with TorrentManager() as torrent:
torrent.delete_all()
return JSONResponse(status_code=200, content={"message": "OK"})

View File

@@ -0,0 +1,36 @@
import logging
from fastapi import Depends, HTTPException, status
from module.conf import settings
from module.models import Config
from module.security import get_current_user
from .bangumi import router
logger = logging.getLogger(__name__)
@router.get("/api/v1/getConfig", tags=["config"], response_model=Config)
async def get_config(current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
return settings
@router.post("/api/v1/updateConfig", tags=["config"])
async def update_config(config: Config, current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
try:
settings.save(config_dict=config.dict())
settings.load()
logger.info("Config updated")
return {"message": "Success"}
except Exception as e:
logger.warning(e)
return {"message": "Failed to update config"}

View File

@@ -0,0 +1,54 @@
from fastapi import Depends, HTTPException, status
from module.manager import SeasonCollector
from module.models import BangumiData
from module.models.api import *
from module.rss import analyser
from module.security import get_current_user
from .config import router
@router.post("/api/v1/download/analysis", tags=["download"])
async def analysis(link: RssLink, current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
data = analyser.link_to_data(link.rss_link)
if data:
return data
else:
return {"status": "Failed to parse link"}
@router.post("/api/v1/download/collection", tags=["download"])
async def download_collection(
data: BangumiData, current_user=Depends(get_current_user)
):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
if data:
with SeasonCollector() as collector:
if collector.collect_season(data, data.rss_link[0], proxy=True):
return {"status": "Success"}
else:
return {"status": "Failed to add torrent"}
else:
return {"status": "Failed to parse link"}
@router.post("/api/v1/download/subscribe", tags=["download"])
async def subscribe(data: BangumiData, current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
if data:
with SeasonCollector() as collector:
collector.subscribe_season(data)
return {"status": "Success"}
else:
return {"status": "Failed to parse link"}

View File

@@ -0,0 +1,35 @@
import os
from fastapi import Depends, HTTPException, Response, status
from module.conf import LOG_PATH
from module.security import get_current_user
from .auth import router
@router.get("/api/v1/log", tags=["log"])
async def get_log(current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
if os.path.isfile(LOG_PATH):
with open(LOG_PATH, "rb") as f:
return Response(f.read(), media_type="text/plain")
else:
return Response("Log file not found", status_code=404)
@router.get("/api/v1/log/clear", tags=["log"])
async def clear_log(current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
if os.path.isfile(LOG_PATH):
with open(LOG_PATH, "w") as f:
f.write("")
return {"status": "ok"}
else:
return Response("Log file not found", status_code=404)

View File

@@ -0,0 +1,103 @@
import logging
import os
import signal
from fastapi import Depends, FastAPI, HTTPException, status
from module.core import Program
from module.security import get_current_user
logger = logging.getLogger(__name__)
program = Program()
router = FastAPI()
@router.on_event("startup")
async def startup():
program.startup()
@router.on_event("shutdown")
async def shutdown():
program.stop()
@router.get("/api/v1/restart", tags=["program"])
async def restart(current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
try:
program.restart()
return {"status": "ok"}
except Exception as e:
logger.debug(e)
logger.warning("Failed to restart program")
raise HTTPException(status_code=500, detail="Failed to restart program")
@router.get("/api/v1/start", tags=["program"])
async def start(current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
try:
return program.start()
except Exception as e:
logger.debug(e)
logger.warning("Failed to start program")
raise HTTPException(status_code=500, detail="Failed to start program")
@router.get("/api/v1/stop", tags=["program"])
async def stop(current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
return program.stop()
@router.get("/api/v1/status", tags=["program"])
async def status(current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
if not program.is_running:
return {"status": "stop"}
else:
return {"status": "running"}
@router.get("/api/v1/shutdown", tags=["program"])
async def shutdown_program(current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
program.stop()
logger.info("Shutting down program...")
os.kill(os.getpid(), signal.SIGINT)
return {"status": "ok"}
# Check status
@router.get("/api/v1/check/downloader", tags=["check"])
async def check_downloader_status(current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
return program.check_downloader()
@router.get("/api/v1/check/rss", tags=["check"])
async def check_rss_status(current_user=Depends(get_current_user)):
if not current_user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token"
)
return program.check_analyser()

View File

@@ -0,0 +1,83 @@
import logging
import re
from fastapi.exceptions import HTTPException
from fastapi.responses import Response
from module.conf import settings
from module.network import RequestContent
from .download import router
logger = logging.getLogger(__name__)
def get_rss_content(full_path):
url = f"https://mikanani.me/RSS/{full_path}"
custom_url = settings.rss_parser.custom_url
if "://" not in custom_url:
custom_url = f"https://{custom_url}"
try:
with RequestContent() as request:
content = request.get_html(url)
return re.sub(r"https://mikanani.me", custom_url, content)
except Exception as e:
logger.debug(e)
logger.warning("Failed to get RSS content")
raise HTTPException(status_code=500, detail="Failed to get RSS content")
def get_torrent(full_path):
url = f"https://mikanani.me/Download/{full_path}"
try:
with RequestContent() as request:
return request.get_content(url)
except Exception as e:
logger.debug(e)
logger.warning("Failed to get torrent")
raise HTTPException(status_code=500, detail="Failed to get torrent")
@router.get("/RSS/MyBangumi", tags=["proxy"])
async def get_my_bangumi(token: str):
full_path = "MyBangumi?token=" + token
content = get_rss_content(full_path)
return Response(content, media_type="application/xml")
@router.get("/RSS/Search", tags=["proxy"])
async def get_search_result(searchstr: str):
full_path = "Search?searchstr=" + searchstr
content = get_rss_content(full_path)
return Response(content, media_type="application/xml")
@router.get("/RSS/Bangumi", tags=["proxy"])
async def get_bangumi(bangumiId: str, subgroupid: str):
full_path = "Bangumi?bangumiId=" + bangumiId + "&subgroupid=" + subgroupid
content = get_rss_content(full_path)
return Response(content, media_type="application/xml")
@router.get("/RSS/{full_path:path}", tags=["proxy"])
async def get_rss(full_path: str):
content = get_rss_content(full_path)
return Response(content, media_type="application/xml")
@router.get("/Download/{full_path:path}", tags=["proxy"])
async def download(full_path: str):
torrent = get_torrent(full_path)
return Response(torrent, media_type="application/x-bittorrent")
@router.get("/Home/Episode/{full_path:path}", tags=["proxy"])
async def get_ep_info(full_path: str):
url = f"https://mikanani.me/Home/Episode/{full_path}"
try:
with RequestContent() as request:
return Response(request.get_html(url), media_type="text/html")
except Exception as e:
logger.debug(e)
logger.warning("Failed to get ep info")
raise HTTPException(status_code=500, detail="Failed to get ep info")

View File

@@ -0,0 +1,37 @@
from fastapi import Request
from fastapi.responses import FileResponse, HTMLResponse, RedirectResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from module.conf import VERSION
from .proxy import router
if VERSION != "DEV_VERSION":
router.mount("/assets", StaticFiles(directory="templates/assets"), name="assets")
templates = Jinja2Templates(directory="templates")
# Resource
@router.get("/favicon.svg", tags=["html"])
def favicon():
return FileResponse("templates/favicon.svg")
@router.get("/AutoBangumi.svg", tags=["html"])
def logo():
return FileResponse("templates/AutoBangumi.svg")
@router.get("/favicon-light.svg", tags=["html"])
def favicon_light():
return FileResponse("templates/favicon-light.svg")
# HTML Response
@router.get("/{full_path:path}", response_class=HTMLResponse, tags=["html"])
def index(request: Request):
context = {"request": request}
return templates.TemplateResponse("index.html", context)
else:
@router.get("/", status_code=302, tags=["html"])
def index():
return RedirectResponse("/docs")