commit
This commit is contained in:
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
// 使用 IntelliSense 了解相关属性。
|
||||||
|
// 悬停以查看现有属性的描述。
|
||||||
|
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "Python 调试程序: 包含参数的当前文件",
|
||||||
|
"type": "debugpy",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${file}",
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"python": "/opt/homebrew/bin/python3",
|
||||||
|
"args": "${command:pickArgs}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Vendored
+11
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"python-envs.defaultEnvManager": "ms-python.python:system",
|
||||||
|
"python.defaultInterpreterPath": "/opt/homebrew/bin/python3",
|
||||||
|
"terminal.integrated.defaultProfile.osx": "zsh",
|
||||||
|
"terminal.integrated.env.osx": {
|
||||||
|
"PATH": "/opt/homebrew/bin:${env:PATH}"
|
||||||
|
},
|
||||||
|
"code-runner.executorMap": {
|
||||||
|
"python": "python3 -u"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# 参数配置(可修改)
|
||||||
|
# ----------------------------------
|
||||||
|
SOURCE_DIR="/path/to/your/directory" # 要扫描的目录(网盘映射路径)
|
||||||
|
OUTPUT_FILE="strm_stats.txt" # 结果输出文件
|
||||||
|
SLEEP_INTERVAL=0.5 # 扫描间隔(秒,可调节防止风控)
|
||||||
|
MAX_DEPTH=5 # 最大递归深度(避免扫描过深)
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# 检查目录是否存在
|
||||||
|
# ----------------------------------
|
||||||
|
if [[ ! -d "$SOURCE_DIR" ]]; then
|
||||||
|
echo "[ERROR] 目录 $SOURCE_DIR 不存在!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# 初始化统计变量
|
||||||
|
# ----------------------------------
|
||||||
|
declare -A dir_counts # 存储各目录的 .strm 文件数
|
||||||
|
|
||||||
|
echo "开始扫描 $SOURCE_DIR(子目录深度 $MAX_DEPTH,间隔 $SLEEP_INTERVAL 秒)..."
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# 递归遍历目录并统计 .strm 文件
|
||||||
|
# ----------------------------------
|
||||||
|
find "$SOURCE_DIR" -type d -print0 | while IFS= read -r -d '' dir; do
|
||||||
|
# 跳过超过深度的目录
|
||||||
|
if [[ $(awk -F/ '{print NF-1}' <<< "${dir#$SOURCE_DIR/}") -ge $MAX_DEPTH ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 统计当前目录的 .strm 文件数
|
||||||
|
count=$(find "$dir" -maxdepth 1 -type f -name "*.strm" | wc -l)
|
||||||
|
if [[ $count -gt 0 ]]; then
|
||||||
|
dir_counts["${dir#$SOURCE_DIR/}"]=$count
|
||||||
|
echo "[发现] ${dir#$SOURCE_DIR/}: $count 个 .strm 文件"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 按需暂停(防止网盘风控)
|
||||||
|
sleep $SLEEP_INTERVAL
|
||||||
|
done
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# 输出结果
|
||||||
|
# ----------------------------------
|
||||||
|
echo "===== 结果统计 =====" > "$OUTPUT_FILE"
|
||||||
|
for dir in "${!dir_counts[@]}"; do
|
||||||
|
echo "$dir: ${dir_counts[$dir]} 个文件" >> "$OUTPUT_FILE"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "扫描完成!结果已保存至 $OUTPUT_FILE。"
|
||||||
Executable
+47
@@ -0,0 +1,47 @@
|
|||||||
|
# 与服务端建立连接,跟上面的配置要对应 阿里106.15.121.26 腾讯150.158.120.215 联通云 116.162.100.119
|
||||||
|
serverAddr = "124.220.30.149"
|
||||||
|
serverPort = 7000
|
||||||
|
|
||||||
|
# 配置Token鉴权,要与服务端一致
|
||||||
|
auth.method = "token"
|
||||||
|
auth.token = "admin8466"
|
||||||
|
|
||||||
|
# 配置日志信息
|
||||||
|
#log.level = "warn"
|
||||||
|
#log.to = "/opt/frpc/frpc.log"
|
||||||
|
|
||||||
|
|
||||||
|
# frpc.toml
|
||||||
|
webServer.addr = "192.168.1.108"
|
||||||
|
webServer.port = 7400
|
||||||
|
webServer.user = "admin"
|
||||||
|
webServer.password = "admin8466"
|
||||||
|
|
||||||
|
[[proxies]]
|
||||||
|
name = "frp-fnOS-openlist-9161"
|
||||||
|
|
||||||
|
type = "tcp"
|
||||||
|
|
||||||
|
localIP = "127.0.0.1"
|
||||||
|
localPort = 7244
|
||||||
|
remotePort = 9161
|
||||||
|
|
||||||
|
#[[proxies]]
|
||||||
|
#name = "frp-fnOST-alist"
|
||||||
|
|
||||||
|
#type = "tcp"
|
||||||
|
|
||||||
|
#localIP = "127.0.0.1"
|
||||||
|
#localPort = 5244
|
||||||
|
#remotePort = 5644
|
||||||
|
|
||||||
|
|
||||||
|
[[proxies]]
|
||||||
|
name = "frp-fnOS-cwa"
|
||||||
|
|
||||||
|
type = "tcp"
|
||||||
|
|
||||||
|
localIP = "127.0.0.1"
|
||||||
|
localPort = 7083
|
||||||
|
remotePort = 7083
|
||||||
|
|
||||||
Executable
+30
@@ -0,0 +1,30 @@
|
|||||||
|
# 与服务端建立连接,跟上面的配置要对应
|
||||||
|
#serverAddr = "106.15.121.26"
|
||||||
|
#serverPort = 7000
|
||||||
|
|
||||||
|
# 配置Token鉴权,要与服务端一致
|
||||||
|
#auth.method = "token"
|
||||||
|
#auth.token = "admin8466"
|
||||||
|
|
||||||
|
# 配置日志信息
|
||||||
|
#log.level = "warn"
|
||||||
|
#log.to = "/opt/frpc/frpc.log"
|
||||||
|
|
||||||
|
|
||||||
|
# frpc.toml
|
||||||
|
webServer.addr = "127.0.0.1"
|
||||||
|
webServer.port = 7400
|
||||||
|
webServer.user = "admin"
|
||||||
|
webServer.password = "admin8466"
|
||||||
|
|
||||||
|
|
||||||
|
#[[proxies]]
|
||||||
|
#name = "frp-fnOS-alist"
|
||||||
|
|
||||||
|
#type = "tcp"
|
||||||
|
|
||||||
|
#localIP = "127.0.0.1"
|
||||||
|
# fnOS 5244 fnOST 5245 106.15.121.26 放行52445245端口
|
||||||
|
#localPort = 5244
|
||||||
|
#remotePort = 5244
|
||||||
|
|
||||||
Executable
+16
@@ -0,0 +1,16 @@
|
|||||||
|
bindAddr = "0.0.0.0"
|
||||||
|
bindPort = 7000
|
||||||
|
|
||||||
|
auth.method = "token"
|
||||||
|
auth.token = "admin8466"
|
||||||
|
|
||||||
|
webServer.addr = "0.0.0.0"
|
||||||
|
webServer.port = 7500
|
||||||
|
webServer.user = "admin"
|
||||||
|
webServer.password = "Mayi19b8"
|
||||||
|
|
||||||
|
# tls
|
||||||
|
#transport.tls.force = true
|
||||||
|
#transport.tls.certFile = "/etc/frp/ssl/server.crt"
|
||||||
|
#transport.tls.keyFile = "/etc/frp/ssl/server.key"
|
||||||
|
#transport.tls.trustedCaFile = "/etc/frp/ssl/ca.crt"
|
||||||
Executable
+6
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
rclone mount xiaoyastrm: /vol4/1000/USBD2/MediaLibrary/xiaoyastrm --header "Referer:" --multi-thread-streams 6 --buffer-size 512M --vfs-fast-fingerprint --vfs-cache-mode full --no-modtime --file-perms 0777 --copy-links --allow-other --allow-non-empty --umask 000 --cache-dir /vol1/cache/rclone
|
||||||
|
|
||||||
|
#rclone mount wd_joycloud_dsm920: /vol4/1000/USBD2/MediaLibrary/Mdsm920 --header "Referer:" --multi-thread-streams 6 --buffer-size 512M --vfs-fast-fingerprint --vfs-cache-mode full --no-modtime --file-perms 0777 --copy-links --allow-other --allow-non-empty --umask 000 --cache-dir /vol1/cache/rclone
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
Executable
+57
@@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# 参数配置(可修改)
|
||||||
|
# ----------------------------------
|
||||||
|
SOURCE_DIR="/vol4/1000/USBD2/MediaLibrary/Mdsm920/本地磁盘/fnOS/strms/电影/动画电影" # 要扫描的目录(网盘映射路径)
|
||||||
|
OUTPUT_FILE="/vol4/1000/USBD2/MediaLibrary/strm_stats.txt" # 结果输出文件
|
||||||
|
SLEEP_INTERVAL=0.5 # 扫描间隔(秒,可调节防止风控)
|
||||||
|
MAX_DEPTH=5 # 最大递归深度(避免扫描过深)
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# 检查目录是否存在
|
||||||
|
# ----------------------------------
|
||||||
|
if [[ ! -d "$SOURCE_DIR" ]]; then
|
||||||
|
echo "[ERROR] 目录 $SOURCE_DIR 不存在!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# 初始化统计变量
|
||||||
|
# ----------------------------------
|
||||||
|
declare -A dir_counts # 存储各目录的 .strm 文件数
|
||||||
|
|
||||||
|
echo "开始扫描 $SOURCE_DIR(子目录深度 $MAX_DEPTH,间隔 $SLEEP_INTERVAL 秒)..."
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# 递归遍历目录并统计 .strm 文件
|
||||||
|
# ----------------------------------
|
||||||
|
find "$SOURCE_DIR" -type d -print0 | while IFS= read -r -d '' dir; do
|
||||||
|
# 跳过超过深度的目录
|
||||||
|
if [[ $(awk -F/ '{print NF-1}' <<< "${dir#$SOURCE_DIR/}") -ge $MAX_DEPTH ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 统计当前目录的 .strm 文件数
|
||||||
|
count=$(find "$dir" -maxdepth 1 -type f -name "*.strm" | wc -l)
|
||||||
|
if [[ $count -gt 0 ]]; then
|
||||||
|
dir_counts["${dir#$SOURCE_DIR/}"]=$count
|
||||||
|
echo "[发现] ${dir#$SOURCE_DIR/}: $count 个 .strm 文件"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 按需暂停(防止网盘风控)
|
||||||
|
sleep $SLEEP_INTERVAL
|
||||||
|
done
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# 输出结果
|
||||||
|
# ----------------------------------
|
||||||
|
echo "===== 结果统计 =====" > "$OUTPUT_FILE"
|
||||||
|
for dir in "${!dir_counts[@]}"; do
|
||||||
|
echo "$dir: ${dir_counts[$dir]} 个文件" >> "$OUTPUT_FILE"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "扫描完成!结果已保存至 $OUTPUT_FILE。"
|
||||||
|
|
||||||
Executable
+18
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 等待某个容器完全启动(支持健康检查)
|
||||||
|
CONTAINER_NAME="xiaoya" # 替换为你的容器名
|
||||||
|
MAX_RETRIES=30
|
||||||
|
SLEEP_TIME=5
|
||||||
|
|
||||||
|
for i in $(seq 1 $MAX_RETRIES); do
|
||||||
|
if docker inspect --format '{{.State.Running}}' $CONTAINER_NAME 2>/dev/null | grep -q "true"; then
|
||||||
|
echo "[INFO] Container $CONTAINER_NAME is running."
|
||||||
|
sleep 30
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
echo "[WAIT] Container $CONTAINER_NAME not ready ($i/$MAX_RETRIES)..."
|
||||||
|
sleep $SLEEP_TIME
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "[ERROR] Timeout: Container $CONTAINER_NAME did not start!"
|
||||||
|
exit 1
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 定义目标目录(可修改为你的路径)
|
||||||
|
TARGET_DIR="$1"
|
||||||
|
|
||||||
|
# 检查是否传入目录参数
|
||||||
|
if [[ -z "$TARGET_DIR" || ! -d "$TARGET_DIR" ]]; then
|
||||||
|
echo "[错误] 请指定有效的目录路径!"
|
||||||
|
echo "用法: $0 /path/to/directory"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 定义目标文件扩展名(视频 + 音频)
|
||||||
|
FILE_EXTENSIONS=("mp4" "mkv" "flv" "avi" "wmv" "ts" "rmvb" "webm" "mp3" "flac" "aac" "wav" "ogg" "m4a" "wma" "alac")
|
||||||
|
|
||||||
|
echo "[INFO] 正在扫描 $TARGET_DIR 下的媒体文件..."
|
||||||
|
|
||||||
|
# 遍历所有子目录并匹配目标扩展名
|
||||||
|
find "$TARGET_DIR" -type f \( \
|
||||||
|
-iname "*.mp4" -o \
|
||||||
|
-iname "*.mkv" -o \
|
||||||
|
-iname "*.flv" -o \
|
||||||
|
-iname "*.avi" -o \
|
||||||
|
-iname "*.wmv" -o \
|
||||||
|
-iname "*.ts" -o \
|
||||||
|
-iname "*.rmvb" -o \
|
||||||
|
-iname "*.webm" -o \
|
||||||
|
-iname "*.mp3" -o \
|
||||||
|
-iname "*.flac" -o \
|
||||||
|
-iname "*.aac" -o \
|
||||||
|
-iname "*.wav" -o \
|
||||||
|
-iname "*.ogg" -o \
|
||||||
|
-iname "*.m4a" -o \
|
||||||
|
-iname "*.wma" -o \
|
||||||
|
-iname "*.alac" \) -exec ls -la {} \;
|
||||||
|
|
||||||
|
# 汇总统计
|
||||||
|
echo "===== 统计 ====="
|
||||||
|
for ext in "${FILE_EXTENSIONS[@]}"; do
|
||||||
|
count=$(find "$TARGET_DIR" -type f -iname "*.$ext" | wc -l)
|
||||||
|
echo ".$ext: $count 个文件"
|
||||||
|
done
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
{
|
||||||
|
"file_rules": [
|
||||||
|
{
|
||||||
|
"rule_id": "F001",
|
||||||
|
"order": 1,
|
||||||
|
"kind": "bracket_pair",
|
||||||
|
"open": "\\[",
|
||||||
|
"close": "\\]",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F002",
|
||||||
|
"order": 2,
|
||||||
|
"kind": "bracket_pair",
|
||||||
|
"open": "【",
|
||||||
|
"close": "】",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F003",
|
||||||
|
"order": 3,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|BD|BluRay|BLURAY|WEBRip|WEB\\-DL|HD|4K|REMUX|RMVB|HDR10Plus|10bit|60fps",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true,
|
||||||
|
"flags": "IGNORECASE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F004",
|
||||||
|
"order": 4,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "双语字幕|双语|中英双语|中英双字|双语中字|官方中字|特效中字",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true,
|
||||||
|
"flags": "IGNORECASE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F005",
|
||||||
|
"order": 5,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "CMCT|WiKi|CHD|SiluHD|PublicHD|RARBG|TGx|‑HDHome|52pt|HHWEB|ZmWeb|ADWeb|BT‑PT|‑CHD|‑WiKi|‑RARBG|‑HHWEB|‑ZmWeb|‑PublicHD|‑52pt|‑CiNEFiLE",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true,
|
||||||
|
"flags": "IGNORECASE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F006",
|
||||||
|
"order": 6,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "收藏不迷路|地址发布页|九洲客|tdw9430|6v电影|电影港|www\\.6v123\\.net|www\\.dygang\\.me|www\\.dream2008\\.cn|www\\.6v123\\.com",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F007",
|
||||||
|
"order": 7,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "\\d+\\.5G|\\d+G|MKV|TS",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true,
|
||||||
|
"flags": "IGNORECASE"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dir_rules": [
|
||||||
|
{
|
||||||
|
"rule_id": "D001",
|
||||||
|
"order": 1,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|BD|BluRay|BLURAY|WEBRip|WEB\\-DL|HD|4K",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true,
|
||||||
|
"flags": "IGNORECASE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "D002",
|
||||||
|
"order": 2,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "双语字幕|双语|中英双语|中英双字|双语中字|官方中字|特效中字",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true,
|
||||||
|
"flags": "IGNORECASE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "D003",
|
||||||
|
"order": 3,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "收藏不迷路|地址发布页|九洲客|tdw9430|6v电影|电影港|www\\.6v123\\.net|www\\.dygang\\.me|www\\.dream2008\\.cn|www\\.6v123\\.com",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
{
|
||||||
|
"file_rules": [
|
||||||
|
{
|
||||||
|
"rule_id": "F001",
|
||||||
|
"order": 1,
|
||||||
|
"kind": "bracket_pair",
|
||||||
|
"open": "\\[",
|
||||||
|
"close": "\\]",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F002",
|
||||||
|
"order": 2,
|
||||||
|
"kind": "bracket_pair",
|
||||||
|
"open": "【",
|
||||||
|
"close": "】",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F003",
|
||||||
|
"order": 3,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|BD|BluRay|BLURAY|WEBRip|WEB\\-DL|HD|4K|REMUX|RMVB|HDR10Plus|10bit|60fps",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true,
|
||||||
|
"flags": "IGNORECASE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F004",
|
||||||
|
"order": 4,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "双语字幕|双语|中英双语|中英双字|双语中字|官方中字|特效中字",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true,
|
||||||
|
"flags": "IGNORECASE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F005",
|
||||||
|
"order": 5,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "CMCT|WiKi|CHD|SiluHD|PublicHD|RARBG|TGx|‑HDHome|52pt|HHWEB|ZmWeb|ADWeb|BT‑PT|‑CHD|‑WiKi|‑RARBG|‑HHWEB|‑ZmWeb|‑PublicHD|‑52pt|‑CiNEFiLE",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true,
|
||||||
|
"flags": "IGNORECASE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F006",
|
||||||
|
"order": 6,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "收藏不迷路|地址发布页|九洲客|tdw9430|6v电影|电影港|www\\.6v123\\.net|www\\.dygang\\.me|www\\.dream2008\\.cn|www\\.6v123\\.com",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F007",
|
||||||
|
"order": 7,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "\\d+\\.5G|\\d+G|MKV|TS",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true,
|
||||||
|
"flags": "IGNORECASE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F013",
|
||||||
|
"order": 13,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "【[^】]*】",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F014",
|
||||||
|
"order": 14,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "\\[\\]",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "F015",
|
||||||
|
"order": 15,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "【】",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dir_rules": [
|
||||||
|
{
|
||||||
|
"rule_id": "D001",
|
||||||
|
"order": 1,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|BD|BluRay|BLURAY|WEBRip|WEB\\-DL|HD|4K",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true,
|
||||||
|
"flags": "IGNORECASE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "D002",
|
||||||
|
"order": 2,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "双语字幕|双语|中英双语|中英双字|双语中字|官方中字|特效中字",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true,
|
||||||
|
"flags": "IGNORECASE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "D003",
|
||||||
|
"order": 3,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "收藏不迷路|地址发布页|九洲客|tdw9430|6v电影|电影港|www\\.6v123\\.net|www\\.dygang\\.me|www\\.dream2008\\.cn|www\\.6v123\\.com",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "D006",
|
||||||
|
"order": 6,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "【[^】]*】",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "D007",
|
||||||
|
"order": 7,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "\\[\\]",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "D008",
|
||||||
|
"order": 8,
|
||||||
|
"kind": "string",
|
||||||
|
"pattern": "【】",
|
||||||
|
"repl": "",
|
||||||
|
"safe_guard_empty": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"source": "/vol4/1000/USBD2/MediaLibrary/output-two",
|
||||||
|
"dest": "/vol4/1000/USBD2/MediaLibrary/out-final",
|
||||||
|
"tmdb_api_key": "",
|
||||||
|
"mock": false,
|
||||||
|
"settle": 6,
|
||||||
|
"language": "zh-CN"
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Self Media Scraper Watcher (TMDB)
|
||||||
|
# 用途:开机自启,监听清理目录,新媒体出现自动刮削并复制落库
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
# ---- 下面 3 行把 /你的项目绝对路径 替换成飞牛上放本项目的真实路径 ----
|
||||||
|
ExecStart=/你的项目绝对路径/.venv/bin/python /你的项目绝对路径/watcher.py --config /你的项目绝对路径/config.json
|
||||||
|
WorkingDirectory=/你的项目绝对路径
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
StandardOutput=append:/你的项目绝对路径/scraper.out
|
||||||
|
StandardError=append:/你的项目绝对路径/scraper.err
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
Executable
+449
@@ -0,0 +1,449 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
import json
|
||||||
|
import argparse
|
||||||
|
import shutil
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
LOG_FILE = "./rename_log.txt"
|
||||||
|
ERR_REPORT_JSON = "./report_err_only.json"
|
||||||
|
|
||||||
|
SKIP_DIRS = [
|
||||||
|
"@eaDir",
|
||||||
|
]
|
||||||
|
SKIP_FILES = {
|
||||||
|
".DS_Store",
|
||||||
|
"Thumbs.db",
|
||||||
|
"desktop.ini",
|
||||||
|
}
|
||||||
|
|
||||||
|
FULL_ALLOW_EXT = {".mkv", ".mp4", ".mov", ".srt", ".ass", ".sub", ".strm", ".flv", ".avi", ".wmv", ".ts", ".rmvb", ".webm", ".mp3", ".flac", ".aac", ".wav", ".ogg", ".m4a", ".wma", ".alac", ".rm", ".iso"}
|
||||||
|
STRM_ONLY_EXT = {".strm", ".srt", ".ass", ".sub"}
|
||||||
|
MAX_FILENAME_LEN = 245
|
||||||
|
|
||||||
|
def full2half(s: str) -> str:
|
||||||
|
res = []
|
||||||
|
for ch in s:
|
||||||
|
oc = ord(ch)
|
||||||
|
if oc == 12288:
|
||||||
|
res.append(chr(32))
|
||||||
|
elif 65281 <= oc <= 65374:
|
||||||
|
res.append(chr(oc - 65248))
|
||||||
|
else:
|
||||||
|
res.append(ch)
|
||||||
|
return "".join(res)
|
||||||
|
|
||||||
|
def remove_emoji(s: str) -> str:
|
||||||
|
emoji_pattern = re.compile("["
|
||||||
|
u"\U0001F600-\U0001F64F"
|
||||||
|
u"\U0001F300-\U0001F5FF"
|
||||||
|
u"\U0001F680-\U0001F6FF"
|
||||||
|
u"\U0001F1E0-\U0001F1FF"
|
||||||
|
u"\U00002700-\U000027BF"
|
||||||
|
u"\U0001F900-\U0001F9FF"
|
||||||
|
"]+", flags=re.UNICODE)
|
||||||
|
return emoji_pattern.sub(r'', s)
|
||||||
|
|
||||||
|
def post_clean_dot(name: str, is_dir: bool=False) -> str:
|
||||||
|
"""后置净化:清除连续点、首尾点、首尾下划线;区分目录/文件,保护扩展名"""
|
||||||
|
if is_dir:
|
||||||
|
body = name
|
||||||
|
ext = ""
|
||||||
|
else:
|
||||||
|
body, ext = os.path.splitext(name)
|
||||||
|
body = re.sub(r"\.+", ".", body)
|
||||||
|
body = body.strip("._")
|
||||||
|
return body + ext
|
||||||
|
|
||||||
|
def stage1_light_clean(name: str, is_dir: bool=False) -> str:
|
||||||
|
"""阶段一:轻清洗"""
|
||||||
|
n = name
|
||||||
|
n = remove_emoji(n)
|
||||||
|
n = full2half(n)
|
||||||
|
n = re.sub(r"^[A-Za-z] +", "", n)
|
||||||
|
n = re.sub(r"\s+", "", n)
|
||||||
|
n = post_clean_dot(n, is_dir=is_dir)
|
||||||
|
return n.strip()
|
||||||
|
|
||||||
|
def run_rule_list(orig_name: str, rules: list, is_dir: bool=False):
|
||||||
|
hit_ids = []
|
||||||
|
cur = orig_name
|
||||||
|
safeguard_trigger = False
|
||||||
|
|
||||||
|
for r in sorted(rules, key=lambda x: x.get("order", 9999)):
|
||||||
|
rid = r["rule_id"]
|
||||||
|
kind = r["kind"]
|
||||||
|
repl = r["repl"]
|
||||||
|
safe_guard = r.get("safe_guard_empty", False)
|
||||||
|
rule_flags = r.get("flags", "")
|
||||||
|
prev = cur
|
||||||
|
|
||||||
|
re_flags = 0
|
||||||
|
if rule_flags == "IGNORECASE":
|
||||||
|
re_flags = re.IGNORECASE
|
||||||
|
|
||||||
|
if kind == "string":
|
||||||
|
cur = re.sub(r["pattern"], repl, cur, flags=re_flags)
|
||||||
|
elif kind == "bracket_pair":
|
||||||
|
o_pat = r["open"]
|
||||||
|
c_pat = r["close"]
|
||||||
|
# bracket_pair额外开启DOTALL,.可匹配中文、各类符号
|
||||||
|
while True:
|
||||||
|
new_val = re.sub(o_pat + ".*?" + c_pat, repl, cur, flags=re_flags | re.DOTALL)
|
||||||
|
if new_val == cur:
|
||||||
|
break
|
||||||
|
cur = new_val
|
||||||
|
if safe_guard:
|
||||||
|
body, ext = (cur, "") if is_dir else os.path.splitext(cur)
|
||||||
|
if len(body.strip()) == 0:
|
||||||
|
cur = prev
|
||||||
|
continue
|
||||||
|
|
||||||
|
cur = cur.strip()
|
||||||
|
if safe_guard:
|
||||||
|
body, ext = (cur, "") if is_dir else os.path.splitext(cur)
|
||||||
|
if len(body.strip()) == 0:
|
||||||
|
cur = prev
|
||||||
|
continue
|
||||||
|
|
||||||
|
if cur != prev:
|
||||||
|
hit_ids.append(rid)
|
||||||
|
|
||||||
|
# 全部规则跑完,全局兜底保护
|
||||||
|
body_final, ext_final = (cur, "") if is_dir else os.path.splitext(cur)
|
||||||
|
if len(body_final.strip()) == 0:
|
||||||
|
safeguard_trigger = True
|
||||||
|
cur = orig_name
|
||||||
|
|
||||||
|
# 符号净化
|
||||||
|
cur = post_clean_dot(cur, is_dir=is_dir)
|
||||||
|
|
||||||
|
# 净化之后再次兜底
|
||||||
|
body2, ext2 = (cur, "") if is_dir else os.path.splitext(cur)
|
||||||
|
if len(body2.strip()) == 0:
|
||||||
|
safeguard_trigger = True
|
||||||
|
cur = orig_name
|
||||||
|
|
||||||
|
return cur, hit_ids, safeguard_trigger
|
||||||
|
|
||||||
|
def assign_unique_name_group(item_list):
|
||||||
|
counter = dict()
|
||||||
|
out = []
|
||||||
|
for it in item_list:
|
||||||
|
cand = it["candidate"]
|
||||||
|
cnt = counter.get(cand, 0)
|
||||||
|
final = cand if cnt == 0 else f"{cand}({cnt})"
|
||||||
|
counter[cand] = cnt + 1
|
||||||
|
ni = dict(it)
|
||||||
|
ni["final_step1"] = final
|
||||||
|
out.append(ni)
|
||||||
|
return out
|
||||||
|
|
||||||
|
def assign_dup_suffix(item_list, name_key: str):
|
||||||
|
counter = dict()
|
||||||
|
for it in item_list:
|
||||||
|
nm = it[name_key]
|
||||||
|
c = counter.get(nm, 0)
|
||||||
|
if c > 0:
|
||||||
|
new_nm = f"{nm}_dup({c})"
|
||||||
|
it[name_key] = new_nm
|
||||||
|
it["step2_dup_warn"] = True
|
||||||
|
else:
|
||||||
|
it["step2_dup_warn"] = False
|
||||||
|
counter[nm] = c + 1
|
||||||
|
|
||||||
|
def write_log(msg: str, log_file: str):
|
||||||
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
line = f"[{now}] {msg}"
|
||||||
|
print(line)
|
||||||
|
try:
|
||||||
|
with open(log_file, "a", encoding="utf-8") as f:
|
||||||
|
f.write(line + "\n")
|
||||||
|
f.flush()
|
||||||
|
except Exception:
|
||||||
|
print(f"[LOG-WRITE-FAILED] {line}")
|
||||||
|
|
||||||
|
def scan_full_tree(root_src, skip_dirs, skip_files, allow_ext):
|
||||||
|
dir_entries = []
|
||||||
|
file_entries = []
|
||||||
|
root_abs = os.path.abspath(root_src)
|
||||||
|
for src_root, dirs, files in os.walk(root_src, topdown=True):
|
||||||
|
remove_idx = []
|
||||||
|
for idx, dname in enumerate(dirs):
|
||||||
|
if dname in skip_dirs:
|
||||||
|
remove_idx.append(idx)
|
||||||
|
for idx in reversed(remove_idx):
|
||||||
|
del dirs[idx]
|
||||||
|
dirs[:] = dirs
|
||||||
|
src_root_abs = os.path.abspath(src_root)
|
||||||
|
if src_root_abs != root_abs:
|
||||||
|
bn = os.path.basename(src_root_abs)
|
||||||
|
c1 = stage1_light_clean(bn, is_dir=True)
|
||||||
|
dir_entries.append({
|
||||||
|
"src_abs": src_root_abs,
|
||||||
|
"src_parent_abs": os.path.dirname(src_root_abs),
|
||||||
|
"depth": src_root_abs.count(os.sep),
|
||||||
|
"orig_basename": bn,
|
||||||
|
"candidate": c1
|
||||||
|
})
|
||||||
|
for fname in files:
|
||||||
|
if fname in skip_files:
|
||||||
|
continue
|
||||||
|
ext = os.path.splitext(fname)[1].lower()
|
||||||
|
if ext not in allow_ext:
|
||||||
|
continue
|
||||||
|
c1 = stage1_light_clean(fname, is_dir=False)
|
||||||
|
file_entries.append({
|
||||||
|
"src_parent_abs": src_root_abs,
|
||||||
|
"orig_basename": fname,
|
||||||
|
"candidate": c1
|
||||||
|
})
|
||||||
|
return root_abs, dir_entries, file_entries
|
||||||
|
|
||||||
|
def group_by_parent_abs(item_list, key_name):
|
||||||
|
groups = dict()
|
||||||
|
for it in item_list:
|
||||||
|
k = it[key_name]
|
||||||
|
if k not in groups:
|
||||||
|
groups[k] = []
|
||||||
|
groups[k].append(it)
|
||||||
|
return groups
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="两阶段媒体清洗【修复括号匹配,DOTALL开启】")
|
||||||
|
parser.add_argument("--dir", required=True)
|
||||||
|
parser.add_argument("--output", required=True)
|
||||||
|
parser.add_argument("--apply", action="store_true")
|
||||||
|
parser.add_argument("--dry-run", action="store_true")
|
||||||
|
parser.add_argument("--strm-mode", action="store_true")
|
||||||
|
parser.add_argument("--rules", default=None, help="外部json规则文件路径")
|
||||||
|
parser.add_argument("--log", default=LOG_FILE)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
target_dir = args.dir
|
||||||
|
out_dir = args.output
|
||||||
|
log_path = args.log
|
||||||
|
rules_path = args.rules
|
||||||
|
|
||||||
|
DRY_RUN = True
|
||||||
|
if args.apply:
|
||||||
|
DRY_RUN = False
|
||||||
|
if args.dry_run:
|
||||||
|
DRY_RUN = True
|
||||||
|
|
||||||
|
if args.strm_mode:
|
||||||
|
ALLOW_EXT = STRM_ONLY_EXT
|
||||||
|
mode_info = "STRM模式【仅strm+字幕】"
|
||||||
|
else:
|
||||||
|
ALLOW_EXT = FULL_ALLOW_EXT
|
||||||
|
mode_info = "完整媒体模式"
|
||||||
|
|
||||||
|
if not os.path.isdir(target_dir):
|
||||||
|
print(f"源目录不存在:{target_dir}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(log_path, "w", encoding="utf-8") as f:
|
||||||
|
f.flush()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"日志初始化警告 {e}")
|
||||||
|
|
||||||
|
file_rules = []
|
||||||
|
dir_rules = []
|
||||||
|
if rules_path is not None and os.path.exists(rules_path):
|
||||||
|
try:
|
||||||
|
with open(rules_path, "r", encoding="utf-8") as f:
|
||||||
|
jdata = json.load(f)
|
||||||
|
file_rules = jdata.get("file_rules", [])
|
||||||
|
dir_rules = jdata.get("dir_rules", [])
|
||||||
|
write_log(f"成功加载外部规则文件 {rules_path},file_rules={len(file_rules)},dir_rules={len(dir_rules)}", log_path)
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
write_log(f"规则文件JSON格式错误(第{e.lineno}行第{e.colno}列):{e.msg}", log_path)
|
||||||
|
write_log("提示:键和字符串值必须用英文双引号,正则中的反斜杠必须写成双反斜杠\\\\", log_path)
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
write_log(f"加载规则文件失败:{e}", log_path)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
write_log("未提供--rules或文件不存在,跳过第二阶段深度清洗", log_path)
|
||||||
|
|
||||||
|
write_log("===== 两阶段媒体清洗【修复括号匹配DOTALL】 =====", log_path)
|
||||||
|
write_log(f"源目录:{target_dir}", log_path)
|
||||||
|
write_log(f"输出:{out_dir}", log_path)
|
||||||
|
write_log(f"模式:{mode_info} DRY_RUN={DRY_RUN}", log_path)
|
||||||
|
|
||||||
|
stat = {
|
||||||
|
"src_dir_total":0,
|
||||||
|
"src_file_total":0,
|
||||||
|
"dir_success":0,
|
||||||
|
"dir_fail":0,
|
||||||
|
"file_success":0,
|
||||||
|
"file_fail":0
|
||||||
|
}
|
||||||
|
report_entries = []
|
||||||
|
|
||||||
|
root_src_abs, dir_entries, file_entries = scan_full_tree(target_dir, SKIP_DIRS, SKIP_FILES, ALLOW_EXT)
|
||||||
|
stat["src_dir_total"] = len(dir_entries)
|
||||||
|
stat["src_file_total"] = len(file_entries)
|
||||||
|
write_log(f"采集统计:目录节点 {stat['src_dir_total']},媒体文件 {stat['src_file_total']}", log_path)
|
||||||
|
|
||||||
|
dir_groups = group_by_parent_abs(dir_entries, "src_parent_abs")
|
||||||
|
dir_final = []
|
||||||
|
for p_abs, items in dir_groups.items():
|
||||||
|
assigned = assign_unique_name_group(items)
|
||||||
|
for it in assigned:
|
||||||
|
step1_name = it["final_step1"]
|
||||||
|
if len(dir_rules) > 0:
|
||||||
|
step2_name, hit_rids, safe_trig = run_rule_list(step1_name, dir_rules, is_dir=True)
|
||||||
|
else:
|
||||||
|
step2_name = step1_name
|
||||||
|
hit_rids = []
|
||||||
|
safe_trig = False
|
||||||
|
it["step2_name"] = step2_name
|
||||||
|
it["hit_rule_ids"] = hit_rids
|
||||||
|
it["safe_guard_trigger"] = safe_trig
|
||||||
|
dir_final.append(it)
|
||||||
|
dir_g2_groups = group_by_parent_abs(dir_final, "src_parent_abs")
|
||||||
|
for _, items in dir_g2_groups.items():
|
||||||
|
assign_dup_suffix(items, "step2_name")
|
||||||
|
|
||||||
|
file_groups = group_by_parent_abs(file_entries, "src_parent_abs")
|
||||||
|
file_final = []
|
||||||
|
for p_abs, items in file_groups.items():
|
||||||
|
assigned = assign_unique_name_group(items)
|
||||||
|
for it in assigned:
|
||||||
|
step1_name = it["final_step1"]
|
||||||
|
if len(file_rules) > 0:
|
||||||
|
step2_name, hit_rids, safe_trig = run_rule_list(step1_name, file_rules, is_dir=False)
|
||||||
|
else:
|
||||||
|
step2_name = step1_name
|
||||||
|
hit_rids = []
|
||||||
|
safe_trig = False
|
||||||
|
it["step2_name"] = step2_name
|
||||||
|
it["hit_rule_ids"] = hit_rids
|
||||||
|
it["safe_guard_trigger"] = safe_trig
|
||||||
|
file_final.append(it)
|
||||||
|
file_g2_groups = group_by_parent_abs(file_final, "src_parent_abs")
|
||||||
|
for _, items in file_g2_groups.items():
|
||||||
|
assign_dup_suffix(items, "step2_name")
|
||||||
|
|
||||||
|
src_to_out = dict()
|
||||||
|
src_to_out[root_src_abs] = out_dir
|
||||||
|
dir_final_sorted = sorted(dir_final, key=lambda x: x["depth"])
|
||||||
|
for d in dir_final_sorted:
|
||||||
|
p_abs = d["src_parent_abs"]
|
||||||
|
parent_out = src_to_out.get(p_abs)
|
||||||
|
if parent_out is None:
|
||||||
|
write_log(f"【警告】父目录映射缺失:{p_abs}", log_path)
|
||||||
|
continue
|
||||||
|
child_out = os.path.join(parent_out, d["step2_name"])
|
||||||
|
src_to_out[d["src_abs"]] = child_out
|
||||||
|
|
||||||
|
for d in dir_final:
|
||||||
|
report_entries.append({
|
||||||
|
"type":"dir",
|
||||||
|
"src_abs":d["src_abs"],
|
||||||
|
"orig_basename":d["orig_basename"],
|
||||||
|
"step1_name":d["final_step1"],
|
||||||
|
"step2_name":d["step2_name"],
|
||||||
|
"hit_rule_ids":d["hit_rule_ids"],
|
||||||
|
"safe_guard_trigger":d["safe_guard_trigger"],
|
||||||
|
"step2_dup_warn":d.get("step2_dup_warn", False),
|
||||||
|
"final_out_path": src_to_out.get(d["src_abs"], "")
|
||||||
|
})
|
||||||
|
for f in file_final:
|
||||||
|
src_file = os.path.join(f["src_parent_abs"], f["orig_basename"])
|
||||||
|
parent_out = src_to_out.get(f["src_parent_abs"])
|
||||||
|
dst_file = os.path.join(parent_out, f["step2_name"]) if parent_out else ""
|
||||||
|
report_entries.append({
|
||||||
|
"type":"file",
|
||||||
|
"src_abs":src_file,
|
||||||
|
"orig_basename":f["orig_basename"],
|
||||||
|
"step1_name":f["final_step1"],
|
||||||
|
"step2_name":f["step2_name"],
|
||||||
|
"hit_rule_ids":f["hit_rule_ids"],
|
||||||
|
"safe_guard_trigger":f["safe_guard_trigger"],
|
||||||
|
"step2_dup_warn":f.get("step2_dup_warn", False),
|
||||||
|
"final_out_path": dst_file
|
||||||
|
})
|
||||||
|
|
||||||
|
# 仅输出异常报告,丢弃完整大JSON
|
||||||
|
err_list = []
|
||||||
|
for entry in report_entries:
|
||||||
|
dup = entry.get("step2_dup_warn", False)
|
||||||
|
safe = entry.get("safe_guard_trigger", False)
|
||||||
|
if dup or safe:
|
||||||
|
err_list.append({
|
||||||
|
"type": entry.get("type"),
|
||||||
|
"orig_basename": entry.get("orig_basename"),
|
||||||
|
"step1_name": entry.get("step1_name"),
|
||||||
|
"step2_name": entry.get("step2_name"),
|
||||||
|
"step2_dup_warn": dup,
|
||||||
|
"safe_guard_trigger": safe,
|
||||||
|
"hit_rule_ids": entry.get("hit_rule_ids", [])
|
||||||
|
})
|
||||||
|
try:
|
||||||
|
with open(ERR_REPORT_JSON, "w", encoding="utf-8") as fw:
|
||||||
|
json.dump(err_list, fw, ensure_ascii=False, indent=2)
|
||||||
|
write_log(f"异常报告已输出:{ERR_REPORT_JSON},异常条目数量:{len(err_list)}", log_path)
|
||||||
|
except Exception as e:
|
||||||
|
write_log(f"异常报告写入失败 {e}", log_path)
|
||||||
|
|
||||||
|
for ent in report_entries:
|
||||||
|
ot = ent["orig_basename"]
|
||||||
|
s1 = ent["step1_name"]
|
||||||
|
s2 = ent["step2_name"]
|
||||||
|
parts = []
|
||||||
|
if ot != s1:
|
||||||
|
parts.append(f"原始→step1:{ot} → {s1}")
|
||||||
|
if s1 != s2:
|
||||||
|
parts.append(f"step1→step2:{s1} → {s2}")
|
||||||
|
if ent["step2_dup_warn"]:
|
||||||
|
parts.append("[告警:step2重名追加_dup标记]")
|
||||||
|
if ent["safe_guard_trigger"]:
|
||||||
|
parts.append("[安全保护触发,放弃部分规则]")
|
||||||
|
if len(parts) > 0:
|
||||||
|
write_log(" | ".join(parts), log_path)
|
||||||
|
|
||||||
|
del report_entries
|
||||||
|
|
||||||
|
if DRY_RUN:
|
||||||
|
write_log("===== DRY-RUN预览模式结束,未执行磁盘IO =====", log_path)
|
||||||
|
return
|
||||||
|
|
||||||
|
for d in dir_final_sorted:
|
||||||
|
full_out = src_to_out.get(d["src_abs"])
|
||||||
|
if not full_out:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
os.makedirs(full_out, exist_ok=True)
|
||||||
|
stat["dir_success"] +=1
|
||||||
|
except OSError as e:
|
||||||
|
stat["dir_fail"] +=1
|
||||||
|
write_log(f"【目录创建失败】{full_out} | {e}", log_path)
|
||||||
|
|
||||||
|
for f in file_final:
|
||||||
|
src_fp = os.path.join(f["src_parent_abs"], f["orig_basename"])
|
||||||
|
parent_out = src_to_out.get(f["src_parent_abs"])
|
||||||
|
if not parent_out:
|
||||||
|
stat["file_fail"] +=1
|
||||||
|
write_log(f"【文件复制失败】父目录映射缺失:{src_fp}", log_path)
|
||||||
|
continue
|
||||||
|
dst_fp = os.path.join(parent_out, f["step2_name"])
|
||||||
|
try:
|
||||||
|
shutil.copy2(src_fp, dst_fp)
|
||||||
|
stat["file_success"] +=1
|
||||||
|
except OSError as e:
|
||||||
|
stat["file_fail"] +=1
|
||||||
|
write_log(f"【文件复制失败】src:{src_fp} dst:{dst_fp} | {e}", log_path)
|
||||||
|
|
||||||
|
write_log("----------任务统计汇总----------", log_path)
|
||||||
|
write_log(f"源采集目录节点总数量:{stat['src_dir_total']},源媒体文件总数量:{stat['src_file_total']}", log_path)
|
||||||
|
write_log(f"目录:成功 {stat['dir_success']},失败 {stat['dir_fail']}", log_path)
|
||||||
|
write_log(f"文件:成功 {stat['file_success']},失败 {stat['file_fail']}", log_path)
|
||||||
|
write_log(f"【校验】预期目录输出={stat['src_dir_total']},实际成功={stat['dir_success']}", log_path)
|
||||||
|
write_log(f"【校验】预期文件输出={stat['src_file_total']},实际成功={stat['file_success']}", log_path)
|
||||||
|
write_log("============================================================", log_path)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,597 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
media_scraper.py —— 自研媒体刮削器(核心库 + 命令行)
|
||||||
|
|
||||||
|
流程:接收一个媒体单元(单个电影文件 / 电影目录 / 剧集目录)
|
||||||
|
1. 从文件名/目录名解析标题、年份、类型(电影/剧集)、季/集
|
||||||
|
2. 查询 TMDB(电影 search/movie,剧集 search/tv)
|
||||||
|
3. 把媒体文件「复制」到成品目录(落库)
|
||||||
|
4. 在成品目录就地生成 Kodi 规范的 nfo + 下载海报/背景图
|
||||||
|
|
||||||
|
命令行用法:
|
||||||
|
./media_scraper.py --source <路径> --dest <成品目录> [--config config.json] [--mock] [--dry-run] [--recurse]
|
||||||
|
|
||||||
|
依赖:requests(TMDB 调用)。TMDB API Key 通过 config.json 或环境变量 TMDB_API_KEY 提供。
|
||||||
|
未配置 Key 时可用 --mock 模式跑通整条管线(用模拟元数据,验证 nfo 生成 + 复制落库)。
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
from datetime import datetime
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 常量与配置
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
VIDEO_EXTS = {".mkv", ".mp4", ".mov", ".avi", ".wmv", ".flv", ".ts", ".webm",
|
||||||
|
".rmvb", ".iso", ".m2ts", ".mts"}
|
||||||
|
SUB_EXTS = {".srt", ".ass", ".sub", ".ssa"}
|
||||||
|
|
||||||
|
TMDB_IMAGE_BASE = "https://image.tmdb.org/t/p/w500"
|
||||||
|
TMDB_IMAGE_ORIG = "https://image.tmdb.org/t/p/original"
|
||||||
|
DEFAULT_LANGUAGE = "zh-CN" # 刮削文案语言,可按需改
|
||||||
|
FALLBACK_LANGUAGE = "en-US"
|
||||||
|
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
"""从 config.json / 环境变量读取配置。"""
|
||||||
|
|
||||||
|
def __init__(self, path=None):
|
||||||
|
self.tmdb_api_key = os.environ.get("TMDB_API_KEY", "")
|
||||||
|
self.language = DEFAULT_LANGUAGE
|
||||||
|
self.mock = False
|
||||||
|
self.timeout = 20
|
||||||
|
if path and os.path.isfile(path):
|
||||||
|
data = json.load(open(path, encoding="utf-8"))
|
||||||
|
self.tmdb_api_key = data.get("tmdb_api_key", self.tmdb_api_key)
|
||||||
|
self.language = data.get("language", self.language)
|
||||||
|
self.mock = data.get("mock", self.mock)
|
||||||
|
self.timeout = data.get("timeout", self.timeout)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 文件名解析
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
def clean_ext(name):
|
||||||
|
return os.path.splitext(name)[1].lower()
|
||||||
|
|
||||||
|
|
||||||
|
def parse_media_name(name):
|
||||||
|
"""从单个文件名或目录名解析媒体信息。
|
||||||
|
|
||||||
|
返回 dict:
|
||||||
|
kind: "movie" | "tv"
|
||||||
|
title: 标题(尽量去除年份/季集标记)
|
||||||
|
year: 年份(int) 或 None
|
||||||
|
season/episode: 剧集时存在
|
||||||
|
"""
|
||||||
|
base = os.path.basename(name)
|
||||||
|
base = os.path.splitext(base)[0]
|
||||||
|
info = {"kind": "movie", "title": base, "year": None,
|
||||||
|
"season": None, "episode": None}
|
||||||
|
|
||||||
|
# 剧集标记:S01E02 / s1e2 / 第01集 / E01 / 第 1 季 第 2 集
|
||||||
|
m = re.search(r"[Ss](\d{1,2})[Ee](\d{1,3})", base) # SxxExx
|
||||||
|
if m:
|
||||||
|
info["kind"] = "tv"
|
||||||
|
info["season"] = int(m.group(1))
|
||||||
|
info["episode"] = int(m.group(2))
|
||||||
|
else:
|
||||||
|
m = re.search(r"第\s*(\d{1,2})\s*[集話话]", base) # 第01集
|
||||||
|
if m:
|
||||||
|
info["kind"] = "tv"
|
||||||
|
info["season"] = 1
|
||||||
|
info["episode"] = int(m.group(1))
|
||||||
|
else:
|
||||||
|
m2 = re.search(r"[Ee](\d{1,3})", base) # E01
|
||||||
|
if m2:
|
||||||
|
info["kind"] = "tv"
|
||||||
|
info["season"] = 1
|
||||||
|
info["episode"] = int(m2.group(1))
|
||||||
|
|
||||||
|
# 年份
|
||||||
|
m = re.search(r"\((\d{4})\)", base) or re.search(r"(\b19\d{2}\b|\b20\d{2}\b)", base)
|
||||||
|
if m:
|
||||||
|
info["year"] = int(m.group(1))
|
||||||
|
base = base.replace(f"({m.group(1)})", "")
|
||||||
|
|
||||||
|
# 去除季集标记,得到标题
|
||||||
|
base = re.sub(r"[Ss]\d{1,2}[Ee]\d{1,3}", "", base)
|
||||||
|
base = re.sub(r"第\s*\d{1,2}\s*[集話话]", "", base)
|
||||||
|
base = re.sub(r"[Ee]\d{1,3}", "", base)
|
||||||
|
base = re.sub(r"\((\d{4})\)", "", base)
|
||||||
|
base = re.sub(r"(\b19\d{2}\b|\b20\d{2}\b)", "", base)
|
||||||
|
base = re.sub(r"[\s._\-]+", " ", base).strip()
|
||||||
|
info["title"] = base if base else info["title"]
|
||||||
|
return info
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# TMDB 客户端
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
class TMDBApi:
|
||||||
|
def __init__(self, config):
|
||||||
|
self.cfg = config
|
||||||
|
self.sess = requests.Session()
|
||||||
|
self.sess.headers.update({
|
||||||
|
"Authorization": f"Bearer {config.tmdb_api_key}",
|
||||||
|
"Content-Type": "application/json;charset=utf-8",
|
||||||
|
})
|
||||||
|
self.base = "https://api.themoviedb.org/3"
|
||||||
|
|
||||||
|
def _get(self, path, params):
|
||||||
|
if not self.cfg.tmdb_api_key:
|
||||||
|
raise RuntimeError("未配置 TMDB API Key(config.json 或环境变量 TMDB_API_KEY)")
|
||||||
|
r = self.sess.get(f"{self.base}/{path}", params=params, timeout=self.cfg.timeout)
|
||||||
|
r.raise_for_status()
|
||||||
|
return r.json()
|
||||||
|
|
||||||
|
def search(self, kind, title, year=None):
|
||||||
|
path = "search/movie" if kind == "movie" else "search/tv"
|
||||||
|
params = {"query": title, "language": self.cfg.language}
|
||||||
|
if year:
|
||||||
|
params["year" if kind == "movie" else "first_air_date_year"] = year
|
||||||
|
data = self._get(path, params)
|
||||||
|
results = data.get("results") or []
|
||||||
|
# 优先标题精确匹配 + 年份匹配
|
||||||
|
exact = [r for r in results
|
||||||
|
if r.get("title" if kind == "movie" else "name", "").lower()
|
||||||
|
== title.lower()]
|
||||||
|
if year and exact:
|
||||||
|
exact = [r for r in exact
|
||||||
|
if str(r.get("release_date" if kind == "movie" else "first_air_date", "") or "")
|
||||||
|
.startswith(str(year))]
|
||||||
|
if exact:
|
||||||
|
return exact[0]
|
||||||
|
if results:
|
||||||
|
return results[0]
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_details(self, kind, tmdb_id):
|
||||||
|
path = f"movie/{tmdb_id}" if kind == "movie" else f"tv/{tmdb_id}"
|
||||||
|
return self._get(path, {"language": self.cfg.language})
|
||||||
|
|
||||||
|
def get_credits(self, kind, tmdb_id):
|
||||||
|
"""电影 cast/crew;剧集 cast。用于 nfo 的演员、导演、制片厂字段。"""
|
||||||
|
path = f"movie/{tmdb_id}/credits" if kind == "movie" else f"tv/{tmdb_id}/credits"
|
||||||
|
return self._get(path, {"language": self.cfg.language})
|
||||||
|
|
||||||
|
def image_url(self, path, size="w500"):
|
||||||
|
if not path:
|
||||||
|
return None
|
||||||
|
base = TMDB_IMAGE_BASE if size == "w500" else TMDB_IMAGE_ORIG
|
||||||
|
return f"{base}{path}"
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# nfo 生成
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
def _esc(s):
|
||||||
|
if s is None:
|
||||||
|
return ""
|
||||||
|
return str(s).replace("&", "&").replace("<", "<").replace(">", ">")
|
||||||
|
|
||||||
|
|
||||||
|
def _txt(node, tag, value):
|
||||||
|
if value is not None and str(value).strip():
|
||||||
|
ET.SubElement(node, tag).text = str(value).strip()
|
||||||
|
|
||||||
|
|
||||||
|
def build_movie_nfo(meta):
|
||||||
|
"""meta: TMDB movie details 的整理字段。返回 movie.nfo XML 字符串。"""
|
||||||
|
root = ET.Element("movie")
|
||||||
|
_txt(root, "title", meta.get("title"))
|
||||||
|
_txt(root, "originaltitle", meta.get("original_title"))
|
||||||
|
_txt(root, "year", meta.get("year"))
|
||||||
|
_txt(root, "rating", meta.get("vote_average"))
|
||||||
|
_txt(root, "votes", meta.get("vote_count"))
|
||||||
|
_txt(root, "runtime", meta.get("runtime"))
|
||||||
|
_txt(root, "plot", meta.get("overview"))
|
||||||
|
_txt(root, "tagline", meta.get("tagline"))
|
||||||
|
_txt(root, "premiered", meta.get("release_date"))
|
||||||
|
_txt(root, "release", meta.get("release_date"))
|
||||||
|
for g in meta.get("genres", []) or []:
|
||||||
|
_txt(root, "genre", g)
|
||||||
|
for d in meta.get("directors", []) or []:
|
||||||
|
_txt(root, "director", d)
|
||||||
|
for s in meta.get("studios", []) or []:
|
||||||
|
_txt(root, "studio", s)
|
||||||
|
_txt(root, "mpaa", meta.get("certification"))
|
||||||
|
if meta.get("tmdb_id"):
|
||||||
|
ET.SubElement(root, "uniqueid", attrib={"type": "tmdb"}).text = str(meta["tmdb_id"])
|
||||||
|
if meta.get("imdb_id"):
|
||||||
|
ET.SubElement(root, "uniqueid", attrib={"type": "imdb"}).text = str(meta["imdb_id"])
|
||||||
|
if meta.get("poster_path"):
|
||||||
|
ET.SubElement(root, "thumb").text = TMDB_IMAGE_BASE + meta["poster_path"]
|
||||||
|
if meta.get("fanart_path"):
|
||||||
|
f = ET.SubElement(root, "fanart")
|
||||||
|
ET.SubElement(f, "thumb").text = TMDB_IMAGE_ORIG + meta["fanart_path"]
|
||||||
|
for a in meta.get("cast", []) or []:
|
||||||
|
ac = ET.SubElement(root, "actor")
|
||||||
|
_txt(ac, "name", a.get("name"))
|
||||||
|
_txt(ac, "role", a.get("role"))
|
||||||
|
if a.get("thumb"):
|
||||||
|
_txt(ac, "thumb", TMDB_IMAGE_BASE + a["thumb"])
|
||||||
|
return '<?xml version="1.0" encoding="UTF-8"?>\n' + ET.tostring(root, encoding="unicode")
|
||||||
|
|
||||||
|
|
||||||
|
def build_tvshow_nfo(meta):
|
||||||
|
root = ET.Element("tvshow")
|
||||||
|
_txt(root, "title", meta.get("name"))
|
||||||
|
_txt(root, "originaltitle", meta.get("original_name"))
|
||||||
|
_txt(root, "year", meta.get("year"))
|
||||||
|
_txt(root, "rating", meta.get("vote_average"))
|
||||||
|
_txt(root, "votes", meta.get("vote_count"))
|
||||||
|
_txt(root, "plot", meta.get("overview"))
|
||||||
|
_txt(root, "premiered", meta.get("first_air_date"))
|
||||||
|
_txt(root, "status", meta.get("status"))
|
||||||
|
for g in meta.get("genres", []) or []:
|
||||||
|
_txt(root, "genre", g)
|
||||||
|
for s in meta.get("studios", []) or []:
|
||||||
|
_txt(root, "studio", s)
|
||||||
|
if meta.get("tmdb_id"):
|
||||||
|
ET.SubElement(root, "uniqueid", attrib={"type": "tmdb"}).text = str(meta["tmdb_id"])
|
||||||
|
if meta.get("imdb_id"):
|
||||||
|
ET.SubElement(root, "uniqueid", attrib={"type": "imdb"}).text = str(meta["imdb_id"])
|
||||||
|
if meta.get("poster_path"):
|
||||||
|
ET.SubElement(root, "thumb").text = TMDB_IMAGE_BASE + meta["poster_path"]
|
||||||
|
for a in meta.get("cast", []) or []:
|
||||||
|
ac = ET.SubElement(root, "actor")
|
||||||
|
_txt(ac, "name", a.get("name"))
|
||||||
|
_txt(ac, "role", a.get("role"))
|
||||||
|
if a.get("thumb"):
|
||||||
|
_txt(ac, "thumb", TMDB_IMAGE_BASE + a["thumb"])
|
||||||
|
return '<?xml version="1.0" encoding="UTF-8"?>\n' + ET.tostring(root, encoding="unicode")
|
||||||
|
|
||||||
|
|
||||||
|
def build_episode_nfo(meta):
|
||||||
|
root = ET.Element("episodedetails")
|
||||||
|
_txt(root, "title", meta.get("name"))
|
||||||
|
_txt(root, "season", meta.get("season_number"))
|
||||||
|
_txt(root, "episode", meta.get("episode_number"))
|
||||||
|
_txt(root, "plot", meta.get("overview"))
|
||||||
|
_txt(root, "aired", meta.get("air_date"))
|
||||||
|
_txt(root, "rating", meta.get("vote_average"))
|
||||||
|
if meta.get("still_path"):
|
||||||
|
ET.SubElement(root, "thumb").text = TMDB_IMAGE_BASE + meta["still_path"]
|
||||||
|
return '<?xml version="1.0" encoding="UTF-8"?>\n' + ET.tostring(root, encoding="unicode")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 刮削器
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
class Scraper:
|
||||||
|
def __init__(self, config, dest, source_root=None, dry_run=False, log=None):
|
||||||
|
self.cfg = config
|
||||||
|
self.dest = os.path.abspath(dest)
|
||||||
|
self.source_root = os.path.abspath(source_root) if source_root else None
|
||||||
|
self.dry_run = dry_run
|
||||||
|
self.log = log or (lambda msg: print(msg))
|
||||||
|
self.api = None if config.mock else TMDBApi(config)
|
||||||
|
|
||||||
|
def logi(self, msg):
|
||||||
|
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
self.log(f"[{ts}] {msg}")
|
||||||
|
|
||||||
|
# ---- 复制媒体到成品目录 ----
|
||||||
|
def _relative(self, path):
|
||||||
|
"""以源根为基准计算相对路径;不在源根下则退回 basename。"""
|
||||||
|
path = os.path.abspath(path)
|
||||||
|
if self.source_root and os.path.commonpath([path, self.source_root]) == self.source_root:
|
||||||
|
return os.path.relpath(path, self.source_root)
|
||||||
|
return os.path.basename(path)
|
||||||
|
|
||||||
|
def _copy_media(self, src_path, rel_src):
|
||||||
|
"""把源媒体文件/目录复制到成品目录,返回成品里的完整路径。
|
||||||
|
|
||||||
|
安全保护:目标路径绝不允许等于源路径,否则直接报错,绝不误删源。
|
||||||
|
"""
|
||||||
|
dst = os.path.join(self.dest, rel_src)
|
||||||
|
if os.path.abspath(dst) == os.path.abspath(src_path):
|
||||||
|
raise RuntimeError(f"目标路径与源路径相同,已终止以防误删: {src_path}")
|
||||||
|
if self.dry_run:
|
||||||
|
self.logi(f"[DRY] 将复制 {src_path} -> {dst}")
|
||||||
|
return dst
|
||||||
|
os.makedirs(os.path.dirname(dst), exist_ok=True)
|
||||||
|
if os.path.isdir(src_path):
|
||||||
|
if os.path.exists(dst):
|
||||||
|
shutil.rmtree(dst)
|
||||||
|
shutil.copytree(src_path, dst)
|
||||||
|
else:
|
||||||
|
shutil.copy2(src_path, dst)
|
||||||
|
return dst
|
||||||
|
|
||||||
|
# ---- 电影刮削(单文件或电影目录)----
|
||||||
|
def scrape_movie(self, src):
|
||||||
|
info = parse_media_name(src)
|
||||||
|
rel = self._relative(src)
|
||||||
|
dst = self._copy_media(src, rel)
|
||||||
|
base = os.path.basename(dst)
|
||||||
|
base_noext = os.path.splitext(base)[0]
|
||||||
|
|
||||||
|
if self.cfg.mock:
|
||||||
|
meta = self._mock_movie_meta(info)
|
||||||
|
else:
|
||||||
|
found = self.api.search("movie", info["title"], info.get("year"))
|
||||||
|
if not found:
|
||||||
|
raise RuntimeError(f"TMDB 未匹配到电影: {info['title']}")
|
||||||
|
details = self.api.get_details("movie", found["id"])
|
||||||
|
try:
|
||||||
|
credits = self.api.get_credits("movie", found["id"])
|
||||||
|
except Exception:
|
||||||
|
credits = {}
|
||||||
|
meta = self._shape_movie_meta(details, credits)
|
||||||
|
|
||||||
|
if self.dry_run:
|
||||||
|
self.logi(f"[DRY] 电影 {base} 匹配 TMDB id={meta.get('tmdb_id')} "
|
||||||
|
f"《{meta.get('title')}》({meta.get('year')})")
|
||||||
|
return
|
||||||
|
|
||||||
|
media_file = self._find_media_file(dst)
|
||||||
|
out_dir = os.path.dirname(media_file) if media_file else dst
|
||||||
|
nfo_name = os.path.splitext(os.path.basename(media_file))[0] if media_file else base_noext
|
||||||
|
nfo_path = os.path.join(out_dir, nfo_name + ".nfo")
|
||||||
|
with open(nfo_path, "w", encoding="utf-8") as f:
|
||||||
|
f.write(build_movie_nfo(meta))
|
||||||
|
self.logi(f"生成 {nfo_path}")
|
||||||
|
|
||||||
|
self._download_art(meta, out_dir, nfo_name, base_noext)
|
||||||
|
|
||||||
|
# ---- 剧集刮削(剧集目录)----
|
||||||
|
def scrape_tv(self, src):
|
||||||
|
info = parse_media_name(src)
|
||||||
|
rel = self._relative(src)
|
||||||
|
dst = self._copy_media(src, rel)
|
||||||
|
|
||||||
|
if self.cfg.mock:
|
||||||
|
meta = self._mock_tv_meta(info)
|
||||||
|
else:
|
||||||
|
found = self.api.search("tv", info["title"], info.get("year"))
|
||||||
|
if not found:
|
||||||
|
raise RuntimeError(f"TMDB 未匹配到剧集: {info['title']}")
|
||||||
|
details = self.api.get_details("tv", found["id"])
|
||||||
|
try:
|
||||||
|
credits = self.api.get_credits("tv", found["id"])
|
||||||
|
except Exception:
|
||||||
|
credits = {}
|
||||||
|
meta = self._shape_tv_meta(details, credits)
|
||||||
|
|
||||||
|
if self.dry_run:
|
||||||
|
self.logi(f"[DRY] 剧集 {os.path.basename(src)} 匹配 TMDB id={meta.get('tmdb_id')} "
|
||||||
|
f"《{meta.get('name')}》")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 剧集目录:在目录根生成 tvshow.nfo + poster;对每个视频文件生成 {文件}.nfo
|
||||||
|
root_dir = dst if os.path.isdir(dst) else os.path.dirname(dst)
|
||||||
|
with open(os.path.join(root_dir, "tvshow.nfo"), "w", encoding="utf-8") as f:
|
||||||
|
f.write(build_tvshow_nfo(meta))
|
||||||
|
self.logi(f"生成 {root_dir}/tvshow.nfo")
|
||||||
|
self._download_art(meta, root_dir, "poster", "poster")
|
||||||
|
|
||||||
|
for vf in self._find_video_files(root_dir):
|
||||||
|
if info.get("season") is not None and info.get("episode") is not None:
|
||||||
|
ep_meta = self._episode_meta(meta, info["season"], info["episode"])
|
||||||
|
else:
|
||||||
|
ep_meta = self._episode_meta_from_filename(vf)
|
||||||
|
vbase = os.path.splitext(os.path.basename(vf))[0]
|
||||||
|
with open(os.path.join(root_dir, vbase + ".nfo"), "w", encoding="utf-8") as f:
|
||||||
|
f.write(build_episode_nfo(ep_meta))
|
||||||
|
self.logi(f"生成 {os.path.join(root_dir, vbase + '.nfo')}")
|
||||||
|
|
||||||
|
# ---- 工具方法 ----
|
||||||
|
def _find_media_file(self, path):
|
||||||
|
if os.path.isfile(path):
|
||||||
|
return path
|
||||||
|
for root, _, files in os.walk(path):
|
||||||
|
for fn in sorted(files):
|
||||||
|
if clean_ext(fn) in VIDEO_EXTS:
|
||||||
|
return os.path.join(root, fn)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _find_video_files(self, root):
|
||||||
|
out = []
|
||||||
|
for root2, _, files in os.walk(root):
|
||||||
|
for fn in sorted(files):
|
||||||
|
if clean_ext(fn) in VIDEO_EXTS:
|
||||||
|
out.append(os.path.join(root2, fn))
|
||||||
|
return out
|
||||||
|
|
||||||
|
def _download_art(self, meta, out_dir, prefix, poster_prefix=None):
|
||||||
|
"""下载海报/背景图(Kodi/Emby 兼容命名)。"""
|
||||||
|
poster_prefix = poster_prefix or prefix
|
||||||
|
poster = meta.get("poster_path")
|
||||||
|
fanart = meta.get("fanart_path")
|
||||||
|
if poster:
|
||||||
|
url = TMDB_IMAGE_BASE + poster
|
||||||
|
self._dl(url, os.path.join(out_dir, f"{poster_prefix}-poster.jpg"))
|
||||||
|
if fanart:
|
||||||
|
url = TMDB_IMAGE_ORIG + fanart
|
||||||
|
self._dl(url, os.path.join(out_dir, f"{prefix}-fanart.jpg"))
|
||||||
|
|
||||||
|
def _dl(self, url, out_path):
|
||||||
|
if self.dry_run or self.cfg.mock:
|
||||||
|
self.logi(f"[DRY/MOCK] 下载图片 {url} -> {out_path}")
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
r = requests.get(url, timeout=self.cfg.timeout)
|
||||||
|
r.raise_for_status()
|
||||||
|
with open(out_path, "wb") as f:
|
||||||
|
f.write(r.content)
|
||||||
|
self.logi(f"下载图片 {out_path}")
|
||||||
|
except Exception as e:
|
||||||
|
self.logi(f"下载图片失败 {url}: {e}")
|
||||||
|
|
||||||
|
# ---- meta 整形 ----
|
||||||
|
def _shape_movie_meta(self, d, credits=None):
|
||||||
|
credits = credits or {}
|
||||||
|
return {
|
||||||
|
"title": d.get("title") or d.get("original_title"),
|
||||||
|
"original_title": d.get("original_title"),
|
||||||
|
"year": (d.get("release_date") or "")[:4],
|
||||||
|
"vote_average": d.get("vote_average"),
|
||||||
|
"vote_count": d.get("vote_count"),
|
||||||
|
"runtime": d.get("runtime"),
|
||||||
|
"overview": d.get("overview"),
|
||||||
|
"tagline": d.get("tagline"),
|
||||||
|
"release_date": d.get("release_date"),
|
||||||
|
"genres": [g.get("name") for g in (d.get("genres") or [])],
|
||||||
|
"certification": None,
|
||||||
|
"tmdb_id": d.get("id"),
|
||||||
|
"imdb_id": d.get("imdb_id"),
|
||||||
|
"poster_path": d.get("poster_path"),
|
||||||
|
"fanart_path": (d.get("backdrop_path")),
|
||||||
|
"directors": [c.get("name") for c in (credits.get("crew") or [])
|
||||||
|
if c.get("job") == "Director"][:3],
|
||||||
|
"studios": [c.get("name") for c in (d.get("production_companies") or [])],
|
||||||
|
"cast": [{"name": c.get("name"), "role": c.get("character"),
|
||||||
|
"thumb": c.get("profile_path")}
|
||||||
|
for c in (credits.get("cast") or [])[:12]],
|
||||||
|
}
|
||||||
|
|
||||||
|
def _shape_tv_meta(self, d, credits=None):
|
||||||
|
credits = credits or {}
|
||||||
|
return {
|
||||||
|
"name": d.get("name") or d.get("original_name"),
|
||||||
|
"original_name": d.get("original_name"),
|
||||||
|
"year": (d.get("first_air_date") or "")[:4],
|
||||||
|
"vote_average": d.get("vote_average"),
|
||||||
|
"vote_count": d.get("vote_count"),
|
||||||
|
"overview": d.get("overview"),
|
||||||
|
"first_air_date": d.get("first_air_date"),
|
||||||
|
"status": d.get("status"),
|
||||||
|
"genres": [g.get("name") for g in (d.get("genres") or [])],
|
||||||
|
"tmdb_id": d.get("id"),
|
||||||
|
"imdb_id": None,
|
||||||
|
"poster_path": d.get("poster_path"),
|
||||||
|
"fanart_path": (d.get("backdrop_path")),
|
||||||
|
"studios": [c.get("name") for c in (d.get("production_companies") or [])],
|
||||||
|
"cast": [{"name": c.get("name"), "role": c.get("character"),
|
||||||
|
"thumb": c.get("profile_path")}
|
||||||
|
for c in (credits.get("cast") or [])[:12]],
|
||||||
|
}
|
||||||
|
|
||||||
|
def _episode_meta(self, tv_meta, season, episode):
|
||||||
|
return {
|
||||||
|
"name": f"第 {episode} 集",
|
||||||
|
"season_number": season,
|
||||||
|
"episode_number": episode,
|
||||||
|
"overview": None,
|
||||||
|
"air_date": None,
|
||||||
|
"vote_average": None,
|
||||||
|
"still_path": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _episode_meta_from_filename(self, vf):
|
||||||
|
info = parse_media_name(vf)
|
||||||
|
return self._episode_meta({}, info.get("season") or 1, info.get("episode") or 1)
|
||||||
|
|
||||||
|
# ---- mock 元数据(无 Key 时验证管线用)----
|
||||||
|
def _mock_movie_meta(self, info):
|
||||||
|
return {
|
||||||
|
"title": info["title"], "original_title": info["title"],
|
||||||
|
"year": info.get("year") or 2024, "vote_average": 8.5,
|
||||||
|
"vote_count": 100, "runtime": 120, "overview": f"(MOCK)电影《{info['title']}》简介",
|
||||||
|
"tagline": "", "release_date": f"{info.get('year') or 2024}-01-01",
|
||||||
|
"genres": ["剧情"], "certification": None,
|
||||||
|
"tmdb_id": 1000, "imdb_id": "tt0000000",
|
||||||
|
"poster_path": None, "fanart_path": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _mock_tv_meta(self, info):
|
||||||
|
return {
|
||||||
|
"name": info["title"], "original_name": info["title"],
|
||||||
|
"year": info.get("year") or 2024, "vote_average": 8.8,
|
||||||
|
"vote_count": 200, "overview": f"(MOCK)剧集《{info['title']}》简介",
|
||||||
|
"first_air_date": f"{info.get('year') or 2024}-01-01",
|
||||||
|
"status": "Returning Series", "genres": ["剧情"],
|
||||||
|
"tmdb_id": 2000, "imdb_id": None,
|
||||||
|
"poster_path": None, "fanart_path": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 命令行入口
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
def scan_and_scrape(source, dest, scraper):
|
||||||
|
"""处理一个源路径:文件直接刮,目录则识别为电影/剧集目录。"""
|
||||||
|
source = os.path.abspath(source)
|
||||||
|
if os.path.isfile(source):
|
||||||
|
info = parse_media_name(source)
|
||||||
|
if info["kind"] == "tv":
|
||||||
|
scraper.scrape_tv(source)
|
||||||
|
else:
|
||||||
|
scraper.scrape_movie(source)
|
||||||
|
elif os.path.isdir(source):
|
||||||
|
# 判断是剧集目录(含 SxxExx / 季结构)还是电影目录
|
||||||
|
vids = [f for f in _walk_files(source) if clean_ext(f) in VIDEO_EXTS]
|
||||||
|
tv_mark = any(re.search(r"[Ss]\d{1,2}[Ee]\d{1,3}|第\s*\d{1,2}\s*[集話话]", f)
|
||||||
|
for f in _walk_files(source))
|
||||||
|
subdir_seasons = any(re.match(r"[Ss]eason\s*\d+|第\s*\d+\s*季", d)
|
||||||
|
for d in os.listdir(source))
|
||||||
|
if tv_mark or subdir_seasons or len(vids) > 1:
|
||||||
|
scraper.scrape_tv(source)
|
||||||
|
else:
|
||||||
|
scraper.scrape_movie(source)
|
||||||
|
else:
|
||||||
|
raise RuntimeError(f"源路径不存在: {source}")
|
||||||
|
|
||||||
|
|
||||||
|
def _walk_files(root):
|
||||||
|
out = []
|
||||||
|
for r, _, files in os.walk(root):
|
||||||
|
for fn in files:
|
||||||
|
out.append(os.path.join(r, fn))
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
ap = argparse.ArgumentParser(description="自研媒体刮削器(TMDB)")
|
||||||
|
ap.add_argument("--source", required=True, help="媒体文件/目录(可重复,或 --recurse 扫整目录)")
|
||||||
|
ap.add_argument("--dest", required=True, help="成品落库目录")
|
||||||
|
ap.add_argument("--config", default=None, help="config.json 路径")
|
||||||
|
ap.add_argument("--mock", action="store_true", help="无 Key 时用模拟元数据跑通管线")
|
||||||
|
ap.add_argument("--dry-run", action="store_true", help="只打印计划不落盘")
|
||||||
|
ap.add_argument("--recurse", action="store_true", help="递归处理 --source 下所有新媒体单元")
|
||||||
|
ap.add_argument("--log", default=None, help="日志文件路径(默认 stdout)")
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
cfg = Config(args.config)
|
||||||
|
if args.mock:
|
||||||
|
cfg.mock = True
|
||||||
|
|
||||||
|
log = (lambda msg: open(args.log, "a", encoding="utf-8").write(msg + "\n")
|
||||||
|
and print(msg)) if args.log else print
|
||||||
|
if args.recurse:
|
||||||
|
source_root = os.path.abspath(args.source)
|
||||||
|
else:
|
||||||
|
source_root = os.path.abspath(os.path.dirname(args.source))
|
||||||
|
scraper = Scraper(cfg, args.dest, source_root=source_root,
|
||||||
|
dry_run=args.dry_run, log=log)
|
||||||
|
os.makedirs(args.dest, exist_ok=True)
|
||||||
|
|
||||||
|
if args.recurse:
|
||||||
|
targets = _walk_files(args.source)
|
||||||
|
# 只处理视频文件,交给 parse 判定
|
||||||
|
targets = [t for t in targets if clean_ext(t) in VIDEO_EXTS]
|
||||||
|
else:
|
||||||
|
targets = [args.source]
|
||||||
|
|
||||||
|
for t in targets:
|
||||||
|
try:
|
||||||
|
scan_and_scrape(t, args.dest, scraper)
|
||||||
|
except Exception as e:
|
||||||
|
scraper.logi(f"跳过 {t}: {e}")
|
||||||
|
|
||||||
|
scraper.logi("全部处理完成")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# =====================================================================
|
||||||
|
# nas-tools (NAStool) 部署配置 —— 飞牛 fnOS Docker
|
||||||
|
# 用途:监听「清理后媒体目录」→ 自动识别并刮削 → 复制落库到「成品媒体库」
|
||||||
|
# 用法:飞牛 → 应用中心/Docker → 添加项目(Compose) → 粘贴本文件 → 启动
|
||||||
|
# 说明:把下面三个 /vol1/... 路径改成你飞牛上的真实路径再粘贴
|
||||||
|
# =====================================================================
|
||||||
|
services:
|
||||||
|
nas-tools:
|
||||||
|
image: jxxghp/nas-tools:latest # 也可换 hsuyelin/nas-tools:latest 或 diluka/nas-tools:2.9.1
|
||||||
|
container_name: nas-tools
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3000:3000" # Web 管理界面
|
||||||
|
volumes:
|
||||||
|
- /vol1/docker/nas-tools/config:/config # 配置持久化(必须)
|
||||||
|
- /vol1/media/cleaned:/media/source # 【你的清理后媒体目录】(media_final.py 的输出)
|
||||||
|
- /vol1/media/library:/media/library # 【成品媒体库】(刮削+复制后的落库目录)
|
||||||
|
environment:
|
||||||
|
- PUID=0
|
||||||
|
- PGID=0
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
- NASTOOL_AUTO_UPDATE=false # 关闭自动更新,避免拉不动 github
|
||||||
|
- NASTOOL_CN_UPDATE=true # 使用国内源加速依赖安装
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# nas-tools 部署与配置说明(飞牛 fnOS)
|
||||||
|
|
||||||
|
目标流程:`media_final.py` 清理后的媒体目录 → nas-tools 自动监听 → 刮削 → **复制**落库到成品媒体库。
|
||||||
|
|
||||||
|
## 一、部署(飞牛 Docker)
|
||||||
|
|
||||||
|
1. 飞牛后台 → **应用中心 → Docker**(或直接 Docker 应用)→ 新建项目 / Compose。
|
||||||
|
2. 粘贴 `nastools-docker-compose.yml` 内容,把 `/vol1/media/cleaned`、`/vol1/media/library`、`/vol1/docker/nas-tools/config` 三处改成你飞牛上的真实路径。
|
||||||
|
3. 保存并启动,等待镜像拉取完成。
|
||||||
|
4. 浏览器打开 `http://<飞牛IP>:3000`,默认账号 `admin` / 密码 `password`(首次登录后改掉)。
|
||||||
|
|
||||||
|
> 镜像拉不动时:确认环境变量 `NASTOOL_AUTO_UPDATE=false`、`NASTOOL_CN_UPDATE=true` 已设置。
|
||||||
|
|
||||||
|
## 二、Web 里必须配的点
|
||||||
|
|
||||||
|
| 配置项 | 位置 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| **TMDB API Key** | 设置 → 媒体库 | 必填,TMDB 官网免费申请(themoviedb.org/settings/api)。没有它无法刮削海报/简介 |
|
||||||
|
| **目录同步:复制模式** | 设置 → 目录同步 | 添加「源目录 = /media/source、目的目录 = /media/library」,传输方式选**复制**(对应你定的落库方式) |
|
||||||
|
| **媒体库识别** | 设置 → 媒体库 | 电影/剧集命名规则保持默认即可,识别率高 |
|
||||||
|
| **联动 Jellyfin/Emby** | 设置 → 媒体服务器 | 可选。填入 Jellyfin/Emby 地址和 API Key,nas-tools 刮削完会通知它刷新海报墙 |
|
||||||
|
|
||||||
|
## 三、关键行为确认
|
||||||
|
|
||||||
|
- nas-tools **默认会监控源目录**,文件新增/变更后自动识别媒体真实名称 → 刮削 → 复制到成品目录。
|
||||||
|
- 「复制」= 源目录保留,成品目录得到一份完整的刮削后副本(含 nfo、海报、背景图)。
|
||||||
|
- 如果你想省空间、源和成品在同一文件系统,可把「复制」换成「硬链接」——效果等同但几乎不占额外空间(自愿切换)。
|
||||||
|
|
||||||
|
## 四、验证
|
||||||
|
|
||||||
|
- 往 `/vol1/media/cleaned` 丢一个清理后的影片,几秒后到 `/vol1/media/library` 检查是否出现了刮削好的副本(含 `.nfo`、`-poster.jpg`)。
|
||||||
|
- 若配合 Jellyfin/Emby,刷新后应出现海报墙。
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
- **海报刮不出来**:多半是 TMDB Key 没配,或无法访问 TMDB(国内网络需在媒体库设置里配代理/TMDB 备用源)。
|
||||||
|
- **没自动触发**:确认源目录路径和目录同步里的监控路径一致;看容器日志 `docker logs nas-tools`。
|
||||||
BIN
Binary file not shown.
@@ -0,0 +1,124 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
from datetime import datetime
|
||||||
|
# ====================== 【配置区】 ======================
|
||||||
|
MEDIA_FOLDER = "/Volumes/JoyDisk/myMedia/olstrms/电影/未分类/2024"
|
||||||
|
DRY_RUN = True # True=预览不修改;False=实际重命名
|
||||||
|
SKIP_PROCESSED = False
|
||||||
|
LOG_FILE = "./rename_log.txt"
|
||||||
|
|
||||||
|
# 清洗规则
|
||||||
|
RULES = [
|
||||||
|
(r"^[A-Za-z] ", ""), #1.移除开头单个字母+空格
|
||||||
|
(r"\[.*?\]", ""), #2.移除英文方括号及内部内容
|
||||||
|
(r"【.*?】", ""), #3.移除中文【】及内部内容
|
||||||
|
(r"丨", ""), #清除汉字竖线 丨
|
||||||
|
(r"\b(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|中英双语|双语字幕)\b", "", re.IGNORECASE),
|
||||||
|
(r"\.+", ""), #删除连续的点
|
||||||
|
(r"\s", ""), #删除全部空格
|
||||||
|
# 保留:汉字、半角英文、数字、半角 () . : + -
|
||||||
|
(r"[^\u4e00-\u9fa5a-zA-Z0-9().:+-]", ""),
|
||||||
|
]
|
||||||
|
# 加入strm
|
||||||
|
ALLOW_EXT = {".mkv", ".mp4", ".mov", ".srt", ".ass", ".sub", ".strm"}
|
||||||
|
# =======================================================
|
||||||
|
|
||||||
|
def clean_filename(name: str) -> str:
|
||||||
|
name_no_ext, ext = os.path.splitext(name)
|
||||||
|
# 全角转半角
|
||||||
|
def full2half(s):
|
||||||
|
result = []
|
||||||
|
for char in s:
|
||||||
|
code = ord(char)
|
||||||
|
if code == 12288:
|
||||||
|
char = chr(32)
|
||||||
|
elif 65281 <= code <= 65374:
|
||||||
|
char = chr(code - 65248)
|
||||||
|
result.append(char)
|
||||||
|
return "".join(result)
|
||||||
|
name_no_ext = full2half(name_no_ext)
|
||||||
|
|
||||||
|
for item in RULES:
|
||||||
|
if len(item) == 3:
|
||||||
|
pat, repl, flag = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext, flags=flag)
|
||||||
|
else:
|
||||||
|
pat, repl = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext)
|
||||||
|
name_no_ext = name_no_ext.strip()
|
||||||
|
return name_no_ext + ext
|
||||||
|
|
||||||
|
def write_log(msg: str):
|
||||||
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
line = f"[{now}] {msg}"
|
||||||
|
print(line)
|
||||||
|
# 增加flush,强制写入磁盘,解决日志文件不更新
|
||||||
|
with open(LOG_FILE, "a", encoding="utf-8") as f:
|
||||||
|
f.write(line + "\n")
|
||||||
|
f.flush()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# 每次运行前清空日志文件
|
||||||
|
with open(LOG_FILE, "w", encoding="utf-8") as f:
|
||||||
|
f.flush()
|
||||||
|
|
||||||
|
write_log("===== 文件名+文件夹清洗(移除开头A 中文片名前缀) =====")
|
||||||
|
write_log(f"根目录:{MEDIA_FOLDER}")
|
||||||
|
write_log(f"预览模式 DRY_RUN = {DRY_RUN}")
|
||||||
|
|
||||||
|
file_rename_list = []
|
||||||
|
dir_rename_list = []
|
||||||
|
total_scan_dirs = 0
|
||||||
|
total_all_files = 0 # 全部扫描到的文件(所有后缀)
|
||||||
|
total_media_files = 0 # 媒体文件(ALLOW_EXT后缀)
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk(MEDIA_FOLDER, topdown=False):
|
||||||
|
total_scan_dirs += 1
|
||||||
|
for fname in files:
|
||||||
|
total_all_files +=1 # 任何文件都计入总扫描文件
|
||||||
|
ext = os.path.splitext(fname)[1].lower()
|
||||||
|
if ext in ALLOW_EXT:
|
||||||
|
total_media_files += 1
|
||||||
|
# 调试:打印所有扫描到的媒体文件(无论是否修改)
|
||||||
|
write_log(f"[扫描媒体] {fname}")
|
||||||
|
new_name = clean_filename(fname)
|
||||||
|
if new_name != fname:
|
||||||
|
if SKIP_PROCESSED and re.search(r"\(\d{4}\)", new_name):
|
||||||
|
write_log(f"【跳过文件】{fname},检测年份括号")
|
||||||
|
continue
|
||||||
|
old_path = os.path.join(root, fname)
|
||||||
|
new_path = os.path.join(root, new_name)
|
||||||
|
file_rename_list.append((old_path, new_path))
|
||||||
|
write_log(f"待修改文件-> {fname} → {new_name}")
|
||||||
|
|
||||||
|
# 处理文件夹
|
||||||
|
for dname in dirs:
|
||||||
|
new_name = clean_filename(dname)
|
||||||
|
if new_name != dname:
|
||||||
|
if SKIP_PROCESSED and re.search(r"\(\d{4}\)", new_name):
|
||||||
|
write_log(f"【跳过文件夹】{dname},检测年份括号")
|
||||||
|
continue
|
||||||
|
old_path = os.path.join(root, dname)
|
||||||
|
new_path = os.path.join(root, new_name)
|
||||||
|
dir_rename_list.append((old_path, new_name))
|
||||||
|
write_log(f"待修改文件夹-> {dname} → {new_name}")
|
||||||
|
|
||||||
|
# ========== 执行阶段 ==========
|
||||||
|
if not DRY_RUN:
|
||||||
|
# 先文件
|
||||||
|
for old, new in file_rename_list:
|
||||||
|
try:
|
||||||
|
os.rename(old, new)
|
||||||
|
except Exception as e:
|
||||||
|
write_log(f"【文件重命名失败】{old} -> {new} | 错误:{e}")
|
||||||
|
# 后文件夹
|
||||||
|
for old, new in dir_rename_list:
|
||||||
|
try:
|
||||||
|
os.rename(old, new)
|
||||||
|
except Exception as e:
|
||||||
|
write_log(f"【文件夹重命名失败】{old} -> {new} | 错误:{e}")
|
||||||
|
|
||||||
|
# 最终汇总输出
|
||||||
|
write_log(f"任务完成,总扫描目录:{total_scan_dirs},待修改文件夹:{len(dir_rename_list)}")
|
||||||
|
write_log(f"总扫描文件:{total_all_files},媒体文件:{total_media_files},待修改文件:{len(file_rename_list)}")
|
||||||
|
write_log("============================================================")
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# ====================== 【配置区,请修改】 ======================
|
||||||
|
MEDIA_FOLDER = "/Volumes/JoyDisk/myMedia/olstrms/电影/未分类/2025" # Mac挂载NAS路径
|
||||||
|
# MEDIA_FOLDER = "/media/movies" # 飞牛容器内运行用这个
|
||||||
|
|
||||||
|
DRY_RUN = True # True=预览,不修改;确认无误改为False执行改名
|
||||||
|
SKIP_PROCESSED = False # True=跳过已处理(文件名含(20xx)年份)
|
||||||
|
LOG_FILE = "./rename_log.txt"
|
||||||
|
# =================================================================
|
||||||
|
|
||||||
|
# 清洗正则规则(文件夹、文件共用一套)
|
||||||
|
RULES = [
|
||||||
|
(r"^[A-Za-z] ", ""), # 【新增】移除开头单个英文字母+空格:A 流浪地球 → 流浪地球
|
||||||
|
(r"(?<=[a-zA-Z0-9])\.(?=[a-zA-Z0-9])", " "), # Dune.Part → Dune Part
|
||||||
|
(r"\[.*?\]", ""), # 删除全部 [xxx] 方括号内容
|
||||||
|
(r"\s*(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD)\b", ""),
|
||||||
|
(r"\.+", " "), # 剩下连续多个点替换成空格
|
||||||
|
]
|
||||||
|
|
||||||
|
# 支持的文件后缀
|
||||||
|
ALLOW_EXT = {".mkv", ".mp4", ".mov", ".srt", ".ass", ".sub"}
|
||||||
|
|
||||||
|
def clean_name(name: str) -> str:
|
||||||
|
"""统一清洗函数,文件夹名、文件名共用"""
|
||||||
|
name_no_ext, ext = os.path.splitext(name)
|
||||||
|
|
||||||
|
# 处理 A . B . C 这种「字母 空格 . 空格 字母」
|
||||||
|
while re.search(r"(\w) \. (\w)", name_no_ext):
|
||||||
|
name_no_ext = re.sub(r"(\w) \. (\w)", r"\1\2", name_no_ext)
|
||||||
|
|
||||||
|
# 执行所有正则替换规则
|
||||||
|
for pattern, repl in RULES:
|
||||||
|
name_no_ext = re.sub(pattern, repl, name_no_ext)
|
||||||
|
|
||||||
|
# 合并连续空格,去除首尾空格
|
||||||
|
name_no_ext = re.sub(r"\s+", " ", name_no_ext).strip()
|
||||||
|
return name_no_ext + ext
|
||||||
|
|
||||||
|
def write_log(msg: str):
|
||||||
|
time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
line = f"[{time_str}] {msg}"
|
||||||
|
print(line)
|
||||||
|
with open(LOG_FILE, "a", encoding="utf-8") as f:
|
||||||
|
f.write(line + "\n")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
write_log("===== 文件名+文件夹清洗(移除开头A 中文片名前缀) =====")
|
||||||
|
write_log(f"根目录:{MEDIA_FOLDER}")
|
||||||
|
write_log(f"预览模式 DRY_RUN = {DRY_RUN}")
|
||||||
|
|
||||||
|
dir_rename_list = []
|
||||||
|
file_rename_list = []
|
||||||
|
|
||||||
|
# 遍历收集(自底向上,防止目录路径错乱)
|
||||||
|
for root, dirs, files in os.walk(MEDIA_FOLDER, topdown=False):
|
||||||
|
# 文件
|
||||||
|
for fname in files:
|
||||||
|
ext = os.path.splitext(fname)[1].lower()
|
||||||
|
if ext not in ALLOW_EXT:
|
||||||
|
continue
|
||||||
|
new_name = clean_name(fname)
|
||||||
|
if new_name != fname:
|
||||||
|
if SKIP_PROCESSED and re.search(r"\(\d{4}\)", new_name):
|
||||||
|
write_log(f"跳过文件(疑似已处理): {fname}")
|
||||||
|
continue
|
||||||
|
old_path = os.path.join(root, fname)
|
||||||
|
new_path = os.path.join(root, new_name)
|
||||||
|
file_rename_list.append((old_path, new_path))
|
||||||
|
|
||||||
|
# 文件夹
|
||||||
|
for dname in dirs:
|
||||||
|
new_name = clean_name(dname)
|
||||||
|
if new_name != dname:
|
||||||
|
if SKIP_PROCESSED and re.search(r"\(\d{4}\)", new_name):
|
||||||
|
write_log(f"跳过文件夹(疑似已处理): {dname}")
|
||||||
|
continue
|
||||||
|
old_path = os.path.join(root, dname)
|
||||||
|
new_path = os.path.join(root, new_name)
|
||||||
|
dir_rename_list.append((old_path, new_name))
|
||||||
|
|
||||||
|
# 先改文件夹,再改文件
|
||||||
|
dir_count = 0
|
||||||
|
for old, new in dir_rename_list:
|
||||||
|
write_log(f"【文件夹】{os.path.basename(old)} → {os.path.basename(new)}")
|
||||||
|
dir_count +=1
|
||||||
|
if not DRY_RUN:
|
||||||
|
os.rename(old, new)
|
||||||
|
|
||||||
|
file_count =0
|
||||||
|
for old, new in file_rename_list:
|
||||||
|
write_log(f"【文件】{os.path.basename(old)} → {os.path.basename(new)}")
|
||||||
|
file_count +=1
|
||||||
|
if not DRY_RUN:
|
||||||
|
os.rename(old, new)
|
||||||
|
|
||||||
|
write_log(f"任务完成,待修改文件夹:{dir_count},待修改文件:{file_count}")
|
||||||
|
write_log("="*60 + "\n")
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
from datetime import datetime
|
||||||
|
# ====================== 【配置区,请修改】 ======================
|
||||||
|
MEDIA_FOLDER = "/Volumes/JoyDisk/myMedia/olstrms/电影/未分类/2024"
|
||||||
|
DRY_RUN = True # True预览不修改;确认后改为False
|
||||||
|
SKIP_PROCESSED = False
|
||||||
|
LOG_FILE = "./rename_log.txt"
|
||||||
|
# =================================================================
|
||||||
|
RULES = [
|
||||||
|
(r"^[A-Za-z] ", ""), #1.开头单个字母+空格
|
||||||
|
(r"\[.*?\]", ""), #2.英文方括号
|
||||||
|
(r"【.*?】", ""), #2.中文方括号
|
||||||
|
(r"\b(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|中英双语)\b", "", re.IGNORECASE),
|
||||||
|
(r"\.+", ""), #4.连续多点删除
|
||||||
|
(r"\s", ""), #5.删除全部空格
|
||||||
|
]
|
||||||
|
ALLOW_EXT = {".mkv", ".mp4", ".mov", ".srt", ".ass", ".sub"}
|
||||||
|
|
||||||
|
def clean_name(name: str) -> str:
|
||||||
|
name_no_ext, ext = os.path.splitext(name)
|
||||||
|
for item in RULES:
|
||||||
|
if len(item) == 3:
|
||||||
|
pattern, repl, flag = item
|
||||||
|
name_no_ext = re.sub(pattern, repl, name_no_ext, flags=flag)
|
||||||
|
else:
|
||||||
|
pattern, repl = item
|
||||||
|
name_no_ext = re.sub(pattern, repl, name_no_ext)
|
||||||
|
name_no_ext = re.sub(r"\s+", " ", name_no_ext).strip()
|
||||||
|
return name_no_ext + ext
|
||||||
|
|
||||||
|
def write_log(msg: str):
|
||||||
|
time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
line = f"[{time_str}] {msg}"
|
||||||
|
print(line)
|
||||||
|
with open(LOG_FILE, "a", encoding="utf-8") as f:
|
||||||
|
f.write(line + "\n")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
write_log("===== 文件名+文件夹清洗【递归处理全部下级子目录】 =====")
|
||||||
|
write_log(f"根目录:{MEDIA_FOLDER}")
|
||||||
|
write_log(f"预览模式 DRY_RUN = {DRY_RUN}")
|
||||||
|
write_log("说明:递归扫描全部子目录,先收集所有待改,执行时【先文件、后文件夹】避免路径失效")
|
||||||
|
dir_rename_list = []
|
||||||
|
file_rename_list = []
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk(MEDIA_FOLDER, topdown=False):
|
||||||
|
write_log(f"\n==== 扫描目录:{root} | 当前目录文件数量:{len(files)} ====")
|
||||||
|
# 处理文件
|
||||||
|
for fname in files:
|
||||||
|
ext = os.path.splitext(fname)[1].lower()
|
||||||
|
if ext not in ALLOW_EXT:
|
||||||
|
continue
|
||||||
|
new_name = clean_name(fname)
|
||||||
|
if new_name != fname:
|
||||||
|
if SKIP_PROCESSED and re.search(r"\(\d{4}\)", new_name):
|
||||||
|
write_log(f"【跳过文件】{fname},检测年份括号")
|
||||||
|
continue
|
||||||
|
old_path = os.path.join(root, fname)
|
||||||
|
new_path = os.path.join(root, new_name)
|
||||||
|
file_rename_list.append((old_path, new_path))
|
||||||
|
write_log(f"【待改文件】{fname} → {new_name}")
|
||||||
|
# 处理文件夹
|
||||||
|
for dname in dirs:
|
||||||
|
new_name = clean_name(dname)
|
||||||
|
if new_name != dname:
|
||||||
|
if SKIP_PROCESSED and re.search(r"\(\d{4}\)", new_name):
|
||||||
|
write_log(f"【跳过文件夹】{dname},检测年份括号")
|
||||||
|
continue
|
||||||
|
old_path = os.path.join(root, dname)
|
||||||
|
new_path = os.path.join(root, new_name)
|
||||||
|
dir_rename_list.append((old_path, new_name))
|
||||||
|
write_log(f"【待改文件夹】{dname} → {new_name}")
|
||||||
|
|
||||||
|
# 执行顺序:先全部文件,再全部文件夹
|
||||||
|
file_count = 0
|
||||||
|
for old, new in file_rename_list:
|
||||||
|
write_log(f"【执行文件】{os.path.basename(old)} → {os.path.basename(new)}")
|
||||||
|
file_count +=1
|
||||||
|
if not DRY_RUN:
|
||||||
|
os.rename(old, new)
|
||||||
|
|
||||||
|
dir_count = 0
|
||||||
|
for old, new in dir_rename_list:
|
||||||
|
write_log(f"【执行文件夹】{os.path.basename(old)} → {os.path.basename(new)}")
|
||||||
|
dir_count +=1
|
||||||
|
if not DRY_RUN:
|
||||||
|
os.rename(old, new)
|
||||||
|
|
||||||
|
write_log(f"\n任务完成,待修改文件夹:{dir_count},待修改文件:{file_count}")
|
||||||
|
write_log("="*60 + "\n")
|
||||||
|
|
||||||
Executable
+326
@@ -0,0 +1,326 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
import argparse
|
||||||
|
import shutil
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
LOG_FILE = "./rename_log.txt"
|
||||||
|
|
||||||
|
SKIP_DIRS = [
|
||||||
|
"@eaDir",
|
||||||
|
]
|
||||||
|
|
||||||
|
SKIP_FILES = {
|
||||||
|
".DS_Store",
|
||||||
|
"Thumbs.db",
|
||||||
|
"desktop.ini",
|
||||||
|
}
|
||||||
|
|
||||||
|
RULES_FILE = [
|
||||||
|
(r"^[A-Za-z] ", ""),
|
||||||
|
(r"\[.*?\]", ""),
|
||||||
|
(r"【.*?】", ""),
|
||||||
|
(r"丨", ""),
|
||||||
|
(r"(?<!\w)(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|BD|BluRay|BLURAY|WEBRip|WEB-DL|HD|4K|中英双语|双语字幕|双语|中文|国语|粤语|台语|中英双字|国语中字|繁体中字|简体中字|简繁中字|双语中字|官方中字|特效中字|收藏不迷路|地址发布页|www6v123net|wwwdygangme)(?!\w)", "", re.IGNORECASE),
|
||||||
|
(r"\.+", ""),
|
||||||
|
(r"\s", ""),
|
||||||
|
(r"[^\u4e00-\u9fa5a-zA-Z0-9().:+\-]", ""),
|
||||||
|
]
|
||||||
|
|
||||||
|
RULES_DIR = [
|
||||||
|
(r"【.*?】", ""),
|
||||||
|
(r"^\[(.*)\]$", r"\1"),
|
||||||
|
(r"\]\[", ""),
|
||||||
|
(r"^[A-Za-z] ", ""),
|
||||||
|
(r"丨", ""),
|
||||||
|
(r"(?<!\w)(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|BD|BluRay|BLURAY|WEBRip|WEB-DL|HD|4K|中英双语|双语字幕|双语|中文|国语|粤语|台语|中英双字|国语中字|繁体中字|简体中字|简繁中字|双语中字|官方中字|特效中字|收藏不迷路|地址发布页|www6v123net|wwwdygangme)(?!\w)", "", re.IGNORECASE),
|
||||||
|
(r"\.+", ""),
|
||||||
|
(r"\s", ""),
|
||||||
|
(r"\(\)", ""),
|
||||||
|
(r"()", ""),
|
||||||
|
(r"[^\u4e00-\u9fa5a-zA-Z0-9().:+\-[\]]", ""),
|
||||||
|
]
|
||||||
|
|
||||||
|
FULL_ALLOW_EXT = {".mkv", ".mp4", ".mov", ".srt", ".ass", ".sub", ".strm", ".flv", ".avi", ".wmv", ".ts", ".rmvb", ".webm", ".mp3", ".flac", ".aac", ".wav", ".ogg", ".m4a", ".wma", ".alac", ".rm", ".iso"}
|
||||||
|
STRM_ONLY_EXT = {".strm", ".srt", ".ass", ".sub"}
|
||||||
|
MAX_FILENAME_LEN = 245
|
||||||
|
|
||||||
|
def full2half(s):
|
||||||
|
result = []
|
||||||
|
for char in s:
|
||||||
|
code = ord(char)
|
||||||
|
if code == 12288:
|
||||||
|
char = chr(32)
|
||||||
|
elif 65281 <= code <= 65374:
|
||||||
|
char = chr(code - 65248)
|
||||||
|
result.append(char)
|
||||||
|
return "".join(result)
|
||||||
|
|
||||||
|
def clean_file_name(name: str) -> str:
|
||||||
|
name_no_ext, ext = os.path.splitext(name)
|
||||||
|
name_no_ext = full2half(name_no_ext)
|
||||||
|
orig_no_ext = name_no_ext
|
||||||
|
for item in RULES_FILE:
|
||||||
|
if len(item) == 3:
|
||||||
|
pat, repl, flag = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext, flags=flag)
|
||||||
|
else:
|
||||||
|
pat, repl = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext)
|
||||||
|
name_no_ext = name_no_ext.strip()
|
||||||
|
if len(name_no_ext) == 0:
|
||||||
|
name_no_ext = orig_no_ext.strip()
|
||||||
|
if len(name_no_ext) > MAX_FILENAME_LEN:
|
||||||
|
name_no_ext = name_no_ext[:MAX_FILENAME_LEN]
|
||||||
|
return name_no_ext + ext
|
||||||
|
|
||||||
|
def clean_dir_name(name: str) -> str:
|
||||||
|
name = full2half(name)
|
||||||
|
year_match = re.search(r"^\[(\d{4})\]$", name)
|
||||||
|
year_str = ""
|
||||||
|
if year_match:
|
||||||
|
year_str = year_match.group(1)
|
||||||
|
for item in RULES_DIR:
|
||||||
|
if len(item) == 3:
|
||||||
|
pat, repl, flag = item
|
||||||
|
name = re.sub(pat, repl, name, flags=flag)
|
||||||
|
else:
|
||||||
|
pat, repl = item
|
||||||
|
name = re.sub(pat, repl, name)
|
||||||
|
name = name.strip()
|
||||||
|
if year_str and name:
|
||||||
|
name = f"{name}({year_str})"
|
||||||
|
if len(name) > MAX_FILENAME_LEN:
|
||||||
|
name = name[:MAX_FILENAME_LEN]
|
||||||
|
return name
|
||||||
|
|
||||||
|
def assign_unique_names(item_list):
|
||||||
|
name_counter = dict()
|
||||||
|
out = []
|
||||||
|
for it in item_list:
|
||||||
|
cand = it["candidate"]
|
||||||
|
cnt = name_counter.get(cand, 0)
|
||||||
|
if cnt == 0:
|
||||||
|
final = cand
|
||||||
|
else:
|
||||||
|
final = f"{cand}({cnt})"
|
||||||
|
name_counter[cand] = cnt + 1
|
||||||
|
new_it = dict(it)
|
||||||
|
new_it["final_basename"] = final
|
||||||
|
out.append(new_it)
|
||||||
|
return out
|
||||||
|
|
||||||
|
def write_log(msg: str, log_file: str):
|
||||||
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
line = f"[{now}] {msg}"
|
||||||
|
print(line)
|
||||||
|
try:
|
||||||
|
with open(log_file, "a", encoding="utf-8") as f:
|
||||||
|
f.write(line + "\n")
|
||||||
|
f.flush()
|
||||||
|
except Exception:
|
||||||
|
print(f"[LOG-WRITE-FAILED] {line}")
|
||||||
|
|
||||||
|
def scan_full_tree(root_src, skip_dirs, skip_files, allow_ext):
|
||||||
|
"""
|
||||||
|
返回:
|
||||||
|
dir_nodes: list,每一个文件夹独立节点,包含:
|
||||||
|
src_abs: 当前文件夹完整源绝对路径
|
||||||
|
parent_src_abs: 父文件夹完整源绝对路径
|
||||||
|
orig_basename: 当前文件夹原始名字
|
||||||
|
candidate: 清洗后的候选basename
|
||||||
|
depth:目录深度,用于排序父先于子创建
|
||||||
|
file_nodes: list,媒体文件节点
|
||||||
|
root_src_abs:源根目录绝对路径
|
||||||
|
"""
|
||||||
|
dir_nodes = []
|
||||||
|
file_nodes = []
|
||||||
|
root_src_abs = os.path.abspath(root_src)
|
||||||
|
for src_root, dirs, files in os.walk(root_src, topdown=True):
|
||||||
|
remove_idx = []
|
||||||
|
for idx, dname in enumerate(dirs):
|
||||||
|
if dname in skip_dirs:
|
||||||
|
remove_idx.append(idx)
|
||||||
|
for idx in reversed(remove_idx):
|
||||||
|
del dirs[idx]
|
||||||
|
dirs[:] = dirs
|
||||||
|
|
||||||
|
src_root_abs = os.path.abspath(src_root)
|
||||||
|
parent_src_abs = os.path.dirname(src_root_abs)
|
||||||
|
depth = src_root_abs.count(os.sep)
|
||||||
|
basename = os.path.basename(src_root_abs)
|
||||||
|
# 每遍历到一个文件夹,就记录为一条dir_nodes(包含所有层级全部目录节点)
|
||||||
|
if src_root_abs != root_src_abs:
|
||||||
|
cand = clean_dir_name(basename)
|
||||||
|
if len(cand) == 0:
|
||||||
|
cand = basename
|
||||||
|
dir_nodes.append({
|
||||||
|
"src_abs": src_root_abs,
|
||||||
|
"parent_src_abs": parent_src_abs,
|
||||||
|
"orig_basename": basename,
|
||||||
|
"candidate": cand,
|
||||||
|
"depth": depth
|
||||||
|
})
|
||||||
|
#收集本目录下媒体文件
|
||||||
|
for fname in files:
|
||||||
|
if fname in skip_files:
|
||||||
|
continue
|
||||||
|
ext = os.path.splitext(fname)[1].lower()
|
||||||
|
if ext not in allow_ext:
|
||||||
|
continue
|
||||||
|
cand_f = clean_file_name(fname)
|
||||||
|
file_nodes.append({
|
||||||
|
"src_parent_abs": src_root_abs,
|
||||||
|
"orig_basename": fname,
|
||||||
|
"candidate": cand_f
|
||||||
|
})
|
||||||
|
return root_src_abs, dir_nodes, file_nodes
|
||||||
|
|
||||||
|
def group_by_parent_src_abs(item_list, key_name):
|
||||||
|
groups = dict()
|
||||||
|
for it in item_list:
|
||||||
|
k = it[key_name]
|
||||||
|
if k not in groups:
|
||||||
|
groups[k] = []
|
||||||
|
groups[k].append(it)
|
||||||
|
return groups
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="镜像重命名【完整节点采集,严格1:1目录文件数量】")
|
||||||
|
parser.add_argument("--dir", required=True)
|
||||||
|
parser.add_argument("--output", required=True)
|
||||||
|
parser.add_argument("--apply", action="store_true")
|
||||||
|
parser.add_argument("--dry-run", action="store_true")
|
||||||
|
parser.add_argument("--strm-mode", action="store_true")
|
||||||
|
parser.add_argument("--log", default="./rename_log.txt")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
target_dir = args.dir
|
||||||
|
out_dir = args.output
|
||||||
|
log_path = args.log
|
||||||
|
|
||||||
|
DRY_RUN = True
|
||||||
|
if args.apply:
|
||||||
|
DRY_RUN = False
|
||||||
|
if args.dry_run:
|
||||||
|
DRY_RUN = True
|
||||||
|
|
||||||
|
if args.strm_mode:
|
||||||
|
ALLOW_EXT = STRM_ONLY_EXT
|
||||||
|
mode_info = "STRM模式【仅strm+字幕】"
|
||||||
|
else:
|
||||||
|
ALLOW_EXT = FULL_ALLOW_EXT
|
||||||
|
mode_info = "完整媒体模式"
|
||||||
|
|
||||||
|
if not os.path.isdir(target_dir):
|
||||||
|
print(f"源目录不存在 {target_dir}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(log_path, "w", encoding="utf-8") as f:
|
||||||
|
f.flush()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"日志初始化警告 {e}")
|
||||||
|
|
||||||
|
write_log("===== 重构:全节点采集,源输出条目严格1:1 =====", log_path)
|
||||||
|
write_log(f"源目录:{target_dir}", log_path)
|
||||||
|
write_log(f"输出镜像目录:{out_dir}", log_path)
|
||||||
|
write_log(f"运行模式:{mode_info}", log_path)
|
||||||
|
write_log(f"预览模式 DRY_RUN = {DRY_RUN}", log_path)
|
||||||
|
|
||||||
|
stat = {
|
||||||
|
"src_dir_total":0,
|
||||||
|
"src_file_total":0,
|
||||||
|
"dir_success":0,
|
||||||
|
"dir_fail":0,
|
||||||
|
"file_success":0,
|
||||||
|
"file_fail":0
|
||||||
|
}
|
||||||
|
|
||||||
|
#阶段1:完整扫描,每一个文件夹都是独立节点
|
||||||
|
root_src_abs, dir_nodes, file_nodes = scan_full_tree(target_dir, SKIP_DIRS, SKIP_FILES, ALLOW_EXT)
|
||||||
|
stat["src_dir_total"] = len(dir_nodes)
|
||||||
|
stat["src_file_total"] = len(file_nodes)
|
||||||
|
write_log(f"【采集统计】源全部目录节点总数:{stat['src_dir_total']},源媒体文件总数:{stat['src_file_total']}", log_path)
|
||||||
|
|
||||||
|
#阶段2:按父源绝对路径分组,组内分配唯一basename,处理重名冲突
|
||||||
|
dir_groups = group_by_parent_src_abs(dir_nodes, "parent_src_abs")
|
||||||
|
dir_final = []
|
||||||
|
for p_abs, items in dir_groups.items():
|
||||||
|
assigned = assign_unique_names(items)
|
||||||
|
dir_final.extend(assigned)
|
||||||
|
|
||||||
|
file_groups = group_by_parent_src_abs(file_nodes, "src_parent_abs")
|
||||||
|
file_final = []
|
||||||
|
for p_abs, items in file_groups.items():
|
||||||
|
assigned = assign_unique_names(items)
|
||||||
|
file_final.extend(assigned)
|
||||||
|
|
||||||
|
#构建源绝对路径 → 输出basename映射
|
||||||
|
src_to_basename = {d["src_abs"]:d["final_basename"] for d in dir_final}
|
||||||
|
#构建源绝对路径 → 输出完整路径映射
|
||||||
|
src_to_out = dict()
|
||||||
|
src_to_out[root_src_abs] = out_dir
|
||||||
|
#按depth升序排序:浅目录优先,父一定先处理
|
||||||
|
dir_final_sorted = sorted(dir_final, key=lambda x:x["depth"])
|
||||||
|
for d in dir_final_sorted:
|
||||||
|
p_src = d["parent_src_abs"]
|
||||||
|
p_out = src_to_out[p_src]
|
||||||
|
child_out = os.path.join(p_out, d["final_basename"])
|
||||||
|
src_to_out[d["src_abs"]] = child_out
|
||||||
|
|
||||||
|
#打印目录日志
|
||||||
|
for it in dir_final:
|
||||||
|
orig = it["orig_basename"]
|
||||||
|
cand = it["candidate"]
|
||||||
|
final = it["final_basename"]
|
||||||
|
if cand != final:
|
||||||
|
write_log(f"【目录重名冲突】源目录[{orig}] 候选[{cand}] → 分配[{final}]", log_path)
|
||||||
|
else:
|
||||||
|
if orig != final:
|
||||||
|
write_log(f"待修改文件夹-> {orig} → {final}", log_path)
|
||||||
|
#打印文件日志
|
||||||
|
for it in file_final:
|
||||||
|
orig = it["orig_basename"]
|
||||||
|
cand = it["candidate"]
|
||||||
|
final = it["final_basename"]
|
||||||
|
if cand != final:
|
||||||
|
write_log(f"【文件重名冲突】源文件[{orig}] 候选[{cand}] → 分配[{final}]", log_path)
|
||||||
|
else:
|
||||||
|
if orig != final:
|
||||||
|
write_log(f"待修改文件-> {orig} → {final}", log_path)
|
||||||
|
|
||||||
|
#阶段3:按深度顺序创建目录,父目录优先
|
||||||
|
for d in dir_final_sorted:
|
||||||
|
full_out = src_to_out[d["src_abs"]]
|
||||||
|
if not DRY_RUN:
|
||||||
|
try:
|
||||||
|
os.makedirs(full_out, exist_ok=True)
|
||||||
|
stat["dir_success"] += 1
|
||||||
|
except OSError as e:
|
||||||
|
stat["dir_fail"] += 1
|
||||||
|
write_log(f"【目录创建失败】{full_out} | {e}", log_path)
|
||||||
|
|
||||||
|
#复制全部媒体文件
|
||||||
|
for it in file_final:
|
||||||
|
src_file = os.path.join(it["src_parent_abs"], it["orig_basename"])
|
||||||
|
dst_parent = src_to_out[it["src_parent_abs"]]
|
||||||
|
dst_file = os.path.join(dst_parent, it["final_basename"])
|
||||||
|
if not DRY_RUN:
|
||||||
|
try:
|
||||||
|
shutil.copy2(src_file, dst_file)
|
||||||
|
stat["file_success"] += 1
|
||||||
|
except OSError as e:
|
||||||
|
stat["file_fail"] +=1
|
||||||
|
write_log(f"【文件复制失败】src:{src_file} dst:{dst_file} | {e}", log_path)
|
||||||
|
|
||||||
|
write_log("----------任务统计汇总----------", log_path)
|
||||||
|
write_log(f"源采集目录节点总数量:{stat['src_dir_total']},源媒体文件总数量:{stat['src_file_total']}", log_path)
|
||||||
|
write_log(f"目录:成功 {stat['dir_success']},失败 {stat['dir_fail']}", log_path)
|
||||||
|
write_log(f"文件:成功 {stat['file_success']},失败 {stat['file_fail']}", log_path)
|
||||||
|
write_log("【校验】预期目录输出={},实际成功={}".format(stat["src_dir_total"], stat["dir_success"]), log_path)
|
||||||
|
write_log("【校验】预期文件输出={},实际成功={}".format(stat["src_file_total"], stat["file_success"]), log_path)
|
||||||
|
write_log("============================================================", log_path)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
import argparse
|
||||||
|
import shutil
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# ====================== 【配置区】 ======================
|
||||||
|
LOG_FILE = "./rename_log.txt"
|
||||||
|
|
||||||
|
# 需要完全跳过的目录名称(basename,大小写敏感)
|
||||||
|
SKIP_DIRS = [
|
||||||
|
"@eaDir", # 群晖隐含目录
|
||||||
|
]
|
||||||
|
|
||||||
|
# 需要跳过的隐含文件名称(完整文件名匹配)
|
||||||
|
SKIP_FILES = {
|
||||||
|
".DS_Store",
|
||||||
|
"Thumbs.db",
|
||||||
|
"desktop.ini",
|
||||||
|
}
|
||||||
|
|
||||||
|
# 文件清洗规则
|
||||||
|
RULES_FILE = [
|
||||||
|
(r"^[A-Za-z] ", ""),
|
||||||
|
(r"\[.*?\]", ""),
|
||||||
|
(r"【.*?】", ""),
|
||||||
|
(r"丨", ""),
|
||||||
|
(r"(?<!\w)(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|BD|BluRay|BLURAY|WEBRip|WEB-DL|HD|4K|中英双语|双语字幕|双语|中文|国语|粤语|台语|中英双字|国语中字|繁体中字|简体中字|简繁中字|双语中字|官方中字|特效中字)(?!\w)", "", re.IGNORECASE),
|
||||||
|
(r"\.+", ""),
|
||||||
|
(r"\s", ""),
|
||||||
|
(r"[^\u4e00-\u9fa5a-zA-Z0-9().:+\-]", ""),
|
||||||
|
]
|
||||||
|
|
||||||
|
# 文件夹清洗规则
|
||||||
|
RULES_DIR = [
|
||||||
|
(r"【.*?】", ""), # 删除中文全角【】以及内部内容
|
||||||
|
(r"^\[(.*)\]$", r"\1"), # 整串被[]包裹,只剥外层
|
||||||
|
(r"\]\[", ""), # 清除中间碎片 ][
|
||||||
|
(r"^[A-Za-z] ", ""),
|
||||||
|
(r"丨", ""),
|
||||||
|
(r"(?<!\w)(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|BD|BluRay|BLURAY|WEBRip|WEB-DL|HD|4K|中英双语|双语字幕|双语|中文|国语|粤语|台语|中英双字|国语中字|繁体中字|简体中字|简繁中字|双语中字|官方中字|特效中字)(?!\w)", "", re.IGNORECASE),
|
||||||
|
(r"\.+", ""),
|
||||||
|
(r"\s", ""),
|
||||||
|
(r"\(\)", ""), # 清除英文空括号 ()
|
||||||
|
(r"()", ""), # 清除中文全角空括号 ()
|
||||||
|
(r"[^\u4e00-\u9fa5a-zA-Z0-9().:+\-[\]]", ""), # 允许文件夹内部保留[]
|
||||||
|
]
|
||||||
|
|
||||||
|
#完整全部媒体后缀(不带--strm-mode时使用)
|
||||||
|
FULL_ALLOW_EXT = {".mkv", ".mp4", ".mov", ".srt", ".ass", ".sub", ".strm", ".flv", ".avi", ".wmv", ".ts", ".rmvb", ".webm", ".mp3", ".flac", ".aac", ".wav", ".ogg", ".m4a", ".wma", ".alac", ".rm", ".iso"}
|
||||||
|
# strm模式:仅strm+字幕
|
||||||
|
STRM_ONLY_EXT = {".strm", ".srt", ".ass", ".sub"}
|
||||||
|
|
||||||
|
MAX_FILENAME_LEN = 245 # mac文件名最大安全长度,预留扩展名位置
|
||||||
|
# =======================================================
|
||||||
|
|
||||||
|
def full2half(s):
|
||||||
|
result = []
|
||||||
|
for char in s:
|
||||||
|
code = ord(char)
|
||||||
|
if code == 12288:
|
||||||
|
char = chr(32)
|
||||||
|
elif 65281 <= code <= 65374:
|
||||||
|
char = chr(code - 65248)
|
||||||
|
result.append(char)
|
||||||
|
return "".join(result)
|
||||||
|
|
||||||
|
def clean_file_name(name: str) -> str:
|
||||||
|
name_no_ext, ext = os.path.splitext(name)
|
||||||
|
name_no_ext = full2half(name_no_ext)
|
||||||
|
for item in RULES_FILE:
|
||||||
|
if len(item) == 3:
|
||||||
|
pat, repl, flag = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext, flags=flag)
|
||||||
|
else:
|
||||||
|
pat, repl = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext)
|
||||||
|
name_no_ext = name_no_ext.strip()
|
||||||
|
if len(name_no_ext) > MAX_FILENAME_LEN:
|
||||||
|
name_no_ext = name_no_ext[:MAX_FILENAME_LEN]
|
||||||
|
return name_no_ext + ext
|
||||||
|
|
||||||
|
def clean_dir_name(name: str) -> str:
|
||||||
|
name = full2half(name)
|
||||||
|
year_match = re.search(r"^\[(\d{4})\]$", name)
|
||||||
|
year_str = ""
|
||||||
|
if year_match:
|
||||||
|
year_str = year_match.group(1)
|
||||||
|
|
||||||
|
for item in RULES_DIR:
|
||||||
|
if len(item) == 3:
|
||||||
|
pat, repl, flag = item
|
||||||
|
name = re.sub(pat, repl, name, flags=flag)
|
||||||
|
else:
|
||||||
|
pat, repl = item
|
||||||
|
name = re.sub(pat, repl, name)
|
||||||
|
name = name.strip()
|
||||||
|
if year_str and name:
|
||||||
|
name = f"{name}({year_str})"
|
||||||
|
if len(name) > MAX_FILENAME_LEN:
|
||||||
|
name = name[:MAX_FILENAME_LEN]
|
||||||
|
return name
|
||||||
|
|
||||||
|
def resolve_dir_path(parent_out_dir: str, want_dir_name: str, orig_src_basename: str, log_file: str):
|
||||||
|
"""目录冲突处理:父输出目录下,如果want_dir_name已存在,则追加(1)(2)..."""
|
||||||
|
candidate = want_dir_name
|
||||||
|
idx = 1
|
||||||
|
while True:
|
||||||
|
full_candidate_path = os.path.join(parent_out_dir, candidate)
|
||||||
|
if not os.path.exists(full_candidate_path):
|
||||||
|
return candidate
|
||||||
|
write_log(f"【目录重名冲突】源目录[{orig_src_basename}],输出目录已存在[{candidate}],自动变更为 {want_dir_name}({idx})", log_file)
|
||||||
|
candidate = f"{want_dir_name}({idx})"
|
||||||
|
idx += 1
|
||||||
|
|
||||||
|
def get_quality_tag(filename:str):
|
||||||
|
m = re.search(r"(?<!\w)(2160p|1080p|720p)(?!\w)", filename, re.IGNORECASE)
|
||||||
|
if m:
|
||||||
|
return m.group(1).lower()
|
||||||
|
return None
|
||||||
|
|
||||||
|
def resolve_conflict(dst_dir:str, base_name:str, ext:str, orig_filename:str):
|
||||||
|
candidate = base_name + ext
|
||||||
|
dst_path = os.path.join(dst_dir, candidate)
|
||||||
|
if not os.path.exists(dst_path):
|
||||||
|
return candidate
|
||||||
|
qual = get_quality_tag(orig_filename)
|
||||||
|
if qual:
|
||||||
|
candidate = f"{base_name}({qual}){ext}"
|
||||||
|
dst_path = os.path.join(dst_dir, candidate)
|
||||||
|
if not os.path.exists(dst_path):
|
||||||
|
return candidate
|
||||||
|
idx = 1
|
||||||
|
while True:
|
||||||
|
candidate = f"{base_name}({idx}){ext}"
|
||||||
|
dst_path = os.path.join(dst_dir, candidate)
|
||||||
|
if not os.path.exists(dst_path):
|
||||||
|
return candidate
|
||||||
|
idx +=1
|
||||||
|
|
||||||
|
def write_log(msg: str, log_file: str):
|
||||||
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
line = f"[{now}] {msg}"
|
||||||
|
print(line)
|
||||||
|
try:
|
||||||
|
with open(log_file, "a", encoding="utf-8") as f:
|
||||||
|
f.write(line + "\n")
|
||||||
|
f.flush()
|
||||||
|
except Exception:
|
||||||
|
#日志写入失败降级控制台输出,不打断程序
|
||||||
|
print(f"[LOG-WRITE-FAILED] {line}")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="媒体文件名镜像清洗工具,源目录只读,生成镜像副本")
|
||||||
|
parser.add_argument("--dir", required=True, help="原始源媒体根目录")
|
||||||
|
parser.add_argument("--output", required=True, help="输出镜像根目录")
|
||||||
|
parser.add_argument("--apply", action="store_true", help="加上此参数才执行真实复制生成镜像")
|
||||||
|
parser.add_argument("--dry-run", action="store_true", help="预览模式(默认就是预览,该参数为显式简写)")
|
||||||
|
parser.add_argument("--strm-mode", action="store_true", help="开启strm模式:仅处理 .strm .srt .ass .sub;过滤mkv/mp4等视频文件")
|
||||||
|
parser.add_argument("--log", default="./rename_log.txt", help="日志文件路径,默认 ./rename_log.txt")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
target_dir = args.dir
|
||||||
|
out_dir = args.output
|
||||||
|
log_path = args.log
|
||||||
|
|
||||||
|
DRY_RUN = True
|
||||||
|
if args.apply:
|
||||||
|
DRY_RUN = False
|
||||||
|
if args.dry_run:
|
||||||
|
DRY_RUN = True
|
||||||
|
|
||||||
|
if args.strm_mode:
|
||||||
|
ALLOW_EXT = STRM_ONLY_EXT
|
||||||
|
mode_info = "STRM模式【仅strm+字幕】"
|
||||||
|
else:
|
||||||
|
ALLOW_EXT = FULL_ALLOW_EXT
|
||||||
|
mode_info = "完整媒体模式【全部媒体后缀】"
|
||||||
|
|
||||||
|
if not os.path.isdir(target_dir):
|
||||||
|
print(f"错误:源目录不存在 -> {target_dir}")
|
||||||
|
return
|
||||||
|
|
||||||
|
#初始化日志
|
||||||
|
try:
|
||||||
|
with open(log_path, "w", encoding="utf-8") as f:
|
||||||
|
f.flush()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"警告:无法初始化日志文件 {log_path},后续仅控制台输出日志,异常:{e}")
|
||||||
|
|
||||||
|
write_log("===== 文件名+文件夹清洗【目录重名冲突修复|全部标准短横杠参数】 =====", log_path)
|
||||||
|
write_log(f"源目录:{target_dir}", log_path)
|
||||||
|
write_log(f"输出镜像目录:{out_dir}", log_path)
|
||||||
|
write_log(f"运行模式:{mode_info}", log_path)
|
||||||
|
write_log(f"预览模式 DRY_RUN = {DRY_RUN}", log_path)
|
||||||
|
if SKIP_DIRS:
|
||||||
|
write_log(f"配置跳过目录名列表:{SKIP_DIRS}", log_path)
|
||||||
|
write_log(f"过滤隐含系统文件:{SKIP_FILES}", log_path)
|
||||||
|
|
||||||
|
stat = {
|
||||||
|
"scan_dir_total":0,
|
||||||
|
"scan_file_total":0,
|
||||||
|
"media_file_total":0,
|
||||||
|
"file_success":0,
|
||||||
|
"file_fail":0,
|
||||||
|
"dir_success":0,
|
||||||
|
"dir_fail":0
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
for root, dirs, files in os.walk(target_dir, topdown=False):
|
||||||
|
#过滤跳过目录:@eaDir、配置SKIP_DIRS
|
||||||
|
remove_idx = []
|
||||||
|
for idx, dname in enumerate(dirs):
|
||||||
|
if dname in SKIP_DIRS:
|
||||||
|
remove_idx.append(idx)
|
||||||
|
for idx in reversed(remove_idx):
|
||||||
|
del dirs[idx]
|
||||||
|
|
||||||
|
stat["scan_dir_total"] += 1
|
||||||
|
rel = os.path.relpath(root, target_dir)
|
||||||
|
if rel == ".":
|
||||||
|
#根目录
|
||||||
|
dst_current_dir = out_dir
|
||||||
|
else:
|
||||||
|
src_basename = os.path.basename(root)
|
||||||
|
parent_src_rel = os.path.dirname(rel)
|
||||||
|
parent_out_dir = os.path.join(out_dir, parent_src_rel)
|
||||||
|
new_dir_name = clean_dir_name(src_basename)
|
||||||
|
if len(new_dir_name) == 0:
|
||||||
|
write_log(f"【警告】文件夹清洗后名称为空,使用原名保留:{src_basename}", log_path)
|
||||||
|
new_dir_name = src_basename
|
||||||
|
# 目录冲突检测,获取最终输出目录名
|
||||||
|
final_dir_name = resolve_dir_path(parent_out_dir, new_dir_name, src_basename, log_path)
|
||||||
|
dst_current_dir = os.path.join(parent_out_dir, final_dir_name)
|
||||||
|
|
||||||
|
# 创建输出目录
|
||||||
|
if not DRY_RUN:
|
||||||
|
try:
|
||||||
|
os.makedirs(dst_current_dir, exist_ok=True)
|
||||||
|
stat["dir_success"] +=1
|
||||||
|
except OSError as e:
|
||||||
|
stat["dir_fail"] +=1
|
||||||
|
write_log(f"【目录创建失败】{dst_current_dir} | {e}", log_path)
|
||||||
|
|
||||||
|
# 处理本目录全部文件
|
||||||
|
for fname in files:
|
||||||
|
if fname in SKIP_FILES:
|
||||||
|
continue
|
||||||
|
stat["scan_file_total"] +=1
|
||||||
|
ext = os.path.splitext(fname)[1].lower()
|
||||||
|
if ext in ALLOW_EXT:
|
||||||
|
stat["media_file_total"] += 1
|
||||||
|
new_name = clean_file_name(fname)
|
||||||
|
old_path = os.path.join(root, fname)
|
||||||
|
base, ext_out = os.path.splitext(new_name)
|
||||||
|
final_fname = resolve_conflict(dst_current_dir, base, ext_out, fname)
|
||||||
|
dst_file = os.path.join(dst_current_dir, final_fname)
|
||||||
|
|
||||||
|
if final_fname != fname:
|
||||||
|
write_log(f"待修改文件-> {fname} → {final_fname}", log_path)
|
||||||
|
|
||||||
|
if not DRY_RUN:
|
||||||
|
try:
|
||||||
|
shutil.copy2(old_path, dst_file)
|
||||||
|
stat["file_success"] +=1
|
||||||
|
except OSError as e:
|
||||||
|
stat["file_fail"] +=1
|
||||||
|
write_log(f"【文件复制失败】src:{old_path} dst:{dst_file} | {e}", log_path)
|
||||||
|
|
||||||
|
# 处理子文件夹,只打印名称发生变更的文件夹
|
||||||
|
for dname in dirs:
|
||||||
|
new_name = clean_dir_name(dname)
|
||||||
|
if len(new_name) == 0:
|
||||||
|
write_log(f"【警告】文件夹清洗后名称为空,跳过改名:{dname}", log_path)
|
||||||
|
continue
|
||||||
|
if new_name != dname:
|
||||||
|
write_log(f"待修改文件夹-> {dname} → {new_name}", log_path)
|
||||||
|
|
||||||
|
except OSError as walk_err:
|
||||||
|
write_log(f"【严重】遍历目录发生IO异常,部分目录未扫描:{walk_err}", log_path)
|
||||||
|
|
||||||
|
write_log("----------任务统计汇总----------", log_path)
|
||||||
|
write_log(f"总扫描目录:{stat['scan_dir_total']}", log_path)
|
||||||
|
write_log(f"总扫描文件:{stat['scan_file_total']},媒体文件:{stat['media_file_total']}", log_path)
|
||||||
|
write_log(f"目录:成功创建 {stat['dir_success']},失败 {stat['dir_fail']}", log_path)
|
||||||
|
write_log(f"文件:成功复制 {stat['file_success']},失败 {stat['file_fail']}", log_path)
|
||||||
|
write_log("============================================================", log_path)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,277 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
import argparse
|
||||||
|
import shutil
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# ====================== 【配置区】 ======================
|
||||||
|
# 建议日志放在【本机内置磁盘】,不要放在容易掉线的外接卷,防止盘断开日志写失败
|
||||||
|
LOG_FILE = "./rename_log.txt"
|
||||||
|
|
||||||
|
#需要完全跳过的目录名称(basename,大小写敏感)
|
||||||
|
SKIP_DIRS = [
|
||||||
|
"@eaDir", # 群晖隐含目录
|
||||||
|
]
|
||||||
|
|
||||||
|
# 需要跳过的隐含文件名称(完整文件名匹配)
|
||||||
|
SKIP_FILES = {
|
||||||
|
".DS_Store",
|
||||||
|
"Thumbs.db",
|
||||||
|
"desktop.ini",
|
||||||
|
}
|
||||||
|
|
||||||
|
# 文件清洗规则:依旧删除全部 []【】
|
||||||
|
RULES_FILE = [
|
||||||
|
(r"^[A-Za-z] ", ""),
|
||||||
|
(r"\[.*?\]", ""),
|
||||||
|
(r"【.*?】", ""),
|
||||||
|
(r"丨", ""),
|
||||||
|
(r"\b(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|中英双语|双语字幕)\b", "", re.IGNORECASE),
|
||||||
|
(r"\.+", ""),
|
||||||
|
(r"\s", ""),
|
||||||
|
(r"[^\u4e00-\u9fa5a-zA-Z0-9().:+-]", ""),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# 1.删除中文全角【】
|
||||||
|
# 2.剥最外层英文[]
|
||||||
|
# 3.清除碎片 ][
|
||||||
|
# 4.最后清理遗留空括号 () ()
|
||||||
|
RULES_DIR = [
|
||||||
|
(r"【.*?】", ""), # 删除中文全角【】以及内部内容
|
||||||
|
(r"^\[(.*)\]$", r"\1"), # 整串被英文[]包裹,只剥外层
|
||||||
|
(r"\]\[", ""), # 清除中间碎片 ][
|
||||||
|
(r"^[A-Za-z] ", ""),
|
||||||
|
(r"丨", ""),
|
||||||
|
(r"\b(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|中英|双语|国语|国粤|中字|超清|高清|清晰|无水印|HD|BD|字幕)\b", "", re.IGNORECASE),
|
||||||
|
(r"\.+", ""),
|
||||||
|
(r"\s", ""),
|
||||||
|
(r"\(\)", ""), # 清除英文空括号 ()
|
||||||
|
(r"()", ""), # 清除中文全角空括号 ()
|
||||||
|
(r"[^\u4e00-\u9fa5a-zA-Z0-9().:+\-[\]]", ""), # 允许文件夹内部保留[]
|
||||||
|
]
|
||||||
|
|
||||||
|
#完整全部媒体后缀(不带--strm‑mode时使用)
|
||||||
|
FULL_ALLOW_EXT = {".mkv", ".mp4", ".mov", ".srt", ".ass", ".sub", ".strm", ".flv", ".avi", ".wmv", ".ts", ".rmvb", ".webm", ".mp3", ".flac", ".aac", ".wav", ".ogg", ".m4a", ".wma", ".alac", ".rm", ".iso"}
|
||||||
|
# strm模式:仅strm+字幕
|
||||||
|
STRM_ONLY_EXT = {".strm", ".srt", ".ass", ".sub"}
|
||||||
|
|
||||||
|
MAX_FILENAME_LEN = 245 # mac文件名最大安全长度,预留扩展名位置
|
||||||
|
# =======================================================
|
||||||
|
|
||||||
|
def full2half(s):
|
||||||
|
result = []
|
||||||
|
for char in s:
|
||||||
|
code = ord(char)
|
||||||
|
if code == 12288:
|
||||||
|
char = chr(32)
|
||||||
|
elif 65281 <= code <= 65374:
|
||||||
|
char = chr(code - 65248)
|
||||||
|
result.append(char)
|
||||||
|
return "".join(result)
|
||||||
|
|
||||||
|
def clean_file_name(name: str) -> str:
|
||||||
|
name_no_ext, ext = os.path.splitext(name)
|
||||||
|
name_no_ext = full2half(name_no_ext)
|
||||||
|
for item in RULES_FILE:
|
||||||
|
if len(item) == 3:
|
||||||
|
pat, repl, flag = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext, flags=flag)
|
||||||
|
else:
|
||||||
|
pat, repl = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext)
|
||||||
|
name_no_ext = name_no_ext.strip()
|
||||||
|
if len(name_no_ext) > MAX_FILENAME_LEN:
|
||||||
|
name_no_ext = name_no_ext[:MAX_FILENAME_LEN]
|
||||||
|
return name_no_ext + ext
|
||||||
|
|
||||||
|
def clean_dir_name(name: str) -> str:
|
||||||
|
name = full2half(name)
|
||||||
|
year_match = re.search(r"^\[(\d{4})\]$", name)
|
||||||
|
year_str = ""
|
||||||
|
if year_match:
|
||||||
|
year_str = year_match.group(1)
|
||||||
|
|
||||||
|
for item in RULES_DIR:
|
||||||
|
if len(item) == 3:
|
||||||
|
pat, repl, flag = item
|
||||||
|
name = re.sub(pat, repl, name, flags=flag)
|
||||||
|
else:
|
||||||
|
pat, repl = item
|
||||||
|
name = re.sub(pat, repl, name)
|
||||||
|
name = name.strip()
|
||||||
|
if year_str and name:
|
||||||
|
name = f"{name}({year_str})"
|
||||||
|
if len(name) > MAX_FILENAME_LEN:
|
||||||
|
name = name[:MAX_FILENAME_LEN]
|
||||||
|
return name
|
||||||
|
|
||||||
|
def get_quality_tag(filename:str):
|
||||||
|
m = re.search(r"\b(2160p|1080p|720p)\b", filename, re.IGNORECASE)
|
||||||
|
if m:
|
||||||
|
return m.group(1).lower()
|
||||||
|
return None
|
||||||
|
|
||||||
|
def resolve_conflict(dst_dir:str, base_name:str, ext:str, orig_filename:str):
|
||||||
|
candidate = base_name + ext
|
||||||
|
dst_path = os.path.join(dst_dir, candidate)
|
||||||
|
if not os.path.exists(dst_path):
|
||||||
|
return candidate
|
||||||
|
qual = get_quality_tag(orig_filename)
|
||||||
|
if qual:
|
||||||
|
candidate = f"{base_name}({qual}){ext}"
|
||||||
|
dst_path = os.path.join(dst_dir, candidate)
|
||||||
|
if not os.path.exists(dst_path):
|
||||||
|
return candidate
|
||||||
|
idx = 1
|
||||||
|
while True:
|
||||||
|
candidate = f"{base_name}({idx}){ext}"
|
||||||
|
dst_path = os.path.join(dst_dir, candidate)
|
||||||
|
if not os.path.exists(dst_path):
|
||||||
|
return candidate
|
||||||
|
idx +=1
|
||||||
|
|
||||||
|
def write_log(msg: str, log_file: str):
|
||||||
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
line = f"[{now}] {msg}"
|
||||||
|
print(line)
|
||||||
|
try:
|
||||||
|
with open(log_file, "a", encoding="utf-8") as f:
|
||||||
|
f.write(line + "\n")
|
||||||
|
f.flush()
|
||||||
|
except Exception:
|
||||||
|
#日志写入失败降级控制台输出,不打断程序
|
||||||
|
print(f"[LOG-WRITE-FAILED] {line}")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="媒体文件名镜像清洗工具,源目录只读,生成镜像副本")
|
||||||
|
parser.add_argument("--dir", required=True, help="原始源媒体根目录")
|
||||||
|
parser.add_argument("--output", required=True, help="输出镜像根目录")
|
||||||
|
parser.add_argument("--apply", action="store_true", help="加上此参数才执行真实复制生成镜像")
|
||||||
|
parser.add_argument("--dry-run", action="store_true", help="预览模式(默认就是预览,该参数为显式简写)")
|
||||||
|
parser.add_argument("--strm-mode", action="store_true", help="开启strm模式:仅处理 .strm .srt .ass .sub;过滤mkv/mp4等视频文件")
|
||||||
|
parser.add_argument("--log", default="./rename_log.txt", help="日志文件路径,默认 ./rename_log.txt")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
target_dir = args.dir
|
||||||
|
out_dir = args.output
|
||||||
|
log_path = args.log
|
||||||
|
|
||||||
|
DRY_RUN = True
|
||||||
|
if args.apply:
|
||||||
|
DRY_RUN = False
|
||||||
|
|
||||||
|
if args.strm_mode:
|
||||||
|
ALLOW_EXT = STRM_ONLY_EXT
|
||||||
|
mode_info = "STRM模式【仅strm+字幕】"
|
||||||
|
else:
|
||||||
|
ALLOW_EXT = FULL_ALLOW_EXT
|
||||||
|
mode_info = "完整媒体模式【全部媒体后缀】"
|
||||||
|
|
||||||
|
if not os.path.isdir(target_dir):
|
||||||
|
print(f"错误:源目录不存在 -> {target_dir}")
|
||||||
|
return
|
||||||
|
|
||||||
|
#初始化日志
|
||||||
|
try:
|
||||||
|
with open(log_path, "w", encoding="utf-8") as f:
|
||||||
|
f.flush()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"警告:无法初始化日志文件 {log_path},后续仅控制台输出日志,异常:{e}")
|
||||||
|
|
||||||
|
write_log("===== 文件名+文件夹清洗【增加清除空括号()()】 =====", log_path)
|
||||||
|
write_log(f"源目录:{target_dir}", log_path)
|
||||||
|
write_log(f"输出镜像目录:{out_dir}", log_path)
|
||||||
|
write_log(f"运行模式:{mode_info}", log_path)
|
||||||
|
write_log(f"预览模式 DRY_RUN = {DRY_RUN}", log_path)
|
||||||
|
if SKIP_DIRS:
|
||||||
|
write_log(f"配置跳过目录名列表:{SKIP_DIRS}", log_path)
|
||||||
|
write_log(f"过滤隐含系统文件:{SKIP_FILES}", log_path)
|
||||||
|
|
||||||
|
stat = {
|
||||||
|
"scan_dir_total":0,
|
||||||
|
"scan_file_total":0,
|
||||||
|
"media_file_total":0,
|
||||||
|
"file_success":0,
|
||||||
|
"file_fail":0,
|
||||||
|
"dir_success":0,
|
||||||
|
"dir_fail":0
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
for root, dirs, files in os.walk(target_dir, topdown=False):
|
||||||
|
#过滤跳过目录:@eaDir、配置SKIP_DIRS
|
||||||
|
remove_idx = []
|
||||||
|
for idx, dname in enumerate(dirs):
|
||||||
|
if dname in SKIP_DIRS:
|
||||||
|
remove_idx.append(idx)
|
||||||
|
for idx in reversed(remove_idx):
|
||||||
|
del dirs[idx]
|
||||||
|
|
||||||
|
stat["scan_dir_total"] += 1
|
||||||
|
rel = os.path.relpath(root, target_dir)
|
||||||
|
if rel == ".":
|
||||||
|
dst_current_dir = out_dir
|
||||||
|
else:
|
||||||
|
src_basename = os.path.basename(root)
|
||||||
|
new_dir_name = clean_dir_name(src_basename)
|
||||||
|
if len(new_dir_name) == 0:
|
||||||
|
write_log(f"【警告】文件夹清洗后名称为空,使用原名保留:{src_basename}", log_path)
|
||||||
|
new_dir_name = src_basename
|
||||||
|
dst_current_dir = os.path.join(out_dir, rel.replace(src_basename, new_dir_name))
|
||||||
|
|
||||||
|
#创建输出目录
|
||||||
|
if not DRY_RUN:
|
||||||
|
try:
|
||||||
|
os.makedirs(dst_current_dir, exist_ok=True)
|
||||||
|
stat["dir_success"] +=1
|
||||||
|
except OSError as e:
|
||||||
|
stat["dir_fail"] +=1
|
||||||
|
write_log(f"【目录创建失败】{dst_current_dir} | {e}", log_path)
|
||||||
|
|
||||||
|
#处理本目录全部文件
|
||||||
|
for fname in files:
|
||||||
|
if fname in SKIP_FILES:
|
||||||
|
continue
|
||||||
|
stat["scan_file_total"] +=1
|
||||||
|
ext = os.path.splitext(fname)[1].lower()
|
||||||
|
if ext in ALLOW_EXT:
|
||||||
|
stat["media_file_total"] += 1
|
||||||
|
new_name = clean_file_name(fname)
|
||||||
|
old_path = os.path.join(root, fname)
|
||||||
|
base, ext_out = os.path.splitext(new_name)
|
||||||
|
final_fname = resolve_conflict(dst_current_dir, base, ext_out, fname)
|
||||||
|
dst_file = os.path.join(dst_current_dir, final_fname)
|
||||||
|
|
||||||
|
if final_fname != fname:
|
||||||
|
write_log(f"待修改文件-> {fname} → {final_fname}", log_path)
|
||||||
|
|
||||||
|
if not DRY_RUN:
|
||||||
|
try:
|
||||||
|
shutil.copy2(old_path, dst_file)
|
||||||
|
stat["file_success"] +=1
|
||||||
|
except OSError as e:
|
||||||
|
stat["file_fail"] +=1
|
||||||
|
write_log(f"【文件复制失败】src:{old_path} dst:{dst_file} | {e}", log_path)
|
||||||
|
|
||||||
|
#处理子文件夹,只打印名称发生变更的文件夹
|
||||||
|
for dname in dirs:
|
||||||
|
new_name = clean_dir_name(dname)
|
||||||
|
if len(new_name) == 0:
|
||||||
|
write_log(f"【警告】文件夹清洗后名称为空,跳过改名:{dname}", log_path)
|
||||||
|
continue
|
||||||
|
if new_name != dname:
|
||||||
|
write_log(f"待修改文件夹-> {dname} → {new_name}", log_path)
|
||||||
|
|
||||||
|
except OSError as walk_err:
|
||||||
|
write_log(f"【严重】遍历目录发生IO异常,部分目录未扫描:{walk_err}", log_path)
|
||||||
|
|
||||||
|
write_log("----------任务统计汇总----------", log_path)
|
||||||
|
write_log(f"总扫描目录:{stat['scan_dir_total']}", log_path)
|
||||||
|
write_log(f"总扫描文件:{stat['scan_file_total']},媒体文件:{stat['media_file_total']}", log_path)
|
||||||
|
write_log(f"目录:成功创建 {stat['dir_success']},失败 {stat['dir_fail']}", log_path)
|
||||||
|
write_log(f"文件:成功复制 {stat['file_success']},失败 {stat['file_fail']}", log_path)
|
||||||
|
write_log("============================================================", log_path)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,274 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
import argparse
|
||||||
|
import shutil
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# ====================== 【配置区】 ======================
|
||||||
|
LOG_FILE = "./rename_log.txt"
|
||||||
|
|
||||||
|
# 需要完全跳过的目录名称(basename,大小写敏感)
|
||||||
|
SKIP_DIRS = [
|
||||||
|
"@eaDir", # 群晖隐含目录
|
||||||
|
]
|
||||||
|
|
||||||
|
# 需要跳过的隐含文件名称(完整文件名匹配)
|
||||||
|
SKIP_FILES = {
|
||||||
|
".DS_Store",
|
||||||
|
"Thumbs.db",
|
||||||
|
"desktop.ini",
|
||||||
|
}
|
||||||
|
|
||||||
|
# 文件清洗规则
|
||||||
|
RULES_FILE = [
|
||||||
|
(r"^[A-Za-z] ", ""),
|
||||||
|
(r"\[.*?\]", ""),
|
||||||
|
(r"【.*?】", ""),
|
||||||
|
(r"丨", ""),
|
||||||
|
(r"(?<!\w)(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|BD|BluRay|BLURAY|WEBRip|WEB-DL|HD|4K|中英双语|双语字幕|双语|中文|国语|粤语|台语|韩语|中英双字|国语中字|繁体中字|简体中字|简繁中字|双语中字|官方中字|特效中字)(?!\w)", "", re.IGNORECASE),
|
||||||
|
(r"\.+", ""),
|
||||||
|
(r"\s", ""),
|
||||||
|
(r"[^\u4e00-\u9fa5a-zA-Z0-9().:+\-]", ""),
|
||||||
|
]
|
||||||
|
|
||||||
|
# 文件夹清洗规则
|
||||||
|
RULES_DIR = [
|
||||||
|
(r"【.*?】", ""), # 删除中文全角【】以及内部内容
|
||||||
|
(r"^\[(.*)\]$", r"\1"), # 整串被[]包裹,只剥外层
|
||||||
|
(r"\]\[", ""), # 清除中间碎片 ][
|
||||||
|
(r"^[A-Za-z] ", ""),
|
||||||
|
(r"丨", ""),
|
||||||
|
(r"(?<!\w)(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|BD|BluRay|BLURAY|WEBRip|WEB-DL|HD|4K|中英双语|双语字幕|双语|中文|国语|粤语|台语|韩语|中英双字|国语中字|繁体中字|简体中字|简繁中字|双语中字|官方中字|特效中字)(?!\w)", "", re.IGNORECASE),
|
||||||
|
(r"\.+", ""),
|
||||||
|
(r"\s", ""),
|
||||||
|
(r"\(\)", ""), # 清除英文空括号 ()
|
||||||
|
(r"()", ""), # 清除中文全角空括号 ()
|
||||||
|
(r"[^\u4e00-\u9fa5a-zA-Z0-9().:+\-[\]]", ""), # 允许文件夹内部保留[]
|
||||||
|
]
|
||||||
|
|
||||||
|
#完整全部媒体后缀(不带--strm-mode时使用)
|
||||||
|
FULL_ALLOW_EXT = {".mkv", ".mp4", ".mov", ".srt", ".ass", ".sub", ".strm", ".flv", ".avi", ".wmv", ".ts", ".rmvb", ".webm", ".mp3", ".flac", ".aac", ".wav", ".ogg", ".m4a", ".wma", ".alac", ".rm", ".iso"}
|
||||||
|
# strm模式:仅strm+字幕
|
||||||
|
STRM_ONLY_EXT = {".strm", ".srt", ".ass", ".sub"}
|
||||||
|
|
||||||
|
MAX_FILENAME_LEN = 245 # mac文件名最大安全长度,预留扩展名位置
|
||||||
|
# =======================================================
|
||||||
|
|
||||||
|
def full2half(s):
|
||||||
|
result = []
|
||||||
|
for char in s:
|
||||||
|
code = ord(char)
|
||||||
|
if code == 12288:
|
||||||
|
char = chr(32)
|
||||||
|
elif 65281 <= code <= 65374:
|
||||||
|
char = chr(code - 65248)
|
||||||
|
result.append(char)
|
||||||
|
return "".join(result)
|
||||||
|
|
||||||
|
def clean_file_name(name: str) -> str:
|
||||||
|
name_no_ext, ext = os.path.splitext(name)
|
||||||
|
name_no_ext = full2half(name_no_ext)
|
||||||
|
for item in RULES_FILE:
|
||||||
|
if len(item) == 3:
|
||||||
|
pat, repl, flag = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext, flags=flag)
|
||||||
|
else:
|
||||||
|
pat, repl = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext)
|
||||||
|
name_no_ext = name_no_ext.strip()
|
||||||
|
if len(name_no_ext) > MAX_FILENAME_LEN:
|
||||||
|
name_no_ext = name_no_ext[:MAX_FILENAME_LEN]
|
||||||
|
return name_no_ext + ext
|
||||||
|
|
||||||
|
def clean_dir_name(name: str) -> str:
|
||||||
|
name = full2half(name)
|
||||||
|
year_match = re.search(r"^\[(\d{4})\]$", name)
|
||||||
|
year_str = ""
|
||||||
|
if year_match:
|
||||||
|
year_str = year_match.group(1)
|
||||||
|
|
||||||
|
for item in RULES_DIR:
|
||||||
|
if len(item) == 3:
|
||||||
|
pat, repl, flag = item
|
||||||
|
name = re.sub(pat, repl, name, flags=flag)
|
||||||
|
else:
|
||||||
|
pat, repl = item
|
||||||
|
name = re.sub(pat, repl, name)
|
||||||
|
name = name.strip()
|
||||||
|
if year_str and name:
|
||||||
|
name = f"{name}({year_str})"
|
||||||
|
if len(name) > MAX_FILENAME_LEN:
|
||||||
|
name = name[:MAX_FILENAME_LEN]
|
||||||
|
return name
|
||||||
|
|
||||||
|
def get_quality_tag(filename:str):
|
||||||
|
m = re.search(r"(?<!\w)(2160p|1080p|720p)(?!\w)", filename, re.IGNORECASE)
|
||||||
|
if m:
|
||||||
|
return m.group(1).lower()
|
||||||
|
return None
|
||||||
|
|
||||||
|
def resolve_conflict(dst_dir:str, base_name:str, ext:str, orig_filename:str):
|
||||||
|
candidate = base_name + ext
|
||||||
|
dst_path = os.path.join(dst_dir, candidate)
|
||||||
|
if not os.path.exists(dst_path):
|
||||||
|
return candidate
|
||||||
|
qual = get_quality_tag(orig_filename)
|
||||||
|
if qual:
|
||||||
|
candidate = f"{base_name}({qual}){ext}"
|
||||||
|
dst_path = os.path.join(dst_dir, candidate)
|
||||||
|
if not os.path.exists(dst_path):
|
||||||
|
return candidate
|
||||||
|
idx = 1
|
||||||
|
while True:
|
||||||
|
candidate = f"{base_name}({idx}){ext}"
|
||||||
|
dst_path = os.path.join(dst_dir, candidate)
|
||||||
|
if not os.path.exists(dst_path):
|
||||||
|
return candidate
|
||||||
|
idx +=1
|
||||||
|
|
||||||
|
def write_log(msg: str, log_file: str):
|
||||||
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
line = f"[{now}] {msg}"
|
||||||
|
print(line)
|
||||||
|
try:
|
||||||
|
with open(log_file, "a", encoding="utf-8") as f:
|
||||||
|
f.write(line + "\n")
|
||||||
|
f.flush()
|
||||||
|
except Exception:
|
||||||
|
#日志写入失败降级控制台输出,不打断程序
|
||||||
|
print(f"[LOG-WRITE-FAILED] {line}")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="媒体文件名镜像清洗工具,源目录只读,生成镜像副本")
|
||||||
|
parser.add_argument("--dir", required=True, help="原始源媒体根目录")
|
||||||
|
parser.add_argument("--output", required=True, help="输出镜像根目录")
|
||||||
|
parser.add_argument("--apply", action="store_true", help="加上此参数才执行真实复制生成镜像")
|
||||||
|
parser.add_argument("--dry-run", action="store_true", help="预览模式(默认就是预览,该参数为显式简写)")
|
||||||
|
parser.add_argument("--strm-mode", action="store_true", help="开启strm模式:仅处理 .strm .srt .ass .sub;过滤mkv/mp4等视频文件")
|
||||||
|
parser.add_argument("--log", default="./rename_log.txt", help="日志文件路径,默认 ./rename_log.txt")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
target_dir = args.dir
|
||||||
|
out_dir = args.output
|
||||||
|
log_path = args.log
|
||||||
|
|
||||||
|
DRY_RUN = True
|
||||||
|
if args.apply:
|
||||||
|
DRY_RUN = False
|
||||||
|
if args.dry_run:
|
||||||
|
DRY_RUN = True
|
||||||
|
|
||||||
|
if args.strm_mode:
|
||||||
|
ALLOW_EXT = STRM_ONLY_EXT
|
||||||
|
mode_info = "STRM模式【仅strm+字幕】"
|
||||||
|
else:
|
||||||
|
ALLOW_EXT = FULL_ALLOW_EXT
|
||||||
|
mode_info = "完整媒体模式【全部媒体后缀】"
|
||||||
|
|
||||||
|
if not os.path.isdir(target_dir):
|
||||||
|
print(f"错误:源目录不存在 -> {target_dir}")
|
||||||
|
return
|
||||||
|
|
||||||
|
#初始化日志
|
||||||
|
try:
|
||||||
|
with open(log_path, "w", encoding="utf-8") as f:
|
||||||
|
f.flush()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"警告:无法初始化日志文件 {log_path},后续仅控制台输出日志,异常:{e}")
|
||||||
|
|
||||||
|
write_log("===== 文件名+文件夹清洗【修复参数符号,过滤BD/HD/4K/双语/国语等标记】 =====", log_path)
|
||||||
|
write_log(f"源目录:{target_dir}", log_path)
|
||||||
|
write_log(f"输出镜像目录:{out_dir}", log_path)
|
||||||
|
write_log(f"运行模式:{mode_info}", log_path)
|
||||||
|
write_log(f"预览模式 DRY_RUN = {DRY_RUN}", log_path)
|
||||||
|
if SKIP_DIRS:
|
||||||
|
write_log(f"配置跳过目录名列表:{SKIP_DIRS}", log_path)
|
||||||
|
write_log(f"过滤隐含系统文件:{SKIP_FILES}", log_path)
|
||||||
|
|
||||||
|
stat = {
|
||||||
|
"scan_dir_total":0,
|
||||||
|
"scan_file_total":0,
|
||||||
|
"media_file_total":0,
|
||||||
|
"file_success":0,
|
||||||
|
"file_fail":0,
|
||||||
|
"dir_success":0,
|
||||||
|
"dir_fail":0
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
for root, dirs, files in os.walk(target_dir, topdown=False):
|
||||||
|
#过滤跳过目录:@eaDir、配置SKIP_DIRS
|
||||||
|
remove_idx = []
|
||||||
|
for idx, dname in enumerate(dirs):
|
||||||
|
if dname in SKIP_DIRS:
|
||||||
|
remove_idx.append(idx)
|
||||||
|
for idx in reversed(remove_idx):
|
||||||
|
del dirs[idx]
|
||||||
|
|
||||||
|
stat["scan_dir_total"] += 1
|
||||||
|
rel = os.path.relpath(root, target_dir)
|
||||||
|
if rel == ".":
|
||||||
|
dst_current_dir = out_dir
|
||||||
|
else:
|
||||||
|
src_basename = os.path.basename(root)
|
||||||
|
new_dir_name = clean_dir_name(src_basename)
|
||||||
|
if len(new_dir_name) == 0:
|
||||||
|
write_log(f"【警告】文件夹清洗后名称为空,使用原名保留:{src_basename}", log_path)
|
||||||
|
new_dir_name = src_basename
|
||||||
|
dst_current_dir = os.path.join(out_dir, rel.replace(src_basename, new_dir_name))
|
||||||
|
|
||||||
|
# 创建输出目录
|
||||||
|
if not DRY_RUN:
|
||||||
|
try:
|
||||||
|
os.makedirs(dst_current_dir, exist_ok=True)
|
||||||
|
stat["dir_success"] +=1
|
||||||
|
except OSError as e:
|
||||||
|
stat["dir_fail"] +=1
|
||||||
|
write_log(f"【目录创建失败】{dst_current_dir} | {e}", log_path)
|
||||||
|
|
||||||
|
# 处理本目录全部文件
|
||||||
|
for fname in files:
|
||||||
|
if fname in SKIP_FILES:
|
||||||
|
continue
|
||||||
|
stat["scan_file_total"] +=1
|
||||||
|
ext = os.path.splitext(fname)[1].lower()
|
||||||
|
if ext in ALLOW_EXT:
|
||||||
|
stat["media_file_total"] += 1
|
||||||
|
new_name = clean_file_name(fname)
|
||||||
|
old_path = os.path.join(root, fname)
|
||||||
|
base, ext_out = os.path.splitext(new_name)
|
||||||
|
final_fname = resolve_conflict(dst_current_dir, base, ext_out, fname)
|
||||||
|
dst_file = os.path.join(dst_current_dir, final_fname)
|
||||||
|
|
||||||
|
if final_fname != fname:
|
||||||
|
write_log(f"待修改文件-> {fname} → {final_fname}", log_path)
|
||||||
|
|
||||||
|
if not DRY_RUN:
|
||||||
|
try:
|
||||||
|
shutil.copy2(old_path, dst_file)
|
||||||
|
stat["file_success"] +=1
|
||||||
|
except OSError as e:
|
||||||
|
stat["file_fail"] +=1
|
||||||
|
write_log(f"【文件复制失败】src:{old_path} dst:{dst_file} | 错误:{e}", log_path)
|
||||||
|
|
||||||
|
# 处理子文件夹,只打印名称发生变更的文件夹
|
||||||
|
for dname in dirs:
|
||||||
|
new_name = clean_dir_name(dname)
|
||||||
|
if len(new_name) == 0:
|
||||||
|
write_log(f"【警告】文件夹清洗后名称为空,跳过改名:{dname}", log_path)
|
||||||
|
continue
|
||||||
|
if new_name != dname:
|
||||||
|
write_log(f"待修改文件夹-> {dname} → {new_name}", log_path)
|
||||||
|
|
||||||
|
except OSError as walk_err:
|
||||||
|
write_log(f"【严重】遍历目录发生IO异常,部分目录未扫描:{walk_err}", log_path)
|
||||||
|
|
||||||
|
write_log("----------任务统计汇总----------", log_path)
|
||||||
|
write_log(f"总扫描目录:{stat['scan_dir_total']}", log_path)
|
||||||
|
write_log(f"总扫描文件:{stat['scan_file_total']},媒体文件:{stat['media_file_total']}", log_path)
|
||||||
|
write_log(f"目录:成功创建 {stat['dir_success']},失败 {stat['dir_fail']}", log_path)
|
||||||
|
write_log(f"文件:成功复制 {stat['file_success']},失败 {stat['file_fail']}", log_path)
|
||||||
|
write_log("============================================================", log_path)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
import argparse
|
||||||
|
import shutil
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# ====================== 配置区 ======================
|
||||||
|
RULES_FILE = [
|
||||||
|
(r"^[A-Za-z] ", ""),
|
||||||
|
(r"\[.*?\]", ""),
|
||||||
|
(r"【.*?】", ""),
|
||||||
|
(r"丨", ""),
|
||||||
|
(r"\b(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|中英双语|双语字幕)\b", "", re.IGNORECASE),
|
||||||
|
(r"\.+", ""),
|
||||||
|
(r"\s", ""),
|
||||||
|
(r"[^\u4e00-\u9fa5a-zA-Z0-9().:+-]", ""),
|
||||||
|
]
|
||||||
|
|
||||||
|
RULES_DIR = [
|
||||||
|
(r"^[A-Za-z] ", ""),
|
||||||
|
(r"丨", ""),
|
||||||
|
(r"\b(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|中英双语|双语字幕)\b", "", re.IGNORECASE),
|
||||||
|
(r"\.+", ""),
|
||||||
|
(r"\s", ""),
|
||||||
|
(r"[^\u4e00-\u9fa5a-zA-Z0-9().:+-]", ""),
|
||||||
|
]
|
||||||
|
|
||||||
|
ALLOW_EXT = {".mkv", ".mp4", ".mov", ".srt", ".ass", ".sub", ".strm",".flv",".avi",".wmv",".ts",".rmvb",".webm",".mp3",".flac",".aac",".wav",".ogg",".m4a",".wma",".alac",".rm",".iso"}
|
||||||
|
# ====================================================
|
||||||
|
|
||||||
|
def full2half(s):
|
||||||
|
result = []
|
||||||
|
for char in s:
|
||||||
|
code = ord(char)
|
||||||
|
if code == 12288:
|
||||||
|
char = chr(32)
|
||||||
|
elif 65281 <= code <= 65374:
|
||||||
|
char = chr(code - 65248)
|
||||||
|
result.append(char)
|
||||||
|
return "".join(result)
|
||||||
|
|
||||||
|
def clean_file_name(name: str) -> str:
|
||||||
|
name_no_ext, ext = os.path.splitext(name)
|
||||||
|
name_no_ext = full2half(name_no_ext)
|
||||||
|
for item in RULES_FILE:
|
||||||
|
if len(item) == 3:
|
||||||
|
pat, repl, flag = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext, flags=flag)
|
||||||
|
else:
|
||||||
|
pat, repl = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext)
|
||||||
|
name_no_ext = name_no_ext.strip()
|
||||||
|
return name_no_ext + ext
|
||||||
|
|
||||||
|
def clean_dir_name(name: str) -> str:
|
||||||
|
name = full2half(name)
|
||||||
|
year_match = re.search(r"\[(\d{4})\]", name)
|
||||||
|
year_str = ""
|
||||||
|
if year_match:
|
||||||
|
year_str = year_match.group(1)
|
||||||
|
name = re.sub(r"\[.*?\]", "", name)
|
||||||
|
for item in RULES_DIR:
|
||||||
|
if len(item) == 3:
|
||||||
|
pat, repl, flag = item
|
||||||
|
name = re.sub(pat, repl, name, flags=flag)
|
||||||
|
else:
|
||||||
|
pat, repl = item
|
||||||
|
name = re.sub(pat, repl, name)
|
||||||
|
name = name.strip()
|
||||||
|
if year_str and name:
|
||||||
|
name = f"{name}({year_str})"
|
||||||
|
return name
|
||||||
|
|
||||||
|
def get_quality_tag(filename:str):
|
||||||
|
m = re.search(r"\b(2160p|1080p|720p)\b", filename, re.IGNORECASE)
|
||||||
|
if m:
|
||||||
|
return m.group(1).lower()
|
||||||
|
return None
|
||||||
|
|
||||||
|
def resolve_conflict(dst_dir:str, base_name:str, ext:str, orig_filename:str):
|
||||||
|
"""解决输出目录同名冲突:优先追加画质,无画质则追加(1)(2)"""
|
||||||
|
candidate = base_name + ext
|
||||||
|
dst_path = os.path.join(dst_dir, candidate)
|
||||||
|
if not os.path.exists(dst_path):
|
||||||
|
return candidate
|
||||||
|
|
||||||
|
qual = get_quality_tag(orig_filename)
|
||||||
|
if qual:
|
||||||
|
candidate = f"{base_name}({qual}){ext}"
|
||||||
|
dst_path = os.path.join(dst_dir, candidate)
|
||||||
|
if not os.path.exists(dst_path):
|
||||||
|
return candidate
|
||||||
|
|
||||||
|
idx = 1
|
||||||
|
while True:
|
||||||
|
candidate = f"{base_name}({idx}){ext}"
|
||||||
|
dst_path = os.path.join(dst_dir, candidate)
|
||||||
|
if not os.path.exists(dst_path):
|
||||||
|
return candidate
|
||||||
|
idx +=1
|
||||||
|
|
||||||
|
def write_log(msg: str, log_file: str):
|
||||||
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
line = f"[{now}] {msg}"
|
||||||
|
print(line)
|
||||||
|
with open(log_file, "a", encoding="utf-8") as f:
|
||||||
|
f.write(line + "\n")
|
||||||
|
f.flush()
|
||||||
|
|
||||||
|
def process_tree(src_root:str, dst_root:str, dry_run:bool, log_path:str):
|
||||||
|
stat = {
|
||||||
|
"scan_dir_total":0,
|
||||||
|
"scan_file_total":0,
|
||||||
|
"media_file_total":0,
|
||||||
|
"file_success":0,
|
||||||
|
"file_fail":0,
|
||||||
|
"dir_success":0,
|
||||||
|
"dir_fail":0
|
||||||
|
}
|
||||||
|
|
||||||
|
for src_dir, dirs, files in os.walk(src_root):
|
||||||
|
stat["scan_dir_total"] +=1
|
||||||
|
rel = os.path.relpath(src_dir, src_root)
|
||||||
|
if rel == ".":
|
||||||
|
dst_current_dir = dst_root
|
||||||
|
else:
|
||||||
|
dst_current_dir = os.path.join(dst_root, clean_dir_name(os.path.basename(src_dir)))
|
||||||
|
|
||||||
|
# 创建输出目录
|
||||||
|
if not dry_run:
|
||||||
|
try:
|
||||||
|
os.makedirs(dst_current_dir, exist_ok=True)
|
||||||
|
stat["dir_success"] +=1
|
||||||
|
except Exception as e:
|
||||||
|
stat["dir_fail"] +=1
|
||||||
|
write_log(f"【目录创建失败】{dst_current_dir} | {e}", log_path)
|
||||||
|
else:
|
||||||
|
write_log(f"【预览-输出目录】{dst_current_dir}", log_path)
|
||||||
|
|
||||||
|
# 处理本目录全部文件
|
||||||
|
for fname in files:
|
||||||
|
stat["scan_file_total"] += 1
|
||||||
|
src_file = os.path.join(src_dir, fname)
|
||||||
|
ext = os.path.splitext(fname)[1].lower()
|
||||||
|
if ext in ALLOW_EXT:
|
||||||
|
stat["media_file_total"] +=1
|
||||||
|
new_fname = clean_file_name(fname)
|
||||||
|
base, ext_out = os.path.splitext(new_fname)
|
||||||
|
final_fname = resolve_conflict(dst_current_dir, base, ext_out, fname)
|
||||||
|
dst_file = os.path.join(dst_current_dir, final_fname)
|
||||||
|
write_log(f"待复制文件-> {fname} → {final_fname}", log_path)
|
||||||
|
if not dry_run:
|
||||||
|
try:
|
||||||
|
shutil.copy2(src_file, dst_file)
|
||||||
|
stat["file_success"] +=1
|
||||||
|
except Exception as e:
|
||||||
|
stat["file_fail"] +=1
|
||||||
|
write_log(f"【文件复制失败】src:{src_file} dst:{dst_file} | {e}", log_path)
|
||||||
|
return stat
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="媒体文件名镜像清洗工具,源目录只读,输出全新镜像目录")
|
||||||
|
parser.add_argument("--dir", required=True, help="原始源媒体根目录")
|
||||||
|
parser.add_argument("--output", required=True, help="输出镜像根目录")
|
||||||
|
parser.add_argument("--apply", action="store_true", help="加上此参数才真正复制生成镜像;默认预览dry‑run")
|
||||||
|
parser.add_argument("--log", default="./rename_log.txt", help="日志文件路径,默认同脚本目录rename_log.txt")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
src_dir = args.dir
|
||||||
|
out_dir = args.output
|
||||||
|
dry_run = not args.apply
|
||||||
|
log_path = args.log
|
||||||
|
|
||||||
|
if not os.path.isdir(src_dir):
|
||||||
|
print(f"错误:源目录不存在 -> {src_dir}")
|
||||||
|
return
|
||||||
|
|
||||||
|
with open(log_path, "w", encoding="utf-8") as f:
|
||||||
|
f.flush()
|
||||||
|
|
||||||
|
write_log("===== 媒体文件名镜像清洗【源目录只读,生成镜像副本】 =====", log_path)
|
||||||
|
write_log(f"源目录:{src_dir}", log_path)
|
||||||
|
write_log(f"输出镜像目录:{out_dir}", log_path)
|
||||||
|
write_log(f"预览模式 DRY_RUN = {dry_run}", log_path)
|
||||||
|
|
||||||
|
stat = process_tree(src_dir, out_dir, dry_run, log_path)
|
||||||
|
|
||||||
|
write_log("----------任务统计汇总----------", log_path)
|
||||||
|
write_log(f"总扫描目录:{stat['scan_dir_total']}", log_path)
|
||||||
|
write_log(f"总扫描文件:{stat['scan_file_total']},媒体文件:{stat['media_file_total']}", log_path)
|
||||||
|
write_log(f"目录:成功创建 {stat['dir_success']},失败 {stat['dir_fail']}", log_path)
|
||||||
|
write_log(f"文件:成功复制 {stat['file_success']},失败 {stat['file_fail']}", log_path)
|
||||||
|
write_log("============================================================", log_path)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
import argparse
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# ====================== 【配置区,不再写死目录】 ======================
|
||||||
|
LOG_FILE = "./rename_log.txt"
|
||||||
|
|
||||||
|
# 清洗规则
|
||||||
|
RULES = [
|
||||||
|
(r"^[A-Za-z] ", ""), #1.移除开头单个字母+空格
|
||||||
|
(r"\[.*?\]", ""), #2.移除英文方括号及内部内容
|
||||||
|
(r"【.*?】", ""), #3.移除中文【】及内部内容
|
||||||
|
(r"丨", ""), #清除汉字竖线 丨
|
||||||
|
(r"\b(2160p|1080p|720p|HDR|DV|DoVi|HEVC|x265|x264|DDP|AAC|Atmos|TrueHD|中英双语|双语字幕)\b", "", re.IGNORECASE),
|
||||||
|
(r"\.+", ""), #删除连续的点
|
||||||
|
(r"\s", ""), #删除全部空格
|
||||||
|
# 保留:汉字、半角英文、数字、半角 () . : + -
|
||||||
|
(r"[^\u4e00-\u9fa5a-zA-Z0-9().:+-]", ""),
|
||||||
|
]
|
||||||
|
ALLOW_EXT = {".mkv", ".mp4", ".mov", ".srt", ".ass", ".sub", ".strm",".flv",".avi",".wmv",".ts",".rmvb",".webm",".mp3",".flac",".aac",".wav",".ogg",".m4a",".wma",".alac",".rm",".iso"}
|
||||||
|
|
||||||
|
|
||||||
|
# ====================================================================
|
||||||
|
|
||||||
|
def clean_filename(name: str) -> str:
|
||||||
|
name_no_ext, ext = os.path.splitext(name)
|
||||||
|
# 全角转半角
|
||||||
|
def full2half(s):
|
||||||
|
result = []
|
||||||
|
for char in s:
|
||||||
|
code = ord(char)
|
||||||
|
if code == 12288:
|
||||||
|
char = chr(32)
|
||||||
|
elif 65281 <= code <= 65374:
|
||||||
|
char = chr(code - 65248)
|
||||||
|
result.append(char)
|
||||||
|
return "".join(result)
|
||||||
|
name_no_ext = full2half(name_no_ext)
|
||||||
|
|
||||||
|
for item in RULES:
|
||||||
|
if len(item) == 3:
|
||||||
|
pat, repl, flag = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext, flags=flag)
|
||||||
|
else:
|
||||||
|
pat, repl = item
|
||||||
|
name_no_ext = re.sub(pat, repl, name_no_ext)
|
||||||
|
name_no_ext = name_no_ext.strip()
|
||||||
|
return name_no_ext + ext
|
||||||
|
|
||||||
|
def write_log(msg: str):
|
||||||
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
line = f"[{now}] {msg}"
|
||||||
|
print(line)
|
||||||
|
with open(LOG_FILE, "a", encoding="utf-8") as f:
|
||||||
|
f.write(line + "\n")
|
||||||
|
f.flush()
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="媒体文件名批量清洗重命名工具")
|
||||||
|
parser.add_argument("--dir", required=True, help="目标根目录路径")
|
||||||
|
parser.add_argument("--apply", action="store_true", help="加上此参数才执行真实重命名;默认仅预览DryRun")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
target_dir = args.dir
|
||||||
|
DRY_RUN = not args.apply
|
||||||
|
|
||||||
|
# 校验目录是否存在
|
||||||
|
if not os.path.isdir(target_dir):
|
||||||
|
print(f"错误:目录不存在 -> {target_dir}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 每次运行前清空日志文件
|
||||||
|
with open(LOG_FILE, "w", encoding="utf-8") as f:
|
||||||
|
f.flush()
|
||||||
|
|
||||||
|
write_log("===== 文件名+文件夹清洗(移除开头A 中文片名前缀) =====")
|
||||||
|
write_log(f"根目录:{target_dir}")
|
||||||
|
write_log(f"预览模式 DRY_RUN = {DRY_RUN}")
|
||||||
|
|
||||||
|
file_rename_list = []
|
||||||
|
dir_rename_list = []
|
||||||
|
total_scan_dirs = 0
|
||||||
|
total_all_files = 0 # 全部扫描到的文件(所有后缀)
|
||||||
|
total_media_files = 0 # 媒体文件(ALLOW_EXT后缀)
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk(target_dir, topdown=False):
|
||||||
|
total_scan_dirs += 1
|
||||||
|
for fname in files:
|
||||||
|
total_all_files +=1
|
||||||
|
ext = os.path.splitext(fname)[1].lower()
|
||||||
|
if ext in ALLOW_EXT:
|
||||||
|
total_media_files += 1
|
||||||
|
new_name = clean_filename(fname)
|
||||||
|
if new_name != fname:
|
||||||
|
old_path = os.path.join(root, fname)
|
||||||
|
new_path = os.path.join(root, new_name)
|
||||||
|
file_rename_list.append((old_path, new_path))
|
||||||
|
write_log(f"待修改文件-> {fname} → {new_name}")
|
||||||
|
|
||||||
|
# 处理文件夹
|
||||||
|
for dname in dirs:
|
||||||
|
new_name = clean_filename(dname)
|
||||||
|
if new_name != dname:
|
||||||
|
old_path = os.path.join(root, dname)
|
||||||
|
new_path = os.path.join(root, new_name)
|
||||||
|
dir_rename_list.append((old_path, new_name))
|
||||||
|
write_log(f"待修改文件夹-> {dname} → {new_name}")
|
||||||
|
|
||||||
|
# ========== 执行阶段 ==========
|
||||||
|
if not DRY_RUN:
|
||||||
|
# 先文件
|
||||||
|
for old, new in file_rename_list:
|
||||||
|
try:
|
||||||
|
os.rename(old, new)
|
||||||
|
except Exception as e:
|
||||||
|
write_log(f"【文件重命名失败】{old} -> {new} | 错误:{e}")
|
||||||
|
# 后文件夹
|
||||||
|
for old, new in dir_rename_list:
|
||||||
|
try:
|
||||||
|
os.rename(old, new)
|
||||||
|
except Exception as e:
|
||||||
|
write_log(f"【文件夹重命名失败】{old} -> {new} | 错误:{e}")
|
||||||
|
|
||||||
|
# 最终汇总输出
|
||||||
|
write_log(f"任务完成,总扫描目录:{total_scan_dirs},待修改文件夹:{len(dir_rename_list)}")
|
||||||
|
write_log(f"总扫描文件:{total_all_files},媒体文件:{total_media_files},待修改文件:{len(file_rename_list)}")
|
||||||
|
write_log("============================================================")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Executable
+7833
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,489 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "dir",
|
||||||
|
"orig_basename": "洛杉矶劫案.2160p.6v电影 地址发布页 www.6v123.net 收藏不迷路",
|
||||||
|
"step1_name": "洛杉矶劫案.2160p.6v电影地址发布页www.6v123.net收藏不迷路",
|
||||||
|
"step2_name": "洛杉矶劫案_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"D001",
|
||||||
|
"D003"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "dir",
|
||||||
|
"orig_basename": "劫机",
|
||||||
|
"step1_name": "劫机",
|
||||||
|
"step2_name": "劫机_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "4K.strm",
|
||||||
|
"step1_name": "4K.strm",
|
||||||
|
"step2_name": "strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F003"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "1080p.strm",
|
||||||
|
"step1_name": "1080p.strm",
|
||||||
|
"step2_name": "strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F003"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "云边有个小卖部_1080P.strm",
|
||||||
|
"step1_name": "云边有个小卖部_1080P.strm",
|
||||||
|
"step2_name": "云边有个小卖部.strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F003"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "1080p.strm",
|
||||||
|
"step1_name": "1080p.strm",
|
||||||
|
"step2_name": "strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F003"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "1080p.strm",
|
||||||
|
"step1_name": "1080p.strm",
|
||||||
|
"step2_name": "strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F003"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[迅雷下载www.2tu.cc]鬼子来了.BD1280高清国语中字.strm",
|
||||||
|
"step1_name": "[迅雷下载www.2tu.cc]鬼子来了.BD1280高清国语中字.strm",
|
||||||
|
"step2_name": "鬼子来了.1280高清国语中字.strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F003"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "【太平洋幽灵.Against the Sun】【高清720P版HD-RMVB.中字】.strm",
|
||||||
|
"step1_name": "【太平洋幽灵.AgainsttheSun】【高清720P版HD-RMVB.中字】.strm",
|
||||||
|
"step2_name": "strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F002"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "【Journey.To.The.West.Conquering.The.Demons】【高清版DVD-RMVB.国语中英双字】.strm",
|
||||||
|
"step1_name": "【Journey.To.The.West.Conquering.The.Demons】【高清版DVD-RMVB.国语中英双字】.strm",
|
||||||
|
"step2_name": "strm_dup(2)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F002"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "【The.Marine.3.Homefront】【高清1280版BD-RMVB.中英双字】.strm",
|
||||||
|
"step1_name": "【The.Marine.3.Homefront】【高清1280版BD-RMVB.中英双字】.strm",
|
||||||
|
"step2_name": "strm_dup(3)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F002"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "加勒比海盗4.strm",
|
||||||
|
"step1_name": "加勒比海盗4.strm",
|
||||||
|
"step2_name": "加勒比海盗4.strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "1080P.strm",
|
||||||
|
"step1_name": "1080P.strm",
|
||||||
|
"step2_name": "strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F003"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "猎杀红色十月.The.Hunt.for.Red.October.1990.BD1080p.X264.2Audio.AAC.HALFCD-NORM.Christian.strm",
|
||||||
|
"step1_name": "猎杀红色十月.The.Hunt.for.Red.October.1990.BD1080p.X264.2Audio.AAC.HALFCD-NORM.Christian.strm",
|
||||||
|
"step2_name": "猎杀红色十月.The.Hunt.for.Red.October.1990.2Audio.HALFCD-NORM.Christian.strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F003"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[1982][CN][逆光]Ni.Guang.TVRip.Xvid-Mustdown[www.ed2kers.com].strm",
|
||||||
|
"step1_name": "[1982][CN][逆光]Ni.Guang.TVRip.Xvid-Mustdown[www.ed2kers.com].strm",
|
||||||
|
"step2_name": "Ni.Guang.TVRip.Xvid-Mustdown.strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[唐山大兄.cd1.1971.国粵双语].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[唐山大兄.cd1.1971.国粵双语].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[死亡游戏.cd2.1978].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[死亡游戏.cd2.1978].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(2)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[死亡游戏.cd1.1978].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[死亡游戏.cd1.1978].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(3)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[死亡塔.cd2.1981].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[死亡塔.cd2.1981].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(4)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[死亡塔.cd1.1981].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[死亡塔.cd1.1981].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(5)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[猛龙过江.cd2.1972.国粵双语].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[猛龙过江.cd2.1972.国粵双语].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(6)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[猛龙过江.cd1.1972.国粵双语].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[猛龙过江.cd1.1972.国粵双语].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(7)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[龙争虎斗.cd2.1973.国粵双语].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[龙争虎斗.cd2.1973.国粵双语].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(8)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[龙争虎斗.cd1.1973.国粵双语].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[龙争虎斗.cd1.1973.国粵双语].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(9)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[精武门.cd2.1972.国粵双语].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[精武门.cd2.1972.国粵双语].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(10)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[精武门.cd1.1972.国粵双语].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[精武门.cd1.1972.国粵双语].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(11)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[开心鬼4.1989.国粤双语.简繁中字].暮云春树.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[开心鬼4.1989.国粤双语.简繁中字].暮云春树.strm",
|
||||||
|
"step2_name": "暮云春树.strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[开心鬼2.1985.国粤双语.简繁中字].tdw9430.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[开心鬼2.1985.国粤双语.简繁中字].tdw9430.strm",
|
||||||
|
"step2_name": "strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[开心鬼1.1984.国粤双语.简繁中字].tdw9430.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[开心鬼1.1984.国粤双语.简繁中字].tdw9430.strm",
|
||||||
|
"step2_name": "strm_dup(2)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[极限特工Ⅰ.2002.中英字幕].九洲客.strm",
|
||||||
|
"step1_name": "[极限特工Ⅰ.2002.中英字幕].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn [黑客帝国 3.2003.中英字幕].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[黑客帝国3.2003.中英字幕].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn [黑客帝国 2.2003.中英字幕].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[黑客帝国2.2003.中英字幕].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(2)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn [黑客帝国 1.1999.中英字幕].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[黑客帝国1.1999.中英字幕].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(3)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[非常人贩2.2005.中英字幕].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[非常人贩2.2005.中英字幕].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[SCG-CMCT]www.dream2008.cn[非常人贩1.2002.中英字幕].九洲客.strm",
|
||||||
|
"step1_name": "[SCG-CMCT]www.dream2008.cn[非常人贩1.2002.中英字幕].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(2)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[电锯惊魂Ⅳ.2007.中英字幕].九洲客.strm",
|
||||||
|
"step1_name": "[电锯惊魂Ⅳ.2007.中英字幕].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[电锯惊魂Ⅲ.2006.中英字幕].九洲客.strm",
|
||||||
|
"step1_name": "[电锯惊魂Ⅲ.2006.中英字幕].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(2)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[电锯惊魂Ⅱ.2005.中英字幕].九洲客.strm",
|
||||||
|
"step1_name": "[电锯惊魂Ⅱ.2005.中英字幕].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(3)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[电锯惊魂Ⅰ.2004.中英字幕].九洲客.strm",
|
||||||
|
"step1_name": "[电锯惊魂Ⅰ.2004.中英字幕].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(4)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[第一滴血Ⅲ.1988.中英字幕].九洲客.strm",
|
||||||
|
"step1_name": "[第一滴血Ⅲ.1988.中英字幕].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(1)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[第一滴血Ⅱ.1985.中英字幕].九洲客.strm",
|
||||||
|
"step1_name": "[第一滴血Ⅱ.1985.中英字幕].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(2)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"orig_basename": "[第一滴血Ⅰ.1982.中英字幕].九洲客.strm",
|
||||||
|
"step1_name": "[第一滴血Ⅰ.1982.中英字幕].九洲客.strm",
|
||||||
|
"step2_name": "strm_dup(3)",
|
||||||
|
"step2_dup_warn": true,
|
||||||
|
"safe_guard_trigger": false,
|
||||||
|
"hit_rule_ids": [
|
||||||
|
"F001",
|
||||||
|
"F006"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
watcher.py —— 自研媒体刮削「监听服务」
|
||||||
|
|
||||||
|
功能:
|
||||||
|
1. 用 watchdog 监听「清理后媒体目录」
|
||||||
|
2. 检测到新媒体文件/目录写入稳定后,自动调用 media_scraper 刮削
|
||||||
|
3. 刮削结果(媒体 + nfo + 海报)复制落库到成品目录
|
||||||
|
4. 源目录保持原样,不写入任何文件
|
||||||
|
|
||||||
|
用法:
|
||||||
|
./watcher.py --config config.json # 常驻服务
|
||||||
|
./watcher.py --config config.json --once # 只扫描一次现有内容后退出(用于初始化存量)
|
||||||
|
|
||||||
|
config.json 字段:
|
||||||
|
{
|
||||||
|
"source": "<清理后媒体目录>",
|
||||||
|
"dest": "<成品落库目录>",
|
||||||
|
"tmdb_api_key": "", # TMDB API Key;留空时用 --mock 跑通管线
|
||||||
|
"mock": true, # true=模拟元数据(无Key验证用);true后配好Key改为 false
|
||||||
|
"settle": 6, # 写入稳定等待秒数
|
||||||
|
"language": "zh-CN"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
from watchdog.events import FileSystemEventHandler
|
||||||
|
from watchdog.observers import Observer
|
||||||
|
|
||||||
|
# 复用核心刮削器
|
||||||
|
from media_scraper import (Config, Scraper, clean_ext, VIDEO_EXTS,
|
||||||
|
scan_and_scrape)
|
||||||
|
|
||||||
|
|
||||||
|
class Config2(Config):
|
||||||
|
"""扩展 Config:加载 watcher 的 source/dest/settle。"""
|
||||||
|
|
||||||
|
def __init__(self, path):
|
||||||
|
super().__init__(path)
|
||||||
|
data = json.load(open(path, encoding="utf-8"))
|
||||||
|
self.source = os.path.abspath(data.get("source", ""))
|
||||||
|
self.dest = os.path.abspath(data.get("dest", ""))
|
||||||
|
self.settle = int(data.get("settle", 6))
|
||||||
|
self.mock = data.get("mock", False)
|
||||||
|
if self.mock:
|
||||||
|
self.tmdb_api_key = "" # mock 模式不需要 key
|
||||||
|
|
||||||
|
|
||||||
|
class ScraperWorker:
|
||||||
|
"""把新媒体单元交给刮削器,带去重与写入稳定判定。"""
|
||||||
|
|
||||||
|
def __init__(self, cfg, log):
|
||||||
|
self.cfg = cfg
|
||||||
|
self.log = log
|
||||||
|
self.scraper = Scraper(cfg, cfg.dest, source_root=cfg.source, log=log)
|
||||||
|
self.processed = set() # 已处理的绝对路径
|
||||||
|
self.lock = threading.Lock()
|
||||||
|
os.makedirs(cfg.dest, exist_ok=True)
|
||||||
|
|
||||||
|
def _is_stable(self, path):
|
||||||
|
"""判断文件/目录是否写入稳定:两次采样大小一致,最多等 settle 秒。"""
|
||||||
|
def size(p):
|
||||||
|
if os.path.isfile(p):
|
||||||
|
return os.path.getsize(p)
|
||||||
|
# 目录:取所有文件大小之和
|
||||||
|
try:
|
||||||
|
return sum(os.path.getsize(os.path.join(r, f))
|
||||||
|
for r, _, fs in os.walk(p) for f in fs)
|
||||||
|
except OSError:
|
||||||
|
return -1
|
||||||
|
last = size(path)
|
||||||
|
wait = self.cfg.settle
|
||||||
|
while wait > 0:
|
||||||
|
time.sleep(min(wait, 2))
|
||||||
|
wait -= 2
|
||||||
|
cur = size(path)
|
||||||
|
if cur == last and cur >= 0:
|
||||||
|
return True
|
||||||
|
last = cur
|
||||||
|
return True
|
||||||
|
|
||||||
|
def handle(self, path):
|
||||||
|
path = os.path.abspath(path)
|
||||||
|
if not os.path.exists(path):
|
||||||
|
return
|
||||||
|
key = path if os.path.isdir(path) else os.path.dirname(path)
|
||||||
|
with self.lock:
|
||||||
|
if key in self.processed:
|
||||||
|
return
|
||||||
|
self.processed.add(key)
|
||||||
|
try:
|
||||||
|
self.log(f"检测到新媒体: {path},等待写入稳定…")
|
||||||
|
self._is_stable(path)
|
||||||
|
self.log(f"开始刮削: {path}")
|
||||||
|
scan_and_scrape(path, self.cfg.dest, self.scraper)
|
||||||
|
self.log(f"完成: {path}")
|
||||||
|
except Exception as e:
|
||||||
|
self.log(f"处理失败 {path}: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
class MediaHandler(FileSystemEventHandler):
|
||||||
|
def __init__(self, worker):
|
||||||
|
self.worker = worker
|
||||||
|
self._threads = []
|
||||||
|
self.lock = threading.Lock()
|
||||||
|
|
||||||
|
def _dispatch(self, path):
|
||||||
|
if os.path.basename(path).startswith("."): # 隐藏/临时文件
|
||||||
|
return
|
||||||
|
ext = clean_ext(path)
|
||||||
|
if ext in VIDEO_EXTS or os.path.isdir(path):
|
||||||
|
t = threading.Thread(target=self.worker.handle, args=(path,),
|
||||||
|
daemon=True)
|
||||||
|
t.start()
|
||||||
|
with self.lock:
|
||||||
|
self._threads.append(t)
|
||||||
|
self._threads = [x for x in self._threads if x.is_alive()]
|
||||||
|
|
||||||
|
def on_created(self, event):
|
||||||
|
self._dispatch(event.src_path)
|
||||||
|
|
||||||
|
def on_moved(self, event):
|
||||||
|
# 下载工具常见:先 .part 再改名成正式名,此时事件是 moved
|
||||||
|
if not event.dest_path.endswith(".part"):
|
||||||
|
self._dispatch(event.dest_path)
|
||||||
|
|
||||||
|
def on_closed(self, event):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
ap = argparse.ArgumentParser(description="自研媒体刮削监听服务")
|
||||||
|
ap.add_argument("--config", required=True, help="config.json 路径")
|
||||||
|
ap.add_argument("--once", action="store_true",
|
||||||
|
help="扫描现有内容一次后退出(初始化存量)")
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
cfg = Config2(args.config)
|
||||||
|
if not cfg.source or not os.path.isdir(cfg.source):
|
||||||
|
print(f"配置错误:source 不存在或未设置 -> {cfg.source}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def log(msg):
|
||||||
|
line = f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {msg}"
|
||||||
|
print(line)
|
||||||
|
# 追加写日志文件
|
||||||
|
logfile = os.path.join(cfg.dest, "..", "scraper.log")
|
||||||
|
try:
|
||||||
|
with open(logfile, "a", encoding="utf-8") as f:
|
||||||
|
f.write(line + "\n")
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
worker = ScraperWorker(cfg, log)
|
||||||
|
|
||||||
|
# 启动时先扫描一次现有内容(这样重启服务能补处理之前漏掉的媒体)
|
||||||
|
for entry in os.listdir(cfg.source):
|
||||||
|
p = os.path.join(cfg.source, entry)
|
||||||
|
if os.path.isdir(p) or clean_ext(p) in VIDEO_EXTS:
|
||||||
|
worker.handle(p)
|
||||||
|
if args.once:
|
||||||
|
log("存量扫描完成,退出")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 常驻监听
|
||||||
|
handler = MediaHandler(worker)
|
||||||
|
observer = Observer()
|
||||||
|
observer.schedule(handler, cfg.source, recursive=False)
|
||||||
|
observer.start()
|
||||||
|
log(f"开始监听: {cfg.source} -> 成品目录: {cfg.dest}")
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
time.sleep(2)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
observer.stop()
|
||||||
|
observer.join()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
# 自研媒体刮削监听服务 —— 使用说明
|
||||||
|
|
||||||
|
一个 Python 服务:监听「清理后媒体目录」,新媒体出现自动刮削(TMDB),结果**复制**落库到成品目录。
|
||||||
|
已在本机 macOS 用 mock 模式跑通整条链路(监听 → 识别 → 刮削 → 复制落库)。
|
||||||
|
|
||||||
|
## 文件清单
|
||||||
|
|
||||||
|
| 文件 | 职责 |
|
||||||
|
|---|---|
|
||||||
|
| `media_scraper.py` | 核心刮削器:文件名解析 → TMDB 查询 → 生成 nfo(Kodi规范) → 下载海报 → 复制落库 |
|
||||||
|
| `watcher.py` | 监听服务:watchdog 监听清理目录,写入稳定后自动触发刮削 |
|
||||||
|
| `config.json` | 配置:源目录、成品目录、TMDB Key、mock 开关 |
|
||||||
|
| `.venv/` | 本地 Python 环境(已装 watchdog、requests) |
|
||||||
|
|
||||||
|
## 快速上手(本地 macOS)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1) 已准备好 .venv(watchdog、requests 已装)。若新环境:
|
||||||
|
python3 -m venv .venv
|
||||||
|
./.venv/bin/pip install watchdog requests
|
||||||
|
|
||||||
|
# 2) 先 mock 跑通管线(无需 Key,验证 nfo 生成 + 复制落库)
|
||||||
|
./.venv/bin/python watcher.py --config config.json --once
|
||||||
|
|
||||||
|
# 3) 配好 TMDB Key 后真刮削
|
||||||
|
# 在 config.json 填 tmdb_api_key,并把 "mock": true 改成 false
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置(config.json)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"source": "/vol1/media/cleaned", // 你的清理后媒体目录(media_final.py 的输出)
|
||||||
|
"dest": "/vol1/media/library", // 成品落库目录(刮削+复制后)
|
||||||
|
"tmdb_api_key": "", // TMDB API Key(themoviedb.org/settings/api 免费申请)
|
||||||
|
"mock": true, // true=模拟元数据;配好 Key 后改 false
|
||||||
|
"settle": 6, // 写入稳定等待秒数(大文件拷贝完再处理)
|
||||||
|
"language": "zh-CN" // 刮削文案语言
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> `mock: true` 时不需要 Key,用于无网络/无 Key 环境下验证整条管线;正式使用务必 `mock: false` + 填 Key。
|
||||||
|
|
||||||
|
## 部署到飞牛 fnOS
|
||||||
|
|
||||||
|
飞牛基于 Linux(Debian)。推荐用 Python3 + systemd(或直接用容器把本目录挂进去跑)。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /你的项目目录
|
||||||
|
python3 -m venv .venv
|
||||||
|
.venv/bin/pip install watchdog requests
|
||||||
|
# 编辑 config.json,把 source/dest 改成飞牛上的真实路径,填 TMDB Key,mock 改 false
|
||||||
|
|
||||||
|
# 常驻运行(前台,Ctrl+C 停止)
|
||||||
|
.venv/bin/python watcher.py --config config.json
|
||||||
|
|
||||||
|
# 后台常驻(nohup)
|
||||||
|
nohup .venv/bin/python watcher.py --config config.json > scraper.out 2>&1 &
|
||||||
|
|
||||||
|
# 或用 systemd 自启(推荐)
|
||||||
|
# 项目里已附 media-scraper.service:先把它里面 3 处「/你的项目绝对路径」改成飞牛真实路径
|
||||||
|
sudo cp media-scraper.service /etc/systemd/system/
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable --now media-scraper # 开机自启 + 立即启动
|
||||||
|
journalctl -u media-scraper -f # 看日志
|
||||||
|
```
|
||||||
|
|
||||||
|
## 命令行用法(media_scraper.py 单条/批量)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 处理单个媒体文件或目录
|
||||||
|
./.venv/bin/python media_scraper.py --source "阿凡达(2009).mkv" --dest /成品目录
|
||||||
|
|
||||||
|
# 递归处理某目录下所有新媒体
|
||||||
|
./.venv/bin/python media_scraper.py --source /清理目录 --dest /成品目录 --recurse
|
||||||
|
|
||||||
|
# 预览不落盘
|
||||||
|
./.venv/bin/python media_scraper.py --source xx --dest yy --dry-run
|
||||||
|
|
||||||
|
# mock 模式(无 Key 验证)
|
||||||
|
./.venv/bin/python media_scraper.py --source xx --dest yy --mock
|
||||||
|
```
|
||||||
|
|
||||||
|
## 行为与命名约定
|
||||||
|
|
||||||
|
- **电影**:单文件 `阿凡达(2009).mkv` 或电影目录 → 复制后生成 `阿凡达(2009).nfo` + 海报。
|
||||||
|
- **剧集**:目录内文件带 `S01E01` / `第01集` / `E01` → 识别为剧集 → 生成 `tvshow.nfo` + 每集 `xxx.nfo` + 海报。
|
||||||
|
- **落库方式**:始终「复制」,源目录保持原样、不写入任何文件。
|
||||||
|
- **安全保护**:目标路径若与源相同会直接报错终止,绝不误删源目录。
|
||||||
|
|
||||||
|
## 已知限制(诚实说明)
|
||||||
|
|
||||||
|
- 数据源仅 TMDB 单一来源;冷门片/非主流命名可能匹配不准。
|
||||||
|
- 海报下载依赖能访问 TMDB 图片服务器;国内网络可能需代理或换 TMDB 备用源。
|
||||||
|
- 单集文件若无季信息默认按第 1 季处理;建议目录按「剧名(年份)/剧名.SxxExx.mkv」组织识别最准。
|
||||||
|
- nfo 字段已覆盖 title/year/rating/plot/uniqueid/genre/**director/studio/actor** 等核心项;如需更多字段可再扩展。演员、导演、制片厂来自 TMDB credits 接口,连不上时为空白但不影响 nfo 生成。
|
||||||
|
|
||||||
|
## 验证方式
|
||||||
|
|
||||||
|
- 本机已用 mock 跑通:电影、剧集目录、单集均正确复制 + 生成 nfo,且实时监听投放新文件能自动触发刮削落库。
|
||||||
|
- 部署后自查:往 `source` 丢一个清理后的影片,几秒后检查 `dest` 是否出现「媒体副本 + .nfo(+ 海报)」。
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
SecretId,SecretKey
|
||||||
|
AKIDh8RvFOL6h6JI3av2ykJemhPvEMMp7E7p,Yu30sY0HNIYeXHpDOL6g2XxCG8nNkxzs
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -0,0 +1,280 @@
|
|||||||
|
.timeline.spaced-lines ul:not(ul ul) > li:nth-child(3n) p {
|
||||||
|
line-height: 1.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline {
|
||||||
|
--timeline-active-color: var(--background-modifier-success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.active-color-background-modifier-success {
|
||||||
|
--timeline-active-color: var(--background-modifier-success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.active-color-background-modifier-error {
|
||||||
|
--timeline-active-color: var(--background-modifier-error);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.active-color-background-modifier-error-hover {
|
||||||
|
--timeline-active-color: var(--background-modifier-error-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.active-color-text-accent {
|
||||||
|
--timeline-active-color: var(--text-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.active-color-text-accent-hover {
|
||||||
|
--timeline-active-color: var(--text-accent-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.active-color-text-error {
|
||||||
|
--timeline-active-color: var(--text-error);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.active-color-text-error-hover {
|
||||||
|
--timeline-active-color: var(--text-error-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.active-color-text-selection {
|
||||||
|
--timeline-active-color: var(--text-selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.active-color-interactive-accent {
|
||||||
|
--timeline-active-color: var(--interactive-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.active-color-interactive-accent-hover {
|
||||||
|
--timeline-active-color: var(--interactive-accent-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.active-color-interactive-success {
|
||||||
|
--timeline-active-color: var(--interactive-success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline ul:not(ul ul) {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto auto 1fr;
|
||||||
|
column-gap: 1.5rem;
|
||||||
|
margin: 2.3rem 0;
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li > *:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li > *:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li:nth-child(3n), .timeline ul:not(ul ul) > li:nth-child(3n+2) {
|
||||||
|
grid-column: 3;
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li:nth-child(3n+1), .timeline ul:not(ul ul) > li:nth-child(3n+2) {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0.4em 0;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li:nth-child(3n+1) > *, .timeline ul:not(ul ul) > li:nth-child(3n+2) > * {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li:nth-child(3n+1) {
|
||||||
|
grid-column: 1;
|
||||||
|
position: relative;
|
||||||
|
justify-self: right;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li:nth-child(3n+1)::before, .timeline ul:not(ul ul) > li:nth-child(3n+1)::after {
|
||||||
|
content: " ";
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 0.5rem;
|
||||||
|
right: -2rem;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li:nth-child(3n+1)::before {
|
||||||
|
background-color: var(--background-primary);
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li:nth-child(3n+1)::after {
|
||||||
|
background-color: var(--text-normal);
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li:nth-child(3n) {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 4.5rem;
|
||||||
|
padding-top: 0.4em;
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li:nth-child(3n)::after {
|
||||||
|
content: " ";
|
||||||
|
position: absolute;
|
||||||
|
border-bottom: 0.1rem dashed var(--text-normal);
|
||||||
|
opacity: 0.1;
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
bottom: -2.25rem;
|
||||||
|
transform: translateY(50%);
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li:nth-child(3n):last-child {
|
||||||
|
margin-bottom: 0.4em;
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul) > li:nth-child(3n):last-child::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.timeline ul:not(ul ul)::before {
|
||||||
|
content: "";
|
||||||
|
height: 100%;
|
||||||
|
width: 0.5rem;
|
||||||
|
grid-column: 2/span 1;
|
||||||
|
grid-row-start: 1;
|
||||||
|
grid-row-end: span 1000;
|
||||||
|
background-color: var(--text-normal);
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.body-2 ul:not(ul ul) > li:nth-child(3n+2), .timeline.body-2 ul:not(ul ul) > li:nth-child(3n), .timeline.body-3 ul:not(ul ul) > li:nth-child(3n+2), .timeline.body-3 ul:not(ul ul) > li:nth-child(3n), .timeline.body-4 ul:not(ul ul) > li:nth-child(3n+2), .timeline.body-4 ul:not(ul ul) > li:nth-child(3n) {
|
||||||
|
background-color: var(--background-primary-alt);
|
||||||
|
}
|
||||||
|
.timeline.body-2 ul:not(ul ul) > li:nth-child(3n), .timeline.body-3 ul:not(ul ul) > li:nth-child(3n), .timeline.body-4 ul:not(ul ul) > li:nth-child(3n) {
|
||||||
|
margin-bottom: 2.25rem;
|
||||||
|
}
|
||||||
|
.timeline.body-2 ul:not(ul ul) > li:nth-child(3n):last-child, .timeline.body-3 ul:not(ul ul) > li:nth-child(3n):last-child, .timeline.body-4 ul:not(ul ul) > li:nth-child(3n):last-child {
|
||||||
|
margin-bottom: 0.4em;
|
||||||
|
}
|
||||||
|
.timeline.body-2 ul:not(ul ul) > li:nth-child(3n)::after, .timeline.body-3 ul:not(ul ul) > li:nth-child(3n)::after, .timeline.body-4 ul:not(ul ul) > li:nth-child(3n)::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.body-2 ul:not(ul ul) > li:nth-child(3n), .timeline.body-2 ul:not(ul ul) > li:nth-child(3n+2), .timeline.body-4 ul:not(ul ul) > li:nth-child(3n), .timeline.body-4 ul:not(ul ul) > li:nth-child(3n+2) {
|
||||||
|
padding: 1.5rem;
|
||||||
|
padding-top: 0.4em;
|
||||||
|
}
|
||||||
|
.timeline.body-2 ul:not(ul ul) > li:nth-child(3n+2), .timeline.body-4 ul:not(ul ul) > li:nth-child(3n+2) {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
.timeline.body-2 ul:not(ul ul) > li:nth-child(3n+1), .timeline.body-4 ul:not(ul ul) > li:nth-child(3n+1) {
|
||||||
|
margin-top: 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.body-2 ul:not(ul ul) > li:nth-child(3n+2) {
|
||||||
|
border-radius: 1.5rem 1.5rem 0 0;
|
||||||
|
}
|
||||||
|
.timeline.body-2 ul:not(ul ul) > li:nth-child(3n) {
|
||||||
|
border-radius: 0 0 1.5rem 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.body-3 ul:not(ul ul) > li:nth-child(3n+2), .timeline.body-3 ul:not(ul ul) > li:nth-child(3n) {
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
.timeline.body-3 ul:not(ul ul) > li:nth-child(3n+2) {
|
||||||
|
position: relative;
|
||||||
|
background: var(--timeline-active-color);
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
padding-right: 1.5rem;
|
||||||
|
}
|
||||||
|
.timeline.body-3 ul:not(ul ul) > li:nth-child(3n+2)::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: 2rem;
|
||||||
|
background: var(--timeline-active-color);
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: -1rem;
|
||||||
|
clip-path: polygon(1rem 0, 100% 0, 100% 100%, 1rem 100%, 0 50%);
|
||||||
|
}
|
||||||
|
.timeline.body-3 ul:not(ul ul) > li:nth-child(3n) {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.body-4 ul:not(ul ul) > li:nth-child(3n+2), .timeline.body-4 ul:not(ul ul) > li:nth-child(3n) {
|
||||||
|
border-left: 0.3rem solid var(--timeline-active-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.line-2 ul:not(ul ul) > li:nth-child(3n+1)::before, .timeline.line-2 ul:not(ul ul) > li:nth-child(3n+1)::after {
|
||||||
|
right: -2.2rem;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.timeline.line-2 ul:not(ul ul) > li:nth-child(3n+1)::before {
|
||||||
|
height: 1.2rem;
|
||||||
|
width: 1.2rem;
|
||||||
|
}
|
||||||
|
.timeline.line-2 ul:not(ul ul) > li:nth-child(3n+1)::after {
|
||||||
|
background: transparent;
|
||||||
|
border: 0.2rem solid var(--text-normal);
|
||||||
|
height: 0.8rem;
|
||||||
|
width: 0.8rem;
|
||||||
|
opacity: 0.15;
|
||||||
|
}
|
||||||
|
.timeline.line-2 ul:not(ul ul)::before {
|
||||||
|
width: 0.2rem;
|
||||||
|
opacity: 0.15;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.line-3 ul:not(ul ul) > li:nth-child(3n+1)::before {
|
||||||
|
background: var(--timeline-active-color);
|
||||||
|
height: 1rem;
|
||||||
|
width: 1rem;
|
||||||
|
border: 0.3rem solid var(--background-primary);
|
||||||
|
right: -2.45rem;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.timeline.line-3 ul:not(ul ul) > li:nth-child(3n+1)::after {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.timeline.line-3 ul:not(ul ul)::before {
|
||||||
|
width: 0.3rem;
|
||||||
|
opacity: 0.15;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.line-4 ul:not(ul ul) > li:nth-child(3n+1)::before, .timeline.line-4 ul:not(ul ul) > li:nth-child(3n+1)::after {
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.timeline.line-4 ul:not(ul ul) > li:nth-child(3n+1)::before {
|
||||||
|
background: var(--text-normal);
|
||||||
|
height: 1.3rem;
|
||||||
|
width: 1.3rem;
|
||||||
|
right: -2.225rem;
|
||||||
|
}
|
||||||
|
.timeline.line-4 ul:not(ul ul) > li:nth-child(3n+1)::after {
|
||||||
|
opacity: 1;
|
||||||
|
background: var(--timeline-active-color);
|
||||||
|
height: 0.85rem;
|
||||||
|
width: 0.85rem;
|
||||||
|
right: -2rem;
|
||||||
|
}
|
||||||
|
.timeline.line-4 ul:not(ul ul)::before {
|
||||||
|
opacity: 1;
|
||||||
|
width: 0.15rem;
|
||||||
|
background-color: transparent;
|
||||||
|
background-image: linear-gradient(var(--text-normal) 60%, rgba(255, 255, 255, 0) 0%);
|
||||||
|
background-position: right;
|
||||||
|
background-size: 0.15rem 1.5rem;
|
||||||
|
background-repeat: repeat-y;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline.line-5 ul:not(ul ul) > li:nth-child(3n+1)::before, .timeline.line-5 ul:not(ul ul) > li:nth-child(3n+1)::after {
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
.timeline.line-5 ul:not(ul ul) > li:nth-child(3n+1)::before {
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
right: -3.1rem;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
.timeline.line-5 ul:not(ul ul) > li:nth-child(3n+1)::after {
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
right: 0;
|
||||||
|
transform: translateY(-50%) translateX(2.1rem) rotate(45deg);
|
||||||
|
}
|
||||||
|
.timeline.line-5 ul:not(ul ul)::before {
|
||||||
|
width: 0.2rem;
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
Executable
+1
@@ -0,0 +1 @@
|
|||||||
|
{"error":{"code":4401},"success":false}
|
||||||
File diff suppressed because it is too large
Load Diff
Executable
+1898
File diff suppressed because it is too large
Load Diff
Executable
+413
File diff suppressed because one or more lines are too long
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,59 @@
|
|||||||
|
services:
|
||||||
|
mysql:
|
||||||
|
image: mysql:8.0
|
||||||
|
container_name: t3fap-mysql
|
||||||
|
restart: always
|
||||||
|
command:
|
||||||
|
- --character-set-server=utf8mb4
|
||||||
|
- --collation-server=utf8mb4_0900_ai_ci
|
||||||
|
environment:
|
||||||
|
MYSQL_DATABASE: t3mt_next
|
||||||
|
MYSQL_USER: t3mt
|
||||||
|
MYSQL_PASSWORD: change_me
|
||||||
|
MYSQL_ROOT_PASSWORD: change_root_me
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
volumes:
|
||||||
|
- ./mysql-data:/var/lib/mysql
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD-SHELL",
|
||||||
|
"mysqladmin ping -h 127.0.0.1 -uroot -p\"$$MYSQL_ROOT_PASSWORD\" --silent",
|
||||||
|
]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 12
|
||||||
|
start_period: 30s
|
||||||
|
networks:
|
||||||
|
- t3fap_net
|
||||||
|
|
||||||
|
t3fap:
|
||||||
|
image: ghcr.io/qq85423296/t3fap
|
||||||
|
container_name: t3fap
|
||||||
|
restart: always
|
||||||
|
depends_on:
|
||||||
|
mysql:
|
||||||
|
condition: service_healthy
|
||||||
|
ports:
|
||||||
|
- "8521:8521"
|
||||||
|
environment:
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
T3MT_ENV: production
|
||||||
|
T3MT_LOG_LEVEL: INFO
|
||||||
|
T3MT_PUBLIC_BASE_URL: http://127.0.0.1:8521
|
||||||
|
T3MT_DATABASE_URL: mysql+pymysql://t3mt:change_me@mysql:3306/t3mt_next?charset=utf8mb4
|
||||||
|
T3MT_ENABLE_QQBOT_GATEWAY: "0"
|
||||||
|
T3MT_QQBOT_GATEWAY_RETRY_SECONDS: "15"
|
||||||
|
volumes:
|
||||||
|
- ./logs:/app/storage/logs
|
||||||
|
- ./packages:/app/storage/packages
|
||||||
|
- ./runtime:/app/storage/runtime
|
||||||
|
- ./downloads:/app/backend/downloads
|
||||||
|
security_opt:
|
||||||
|
- apparmor:unconfined
|
||||||
|
networks:
|
||||||
|
- t3fap_net
|
||||||
|
|
||||||
|
networks:
|
||||||
|
t3fap_net:
|
||||||
|
driver: bridge
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
services:
|
||||||
|
t3fap:
|
||||||
|
image: ghcr.io/qq85423296/t3fap
|
||||||
|
container_name: t3fap
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "8521:8521"
|
||||||
|
environment:
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
T3MT_ENV: production
|
||||||
|
T3MT_LOG_LEVEL: INFO
|
||||||
|
T3MT_PUBLIC_BASE_URL: http://127.0.0.1:8521
|
||||||
|
T3MT_DATABASE_URL: sqlite:////app/storage/runtime/t3mt-next.db
|
||||||
|
T3MT_ENABLE_QQBOT_GATEWAY: "0"
|
||||||
|
volumes:
|
||||||
|
- ./logs:/app/storage/logs
|
||||||
|
- ./packages:/app/storage/packages
|
||||||
|
- ./runtime:/app/storage/runtime
|
||||||
|
- ./downloads:/app/backend/downloads
|
||||||
|
security_opt:
|
||||||
|
- apparmor:unconfined
|
||||||
@@ -0,0 +1,832 @@
|
|||||||
|
mixed-port: 7890
|
||||||
|
allow-lan: true
|
||||||
|
mode: rule
|
||||||
|
bind-address: '*'
|
||||||
|
|
||||||
|
log-level: info
|
||||||
|
|
||||||
|
external-controller: 0.0.0.0:9090
|
||||||
|
|
||||||
|
unified-delay: true
|
||||||
|
ipv6: false
|
||||||
|
profile:
|
||||||
|
store-selected: true
|
||||||
|
tun:
|
||||||
|
mtu: 1500
|
||||||
|
dns:
|
||||||
|
enable: true
|
||||||
|
ipv6: true
|
||||||
|
use-system-hosts: false
|
||||||
|
listen: '127.0.0.1:5335'
|
||||||
|
default-nameserver: [180.76.76.76, 182.254.118.118, 8.8.8.8, 180.184.2.2]
|
||||||
|
enhanced-mode: fake-ip
|
||||||
|
fake-ip-range: 198.18.0.1/16
|
||||||
|
fake-ip-filter: ['*.lan', 'stun.*.*.*', 'stun.*.*', time.windows.com, time.nist.gov, time.apple.com, time.asia.apple.com, '*.ntp.org.cn', '*.openwrt.pool.ntp.org', time1.cloud.tencent.com, time.ustc.edu.cn, pool.ntp.org, ntp.ubuntu.com, ntp.aliyun.com, ntp1.aliyun.com, ntp2.aliyun.com, ntp3.aliyun.com, ntp4.aliyun.com, ntp5.aliyun.com, ntp6.aliyun.com, ntp7.aliyun.com, time1.aliyun.com, time2.aliyun.com, time3.aliyun.com, time4.aliyun.com, time5.aliyun.com, time6.aliyun.com, time7.aliyun.com, '*.time.edu.cn', time1.apple.com, time2.apple.com, time3.apple.com, time4.apple.com, time5.apple.com, time6.apple.com, time7.apple.com, time1.google.com, time2.google.com, time3.google.com, time4.google.com, music.163.com, '*.music.163.com', '*.126.net', musicapi.taihe.com, music.taihe.com, songsearch.kugou.com, trackercdn.kugou.com, '*.kuwo.cn', api-jooxtt.sanook.com, api.joox.com, joox.com, y.qq.com, '*.y.qq.com', streamoc.music.tc.qq.com, mobileoc.music.tc.qq.com, isure.stream.qqmusic.qq.com, dl.stream.qqmusic.qq.com, aqqmusic.tc.qq.com, amobile.music.tc.qq.com, '*.xiami.com', '*.music.migu.cn', music.migu.cn, '*.msftconnecttest.com', '*.msftncsi.com', localhost.ptlogin2.qq.com, '*.*.*.srv.nintendo.net', '*.*.stun.playstation.net', 'xbox.*.*.microsoft.com', '*.ipv6.microsoft.com', '*.*.xboxlive.com', '*.cpolar.top','*.picp.net','*.3322.org','*.dscloud.me','*.joyagain.top','*.joyagain.me','*.xicp.cn','*.himan.vip',speedtest.cros.wr.pvp.net]
|
||||||
|
nameserver: [180.76.76.76, 119.29.29.29, 180.184.1.1, 223.5.5.5, 8.8.8.8, 'https://223.6.6.6/dns-query#h3=true', 'https://dns.alidns.com/dns-query', 'https://cloudflare-dns.com/dns-query', 'https://doh.pub/dns-query']
|
||||||
|
fallback-filter: { geoip: true, ipcidr: [240.0.0.0/4, 0.0.0.0/32, 127.0.0.1/32], domain: [+.google.com, +.facebook.com, +.twitter.com, +.youtube.com, +.xn--ngstr-lra8j.com, +.google.cn, +.googleapis.cn, +.googleapis.com, +.gvt1.com] }
|
||||||
|
proxies:
|
||||||
|
- { name: '🌏自动最优线路(hy2)-网址: www.dg6.me', type: hysteria2, server: cluster.cloudfrontcdn.com, port: 25948, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: '🌏自动最优线路(AnyTLS)-网址: www.dg6.me', type: anytls, server: cluster.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇯🇵6日本-连通/移动(hy2), type: hysteria2, server: 6jp.cloudfrontcdn.com, port: 22162, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇯🇵6日本-连通/移动(AnyTLS), type: anytls, server: 6jp.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇯🇵7日本-联通/移动(hy2), type: hysteria2, server: 7jp.cloudfrontcdn.com, port: 25118, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇯🇵7日本-联通/移动(AnyTLS), type: anytls, server: 7jp.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇯🇵10日本-全网优化(hy2), type: hysteria2, server: 10jp.cloudfrontcdn.com, port: 25761, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇯🇵10日本-全网优化(AnyTLS), type: anytls, server: 10jp.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇰🇷8韩国集群-全网优化(hy2), type: hysteria2, server: 8kr.cloudfrontcdn.com, port: 22558, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇰🇷8韩国集群-全网优化(AnyTLS), type: anytls, server: 8kr.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇰🇷9韩国-全网优化(hy2), type: hysteria2, server: 9kr.cloudfrontcdn.com, port: 21074, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇰🇷9韩国-全网优化(AnyTLS), type: anytls, server: 9kr.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇰🇷25韩国-全网优化(hy2), type: hysteria2, server: 25kr.cloudfrontcdn.com, port: 24714, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇰🇷25韩国-全网优化(AnyTLS), type: anytls, server: 25kr.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇺🇸11美国西集群-全网优化(hy2), type: hysteria2, server: 11us.cloudfrontcdn.com, port: 23124, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇺🇸11美国西集群-全网优化(AnyTLS), type: anytls, server: 11us.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇺🇸12美国凤凰城-全网优化(hy2), type: hysteria2, server: 12us.cloudfrontcdn.com, port: 21148, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇺🇸12美国凤凰城-全网优化(AnyTLS), type: anytls, server: 12us.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇺🇸29美国旧金山-全网优化(hy2), type: hysteria2, server: 29us.cloudfrontcdn.com, port: 22289, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇺🇸29美国旧金山-全网优化(AnyTLS), type: anytls, server: 29us.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇺🇸39美国华盛顿-全网优化(hy2), type: hysteria2, server: 39us.cloudfrontcdn.com, port: 24627, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇺🇸39美国华盛顿-全网优化(AnyTLS), type: anytls, server: 39us.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇦🇪13迪拜-电信/移动/南方联通(hy2), type: hysteria2, server: 13dxb.cloudfrontcdn.com, port: 24189, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇦🇪13迪拜-电信/移动/南方联通(AnyTLS), type: anytls, server: 13dxb.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇮🇳14印度-移动/南方联通(hy2), type: hysteria2, server: 14in.cloudfrontcdn.com, port: 23335, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇮🇳14印度-移动/南方联通(AnyTLS), type: anytls, server: 14in.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇸🇬15新加坡-全网优化(hy2), type: hysteria2, server: 15sg.cloudfrontcdn.com, port: 23753, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇸🇬15新加坡-全网优化(AnyTLS), type: anytls, server: 15sg.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇸🇬24新加坡-联通/移动(hy2), type: hysteria2, server: 24sg.cloudfrontcdn.com, port: 23987, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇸🇬24新加坡-联通/移动(AnyTLS), type: anytls, server: 24sg.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇩🇪16德国-电信/联通(hy2), type: hysteria2, server: 16de.cloudfrontcdn.com, port: 24200, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇩🇪16德国-电信/联通(AnyTLS), type: anytls, server: 16de.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇬🇧17英国-全网优化(hy2), type: hysteria2, server: 17uk.cloudfrontcdn.com, port: 22675, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇬🇧17英国-全网优化(AnyTLS), type: anytls, server: 17uk.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇦18加拿大-全网优化(hy2), type: hysteria2, server: 18ca.cloudfrontcdn.com, port: 24663, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇦18加拿大-全网优化(AnyTLS), type: anytls, server: 18ca.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇦26加拿大-全网优化(hy2), type: hysteria2, server: 26ca.cloudfrontcdn.com, port: 23256, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇦26加拿大-全网优化(AnyTLS), type: anytls, server: 26ca.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇦🇺19澳洲-移动优化(hy2), type: hysteria2, server: 19sdy.cloudfrontcdn.com, port: 24886, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇦🇺19澳洲-移动优化(AnyTLS), type: anytls, server: 19sdy.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇧🇷20巴西-全网优化(hy2), type: hysteria2, server: 20br.cloudfrontcdn.com, port: 23011, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇧🇷20巴西-全网优化(AnyTLS), type: anytls, server: 20br.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇱21智利-全网优化(hy2), type: hysteria2, server: 21chi.cloudfrontcdn.com, port: 25241, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇱21智利-全网优化(AnyTLS), type: anytls, server: 21chi.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇹🇷22土耳其-全网优化(hy2), type: hysteria2, server: 22tr.cloudfrontcdn.com, port: 23440, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇹🇷22土耳其-全网优化(AnyTLS), type: anytls, server: 22tr.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇫🇷23法国-全网优化(hy2), type: hysteria2, server: 23fr.cloudfrontcdn.com, port: 22562, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇫🇷23法国-全网优化(AnyTLS), type: anytls, server: 23fr.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇲🇽27墨西哥-全网优化(hy2), type: hysteria2, server: 27mx.cloudfrontcdn.com, port: 24799, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇲🇽27墨西哥-全网优化(AnyTLS), type: anytls, server: 27mx.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇳🇱28荷兰-全网优化(hy2), type: hysteria2, server: 28nl.cloudfrontcdn.com, port: 21510, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇳🇱28荷兰-全网优化(AnyTLS), type: anytls, server: 28nl.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇪🇸31西班牙-全网优化(hy2), type: hysteria2, server: 31es.cloudfrontcdn.com, port: 24260, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇪🇸31西班牙-全网优化(AnyTLS), type: anytls, server: 31es.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇷🇺32俄罗斯-全网优化(hy2), type: hysteria2, server: 32ru.cloudfrontcdn.com, port: 22021, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇷🇺32俄罗斯-全网优化(AnyTLS), type: anytls, server: 32ru.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: '🇺🇦40 乌克兰-全网优化(hy2)', type: hysteria2, server: 40ua.cloudfrontcdn.com, port: 21392, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: '🇺🇦40 乌克兰-全网优化(AnyTLS)', type: anytls, server: 40ua.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇭41瑞士-全网优化(hy2), type: hysteria2, server: 41ch.cloudfrontcdn.com, port: 24726, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇭41瑞士-全网优化(AnyTLS), type: anytls, server: 41ch.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇭🇰1香港集群-全网优化(hy2)(限速30M), type: hysteria2, server: 1hk.cloudfrontcdn.com, port: 23542, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, up: 50, down: 100, skip-cert-verify: true }
|
||||||
|
- { name: 🇯🇵6日本-连通/移动(TCP), type: trojan, server: dnsmart.dg-cdn.mob.networklinkpro.com, port: 17906, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, skip-cert-verify: true, network: ws }
|
||||||
|
- { name: 🇰🇷8韩国-专线(TCP), type: trojan, server: dnsmart.dg-cdn.mob.networklinkpro.com, port: 17908, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, skip-cert-verify: true, network: ws }
|
||||||
|
- { name: 🇰🇷9韩国-专线(TCP), type: trojan, server: dnsmart.dg-cdn.mob.networklinkpro.com, port: 17909, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, skip-cert-verify: true, network: ws }
|
||||||
|
- { name: 🇯🇵10日本-专线(TCP), type: trojan, server: dnsmart.dg-cdn.mob.networklinkpro.com, port: 17910, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, skip-cert-verify: true, network: ws }
|
||||||
|
- { name: 🇺🇸11美国西集群-专线(TCP), type: trojan, server: dnsmart.dg-cdn.mob.networklinkpro.com, port: 17911, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, skip-cert-verify: true, network: ws }
|
||||||
|
- { name: 🇺🇸12美国凤凰城-专线(TCP), type: trojan, server: dnsmart.dg-cdn.mob.networklinkpro.com, port: 17912, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, skip-cert-verify: true, network: ws }
|
||||||
|
- { name: 🇸🇬15新加坡-专线(TCP), type: trojan, server: dnsmart.dg-cdn.mob.networklinkpro.com, port: 17915, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, skip-cert-verify: true, network: ws }
|
||||||
|
- { name: 🇸🇬24新加坡-专线(TCP), type: trojan, server: dnsmart.dg-cdn.mob.networklinkpro.com, port: 17924, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, skip-cert-verify: true, network: ws }
|
||||||
|
- { name: 🇰🇷25韩国-专线(TCP), type: trojan, server: dnsmart.dg-cdn.mob.networklinkpro.com, port: 17925, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, skip-cert-verify: true, network: ws }
|
||||||
|
- { name: 🇦🇺19澳洲-专线(TCP), type: trojan, server: dnsmart.dg-cdn.mob.networklinkpro.com, port: 17919, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, skip-cert-verify: true, network: ws }
|
||||||
|
- { name: 🇭🇰1香港-专线(TCP), type: trojan, server: dnsmart.dg-cdn.mob.networklinkpro.com, port: 17901, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, skip-cert-verify: true, network: ws }
|
||||||
|
- { name: 🇭🇰2香港-专线(TCP), type: trojan, server: dnsmart.dg-cdn.mob.networklinkpro.com, port: 17902, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, skip-cert-verify: true, network: ws }
|
||||||
|
- { name: 🇭🇰1香港集群-全网优化(AnyTLS), type: anytls, server: 1hk.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇭🇰2香港集群-全网优化(hy2)(限速30M), type: hysteria2, server: 2hk.cloudfrontcdn.com, port: 24943, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, up: 30, down: 30, skip-cert-verify: true }
|
||||||
|
- { name: 🇭🇰3香港集群-全网优化(hy2), type: hysteria2, server: 3hk.cloudfrontcdn.com, port: 21066, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, up: 50, down: 100, skip-cert-verify: true }
|
||||||
|
- { name: 🇭🇰3香港集群-全网优化(AnyTLS), type: anytls, server: 3hk.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇳4台湾-联通优化(hy2), type: hysteria2, server: 4tw.cloudfrontcdn.com, port: 23576, ports: 21000-26000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇳4台湾-联通优化(AnyTLS), type: anytls, server: 4tw.cloudfrontcdn.com, port: 4430, client-fingerprint: chrome, password: de4f90f7-263c-4a81-af14-2add4630b4d9, udp: true, tfo: true, sni: d2-cn-gotcha204-1.bilivideo.com, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇳5台湾-联通/移动(hy2), type: hysteria2, server: 5tw.cloudfrontcdn.com, port: 51164, ports: 50001-55000, password: de4f90f7-263c-4a81-af14-2add4630b4d9, skip-cert-verify: true }
|
||||||
|
- { name: '🌏自动最优线路(hy1)-网址: www.dg6.me', type: hysteria, server: cluster.cloudfrontcdn.com, port: 9845, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇺🇸11美国西集群-全网优化(hy1), type: hysteria, server: 11us.cloudfrontcdn.com, port: 8221, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇺🇸12美国凤凰城-电信/连通(hy1), type: hysteria, server: 12us.cloudfrontcdn.com, port: 8656, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇺🇸39美国华盛顿-全网优化(hy1), type: hysteria, server: 39us.cloudfrontcdn.com, port: 9738, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇮🇳14印度-移动/南方联通(hy1), type: hysteria, server: 14in.cloudfrontcdn.com, port: 5625, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇸🇬24新加坡-联通/移动(hy1), type: hysteria, server: 24sg.cloudfrontcdn.com, port: 8551, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: false, skip-cert-verify: true }
|
||||||
|
- { name: 🇩🇪16德国-电信/联通(hy1), type: hysteria, server: 16de.cloudfrontcdn.com, port: 8268, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇬🇧17英国-全网优化(hy1), type: hysteria, server: 17uk.cloudfrontcdn.com, port: 5786, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇦18加拿大-全网优化(hy1), type: hysteria, server: 18ca.cloudfrontcdn.com, port: 8215, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇦26加拿大-全网优化(hy1), type: hysteria, server: 26ca.cloudfrontcdn.com, port: 8948, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇦🇺19澳洲-连通/移动(hy1), type: hysteria, server: 19sdy.cloudfrontcdn.com, port: 7017, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: false, skip-cert-verify: true }
|
||||||
|
- { name: 🇧🇷20巴西-全网优化(hy1), type: hysteria, server: 20br.cloudfrontcdn.com, port: 9264, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇱21智利-全网优化(hy1), type: hysteria, server: 21chi.cloudfrontcdn.com, port: 8190, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇫🇷23法国-全网优化(hy1), type: hysteria, server: 23fr.cloudfrontcdn.com, port: 7354, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇲🇽27墨西哥-全网优化(hy1), type: hysteria, server: 27mx.cloudfrontcdn.com, port: 7248, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇪🇸31西班牙-全网优化(hy1), type: hysteria, server: 31es.cloudfrontcdn.com, port: 5720, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇭🇰3香港集群-全网优化(hy1), type: hysteria, server: 3hk.cloudfrontcdn.com, port: 6452, ports: 5000-10000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 50, down: 100, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: 🇨🇳5台湾-联通/移动(hy1), type: hysteria, server: 5tw.cloudfrontcdn.com, port: 40541, ports: 40001-45000, auth_str: de4f90f7-263c-4a81-af14-2add4630b4d9, alpn: [h3], protocol: udp, up: 70, down: 150, fast-open: true, disable_mtu_discovery: true, skip-cert-verify: true }
|
||||||
|
- { name: '官网: www.dg6.me', type: vmess, server: 114.114.114.114, port: 2235, uuid: de4f90f7-263c-4a81-af14-2add4630b4d9, alterId: 0, cipher: auto, udp: true }
|
||||||
|
proxy-groups:
|
||||||
|
- { name: 狗狗加速.com, type: select, proxies: [♻️自动选择, 🔯故障转移, hy1, 🐴Trojan, AnyTLS, 🔥ChatGPT, Hysteria2, '🌏自动最优线路(hy2)-网址: www.dg6.me', '🌏自动最优线路(AnyTLS)-网址: www.dg6.me', 🇯🇵6日本-连通/移动(hy2), 🇯🇵6日本-连通/移动(AnyTLS), 🇯🇵7日本-联通/移动(hy2), 🇯🇵7日本-联通/移动(AnyTLS), 🇯🇵10日本-全网优化(hy2), 🇯🇵10日本-全网优化(AnyTLS), 🇰🇷8韩国集群-全网优化(hy2), 🇰🇷8韩国集群-全网优化(AnyTLS), 🇰🇷9韩国-全网优化(hy2), 🇰🇷9韩国-全网优化(AnyTLS), 🇰🇷25韩国-全网优化(hy2), 🇰🇷25韩国-全网优化(AnyTLS), 🇺🇸11美国西集群-全网优化(hy2), 🇺🇸11美国西集群-全网优化(AnyTLS), 🇺🇸12美国凤凰城-全网优化(hy2), 🇺🇸12美国凤凰城-全网优化(AnyTLS), 🇺🇸29美国旧金山-全网优化(hy2), 🇺🇸29美国旧金山-全网优化(AnyTLS), 🇺🇸39美国华盛顿-全网优化(hy2), 🇺🇸39美国华盛顿-全网优化(AnyTLS), 🇦🇪13迪拜-电信/移动/南方联通(hy2), 🇦🇪13迪拜-电信/移动/南方联通(AnyTLS), 🇮🇳14印度-移动/南方联通(hy2), 🇮🇳14印度-移动/南方联通(AnyTLS), 🇸🇬15新加坡-全网优化(hy2), 🇸🇬15新加坡-全网优化(AnyTLS), 🇸🇬24新加坡-联通/移动(hy2), 🇸🇬24新加坡-联通/移动(AnyTLS), 🇩🇪16德国-电信/联通(hy2), 🇩🇪16德国-电信/联通(AnyTLS), 🇬🇧17英国-全网优化(hy2), 🇬🇧17英国-全网优化(AnyTLS), 🇨🇦18加拿大-全网优化(hy2), 🇨🇦18加拿大-全网优化(AnyTLS), 🇨🇦26加拿大-全网优化(hy2), 🇨🇦26加拿大-全网优化(AnyTLS), 🇦🇺19澳洲-移动优化(hy2), 🇦🇺19澳洲-移动优化(AnyTLS), 🇧🇷20巴西-全网优化(hy2), 🇧🇷20巴西-全网优化(AnyTLS), 🇨🇱21智利-全网优化(hy2), 🇨🇱21智利-全网优化(AnyTLS), 🇹🇷22土耳其-全网优化(hy2), 🇹🇷22土耳其-全网优化(AnyTLS), 🇫🇷23法国-全网优化(hy2), 🇫🇷23法国-全网优化(AnyTLS), 🇲🇽27墨西哥-全网优化(hy2), 🇲🇽27墨西哥-全网优化(AnyTLS), 🇳🇱28荷兰-全网优化(hy2), 🇳🇱28荷兰-全网优化(AnyTLS), 🇪🇸31西班牙-全网优化(hy2), 🇪🇸31西班牙-全网优化(AnyTLS), 🇷🇺32俄罗斯-全网优化(hy2), 🇷🇺32俄罗斯-全网优化(AnyTLS), '🇺🇦40 乌克兰-全网优化(hy2)', '🇺🇦40 乌克兰-全网优化(AnyTLS)', 🇨🇭41瑞士-全网优化(hy2), 🇨🇭41瑞士-全网优化(AnyTLS), 🇭🇰1香港集群-全网优化(hy2)(限速30M), 🇯🇵6日本-连通/移动(TCP), 🇰🇷8韩国-专线(TCP), 🇰🇷9韩国-专线(TCP), 🇯🇵10日本-专线(TCP), 🇺🇸11美国西集群-专线(TCP), 🇺🇸12美国凤凰城-专线(TCP), 🇸🇬15新加坡-专线(TCP), 🇸🇬24新加坡-专线(TCP), 🇰🇷25韩国-专线(TCP), 🇦🇺19澳洲-专线(TCP), 🇭🇰1香港-专线(TCP), 🇭🇰2香港-专线(TCP), 🇭🇰1香港集群-全网优化(AnyTLS), 🇭🇰2香港集群-全网优化(hy2)(限速30M), 🇭🇰3香港集群-全网优化(hy2), 🇭🇰3香港集群-全网优化(AnyTLS), 🇨🇳4台湾-联通优化(hy2), 🇨🇳4台湾-联通优化(AnyTLS), 🇨🇳5台湾-联通/移动(hy2), '🌏自动最优线路(hy1)-网址: www.dg6.me', 🇺🇸11美国西集群-全网优化(hy1), 🇺🇸12美国凤凰城-电信/连通(hy1), 🇺🇸39美国华盛顿-全网优化(hy1), 🇮🇳14印度-移动/南方联通(hy1), 🇸🇬24新加坡-联通/移动(hy1), 🇩🇪16德国-电信/联通(hy1), 🇬🇧17英国-全网优化(hy1), 🇨🇦18加拿大-全网优化(hy1), 🇨🇦26加拿大-全网优化(hy1), 🇦🇺19澳洲-连通/移动(hy1), 🇧🇷20巴西-全网优化(hy1), 🇨🇱21智利-全网优化(hy1), 🇫🇷23法国-全网优化(hy1), 🇲🇽27墨西哥-全网优化(hy1), 🇪🇸31西班牙-全网优化(hy1), 🇭🇰3香港集群-全网优化(hy1), 🇨🇳5台湾-联通/移动(hy1), '官网: www.dg6.me'] }
|
||||||
|
- { name: ♻️自动选择, type: url-test, proxies: ['🌏自动最优线路(hy2)-网址: www.dg6.me', '🌏自动最优线路(AnyTLS)-网址: www.dg6.me', 🇯🇵6日本-连通/移动(hy2), 🇯🇵6日本-连通/移动(AnyTLS), 🇯🇵7日本-联通/移动(hy2), 🇯🇵7日本-联通/移动(AnyTLS), 🇯🇵10日本-全网优化(hy2), 🇯🇵10日本-全网优化(AnyTLS), 🇰🇷8韩国集群-全网优化(hy2), 🇰🇷8韩国集群-全网优化(AnyTLS), 🇰🇷9韩国-全网优化(hy2), 🇰🇷9韩国-全网优化(AnyTLS), 🇰🇷25韩国-全网优化(hy2), 🇰🇷25韩国-全网优化(AnyTLS), 🇺🇸11美国西集群-全网优化(hy2), 🇺🇸11美国西集群-全网优化(AnyTLS), 🇺🇸12美国凤凰城-全网优化(hy2), 🇺🇸12美国凤凰城-全网优化(AnyTLS), 🇺🇸29美国旧金山-全网优化(hy2), 🇺🇸29美国旧金山-全网优化(AnyTLS), 🇺🇸39美国华盛顿-全网优化(hy2), 🇺🇸39美国华盛顿-全网优化(AnyTLS), 🇦🇪13迪拜-电信/移动/南方联通(hy2), 🇦🇪13迪拜-电信/移动/南方联通(AnyTLS), 🇮🇳14印度-移动/南方联通(hy2), 🇮🇳14印度-移动/南方联通(AnyTLS), 🇸🇬15新加坡-全网优化(hy2), 🇸🇬15新加坡-全网优化(AnyTLS), 🇸🇬24新加坡-联通/移动(hy2), 🇸🇬24新加坡-联通/移动(AnyTLS), 🇩🇪16德国-电信/联通(hy2), 🇩🇪16德国-电信/联通(AnyTLS), 🇬🇧17英国-全网优化(hy2), 🇬🇧17英国-全网优化(AnyTLS), 🇨🇦18加拿大-全网优化(hy2), 🇨🇦18加拿大-全网优化(AnyTLS), 🇨🇦26加拿大-全网优化(hy2), 🇨🇦26加拿大-全网优化(AnyTLS), 🇦🇺19澳洲-移动优化(hy2), 🇦🇺19澳洲-移动优化(AnyTLS), 🇧🇷20巴西-全网优化(hy2), 🇧🇷20巴西-全网优化(AnyTLS), 🇨🇱21智利-全网优化(hy2), 🇨🇱21智利-全网优化(AnyTLS), 🇹🇷22土耳其-全网优化(hy2), 🇹🇷22土耳其-全网优化(AnyTLS), 🇫🇷23法国-全网优化(hy2), 🇫🇷23法国-全网优化(AnyTLS), 🇲🇽27墨西哥-全网优化(hy2), 🇲🇽27墨西哥-全网优化(AnyTLS), 🇳🇱28荷兰-全网优化(hy2), 🇳🇱28荷兰-全网优化(AnyTLS), 🇪🇸31西班牙-全网优化(hy2), 🇪🇸31西班牙-全网优化(AnyTLS), 🇷🇺32俄罗斯-全网优化(hy2), 🇷🇺32俄罗斯-全网优化(AnyTLS), '🇺🇦40 乌克兰-全网优化(hy2)', '🇺🇦40 乌克兰-全网优化(AnyTLS)', 🇨🇭41瑞士-全网优化(hy2), 🇨🇭41瑞士-全网优化(AnyTLS), 🇭🇰1香港集群-全网优化(hy2)(限速30M), 🇯🇵6日本-连通/移动(TCP), 🇰🇷8韩国-专线(TCP), 🇰🇷9韩国-专线(TCP), 🇯🇵10日本-专线(TCP), 🇺🇸11美国西集群-专线(TCP), 🇺🇸12美国凤凰城-专线(TCP), 🇸🇬15新加坡-专线(TCP), 🇸🇬24新加坡-专线(TCP), 🇰🇷25韩国-专线(TCP), 🇦🇺19澳洲-专线(TCP), 🇭🇰1香港-专线(TCP), 🇭🇰2香港-专线(TCP), 🇭🇰1香港集群-全网优化(AnyTLS), 🇭🇰2香港集群-全网优化(hy2)(限速30M), 🇭🇰3香港集群-全网优化(hy2), 🇭🇰3香港集群-全网优化(AnyTLS), 🇨🇳4台湾-联通优化(hy2), 🇨🇳4台湾-联通优化(AnyTLS), 🇨🇳5台湾-联通/移动(hy2), '🌏自动最优线路(hy1)-网址: www.dg6.me', 🇺🇸11美国西集群-全网优化(hy1), 🇺🇸12美国凤凰城-电信/连通(hy1), 🇺🇸39美国华盛顿-全网优化(hy1), 🇮🇳14印度-移动/南方联通(hy1), 🇸🇬24新加坡-联通/移动(hy1), 🇩🇪16德国-电信/联通(hy1), 🇬🇧17英国-全网优化(hy1), 🇨🇦18加拿大-全网优化(hy1), 🇨🇦26加拿大-全网优化(hy1), 🇦🇺19澳洲-连通/移动(hy1), 🇧🇷20巴西-全网优化(hy1), 🇨🇱21智利-全网优化(hy1), 🇫🇷23法国-全网优化(hy1), 🇲🇽27墨西哥-全网优化(hy1), 🇪🇸31西班牙-全网优化(hy1), 🇭🇰3香港集群-全网优化(hy1), 🇨🇳5台湾-联通/移动(hy1), '官网: www.dg6.me'], url: 'http://1.1.1.1', interval: 600 }
|
||||||
|
- { name: 🔯故障转移, type: fallback, proxies: ['🌏自动最优线路(hy2)-网址: www.dg6.me', '🌏自动最优线路(AnyTLS)-网址: www.dg6.me', 🇯🇵6日本-连通/移动(hy2), 🇯🇵6日本-连通/移动(AnyTLS), 🇯🇵7日本-联通/移动(hy2), 🇯🇵7日本-联通/移动(AnyTLS), 🇯🇵10日本-全网优化(hy2), 🇯🇵10日本-全网优化(AnyTLS), 🇰🇷8韩国集群-全网优化(hy2), 🇰🇷8韩国集群-全网优化(AnyTLS), 🇰🇷9韩国-全网优化(hy2), 🇰🇷9韩国-全网优化(AnyTLS), 🇰🇷25韩国-全网优化(hy2), 🇰🇷25韩国-全网优化(AnyTLS), 🇺🇸11美国西集群-全网优化(hy2), 🇺🇸11美国西集群-全网优化(AnyTLS), 🇺🇸12美国凤凰城-全网优化(hy2), 🇺🇸12美国凤凰城-全网优化(AnyTLS), 🇺🇸29美国旧金山-全网优化(hy2), 🇺🇸29美国旧金山-全网优化(AnyTLS), 🇺🇸39美国华盛顿-全网优化(hy2), 🇺🇸39美国华盛顿-全网优化(AnyTLS), 🇦🇪13迪拜-电信/移动/南方联通(hy2), 🇦🇪13迪拜-电信/移动/南方联通(AnyTLS), 🇮🇳14印度-移动/南方联通(hy2), 🇮🇳14印度-移动/南方联通(AnyTLS), 🇸🇬15新加坡-全网优化(hy2), 🇸🇬15新加坡-全网优化(AnyTLS), 🇸🇬24新加坡-联通/移动(hy2), 🇸🇬24新加坡-联通/移动(AnyTLS), 🇩🇪16德国-电信/联通(hy2), 🇩🇪16德国-电信/联通(AnyTLS), 🇬🇧17英国-全网优化(hy2), 🇬🇧17英国-全网优化(AnyTLS), 🇨🇦18加拿大-全网优化(hy2), 🇨🇦18加拿大-全网优化(AnyTLS), 🇨🇦26加拿大-全网优化(hy2), 🇨🇦26加拿大-全网优化(AnyTLS), 🇦🇺19澳洲-移动优化(hy2), 🇦🇺19澳洲-移动优化(AnyTLS), 🇧🇷20巴西-全网优化(hy2), 🇧🇷20巴西-全网优化(AnyTLS), 🇨🇱21智利-全网优化(hy2), 🇨🇱21智利-全网优化(AnyTLS), 🇹🇷22土耳其-全网优化(hy2), 🇹🇷22土耳其-全网优化(AnyTLS), 🇫🇷23法国-全网优化(hy2), 🇫🇷23法国-全网优化(AnyTLS), 🇲🇽27墨西哥-全网优化(hy2), 🇲🇽27墨西哥-全网优化(AnyTLS), 🇳🇱28荷兰-全网优化(hy2), 🇳🇱28荷兰-全网优化(AnyTLS), 🇪🇸31西班牙-全网优化(hy2), 🇪🇸31西班牙-全网优化(AnyTLS), 🇷🇺32俄罗斯-全网优化(hy2), 🇷🇺32俄罗斯-全网优化(AnyTLS), '🇺🇦40 乌克兰-全网优化(hy2)', '🇺🇦40 乌克兰-全网优化(AnyTLS)', 🇨🇭41瑞士-全网优化(hy2), 🇨🇭41瑞士-全网优化(AnyTLS), 🇭🇰1香港集群-全网优化(hy2)(限速30M), 🇯🇵6日本-连通/移动(TCP), 🇰🇷8韩国-专线(TCP), 🇰🇷9韩国-专线(TCP), 🇯🇵10日本-专线(TCP), 🇺🇸11美国西集群-专线(TCP), 🇺🇸12美国凤凰城-专线(TCP), 🇸🇬15新加坡-专线(TCP), 🇸🇬24新加坡-专线(TCP), 🇰🇷25韩国-专线(TCP), 🇦🇺19澳洲-专线(TCP), 🇭🇰1香港-专线(TCP), 🇭🇰2香港-专线(TCP), 🇭🇰1香港集群-全网优化(AnyTLS), 🇭🇰2香港集群-全网优化(hy2)(限速30M), 🇭🇰3香港集群-全网优化(hy2), 🇭🇰3香港集群-全网优化(AnyTLS), 🇨🇳4台湾-联通优化(hy2), 🇨🇳4台湾-联通优化(AnyTLS), 🇨🇳5台湾-联通/移动(hy2), '🌏自动最优线路(hy1)-网址: www.dg6.me', 🇺🇸11美国西集群-全网优化(hy1), 🇺🇸12美国凤凰城-电信/连通(hy1), 🇺🇸39美国华盛顿-全网优化(hy1), 🇮🇳14印度-移动/南方联通(hy1), 🇸🇬24新加坡-联通/移动(hy1), 🇩🇪16德国-电信/联通(hy1), 🇬🇧17英国-全网优化(hy1), 🇨🇦18加拿大-全网优化(hy1), 🇨🇦26加拿大-全网优化(hy1), 🇦🇺19澳洲-连通/移动(hy1), 🇧🇷20巴西-全网优化(hy1), 🇨🇱21智利-全网优化(hy1), 🇫🇷23法国-全网优化(hy1), 🇲🇽27墨西哥-全网优化(hy1), 🇪🇸31西班牙-全网优化(hy1), 🇭🇰3香港集群-全网优化(hy1), 🇨🇳5台湾-联通/移动(hy1), '官网: www.dg6.me'], url: 'http://1.1.1.1', interval: 450 }
|
||||||
|
- { name: Hysteria2, type: select, proxies: ['🌏自动最优线路(hy2)-网址: www.dg6.me', 🇯🇵6日本-连通/移动(hy2), 🇯🇵7日本-联通/移动(hy2), 🇯🇵10日本-全网优化(hy2), 🇰🇷8韩国集群-全网优化(hy2), 🇰🇷9韩国-全网优化(hy2), 🇰🇷25韩国-全网优化(hy2), 🇺🇸11美国西集群-全网优化(hy2), 🇺🇸12美国凤凰城-全网优化(hy2), 🇺🇸29美国旧金山-全网优化(hy2), 🇺🇸39美国华盛顿-全网优化(hy2), 🇦🇪13迪拜-电信/移动/南方联通(hy2), 🇮🇳14印度-移动/南方联通(hy2), 🇸🇬15新加坡-全网优化(hy2), 🇸🇬24新加坡-联通/移动(hy2), 🇩🇪16德国-电信/联通(hy2), 🇬🇧17英国-全网优化(hy2), 🇨🇦18加拿大-全网优化(hy2), 🇨🇦26加拿大-全网优化(hy2), 🇦🇺19澳洲-移动优化(hy2), 🇧🇷20巴西-全网优化(hy2), 🇨🇱21智利-全网优化(hy2), 🇹🇷22土耳其-全网优化(hy2), 🇫🇷23法国-全网优化(hy2), 🇲🇽27墨西哥-全网优化(hy2), 🇳🇱28荷兰-全网优化(hy2), 🇪🇸31西班牙-全网优化(hy2), 🇷🇺32俄罗斯-全网优化(hy2), '🇺🇦40 乌克兰-全网优化(hy2)', 🇨🇭41瑞士-全网优化(hy2), 🇭🇰1香港集群-全网优化(hy2)(限速30M), 🇭🇰2香港集群-全网优化(hy2)(限速30M), 🇭🇰3香港集群-全网优化(hy2), 🇨🇳4台湾-联通优化(hy2), 🇨🇳5台湾-联通/移动(hy2)] }
|
||||||
|
- { name: 🔥ChatGPT, type: select, proxies: ['🌏自动最优线路(hy2)-网址: www.dg6.me', '🌏自动最优线路(AnyTLS)-网址: www.dg6.me', 🇯🇵6日本-连通/移动(hy2), 🇯🇵6日本-连通/移动(AnyTLS), 🇯🇵7日本-联通/移动(hy2), 🇯🇵7日本-联通/移动(AnyTLS), 🇯🇵10日本-全网优化(hy2), 🇯🇵10日本-全网优化(AnyTLS), 🇰🇷8韩国集群-全网优化(hy2), 🇰🇷8韩国集群-全网优化(AnyTLS), 🇰🇷9韩国-全网优化(hy2), 🇰🇷9韩国-全网优化(AnyTLS), 🇰🇷25韩国-全网优化(hy2), 🇰🇷25韩国-全网优化(AnyTLS), 🇺🇸11美国西集群-全网优化(hy2), 🇺🇸11美国西集群-全网优化(AnyTLS), 🇺🇸12美国凤凰城-全网优化(hy2), 🇺🇸12美国凤凰城-全网优化(AnyTLS), 🇺🇸29美国旧金山-全网优化(hy2), 🇺🇸29美国旧金山-全网优化(AnyTLS), 🇺🇸39美国华盛顿-全网优化(hy2), 🇺🇸39美国华盛顿-全网优化(AnyTLS), 🇦🇪13迪拜-电信/移动/南方联通(hy2), 🇦🇪13迪拜-电信/移动/南方联通(AnyTLS), 🇮🇳14印度-移动/南方联通(hy2), 🇮🇳14印度-移动/南方联通(AnyTLS), 🇸🇬15新加坡-全网优化(hy2), 🇸🇬15新加坡-全网优化(AnyTLS), 🇸🇬24新加坡-联通/移动(hy2), 🇸🇬24新加坡-联通/移动(AnyTLS), 🇩🇪16德国-电信/联通(hy2), 🇩🇪16德国-电信/联通(AnyTLS), 🇬🇧17英国-全网优化(hy2), 🇬🇧17英国-全网优化(AnyTLS), 🇨🇦18加拿大-全网优化(hy2), 🇨🇦18加拿大-全网优化(AnyTLS), 🇨🇦26加拿大-全网优化(hy2), 🇨🇦26加拿大-全网优化(AnyTLS), 🇦🇺19澳洲-移动优化(hy2), 🇦🇺19澳洲-移动优化(AnyTLS), 🇧🇷20巴西-全网优化(hy2), 🇧🇷20巴西-全网优化(AnyTLS), 🇨🇱21智利-全网优化(hy2), 🇨🇱21智利-全网优化(AnyTLS), 🇹🇷22土耳其-全网优化(hy2), 🇹🇷22土耳其-全网优化(AnyTLS), 🇫🇷23法国-全网优化(hy2), 🇫🇷23法国-全网优化(AnyTLS), 🇲🇽27墨西哥-全网优化(hy2), 🇲🇽27墨西哥-全网优化(AnyTLS), 🇳🇱28荷兰-全网优化(hy2), 🇳🇱28荷兰-全网优化(AnyTLS), 🇪🇸31西班牙-全网优化(hy2), 🇪🇸31西班牙-全网优化(AnyTLS), '🇺🇦40 乌克兰-全网优化(hy2)', '🇺🇦40 乌克兰-全网优化(AnyTLS)', 🇨🇭41瑞士-全网优化(hy2), 🇨🇭41瑞士-全网优化(AnyTLS), 🇰🇷8韩国-专线(TCP), 🇰🇷9韩国-专线(TCP), 🇯🇵10日本-专线(TCP), 🇺🇸11美国西集群-专线(TCP), 🇺🇸12美国凤凰城-专线(TCP), 🇸🇬15新加坡-专线(TCP), 🇸🇬24新加坡-专线(TCP), 🇰🇷25韩国-专线(TCP), 🇦🇺19澳洲-专线(TCP), '🌏自动最优线路(hy1)-网址: www.dg6.me', 🇺🇸11美国西集群-全网优化(hy1), 🇺🇸12美国凤凰城-电信/连通(hy1), 🇺🇸39美国华盛顿-全网优化(hy1), 🇮🇳14印度-移动/南方联通(hy1), 🇸🇬24新加坡-联通/移动(hy1), 🇩🇪16德国-电信/联通(hy1), 🇬🇧17英国-全网优化(hy1), 🇨🇦18加拿大-全网优化(hy1), 🇨🇦26加拿大-全网优化(hy1), 🇦🇺19澳洲-连通/移动(hy1), 🇧🇷20巴西-全网优化(hy1), 🇨🇱21智利-全网优化(hy1), 🇫🇷23法国-全网优化(hy1), 🇲🇽27墨西哥-全网优化(hy1), 🇪🇸31西班牙-全网优化(hy1), '官网: www.dg6.me'] }
|
||||||
|
- { name: AnyTLS, type: select, proxies: ['🌏自动最优线路(AnyTLS)-网址: www.dg6.me', 🇯🇵6日本-连通/移动(AnyTLS), 🇯🇵7日本-联通/移动(AnyTLS), 🇯🇵10日本-全网优化(AnyTLS), 🇰🇷8韩国集群-全网优化(AnyTLS), 🇰🇷9韩国-全网优化(AnyTLS), 🇰🇷25韩国-全网优化(AnyTLS), 🇺🇸11美国西集群-全网优化(AnyTLS), 🇺🇸12美国凤凰城-全网优化(AnyTLS), 🇺🇸29美国旧金山-全网优化(AnyTLS), 🇺🇸39美国华盛顿-全网优化(AnyTLS), 🇦🇪13迪拜-电信/移动/南方联通(AnyTLS), 🇮🇳14印度-移动/南方联通(AnyTLS), 🇸🇬15新加坡-全网优化(AnyTLS), 🇸🇬24新加坡-联通/移动(AnyTLS), 🇩🇪16德国-电信/联通(AnyTLS), 🇬🇧17英国-全网优化(AnyTLS), 🇨🇦18加拿大-全网优化(AnyTLS), 🇨🇦26加拿大-全网优化(AnyTLS), 🇦🇺19澳洲-移动优化(AnyTLS), 🇧🇷20巴西-全网优化(AnyTLS), 🇨🇱21智利-全网优化(AnyTLS), 🇹🇷22土耳其-全网优化(AnyTLS), 🇫🇷23法国-全网优化(AnyTLS), 🇲🇽27墨西哥-全网优化(AnyTLS), 🇳🇱28荷兰-全网优化(AnyTLS), 🇪🇸31西班牙-全网优化(AnyTLS), 🇷🇺32俄罗斯-全网优化(AnyTLS), '🇺🇦40 乌克兰-全网优化(AnyTLS)', 🇨🇭41瑞士-全网优化(AnyTLS), 🇭🇰1香港集群-全网优化(AnyTLS), 🇭🇰3香港集群-全网优化(AnyTLS), 🇨🇳4台湾-联通优化(AnyTLS)] }
|
||||||
|
- { name: 🐴Trojan, type: select, proxies: [🇯🇵6日本-连通/移动(TCP), 🇰🇷8韩国-专线(TCP), 🇰🇷9韩国-专线(TCP), 🇯🇵10日本-专线(TCP), 🇺🇸11美国西集群-专线(TCP), 🇺🇸12美国凤凰城-专线(TCP), 🇸🇬15新加坡-专线(TCP), 🇸🇬24新加坡-专线(TCP), 🇰🇷25韩国-专线(TCP), 🇦🇺19澳洲-专线(TCP), 🇭🇰1香港-专线(TCP), 🇭🇰2香港-专线(TCP)] }
|
||||||
|
- { name: hy1, type: select, proxies: ['🌏自动最优线路(hy1)-网址: www.dg6.me', 🇺🇸11美国西集群-全网优化(hy1), 🇺🇸12美国凤凰城-电信/连通(hy1), 🇺🇸39美国华盛顿-全网优化(hy1), 🇮🇳14印度-移动/南方联通(hy1), 🇸🇬24新加坡-联通/移动(hy1), 🇩🇪16德国-电信/联通(hy1), 🇬🇧17英国-全网优化(hy1), 🇨🇦18加拿大-全网优化(hy1), 🇨🇦26加拿大-全网优化(hy1), 🇦🇺19澳洲-连通/移动(hy1), 🇧🇷20巴西-全网优化(hy1), 🇨🇱21智利-全网优化(hy1), 🇫🇷23法国-全网优化(hy1), 🇲🇽27墨西哥-全网优化(hy1), 🇪🇸31西班牙-全网优化(hy1), 🇭🇰3香港集群-全网优化(hy1), 🇨🇳5台湾-联通/移动(hy1)] }
|
||||||
|
rules:
|
||||||
|
- 'DOMAIN,subapi.doggysub.uk,DIRECT'
|
||||||
|
- 'PROCESS-NAME,v2ray,DIRECT'
|
||||||
|
- 'PROCESS-NAME,xray,DIRECT'
|
||||||
|
- 'PROCESS-NAME,naive,DIRECT'
|
||||||
|
- 'PROCESS-NAME,trojan,DIRECT'
|
||||||
|
- 'PROCESS-NAME,trojan-go,DIRECT'
|
||||||
|
- 'PROCESS-NAME,ss-local,DIRECT'
|
||||||
|
- 'PROCESS-NAME,privoxy,DIRECT'
|
||||||
|
- 'PROCESS-NAME,leaf,DIRECT'
|
||||||
|
- 'PROCESS-NAME,v2ray.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,xray.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,naive.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,trojan.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,trojan-go.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,ss-local.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,privoxy.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,leaf.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,Surge,DIRECT'
|
||||||
|
- 'PROCESS-NAME,Surge 2,DIRECT'
|
||||||
|
- 'PROCESS-NAME,Surge 3,DIRECT'
|
||||||
|
- 'PROCESS-NAME,Surge 4,DIRECT'
|
||||||
|
- 'PROCESS-NAME,Surge%202,DIRECT'
|
||||||
|
- 'PROCESS-NAME,Surge%203,DIRECT'
|
||||||
|
- 'PROCESS-NAME,Surge%204,DIRECT'
|
||||||
|
- 'PROCESS-NAME,Thunder,DIRECT'
|
||||||
|
- 'PROCESS-NAME,DownloadService,DIRECT'
|
||||||
|
- 'PROCESS-NAME,qBittorrent,DIRECT'
|
||||||
|
- 'PROCESS-NAME,Transmission,DIRECT'
|
||||||
|
- 'PROCESS-NAME,fdm,DIRECT'
|
||||||
|
- 'PROCESS-NAME,aria2c,DIRECT'
|
||||||
|
- 'PROCESS-NAME,Folx,DIRECT'
|
||||||
|
- 'PROCESS-NAME,NetTransport,DIRECT'
|
||||||
|
- 'PROCESS-NAME,uTorrent,DIRECT'
|
||||||
|
- 'PROCESS-NAME,WebTorrent,DIRECT'
|
||||||
|
- 'PROCESS-NAME,aria2c.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,BitComet.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,fdm.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,NetTransport.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,qbittorrent.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,Thunder.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,ThunderVIP.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,transmission-daemon.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,transmission-qt.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,uTorrent.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,WebTorrent.exe,DIRECT'
|
||||||
|
- 'PROCESS-NAME,aDrive.exe,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,services.googleapis.cn,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,xn--ngstr-lra8j.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN,safebrowsing.urlsec.qq.com,DIRECT'
|
||||||
|
- 'DOMAIN,safebrowsing.googleapis.com,DIRECT'
|
||||||
|
- 'DOMAIN,developer.apple.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,digicert.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN,ocsp.apple.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN,ocsp.comodoca.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN,ocsp.usertrust.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN,ocsp.sectigo.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN,ocsp.verisign.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,apple-dns.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN,testflight.apple.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN,sandbox.itunes.apple.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN,itunes.apple.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,apps.apple.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,blobstore.apple.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN,cvws.icloud-content.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,mzstatic.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,itunes.apple.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,icloud.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,icloud-content.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,me.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,aaplimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cdn20.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cdn-apple.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,akadns.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,akamaiedge.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,edgekey.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,mwcloudcdn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,mwcname.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,apple.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,apple-cloudkit.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,apple-mapkit.com,DIRECT'
|
||||||
|
- 'DOMAIN,browser-intake-datadoghq.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,chat.openai.com.cdn.cloudflare.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,gemini.google.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,openai-api.arkoselabs.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,openaicom-api-bdcpf8c6d2e9atf6.z01.azurefd.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,openaicomproductionae4b.blob.core.windows.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,production-openaicom-storage.azureedge.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,static.cloudflareinsights.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,ai.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,algolia.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,api.statsig.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,auth0.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,chatgpt.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,chatgpt.livekit.cloud,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,client-api.arkoselabs.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,events.statsigapi.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,featuregates.org,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,host.livekit.cloud,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,identrust.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,intercom.io,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,intercomcdn.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,launchdarkly.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,oaistatic.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,oaiusercontent.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,observeit.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,openai.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,openaiapi-site.azureedge.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,openaicom.imgix.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,segment.io,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,sentry.io,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,stripe.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,turn.livekit.cloud,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,sora.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-KEYWORD,openai,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,api.msn.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,api.statsig.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,assets.msn.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,browser-intake-datadoghq.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,chat.openai.com.cdn.cloudflare.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,copilot.microsoft.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,gateway.bingviz.microsoft.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,gateway.bingviz.microsoftapp.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,in.appcenter.ms,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,location.microsoft.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,odc.officeapps.live.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,openai-api.arkoselabs.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,openaicomproductionae4b.blob.core.windows.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,production-openaicom-storage.azureedge.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,r.bing.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,self.events.data.microsoft.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,services.bingapis.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,static.cloudflareinsights.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,sydney.bing.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,www.bing.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,algolia.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,api.microsoftapp.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,auth0.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,bing-shopping.microsoft-falcon.io,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,challenges.cloudflare.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,chatgpt.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,chatgpt.livekit.cloud,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,client-api.arkoselabs.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,edgeservices.bing.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,events.statsigapi.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,featuregates.org,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,host.livekit.cloud,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,identrust.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,intercom.io,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,intercomcdn.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,launchdarkly.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,oaistatic.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,oaiusercontent.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,observeit.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,openai.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,openaiapi-site.azureedge.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,openaicom.imgix.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,segment.io,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,sentry.io,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,stripe.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,turn.livekit.cloud,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-KEYWORD,openaicom-api,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,ai.google.dev,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,alkalimakersuite-pa.clients6.google.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,makersuite.google.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,bard.google.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,deepmind.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,deepmind.google,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,gemini.google.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,generativeai.google,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,proactivebackend-pa.googleapis.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,apis.google.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-KEYWORD,colab,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-KEYWORD,developerprofiles,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-KEYWORD,generativelanguage,🔥ChatGPT'
|
||||||
|
- 'DOMAIN,cdn.usefathom.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,anthropic.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,claude.ai,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,razie.ai,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,razie.aws.intellij.net,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,etbrains.ai,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,meta.com,🔥ChatGPT'
|
||||||
|
- 'DOMAIN-SUFFIX,cn,DIRECT'
|
||||||
|
- 'DOMAIN-KEYWORD,-cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,126.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,126.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,127.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,163.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,360buyimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,36kr.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,acfun.tv,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,air-matters.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,aixifan.com,DIRECT'
|
||||||
|
- 'DOMAIN-KEYWORD,alicdn,DIRECT'
|
||||||
|
- 'DOMAIN-KEYWORD,alipay,DIRECT'
|
||||||
|
- 'DOMAIN-KEYWORD,taobao,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,amap.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,autonavi.com,DIRECT'
|
||||||
|
- 'DOMAIN-KEYWORD,baidu,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,bdimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,bdstatic.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,bilibili.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,bilivideo.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,caiyunapp.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,clouddn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cnbeta.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cnbetacdn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cootekservice.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,csdn.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ctrip.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,dgtle.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,dianping.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,douban.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,doubanio.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,duokan.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,easou.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ele.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,feng.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,fir.im,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,frdic.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,g-cores.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,godic.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,gtimg.com,DIRECT'
|
||||||
|
- 'DOMAIN,cdn.hockeyapp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,hongxiu.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,hxcdn.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,iciba.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ifeng.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ifengimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ipip.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,iqiyi.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,jd.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,jianshu.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,knewone.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,le.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,lecloud.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,lemicp.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,luoo.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,meituan.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,meituan.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,mi.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,miaopai.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,microsoft.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,microsoftonline.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,miui.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,miwifi.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,mob.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,netease.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,office.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,office365.com,DIRECT'
|
||||||
|
- 'DOMAIN-KEYWORD,officecdn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,oschina.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ppsimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,pstatp.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qcloud.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qdaily.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qdmm.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qhimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qhres.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qidian.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qihucdn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qiniu.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qiniucdn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qiyipic.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qq.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qqurl.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,rarbg.to,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ruguoapp.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,segmentfault.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,sinaapp.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,smzdm.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,snapdrop.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,sogou.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,sogoucdn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,sohu.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,soku.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,speedtest.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,sspai.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,suning.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,taobao.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,tencent.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,tenpay.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,tianyancha.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,tmall.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,tudou.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,umetrip.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,upaiyun.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,upyun.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,veryzhun.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,weather.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,weibo.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xiami.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xiami.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xiaomicp.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ximalaya.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xmcdn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xunlei.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,yhd.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,yihaodianimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,yinxiang.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ykimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,youdao.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,youku.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,zealer.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,zhihu.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,zhimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,zimuzu.tv,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,zoho.com,DIRECT'
|
||||||
|
- 'DOMAIN,fastly-download.epicgames.com,DIRECT'
|
||||||
|
- 'DOMAIN,epicgames-download1.akamaized.net,DIRECT'
|
||||||
|
- 'DOMAIN,steamcdn-a.akamaihd.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,steamserver.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cm.steampowered.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,synology.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,dyndns.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,egdownload.fastly-edge.com,DIRECT'
|
||||||
|
- 'DOMAIN,cn.bing.com,DIRECT'
|
||||||
|
- 'DOMAIN-KEYWORD,amazon,狗狗加速.com'
|
||||||
|
- 'DOMAIN-KEYWORD,google,狗狗加速.com'
|
||||||
|
- 'DOMAIN-KEYWORD,gmail,狗狗加速.com'
|
||||||
|
- 'DOMAIN-KEYWORD,youtube,狗狗加速.com'
|
||||||
|
- 'DOMAIN-KEYWORD,facebook,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,fb.me,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,fbcdn.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-KEYWORD,twitter,狗狗加速.com'
|
||||||
|
- 'DOMAIN-KEYWORD,instagram,狗狗加速.com'
|
||||||
|
- 'DOMAIN-KEYWORD,dropbox,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,twimg.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-KEYWORD,blogspot,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,youtu.be,狗狗加速.com'
|
||||||
|
- 'DOMAIN-KEYWORD,whatsapp,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ipleak.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,browserscan.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,surfsharkdns.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,edns.ip-api.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,dnsleaktest.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,dnsleak.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,expressvpn.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,nordvpn.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,surfshark.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,perfect-privacy.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,browserleaks.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,browserleaks.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,browserleaks.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,vpnunlimited.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,whoer.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,whrq.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-KEYWORD,admarvel,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,admaster,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,adsage,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,adsmogo,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,adsrvmedia,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,adwords,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,adservice,REJECT'
|
||||||
|
- 'DOMAIN-SUFFIX,appsflyer.com,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,domob,REJECT'
|
||||||
|
- 'DOMAIN-SUFFIX,doubleclick.net,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,duomeng,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,dwtrack,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,guanggao,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,lianmeng,REJECT'
|
||||||
|
- 'DOMAIN-SUFFIX,mmstat.com,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,mopub,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,omgmta,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,openx,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,partnerad,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,pingfore,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,supersonicads,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,uedas,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,umeng,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,usage,REJECT'
|
||||||
|
- 'DOMAIN-SUFFIX,vungle.com,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,wlmonitor,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,zjtoolbar,REJECT'
|
||||||
|
- 'DOMAIN-SUFFIX,linkedin.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,licdn.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,9to5mac.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,abpchina.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,adblockplus.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,adobe.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,akamaized.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,alfredapp.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,amplitude.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ampproject.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,android.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,angularjs.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,aolcdn.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,apkpure.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,appledaily.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,appshopper.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,appspot.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,arcgis.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,archive.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,armorgames.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,aspnetcdn.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,att.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,awsstatic.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,azurewebsites.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,bing.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,bintray.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,bit.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,bit.ly,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,bitbucket.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,bjango.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,bkrtx.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,blog.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,blogcdn.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,blogger.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,blogsmithmedia.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,blogspot.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,blogspot.hk,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,bloomberg.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,box.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,box.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,cachefly.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,chromium.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,cl.ly,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,cloudflare.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,cloudfront.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,cloudmagic.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,cmail19.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,cnet.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,cocoapods.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,comodoca.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,crashlytics.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,culturedcode.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,d.pr,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,danilo.to,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,dayone.me,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,db.tt,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,deskconnect.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,disq.us,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,disqus.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,disquscdn.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,dnsimple.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,docker.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,dribbble.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,droplr.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,duckduckgo.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,dueapp.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,dytt8.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,edgecastcdn.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,edgekey.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,edgesuite.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,engadget.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,entrust.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,eurekavpt.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,evernote.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,fabric.io,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,fast.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,fastly.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,fc2.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,feedburner.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,feedly.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,feedsportal.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,fiftythree.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,firebaseio.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,flexibits.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,flickr.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,flipboard.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,g.co,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,gabia.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,geni.us,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,gfx.ms,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ggpht.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ghostnoteapp.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,git.io,狗狗加速.com'
|
||||||
|
- 'DOMAIN-KEYWORD,github,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,globalsign.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,gmodules.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,godaddy.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,golang.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,gongm.in,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,goo.gl,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,goodreaders.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,goodreads.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,gravatar.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,gstatic.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,gvt0.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,hockeyapp.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,hotmail.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,icons8.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ifixit.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ift.tt,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ifttt.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,iherb.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,imageshack.us,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,img.ly,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,imgur.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,imore.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,instapaper.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ipn.li,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,is.gd,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,issuu.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,itgonglun.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,itun.es,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ixquick.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,j.mp,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,js.revsci.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,jshint.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,jtvnw.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,justgetflux.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,kat.cr,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,klip.me,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,libsyn.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,line-apps.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,linode.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,lithium.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,littlehj.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,live.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,live.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,livefilestore.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,llnwd.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,macid.co,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,macromedia.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,macrumors.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,mashable.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,mathjax.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,medium.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,mega.co.nz,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,mega.nz,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,megaupload.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,microsofttranslator.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,mindnode.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,mobile01.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,modmyi.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,msedge.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,myfontastic.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,name.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,nextmedia.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,nsstatic.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,nssurge.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,nyt.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,nytimes.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,omnigroup.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,onedrive.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,onenote.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ooyala.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,openvpn.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,openwrt.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,orkut.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,osxdaily.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,outlook.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ow.ly,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,paddleapi.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,parallels.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,parse.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,pdfexpert.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,periscope.tv,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,pinboard.in,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,pinterest.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,pixelmator.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,pixiv.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,playpcesor.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,playstation.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,playstation.com.hk,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,playstation.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,playstationnetwork.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,pushwoosh.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,rime.im,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,servebom.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,sfx.ms,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,shadowsocks.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,sharethis.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,shazam.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,skype.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,smartdnsproxy.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,smartmailcloud.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,sndcdn.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,sony.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,soundcloud.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,sourceforge.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,spotify.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,squarespace.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,sstatic.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,st.luluku.pw,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,stackoverflow.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,startpage.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,staticflickr.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,steamcommunity.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,symauth.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,symcb.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,symcd.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,tapbots.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,tapbots.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,tdesktop.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,techcrunch.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,techsmith.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,thepiratebay.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,theverge.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,time.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,timeinc.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,tiny.cc,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,tinypic.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,tmblr.co,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,todoist.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,trello.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,trustasiassl.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,tumblr.co,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,tumblr.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,tweetdeck.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,tweetmarker.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,twitch.tv,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,txmblr.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,typekit.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ubertags.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ublock.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ubnt.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ulyssesapp.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,urchin.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,usertrust.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,v.gd,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,v2ex.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,vimeo.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,vimeocdn.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,vine.co,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,vivaldi.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,vox-cdn.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,vsco.co,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,vultr.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,w.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,w3schools.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,webtype.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,wikiwand.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,wikileaks.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,wikimedia.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,wikipedia.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,wikipedia.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,windows.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,windows.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,wire.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,wordpress.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,workflowy.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,wp.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,wsj.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,wsj.net,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,xda-developers.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,xeeno.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,xiti.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,yahoo.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,yimg.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ying.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,yoyo.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,ytimg.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,signal.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,whispersystems.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,cangku.moe,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,tradingview.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,x.com,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,asmr.one,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,telegra.ph,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,telegram.org,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,t.me,狗狗加速.com'
|
||||||
|
- 'DOMAIN-SUFFIX,telegram.me,狗狗加速.com'
|
||||||
|
- 'IP-CIDR,91.108.4.0/22,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,91.108.8.0/21,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,91.108.16.0/22,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,91.108.56.0/22,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,149.154.160.0/20,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR6,2001:67c:4e8::/48,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR6,2001:b28:f23d::/48,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR6,2001:b28:f23f::/48,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,120.232.181.162/32,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,120.241.147.226/32,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,120.253.253.226/32,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,120.253.255.162/32,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,120.253.255.34/32,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,120.253.255.98/32,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,180.163.150.162/32,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,180.163.150.34/32,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,180.163.151.162/32,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,180.163.151.34/32,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,203.208.39.0/24,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,203.208.40.0/24,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,203.208.41.0/24,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,203.208.43.0/24,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,203.208.50.0/24,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,220.181.174.162/32,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,220.181.174.226/32,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,220.181.174.34/32,狗狗加速.com,no-resolve'
|
||||||
|
- 'IP-CIDR,24.199.123.28/32,🔥ChatGPT,no-resolve'
|
||||||
|
- 'IP-CIDR,64.23.132.171/32,🔥ChatGPT,no-resolve'
|
||||||
|
- 'IP-CIDR,24.199.123.28/32,🔥ChatGPT,no-resolve'
|
||||||
|
- 'IP-CIDR,64.23.132.171/32,🔥ChatGPT,no-resolve'
|
||||||
|
- 'DOMAIN,injections.adguard.org,DIRECT'
|
||||||
|
- 'DOMAIN,local.adguard.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,local,DIRECT'
|
||||||
|
- 'IP-CIDR,127.0.0.0/8,DIRECT'
|
||||||
|
- 'IP-CIDR,172.16.0.0/12,DIRECT'
|
||||||
|
- 'IP-CIDR,192.168.0.0/16,DIRECT'
|
||||||
|
- 'IP-CIDR,10.0.0.0/8,DIRECT'
|
||||||
|
- 'IP-CIDR,17.0.0.0/8,DIRECT'
|
||||||
|
- 'IP-CIDR,100.64.0.0/10,DIRECT'
|
||||||
|
- 'IP-CIDR,224.0.0.0/4,DIRECT'
|
||||||
|
- 'IP-CIDR6,fe80::/10,DIRECT'
|
||||||
|
- 'GEOIP,CN,DIRECT'
|
||||||
|
- 'MATCH,狗狗加速.com'
|
||||||
File diff suppressed because it is too large
Load Diff
Executable
+647
@@ -0,0 +1,647 @@
|
|||||||
|
mixed-port: 7890
|
||||||
|
allow-lan: true
|
||||||
|
bind-address: '*'
|
||||||
|
mode: rule
|
||||||
|
log-level: info
|
||||||
|
ipv6: false
|
||||||
|
|
||||||
|
skip-auth-prefixes: # 设置跳过验证的 IP 段
|
||||||
|
- 127.0.0.1/8
|
||||||
|
- ::1/128
|
||||||
|
|
||||||
|
find-process-mode: strict
|
||||||
|
unified-delay: true
|
||||||
|
|
||||||
|
|
||||||
|
external-controller: 0.0.0.0:9090
|
||||||
|
external-controller-cors:
|
||||||
|
allow-private-network: true
|
||||||
|
allow-origins:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
|
||||||
|
### Tunnel配置
|
||||||
|
tun:
|
||||||
|
enable: false
|
||||||
|
stack: system
|
||||||
|
device: meta
|
||||||
|
auto-route: true
|
||||||
|
auto-detect-interface: true
|
||||||
|
dns-hijack:
|
||||||
|
- any:53
|
||||||
|
- tcp://any:53
|
||||||
|
strict-route: true
|
||||||
|
mtu: 1500
|
||||||
|
# 如果有使用zerotier或者headscale等,需要自己配置排除自己的网段
|
||||||
|
# route-exclude-address: ["192.168.110.0/24"]
|
||||||
|
|
||||||
|
|
||||||
|
dns:
|
||||||
|
enable: true
|
||||||
|
ipv6: false
|
||||||
|
default-nameserver: [223.5.5.5, 119.29.29.29]
|
||||||
|
enhanced-mode: fake-ip
|
||||||
|
fake-ip-range: 198.18.0.1/16
|
||||||
|
fake-ip-filter: ['*.lan','*.localhost','*.cpolar.top','*.picp.net','*.3322.org','*.dscloud.me','*.joyagain.top','*.joyagain.me','*.xicp.cn','*.himan.vip']
|
||||||
|
use-hosts: true
|
||||||
|
nameserver: ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query']
|
||||||
|
fallback: ['https://doh.dns.sb/dns-query', 'https://dns.cloudflare.com/dns-query', 'https://dns.twnic.tw/dns-query', 'tls://8.8.4.4:853']
|
||||||
|
fallback-filter: { geoip: true, ipcidr: [240.0.0.0/4, 0.0.0.0/32] }
|
||||||
|
proxies:
|
||||||
|
- { name: '剩余流量:3574.8 GB', type: ss, server: www.4399.com, port: 60001, cipher: chacha20-ietf-poly1305, password: 5135ccc0-37f1-4d5e-8df5-594b2440878d, udp: true }
|
||||||
|
- { name: 套餐到期:长期有效, type: ss, server: www.4399.com, port: 60001, cipher: chacha20-ietf-poly1305, password: 5135ccc0-37f1-4d5e-8df5-594b2440878d, udp: true }
|
||||||
|
- { name: 地址:国际流量.COM, type: ss, server: www.4399.com, port: 60001, cipher: chacha20-ietf-poly1305, password: 5135ccc0-37f1-4d5e-8df5-594b2440878d, udp: true }
|
||||||
|
- { name: 地址:iPLC国际流量站.COM, type: ss, server: www.4399.com, port: 60001, cipher: chacha20-ietf-poly1305, password: 5135ccc0-37f1-4d5e-8df5-594b2440878d, udp: true }
|
||||||
|
- { name: ⚠️请设置自动更新订阅, type: ss, server: www.4399.com, port: 60008, cipher: chacha20-ietf-poly1305, password: 5135ccc0-37f1-4d5e-8df5-594b2440878d, udp: true }
|
||||||
|
- { name: '01 美国 高级静态', type: vmess, server: 50001.20250808iplcin.top, port: 50001, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '02 美国 顶级', type: vmess, server: 50002.20250808iplcin.top, port: 50002, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '03 美国 初级慢速', type: vmess, server: 50003.20250808iplcin.top, port: 50003, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '04 美国 初级年费专享', type: vmess, server: 50004.20250808iplcin.top, port: 50004, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '05 美国 高级优先', type: vmess, server: 50005.20250808iplcin.top, port: 50005, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '06 新加坡 高级', type: vmess, server: 50006.20250808iplcin.top, port: 50006, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '07 新加坡 顶级', type: vmess, server: 50007.20250808iplcin.top, port: 50007, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '08 新加坡 高级', type: vmess, server: 50008.20250808iplcin.top, port: 50008, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '09 新加坡 高级下载', type: vmess, server: 50009.20250808iplcin.top, port: 50009, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '10 新加坡 高级概率解锁', type: vmess, server: 50010.20250808iplcin.top, port: 50010, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '11 新加坡 高级概率解锁', type: vmess, server: 50011.20250808iplcin.top, port: 50011, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '12 新加坡 高级高速', type: vmess, server: 50012.20250808iplcin.top, port: 50012, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '13 新加坡 顶级极速', type: vmess, server: 50013.20250808iplcin.top, port: 50013, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '14 新加坡 流畅初级', type: vmess, server: 50014.20250808iplcin.top, port: 50014, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '15 新加坡 初级', type: vmess, server: 50015.20250808iplcin.top, port: 50015, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '16 台湾 顶级', type: vmess, server: 50016.20250808iplcin.top, port: 50016, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '17 台湾 高级', type: vmess, server: 50017.20250808iplcin.top, port: 50017, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '18 台湾 高级', type: vmess, server: 50018.20250808iplcin.top, port: 50018, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '19 台湾 顶级', type: vmess, server: 50019.20250808iplcin.top, port: 50019, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '20 台湾 高级高速', type: vmess, server: 50020.20250808iplcin.top, port: 50020, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '21 香港 初级年付', type: vmess, server: 50021.20250808iplcin.top, port: 50021, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '22 香港 新加坡 动态', type: vmess, server: 50022.20250808iplcin.top, port: 50022, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '23 新加坡高级高速', type: vmess, server: 50023.20250808iplcin.top, port: 50023, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '24 香港 新加坡 高级动态', type: vmess, server: 50024.20250808iplcin.top, port: 50024, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '25 香港 新加坡 高级动态', type: vmess, server: 50025.20250808iplcin.top, port: 50025, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '26 新加坡 顶级极速 静态', type: vmess, server: 50026.20250808iplcin.top, port: 50026, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '27 香港 新加坡 高级动态', type: vmess, server: 50027.20250808iplcin.top, port: 50027, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '28 香港 新加坡 高级', type: vmess, server: 50028.20250808iplcin.top, port: 50028, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '29 香港 新加坡 视频增强', type: vmess, server: 50029.20250808iplcin.top, port: 50029, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '30 香港 新加坡 高级双线', type: vmess, server: 50030.20250808iplcin.top, port: 50030, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '31 日本 高级', type: vmess, server: 50031.20250808iplcin.top, port: 50031, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '32 日本 高级', type: vmess, server: 50032.20250808iplcin.top, port: 50032, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '33 日本 顶级极速', type: vmess, server: 50033.20250808iplcin.top, port: 50033, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '34 日本 顶级极速', type: vmess, server: 50034.20250808iplcin.top, port: 50034, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
- { name: '35 日本 顶级', type: vmess, server: 50035.20250808iplcin.top, port: 50035, uuid: 5135ccc0-37f1-4d5e-8df5-594b2440878d, alterId: 0, cipher: auto, udp: true }
|
||||||
|
proxy-groups:
|
||||||
|
- { name: IPLC 国际流量站, type: select, proxies: [自动选择, 故障转移, '剩余流量:3574.8 GB', 套餐到期:长期有效, 地址:国际流量.COM, 地址:iPLC国际流量站.COM, ⚠️请设置自动更新订阅, '01 美国 高级静态', '02 美国 顶级', '03 美国 初级慢速', '04 美国 初级年费专享', '05 美国 高级优先', '06 新加坡 高级', '07 新加坡 顶级', '08 新加坡 高级', '09 新加坡 高级下载', '10 新加坡 高级概率解锁', '11 新加坡 高级概率解锁', '12 新加坡 高级高速', '13 新加坡 顶级极速', '14 新加坡 流畅初级', '15 新加坡 初级', '16 台湾 顶级', '17 台湾 高级', '18 台湾 高级', '19 台湾 顶级', '20 台湾 高级高速', '21 香港 初级年付', '22 香港 新加坡 动态', '23 新加坡高级高速', '24 香港 新加坡 高级动态', '25 香港 新加坡 高级动态', '26 新加坡 顶级极速 静态', '27 香港 新加坡 高级动态', '28 香港 新加坡 高级', '29 香港 新加坡 视频增强', '30 香港 新加坡 高级双线', '31 日本 高级', '32 日本 高级', '33 日本 顶级极速', '34 日本 顶级极速', '35 日本 顶级'] }
|
||||||
|
- { name: 自动选择, type: url-test, proxies: ['剩余流量:3574.8 GB', 套餐到期:长期有效, 地址:国际流量.COM, 地址:iPLC国际流量站.COM, ⚠️请设置自动更新订阅, '01 美国 高级静态', '02 美国 顶级', '03 美国 初级慢速', '04 美国 初级年费专享', '05 美国 高级优先', '06 新加坡 高级', '07 新加坡 顶级', '08 新加坡 高级', '09 新加坡 高级下载', '10 新加坡 高级概率解锁', '11 新加坡 高级概率解锁', '12 新加坡 高级高速', '13 新加坡 顶级极速', '14 新加坡 流畅初级', '15 新加坡 初级', '16 台湾 顶级', '17 台湾 高级', '18 台湾 高级', '19 台湾 顶级', '20 台湾 高级高速', '21 香港 初级年付', '22 香港 新加坡 动态', '23 新加坡高级高速', '24 香港 新加坡 高级动态', '25 香港 新加坡 高级动态', '26 新加坡 顶级极速 静态', '27 香港 新加坡 高级动态', '28 香港 新加坡 高级', '29 香港 新加坡 视频增强', '30 香港 新加坡 高级双线', '31 日本 高级', '32 日本 高级', '33 日本 顶级极速', '34 日本 顶级极速', '35 日本 顶级'], url: 'http://www.gstatic.com/generate_204', interval: 86400 }
|
||||||
|
- { name: 故障转移, type: fallback, proxies: ['剩余流量:3574.8 GB', 套餐到期:长期有效, 地址:国际流量.COM, 地址:iPLC国际流量站.COM, ⚠️请设置自动更新订阅, '01 美国 高级静态', '02 美国 顶级', '03 美国 初级慢速', '04 美国 初级年费专享', '05 美国 高级优先', '06 新加坡 高级', '07 新加坡 顶级', '08 新加坡 高级', '09 新加坡 高级下载', '10 新加坡 高级概率解锁', '11 新加坡 高级概率解锁', '12 新加坡 高级高速', '13 新加坡 顶级极速', '14 新加坡 流畅初级', '15 新加坡 初级', '16 台湾 顶级', '17 台湾 高级', '18 台湾 高级', '19 台湾 顶级', '20 台湾 高级高速', '21 香港 初级年付', '22 香港 新加坡 动态', '23 新加坡高级高速', '24 香港 新加坡 高级动态', '25 香港 新加坡 高级动态', '26 新加坡 顶级极速 静态', '27 香港 新加坡 高级动态', '28 香港 新加坡 高级', '29 香港 新加坡 视频增强', '30 香港 新加坡 高级双线', '31 日本 高级', '32 日本 高级', '33 日本 顶级极速', '34 日本 顶级极速', '35 日本 顶级'], url: 'http://www.gstatic.com/generate_204', interval: 7200 }
|
||||||
|
rules:
|
||||||
|
- 'DOMAIN,20250808iplcin.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,services.googleapis.cn,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,xn--ngstr-lra8j.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN,safebrowsing.urlsec.qq.com,DIRECT'
|
||||||
|
- 'DOMAIN,safebrowsing.googleapis.com,DIRECT'
|
||||||
|
- 'DOMAIN,developer.apple.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,digicert.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN,ocsp.apple.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN,ocsp.comodoca.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN,ocsp.usertrust.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN,ocsp.sectigo.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN,ocsp.verisign.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,apple-dns.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN,testflight.apple.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN,sandbox.itunes.apple.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN,itunes.apple.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,apps.apple.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,blobstore.apple.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN,cvws.icloud-content.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,mzstatic.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,itunes.apple.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,icloud.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,icloud-content.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,me.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,aaplimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cdn20.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cdn-apple.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,akadns.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,akamaiedge.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,edgekey.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,mwcloudcdn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,mwcname.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,apple.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,apple-cloudkit.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,apple-mapkit.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,126.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,126.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,127.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,163.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,360buyimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,36kr.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,acfun.tv,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,air-matters.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,aixifan.com,DIRECT'
|
||||||
|
- 'DOMAIN-KEYWORD,alicdn,DIRECT'
|
||||||
|
- 'DOMAIN-KEYWORD,alipay,DIRECT'
|
||||||
|
- 'DOMAIN-KEYWORD,taobao,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,amap.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,autonavi.com,DIRECT'
|
||||||
|
- 'DOMAIN-KEYWORD,baidu,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,bdimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,bdstatic.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,bilibili.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,bilivideo.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,caiyunapp.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,clouddn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cnbeta.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cnbetacdn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cootekservice.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,csdn.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ctrip.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,dgtle.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,dianping.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,douban.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,doubanio.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,duokan.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,easou.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ele.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,feng.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,fir.im,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,frdic.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,g-cores.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,godic.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,gtimg.com,DIRECT'
|
||||||
|
- 'DOMAIN,cdn.hockeyapp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,hongxiu.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,hxcdn.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,iciba.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ifeng.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ifengimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ipip.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,iqiyi.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,jd.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,jianshu.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,knewone.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,le.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,lecloud.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,lemicp.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,licdn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,luoo.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,meituan.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,meituan.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,mi.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,miaopai.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,microsoft.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,microsoftonline.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,miui.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,miwifi.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,mob.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,netease.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,office.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,office365.com,DIRECT'
|
||||||
|
- 'DOMAIN-KEYWORD,officecdn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,oschina.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ppsimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,pstatp.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qcloud.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qdaily.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qdmm.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qhimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qhres.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qidian.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qihucdn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qiniu.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qiniucdn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qiyipic.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qq.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,qqurl.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,rarbg.to,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ruguoapp.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,segmentfault.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,sinaapp.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,smzdm.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,snapdrop.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,sogou.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,sogoucdn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,sohu.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,soku.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,speedtest.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,sspai.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,suning.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,taobao.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,tencent.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,tenpay.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,tianyancha.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,tmall.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,tudou.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,umetrip.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,upaiyun.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,upyun.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,veryzhun.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,weather.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,weibo.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xiami.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xiami.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xiaomicp.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ximalaya.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xmcdn.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xunlei.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,yhd.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,yihaodianimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,yinxiang.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,ykimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,youdao.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,youku.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,zealer.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,zhihu.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,zhimg.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,zimuzu.tv,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,zoho.com,DIRECT'
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,emby.xiaoya.pro,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,icyou.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,lanyuewan.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.8.net.co,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.raydoom.tk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.kaiserver.uk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,embyxiaoya.laogl.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.poxi1221.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ermaokj.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.bdbd.fun,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wwwh.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.f1rst.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ymschh.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wx1.us.kg,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.r2s.site,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.neversay.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.800686.xyz,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,syncthing.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,3322.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,picp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,3322.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,picp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,wicp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xicp.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,dscloud.me,DIRECT'
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,againgo.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.vip,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xuanyuan.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,1ms.run,DIRECT'
|
||||||
|
|
||||||
|
|
||||||
|
- 'DOMAIN-KEYWORD,amazon,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-KEYWORD,google,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-KEYWORD,gmail,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-KEYWORD,youtube,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-KEYWORD,facebook,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,fb.me,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,fbcdn.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-KEYWORD,twitter,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-KEYWORD,instagram,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-KEYWORD,dropbox,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,twimg.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-KEYWORD,blogspot,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,youtu.be,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-KEYWORD,whatsapp,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-KEYWORD,admarvel,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,admaster,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,adsage,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,adsmogo,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,adsrvmedia,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,adwords,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,adservice,REJECT'
|
||||||
|
- 'DOMAIN-SUFFIX,appsflyer.com,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,domob,REJECT'
|
||||||
|
- 'DOMAIN-SUFFIX,doubleclick.net,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,duomeng,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,dwtrack,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,guanggao,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,lianmeng,REJECT'
|
||||||
|
- 'DOMAIN-SUFFIX,mmstat.com,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,mopub,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,omgmta,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,openx,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,partnerad,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,pingfore,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,supersonicads,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,uedas,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,umeng,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,usage,REJECT'
|
||||||
|
- 'DOMAIN-SUFFIX,vungle.com,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,wlmonitor,REJECT'
|
||||||
|
- 'DOMAIN-KEYWORD,zjtoolbar,REJECT'
|
||||||
|
- 'DOMAIN-SUFFIX,9to5mac.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,abpchina.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,adblockplus.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,adobe.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,akamaized.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,alfredapp.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,amplitude.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ampproject.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,android.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,angularjs.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,aolcdn.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,apkpure.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,appledaily.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,appshopper.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,appspot.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,arcgis.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,archive.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,armorgames.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,aspnetcdn.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,att.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,awsstatic.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,azureedge.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,azurewebsites.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,bing.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,bintray.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,bit.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,bit.ly,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,bitbucket.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,bjango.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,bkrtx.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,blog.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,blogcdn.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,blogger.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,blogsmithmedia.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,blogspot.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,blogspot.hk,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,bloomberg.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,box.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,box.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,cachefly.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,chromium.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,cl.ly,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,cloudflare.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,cloudfront.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,cloudmagic.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,cmail19.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,cnet.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,cocoapods.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,comodoca.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,crashlytics.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,culturedcode.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,d.pr,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,danilo.to,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,dayone.me,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,db.tt,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,deskconnect.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,disq.us,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,disqus.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,disquscdn.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,dnsimple.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,docker.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,dribbble.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,droplr.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,duckduckgo.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,dueapp.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,dytt8.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,edgecastcdn.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,edgekey.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,edgesuite.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,engadget.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,entrust.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,eurekavpt.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,evernote.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,fabric.io,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,fast.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,fastly.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,fc2.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,feedburner.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,feedly.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,feedsportal.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,fiftythree.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,firebaseio.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,flexibits.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,flickr.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,flipboard.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,g.co,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,gabia.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,geni.us,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,gfx.ms,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ggpht.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ghostnoteapp.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,git.io,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-KEYWORD,github,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,globalsign.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,gmodules.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,godaddy.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,golang.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,gongm.in,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,goo.gl,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,goodreaders.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,goodreads.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,gravatar.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,gstatic.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,gvt0.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,hockeyapp.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,hotmail.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,icons8.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ifixit.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ift.tt,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ifttt.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,iherb.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,imageshack.us,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,img.ly,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,imgur.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,imore.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,instapaper.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ipn.li,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,is.gd,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,issuu.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,itgonglun.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,itun.es,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ixquick.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,j.mp,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,js.revsci.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,jshint.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,jtvnw.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,justgetflux.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,kat.cr,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,klip.me,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,libsyn.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,linkedin.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,line-apps.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,linode.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,lithium.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,littlehj.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,live.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,live.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,livefilestore.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,llnwd.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,macid.co,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,macromedia.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,macrumors.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,mashable.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,mathjax.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,medium.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,mega.co.nz,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,mega.nz,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,megaupload.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,microsofttranslator.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,mindnode.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,mobile01.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,modmyi.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,msedge.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,myfontastic.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,name.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,nextmedia.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,nsstatic.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,nssurge.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,nyt.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,nytimes.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,omnigroup.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,onedrive.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,onenote.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ooyala.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,openvpn.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,openwrt.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,orkut.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,osxdaily.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,outlook.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ow.ly,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,paddleapi.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,parallels.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,parse.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,pdfexpert.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,periscope.tv,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,pinboard.in,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,pinterest.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,pixelmator.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,pixiv.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,playpcesor.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,playstation.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,playstation.com.hk,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,playstation.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,playstationnetwork.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,pushwoosh.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,rime.im,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,servebom.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,sfx.ms,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,shadowsocks.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,sharethis.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,shazam.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,skype.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,slack.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,smartdnsIPLC 国际流量站.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,smartmailcloud.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,sndcdn.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,sony.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,soundcloud.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,sourceforge.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,spotify.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,squarespace.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,sstatic.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,st.luluku.pw,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,stackoverflow.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,startpage.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,staticflickr.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,steamcommunity.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,symauth.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,symcb.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,symcd.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,tapbots.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,tapbots.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,tdesktop.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,techcrunch.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,techsmith.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,thepiratebay.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,theverge.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,time.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,timeinc.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,tiny.cc,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,tinypic.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,tmblr.co,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,todoist.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,trello.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,trustasiassl.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,tumblr.co,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,tumblr.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,tweetdeck.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,tweetmarker.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,twitch.tv,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,txmblr.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,typekit.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ubertags.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ublock.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ubnt.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ulyssesapp.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,urchin.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,usertrust.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,v.gd,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,v2ex.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,vimeo.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,vimeocdn.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,vine.co,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,vivaldi.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,vox-cdn.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,vsco.co,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,vultr.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,w.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,w3schools.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,webtype.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,wikiwand.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,wikileaks.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,wikimedia.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,wikipedia.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,wikipedia.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,windows.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,windows.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,wire.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,wordpress.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,workflowy.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,wp.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,wsj.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,wsj.net,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,xda-developers.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,xeeno.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,xiti.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,yahoo.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,yimg.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ying.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,yoyo.org,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,ytimg.com,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,telegra.ph,IPLC 国际流量站'
|
||||||
|
- 'DOMAIN-SUFFIX,telegram.org,IPLC 国际流量站'
|
||||||
|
- 'IP-CIDR,91.108.4.0/22,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,91.108.8.0/21,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,91.108.16.0/22,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,91.108.56.0/22,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,149.154.160.0/20,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR6,2001:67c:4e8::/48,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR6,2001:b28:f23d::/48,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR6,2001:b28:f23f::/48,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,120.232.181.162/32,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,120.241.147.226/32,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,120.253.253.226/32,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,120.253.255.162/32,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,120.253.255.34/32,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,120.253.255.98/32,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,180.163.150.162/32,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,180.163.150.34/32,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,180.163.151.162/32,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,180.163.151.34/32,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,203.208.39.0/24,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,203.208.40.0/24,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,203.208.41.0/24,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,203.208.43.0/24,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,203.208.50.0/24,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,220.181.174.162/32,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,220.181.174.226/32,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'IP-CIDR,220.181.174.34/32,IPLC 国际流量站,no-resolve'
|
||||||
|
- 'DOMAIN,injections.adguard.org,DIRECT'
|
||||||
|
- 'DOMAIN,local.adguard.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,local,DIRECT'
|
||||||
|
- 'IP-CIDR,127.0.0.0/8,DIRECT'
|
||||||
|
- 'IP-CIDR,172.16.0.0/12,DIRECT'
|
||||||
|
- 'IP-CIDR,192.168.0.0/16,DIRECT'
|
||||||
|
- 'IP-CIDR,10.0.0.0/8,DIRECT'
|
||||||
|
- 'IP-CIDR,17.0.0.0/8,DIRECT'
|
||||||
|
- 'IP-CIDR,100.64.0.0/10,DIRECT'
|
||||||
|
- 'IP-CIDR,224.0.0.0/4,DIRECT'
|
||||||
|
- 'IP-CIDR6,fe80::/10,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cn,DIRECT'
|
||||||
|
- 'DOMAIN-KEYWORD,-cn,DIRECT'
|
||||||
|
- 'GEOIP,CN,DIRECT'
|
||||||
|
- 'MATCH,IPLC 国际流量站'
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
mixed-port: 7890
|
||||||
|
allow-lan: true
|
||||||
|
bind-address: '*'
|
||||||
|
mode: rule
|
||||||
|
log-level: info
|
||||||
|
external-controller: '0.0.0.0:9090'
|
||||||
|
|
||||||
|
tun:
|
||||||
|
enable: true
|
||||||
|
stack: mixed
|
||||||
|
dns-hijack:
|
||||||
|
- "any:53"
|
||||||
|
- "tcp://any:53"
|
||||||
|
auto-route: true
|
||||||
|
auto-redirect: true
|
||||||
|
auto-detect-interface: true
|
||||||
|
|
||||||
|
proxy-providers:
|
||||||
|
IPLC:
|
||||||
|
url: "https://sub.20250715iplcsub.link/qC8zV8qS1kB1lX2u/4OLCCKkHWHgeCM6m"
|
||||||
|
type: http
|
||||||
|
interval: 86400
|
||||||
|
health-check: {enable: true,url: "https://www.gstatic.com/generate_204", interval: 300}
|
||||||
|
override:
|
||||||
|
additional-prefix: "IPLC"
|
||||||
|
|
||||||
|
proxies:
|
||||||
|
- name: "直连"
|
||||||
|
type: direct
|
||||||
|
udp: true
|
||||||
|
|
||||||
|
geodata-mode: true
|
||||||
|
geox-url:
|
||||||
|
geoip: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat"
|
||||||
|
geosite: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat"
|
||||||
|
mmdb: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country-lite.mmdb"
|
||||||
|
asn: "https://gh-proxy.com/https://github.com/xishang0128/geoip/releases/download/latest/GeoLite2-ASN.mmdb"
|
||||||
|
|
||||||
|
dns:
|
||||||
|
enable: true
|
||||||
|
ipv6: true
|
||||||
|
respect-rules: true
|
||||||
|
enhanced-mode: fake-ip
|
||||||
|
fake-ip-filter:
|
||||||
|
- "*"
|
||||||
|
- "+.lan"
|
||||||
|
- "+.local"
|
||||||
|
- "+.market.xiaomi.com"
|
||||||
|
nameserver:
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
proxy-server-nameserver:
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
nameserver-policy:
|
||||||
|
"geosite:cn,private":
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
"geosite:geolocation-!cn":
|
||||||
|
- "https://dns.cloudflare.com/dns-query"
|
||||||
|
- "https://dns.google/dns-query"
|
||||||
|
|
||||||
|
proxy-groups:
|
||||||
|
|
||||||
|
- name: 默认
|
||||||
|
type: select
|
||||||
|
proxies: [自动选择,直连,香港,台湾,日本,新加坡,美国,其它地区,全部节点]
|
||||||
|
|
||||||
|
- name: Google
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Telegram
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Twitter
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 哔哩哔哩
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 巴哈姆特
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: YouTube
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: NETFLIX
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Spotify
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Github
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 国内
|
||||||
|
type: select
|
||||||
|
proxies: [直连,默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择]
|
||||||
|
|
||||||
|
- name: 其他
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
#分隔,下面是地区分组
|
||||||
|
- name: 香港
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)港|hk|hongkong|hong kong"
|
||||||
|
|
||||||
|
- name: 台湾
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)台|tw|taiwan"
|
||||||
|
|
||||||
|
- name: 日本
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)日|jp|japan"
|
||||||
|
|
||||||
|
- name: 美国
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)美|us|unitedstates|united states"
|
||||||
|
|
||||||
|
- name: 新加坡
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)(新|sg|singapore)"
|
||||||
|
|
||||||
|
- name: 其它地区
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)^(?!.*(?:|||||港|hk|hongkong|台|tw|taiwan|日|jp|japan|新|sg|singapore|美|us|unitedstates)).*"
|
||||||
|
|
||||||
|
- name: 全部节点
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
|
||||||
|
- name: 自动选择
|
||||||
|
type: url-test
|
||||||
|
include-all: true
|
||||||
|
tolerance: 10
|
||||||
|
|
||||||
|
rules:
|
||||||
|
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,synology.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,digitalocean.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,synocommunity.com,DIRECT'
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,emby.xiaoya.pro,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,icyou.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,lanyuewan.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.8.net.co,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.raydoom.tk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.kaiserver.uk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,embyxiaoya.laogl.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.poxi1221.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ermaokj.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.bdbd.fun,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wwwh.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.f1rst.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ymschh.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wx1.us.kg,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.r2s.site,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.neversay.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.800686.xyz,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,syncthing.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,3322.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,picp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,wicp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xicp.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,againgo.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.vip,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.cloud,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xuanyuan.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,1ms.run,DIRECT'
|
||||||
|
|
||||||
|
- GEOIP,lan,直连,no-resolve
|
||||||
|
- GEOSITE,github,Github
|
||||||
|
- GEOSITE,twitter,Twitter
|
||||||
|
- GEOSITE,youtube,YouTube
|
||||||
|
- GEOSITE,google,Google
|
||||||
|
- GEOSITE,telegram,Telegram
|
||||||
|
- GEOSITE,netflix,NETFLIX
|
||||||
|
- GEOSITE,bilibili,哔哩哔哩
|
||||||
|
- GEOSITE,bahamut,巴哈姆特
|
||||||
|
- GEOSITE,spotify,Spotify
|
||||||
|
- GEOSITE,CN,国内
|
||||||
|
- GEOSITE,geolocation-!cn,其他
|
||||||
|
|
||||||
|
- GEOIP,google,Google
|
||||||
|
- GEOIP,netflix,NETFLIX
|
||||||
|
- GEOIP,telegram,Telegram
|
||||||
|
- GEOIP,twitter,Twitter
|
||||||
|
- GEOIP,CN,国内
|
||||||
|
- MATCH,其他
|
||||||
Executable
+16
@@ -0,0 +1,16 @@
|
|||||||
|
services:
|
||||||
|
calibre-web-automated:
|
||||||
|
image: crocodilestick/calibre-web-automated:latest
|
||||||
|
container_name: calibre-web-automated
|
||||||
|
network_mode: bridge
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=100
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
volumes:
|
||||||
|
- /vol2/1000/docker/CWA/config:/config
|
||||||
|
- /vol3/1000/USBD1/Imports:/cwa-book-ingest
|
||||||
|
- /vol3/1000/USBD1/Books:/calibre-library
|
||||||
|
ports:
|
||||||
|
- 7083:8083
|
||||||
|
restart: always
|
||||||
Executable
+20
@@ -0,0 +1,20 @@
|
|||||||
|
version: "3"
|
||||||
|
services:
|
||||||
|
syncthing:
|
||||||
|
image: syncthing/syncthing:latest
|
||||||
|
container_name: syncthing
|
||||||
|
hostname: syncthing-fn
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- STGUIADDRESS=0.0.0.0:8384
|
||||||
|
volumes:
|
||||||
|
- /vol2/1000/docker/syncthing:/var/syncthing
|
||||||
|
- /vol3/1000/USBD1/Imports:/data1
|
||||||
|
network_mode: host
|
||||||
|
restart: always
|
||||||
|
healthcheck:
|
||||||
|
test: curl -fkLsS -m 2 127.0.0.1:8384/rest/noauth/health | grep -o --color=never OK || exit 1
|
||||||
|
interval: 1m
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
version: '2.0'
|
||||||
|
services:
|
||||||
|
chatgpt-on-wechat:
|
||||||
|
image: zhayujie/chatgpt-on-wechat
|
||||||
|
container_name: chatgpt-on-wechat
|
||||||
|
security_opt:
|
||||||
|
- seccomp:unconfined
|
||||||
|
environment:
|
||||||
|
CHANNEL_TYPE: 'web'
|
||||||
|
OPEN_AI_API_KEY: 'YOUR API KEY'
|
||||||
|
MODEL: ''
|
||||||
|
PROXY: ''
|
||||||
|
SINGLE_CHAT_PREFIX: '["bot", "@bot"]'
|
||||||
|
SINGLE_CHAT_REPLY_PREFIX: '"[bot] "'
|
||||||
|
GROUP_CHAT_PREFIX: '["@bot"]'
|
||||||
|
GROUP_NAME_WHITE_LIST: '["ChatGPT测试群", "ChatGPT测试群2"]'
|
||||||
|
IMAGE_CREATE_PREFIX: '["画", "看", "找"]'
|
||||||
|
CONVERSATION_MAX_TOKENS: 1000
|
||||||
|
SPEECH_RECOGNITION: 'False'
|
||||||
|
CHARACTER_DESC: '你是基于大语言模型的AI智能助手,旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。'
|
||||||
|
EXPIRES_IN_SECONDS: 3600
|
||||||
|
USE_GLOBAL_PLUGIN_CONFIG: 'True'
|
||||||
|
USE_LINKAI: 'False'
|
||||||
|
LINKAI_API_KEY: ''
|
||||||
|
LINKAI_APP_CODE: ''
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
services:
|
||||||
|
onlyoffice-mysql-server:
|
||||||
|
container_name: onlyoffice-mysql-server
|
||||||
|
image: mysql:8.0.29
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=my-secret-pw
|
||||||
|
networks:
|
||||||
|
- onlyoffice
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./config/mysql/conf.d:/etc/mysql/conf.d
|
||||||
|
- ./config/mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
|
||||||
|
- mysql_data:/var/lib/mysql
|
||||||
|
onlyoffice-community-server:
|
||||||
|
container_name: onlyoffice-community-server
|
||||||
|
image: onlyoffice/communityserver:12.6.0.1900
|
||||||
|
depends_on:
|
||||||
|
- onlyoffice-mysql-server
|
||||||
|
- onlyoffice-document-server
|
||||||
|
- onlyoffice-mail-server
|
||||||
|
- onlyoffice-elasticsearch
|
||||||
|
environment:
|
||||||
|
- ONLYOFFICE_CORE_MACHINEKEY=core_secret
|
||||||
|
- CONTROL_PANEL_PORT_80_TCP=80
|
||||||
|
- CONTROL_PANEL_PORT_80_TCP_ADDR=onlyoffice-control-panel
|
||||||
|
- DOCUMENT_SERVER_PORT_80_TCP_ADDR=onlyoffice-document-server
|
||||||
|
- DOCUMENT_SERVER_JWT_ENABLED=true
|
||||||
|
- DOCUMENT_SERVER_JWT_SECRET=jwt_secret
|
||||||
|
- DOCUMENT_SERVER_JWT_HEADER=AuthorizationJwt
|
||||||
|
- MYSQL_SERVER_ROOT_PASSWORD=my-secret-pw
|
||||||
|
- MYSQL_SERVER_DB_NAME=onlyoffice
|
||||||
|
- MYSQL_SERVER_HOST=onlyoffice-mysql-server
|
||||||
|
- MYSQL_SERVER_USER=onlyoffice_user
|
||||||
|
- MYSQL_SERVER_PASS=onlyoffice_pass
|
||||||
|
- MAIL_SERVER_API_PORT=8081
|
||||||
|
- MAIL_SERVER_API_HOST=onlyoffice-mail-server
|
||||||
|
- MAIL_SERVER_DB_HOST=onlyoffice-mysql-server
|
||||||
|
- MAIL_SERVER_DB_PORT=3306
|
||||||
|
- MAIL_SERVER_DB_NAME=onlyoffice_mailserver
|
||||||
|
- MAIL_SERVER_DB_USER=mail_admin
|
||||||
|
- MAIL_SERVER_DB_PASS=Isadmin123
|
||||||
|
- ELASTICSEARCH_SERVER_HOST=onlyoffice-elasticsearch
|
||||||
|
- ELASTICSEARCH_SERVER_HTTPPORT=9200
|
||||||
|
networks:
|
||||||
|
- onlyoffice
|
||||||
|
ports:
|
||||||
|
- '80:80'
|
||||||
|
- '443:443'
|
||||||
|
- '5222:5222'
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
restart: always
|
||||||
|
privileged: true
|
||||||
|
cgroup: host
|
||||||
|
volumes:
|
||||||
|
- community_data:/var/www/onlyoffice/Data
|
||||||
|
- community_log:/var/log/onlyoffice
|
||||||
|
- community_letsencrypt:/etc/letsencrypt
|
||||||
|
- document_data:/var/www/onlyoffice/DocumentServerData
|
||||||
|
- /sys/fs/cgroup:/sys/fs/cgroup:rw
|
||||||
|
- ./certs:/var/www/onlyoffice/Data/certs
|
||||||
|
onlyoffice-elasticsearch:
|
||||||
|
image: onlyoffice/elasticsearch:7.16.3
|
||||||
|
container_name: onlyoffice-elasticsearch
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- discovery.type=single-node
|
||||||
|
- bootstrap.memory_lock=true
|
||||||
|
- "ES_JAVA_OPTS=-Xms1g -Xmx1g -Dlog4j2.formatMsgNoLookups=true"
|
||||||
|
- "indices.fielddata.cache.size=30%"
|
||||||
|
- "indices.memory.index_buffer_size=30%"
|
||||||
|
- "ingest.geoip.downloader.enabled=false"
|
||||||
|
networks:
|
||||||
|
- onlyoffice
|
||||||
|
ulimits:
|
||||||
|
memlock:
|
||||||
|
soft: -1
|
||||||
|
hard: -1
|
||||||
|
nofile:
|
||||||
|
soft: 65535
|
||||||
|
hard: 65535
|
||||||
|
volumes:
|
||||||
|
- es_data:/usr/share/elasticsearch/data
|
||||||
|
expose:
|
||||||
|
- "9200"
|
||||||
|
- "9300"
|
||||||
|
onlyoffice-document-server:
|
||||||
|
container_name: onlyoffice-document-server
|
||||||
|
image: onlyoffice/documentserver:8.1
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- JWT_ENABLED=true
|
||||||
|
- JWT_SECRET=jwt_secret
|
||||||
|
- JWT_HEADER=AuthorizationJwt
|
||||||
|
networks:
|
||||||
|
- onlyoffice
|
||||||
|
expose:
|
||||||
|
- '80'
|
||||||
|
- '443'
|
||||||
|
volumes:
|
||||||
|
- document_data:/var/www/onlyoffice/Data
|
||||||
|
- document_log:/var/log/onlyoffice
|
||||||
|
- ./document_fonts:/usr/share/fonts/truetype/custom
|
||||||
|
- document_forgotten:/var/lib/onlyoffice/documentserver/App_Data/cache/files/forgotten
|
||||||
|
onlyoffice-mail-server:
|
||||||
|
container_name: onlyoffice-mail-server
|
||||||
|
image: onlyoffice/mailserver:1.6.75
|
||||||
|
depends_on:
|
||||||
|
- onlyoffice-mysql-server
|
||||||
|
hostname: ${MAIL_SERVER_HOSTNAME}
|
||||||
|
environment:
|
||||||
|
- MYSQL_SERVER=onlyoffice-mysql-server
|
||||||
|
- MYSQL_SERVER_PORT=3306
|
||||||
|
- MYSQL_ROOT_USER=mail_admin
|
||||||
|
- MYSQL_ROOT_PASSWD=Isadmin123
|
||||||
|
- MYSQL_SERVER_DB_NAME=onlyoffice_mailserver
|
||||||
|
networks:
|
||||||
|
- onlyoffice
|
||||||
|
restart: always
|
||||||
|
privileged: true
|
||||||
|
ports: ['25:25','143:143','587:587']
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
expose:
|
||||||
|
- '8081'
|
||||||
|
- '3306'
|
||||||
|
volumes:
|
||||||
|
- mail_data:/var/vmail
|
||||||
|
- mail_certs:/etc/pki/tls/mailserver
|
||||||
|
- mail_log:/var/log
|
||||||
|
onlyoffice-control-panel:
|
||||||
|
container_name: onlyoffice-control-panel
|
||||||
|
depends_on:
|
||||||
|
- onlyoffice-document-server
|
||||||
|
- onlyoffice-mail-server
|
||||||
|
- onlyoffice-community-server
|
||||||
|
image: onlyoffice/controlpanel:3.5.2.530
|
||||||
|
environment:
|
||||||
|
- ONLYOFFICE_CORE_MACHINEKEY=core_secret
|
||||||
|
expose:
|
||||||
|
- '80'
|
||||||
|
- '443'
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- controlpanel_data:/var/www/onlyoffice/Data
|
||||||
|
- controlpanel_log:/var/log/onlyoffice
|
||||||
|
networks:
|
||||||
|
- onlyoffice
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
networks:
|
||||||
|
onlyoffice:
|
||||||
|
driver: 'bridge'
|
||||||
|
volumes:
|
||||||
|
mail_data:
|
||||||
|
mail_certs:
|
||||||
|
mail_log:
|
||||||
|
mail_mysql:
|
||||||
|
document_data:
|
||||||
|
document_log:
|
||||||
|
document_forgotten:
|
||||||
|
community_mysql:
|
||||||
|
community_data:
|
||||||
|
community_log:
|
||||||
|
community_letsencrypt:
|
||||||
|
controlpanel_data:
|
||||||
|
controlpanel_log:
|
||||||
|
mysql_data:
|
||||||
|
es_data:
|
||||||
Executable
+25
@@ -0,0 +1,25 @@
|
|||||||
|
version: '2.0'
|
||||||
|
services:
|
||||||
|
chatgpt-on-wechat:
|
||||||
|
image: zhayujie/chatgpt-on-wechat
|
||||||
|
container_name: chatgpt-on-wechat
|
||||||
|
security_opt:
|
||||||
|
- seccomp:unconfined
|
||||||
|
environment:
|
||||||
|
OPEN_AI_API_KEY: 'sk-1A7f5vBSlhudYmxmyxxxxxxxx7i4KmuHy9ZxPO'
|
||||||
|
open_ai_api_base: 'https://api.chatanywhere.tech/v1'
|
||||||
|
MODEL: 'gpt-4o-mini'
|
||||||
|
PROXY: ''
|
||||||
|
SINGLE_CHAT_PREFIX: '["bot", "@bot"]'
|
||||||
|
SINGLE_CHAT_REPLY_PREFIX: '"[bot] "'
|
||||||
|
GROUP_CHAT_PREFIX: '["@bot"]'
|
||||||
|
GROUP_NAME_WHITE_LIST: '["ChatGPT测试群", "ChatGPT测试群2"]'
|
||||||
|
IMAGE_CREATE_PREFIX: '["画", "看", "找"]'
|
||||||
|
CONVERSATION_MAX_TOKENS: 1000
|
||||||
|
SPEECH_RECOGNITION: 'False'
|
||||||
|
CHARACTER_DESC: '你是基于大语言模型的AI智能助手,旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。'
|
||||||
|
EXPIRES_IN_SECONDS: 3600
|
||||||
|
USE_GLOBAL_PLUGIN_CONFIG: 'True'
|
||||||
|
USE_LINKAI: 'False'
|
||||||
|
LINKAI_API_KEY: ''
|
||||||
|
LINKAI_APP_CODE: ''
|
||||||
Executable
+56
@@ -0,0 +1,56 @@
|
|||||||
|
# 与服务端建立连接,跟上面的配置要对应 阿里106.15.121.26 腾讯150.158.120.215 联通云 116.162.100.119
|
||||||
|
serverAddr = "124.220.30.149"
|
||||||
|
serverPort = 7000
|
||||||
|
|
||||||
|
# 配置Token鉴权,要与服务端一致
|
||||||
|
auth.method = "token"
|
||||||
|
auth.token = "admin8466"
|
||||||
|
|
||||||
|
# 配置日志信息
|
||||||
|
#log.level = "warn"
|
||||||
|
#log.to = "/opt/frpc/frpc.log"
|
||||||
|
|
||||||
|
|
||||||
|
# frpc.toml
|
||||||
|
webServer.addr = "192.168.1.108"
|
||||||
|
webServer.port = 7400
|
||||||
|
webServer.user = "admin"
|
||||||
|
webServer.password = "admin8466"
|
||||||
|
|
||||||
|
[[proxies]]
|
||||||
|
name = "frp-fnOS-openlist-9161"
|
||||||
|
|
||||||
|
type = "tcp"
|
||||||
|
|
||||||
|
localIP = "127.0.0.1"
|
||||||
|
localPort = 7244
|
||||||
|
remotePort = 9161
|
||||||
|
|
||||||
|
[[proxies]]
|
||||||
|
name = "frp-dsm-lskypro"
|
||||||
|
|
||||||
|
type = "tcp"
|
||||||
|
|
||||||
|
localIP = "192.168.1.181"
|
||||||
|
localPort = 6089
|
||||||
|
remotePort = 6089
|
||||||
|
|
||||||
|
|
||||||
|
[[proxies]]
|
||||||
|
name = "frp-fnOS-cwa"
|
||||||
|
|
||||||
|
type = "tcp"
|
||||||
|
|
||||||
|
localIP = "127.0.0.1"
|
||||||
|
localPort = 7083
|
||||||
|
remotePort = 7083
|
||||||
|
|
||||||
|
|
||||||
|
[[proxies]]
|
||||||
|
name = "frp-fnOS-photo"
|
||||||
|
|
||||||
|
type = "tcp"
|
||||||
|
|
||||||
|
localIP = "127.0.0.1"
|
||||||
|
localPort = 2342
|
||||||
|
remotePort = 2342
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0
|
||||||
|
|
||||||
|
|
||||||
|
memos_pat_BwWQTJJhR1UoNBhkMkkfMQzthWaqXWVR
|
||||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 383 KiB |
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
+1209
File diff suppressed because it is too large
Load Diff
Executable
+43037
File diff suppressed because one or more lines are too long
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
+172
@@ -0,0 +1,172 @@
|
|||||||
|
mixed-port: 7890
|
||||||
|
allow-lan: true
|
||||||
|
bind-address: '*'
|
||||||
|
mode: rule
|
||||||
|
log-level: info
|
||||||
|
external-controller: '0.0.0.0:9090'
|
||||||
|
|
||||||
|
tun:
|
||||||
|
enable: true
|
||||||
|
stack: mixed
|
||||||
|
dns-hijack:
|
||||||
|
- "any:53"
|
||||||
|
- "tcp://any:53"
|
||||||
|
auto-route: true
|
||||||
|
auto-redirect: true
|
||||||
|
auto-detect-interface: true
|
||||||
|
|
||||||
|
proxy-providers:
|
||||||
|
OneMuggle:
|
||||||
|
url: "订阅链接"
|
||||||
|
type: http
|
||||||
|
interval: 86400
|
||||||
|
health-check: {enable: true,url: "https://www.gstatic.com/generate_204", interval: 300}
|
||||||
|
override:
|
||||||
|
additional-prefix: "Muggle"
|
||||||
|
|
||||||
|
proxies:
|
||||||
|
- name: "直连"
|
||||||
|
type: direct
|
||||||
|
udp: true
|
||||||
|
|
||||||
|
geodata-mode: true
|
||||||
|
geox-url:
|
||||||
|
geoip: "https://mirror.ghproxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat"
|
||||||
|
geosite: "https://mirror.ghproxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat"
|
||||||
|
mmdb: "https://mirror.ghproxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country-lite.mmdb"
|
||||||
|
asn: "https://mirror.ghproxy.com/https://github.com/xishang0128/geoip/releases/download/latest/GeoLite2-ASN.mmdb"
|
||||||
|
|
||||||
|
dns:
|
||||||
|
enable: true
|
||||||
|
ipv6: true
|
||||||
|
respect-rules: true
|
||||||
|
enhanced-mode: fake-ip
|
||||||
|
fake-ip-filter:
|
||||||
|
- "*"
|
||||||
|
- "+.lan"
|
||||||
|
- "+.local"
|
||||||
|
- "+.market.xiaomi.com"
|
||||||
|
nameserver:
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
proxy-server-nameserver:
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
nameserver-policy:
|
||||||
|
"geosite:cn,private":
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
"geosite:geolocation-!cn":
|
||||||
|
- "https://dns.cloudflare.com/dns-query"
|
||||||
|
- "https://dns.google/dns-query"
|
||||||
|
|
||||||
|
proxy-groups:
|
||||||
|
|
||||||
|
- name: 默认
|
||||||
|
type: select
|
||||||
|
proxies: [自动选择,直连,香港,台湾,日本,新加坡,美国,其它地区,全部节点]
|
||||||
|
|
||||||
|
- name: Google
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Telegram
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Twitter
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 哔哩哔哩
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 巴哈姆特
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: YouTube
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: NETFLIX
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Spotify
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Github
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 国内
|
||||||
|
type: select
|
||||||
|
proxies: [直连,默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择]
|
||||||
|
|
||||||
|
- name: 其他
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
#分隔,下面是地区分组
|
||||||
|
- name: 香港
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)港|hk|hongkong|hong kong"
|
||||||
|
|
||||||
|
- name: 台湾
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)台|tw|taiwan"
|
||||||
|
|
||||||
|
- name: 日本
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)日|jp|japan"
|
||||||
|
|
||||||
|
- name: 美国
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)美|us|unitedstates|united states"
|
||||||
|
|
||||||
|
- name: 新加坡
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)(新|sg|singapore)"
|
||||||
|
|
||||||
|
- name: 其它地区
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)^(?!.*(?:|||||港|hk|hongkong|台|tw|taiwan|日|jp|japan|新|sg|singapore|美|us|unitedstates)).*"
|
||||||
|
|
||||||
|
- name: 全部节点
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
|
||||||
|
- name: 自动选择
|
||||||
|
type: url-test
|
||||||
|
include-all: true
|
||||||
|
tolerance: 10
|
||||||
|
|
||||||
|
rules:
|
||||||
|
- GEOIP,lan,直连,no-resolve
|
||||||
|
- GEOSITE,github,Github
|
||||||
|
- GEOSITE,twitter,Twitter
|
||||||
|
- GEOSITE,youtube,YouTube
|
||||||
|
- GEOSITE,google,Google
|
||||||
|
- GEOSITE,telegram,Telegram
|
||||||
|
- GEOSITE,netflix,NETFLIX
|
||||||
|
- GEOSITE,bilibili,哔哩哔哩
|
||||||
|
- GEOSITE,bahamut,巴哈姆特
|
||||||
|
- GEOSITE,spotify,Spotify
|
||||||
|
- GEOSITE,CN,国内
|
||||||
|
- GEOSITE,geolocation-!cn,其他
|
||||||
|
|
||||||
|
- GEOIP,google,Google
|
||||||
|
- GEOIP,netflix,NETFLIX
|
||||||
|
- GEOIP,telegram,Telegram
|
||||||
|
- GEOIP,twitter,Twitter
|
||||||
|
- GEOIP,CN,国内
|
||||||
|
- MATCH,其他
|
||||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
+45132
File diff suppressed because one or more lines are too long
Executable
+211
@@ -0,0 +1,211 @@
|
|||||||
|
mixed-port: 7890
|
||||||
|
allow-lan: true
|
||||||
|
bind-address: '*'
|
||||||
|
mode: rule
|
||||||
|
log-level: info
|
||||||
|
external-controller: '0.0.0.0:9090'
|
||||||
|
|
||||||
|
tun:
|
||||||
|
enable: true
|
||||||
|
stack: mixed
|
||||||
|
dns-hijack:
|
||||||
|
- "any:53"
|
||||||
|
- "tcp://any:53"
|
||||||
|
auto-route: true
|
||||||
|
auto-redirect: true
|
||||||
|
auto-detect-interface: true
|
||||||
|
|
||||||
|
proxy-providers:
|
||||||
|
狗狗加速:
|
||||||
|
url: "https://xwj6tm.doggygosubs.com:8443/api/v1/client/5a471ca14910318c9491470a62a712ea?flag=mihomo"
|
||||||
|
type: http
|
||||||
|
interval: 86400
|
||||||
|
health-check: {enable: true,url: "https://www.gstatic.com/generate_204", interval: 300}
|
||||||
|
override:
|
||||||
|
additional-prefix: "IPLC"
|
||||||
|
|
||||||
|
proxies:
|
||||||
|
- name: "直连"
|
||||||
|
type: direct
|
||||||
|
udp: true
|
||||||
|
|
||||||
|
geodata-mode: true
|
||||||
|
geox-url:
|
||||||
|
geoip: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat"
|
||||||
|
geosite: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat"
|
||||||
|
mmdb: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country-lite.mmdb"
|
||||||
|
asn: "https://gh-proxy.com/https://github.com/xishang0128/geoip/releases/download/latest/GeoLite2-ASN.mmdb"
|
||||||
|
|
||||||
|
dns:
|
||||||
|
enable: true
|
||||||
|
ipv6: true
|
||||||
|
respect-rules: true
|
||||||
|
enhanced-mode: fake-ip
|
||||||
|
fake-ip-filter:
|
||||||
|
- "*"
|
||||||
|
- "+.lan"
|
||||||
|
- "+.local"
|
||||||
|
- "+.market.xiaomi.com"
|
||||||
|
nameserver:
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
proxy-server-nameserver:
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
nameserver-policy:
|
||||||
|
"geosite:cn,private":
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
"geosite:geolocation-!cn":
|
||||||
|
- "https://dns.cloudflare.com/dns-query"
|
||||||
|
- "https://dns.google/dns-query"
|
||||||
|
|
||||||
|
proxy-groups:
|
||||||
|
|
||||||
|
- name: 默认
|
||||||
|
type: select
|
||||||
|
proxies: [自动选择,直连,香港,台湾,日本,新加坡,美国,其它地区,全部节点]
|
||||||
|
|
||||||
|
- name: Google
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Telegram
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Twitter
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 哔哩哔哩
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 巴哈姆特
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: YouTube
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: NETFLIX
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Spotify
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Github
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 国内
|
||||||
|
type: select
|
||||||
|
proxies: [直连,默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择]
|
||||||
|
|
||||||
|
- name: 其他
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
#分隔,下面是地区分组
|
||||||
|
- name: 香港
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)港|hk|hongkong|hong kong"
|
||||||
|
|
||||||
|
- name: 台湾
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)台|tw|taiwan"
|
||||||
|
|
||||||
|
- name: 日本
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)日|jp|japan"
|
||||||
|
|
||||||
|
- name: 美国
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)美|us|unitedstates|united states"
|
||||||
|
|
||||||
|
- name: 新加坡
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)(新|sg|singapore)"
|
||||||
|
|
||||||
|
- name: 其它地区
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)^(?!.*(?:|||||港|hk|hongkong|台|tw|taiwan|日|jp|japan|新|sg|singapore|美|us|unitedstates)).*"
|
||||||
|
|
||||||
|
- name: 全部节点
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
|
||||||
|
- name: 自动选择
|
||||||
|
type: url-test
|
||||||
|
include-all: true
|
||||||
|
tolerance: 10
|
||||||
|
|
||||||
|
rules:
|
||||||
|
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,synology.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,digitalocean.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,synocommunity.com,DIRECT'
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,emby.xiaoya.pro,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,icyou.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,lanyuewan.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.8.net.co,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.raydoom.tk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.kaiserver.uk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,embyxiaoya.laogl.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.poxi1221.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ermaokj.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.bdbd.fun,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wwwh.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.f1rst.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ymschh.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wx1.us.kg,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.r2s.site,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.neversay.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.800686.xyz,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,syncthing.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,3322.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,picp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,wicp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xicp.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,againgo.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.vip,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.cloud,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xuanyuan.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,1ms.run,DIRECT'
|
||||||
|
|
||||||
|
- GEOIP,lan,直连,no-resolve
|
||||||
|
- GEOSITE,github,Github
|
||||||
|
- GEOSITE,twitter,Twitter
|
||||||
|
- GEOSITE,youtube,YouTube
|
||||||
|
- GEOSITE,google,Google
|
||||||
|
- GEOSITE,telegram,Telegram
|
||||||
|
- GEOSITE,netflix,NETFLIX
|
||||||
|
- GEOSITE,bilibili,哔哩哔哩
|
||||||
|
- GEOSITE,bahamut,巴哈姆特
|
||||||
|
- GEOSITE,spotify,Spotify
|
||||||
|
- GEOSITE,CN,国内
|
||||||
|
- GEOSITE,geolocation-!cn,其他
|
||||||
|
|
||||||
|
- GEOIP,google,Google
|
||||||
|
- GEOIP,netflix,NETFLIX
|
||||||
|
- GEOIP,telegram,Telegram
|
||||||
|
- GEOIP,twitter,Twitter
|
||||||
|
- GEOIP,CN,国内
|
||||||
|
- MATCH,其他
|
||||||
Executable
+421
@@ -0,0 +1,421 @@
|
|||||||
|
mixed-port: 7890
|
||||||
|
allow-lan: true
|
||||||
|
bind-address: '*'
|
||||||
|
mode: rule
|
||||||
|
log-level: info
|
||||||
|
external-controller: '0.0.0.0:9090'
|
||||||
|
|
||||||
|
tun:
|
||||||
|
enable: true
|
||||||
|
stack: mixed
|
||||||
|
dns-hijack:
|
||||||
|
- "any:53"
|
||||||
|
- "tcp://any:53"
|
||||||
|
auto-route: true
|
||||||
|
auto-redirect: true
|
||||||
|
auto-detect-interface: true
|
||||||
|
|
||||||
|
proxy-providers:
|
||||||
|
gg:
|
||||||
|
url: "https://xwj6tm.doggygosubs.com:8443/api/v1/client/5a471ca14910318c9491470a62a712ea?flag=mihomo"
|
||||||
|
type: http
|
||||||
|
interval: 86400
|
||||||
|
health-check: {enable: true,url: "https://www.gstatic.com/generate_204", interval: 300}
|
||||||
|
override:
|
||||||
|
additional-prefix: "gg"
|
||||||
|
|
||||||
|
proxies:
|
||||||
|
- name: "直连"
|
||||||
|
type: direct
|
||||||
|
udp: truemixed-port: 7890
|
||||||
|
allow-lan: true
|
||||||
|
bind-address: '*'
|
||||||
|
mode: rule
|
||||||
|
log-level: info
|
||||||
|
external-controller: '0.0.0.0:9090'
|
||||||
|
|
||||||
|
tun:
|
||||||
|
enable: true
|
||||||
|
stack: mixed
|
||||||
|
dns-hijack:
|
||||||
|
- "any:53"
|
||||||
|
- "tcp://any:53"
|
||||||
|
auto-route: true
|
||||||
|
auto-redirect: true
|
||||||
|
auto-detect-interface: true
|
||||||
|
|
||||||
|
proxy-providers:
|
||||||
|
IPLC:
|
||||||
|
url: "https://sub.20250715iplcsub.link/qC8zV8qS1kB1lX2u/4OLCCKkHWHgeCM6m?clash=1"
|
||||||
|
type: http
|
||||||
|
interval: 86400
|
||||||
|
health-check: {enable: true,url: "https://www.gstatic.com/generate_204", interval: 300}
|
||||||
|
override:
|
||||||
|
additional-prefix: "IPLC"
|
||||||
|
|
||||||
|
proxies:
|
||||||
|
- name: "直连"
|
||||||
|
type: direct
|
||||||
|
udp: true
|
||||||
|
|
||||||
|
geodata-mode: true
|
||||||
|
geox-url:
|
||||||
|
geoip: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat"
|
||||||
|
geosite: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat"
|
||||||
|
mmdb: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country-lite.mmdb"
|
||||||
|
asn: "https://gh-proxy.com/https://github.com/xishang0128/geoip/releases/download/latest/GeoLite2-ASN.mmdb"
|
||||||
|
|
||||||
|
dns:
|
||||||
|
enable: true
|
||||||
|
ipv6: true
|
||||||
|
respect-rules: true
|
||||||
|
enhanced-mode: fake-ip
|
||||||
|
fake-ip-filter:
|
||||||
|
- "*"
|
||||||
|
- "+.lan"
|
||||||
|
- "+.local"
|
||||||
|
- "+.market.xiaomi.com"
|
||||||
|
nameserver:
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
proxy-server-nameserver:
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
nameserver-policy:
|
||||||
|
"geosite:cn,private":
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
"geosite:geolocation-!cn":
|
||||||
|
- "https://dns.cloudflare.com/dns-query"
|
||||||
|
- "https://dns.google/dns-query"
|
||||||
|
|
||||||
|
proxy-groups:
|
||||||
|
|
||||||
|
- name: 默认
|
||||||
|
type: select
|
||||||
|
proxies: [自动选择,直连,香港,台湾,日本,新加坡,美国,其它地区,全部节点]
|
||||||
|
|
||||||
|
- name: Google
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Telegram
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Twitter
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 哔哩哔哩
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 巴哈姆特
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: YouTube
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: NETFLIX
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Spotify
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Github
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 国内
|
||||||
|
type: select
|
||||||
|
proxies: [直连,默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择]
|
||||||
|
|
||||||
|
- name: 其他
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
#分隔,下面是地区分组
|
||||||
|
- name: 香港
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)港|hk|hongkong|hong kong"
|
||||||
|
|
||||||
|
- name: 台湾
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)台|tw|taiwan"
|
||||||
|
|
||||||
|
- name: 日本
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)日|jp|japan"
|
||||||
|
|
||||||
|
- name: 美国
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)美|us|unitedstates|united states"
|
||||||
|
|
||||||
|
- name: 新加坡
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)(新|sg|singapore)"
|
||||||
|
|
||||||
|
- name: 其它地区
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)^(?!.*(?:|||||港|hk|hongkong|台|tw|taiwan|日|jp|japan|新|sg|singapore|美|us|unitedstates)).*"
|
||||||
|
|
||||||
|
- name: 全部节点
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
|
||||||
|
- name: 自动选择
|
||||||
|
type: url-test
|
||||||
|
include-all: true
|
||||||
|
tolerance: 10
|
||||||
|
|
||||||
|
rules:
|
||||||
|
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,synology.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,digitalocean.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,synocommunity.com,DIRECT'
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,emby.xiaoya.pro,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,icyou.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,lanyuewan.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.8.net.co,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.raydoom.tk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.kaiserver.uk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,embyxiaoya.laogl.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.poxi1221.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ermaokj.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.bdbd.fun,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wwwh.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.f1rst.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ymschh.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wx1.us.kg,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.r2s.site,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.neversay.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.800686.xyz,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,syncthing.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,3322.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,picp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,wicp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xicp.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,againgo.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.vip,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.cloud,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xuanyuan.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,1ms.run,DIRECT'
|
||||||
|
|
||||||
|
- GEOIP,lan,直连,no-resolve
|
||||||
|
- GEOSITE,github,Github
|
||||||
|
- GEOSITE,twitter,Twitter
|
||||||
|
- GEOSITE,youtube,YouTube
|
||||||
|
- GEOSITE,google,Google
|
||||||
|
- GEOSITE,telegram,Telegram
|
||||||
|
- GEOSITE,netflix,NETFLIX
|
||||||
|
- GEOSITE,bilibili,哔哩哔哩
|
||||||
|
- GEOSITE,bahamut,巴哈姆特
|
||||||
|
- GEOSITE,spotify,Spotify
|
||||||
|
- GEOSITE,CN,国内
|
||||||
|
- GEOSITE,geolocation-!cn,其他
|
||||||
|
|
||||||
|
- GEOIP,google,Google
|
||||||
|
- GEOIP,netflix,NETFLIX
|
||||||
|
- GEOIP,telegram,Telegram
|
||||||
|
- GEOIP,twitter,Twitter
|
||||||
|
- GEOIP,CN,国内
|
||||||
|
- MATCH,其他
|
||||||
|
|
||||||
|
geodata-mode: true
|
||||||
|
geox-url:
|
||||||
|
geoip: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat"
|
||||||
|
geosite: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat"
|
||||||
|
mmdb: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country-lite.mmdb"
|
||||||
|
asn: "https://gh-proxy.com/https://github.com/xishang0128/geoip/releases/download/latest/GeoLite2-ASN.mmdb"
|
||||||
|
|
||||||
|
dns:
|
||||||
|
enable: true
|
||||||
|
ipv6: true
|
||||||
|
respect-rules: true
|
||||||
|
enhanced-mode: fake-ip
|
||||||
|
fake-ip-filter:
|
||||||
|
- "*"
|
||||||
|
- "+.lan"
|
||||||
|
- "+.local"
|
||||||
|
- "+.market.xiaomi.com"
|
||||||
|
nameserver:
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
proxy-server-nameserver:
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
nameserver-policy:
|
||||||
|
"geosite:cn,private":
|
||||||
|
- https://120.53.53.53/dns-query
|
||||||
|
- https://223.5.5.5/dns-query
|
||||||
|
"geosite:geolocation-!cn":
|
||||||
|
- "https://dns.cloudflare.com/dns-query"
|
||||||
|
- "https://dns.google/dns-query"
|
||||||
|
|
||||||
|
proxy-groups:
|
||||||
|
|
||||||
|
- name: 默认
|
||||||
|
type: select
|
||||||
|
proxies: [自动选择,直连,香港,台湾,日本,新加坡,美国,其它地区,全部节点]
|
||||||
|
|
||||||
|
- name: Google
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Telegram
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Twitter
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 哔哩哔哩
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 巴哈姆特
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: YouTube
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: NETFLIX
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Spotify
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Github
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 国内
|
||||||
|
type: select
|
||||||
|
proxies: [直连,默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择]
|
||||||
|
|
||||||
|
- name: 其他
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
#分隔,下面是地区分组
|
||||||
|
- name: 香港
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)港|hk|hongkong|hong kong"
|
||||||
|
|
||||||
|
- name: 台湾
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)台|tw|taiwan"
|
||||||
|
|
||||||
|
- name: 日本
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)日|jp|japan"
|
||||||
|
|
||||||
|
- name: 美国
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)美|us|unitedstates|united states"
|
||||||
|
|
||||||
|
- name: 新加坡
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)(新|sg|singapore)"
|
||||||
|
|
||||||
|
- name: 其它地区
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
filter: "(?i)^(?!.*(?:|||||港|hk|hongkong|台|tw|taiwan|日|jp|japan|新|sg|singapore|美|us|unitedstates)).*"
|
||||||
|
|
||||||
|
- name: 全部节点
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
|
||||||
|
- name: 自动选择
|
||||||
|
type: url-test
|
||||||
|
include-all: true
|
||||||
|
tolerance: 10
|
||||||
|
|
||||||
|
rules:
|
||||||
|
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,synology.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,digitalocean.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,synocommunity.com,DIRECT'
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,emby.xiaoya.pro,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,icyou.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,lanyuewan.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.8.net.co,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.raydoom.tk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.kaiserver.uk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,embyxiaoya.laogl.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.poxi1221.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ermaokj.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.bdbd.fun,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wwwh.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.f1rst.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ymschh.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wx1.us.kg,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.r2s.site,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.neversay.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.800686.xyz,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,syncthing.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,3322.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,picp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,wicp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xicp.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,againgo.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.vip,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.cloud,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xuanyuan.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,1ms.run,DIRECT'
|
||||||
|
|
||||||
|
- GEOIP,lan,直连,no-resolve
|
||||||
|
- GEOSITE,github,Github
|
||||||
|
- GEOSITE,twitter,Twitter
|
||||||
|
- GEOSITE,youtube,YouTube
|
||||||
|
- GEOSITE,google,Google
|
||||||
|
- GEOSITE,telegram,Telegram
|
||||||
|
- GEOSITE,netflix,NETFLIX
|
||||||
|
- GEOSITE,bilibili,哔哩哔哩
|
||||||
|
- GEOSITE,bahamut,巴哈姆特
|
||||||
|
- GEOSITE,spotify,Spotify
|
||||||
|
- GEOSITE,CN,国内
|
||||||
|
- GEOSITE,geolocation-!cn,其他
|
||||||
|
|
||||||
|
- GEOIP,google,Google
|
||||||
|
- GEOIP,netflix,NETFLIX
|
||||||
|
- GEOIP,telegram,Telegram
|
||||||
|
- GEOIP,twitter,Twitter
|
||||||
|
- GEOIP,CN,国内
|
||||||
|
- MATCH,其他
|
||||||
Executable
+244
@@ -0,0 +1,244 @@
|
|||||||
|
# url 里填写自己的订阅,名称不能重复
|
||||||
|
proxy-providers:
|
||||||
|
provider1:
|
||||||
|
url: ""
|
||||||
|
type: http
|
||||||
|
interval: 86400
|
||||||
|
health-check: {enable: true,url: "https://www.gstatic.com/generate_204", interval: 300}
|
||||||
|
override:
|
||||||
|
additional-prefix: "[provider1]"
|
||||||
|
|
||||||
|
provider2:
|
||||||
|
url: ""
|
||||||
|
type: http
|
||||||
|
interval: 86400
|
||||||
|
health-check: {enable: true,url: "https://www.gstatic.com/generate_204",interval: 300}
|
||||||
|
override:
|
||||||
|
additional-prefix: "[provider2]"
|
||||||
|
|
||||||
|
proxies:
|
||||||
|
- name: "直连"
|
||||||
|
type: direct
|
||||||
|
udp: true
|
||||||
|
|
||||||
|
mixed-port: 7890
|
||||||
|
ipv6: true
|
||||||
|
allow-lan: true
|
||||||
|
unified-delay: false
|
||||||
|
tcp-concurrent: true
|
||||||
|
external-controller: 0.0.0.0:9090
|
||||||
|
external-ui: ui
|
||||||
|
external-ui-url: "https://github.com/MetaCubeX/metacubexd/archive/refs/heads/gh-pages.zip"
|
||||||
|
|
||||||
|
geodata-mode: true
|
||||||
|
geox-url:
|
||||||
|
|
||||||
|
geoip: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat"
|
||||||
|
geosite: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat"
|
||||||
|
mmdb: "https://gh-proxy.com/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country-lite.mmdb"
|
||||||
|
asn: "https://gh-proxy.com/https://github.com/xishang0128/geoip/releases/download/latest/GeoLite2-ASN.mmdb"
|
||||||
|
|
||||||
|
find-process-mode: strict
|
||||||
|
global-client-fingerprint: chrome
|
||||||
|
|
||||||
|
profile:
|
||||||
|
store-selected: true
|
||||||
|
store-fake-ip: true
|
||||||
|
|
||||||
|
sniffer:
|
||||||
|
enable: true
|
||||||
|
sniff:
|
||||||
|
HTTP:
|
||||||
|
ports: [80, 8080-8880]
|
||||||
|
override-destination: true
|
||||||
|
TLS:
|
||||||
|
ports: [443, 8443]
|
||||||
|
QUIC:
|
||||||
|
ports: [443, 8443]
|
||||||
|
skip-domain:
|
||||||
|
- "Mijia Cloud"
|
||||||
|
- "+.push.apple.com"
|
||||||
|
|
||||||
|
tun:
|
||||||
|
enable: true
|
||||||
|
stack: mixed
|
||||||
|
dns-hijack:
|
||||||
|
- "any:53"
|
||||||
|
- "tcp://any:53"
|
||||||
|
auto-route: true
|
||||||
|
auto-redirect: true
|
||||||
|
auto-detect-interface: true
|
||||||
|
|
||||||
|
dns:
|
||||||
|
enable: true
|
||||||
|
ipv6: true
|
||||||
|
enhanced-mode: fake-ip
|
||||||
|
fake-ip-filter:
|
||||||
|
- "*"
|
||||||
|
- "+.lan"
|
||||||
|
- "+.local"
|
||||||
|
- "+.market.xiaomi.com"
|
||||||
|
default-nameserver:
|
||||||
|
- tls://223.5.5.5
|
||||||
|
- tls://223.6.6.6
|
||||||
|
nameserver:
|
||||||
|
- https://doh.pub/dns-query
|
||||||
|
- https://dns.alidns.com/dns-query
|
||||||
|
|
||||||
|
proxy-groups:
|
||||||
|
|
||||||
|
- name: 默认
|
||||||
|
type: select
|
||||||
|
proxies: [自动选择,直连,香港,台湾,日本,新加坡,美国,其它地区,全部节点]
|
||||||
|
|
||||||
|
- name: Google
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Telegram
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Twitter
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 哔哩哔哩
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 巴哈姆特
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: YouTube
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: NETFLIX
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Spotify
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: Github
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
- name: 国内
|
||||||
|
type: select
|
||||||
|
proxies: [直连,默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择]
|
||||||
|
|
||||||
|
- name: 其他
|
||||||
|
type: select
|
||||||
|
proxies: [默认,香港,台湾,日本,新加坡,美国,其它地区,全部节点,自动选择,直连]
|
||||||
|
|
||||||
|
#分隔,下面是地区分组
|
||||||
|
- name: 香港
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
exclude-type: direct
|
||||||
|
filter: "(?i)港|hk|hongkong|hong kong"
|
||||||
|
|
||||||
|
- name: 台湾
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
exclude-type: direct
|
||||||
|
filter: "(?i)台|tw|taiwan"
|
||||||
|
|
||||||
|
- name: 日本
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
exclude-type: direct
|
||||||
|
filter: "(?i)日|jp|japan"
|
||||||
|
|
||||||
|
- name: 美国
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
exclude-type: direct
|
||||||
|
filter: "(?i)美|us|unitedstates|united states"
|
||||||
|
|
||||||
|
- name: 新加坡
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
exclude-type: direct
|
||||||
|
filter: "(?i)(新|sg|singapore)"
|
||||||
|
|
||||||
|
- name: 其它地区
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
exclude-type: direct
|
||||||
|
filter: "(?i)^(?!.*(?:|||||港|hk|hongkong|台|tw|taiwan|日|jp|japan|新|sg|singapore|美|us|unitedstates)).*"
|
||||||
|
|
||||||
|
- name: 全部节点
|
||||||
|
type: select
|
||||||
|
include-all: true
|
||||||
|
exclude-type: direct
|
||||||
|
|
||||||
|
- name: 自动选择
|
||||||
|
type: url-test
|
||||||
|
include-all: true
|
||||||
|
exclude-type: direct
|
||||||
|
tolerance: 10
|
||||||
|
|
||||||
|
rules:
|
||||||
|
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,synology.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,digitalocean.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,synocommunity.com,DIRECT'
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,emby.xiaoya.pro,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,icyou.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,lanyuewan.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.8.net.co,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.raydoom.tk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.kaiserver.uk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,embyxiaoya.laogl.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.poxi1221.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ermaokj.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.bdbd.fun,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wwwh.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.f1rst.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ymschh.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wx1.us.kg,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.r2s.site,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.neversay.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.800686.xyz,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,syncthing.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,3322.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,picp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,wicp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xicp.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,againgo.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.vip,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.cloud,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xuanyuan.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,1ms.run,DIRECT'
|
||||||
|
|
||||||
|
- GEOIP,lan,直连,no-resolve
|
||||||
|
- GEOSITE,github,Github
|
||||||
|
- GEOSITE,twitter,Twitter
|
||||||
|
- GEOSITE,youtube,YouTube
|
||||||
|
- GEOSITE,google,Google
|
||||||
|
- GEOSITE,telegram,Telegram
|
||||||
|
- GEOSITE,netflix,NETFLIX
|
||||||
|
- GEOSITE,bilibili,哔哩哔哩
|
||||||
|
- GEOSITE,bahamut,巴哈姆特
|
||||||
|
- GEOSITE,spotify,Spotify
|
||||||
|
- GEOSITE,CN,国内
|
||||||
|
- GEOSITE,geolocation-!cn,其他
|
||||||
|
|
||||||
|
- GEOIP,google,Google
|
||||||
|
- GEOIP,netflix,NETFLIX
|
||||||
|
- GEOIP,telegram,Telegram
|
||||||
|
- GEOIP,twitter,Twitter
|
||||||
|
- GEOIP,CN,国内
|
||||||
|
- MATCH,其他
|
||||||
Executable
+131
@@ -0,0 +1,131 @@
|
|||||||
|
mixed-port: 7890
|
||||||
|
allow-lan: true
|
||||||
|
bind-address: "*"
|
||||||
|
mode: rule
|
||||||
|
log-level: info
|
||||||
|
|
||||||
|
external-controller: 0.0.0.0:9090
|
||||||
|
secret: "123456" # 可选,用于设置访问密码
|
||||||
|
|
||||||
|
tun:
|
||||||
|
enable: true
|
||||||
|
stack: mixed
|
||||||
|
auto-route: true
|
||||||
|
auto-detect-interface: true
|
||||||
|
dns-hijack:
|
||||||
|
- any:53
|
||||||
|
- tcp://any:53
|
||||||
|
|
||||||
|
dns:
|
||||||
|
enable: true
|
||||||
|
ipv6: false
|
||||||
|
enhanced-mode: fake-ip
|
||||||
|
fake-ip-range: 198.18.0.1/16
|
||||||
|
nameserver:
|
||||||
|
- 114.114.114.114
|
||||||
|
- 223.5.5.5
|
||||||
|
fallback:
|
||||||
|
- tls://8.8.8.8:853
|
||||||
|
- tls://1.1.1.1:853
|
||||||
|
|
||||||
|
proxy-providers:
|
||||||
|
狗狗加速: # 随便起名,建议有意义
|
||||||
|
type: http
|
||||||
|
url: "https://CSWyZi.doggygo.top:8443/api/v1/client/5a471ca14910318c9491470a62a712ea" # 替换成你的第1个链接
|
||||||
|
path: ./gg.yaml
|
||||||
|
interval: 86400 # 每天更新一次
|
||||||
|
health-check:
|
||||||
|
enable: true
|
||||||
|
url: "https://www.gstatic.com/generate_204"
|
||||||
|
interval: 300
|
||||||
|
|
||||||
|
IPLC:
|
||||||
|
type: http
|
||||||
|
url: "https://sub.20250715iplcsub.link/qC8zV8qS1kB1lX2u/4OLCCKkHWHgeCM6m?clash=1" # 第2个
|
||||||
|
path: ./iplc.yaml
|
||||||
|
interval: 86400
|
||||||
|
health-check:
|
||||||
|
enable: true
|
||||||
|
url: "https://www.gstatic.com/generate_204"
|
||||||
|
interval: 300
|
||||||
|
|
||||||
|
proxy-groups:
|
||||||
|
# 主出口组:你可以在这里手动选机场,或用自动策略
|
||||||
|
- name: "主出口"
|
||||||
|
type: select # 手动选择模式(最常用)
|
||||||
|
proxies:
|
||||||
|
- "gg-自动"
|
||||||
|
- "iplc-自动"
|
||||||
|
- DIRECT
|
||||||
|
- REJECT
|
||||||
|
|
||||||
|
# 每个机场单独做 url-test(延迟最低自动选节点)
|
||||||
|
- name: "gg-自动"
|
||||||
|
type: url-test
|
||||||
|
use:
|
||||||
|
- 狗狗加速 # 只用这个 provider 的节点
|
||||||
|
url: "http://www.gstatic.com/generate_204"
|
||||||
|
interval: 300
|
||||||
|
tolerance: 50 # 延迟波动容忍(可选)
|
||||||
|
|
||||||
|
- name: "iplc-自动"
|
||||||
|
type: url-test
|
||||||
|
use:
|
||||||
|
- IPLC
|
||||||
|
url: "http://www.gstatic.com/generate_204"
|
||||||
|
interval: 300
|
||||||
|
|
||||||
|
# 可选:全部节点合并 + 自动选延迟最低的(适合追求极致速度)
|
||||||
|
- name: "全部-最低延迟"
|
||||||
|
type: url-test
|
||||||
|
use:
|
||||||
|
- 狗狗加速
|
||||||
|
- IPLC
|
||||||
|
url: "http://www.gstatic.com/generate_204"
|
||||||
|
interval: 300
|
||||||
|
tolerance: 100
|
||||||
|
|
||||||
|
rules:
|
||||||
|
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,synology.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,digitalocean.com,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,synocommunity.com,DIRECT'
|
||||||
|
|
||||||
|
- 'DOMAIN-SUFFIX,emby.xiaoya.pro,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,icyou.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,lanyuewan.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.8.net.co,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.raydoom.tk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby.kaiserver.uk,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,embyxiaoya.laogl.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.poxi1221.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ermaokj.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.bdbd.fun,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wwwh.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.f1rst.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.ymschh.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.wx1.us.kg,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.r2s.site,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.neversay.eu.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,emby-data.800686.xyz,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,syncthing.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,3322.org,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,picp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,wicp.net,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xicp.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,cpolar.cn,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,againgo.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.vip,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.cloud,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,himan.top,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,joyagain.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,xuanyuan.me,DIRECT'
|
||||||
|
- 'DOMAIN-SUFFIX,1ms.run,DIRECT'
|
||||||
|
|
||||||
|
|
||||||
|
- GEOIP,LAN,DIRECT
|
||||||
|
- GEOIP,CN,DIRECT
|
||||||
|
- MATCH,主出口 # 改成你的主出口组名
|
||||||
Executable
BIN
Binary file not shown.
+35
@@ -0,0 +1,35 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
mihomo:
|
||||||
|
container_name: mihomo-core
|
||||||
|
# image: metacubex/mihomo:latest # :Alpha :v1.19.x
|
||||||
|
#
|
||||||
|
image: docker.1ms.run/metacubex/mihomo:latest
|
||||||
|
restart: always
|
||||||
|
network_mode: host
|
||||||
|
pid: host
|
||||||
|
ipc: host
|
||||||
|
cap_add:
|
||||||
|
- ALL # NET_ADMIN - ALL
|
||||||
|
security_opt:
|
||||||
|
- apparmor=unconfined #
|
||||||
|
volumes:
|
||||||
|
- ./data:/root/.config/mihomo #
|
||||||
|
- /dev/net/tun:/dev/net/tun # TUN
|
||||||
|
- /etc/localtime:/etc/localtime:ro #
|
||||||
|
depends_on:
|
||||||
|
- metacubexd
|
||||||
|
|
||||||
|
metacubexd: # (XD)
|
||||||
|
container_name: mihomo-web
|
||||||
|
# image: ghcr.io/metacubex/metacubexd:latest
|
||||||
|
#
|
||||||
|
image: ghcr.1ms.run/metacubex/metacubexd:latest
|
||||||
|
restart: always
|
||||||
|
network_mode: bridge # host
|
||||||
|
ports:
|
||||||
|
- "9097:80" # 9091
|
||||||
|
volumes:
|
||||||
|
- ./config:/config/caddy #
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
+45132
File diff suppressed because one or more lines are too long
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Executable
+7
@@ -0,0 +1,7 @@
|
|||||||
|
[JoyCloud]
|
||||||
|
type = webdav
|
||||||
|
url = http://192.168.1.181:6244/dav
|
||||||
|
vendor = other
|
||||||
|
user = alAdmin
|
||||||
|
pass = a-srLYRoZi6Nvr_JmSzmVFDf7iP7_q4W
|
||||||
|
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "织梦",
|
||||||
|
"domain": "zmpt.cc",
|
||||||
|
"url": "https://zmpt.cc/",
|
||||||
|
"rss": "https://zmpt.cc/torrentrss.php?passkey=a5b24e65a4359e2120dfbcde82e70fa6&rows=50&ismalldescr=1&linktype=dl",
|
||||||
|
"downloader": null,
|
||||||
|
"cookie": "c_secure_pass=eyJ1c2VyX2lkIjoiMTg0NTkiLCJleHBpcmVzIjoxNzkxMzQ3MzIxfS5mOTUwYTc5OGI1MTY3MGU1M2IwMTcwZTM3MGZkZDMyYjUxM2MzZGZhZjEwMWIzMTI4ZGQ2ZjllNjBiNzg4ZWUy",
|
||||||
|
"apikey": null,
|
||||||
|
"token": null,
|
||||||
|
"ua": null,
|
||||||
|
"proxy": 0,
|
||||||
|
"filter": null,
|
||||||
|
"render": null,
|
||||||
|
"public": 0,
|
||||||
|
"note": null,
|
||||||
|
"timeout": 15,
|
||||||
|
"limit_interval": 0,
|
||||||
|
"limit_count": 0,
|
||||||
|
"limit_seconds": 0,
|
||||||
|
"is_active": true,
|
||||||
|
"pri": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "铂金家",
|
||||||
|
"domain": "pthome.net",
|
||||||
|
"url": "https://pthome.net/",
|
||||||
|
"rss": "https://pthome.net/torrentrss.php?rows=50&exp=180&ismalldescr=1&linktype=dl&passkey=b867c4dbx1739045435x137159x180x15a0e9fe03fb7b04ef8b5ea20d675bcd",
|
||||||
|
"downloader": null,
|
||||||
|
"cookie": "c_secure_uid=MTM3MTU5;c_secure_pass=96b77cf06e40ec17f880a3d3343255dd;c_secure_ssl=eWVhaA%3D%3D;c_secure_tracker_ssl=eWVhaA%3D%3D;c_secure_login=bm9wZQ%3D%3D;Hm_lvt_41bc5487f653d238d282d7de5990fd73=1745069331",
|
||||||
|
"apikey": null,
|
||||||
|
"token": null,
|
||||||
|
"ua": null,
|
||||||
|
"proxy": 0,
|
||||||
|
"filter": null,
|
||||||
|
"render": null,
|
||||||
|
"public": 0,
|
||||||
|
"note": null,
|
||||||
|
"timeout": 15,
|
||||||
|
"limit_interval": 0,
|
||||||
|
"limit_count": 0,
|
||||||
|
"limit_seconds": 0,
|
||||||
|
"is_active": true,
|
||||||
|
"pri": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "52pt",
|
||||||
|
"domain": "52pt.site",
|
||||||
|
"url": "https://52pt.site/",
|
||||||
|
"rss": "https://52pt.site/torrentrss.php?rows=50&ismalldescr=1&linktype=dl&passkey=0bde86842ddf1615426b5b6912f85913",
|
||||||
|
"downloader": null,
|
||||||
|
"cookie": "c_secure_uid=MjExNjU%3D;c_secure_pass=322dc728c8926892784dc9a81fcc88d6;c_secure_ssl=eWVhaA%3D%3D;c_secure_tracker_ssl=eWVhaA%3D%3D;c_secure_login=bm9wZQ%3D%3D",
|
||||||
|
"apikey": null,
|
||||||
|
"token": null,
|
||||||
|
"ua": null,
|
||||||
|
"proxy": 0,
|
||||||
|
"filter": null,
|
||||||
|
"render": null,
|
||||||
|
"public": 0,
|
||||||
|
"note": null,
|
||||||
|
"timeout": 15,
|
||||||
|
"limit_interval": 0,
|
||||||
|
"limit_count": 0,
|
||||||
|
"limit_seconds": 0,
|
||||||
|
"is_active": true,
|
||||||
|
"pri": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "1PTBA",
|
||||||
|
"domain": "1ptba.com",
|
||||||
|
"url": "http://1ptba.com/",
|
||||||
|
"rss": "https://1ptba.com/torrentrss.php?passkey=2f0d543c0883d6923fb303446d061cce&rows=10&cat401=1&cat402=1&cat403=1&cat404=1&cat408=1&cat410=1&cat412=1&paid=0&linktype=dl",
|
||||||
|
"downloader": "",
|
||||||
|
"cookie": "_qimei_uuid42=19a070c1e17100762d7eed9b34e39c9a39df8e760b;_qimei_fingerprint=3be02bb021893604b5a7ebe075a55ff0;_qimei_i_3=27d86b80c60b02d39391fe31088776e9f3eaa0f0125b05d1b6db205e26c67539636a35973c89e2d4bf8c;_qimei_h38=;_qimei_i_1=6dfa45f8945a;c_secure_pass=eyJ1c2VyX2lkIjoiMTA5NjY1IiwiZXhwaXJlcyI6MTc5MTM0NzQ5NX0uYzkwNWQ4YzNhNjZhNjlmNWNhYjI2MmYyYzExMTYyY2JlZmNlMGRjNDhmMjk2YWM3YTEyZDc2MTA1ZWI2NGQ3OA%3D%3D",
|
||||||
|
"apikey": null,
|
||||||
|
"token": null,
|
||||||
|
"ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0",
|
||||||
|
"proxy": 0,
|
||||||
|
"filter": null,
|
||||||
|
"render": 0,
|
||||||
|
"public": 0,
|
||||||
|
"note": null,
|
||||||
|
"timeout": 0,
|
||||||
|
"limit_interval": 0,
|
||||||
|
"limit_count": 0,
|
||||||
|
"limit_seconds": 0,
|
||||||
|
"is_active": true,
|
||||||
|
"pri": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
services:
|
||||||
|
ai-assistant:
|
||||||
|
image: ghcr.io/qq85423296/t3fap-ai-assistant:latest
|
||||||
|
container_name: t3fap-ai-assistant
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
T3MT_HOST: http://192.168.0.111:8521
|
||||||
|
T3MT_API_KEY: "这里填t3fap 个人密钥 获取的 key"
|
||||||
|
T3MT_AUTOMATION_MODE: full-access
|
||||||
|
T3MT_CONFIRM_REDLINE_ACTIONS: "true"
|
||||||
|
T3FAP_ASSISTANT_MODEL_NAME: gpt-5.4
|
||||||
|
T3FAP_ASSISTANT_MODEL: openai/gpt-5.4
|
||||||
|
T3FAP_ASSISTANT_API_KEY: "这里填新模型 key"
|
||||||
|
T3FAP_ASSISTANT_API_BASE: https://api.openai.com/v1
|
||||||
|
T3FAP_ASSISTANT_PICO_TOKEN: ""
|
||||||
|
ports:
|
||||||
|
- "18800:18800"
|
||||||
|
- "18790:18790"
|
||||||
|
volumes:
|
||||||
|
- ./assistant-data:/data/picoclaw
|
||||||
Executable
BIN
Binary file not shown.
Executable
+3
@@ -0,0 +1,3 @@
|
|||||||
|
frpc
|
||||||
|
wordpress-1
|
||||||
|
jeessy-ddns-go-1
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
services:
|
||||||
|
pansou:
|
||||||
|
image: ghcr.io/fish2018/pansou-web:latest
|
||||||
|
container_name: pansou
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8383:80" #左边是宿主机端口
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
- CACHE_PATH=/app/data/cache
|
||||||
|
- LOG_PATH=/app/data/logs
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- ./config:/app/config # 挂载配置文件目录
|
||||||
|
- ./data:/app/data
|
||||||
Reference in New Issue
Block a user