From 6cbacab98b9d774e0d1a0d08b5b06d3ef86c076a Mon Sep 17 00:00:00 2001 From: zhengshunjin <2667579369@qq.com> Date: Mon, 1 Jun 2026 18:43:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(app):=20=E6=B7=BB=E5=8A=A0=20ASMR=20?= =?UTF-8?q?=E5=92=8C=E7=A3=81=E5=8A=9B=E9=93=BE=E6=8E=A5=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 asmr_bp 蓝图模块和 AsmrService 服务 - 新增 magnet_bp 蓝图模块和 MagnetService 服务 - 在应用初始化时注册新的蓝图模块 - 将 switch 语句替换为 if-elif 语句进行配置管理 - 在前端界面添加 ASMR 功能入口 - 增加 libtorrent 依赖包 - 修复字符串引号使用问题 - 增加文件重命名异常处理 - 扩展类型注解支持 Union 类型 - 增加请求超时时间到 30 秒 - 优化前端错误处理逻辑 --- app/__init__.py | 18 ++++++++++-------- app/blueprints/asmr_bp.py | 11 +++++++++++ app/blueprints/magnet_bp.py | 11 +++++++++++ app/services/asmr_service.py | 16 ++++++++++++++++ app/services/book_service.py | 9 ++++----- app/services/file_service.py | 7 +++++-- app/services/folder_service.py | 4 ++-- app/services/magnet_service.py | 9 +++++++++ flask-ui/src/api/index.ts | 24 +++++++++++++++--------- flask-ui/src/utils/request.ts | 2 +- flask-ui/src/views/HomeView.vue | 9 +++++++-- instance/flask.db | Bin 36864 -> 36864 bytes requirements.txt | 3 ++- 13 files changed, 93 insertions(+), 30 deletions(-) create mode 100644 app/blueprints/asmr_bp.py create mode 100644 app/blueprints/magnet_bp.py create mode 100644 app/services/asmr_service.py create mode 100644 app/services/magnet_service.py diff --git a/app/__init__.py b/app/__init__.py index 46da7bb..68daedb 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -2,7 +2,7 @@ from flask import Flask from flask_cors import CORS from .extensions import db, migrate from .config import DevelopmentConfig, ProductionConfig, TestingConfig -from .blueprints import torrent_bp, book_bp, music_bp, file_bp, video_bp, image_bp +from .blueprints import torrent_bp, book_bp, music_bp, file_bp, video_bp, image_bp, asmr_bp, magnet_bp def create_app(config_name="development"): @@ -10,13 +10,13 @@ def create_app(config_name="development"): CORS(app) app.config.from_object(DevelopmentConfig) - match config_name: - case 'production': - app.config.from_object(ProductionConfig) - case 'testing': - app.config.from_object(TestingConfig) - case _: - app.config.from_object(DevelopmentConfig) + if config_name == 'production': + app.config.from_object(ProductionConfig) + elif config_name == 'testing': + app.config.from_object(TestingConfig) + else: + app.config.from_object(DevelopmentConfig) + db.init_app(app) migrate.init_app(app, db) @@ -27,5 +27,7 @@ def create_app(config_name="development"): app.register_blueprint(file_bp.bp, url_prefix='/api/file') app.register_blueprint(video_bp.bp, url_prefix='/api/video') app.register_blueprint(image_bp.bp, url_prefix='/api/image') + app.register_blueprint(asmr_bp.bp, url_prefix='/api/asmr') + app.register_blueprint(magnet_bp.bp, url_prefix='/api/magnet') return app diff --git a/app/blueprints/asmr_bp.py b/app/blueprints/asmr_bp.py new file mode 100644 index 0000000..d044de4 --- /dev/null +++ b/app/blueprints/asmr_bp.py @@ -0,0 +1,11 @@ +from flask import Blueprint, Response, jsonify + +from app.services.asmr_service import AsmrService + +bp = Blueprint("asmr", __name__) + + +@bp.route("/") +def index(): + asmr_object = AsmrService() + return jsonify({"code": 200, "message": asmr_object.get_all()}) \ No newline at end of file diff --git a/app/blueprints/magnet_bp.py b/app/blueprints/magnet_bp.py new file mode 100644 index 0000000..2c16fda --- /dev/null +++ b/app/blueprints/magnet_bp.py @@ -0,0 +1,11 @@ +from flask import Blueprint, Response, jsonify + +from app.services.magnet_service import MagnetService + +bp = Blueprint("magnet", __name__) + + +@bp.route("/") +def index(): + magnet_object = MagnetService() + return jsonify({"code": 200, "message": magnet_object.to_torrent()}) \ No newline at end of file diff --git a/app/services/asmr_service.py b/app/services/asmr_service.py new file mode 100644 index 0000000..065c6eb --- /dev/null +++ b/app/services/asmr_service.py @@ -0,0 +1,16 @@ +import requests + +class AsmrService: + API_URL = "https://www.asmrgay.com/api/fs/list" + base_params = { + "path": "/asmr/中文音声", + "password": "", + "per_page": 30, + "refresh": False + } + + def __init__(self): + pass + + def get_all(self): + return [self.API_URL] diff --git a/app/services/book_service.py b/app/services/book_service.py index 2ddb229..5b93acd 100644 --- a/app/services/book_service.py +++ b/app/services/book_service.py @@ -87,8 +87,7 @@ class BookService: if privilege_level > self.setting["privilegeLevel"]: print("下载失败,权限等级不够") return - yield from self.download_file(f"{self.setting["baseUrl"]}{i.select_one( - 'a')['href']}", name, i.select_one('a').string) + yield from self.download_file(f"{self.setting['baseUrl']}{i.select_one('a')['href']}", name, i.select_one('a').string) # yield from self.download_file(f"{self.setting["baseUrl"]}{i.select_one( # 'a')['href']}", name, self.legitimate_naming(i.select_one('a').string)) except RetryError as e: @@ -106,7 +105,7 @@ class BookService: print(dir_name + "/" + file_name) content_type = response.headers.get('Content-Type', '') if content_type not in self.ALLOWED_CONTENT_TYPES: - yield f"event: mes_error\ndata: {self.setting["targetDate"]} {file_name}\n\n" + yield f"event: mes_error\ndata: {self.setting['targetDate']} {file_name}\n\n" print("不是可下载文件") return target_dir = self.download_path / self.setting["targetDate"] / dir_name / file_name @@ -115,7 +114,7 @@ class BookService: for chunk in response.iter_content(chunk_size=1024): if chunk: f.write(chunk) - yield f"data: {self.setting["targetDate"]} {file_name}\n\n" + yield f"data: {self.setting['targetDate']} {file_name}\n\n" except requests.RequestException as e: yield f"event: error\ndata: {self.setting['targetDate']} {file_name} 网络错误\n\n" raise # 触发 tenacity 重试 @@ -128,7 +127,7 @@ class BookService: yield f"data: 不允许下载当天的\n\n" return None # yield f"data: 当前页面 {page}\n\n" - url = f"{self.setting["baseUrl"]}forum.php?mod={self.setting["mod"]}&fid={self.setting["fid"]}&page={page}" # 版块页面地址 + url = f"{self.setting['baseUrl']}forum.php?mod={self.setting['mod']}&fid={self.setting['fid']}&page={page}" # 版块页面地址 response = self.session.get(url) # 请求 response.raise_for_status() soup = BeautifulSoup(response.text, 'lxml') # 解析 diff --git a/app/services/file_service.py b/app/services/file_service.py index 3aeff70..be069c6 100644 --- a/app/services/file_service.py +++ b/app/services/file_service.py @@ -16,7 +16,10 @@ class FileService: return None new_path = os.path.join(os.path.dirname(entry.path), new_name) - os.rename(entry.path, new_path) + try: + os.rename(entry.path, new_path) + except Exception as e: + print(e) self.result_list.insert(0, new_path) # return new_path @@ -73,4 +76,4 @@ class FileService: def rename(self) -> List[str]: FolderService(paths=self.paths, ignore_dirs=IGNORE_DIRS, folder_callback=self.process_folder_name, file_callback=self.process_file_name).process_folder() - return self.result_list \ No newline at end of file + return self.result_list diff --git a/app/services/folder_service.py b/app/services/folder_service.py index 98799f2..54e492b 100644 --- a/app/services/folder_service.py +++ b/app/services/folder_service.py @@ -1,11 +1,11 @@ import os -from typing import Optional, Callable, List +from typing import Optional, Callable, List, Union class FolderService: def __init__( self, - paths: List[str] | str, + paths: Union[List[str], str], ignore_dirs: Optional[set] = None, folder_callback: Optional[Callable] = None, file_callback: Optional[Callable] = None, diff --git a/app/services/magnet_service.py b/app/services/magnet_service.py new file mode 100644 index 0000000..6d45343 --- /dev/null +++ b/app/services/magnet_service.py @@ -0,0 +1,9 @@ +import requests + + +class MagnetService: + def __init__(self): + pass + + def to_torrent(self): + pass \ No newline at end of file diff --git a/flask-ui/src/api/index.ts b/flask-ui/src/api/index.ts index bcdf66c..6638c46 100644 --- a/flask-ui/src/api/index.ts +++ b/flask-ui/src/api/index.ts @@ -2,25 +2,25 @@ import request from "../utils/request.ts" type ResponseData = Promise<{ code: number, message: Array }> -export function book_download():ResponseData { +export function book_download(): ResponseData { return request({ url: "/book/download", }) } -export function video_findDeduplication():ResponseData { +export function video_findDeduplication(): ResponseData { return request({ url: "/video/findDeduplication", }) } -export function video_deduplication():ResponseData { +export function video_deduplication(): ResponseData { return request({ url: "/video/deduplication", }) } -export function video_hasTorrent():ResponseData { +export function video_hasTorrent(): ResponseData { return request({ url: "/video/hasTorrent", }) @@ -32,31 +32,31 @@ export function file_rename(): ResponseData { }) } -export function torrent_deduplication():ResponseData { +export function torrent_deduplication(): ResponseData { return request({ url: "/torrent/deduplication", }) } -export function image_export():ResponseData { +export function image_export(): ResponseData { return request({ url: "/image/export", }) } -export function image_hasTorrent():ResponseData { +export function image_hasTorrent(): ResponseData { return request({ url: "/image/hasTorrent", }) } -export function music_rename():ResponseData { +export function music_rename(): ResponseData { return request({ url: "/music/rename", }) } -export function test():ResponseData { +export function test(): ResponseData { return request({ url: "/test", }) @@ -67,3 +67,9 @@ export function torrent_statistics(): ResponseData { url: "/torrent/statistics", }) } + +export function asmr(): ResponseData { + return request({ + url: "/asmr/", + }) +} diff --git a/flask-ui/src/utils/request.ts b/flask-ui/src/utils/request.ts index a2f9ce1..11cfef4 100644 --- a/flask-ui/src/utils/request.ts +++ b/flask-ui/src/utils/request.ts @@ -25,7 +25,7 @@ axios.defaults.headers["Content-Type"] = "application/json; charset=UTF-8" const service: AxiosInstance = axios.create({ baseURL: "http://192.168.1.32:5000/api/", // baseURL: "/api", - timeout: 10000, + timeout: 30000, }) service.interceptors.request.use((config: InternalAxiosRequestConfig) => { diff --git a/flask-ui/src/views/HomeView.vue b/flask-ui/src/views/HomeView.vue index 7dcef89..47ab930 100644 --- a/flask-ui/src/views/HomeView.vue +++ b/flask-ui/src/views/HomeView.vue @@ -1,6 +1,7 @@