diff --git a/Dockerfile b/Dockerfile index af30fe63..7aaa433b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,7 +34,6 @@ RUN apt-get update -y \ rsync \ ffmpeg \ nano \ - proxychains4 \ && \ if [ "$(uname -m)" = "x86_64" ]; \ then ln -s /usr/lib/x86_64-linux-musl/libc.so /lib/libc.musl-x86_64.so.1; \ diff --git a/app/core/config.py b/app/core/config.py index c2d8f41c..aa2233e3 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -150,8 +150,6 @@ class Settings(BaseSettings): GITHUB_PROXY: Optional[str] = '' # pip镜像站点,格式:https://pypi.tuna.tsinghua.edu.cn/simple PIP_PROXY: Optional[str] = '' - # 代理补全开关,支持 True、False, 在没有配置镜像站的时候,True 使用 PROXY_HOST 补全镜像站缺失,False 在没有配置镜像站的时候,不使用全局补全 - PROXY_SUPPLEMENT: bool = True # 大内存模式 BIG_MEMORY_MODE: bool = False @@ -231,33 +229,22 @@ class Settings(BaseSettings): return None @property - def PROXY_URLPARSE(self, url: str = PROXY_HOST): + def PROXY_URLPARSE(self): """ - 解析地址组成 - 允许其他地址调用 + 解析地址组成 """ - if url: - # 解析 URL - parsed_url = urlparse(url) - # 协议 - protocol = parsed_url.scheme or "" - # 用户名 - username = parsed_url.username or "" - # 密码 - password = parsed_url.password or "" - # 主机 - host = parsed_url.hostname or "" - # 端口: - port = parsed_url.port or "" - # 路径 - path = parsed_url.path or "" - # 用户名:密码@主机:端口 - netloc = parsed_url.netloc or "" - # 查询参数: ?key=value - query = parsed_url.query or "" - # 使用;分割的参数 - params = parsed_url.params or "" - # 片段: #fragment - fragment = parsed_url.fragment or "" + if self.PROXY_HOST: + parsed_url = urlparse(self.PROXY_HOST) + protocol = parsed_url.scheme or "" # 协议 + username = parsed_url.username or "" # 用户名 + password = parsed_url.password or "" # 密码 + host = parsed_url.hostname or "" # 主机 + port = parsed_url.port or "" # 端口 + path = parsed_url.path or "" # 路径 + netloc = parsed_url.netloc or "" # 用户名:密码@主机:端口 + query = parsed_url.query or "" # 查询参数: ?key=value + params = parsed_url.params or "" # 使用;分割的参数 + fragment = parsed_url.fragment or "" # 片段: #fragment if not port: if protocol == "https": @@ -267,7 +254,6 @@ class Settings(BaseSettings): elif protocol in {"socks5", "socks5h", "socks4", "socks4a"}: port = 1080 - # 返回解析结果 return { "protocol": protocol, "username": username, @@ -300,6 +286,28 @@ class Settings(BaseSettings): } return {} + @property + def PIP_OPTIONS(self): + """ + pip调用附加参数 + """ + protocol = host = port = "" + parsed_url = self.PROXY_URLPARSE + if parsed_url: + protocol = parsed_url.get("scheme", "").lower() + host = parsed_url.get("host", "").lower() + port = parsed_url.get("port", "") + # 优先级:镜像站 > 全局 > 不代理 + if settings.PIP_PROXY: + PIP_OPTIONS = f" -i {settings.PIP_PROXY} " + # 全局代理地址 + elif protocol in {"http", "https", "socks4", "socks4a", "socks5", "socks5h"} and host and port: + PIP_OPTIONS = f" --proxy={settings.PROXY_HOST} " + # 不使用代理 + else: + PIP_OPTIONS = "" + return PIP_OPTIONS + @property def VAPID(self): return { diff --git a/app/helper/plugin.py b/app/helper/plugin.py index 09c5a148..523ac1fe 100644 --- a/app/helper/plugin.py +++ b/app/helper/plugin.py @@ -222,52 +222,7 @@ class PluginHelper(metaclass=Singleton): # 插件目录下如有requirements.txt则安装依赖 requirements_file = plugin_dir / "requirements.txt" if requirements_file.exists(): - # 初始化 - protocol = host = port = username = password = PROXY_CHAINS = PIP_PROXY = "" - # 返回json格式解析结果 - parsed_url = settings.PROXY_URLPARSE() - if parsed_url: - protocol = parsed_url.get("scheme", "").lower() - username = parsed_url.get("username", "") - password = parsed_url.get("password", "") - host = parsed_url.get("host", "").lower() - port = parsed_url.get("port", "") - - # 全局优先,镜像站不存在时,使用全局代理 - if settings.PROXY_SUPPLEMENT: - - # 检查settings.PROXY_HOST的协议类型,http或https - if protocol in {"http", "https"}: - if settings.PIP_PROXY: - PIP_PROXY = f" -i {settings.PIP_PROXY} " if settings.PIP_PROXY else "" - else: - # 有主机名与端口号的时候 - if host and port: - PIP_PROXY = f" --proxy={settings.PROXY_HOST} " if settings.PROXY_HOST else "" - - # Todo:目前proxychains4的临时调用命令不支持socks5h和socks4a,需要生成临时配置文件才能解决,后面考虑支持一下 - elif protocol in {"socks4", "socks4a", "socks5", "socks5h"}: - # 没有主机名,端口号 - if not host or not port: - PIP_PROXY = f" -i {settings.PIP_PROXY} " if settings.PIP_PROXY else "" - # 将拓展的socks协议转换为proxychains4支持的socks4和socks5 - else: - if protocol in {"socks5", "socks5h"}: - protocol = "socks5" - elif protocol in {"socks4", "socks4a"}: - protocol = "socks4" - # 生成配置 - PROXY_CHAINS = f"proxychains4 -f <( echo -e '[ProxyList]\n{protocol} {host} {port} {username} {password}')" - - # 不支持的协议类型 - else: - PIP_PROXY = f" -i {settings.PIP_PROXY} " if settings.PIP_PROXY else "" - - # 本地优先,镜像站不存在时,不使用全局代理 - else: - PIP_PROXY = f" -i {settings.PIP_PROXY} " if settings.PIP_PROXY else "" - - SystemUtils.execute(f"{PROXY_CHAINS} pip install -r {requirements_file} {PIP_PROXY} > /dev/null 2>&1") + SystemUtils.execute(f"pip install -r {requirements_file} {settings.PIP_OPTIONS} > /dev/null 2>&1") # 安装成功后统计 self.install_reg(pid) diff --git a/config/app.env b/config/app.env index 6eb35bab..956d17b8 100644 --- a/config/app.env +++ b/config/app.env @@ -17,8 +17,6 @@ DOH_ENABLE=true META_CACHE_EXPIRE=0 # 自动检查和更新站点资源包(索引、认证等) AUTO_UPDATE_RESOURCE=true -# 代理补全开关,支持 True、False, 在没有配置镜像站的时候,True 使用 PROXY_HOST 补全镜像站缺失,False 在没有配置镜像站的时候,不使用全局补全 -PROXY_INTERNET_PRIORITY=true # 【*】API密钥,建议更换复杂字符串,有Jellyseerr/Overseerr、媒体服务器Webhook等配置以及部分支持API_TOKEN的API中使用 API_TOKEN=moviepilot # 登录页面电影海报,tmdb/bing,tmdb要求能正常连接api.themoviedb.org diff --git a/update b/update index c9b897fb..d9d553b4 100644 --- a/update +++ b/update @@ -41,8 +41,8 @@ function install_backend_and_download_resources() { if download_and_unzip "${GITHUB_PROXY}https://github.com/jxxghp/MoviePilot/archive/refs/${1}" "App"; then INFO "后端程序下载成功" INFO "依赖安装中..." - ${PROXY_CHAINS} pip install ${PIP_OPTIONS} --upgrade --root-user-action pip > /dev/null - if ${PROXY_CHAINS} pip install ${PIP_OPTIONS} --root-user-action -r /tmp/App/requirements.txt > /dev/null; then + pip install ${PIP_OPTIONS} --upgrade --root-user-action pip > /dev/null + if pip install ${PIP_OPTIONS} --root-user-action -r /tmp/App/requirements.txt > /dev/null; then INFO "安装依赖成功" frontend_version=$(curl ${CURL_OPTIONS} "https://api.github.com/repos/jxxghp/MoviePilot-Frontend/releases/latest" ${CURL_HEADERS} | jq -r .tag_name) if [[ "${frontend_version}" == *v* ]]; then @@ -80,7 +80,7 @@ function install_backend_and_download_resources() { # 插件仓库 rsync -av --remove-source-files /tmp/Plugins/plugins/* /app/app/plugins/ > /dev/null # 提前安装插件依赖 - find /app/app/plugins -name requirements.txt -exec ${PROXY_CHAINS} pip install --root-user-action ${PIP_OPTIONS} -r {} \; > /dev/null + find /app/app/plugins -name requirements.txt -exec pip install --root-user-action ${PIP_OPTIONS} -r {} \; > /dev/null # 清理临时目录 rm -rf /tmp/* INFO "插件更新成功" @@ -122,124 +122,50 @@ function parse_url() { result=$(./parse_url.py ${1}) # 解析结果并提取各项 PROTOCOL=$(echo "$result" | grep "^SCHEME:" | awk '{print $2}') - USERNAME=$(echo "$result" | grep "^USERNAME:" | awk '{print $2}') - PASSWORD=$(echo "$result" | grep "^PASSWORD:" | awk '{print $2}') HOST=$(echo "$result" | grep "^HOST:" | awk '{print $2}') PORT=$(echo "$result" | grep "^PORT:" | awk '{print $2}') } if [[ "${MOVIEPILOT_AUTO_UPDATE}" = "true" ]] || [[ "${MOVIEPILOT_AUTO_UPDATE}" = "release" ]] || [[ "${MOVIEPILOT_AUTO_UPDATE}" = "dev" ]]; then - # 默认不使用proxychains代理PIP - PROXY_CHAINS="" # 解析代理地址,判断代理合法性 if [[ -n "${PROXY_HOST}" ]]; then parse_url "${PROXY_HOST}" INFO "检测到代理地址,开始解析..." - if [[ "${PROTOCOL}" =~ ^http ]]; then + if [[ "${PROTOCOL}" =~ ^(http|https|socks4|socks4a|socks5|socks5h)$ ]] && [[ -n "${HOST}" && -n "${PORT}" ]]; then PROXY_HOST_MODE="true" - SOCKS_MODE="false" - elif [[ "${PROTOCOL}" =~ ^socks ]]; then - PROXY_HOST_MODE="true" - SOCKS_MODE="true" else PROXY_HOST_MODE="false" - SOCKS_MODE="false" - WARN "【PROXY_HOST】代理地址错误,无法添加全局代理环境,开始使用其他更新方式" + WARN "【PROXY_HOST】代理地址不符合要求,无法使用全局代理环境,开始使用其他更新方式" fi fi - - # 模式1:镜像站点代理 - if [[ -n "${PIP_PROXY}" ]] || [[ -n "${GITHUB_PROXY}" ]]; then - # 通用代理参数 - GITHUB_PROXY=${GITHUB_PROXY:-""} - # 模式1-1:全局代理补充本地网络代理,并修改pip支持socks代理 - if [[ "${PROXY_SUPPLEMENT}" = "true" ]] && [[ "${PROXY_HOST_MODE}" = "true" ]]; then - CURL_OPTIONS="-sL -x ${PROXY_HOST}" - # 针对socks模式下,启用proxychains - if [[ "${SOCKS_MODE}" == "true" ]]; then - PROXY_CHAINS="proxychains4 -f <( echo -e '[ProxyList]\n${PROTOCOL} ${HOST} ${PORT} ${USERNAME} ${PASSWORD}')" - PIP_OPTIONS=${PIP_PROXY:+-i ${PIP_PROXY}} - # http/https代理,不需要启用proxychains - else - PROXY_CHAINS="" - # http/https代理下,优先使用-i镜像站 - if [[ -n "${PIP_PROXY}" ]]; then - PIP_OPTIONS="-i ${PIP_PROXY}" - else - PIP_OPTIONS="--proxy=${PROXY_HOST}" - fi - fi - # 双镜像站,去除proxychains - if [[ -n "${PIP_OPTIONS}" && -n "${GITHUB_PROXY}" ]]; then - PROXY_CHAINS="" - INFO "使用Pip镜像代理更新环境依赖,使用Github镜像代理更新程序" - # 单Github镜像站,保留proxychains - elif [[ -z "${PIP_OPTIONS}" && -n "${GITHUB_PROXY}" ]];then - # 全局为socks代理时,优先使用-i镜像站,去除proxychains - if [[ -n "${PIP_OPTIONS}" ]]; then - PROXY_CHAINS="" - fi - INFO "使用全局代理更新环境依赖,使用Github镜像代理更新程序" - # 单Pip镜像站,去除proxychains - elif [[ -n "${PIP_OPTIONS}" && -z "${GITHUB_PROXY}" ]];then - PROXY_CHAINS="" - INFO "使用Pip镜像代理更新环境依赖,使用全局代理更新程序" - # 没有镜像站,一般情况下不会出现,过不了第一层判断 - else - INFO "使用全局代理更新程序与环境依赖" - fi - - # 模式1-2:本地网络优先,不使用全局代理补全 - elif [[ "${PROXY_SUPPLEMENT}" = "false" ]]; then - CURL_OPTIONS="-sL" - PIP_OPTIONS=${PIP_PROXY:+-i ${PIP_PROXY}} - PROXY_CHAINS="" - # 双镜像站 - if [[ -n "${PIP_PROXY}" && -n "${GITHUB_PROXY}" ]]; then - INFO "使用Pip镜像代理更新环境依赖,使用Github镜像代理更新程序" - # 单Github镜像站 - elif [[ -z "${PIP_OPTIONS}" && -n "${GITHUB_PROXY}" ]]; then - INFO "不使用代理更新环境依赖,使用Github镜像代理更新程序" - # 单Pip镜像站 - elif [[ -n "${PIP_OPTIONS}" && -z "${GITHUB_PROXY}" ]]; then - INFO "使用Pip镜像代理更新环境依赖,不使用代理更新程序" - # 没有镜像站,一般情况下不会出现,过不了第一层判断 - else - INFO "不使用任何代理更新程序与环境依赖" - fi - - # 模式1-3:其他情况,一般不会出现 - else - CURL_OPTIONS="-sL" - PIP_OPTIONS="" - GITHUB_PROXY="" - PROXY_CHAINS="" - WARN "出现了未知的情况,不使用任何代理更新程序与环境依赖" - fi - - # 模式3:代理地址正常,则使用全局代理 + # 初始化变量 + PIP_PROXY=${PIP_PROXY:-""} + GITHUB_PROXY=${GITHUB_PROXY:-""} + PIP_OPTIONS="" + CURL_OPTIONS="-sL" + # 优先级:镜像站 > 全局 > 不代理 + # pip + if [[ -n "${PIP_PROXY}" ]]; then + PIP_OPTIONS="-i ${PIP_PROXY}" + PIP_LOG="使用Pip镜像代理更新环境依赖" + elif [[ -n "${PROXY_HOST}" && "${PROXY_HOST_MODE}" = "true" ]]; then + PIP_OPTIONS="--proxy=${PROXY_HOST}" + PIP_LOG="使用全局代理更新环境依赖" + else + PIP_OPTIONS="" + PIP_LOG="不使用代理更新环境依赖" + fi + # GitHub + if [[ -n "${GITHUB_PROXY}" ]]; then + GITHUB_LOG="使用Github镜像代理更新程序" elif [[ -n "${PROXY_HOST}" && "${PROXY_HOST_MODE}" = "true" ]]; then CURL_OPTIONS="-sL -x ${PROXY_HOST}" - # 针对socks模式下,启用proxychains4 - if [[ "${SOCKS_MODE}" == "true" ]]; then - PIP_OPTIONS="" - PROXY_CHAINS="proxychains4 -f <( echo -e '[ProxyList]\n${PROTOCOL} ${HOST} ${PORT} ${USERNAME} ${PASSWORD}')" - else - PROXY_CHAINS="" - PIP_OPTIONS="--proxy=${PROXY_HOST}" - fi - GITHUB_PROXY="" - PROXY_CHAINS="" - INFO "使用全局代理更新程序与环境依赖" - - # 模式4:其他情况,统一不使用代理 + GITHUB_LOG="使用全局代理更新程序" else CURL_OPTIONS="-sL" - PIP_OPTIONS="" - GITHUB_PROXY="" - PROXY_CHAINS="" - INFO "不使用任何代理更新程序与环境依赖" + GITHUB_LOG="不使用代理更新程序" fi + INFO "${PIP_LOG},${GITHUB_LOG}" if [ -n "${GITHUB_TOKEN}" ]; then CURL_HEADERS="--oauth2-bearer ${GITHUB_TOKEN}" else diff --git a/urlparse.py b/urlparse.py index 7b982b01..2bf277da 100644 --- a/urlparse.py +++ b/urlparse.py @@ -7,8 +7,6 @@ def parse_url(url): # 提取各个部分 protocol = parsed_url.scheme or "" - username = parsed_url.username or "" - password = parsed_url.password or "" hostname = parsed_url.hostname or "" port = parsed_url.port or "" @@ -23,18 +21,11 @@ def parse_url(url): elif protocol in {"socks5", "socks5h", "socks4", "socks4a"}: port = 1080 - # socks协议转换,适配proxychains4的临时命令不支持的socks4a与socks5h if protocol: protocol = protocol.lower() - if protocol in {"socks5", "socks5h"}: - protocol = "socks5" - elif protocol in {"socks4", "socks4a"}: - protocol = "socks4" # 打印提取的部分 print(f"SCHEME:{protocol}") - print(f"USERNAME:{username}") - print(f"PASSWORD:{password}") print(f"HOST:{hostname}") print(f"PORT:{port}") @@ -43,8 +34,6 @@ if __name__ == "__main__": # 参数不全,直接返回空解析结果 if len(sys.argv) != 2: print(f"SCHEME:''") - print(f"USERNAME:''") - print(f"PASSWORD:''") print(f"HOST:''") print(f"PORT:''") # 参数全,解析URL