feat 资源包自动更新
This commit is contained in:
@ -70,7 +70,8 @@ MoviePilot需要配套下载器和媒体服务器配合使用。
|
|||||||
- **PGID**:运行程序用户的`gid`,默认`0`(仅支持环境变量配置)
|
- **PGID**:运行程序用户的`gid`,默认`0`(仅支持环境变量配置)
|
||||||
- **UMASK**:掩码权限,默认`000`,可以考虑设置为`022`(仅支持环境变量配置)
|
- **UMASK**:掩码权限,默认`000`,可以考虑设置为`022`(仅支持环境变量配置)
|
||||||
- **PROXY_HOST:** 网络代理,访问themoviedb或者重启更新需要使用代理访问,格式为`http(s)://ip:port`、`socks5://user:pass@host:port`(仅支持环境变量配置)
|
- **PROXY_HOST:** 网络代理,访问themoviedb或者重启更新需要使用代理访问,格式为`http(s)://ip:port`、`socks5://user:pass@host:port`(仅支持环境变量配置)
|
||||||
- **MOVIEPILOT_AUTO_UPDATE**:重启更新,`true`/`release`/`dev`/`false`,默认`release` **注意:如果出现网络问题可以配置`PROXY_HOST`**(仅支持环境变量配置)
|
- **MOVIEPILOT_AUTO_UPDATE:** 重启时自动更新,`true`/`release`/`dev`/`false`,默认`release`,需要能正常连接Github **注意:如果出现网络问题可以配置`PROXY_HOST`**(仅支持环境变量配置)
|
||||||
|
- **AUTO_UPDATE_RESOURCE**:启动时自动检测和更新资源包(站点索引及认证等),`true`/`false`,默认`true`,需要能正常连接Github,仅支持Docker
|
||||||
---
|
---
|
||||||
- **❗SUPERUSER:** 超级管理员用户名,默认`admin`,安装后使用该用户登录后台管理界面
|
- **❗SUPERUSER:** 超级管理员用户名,默认`admin`,安装后使用该用户登录后台管理界面
|
||||||
- **❗SUPERUSER_PASSWORD:** 超级管理员初始密码,默认`password`,建议修改为复杂密码
|
- **❗SUPERUSER_PASSWORD:** 超级管理员初始密码,默认`password`,建议修改为复杂密码
|
||||||
|
@ -214,6 +214,8 @@ class Settings(BaseSettings):
|
|||||||
PLUGIN_MARKET: str = "https://raw.githubusercontent.com/jxxghp/MoviePilot-Plugins/main/"
|
PLUGIN_MARKET: str = "https://raw.githubusercontent.com/jxxghp/MoviePilot-Plugins/main/"
|
||||||
# Github token,提高请求api限流阈值 ghp_****
|
# Github token,提高请求api限流阈值 ghp_****
|
||||||
GITHUB_TOKEN: str = None
|
GITHUB_TOKEN: str = None
|
||||||
|
# 自动检查和更新站点资源包(站点索引、认证等)
|
||||||
|
AUTO_UPDATE_RESOURCE: bool = True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def INNER_CONFIG_PATH(self):
|
def INNER_CONFIG_PATH(self):
|
||||||
|
@ -24,7 +24,8 @@ class PluginHelper(metaclass=Singleton):
|
|||||||
"""
|
"""
|
||||||
if not repo_url:
|
if not repo_url:
|
||||||
return {}
|
return {}
|
||||||
res = RequestUtils(proxies=settings.PROXY, timeout=10).get_res(f"{repo_url}package.json")
|
res = RequestUtils(proxies=settings.PROXY, headers=settings.GITHUB_HEADERS,
|
||||||
|
timeout=10).get_res(f"{repo_url}package.json")
|
||||||
if res:
|
if res:
|
||||||
return json.loads(res.text)
|
return json.loads(res.text)
|
||||||
return {}
|
return {}
|
||||||
@ -49,7 +50,7 @@ class PluginHelper(metaclass=Singleton):
|
|||||||
获取插件的文件列表
|
获取插件的文件列表
|
||||||
"""
|
"""
|
||||||
file_api = f"https://api.github.com/repos/{user}/{repo}/contents/plugins/{_p.lower()}"
|
file_api = f"https://api.github.com/repos/{user}/{repo}/contents/plugins/{_p.lower()}"
|
||||||
r = RequestUtils(proxies=settings.PROXY, headers=settings.GITHUB_HEADERS).get_res(file_api)
|
r = RequestUtils(proxies=settings.PROXY, headers=settings.GITHUB_HEADERS, timeout=10).get_res(file_api)
|
||||||
if not r or r.status_code != 200:
|
if not r or r.status_code != 200:
|
||||||
return None, f"连接仓库失败:{r.status_code} - {r.reason}"
|
return None, f"连接仓库失败:{r.status_code} - {r.reason}"
|
||||||
ret = r.json()
|
ret = r.json()
|
||||||
@ -66,7 +67,8 @@ class PluginHelper(metaclass=Singleton):
|
|||||||
for item in _l:
|
for item in _l:
|
||||||
if item.get("download_url"):
|
if item.get("download_url"):
|
||||||
# 下载插件文件
|
# 下载插件文件
|
||||||
res = RequestUtils(proxies=settings.PROXY).get_res(item["download_url"])
|
res = RequestUtils(proxies=settings.PROXY,
|
||||||
|
headers=settings.GITHUB_HEADERS, timeout=30).get_res(item["download_url"])
|
||||||
if not res:
|
if not res:
|
||||||
return False, f"文件 {item.get('name')} 下载失败!"
|
return False, f"文件 {item.get('name')} 下载失败!"
|
||||||
elif res.status_code != 200:
|
elif res.status_code != 200:
|
||||||
|
101
app/helper/resource.py
Normal file
101
app/helper/resource.py
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from app.core.config import settings
|
||||||
|
from app.helper.sites import SitesHelper
|
||||||
|
from app.log import logger
|
||||||
|
from app.utils.http import RequestUtils
|
||||||
|
from app.utils.singleton import Singleton
|
||||||
|
from app.utils.string import StringUtils
|
||||||
|
from app.utils.system import SystemUtils
|
||||||
|
|
||||||
|
|
||||||
|
class ResourceHelper(metaclass=Singleton):
|
||||||
|
"""
|
||||||
|
检测和更新资源包
|
||||||
|
"""
|
||||||
|
# 资源包的git仓库地址
|
||||||
|
_repo = "https://raw.githubusercontent.com/jxxghp/MoviePilot-Resources/main/package.json"
|
||||||
|
_files_api = f"https://api.github.com/repos/jxxghp/MoviePilot-Resources/contents/resources"
|
||||||
|
_base_dir: Path = settings.ROOT_PATH / "app"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.siteshelper = SitesHelper()
|
||||||
|
self.check()
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
"""
|
||||||
|
检测是否有更新,如有则下载安装
|
||||||
|
"""
|
||||||
|
if not settings.AUTO_UPDATE_RESOURCE:
|
||||||
|
return
|
||||||
|
if SystemUtils.is_frozen():
|
||||||
|
return
|
||||||
|
logger.info("开始检测资源包版本...")
|
||||||
|
res = RequestUtils(proxies=settings.PROXY, headers=settings.GITHUB_HEADERS, timeout=10).get_res(self._repo)
|
||||||
|
if res:
|
||||||
|
resource_info = json.loads(res.text)
|
||||||
|
else:
|
||||||
|
logger.warn("无法连接资源包仓库!")
|
||||||
|
return
|
||||||
|
online_version = resource_info.get("version")
|
||||||
|
if online_version:
|
||||||
|
logger.info(f"最新资源包版本:v{online_version}")
|
||||||
|
# 需要更新的资源包
|
||||||
|
need_updates = {}
|
||||||
|
# 资源明细
|
||||||
|
resources: dict = resource_info.get("resources") or {}
|
||||||
|
for rname, resource in resources.items():
|
||||||
|
rtype = resource.get("type")
|
||||||
|
platform = resource.get("platform")
|
||||||
|
target = resource.get("target")
|
||||||
|
version = resource.get("version")
|
||||||
|
# 判断平台
|
||||||
|
if platform and platform != SystemUtils.platform:
|
||||||
|
continue
|
||||||
|
# 判断本地是否存在
|
||||||
|
local_path = self._base_dir / target
|
||||||
|
if not local_path.exists():
|
||||||
|
continue
|
||||||
|
# 判断版本号
|
||||||
|
if rtype == "auth":
|
||||||
|
# 站点认证资源
|
||||||
|
local_version = self.siteshelper.auth_version
|
||||||
|
elif rtype == "sites":
|
||||||
|
# 站点索引资源
|
||||||
|
local_version = self.siteshelper.indexer_version
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
if StringUtils.compare_version(version, local_version) > 0:
|
||||||
|
logger.info(f"{rname} 资源包有更新,最新版本:v{version}")
|
||||||
|
# 需要安装
|
||||||
|
need_updates[rname] = target
|
||||||
|
if need_updates:
|
||||||
|
# 下载文件信息列表
|
||||||
|
r = RequestUtils(proxies=settings.PROXY, headers=settings.GITHUB_HEADERS,
|
||||||
|
timeout=10).get_res(self._files_api)
|
||||||
|
if not r or r.status_code != 200:
|
||||||
|
return None, f"连接仓库失败:{r.status_code} - {r.reason}"
|
||||||
|
files_info = r.json()
|
||||||
|
for item in files_info:
|
||||||
|
save_path = need_updates.get(item.get("name"))
|
||||||
|
if not save_path:
|
||||||
|
continue
|
||||||
|
if item.get("download_url"):
|
||||||
|
# 下载插件文件
|
||||||
|
res = RequestUtils(proxies=settings.PROXY, headers=settings.GITHUB_HEADERS,
|
||||||
|
timeout=60).get_res(item["download_url"])
|
||||||
|
if not res:
|
||||||
|
logger.error(f"文件 {item.get('name')} 下载失败!")
|
||||||
|
elif res.status_code != 200:
|
||||||
|
logger.error(f"下载文件 {item.get('name')} 失败:{res.status_code} - {res.reason}")
|
||||||
|
# 创建插件文件夹
|
||||||
|
file_path = self._base_dir / save_path
|
||||||
|
if not file_path.parent.exists():
|
||||||
|
file_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
# 写入文件
|
||||||
|
file_path.write_bytes(res.content)
|
||||||
|
logger.info("资源包更新完成,开始重启服务...")
|
||||||
|
SystemUtils.restart()
|
||||||
|
else:
|
||||||
|
logger.info("所有资源已最新,无需更新")
|
@ -22,10 +22,12 @@ from app.core.plugin import PluginManager
|
|||||||
from app.db.init import init_db, update_db
|
from app.db.init import init_db, update_db
|
||||||
from app.helper.thread import ThreadHelper
|
from app.helper.thread import ThreadHelper
|
||||||
from app.helper.display import DisplayHelper
|
from app.helper.display import DisplayHelper
|
||||||
|
from app.helper.resource import ResourceHelper
|
||||||
from app.helper.sites import SitesHelper
|
from app.helper.sites import SitesHelper
|
||||||
from app.scheduler import Scheduler
|
from app.scheduler import Scheduler
|
||||||
from app.command import Command
|
from app.command import Command
|
||||||
|
|
||||||
|
|
||||||
# App
|
# App
|
||||||
App = FastAPI(title=settings.PROJECT_NAME,
|
App = FastAPI(title=settings.PROJECT_NAME,
|
||||||
openapi_url=f"{settings.API_V1_STR}/openapi.json")
|
openapi_url=f"{settings.API_V1_STR}/openapi.json")
|
||||||
@ -169,6 +171,8 @@ def start_module():
|
|||||||
DisplayHelper()
|
DisplayHelper()
|
||||||
# 站点管理
|
# 站点管理
|
||||||
SitesHelper()
|
SitesHelper()
|
||||||
|
# 资源包检测
|
||||||
|
ResourceHelper()
|
||||||
# 加载模块
|
# 加载模块
|
||||||
ModuleManager()
|
ModuleManager()
|
||||||
# 加载插件
|
# 加载插件
|
||||||
|
@ -27,6 +27,8 @@ TMDB_API_DOMAIN=api.themoviedb.org
|
|||||||
RECOGNIZE_SOURCE=themoviedb
|
RECOGNIZE_SOURCE=themoviedb
|
||||||
# 大内存模式,开启后会增加缓存数量,但会占用更多内存
|
# 大内存模式,开启后会增加缓存数量,但会占用更多内存
|
||||||
BIG_MEMORY_MODE=false
|
BIG_MEMORY_MODE=false
|
||||||
|
# 自动检查和更新站点资源包(索引、认证等)
|
||||||
|
AUTO_UPDATE_RESOURCE=true
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
# 媒体识别&刮削 #
|
# 媒体识别&刮削 #
|
||||||
|
Reference in New Issue
Block a user