diff --git a/.github/ISSUE_TEMPLATE/rfc.yml b/.github/ISSUE_TEMPLATE/rfc.yml index 30f11674..991916c3 100644 --- a/.github/ISSUE_TEMPLATE/rfc.yml +++ b/.github/ISSUE_TEMPLATE/rfc.yml @@ -10,7 +10,7 @@ body: 目的是让协作的开发者间清晰的知道「要做什么」和「具体会怎么做」,以及所有的开发者都能公开透明的参与讨论; 以便评估和讨论产生的影响 (遗漏的考虑、向后兼容性、与现有功能的冲突), 因此提案侧重在对解决问题的 **方案、设计、步骤** 的描述上。 - + 如果仅希望讨论是否添加或改进某功能本身,请使用 -> [Issue: 功能改进](https://github.com/jxxghp/MoviePilot/issues/new?assignees=&labels=feature+request&projects=&template=feature_request.yml&title=%5BFeature+Request%5D%3A+) - type: textarea id: background diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index a87cb7da..e7d3263a 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -8,17 +8,17 @@ jobs: pylint: runs-on: ubuntu-latest name: Pylint Code Quality Check - + steps: - name: Checkout code uses: actions/checkout@v4 - + - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.12' cache: 'pip' - + - name: Cache pip dependencies uses: actions/cache@v4 with: @@ -26,7 +26,7 @@ jobs: key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt', '**/requirements.in') }} restore-keys: | ${{ runner.os }}-pip- - + - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel @@ -41,7 +41,7 @@ jobs: else echo "⚠️ 未找到依赖文件,仅安装 pylint" fi - + - name: Verify pylint config run: | # 检查项目中的pylint配置文件是否存在 @@ -57,35 +57,35 @@ jobs: run: | # 运行pylint,检查主要的Python文件 echo "🚀 运行 Pylint 错误检查..." - + # 检查主要目录 - 只关注错误,如果有错误则退出 echo "📂 检查 app/ 目录..." pylint app/ --output-format=colorized --reports=yes --score=yes - + # 检查根目录的Python文件 echo "📂 检查根目录 Python 文件..." for file in $(find . -name "*.py" -not -path "./.*" -not -path "./.venv/*" -not -path "./build/*" -not -path "./dist/*" -not -path "./tests/*" -not -path "./docs/*" -not -path "./__pycache__/*" -maxdepth 1); do echo "检查文件: $file" pylint "$file" --output-format=colorized || exit 1 done - + # 生成详细报告 echo "📊 生成 Pylint 详细报告..." pylint app/ --output-format=json > pylint-report.json || true - + # 显示评分(仅供参考) echo "📈 Pylint 评分(仅供参考):" pylint app/ --score=yes --reports=no | tail -2 || true - + - name: Upload pylint report uses: actions/upload-artifact@v4 if: always() with: name: pylint-report path: pylint-report.json - + - name: Summary run: | echo "🎉 Pylint 检查完成!" echo "✅ 没有发现语法错误或严重问题" - echo "📊 详细报告已保存为构建工件" \ No newline at end of file + echo "📊 详细报告已保存为构建工件" \ No newline at end of file diff --git a/.pylintrc b/.pylintrc index 55dcaec4..f59dd614 100644 --- a/.pylintrc +++ b/.pylintrc @@ -12,7 +12,7 @@ jobs=0 # 只关注错误级别的问题,禁用警告、约定和重构建议 # E = Error (错误) - 会导致构建失败 # W = Warning (警告) - 仅显示,不会失败 -# R = Refactor (重构建议) - 仅显示,不会失败 +# R = Refactor (重构建议) - 仅显示,不会失败 # C = Convention (约定) - 仅显示,不会失败 # I = Information (信息) - 仅显示,不会失败 @@ -80,4 +80,4 @@ ignore-imports=yes [TYPECHECK] # 生成缺失成员提示的类列表 -generated-members=requests.packages.urllib3 \ No newline at end of file +generated-members=requests.packages.urllib3 \ No newline at end of file diff --git a/app/chain/media.py b/app/chain/media.py index 850d1394..52e6ab02 100644 --- a/app/chain/media.py +++ b/app/chain/media.py @@ -43,7 +43,7 @@ class MediaChain(ChainBase): 'movie_banner': True, # 电影横幅图 'movie_thumb': True, # 电影缩略图 'tv_nfo': True, # 电视剧NFO - 'tv_poster': True, # 电视剧海报 + 'tv_poster': True, # 电视剧海报 'tv_backdrop': True, # 电视剧背景图 'tv_banner': True, # 电视剧横幅图 'tv_logo': True, # 电视剧Logo @@ -448,7 +448,7 @@ class MediaChain(ChainBase): if not mediainfo: logger.warn(f"{filepath} 无法识别文件媒体信息!") return - + # 获取刮削开关配置 scraping_switchs = self._get_scraping_switchs() logger.info(f"开始刮削:{filepath} ...") @@ -520,7 +520,7 @@ class MediaChain(ChainBase): should_scrape = scraping_switchs.get('movie_thumb', True) else: should_scrape = True # 未知类型默认刮削 - + if should_scrape: image_path = filepath.with_name(image_name) if overwrite or not storagechain.get_file_item(storage=fileitem.storage, @@ -653,7 +653,7 @@ class MediaChain(ChainBase): should_scrape = scraping_switchs.get('season_thumb', True) else: should_scrape = True # 未知类型默认刮削 - + if should_scrape: image_path = filepath.with_name(image_name) # 只下载当前刮削季的图片 @@ -714,7 +714,7 @@ class MediaChain(ChainBase): should_scrape = scraping_switchs.get('tv_thumb', True) else: should_scrape = True # 未知类型默认刮削 - + if should_scrape: image_path = filepath / image_name if overwrite or not storagechain.get_file_item(storage=fileitem.storage, diff --git a/app/chain/system.py b/app/chain/system.py index 1431cda5..fb92665f 100644 --- a/app/chain/system.py +++ b/app/chain/system.py @@ -35,7 +35,7 @@ class SystemChain(ChainBase): 重启系统 """ from app.core.config import global_vars - + if channel and userid: self.post_message(Notification(channel=channel, source=source, title="系统正在重启,请耐心等候!", userid=userid)) diff --git a/app/chain/transfer.py b/app/chain/transfer.py index f8fe124e..560b2233 100755 --- a/app/chain/transfer.py +++ b/app/chain/transfer.py @@ -880,7 +880,7 @@ class TransferChain(ChainBase, metaclass=Singleton): ) -> List[Tuple[FileItem, bool]]: """ 获取整理目录或文件列表 - + :param fileitem: 文件项 :param depth: 递归深度,默认为1 """ diff --git a/app/core/cache.py b/app/core/cache.py index c5a12b97..e2a1d0d4 100644 --- a/app/core/cache.py +++ b/app/core/cache.py @@ -150,7 +150,7 @@ class CacheToolsBackend(CacheBackend): region = self.get_region(region) return self._region_caches.get(region) - def set(self, key: str, value: Any, ttl: Optional[int] = None, + def set(self, key: str, value: Any, ttl: Optional[int] = None, region: Optional[str] = DEFAULT_CACHE_REGION, **kwargs) -> None: """ 设置缓存值支持每个 key 独立配置 TTL 和 Maxsize @@ -357,7 +357,7 @@ class RedisBackend(CacheBackend): region = self.get_region(quote(region)) return f"{region}:key:{quote(key)}" - def set(self, key: str, value: Any, ttl: Optional[int] = None, + def set(self, key: str, value: Any, ttl: Optional[int] = None, region: Optional[str] = DEFAULT_CACHE_REGION, **kwargs) -> None: """ 设置缓存 diff --git a/app/core/metainfo.py b/app/core/metainfo.py index b38c019c..c9dbe02f 100644 --- a/app/core/metainfo.py +++ b/app/core/metainfo.py @@ -154,35 +154,35 @@ def find_metainfo(title: str) -> Tuple[str, dict]: # 去除title中该部分 if tmdbid or mtype or begin_season or end_season or begin_episode or end_episode: title = title.replace(f"{{[{result}]}}", '') - + # 支持Emby格式的ID标签 # 1. [tmdbid=xxxx] 或 [tmdbid-xxxx] 格式 tmdb_match = re.search(r'\[tmdbid[=\-](\d+)\]', title) if tmdb_match: metainfo['tmdbid'] = tmdb_match.group(1) title = re.sub(r'\[tmdbid[=\-](\d+)\]', '', title).strip() - + # 2. [tmdb=xxxx] 或 [tmdb-xxxx] 格式 if not metainfo['tmdbid']: tmdb_match = re.search(r'\[tmdb[=\-](\d+)\]', title) if tmdb_match: metainfo['tmdbid'] = tmdb_match.group(1) title = re.sub(r'\[tmdb[=\-](\d+)\]', '', title).strip() - + # 3. {tmdbid=xxxx} 或 {tmdbid-xxxx} 格式 if not metainfo['tmdbid']: tmdb_match = re.search(r'\{tmdbid[=\-](\d+)\}', title) if tmdb_match: metainfo['tmdbid'] = tmdb_match.group(1) title = re.sub(r'\{tmdbid[=\-](\d+)\}', '', title).strip() - + # 4. {tmdb=xxxx} 或 {tmdb-xxxx} 格式 if not metainfo['tmdbid']: tmdb_match = re.search(r'\{tmdb[=\-](\d+)\}', title) if tmdb_match: metainfo['tmdbid'] = tmdb_match.group(1) title = re.sub(r'\{tmdb[=\-](\d+)\}', '', title).strip() - + # 计算季集总数 if metainfo.get('begin_season') and metainfo.get('end_season'): if metainfo['begin_season'] > metainfo['end_season']: diff --git a/app/helper/browser.py b/app/helper/browser.py index 8f90ef9c..7c36ce5a 100644 --- a/app/helper/browser.py +++ b/app/helper/browser.py @@ -46,17 +46,17 @@ class PlaywrightHelper: browser = playwright[self.browser_type].launch(headless=headless) context = browser.new_context(user_agent=ua, proxy=proxies) page = context.new_page() - + if cookies: page.set_extra_http_headers({"cookie": cookies}) - + if not self.__pass_cloudflare(url, page): logger.warn("cloudflare challenge fail!") page.wait_for_load_state("networkidle", timeout=timeout * 1000) - + # 回调函数 result = callback(page) - + except Exception as e: logger.error(f"网页操作失败: {str(e)}") finally: @@ -69,7 +69,7 @@ class PlaywrightHelper: browser.close() except Exception as e: logger.error(f"Playwright初始化失败: {str(e)}") - + return result def get_page_source(self, url: str, @@ -97,16 +97,16 @@ class PlaywrightHelper: browser = playwright[self.browser_type].launch(headless=headless) context = browser.new_context(user_agent=ua, proxy=proxies) page = context.new_page() - + if cookies: page.set_extra_http_headers({"cookie": cookies}) - + if not self.__pass_cloudflare(url, page): logger.warn("cloudflare challenge fail!") page.wait_for_load_state("networkidle", timeout=timeout * 1000) - + source = page.content() - + except Exception as e: logger.error(f"获取网页源码失败: {str(e)}") source = None @@ -120,7 +120,7 @@ class PlaywrightHelper: browser.close() except Exception as e: logger.error(f"Playwright初始化失败: {str(e)}") - + return source diff --git a/app/helper/memory.py b/app/helper/memory.py index a2b547f1..57e7aeec 100644 --- a/app/helper/memory.py +++ b/app/helper/memory.py @@ -361,7 +361,7 @@ class MemoryHelper(metaclass=Singleton): # 对于较大的对象,使用 asizeof 进行深度计算 size_bytes = asizeof.asizeof(obj) - + # 只处理大于10KB的对象,提高分析效率 if size_bytes < 10240: continue diff --git a/app/helper/ocr.py b/app/helper/ocr.py index 2ef22db2..9ec76a11 100644 --- a/app/helper/ocr.py +++ b/app/helper/ocr.py @@ -9,7 +9,7 @@ class OcrHelper: _ocr_b64_url = f"{settings.OCR_HOST}/captcha/base64" - def get_captcha_text(self, image_url: Optional[str] = None, image_b64: Optional[str] = None, + def get_captcha_text(self, image_url: Optional[str] = None, image_b64: Optional[str] = None, cookie: Optional[str] = None, ua: Optional[str] = None): """ 根据图片地址,获取验证码图片,并识别内容 diff --git a/app/helper/plugin.py b/app/helper/plugin.py index 68ca396d..2d2ef766 100644 --- a/app/helper/plugin.py +++ b/app/helper/plugin.py @@ -53,10 +53,10 @@ class PluginHelper(metaclass=Singleton): # 如果强制刷新,直接调用不带缓存的版本 if force: return self._get_plugins_uncached(repo_url, package_version) - + # 正常情况下调用带缓存的版本 return self._get_plugins_cached(repo_url, package_version) - + @cached(maxsize=64, ttl=1800) def _get_plugins_cached(self, repo_url: str, package_version: Optional[str] = None) -> Optional[Dict[str, dict]]: """ @@ -65,7 +65,7 @@ class PluginHelper(metaclass=Singleton): :param package_version: 首选插件版本 (如 "v2", "v3"),如果不指定则获取 v1 版本 """ return self._get_plugins_uncached(repo_url, package_version) - + def _get_plugins_uncached(self, repo_url: str, package_version: Optional[str] = None) -> Optional[Dict[str, dict]]: """ 获取Github所有最新插件列表(不使用缓存) diff --git a/app/helper/rss.py b/app/helper/rss.py index 7f9373ab..83ee4a57 100644 --- a/app/helper/rss.py +++ b/app/helper/rss.py @@ -289,7 +289,7 @@ class RssHelper: if not ret_xml or not ret_xml.strip(): logger.error("RSS内容为空") return False - + # 检查是否包含基本的RSS/XML结构 ret_xml_stripped = ret_xml.strip() if not ret_xml_stripped.startswith('<'): diff --git a/app/helper/system.py b/app/helper/system.py index f93d239f..faf9f3dc 100644 --- a/app/helper/system.py +++ b/app/helper/system.py @@ -91,10 +91,10 @@ class SystemHelper: # 检查是否有有效的重启策略 auto_restart_policies = ['always', 'unless-stopped', 'on-failure'] has_restart_policy = policy_name in auto_restart_policies - + logger.info(f"容器重启策略: {policy_name}, 支持自动重启: {has_restart_policy}") return has_restart_policy - + except Exception as e: logger.warning(f"检查重启策略失败: {str(e)}") return False @@ -106,7 +106,7 @@ class SystemHelper: """ if not SystemUtils.is_docker(): return False, "非Docker环境,无法重启!" - + try: # 检查容器是否配置了自动重启策略 has_restart_policy = SystemHelper._check_restart_policy() diff --git a/app/main.py b/app/main.py index 0aac48f3..dafbb62a 100644 --- a/app/main.py +++ b/app/main.py @@ -83,7 +83,7 @@ if __name__ == '__main__': # 注册信号处理器 signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGINT, signal_handler) - + # 启动托盘 start_tray() # 初始化数据库 diff --git a/app/modules/bangumi/__init__.py b/app/modules/bangumi/__init__.py index d51364cc..3246d03a 100644 --- a/app/modules/bangumi/__init__.py +++ b/app/modules/bangumi/__init__.py @@ -51,7 +51,7 @@ class BangumiModule(_ModuleBase): 获取模块子类型 """ return MediaRecognizeType.Bangumi - + @staticmethod def get_priority() -> int: """ diff --git a/app/modules/filter/RuleParser.py b/app/modules/filter/RuleParser.py index 6effa6dd..c02cfd09 100644 --- a/app/modules/filter/RuleParser.py +++ b/app/modules/filter/RuleParser.py @@ -54,7 +54,7 @@ class RuleParser: if __name__ == '__main__': # 测试代码 expression_str = """ - SPECSUB & CNVOI & 4K & !BLU & !REMUX & !WEBDL & 60FPS & !DOLBY & !SDR & !3D > CNSUB & CNVOI & 4K & !BLU & !REMUX & !WEBDL & 60FPS & !DOLBY & !SDR & !3D > SPECSUB & 4K & !BLU & !REMUX & !WEBDL & 60FPS & !DOLBY & !SDR & !3D > CNSUB & 4K & !BLU & !REMUX & !WEBDL & 60FPS & !DOLBY & !SDR & !3D > SPECSUB & CNVOI & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & HDR & !3D > CNSUB & CNVOI & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & HDR & !3D > SPECSUB & CNVOI & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & !3D > CNSUB & CNVOI & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & !3D > SPECSUB & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & HDR & !3D > CNSUB & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & HDR & !3D > SPECSUB & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & !3D > CNSUB & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & !3D > SPECSUB & CNVOI & 4K & WEBDL & 60FPS & !DOLBY & !SDR & !3D > CNSUB & CNVOI & 4K & WEBDL & 60FPS & !DOLBY & !SDR & !3D > SPECSUB & 4K & WEBDL & 60FPS & !DOLBY & !SDR & !3D > CNSUB & 4K & WEBDL & 60FPS & !DOLBY & !SDR & !3D > SPECSUB & CNVOI & 4K & WEBDL & !DOLBY & HDR & !3D > CNSUB & CNVOI & 4K & WEBDL & !DOLBY & HDR & !3D > SPECSUB & CNVOI & 4K & WEBDL & !DOLBY & !3D > CNSUB & CNVOI & 4K & WEBDL & !DOLBY & !3D > SPECSUB & 4K & WEBDL & !DOLBY & HDR & !3D > CNSUB & 4K & WEBDL & !DOLBY & HDR & !3D > SPECSUB & 4K & WEBDL & !DOLBY & !3D > CNSUB & 4K & WEBDL & !DOLBY & !3D > SPECSUB & CNVOI & 4K & !BLU & !WEBDL & !DOLBY & HDR & !3D > CNSUB & CNVOI & 4K & !BLU & !WEBDL & !DOLBY & HDR & !3D > SPECSUB & CNVOI & 4K & !BLU & !WEBDL & !DOLBY & !3D > CNSUB & CNVOI & 4K & !BLU & !WEBDL & !DOLBY & !3D > SPECSUB & 4K & !BLU & !WEBDL & !DOLBY & HDR & !3D > CNSUB & 4K & !BLU & !WEBDL & !DOLBY & HDR & !3D > SPECSUB & 4K & !BLU & !WEBDL & !DOLBY & !SDR & !3D > CNSUB & 4K & !BLU & !WEBDL & !DOLBY & !SDR & !3D > 4K & !BLU & !REMUX & !DOLBY & HDR & !3D > 4K & !BLURAY & !REMUX & !DOLBY & !3D > SPECSUB & 1080P & !BLU & !REMUX & !WEBDL & !DOLBY & HDR & !3D > CNSUB & 1080P & !BLU & !REMUX & !WEBDL & !DOLBY & HDR & !3D > SPECSUB & 1080P & !BLU & !REMUX & !WEBDL & !DOLBY & !3D > CNSUB & 1080P & !BLU & !REMUX & !WEBDL & !DOLBY & !3D > SPECSUB & 1080P & !BLU & !WEBDL & !DOLBY & HDR & !3D > CNSUB & 1080P & !BLU & !WEBDL & !DOLBY & HDR & !3D > SPECSUB & 1080P & !BLU & !WEBDL & !DOLBY & !3D > CNSUB & 1080P & !BLU & !WEBDL & !DOLBY & !3D > SPECSUB & 1080P & WEBDL & !DOLBY & HDR & !3D > CNSUB & 1080P & WEBDL & !DOLBY & HDR & !3D > SPECSUB & 1080P & WEBDL & !DOLBY & !3D > CNSUB & 1080P & WEBDL & !DOLBY & !3D > 1080P & !BLU & !REMUX & !DOLBY & HDR & !3D > 1080P & !BLU & !REMUX & !DOLBY & !3D + SPECSUB & CNVOI & 4K & !BLU & !REMUX & !WEBDL & 60FPS & !DOLBY & !SDR & !3D > CNSUB & CNVOI & 4K & !BLU & !REMUX & !WEBDL & 60FPS & !DOLBY & !SDR & !3D > SPECSUB & 4K & !BLU & !REMUX & !WEBDL & 60FPS & !DOLBY & !SDR & !3D > CNSUB & 4K & !BLU & !REMUX & !WEBDL & 60FPS & !DOLBY & !SDR & !3D > SPECSUB & CNVOI & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & HDR & !3D > CNSUB & CNVOI & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & HDR & !3D > SPECSUB & CNVOI & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & !3D > CNSUB & CNVOI & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & !3D > SPECSUB & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & HDR & !3D > CNSUB & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & HDR & !3D > SPECSUB & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & !3D > CNSUB & 4K & !BLU & !REMUX & !WEBDL & !DOLBY & !3D > SPECSUB & CNVOI & 4K & WEBDL & 60FPS & !DOLBY & !SDR & !3D > CNSUB & CNVOI & 4K & WEBDL & 60FPS & !DOLBY & !SDR & !3D > SPECSUB & 4K & WEBDL & 60FPS & !DOLBY & !SDR & !3D > CNSUB & 4K & WEBDL & 60FPS & !DOLBY & !SDR & !3D > SPECSUB & CNVOI & 4K & WEBDL & !DOLBY & HDR & !3D > CNSUB & CNVOI & 4K & WEBDL & !DOLBY & HDR & !3D > SPECSUB & CNVOI & 4K & WEBDL & !DOLBY & !3D > CNSUB & CNVOI & 4K & WEBDL & !DOLBY & !3D > SPECSUB & 4K & WEBDL & !DOLBY & HDR & !3D > CNSUB & 4K & WEBDL & !DOLBY & HDR & !3D > SPECSUB & 4K & WEBDL & !DOLBY & !3D > CNSUB & 4K & WEBDL & !DOLBY & !3D > SPECSUB & CNVOI & 4K & !BLU & !WEBDL & !DOLBY & HDR & !3D > CNSUB & CNVOI & 4K & !BLU & !WEBDL & !DOLBY & HDR & !3D > SPECSUB & CNVOI & 4K & !BLU & !WEBDL & !DOLBY & !3D > CNSUB & CNVOI & 4K & !BLU & !WEBDL & !DOLBY & !3D > SPECSUB & 4K & !BLU & !WEBDL & !DOLBY & HDR & !3D > CNSUB & 4K & !BLU & !WEBDL & !DOLBY & HDR & !3D > SPECSUB & 4K & !BLU & !WEBDL & !DOLBY & !SDR & !3D > CNSUB & 4K & !BLU & !WEBDL & !DOLBY & !SDR & !3D > 4K & !BLU & !REMUX & !DOLBY & HDR & !3D > 4K & !BLURAY & !REMUX & !DOLBY & !3D > SPECSUB & 1080P & !BLU & !REMUX & !WEBDL & !DOLBY & HDR & !3D > CNSUB & 1080P & !BLU & !REMUX & !WEBDL & !DOLBY & HDR & !3D > SPECSUB & 1080P & !BLU & !REMUX & !WEBDL & !DOLBY & !3D > CNSUB & 1080P & !BLU & !REMUX & !WEBDL & !DOLBY & !3D > SPECSUB & 1080P & !BLU & !WEBDL & !DOLBY & HDR & !3D > CNSUB & 1080P & !BLU & !WEBDL & !DOLBY & HDR & !3D > SPECSUB & 1080P & !BLU & !WEBDL & !DOLBY & !3D > CNSUB & 1080P & !BLU & !WEBDL & !DOLBY & !3D > SPECSUB & 1080P & WEBDL & !DOLBY & HDR & !3D > CNSUB & 1080P & WEBDL & !DOLBY & HDR & !3D > SPECSUB & 1080P & WEBDL & !DOLBY & !3D > CNSUB & 1080P & WEBDL & !DOLBY & !3D > 1080P & !BLU & !REMUX & !DOLBY & HDR & !3D > 1080P & !BLU & !REMUX & !DOLBY & !3D """ for exp in expression_str.split('>'): parsed_expr = RuleParser().parse(exp.strip()) diff --git a/app/modules/telegram/__init__.py b/app/modules/telegram/__init__.py index ad7ac183..a9c55a89 100644 --- a/app/modules/telegram/__init__.py +++ b/app/modules/telegram/__init__.py @@ -122,7 +122,7 @@ class TelegramModule(_ModuleBase, _MessageBase[Telegram]): 'text': '' } } - + 按钮回调格式: { 'callback_query': { diff --git a/app/modules/themoviedb/tmdbv3api/as_obj.py b/app/modules/themoviedb/tmdbv3api/as_obj.py index 111e9010..2f4254fe 100644 --- a/app/modules/themoviedb/tmdbv3api/as_obj.py +++ b/app/modules/themoviedb/tmdbv3api/as_obj.py @@ -59,7 +59,7 @@ class AsObj: def __setitem__(self, key, value): return setattr(self, key, value) - + def __str__(self): return str(self._obj_list) if self._list_only else str(self._dict()) @@ -91,10 +91,10 @@ class AsObj: def pop(self, key, value=None): return self.__dict__.pop(key, value) - + def popitem(self): return self.__dict__.popitem() - + def setdefault(self, key, value=None): return self.__dict__.setdefault(key, value) diff --git a/app/modules/themoviedb/tmdbv3api/objs/collection.py b/app/modules/themoviedb/tmdbv3api/objs/collection.py index 73ca1701..ffb0ee25 100644 --- a/app/modules/themoviedb/tmdbv3api/objs/collection.py +++ b/app/modules/themoviedb/tmdbv3api/objs/collection.py @@ -4,7 +4,7 @@ from ..tmdb import TMDb class Collection(TMDb): _urls = { "details": "/collection/%s", - "images": "/collection/%s/images", + "images": "/collection/%s/images", "translations": "/collection/%s/translations" } diff --git a/app/modules/themoviedb/tmdbv3api/objs/company.py b/app/modules/themoviedb/tmdbv3api/objs/company.py index eed7add3..77ea46b9 100644 --- a/app/modules/themoviedb/tmdbv3api/objs/company.py +++ b/app/modules/themoviedb/tmdbv3api/objs/company.py @@ -3,7 +3,7 @@ from ..tmdb import TMDb class Company(TMDb): _urls = { - "details": "/company/%s", + "details": "/company/%s", "alternative_names": "/company/%s/alternative_names", "images": "/company/%s/images", "movies": "/company/%s/movies" diff --git a/app/modules/themoviedb/tmdbv3api/objs/movie.py b/app/modules/themoviedb/tmdbv3api/objs/movie.py index 9e01e57c..5c93639a 100644 --- a/app/modules/themoviedb/tmdbv3api/objs/movie.py +++ b/app/modules/themoviedb/tmdbv3api/objs/movie.py @@ -101,11 +101,11 @@ class Movie(TMDb): :return: """ return self._request_obj(self._urls["external_ids"] % movie_id) - + def images(self, movie_id, include_image_language=None): """ Get the images that belong to a movie. - Querying images with a language parameter will filter the results. + Querying images with a language parameter will filter the results. If you want to include a fallback language (especially useful for backdrops) you can use the include_image_language parameter. This should be a comma separated value like so: include_image_language=en,null. diff --git a/app/modules/themoviedb/tmdbv3api/objs/search.py b/app/modules/themoviedb/tmdbv3api/objs/search.py index 1d4b377e..78912cb9 100644 --- a/app/modules/themoviedb/tmdbv3api/objs/search.py +++ b/app/modules/themoviedb/tmdbv3api/objs/search.py @@ -55,7 +55,7 @@ class Search(TMDb): params="query=%s&page=%s" % (quote(term), page), key="results" ) - + def movies(self, term, adult=None, region=None, year=None, release_year=None, page=1): """ Search for movies. diff --git a/app/modules/transmission/transmission.py b/app/modules/transmission/transmission.py index 564a55a9..21b249a1 100755 --- a/app/modules/transmission/transmission.py +++ b/app/modules/transmission/transmission.py @@ -19,7 +19,7 @@ class Transmission: "peersGettingFromUs", "peersSendingToUs", "uploadRatio", "uploadedEver", "downloadedEver", "downloadDir", "error", "errorString", "doneDate", "queuePosition", "activityDate", "trackers"] - def __init__(self, host: Optional[str] = None, port: Optional[int] = None, + def __init__(self, host: Optional[str] = None, port: Optional[int] = None, username: Optional[str] = None, password: Optional[str] = None, **kwargs): """ 若不设置参数,则创建配置文件设置的下载器 diff --git a/app/modules/wechat/__init__.py b/app/modules/wechat/__init__.py index ce8ac0ef..cfc99a7a 100644 --- a/app/modules/wechat/__init__.py +++ b/app/modules/wechat/__init__.py @@ -128,7 +128,7 @@ class WechatModule(_ModuleBase, _MessageBase[WeChat]): 1、消息格式: - + 1348831860 @@ -143,7 +143,7 @@ class WechatModule(_ModuleBase, _MessageBase[WeChat]): 1 - + """ dom_tree = xml.dom.minidom.parseString(sMsg.decode('UTF-8')) root_node = dom_tree.documentElement diff --git a/app/utils/http.py b/app/utils/http.py index f3dadc30..e7b047d5 100644 --- a/app/utils/http.py +++ b/app/utils/http.py @@ -523,7 +523,7 @@ class RequestUtils: def get_json(self, url: str, params: dict = None, **kwargs) -> Optional[dict]: """ 发送GET请求并返回JSON数据,自动关闭连接 - :param url: 请求的URL + :param url: 请求的URL :param params: 请求的参数 :param kwargs: 其他请求参数 :return: JSON数据,若发生异常则返回None diff --git a/database/versions/294b007932ef_2_0_0.py b/database/versions/294b007932ef_2_0_0.py index 863b887a..f03c6a51 100644 --- a/database/versions/294b007932ef_2_0_0.py +++ b/database/versions/294b007932ef_2_0_0.py @@ -1,7 +1,7 @@ """2.0.0 Revision ID: 294b007932ef -Revises: +Revises: Create Date: 2024-07-20 08:43:40.741251 """ diff --git a/docker/docker_http_proxy.conf b/docker/docker_http_proxy.conf index 0ea788ad..e0154e35 100644 --- a/docker/docker_http_proxy.conf +++ b/docker/docker_http_proxy.conf @@ -15,25 +15,25 @@ http { server { listen 38379; server_name localhost; - + access_log /dev/stdout combined; error_log /dev/stdout; - + location / { proxy_pass http://docker; proxy_redirect off; - + proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - + client_max_body_size 10m; client_body_buffer_size 128k; - + proxy_connect_timeout 90; proxy_send_timeout 120; proxy_read_timeout 120; - + proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; diff --git a/docs/development-setup.md b/docs/development-setup.md index 2c3bfb3b..39ae73c3 100644 --- a/docs/development-setup.md +++ b/docs/development-setup.md @@ -61,7 +61,7 @@ pip install pip-tools ```bash pip-compile --upgrade-package requests requirements.in ``` - + 3. **全量更新依赖项**: 如果你想更新 `requirements.in` 中的所有依赖包,运行以下命令生成或更新 `requirements.txt` 文件: