diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml new file mode 100644 index 00000000..7d62c7cf --- /dev/null +++ b/.github/workflows/beta.yml @@ -0,0 +1,59 @@ +name: MoviePilot Builder Beta +on: + workflow_dispatch: + +jobs: + Docker-build: + runs-on: ubuntu-latest + name: Build Docker Image + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Release version + id: release_version + run: | + app_version=$(cat version.py |sed -ne "s/APP_VERSION\s=\s'v\(.*\)'/\1/gp") + echo "app_version=$app_version" >> $GITHUB_ENV + + - name: Docker Meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ secrets.DOCKER_USERNAME }}/moviepilot-v2 + ghcr.io/${{ github.repository }} + tags: | + type=raw,value=beta + + - name: Set Up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set Up Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Login GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build Image + uses: docker/build-push-action@v5 + with: + context: . + file: docker/Dockerfile + platforms: | + linux/amd64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha, scope=${{ github.workflow }}-docker + cache-to: type=gha, scope=${{ github.workflow }}-docker diff --git a/app/core/config.py b/app/core/config.py index b3e28a41..c18b39c0 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -56,6 +56,7 @@ class ConfigModel(BaseModel): class Config: extra = "ignore" # 忽略未定义的配置项 + # ==================== 基础应用配置 ==================== # 项目名称 PROJECT_NAME: str = "MoviePilot" # 域名 格式;https://movie-pilot.org @@ -64,16 +65,6 @@ class ConfigModel(BaseModel): API_V1_STR: str = "/api/v1" # 前端资源路径 FRONTEND_PATH: str = "/public" - # 密钥 - SECRET_KEY: str = secrets.token_urlsafe(32) - # RESOURCE密钥 - RESOURCE_SECRET_KEY: str = secrets.token_urlsafe(32) - # 允许的域名 - ALLOWED_HOSTS: list = Field(default_factory=lambda: ["*"]) - # TOKEN过期时间 - ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8 - # RESOURCE_TOKEN过期时间 - RESOURCE_ACCESS_TOKEN_EXPIRE_SECONDS: int = 60 * 30 # 时区 TZ: str = "Asia/Shanghai" # API监听地址 @@ -84,12 +75,32 @@ class ConfigModel(BaseModel): NGINX_PORT: int = 3000 # 配置文件目录 CONFIG_DIR: Optional[str] = None - # 超级管理员 - SUPERUSER: str = "admin" # 是否调试模式 DEBUG: bool = False # 是否开发模式 DEV: bool = False + + # ==================== 安全认证配置 ==================== + # 密钥 + SECRET_KEY: str = secrets.token_urlsafe(32) + # RESOURCE密钥 + RESOURCE_SECRET_KEY: str = secrets.token_urlsafe(32) + # 允许的域名 + ALLOWED_HOSTS: list = Field(default_factory=lambda: ["*"]) + # TOKEN过期时间 + ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8 + # RESOURCE_TOKEN过期时间 + RESOURCE_ACCESS_TOKEN_EXPIRE_SECONDS: int = 60 * 30 + # 超级管理员 + SUPERUSER: str = "admin" + # 辅助认证,允许通过外部服务进行认证、单点登录以及自动创建用户 + AUXILIARY_AUTH_ENABLE: bool = False + # API密钥,需要更换 + API_TOKEN: Optional[str] = None + # 用户认证站点 + AUTH_SITE: str = "" + + # ==================== 数据库配置 ==================== # 数据库类型,支持 sqlite 和 postgresql,默认使用 sqlite DB_TYPE: str = "sqlite" # 是否在控制台输出 SQL 语句,默认关闭 @@ -120,63 +131,18 @@ class ConfigModel(BaseModel): DB_POSTGRESQL_POOL_SIZE: int = 20 # PostgreSQL 连接池溢出数量 DB_POSTGRESQL_MAX_OVERFLOW: int = 30 + + # ==================== 缓存配置 ==================== # 缓存类型,支持 cachetools 和 redis,默认使用 cachetools CACHE_BACKEND_TYPE: str = "cachetools" # 缓存连接字符串,仅外部缓存(如 Redis、Memcached)需要 CACHE_BACKEND_URL: Optional[str] = None # Redis 缓存最大内存限制,未配置时,如开启大内存模式时为 "1024mb",未开启时为 "256mb" CACHE_REDIS_MAXMEMORY: Optional[str] = None - # 辅助认证,允许通过外部服务进行认证、单点登录以及自动创建用户 - AUXILIARY_AUTH_ENABLE: bool = False - # API密钥,需要更换 - API_TOKEN: Optional[str] = None + + # ==================== 网络代理配置 ==================== # 网络代理服务器地址 PROXY_HOST: Optional[str] = None - # 登录页面电影海报,tmdb/bing/mediaserver - WALLPAPER: str = "tmdb" - # 自定义壁纸api地址 - CUSTOMIZE_WALLPAPER_API_URL: Optional[str] = None - # 媒体搜索来源 themoviedb/douban/bangumi,多个用,分隔 - SEARCH_SOURCE: str = "themoviedb,douban,bangumi" - # 媒体识别来源 themoviedb/douban - RECOGNIZE_SOURCE: str = "themoviedb" - # 元数据识别缓存过期时间(小时) - META_CACHE_EXPIRE: int = 0 - # 电视剧动漫的分类genre_ids - ANIME_GENREIDS: List[int] = Field(default=[16]) - # 刮削来源 themoviedb/douban - SCRAP_SOURCE: str = "themoviedb" - # 新增已入库媒体是否跟随TMDB信息变化 - SCRAP_FOLLOW_TMDB: bool = True - # TMDB图片地址 - TMDB_IMAGE_DOMAIN: str = "image.tmdb.org" - # TMDB API地址 - TMDB_API_DOMAIN: str = "api.themoviedb.org" - # TMDB元数据语言 - TMDB_LOCALE: str = "zh" - # 刮削使用TMDB原始语种图片 - TMDB_SCRAP_ORIGINAL_IMAGE: bool = False - # TMDB API Key - TMDB_API_KEY: str = "db55323b8d3e4154498498a75642b381" - # TVDB API Key - TVDB_V4_API_KEY: str = "ed2aa66b-7899-4677-92a7-67bc9ce3d93a" - TVDB_V4_API_PIN: str = "" - # Fanart开关 - FANART_ENABLE: bool = True - # Fanart语言 - FANART_LANG: str = "zh,en" - # Fanart API Key - FANART_API_KEY: str = "d2d31f9ecabea050fc7d68aa3146015f" - # 115 AppId - U115_APP_ID: str = "100196807" - # Alipan AppId - ALIPAN_APP_ID: str = "ac1bf04dc9fd4d9aaabb65b4a668d403" - # 用户认证站点 - AUTH_SITE: str = "" - # 重启自动升级 - MOVIEPILOT_AUTO_UPDATE: str = 'release' - # 自动检查和更新站点资源包(站点索引、认证等) - AUTO_UPDATE_RESOURCE: bool = True # 是否启用DOH解析域名 DOH_ENABLE: bool = False # 使用 DOH 解析的域名列表 @@ -190,6 +156,65 @@ class ConfigModel(BaseModel): "api.telegram.org") # DOH 解析服务器列表 DOH_RESOLVERS: str = "1.0.0.1,1.1.1.1,9.9.9.9,149.112.112.112" + + # ==================== 媒体元数据配置 ==================== + # 媒体搜索来源 themoviedb/douban/bangumi,多个用,分隔 + SEARCH_SOURCE: str = "themoviedb,douban,bangumi" + # 媒体识别来源 themoviedb/douban + RECOGNIZE_SOURCE: str = "themoviedb" + # 元数据识别缓存过期时间(小时) + META_CACHE_EXPIRE: int = 0 + # 电视剧动漫的分类genre_ids + ANIME_GENREIDS: List[int] = Field(default=[16]) + # 刮削来源 themoviedb/douban + SCRAP_SOURCE: str = "themoviedb" + # 新增已入库媒体是否跟随TMDB信息变化 + SCRAP_FOLLOW_TMDB: bool = True + # 检查本地媒体库是否存在资源开关 + LOCAL_EXISTS_SEARCH: bool = False + # 搜索多个名称 + SEARCH_MULTIPLE_NAME: bool = False + # 最大搜索名称数量 + MAX_SEARCH_NAME_LIMIT: int = 2 + + # ==================== TMDB配置 ==================== + # TMDB图片地址 + TMDB_IMAGE_DOMAIN: str = "image.tmdb.org" + # TMDB API地址 + TMDB_API_DOMAIN: str = "api.themoviedb.org" + # TMDB元数据语言 + TMDB_LOCALE: str = "zh" + # 刮削使用TMDB原始语种图片 + TMDB_SCRAP_ORIGINAL_IMAGE: bool = False + # TMDB API Key + TMDB_API_KEY: str = "db55323b8d3e4154498498a75642b381" + + # ==================== TVDB配置 ==================== + # TVDB API Key + TVDB_V4_API_KEY: str = "ed2aa66b-7899-4677-92a7-67bc9ce3d93a" + TVDB_V4_API_PIN: str = "" + + # ==================== Fanart配置 ==================== + # Fanart开关 + FANART_ENABLE: bool = True + # Fanart语言 + FANART_LANG: str = "zh,en" + # Fanart API Key + FANART_API_KEY: str = "d2d31f9ecabea050fc7d68aa3146015f" + + # ==================== 云盘配置 ==================== + # 115 AppId + U115_APP_ID: str = "100196807" + # Alipan AppId + ALIPAN_APP_ID: str = "ac1bf04dc9fd4d9aaabb65b4a668d403" + + # ==================== 系统升级配置 ==================== + # 重启自动升级 + MOVIEPILOT_AUTO_UPDATE: str = 'release' + # 自动检查和更新站点资源包(站点索引、认证等) + AUTO_UPDATE_RESOURCE: bool = True + + # ==================== 媒体文件格式配置 ==================== # 支持的后缀格式 RMT_MEDIAEXT: list = Field( default_factory=lambda: ['.mp4', '.mkv', '.ts', '.iso', @@ -214,8 +239,12 @@ class ConfigModel(BaseModel): ) # 下载器临时文件后缀 DOWNLOAD_TMPEXT: list = Field(default_factory=lambda: ['.!qb', '.part']) + + # ==================== 媒体服务器配置 ==================== # 媒体服务器同步间隔(小时) MEDIASERVER_SYNC_INTERVAL: int = 6 + + # ==================== 订阅配置 ==================== # 订阅模式 SUBSCRIBE_MODE: str = "spider" # RSS订阅模式刷新时间间隔(分钟) @@ -224,24 +253,24 @@ class ConfigModel(BaseModel): SUBSCRIBE_STATISTIC_SHARE: bool = True # 订阅搜索开关 SUBSCRIBE_SEARCH: bool = False - # 检查本地媒体库是否存在资源开关 - LOCAL_EXISTS_SEARCH: bool = False - # 搜索多个名称 - SEARCH_MULTIPLE_NAME: bool = False - # 最大搜索名称数量 - MAX_SEARCH_NAME_LIMIT: int = 2 + + # ==================== 站点配置 ==================== # 站点数据刷新间隔(小时) SITEDATA_REFRESH_INTERVAL: int = 6 # 读取和发送站点消息 SITE_MESSAGE: bool = True # 不能缓存站点资源的站点域名,多个使用,分隔 NO_CACHE_SITE_KEY: str = "m-team" + + # ==================== 下载配置 ==================== # 种子标签 TORRENT_TAG: str = "MOVIEPILOT" # 下载站点字幕 DOWNLOAD_SUBTITLE: bool = True # 交互搜索自动下载用户ID,使用,分割 AUTO_DOWNLOAD_USER: Optional[str] = None + + # ==================== CookieCloud配置 ==================== # CookieCloud是否启动本地服务 COOKIECLOUD_ENABLE_LOCAL: Optional[bool] = False # CookieCloud服务器地址 @@ -254,6 +283,8 @@ class ConfigModel(BaseModel): COOKIECLOUD_INTERVAL: Optional[int] = 60 * 24 # CookieCloud同步黑名单,多个域名,分割 COOKIECLOUD_BLACKLIST: Optional[str] = None + + # ==================== 重命名配置 ==================== # 电影重命名格式 MOVIE_RENAME_FORMAT: str = "{{title}}{% if year %} ({{year}}){% endif %}" \ "/{{title}}{% if year %} ({{year}}){% endif %}{% if part %}-{{part}}{% endif %}{% if videoFormat %} - {{videoFormat}}{% endif %}" \ @@ -263,10 +294,22 @@ class ConfigModel(BaseModel): "/Season {{season}}" \ "/{{title}} - {{season_episode}}{% if part %}-{{part}}{% endif %}{% if episode %} - 第 {{episode}} 集{% endif %}" \ "{{fileExt}}" + # 重命名时支持的S0别名 + RENAME_FORMAT_S0_NAMES: list = Field(default=["Specials", "SPs"]) + # 为指定默认字幕添加.default后缀 + DEFAULT_SUB: Optional[str] = "zh-cn" + + # ==================== 服务地址配置 ==================== # OCR服务器地址 OCR_HOST: str = "https://movie-pilot.org" # 服务器地址,对应 https://github.com/jxxghp/MoviePilot-Server 项目 MP_SERVER_HOST: str = "https://movie-pilot.org" + # 登录页面电影海报,tmdb/bing/mediaserver + WALLPAPER: str = "tmdb" + # 自定义壁纸api地址 + CUSTOMIZE_WALLPAPER_API_URL: Optional[str] = None + + # ==================== 插件配置 ==================== # 插件市场仓库地址,多个地址使用,分隔,地址以/结尾 PLUGIN_MARKET: str = ("https://github.com/jxxghp/MoviePilot-Plugins," "https://github.com/thsrite/MoviePilot-Plugins," @@ -287,6 +330,8 @@ class ConfigModel(BaseModel): PLUGIN_STATISTIC_SHARE: bool = True # 是否开启插件热加载 PLUGIN_AUTO_RELOAD: bool = False + + # ==================== GitHub配置 ==================== # Github token,提高请求api限流阈值 ghp_**** GITHUB_TOKEN: Optional[str] = None # Github代理服务器,格式:https://mirror.ghproxy.com/ @@ -295,6 +340,8 @@ class ConfigModel(BaseModel): PIP_PROXY: Optional[str] = '' # 指定的仓库Github token,多个仓库使用,分隔,格式:{user1}/{repo1}:ghp_****,{user2}/{repo2}:github_pat_**** REPO_GITHUB_TOKEN: Optional[str] = None + + # ==================== 性能配置 ==================== # 大内存模式 BIG_MEMORY_MODE: bool = False # FastApi性能监控 @@ -305,6 +352,8 @@ class ConfigModel(BaseModel): ENCODING_DETECTION_PERFORMANCE_MODE: bool = True # 编码探测的最低置信度阈值 ENCODING_DETECTION_MIN_CONFIDENCE: float = 0.8 + + # ==================== 安全配置 ==================== # 允许的图片缓存域名 SECURITY_IMAGE_DOMAINS: list = Field(default=[ "image.tmdb.org", @@ -324,23 +373,27 @@ class ConfigModel(BaseModel): ]) # 允许的图片文件后缀格式 SECURITY_IMAGE_SUFFIXES: list = Field(default=[".jpg", ".jpeg", ".png", ".webp", ".gif", ".svg", ".avif"]) - # 重命名时支持的S0别名 - RENAME_FORMAT_S0_NAMES: list = Field(default=["Specials", "SPs"]) - # 为指定默认字幕添加.default后缀 - DEFAULT_SUB: Optional[str] = "zh-cn" - # Docker Client API地址 - DOCKER_CLIENT_API: Optional[str] = "tcp://127.0.0.1:38379" + + # ==================== 工作流配置 ==================== # 工作流数据共享 WORKFLOW_STATISTIC_SHARE: bool = True + + # ==================== 存储配置 ==================== # 对rclone进行快照对比时,是否检查文件夹的修改时间 RCLONE_SNAPSHOT_CHECK_FOLDER_MODTIME = True # 对OpenList进行快照对比时,是否检查文件夹的修改时间 OPENLIST_SNAPSHOT_CHECK_FOLDER_MODTIME = True + + # ==================== 浏览器仿真配置 ==================== # 仿真类型:playwright 或 flaresolverr BROWSER_EMULATION: str = "playwright" # FlareSolverr 服务地址,例如 http://127.0.0.1:8191 FLARESOLVERR_URL: Optional[str] = None + # ==================== Docker配置 ==================== + # Docker Client API地址 + DOCKER_CLIENT_API: Optional[str] = "tcp://127.0.0.1:38379" + class Settings(BaseSettings, ConfigModel, LogConfigModel): """