Files
MoviePilot/app/db/models/site.py
freeman f3ad81b39e style: apply safe ruff auto-fixes and exempt startup late imports
Run `ruff check app tests scripts --fix` with the configured rule set
(E4/E7/E9/F/I): import sorting (I001), f-strings without placeholders
(F541), lambda/variable/unused-import cleanups that ruff marks safe.
Nine files whose only ruff debt sits next to pre-existing pylint
import-resolution errors (lazy exports, sys.path script imports) or
whose "unused" imports are reached through attribute access by tests are
left untouched so the changed-file pylint gate and the benchmark tests
stay green; their diagnostics remain in the baseline.

app/startup/lifecycle/__init__.py and app/main.py import business
modules after cache composition, import-path and stdio setup on purpose
(the source comments document the contract), so declare E402
per-file-ignores for them instead of adding per-line noqa.

Ruff ratchet watermark drops from 498 to 100; sync the baseline fixture
and the optimization checklist figure.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 13:29:09 +08:00

130 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from datetime import datetime
from typing import Any, Optional
from sqlalchemy import JSON, Boolean, Integer, String, delete, select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import Mapped, Session, mapped_column
from app.db.base import Base, get_id_column
class Site(Base):
"""
站点表
"""
id = get_id_column()
# 站点名
name: Mapped[str] = mapped_column(String, nullable=False)
# 域名Key
domain: Mapped[Optional[str]] = mapped_column(String, index=True)
# 站点地址
url: Mapped[str] = mapped_column(String, nullable=False)
# 站点优先级
pri: Mapped[Optional[int]] = mapped_column(Integer, default=1)
# RSS地址,未启用
rss: Mapped[Optional[str]] = mapped_column(String)
# Cookie
cookie: Mapped[Optional[str]] = mapped_column(String)
# User-Agent
ua: Mapped[Optional[str]] = mapped_column(String)
# ApiKey
apikey: Mapped[Optional[str]] = mapped_column(String)
# Token
token: Mapped[Optional[str]] = mapped_column(String)
# 是否使用代理 0-否,1-是
proxy: Mapped[Optional[int]] = mapped_column(Integer)
# 过滤规则
filter: Mapped[Optional[str]] = mapped_column(String)
# 是否渲染
render: Mapped[Optional[int]] = mapped_column(Integer)
# 是否公开站点
public: Mapped[Optional[int]] = mapped_column(Integer)
# 附加信息
note: Mapped[Optional[Any]] = mapped_column(JSON)
# 流控单位周期
limit_interval: Mapped[Optional[int]] = mapped_column(Integer, default=0)
# 流控次数
limit_count: Mapped[Optional[int]] = mapped_column(Integer, default=0)
# 流控间隔
limit_seconds: Mapped[Optional[int]] = mapped_column(Integer, default=0)
# 超时时间
timeout: Mapped[Optional[int]] = mapped_column(Integer, default=15)
# 是否启用
is_active: Mapped[Optional[bool]] = mapped_column(Boolean(), default=True)
# 创建时间
lst_mod_date: Mapped[Optional[str]] = mapped_column(String, default=datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
# 下载器
downloader: Mapped[Optional[str]] = mapped_column(String)
@classmethod
def get_by_domain(cls, db: Session, domain: str):
"""在调用方 Session 中按域名查询站点。"""
return db.execute(select(cls).where(cls.domain == domain)).scalars().first()
@classmethod
async def async_get_by_domain(
cls,
db: AsyncSession,
domain: str,
):
"""在调用方 AsyncSession 中按域名查询站点。"""
result = await db.execute(select(cls).where(cls.domain == domain))
return result.scalar_one_or_none()
@classmethod
async def async_get_by_name(
cls,
db: AsyncSession,
name: str,
):
"""在调用方 AsyncSession 中按站点名称查询。"""
result = await db.execute(select(cls).where(cls.name == name))
return result.scalar_one_or_none()
@classmethod
def get_actives(cls, db: Session):
"""在调用方 Session 中查询启用站点。"""
return list(db.execute(
select(cls).where(cls.is_active.is_(True))
).scalars().all())
@classmethod
async def async_get_actives(cls, db: AsyncSession):
"""在调用方 AsyncSession 中查询启用站点。"""
result = await db.execute(select(cls).where(cls.is_active.is_(True)))
return list(result.scalars().all())
@classmethod
def list_order_by_pri(cls, db: Session):
"""在调用方 Session 中按优先级升序查询站点。"""
return list(db.execute(select(cls).order_by(cls.pri)).scalars().all())
@classmethod
async def async_list_order_by_pri(cls, db: AsyncSession):
"""在调用方 AsyncSession 中按优先级升序查询站点。"""
result = await db.execute(select(cls).order_by(cls.pri))
return list(result.scalars().all())
@classmethod
def get_domains_by_ids(
cls,
db: Session,
ids: list[int],
):
"""在调用方 Session 中按 ID 查询域名。"""
if not ids:
return []
return list(db.execute(
select(cls.domain).where(cls.id.in_(ids))
).scalars().all())
@classmethod
def reset(cls, db: Session):
"""在调用方持有的同步事务中暂存清空操作。"""
db.execute(delete(cls))
@classmethod
async def async_reset(cls, db: AsyncSession):
"""在调用方持有的异步事务中暂存清空操作。"""
await db.execute(delete(cls))