From c69d317054883ae476da4634286430d5954276a7 Mon Sep 17 00:00:00 2001 From: Aqr-K <95741669+Aqr-K@users.noreply.github.com> Date: Sat, 3 Aug 2024 18:29:06 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0`PROXY=5FSUPPLEMENT`?= =?UTF-8?q?=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1、增加proxychains4模块,用于解决pip在socks5代理时,pip无法使用全局代理的问题 2、增加`PROXY_SUPPLEMENT`变量,可以手动控制,实现使用镜像站进行更新时,但缺少pip镜像站或者GitHub镜像站时,可以使用全局代理补全缺失的代理 --- Dockerfile | 1 + app/core/config.py | 56 ++++++++++++++++++ app/helper/plugin.py | 48 +++++++++++++++- config/app.env | 2 + update | 132 ++++++++++++++++++++++++++++++++++++++----- urlparse.py | 53 +++++++++++++++++ 6 files changed, 275 insertions(+), 17 deletions(-) create mode 100644 urlparse.py diff --git a/Dockerfile b/Dockerfile index 7aaa433b..af30fe63 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,6 +34,7 @@ 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 2f846fd6..c2d8f41c 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -1,4 +1,6 @@ import secrets +from urllib.parse import urlparse + import sys import threading from pathlib import Path @@ -148,6 +150,8 @@ 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 @@ -226,6 +230,58 @@ class Settings(BaseSettings): } return None + @property + def PROXY_URLPARSE(self, url: str = PROXY_HOST): + """ + 解析地址组成 - 允许其他地址调用 + """ + 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 not port: + if protocol == "https": + port = 443 + elif protocol == "http": + port = 80 + elif protocol in {"socks5", "socks5h", "socks4", "socks4a"}: + port = 1080 + + # 返回解析结果 + return { + "protocol": protocol, + "username": username, + "password": password, + "host": host, + "port": port, + "path": path, + "netloc": netloc, + "query": query, + "params": params, + "fragment": fragment + } + return None + @property def PROXY_SERVER(self): if self.PROXY_HOST: diff --git a/app/helper/plugin.py b/app/helper/plugin.py index 0e2700de..09c5a148 100644 --- a/app/helper/plugin.py +++ b/app/helper/plugin.py @@ -222,8 +222,52 @@ class PluginHelper(metaclass=Singleton): # 插件目录下如有requirements.txt则安装依赖 requirements_file = plugin_dir / "requirements.txt" if requirements_file.exists(): - PIP_PROXY = f" -i {settings.PIP_PROXY} " if settings.PIP_PROXY else "" - SystemUtils.execute(f"pip install -r {requirements_file} {PIP_PROXY} > /dev/null 2>&1") + # 初始化 + 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") # 安装成功后统计 self.install_reg(pid) diff --git a/config/app.env b/config/app.env index 956d17b8..6eb35bab 100644 --- a/config/app.env +++ b/config/app.env @@ -17,6 +17,8 @@ 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 b0bd0af7..c9b897fb 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 "依赖安装中..." - 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 + ${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 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 pip install --root-user-action ${PIP_OPTIONS} -r {} \; > /dev/null + find /app/app/plugins -name requirements.txt -exec ${PROXY_CHAINS} pip install --root-user-action ${PIP_OPTIONS} -r {} \; > /dev/null # 清理临时目录 rm -rf /tmp/* INFO "插件更新成功" @@ -116,26 +116,128 @@ function install_backend_and_download_resources() { fi } +# 使用python进行URL解析,$1为PROXY_HOST +function parse_url() { + local result + 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 - if [[ -n "${PIP_PROXY}" ]] || [[ -n "${GITHUB_PROXY}" ]]; then - CURL_OPTIONS="-sL" - PIP_OPTIONS=${PIP_PROXY:+-i ${PIP_PROXY}} - GITHUB_PROXY=${GITHUB_PROXY:-""} - # 判断不同的代理组合 - if [ -z "${PIP_OPTIONS}" ] && [ -n "${GITHUB_PROXY}" ]; then - INFO "不使用代理更新环境依赖,使用Github镜像代理更新程序" - elif [ -n "${PIP_OPTIONS}" ] && [ -z "${GITHUB_PROXY}" ]; then - INFO "使用Pip镜像代理更新环境依赖,不使用代理更新程序" + # 默认不使用proxychains代理PIP + PROXY_CHAINS="" + # 解析代理地址,判断代理合法性 + if [[ -n "${PROXY_HOST}" ]]; then + parse_url "${PROXY_HOST}" + INFO "检测到代理地址,开始解析..." + if [[ "${PROTOCOL}" =~ ^http ]]; then + PROXY_HOST_MODE="true" + SOCKS_MODE="false" + elif [[ "${PROTOCOL}" =~ ^socks ]]; then + PROXY_HOST_MODE="true" + SOCKS_MODE="true" else - INFO "使用Pip镜像代理更新环境依赖,使用Github镜像代理更新程序" + PROXY_HOST_MODE="false" + SOCKS_MODE="false" + WARN "【PROXY_HOST】代理地址错误,无法添加全局代理环境,开始使用其他更新方式" fi - elif [ -n "${PROXY_HOST}" ]; then + 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:代理地址正常,则使用全局代理 + elif [[ -n "${PROXY_HOST}" && "${PROXY_HOST_MODE}" = "true" ]]; then CURL_OPTIONS="-sL -x ${PROXY_HOST}" - PIP_OPTIONS="--proxy=${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:其他情况,统一不使用代理 else CURL_OPTIONS="-sL" + PIP_OPTIONS="" + GITHUB_PROXY="" + PROXY_CHAINS="" INFO "不使用任何代理更新程序与环境依赖" fi if [ -n "${GITHUB_TOKEN}" ]; then diff --git a/urlparse.py b/urlparse.py new file mode 100644 index 00000000..70470803 --- /dev/null +++ b/urlparse.py @@ -0,0 +1,53 @@ +import sys +from urllib.parse import urlparse + + +def parse_url(url): + parsed_url = urlparse(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 "" + + if hostname: + hostname = hostname.lower() + + if not port: + if protocol == "https": + port = 443 + elif protocol == "http": + port = 80 + 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}") + + +if __name__ == "__main__": + # 参数不全,直接返回空解析结果 + if len(sys.argv) != 2: + print(f"SCHEME:''") + print(f"USERNAME:''") + print(f"PASSWORD:''") + print(f"HOST:''") + print(f"PORT:''") + + # 参数全,解析URL + PROXY_HOST = sys.argv[1] + parse_url(url=PROXY_HOST) From fea7b7d02da934a96617885ebbc92d59bfdf6bc5 Mon Sep 17 00:00:00 2001 From: Aqr-K <95741669+Aqr-K@users.noreply.github.com> Date: Sat, 3 Aug 2024 18:36:16 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20urlparse.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- urlparse.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/urlparse.py b/urlparse.py index 70470803..7b982b01 100644 --- a/urlparse.py +++ b/urlparse.py @@ -47,7 +47,7 @@ if __name__ == "__main__": print(f"PASSWORD:''") print(f"HOST:''") print(f"PORT:''") - # 参数全,解析URL - PROXY_HOST = sys.argv[1] - parse_url(url=PROXY_HOST) + else: + PROXY_HOST = sys.argv[1] + parse_url(url=PROXY_HOST) From e8ff878aac45dfd377d83f7e20e6b8c4f4fc75f6 Mon Sep 17 00:00:00 2001 From: Aqr-K <95741669+Aqr-K@users.noreply.github.com> Date: Sat, 3 Aug 2024 23:02:10 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=88=A0=E9=99=A4`PROXY=5FSUPPLEMENT`?= =?UTF-8?q?=E5=8F=98=E9=87=8F=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=8F=AA=E8=AF=BB?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E2=80=98PIP=5FOPTIONS=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1、删除`proxychains4`模块支持,`pip`代理已支持全局模式下的`socks4`、`socks4a`、`socks5`、`socks5h`、`http`、`https`协议; 2、删除`PROXY_SUPPLEMENT`变量,取消手动控制功能; 3、增加自动判断,将`pip`与`update`的代理判断,从手动改为自动,优先级:镜像站 > 全局 > 不代理; 4、将`pip`的附加代理参数,作为只读属性`PIP_OPTIONS`写入到`config`中,其他对象可通过`settings.PIP_OPTIONS`实现快速调用。 --- Dockerfile | 1 - app/core/config.py | 64 +++++++++++---------- app/helper/plugin.py | 47 +--------------- config/app.env | 2 - update | 130 ++++++++++--------------------------------- urlparse.py | 11 ---- 6 files changed, 65 insertions(+), 190 deletions(-) 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 From d5d32e2335790de52b83e192138532989084b7ce Mon Sep 17 00:00:00 2001 From: Aqr-K <95741669+Aqr-K@users.noreply.github.com> Date: Sun, 4 Aug 2024 00:09:00 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- update | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update b/update index d9d553b4..f0375e21 100644 --- a/update +++ b/update @@ -119,7 +119,7 @@ function install_backend_and_download_resources() { # 使用python进行URL解析,$1为PROXY_HOST function parse_url() { local result - result=$(./parse_url.py ${1}) + result=$(python3 /app/parse_url.py ${1}) # 解析结果并提取各项 PROTOCOL=$(echo "$result" | grep "^SCHEME:" | awk '{print $2}') HOST=$(echo "$result" | grep "^HOST:" | awk '{print $2}')