feat: add loon and mihomo compatibility outputs from surge source
This commit is contained in:
@@ -56,6 +56,7 @@ jobs:
|
||||
SOURCE_REF="${SOURCE_REF:-main}"
|
||||
SOURCE_ROOT="${SOURCE_ROOT:-rule/Surge}"
|
||||
CLASH_NO_RESOLVE="${CLASH_NO_RESOLVE:-false}"
|
||||
MIHOMO_NO_RESOLVE="${MIHOMO_NO_RESOLVE:-false}"
|
||||
|
||||
cat > config.runtime.json <<JSON
|
||||
{
|
||||
@@ -74,7 +75,8 @@ jobs:
|
||||
},
|
||||
"output": {
|
||||
"dir": "dist",
|
||||
"clash_no_resolve": ${CLASH_NO_RESOLVE}
|
||||
"clash_no_resolve": ${CLASH_NO_RESOLVE},
|
||||
"mihomo_no_resolve": ${MIHOMO_NO_RESOLVE}
|
||||
}
|
||||
}
|
||||
JSON
|
||||
@@ -85,6 +87,7 @@ jobs:
|
||||
SOURCE_REF: ${{ vars.SOURCE_REF }}
|
||||
SOURCE_ROOT: ${{ vars.SOURCE_ROOT }}
|
||||
CLASH_NO_RESOLVE: ${{ vars.CLASH_NO_RESOLVE }}
|
||||
MIHOMO_NO_RESOLVE: ${{ vars.MIHOMO_NO_RESOLVE }}
|
||||
|
||||
- name: Generate rules
|
||||
if: steps.preflight.outputs.skip != 'true'
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
- 输入按目录分类(默认读取 `rule/Surge/<Name>/<Name>.list`)
|
||||
- 输出仅包含你要的两种格式:
|
||||
- `dist/surge/<Name>.list`
|
||||
- `dist/loon/<Name>.list`
|
||||
- `dist/clash/<Name>.yaml`
|
||||
- `dist/mihomo/<Name>.yaml`
|
||||
- 当前策略:**只使用 Surge 作为上游源,Clash 由 Surge 规则转换生成**
|
||||
|
||||
## 为什么这个方案适合你
|
||||
@@ -88,10 +90,17 @@ USER-AGENT,*youtube*
|
||||
## 转换规则说明
|
||||
|
||||
- Surge 输出:保留源规则(去重、清理空白)
|
||||
- Loon 输出:基于 Surge 规则直接输出(同样去重、清理空白)
|
||||
- Clash 输出:
|
||||
- 自动移除注释/空行
|
||||
- `USER-AGENT`、`URL-REGEX` 默认跳过(并在头部记录 `SKIPPED-*`)
|
||||
- `DEST-PORT` 自动映射为 `DST-PORT`
|
||||
- `IP-CIDR`/`IP-CIDR6` 可通过 `clash_no_resolve` 控制是否追加 `no-resolve`
|
||||
- Mihomo 输出:
|
||||
- 使用与 Clash 相同的 provider YAML 结构
|
||||
- `DEST-PORT` 自动映射为 `DST-PORT`
|
||||
- `USER-AGENT`、`URL-REGEX` 默认跳过(并在头部记录 `SKIPPED-*`)
|
||||
- `IP-CIDR`/`IP-CIDR6` 可通过 `mihomo_no_resolve` 控制是否追加 `no-resolve`
|
||||
|
||||
## 定时更新建议
|
||||
|
||||
@@ -140,5 +149,6 @@ USER-AGENT,*youtube*
|
||||
- `SOURCE_ROOT`(默认 `rule/Surge`)
|
||||
- `TARGET_BRANCH`(默认 `main`)
|
||||
- `CLASH_NO_RESOLVE`(默认 `false`)
|
||||
- `MIHOMO_NO_RESOLVE`(默认 `false`)
|
||||
|
||||
该工作流当前定时为 `15 3 * * *`(UTC),对应北京时间每天 `11:15`,也支持手动触发。
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@
|
||||
},
|
||||
"output": {
|
||||
"dir": "dist",
|
||||
"clash_no_resolve": false
|
||||
"clash_no_resolve": false,
|
||||
"mihomo_no_resolve": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,3 +16,5 @@ exclude_categories = []
|
||||
dir = "dist"
|
||||
# true: IP-CIDR/IP-CIDR6 in Clash payload include no-resolve
|
||||
clash_no_resolve = false
|
||||
# true: IP-CIDR/IP-CIDR6 in Mihomo payload include no-resolve
|
||||
mihomo_no_resolve = false
|
||||
|
||||
+2
-1
@@ -682,6 +682,7 @@
|
||||
},
|
||||
"output": {
|
||||
"dir": "dist",
|
||||
"clash_no_resolve": false
|
||||
"clash_no_resolve": false,
|
||||
"mihomo_no_resolve": false
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# NAME: YouTube
|
||||
# AUTHOR: gitea-shunt-rules
|
||||
# SOURCE: rule/Surge/YouTube/YouTube.list
|
||||
# UPDATED: 2026-04-06 05:01:32 UTC
|
||||
# UPDATED: 2026-04-06 05:38:50 UTC
|
||||
# DOMAIN-KEYWORD: 1
|
||||
# DOMAIN-SUFFIX: 179
|
||||
# IP-CIDR: 2
|
||||
|
||||
Vendored
+200
@@ -0,0 +1,200 @@
|
||||
# NAME: YouTube
|
||||
# AUTHOR: gitea-shunt-rules
|
||||
# SOURCE: rule/Surge/YouTube/YouTube.list
|
||||
# UPDATED: 2026-04-06 05:38:50 UTC
|
||||
# DOMAIN-KEYWORD: 1
|
||||
# DOMAIN-SUFFIX: 179
|
||||
# IP-CIDR: 2
|
||||
# IP-CIDR6: 1
|
||||
# USER-AGENT: 7
|
||||
# TOTAL: 190
|
||||
DOMAIN-SUFFIX,ggpht.cn
|
||||
DOMAIN-SUFFIX,ggpht.com
|
||||
DOMAIN-SUFFIX,googlevideo.com
|
||||
DOMAIN-SUFFIX,gvt1.com
|
||||
DOMAIN-SUFFIX,gvt2.com
|
||||
DOMAIN-SUFFIX,video.google.com
|
||||
DOMAIN-SUFFIX,wide-youtube.l.google.com
|
||||
DOMAIN-SUFFIX,withyoutube.com
|
||||
DOMAIN-SUFFIX,youtu.be
|
||||
DOMAIN-SUFFIX,youtube
|
||||
DOMAIN-SUFFIX,youtube-nocookie.com
|
||||
DOMAIN-SUFFIX,youtube-ui.l.google.com
|
||||
DOMAIN-SUFFIX,youtube.ae
|
||||
DOMAIN-SUFFIX,youtube.al
|
||||
DOMAIN-SUFFIX,youtube.am
|
||||
DOMAIN-SUFFIX,youtube.at
|
||||
DOMAIN-SUFFIX,youtube.az
|
||||
DOMAIN-SUFFIX,youtube.ba
|
||||
DOMAIN-SUFFIX,youtube.be
|
||||
DOMAIN-SUFFIX,youtube.bg
|
||||
DOMAIN-SUFFIX,youtube.bh
|
||||
DOMAIN-SUFFIX,youtube.bo
|
||||
DOMAIN-SUFFIX,youtube.by
|
||||
DOMAIN-SUFFIX,youtube.ca
|
||||
DOMAIN-SUFFIX,youtube.cat
|
||||
DOMAIN-SUFFIX,youtube.ch
|
||||
DOMAIN-SUFFIX,youtube.cl
|
||||
DOMAIN-SUFFIX,youtube.co
|
||||
DOMAIN-SUFFIX,youtube.co.ae
|
||||
DOMAIN-SUFFIX,youtube.co.at
|
||||
DOMAIN-SUFFIX,youtube.co.cr
|
||||
DOMAIN-SUFFIX,youtube.co.hu
|
||||
DOMAIN-SUFFIX,youtube.co.id
|
||||
DOMAIN-SUFFIX,youtube.co.il
|
||||
DOMAIN-SUFFIX,youtube.co.in
|
||||
DOMAIN-SUFFIX,youtube.co.jp
|
||||
DOMAIN-SUFFIX,youtube.co.ke
|
||||
DOMAIN-SUFFIX,youtube.co.kr
|
||||
DOMAIN-SUFFIX,youtube.co.ma
|
||||
DOMAIN-SUFFIX,youtube.co.nz
|
||||
DOMAIN-SUFFIX,youtube.co.th
|
||||
DOMAIN-SUFFIX,youtube.co.tz
|
||||
DOMAIN-SUFFIX,youtube.co.ug
|
||||
DOMAIN-SUFFIX,youtube.co.uk
|
||||
DOMAIN-SUFFIX,youtube.co.ve
|
||||
DOMAIN-SUFFIX,youtube.co.za
|
||||
DOMAIN-SUFFIX,youtube.co.zw
|
||||
DOMAIN-SUFFIX,youtube.com
|
||||
DOMAIN-SUFFIX,youtube.com.ar
|
||||
DOMAIN-SUFFIX,youtube.com.au
|
||||
DOMAIN-SUFFIX,youtube.com.az
|
||||
DOMAIN-SUFFIX,youtube.com.bd
|
||||
DOMAIN-SUFFIX,youtube.com.bh
|
||||
DOMAIN-SUFFIX,youtube.com.bo
|
||||
DOMAIN-SUFFIX,youtube.com.br
|
||||
DOMAIN-SUFFIX,youtube.com.by
|
||||
DOMAIN-SUFFIX,youtube.com.co
|
||||
DOMAIN-SUFFIX,youtube.com.do
|
||||
DOMAIN-SUFFIX,youtube.com.ec
|
||||
DOMAIN-SUFFIX,youtube.com.ee
|
||||
DOMAIN-SUFFIX,youtube.com.eg
|
||||
DOMAIN-SUFFIX,youtube.com.es
|
||||
DOMAIN-SUFFIX,youtube.com.gh
|
||||
DOMAIN-SUFFIX,youtube.com.gr
|
||||
DOMAIN-SUFFIX,youtube.com.gt
|
||||
DOMAIN-SUFFIX,youtube.com.hk
|
||||
DOMAIN-SUFFIX,youtube.com.hn
|
||||
DOMAIN-SUFFIX,youtube.com.hr
|
||||
DOMAIN-SUFFIX,youtube.com.jm
|
||||
DOMAIN-SUFFIX,youtube.com.jo
|
||||
DOMAIN-SUFFIX,youtube.com.kw
|
||||
DOMAIN-SUFFIX,youtube.com.lb
|
||||
DOMAIN-SUFFIX,youtube.com.lv
|
||||
DOMAIN-SUFFIX,youtube.com.ly
|
||||
DOMAIN-SUFFIX,youtube.com.mk
|
||||
DOMAIN-SUFFIX,youtube.com.mt
|
||||
DOMAIN-SUFFIX,youtube.com.mx
|
||||
DOMAIN-SUFFIX,youtube.com.my
|
||||
DOMAIN-SUFFIX,youtube.com.ng
|
||||
DOMAIN-SUFFIX,youtube.com.ni
|
||||
DOMAIN-SUFFIX,youtube.com.om
|
||||
DOMAIN-SUFFIX,youtube.com.pa
|
||||
DOMAIN-SUFFIX,youtube.com.pe
|
||||
DOMAIN-SUFFIX,youtube.com.ph
|
||||
DOMAIN-SUFFIX,youtube.com.pk
|
||||
DOMAIN-SUFFIX,youtube.com.pt
|
||||
DOMAIN-SUFFIX,youtube.com.py
|
||||
DOMAIN-SUFFIX,youtube.com.qa
|
||||
DOMAIN-SUFFIX,youtube.com.ro
|
||||
DOMAIN-SUFFIX,youtube.com.sa
|
||||
DOMAIN-SUFFIX,youtube.com.sg
|
||||
DOMAIN-SUFFIX,youtube.com.sv
|
||||
DOMAIN-SUFFIX,youtube.com.tn
|
||||
DOMAIN-SUFFIX,youtube.com.tr
|
||||
DOMAIN-SUFFIX,youtube.com.tw
|
||||
DOMAIN-SUFFIX,youtube.com.ua
|
||||
DOMAIN-SUFFIX,youtube.com.uy
|
||||
DOMAIN-SUFFIX,youtube.com.ve
|
||||
DOMAIN-SUFFIX,youtube.cr
|
||||
DOMAIN-SUFFIX,youtube.cz
|
||||
DOMAIN-SUFFIX,youtube.de
|
||||
DOMAIN-SUFFIX,youtube.dk
|
||||
DOMAIN-SUFFIX,youtube.ee
|
||||
DOMAIN-SUFFIX,youtube.es
|
||||
DOMAIN-SUFFIX,youtube.fi
|
||||
DOMAIN-SUFFIX,youtube.fr
|
||||
DOMAIN-SUFFIX,youtube.ge
|
||||
DOMAIN-SUFFIX,youtube.googleapis.com
|
||||
DOMAIN-SUFFIX,youtube.gr
|
||||
DOMAIN-SUFFIX,youtube.gt
|
||||
DOMAIN-SUFFIX,youtube.hk
|
||||
DOMAIN-SUFFIX,youtube.hr
|
||||
DOMAIN-SUFFIX,youtube.hu
|
||||
DOMAIN-SUFFIX,youtube.ie
|
||||
DOMAIN-SUFFIX,youtube.in
|
||||
DOMAIN-SUFFIX,youtube.iq
|
||||
DOMAIN-SUFFIX,youtube.is
|
||||
DOMAIN-SUFFIX,youtube.it
|
||||
DOMAIN-SUFFIX,youtube.jo
|
||||
DOMAIN-SUFFIX,youtube.jp
|
||||
DOMAIN-SUFFIX,youtube.kr
|
||||
DOMAIN-SUFFIX,youtube.kz
|
||||
DOMAIN-SUFFIX,youtube.la
|
||||
DOMAIN-SUFFIX,youtube.lk
|
||||
DOMAIN-SUFFIX,youtube.lt
|
||||
DOMAIN-SUFFIX,youtube.lu
|
||||
DOMAIN-SUFFIX,youtube.lv
|
||||
DOMAIN-SUFFIX,youtube.ly
|
||||
DOMAIN-SUFFIX,youtube.ma
|
||||
DOMAIN-SUFFIX,youtube.md
|
||||
DOMAIN-SUFFIX,youtube.me
|
||||
DOMAIN-SUFFIX,youtube.mk
|
||||
DOMAIN-SUFFIX,youtube.mn
|
||||
DOMAIN-SUFFIX,youtube.mx
|
||||
DOMAIN-SUFFIX,youtube.my
|
||||
DOMAIN-SUFFIX,youtube.ng
|
||||
DOMAIN-SUFFIX,youtube.ni
|
||||
DOMAIN-SUFFIX,youtube.nl
|
||||
DOMAIN-SUFFIX,youtube.no
|
||||
DOMAIN-SUFFIX,youtube.pa
|
||||
DOMAIN-SUFFIX,youtube.pe
|
||||
DOMAIN-SUFFIX,youtube.ph
|
||||
DOMAIN-SUFFIX,youtube.pk
|
||||
DOMAIN-SUFFIX,youtube.pl
|
||||
DOMAIN-SUFFIX,youtube.pr
|
||||
DOMAIN-SUFFIX,youtube.pt
|
||||
DOMAIN-SUFFIX,youtube.qa
|
||||
DOMAIN-SUFFIX,youtube.ro
|
||||
DOMAIN-SUFFIX,youtube.rs
|
||||
DOMAIN-SUFFIX,youtube.ru
|
||||
DOMAIN-SUFFIX,youtube.sa
|
||||
DOMAIN-SUFFIX,youtube.se
|
||||
DOMAIN-SUFFIX,youtube.sg
|
||||
DOMAIN-SUFFIX,youtube.si
|
||||
DOMAIN-SUFFIX,youtube.sk
|
||||
DOMAIN-SUFFIX,youtube.sn
|
||||
DOMAIN-SUFFIX,youtube.soy
|
||||
DOMAIN-SUFFIX,youtube.sv
|
||||
DOMAIN-SUFFIX,youtube.tn
|
||||
DOMAIN-SUFFIX,youtube.tv
|
||||
DOMAIN-SUFFIX,youtube.ua
|
||||
DOMAIN-SUFFIX,youtube.ug
|
||||
DOMAIN-SUFFIX,youtube.uy
|
||||
DOMAIN-SUFFIX,youtube.vn
|
||||
DOMAIN-SUFFIX,youtubeeducation.com
|
||||
DOMAIN-SUFFIX,youtubeembeddedplayer.googleapis.com
|
||||
DOMAIN-SUFFIX,youtubefanfest.com
|
||||
DOMAIN-SUFFIX,youtubegaming.com
|
||||
DOMAIN-SUFFIX,youtubego.co.id
|
||||
DOMAIN-SUFFIX,youtubego.co.in
|
||||
DOMAIN-SUFFIX,youtubego.com
|
||||
DOMAIN-SUFFIX,youtubego.com.br
|
||||
DOMAIN-SUFFIX,youtubego.id
|
||||
DOMAIN-SUFFIX,youtubego.in
|
||||
DOMAIN-SUFFIX,youtubei.googleapis.com
|
||||
DOMAIN-SUFFIX,youtubekids.com
|
||||
DOMAIN-SUFFIX,youtubemobilesupport.com
|
||||
DOMAIN-SUFFIX,yt.be
|
||||
DOMAIN-SUFFIX,ytimg.com
|
||||
DOMAIN-KEYWORD,youtube
|
||||
IP-CIDR,172.110.32.0/21,no-resolve
|
||||
IP-CIDR,216.73.80.0/20,no-resolve
|
||||
IP-CIDR6,2620:120:e000::/40,no-resolve
|
||||
USER-AGENT,*YouTubeMusic*
|
||||
USER-AGENT,*com.google.ios.youtubemusic*
|
||||
USER-AGENT,*youtube*
|
||||
USER-AGENT,YouTube*
|
||||
USER-AGENT,YouTubeMusic*
|
||||
USER-AGENT,com.google.ios.youtube*
|
||||
USER-AGENT,com.google.ios.youtubemusic*
|
||||
Vendored
+194
@@ -0,0 +1,194 @@
|
||||
# NAME: YouTube
|
||||
# AUTHOR: gitea-shunt-rules-mihomo
|
||||
# SOURCE: rule/Surge/YouTube/YouTube.list
|
||||
# UPDATED: 2026-04-06 05:38:50 UTC
|
||||
# DOMAIN-KEYWORD: 1
|
||||
# DOMAIN-SUFFIX: 179
|
||||
# IP-CIDR: 2
|
||||
# IP-CIDR6: 1
|
||||
# SKIPPED-USER-AGENT: 7
|
||||
# TOTAL: 183
|
||||
payload:
|
||||
- DOMAIN-SUFFIX,ggpht.cn
|
||||
- DOMAIN-SUFFIX,ggpht.com
|
||||
- DOMAIN-SUFFIX,googlevideo.com
|
||||
- DOMAIN-SUFFIX,gvt1.com
|
||||
- DOMAIN-SUFFIX,gvt2.com
|
||||
- DOMAIN-SUFFIX,video.google.com
|
||||
- DOMAIN-SUFFIX,wide-youtube.l.google.com
|
||||
- DOMAIN-SUFFIX,withyoutube.com
|
||||
- DOMAIN-SUFFIX,youtu.be
|
||||
- DOMAIN-SUFFIX,youtube
|
||||
- DOMAIN-SUFFIX,youtube-nocookie.com
|
||||
- DOMAIN-SUFFIX,youtube-ui.l.google.com
|
||||
- DOMAIN-SUFFIX,youtube.ae
|
||||
- DOMAIN-SUFFIX,youtube.al
|
||||
- DOMAIN-SUFFIX,youtube.am
|
||||
- DOMAIN-SUFFIX,youtube.at
|
||||
- DOMAIN-SUFFIX,youtube.az
|
||||
- DOMAIN-SUFFIX,youtube.ba
|
||||
- DOMAIN-SUFFIX,youtube.be
|
||||
- DOMAIN-SUFFIX,youtube.bg
|
||||
- DOMAIN-SUFFIX,youtube.bh
|
||||
- DOMAIN-SUFFIX,youtube.bo
|
||||
- DOMAIN-SUFFIX,youtube.by
|
||||
- DOMAIN-SUFFIX,youtube.ca
|
||||
- DOMAIN-SUFFIX,youtube.cat
|
||||
- DOMAIN-SUFFIX,youtube.ch
|
||||
- DOMAIN-SUFFIX,youtube.cl
|
||||
- DOMAIN-SUFFIX,youtube.co
|
||||
- DOMAIN-SUFFIX,youtube.co.ae
|
||||
- DOMAIN-SUFFIX,youtube.co.at
|
||||
- DOMAIN-SUFFIX,youtube.co.cr
|
||||
- DOMAIN-SUFFIX,youtube.co.hu
|
||||
- DOMAIN-SUFFIX,youtube.co.id
|
||||
- DOMAIN-SUFFIX,youtube.co.il
|
||||
- DOMAIN-SUFFIX,youtube.co.in
|
||||
- DOMAIN-SUFFIX,youtube.co.jp
|
||||
- DOMAIN-SUFFIX,youtube.co.ke
|
||||
- DOMAIN-SUFFIX,youtube.co.kr
|
||||
- DOMAIN-SUFFIX,youtube.co.ma
|
||||
- DOMAIN-SUFFIX,youtube.co.nz
|
||||
- DOMAIN-SUFFIX,youtube.co.th
|
||||
- DOMAIN-SUFFIX,youtube.co.tz
|
||||
- DOMAIN-SUFFIX,youtube.co.ug
|
||||
- DOMAIN-SUFFIX,youtube.co.uk
|
||||
- DOMAIN-SUFFIX,youtube.co.ve
|
||||
- DOMAIN-SUFFIX,youtube.co.za
|
||||
- DOMAIN-SUFFIX,youtube.co.zw
|
||||
- DOMAIN-SUFFIX,youtube.com
|
||||
- DOMAIN-SUFFIX,youtube.com.ar
|
||||
- DOMAIN-SUFFIX,youtube.com.au
|
||||
- DOMAIN-SUFFIX,youtube.com.az
|
||||
- DOMAIN-SUFFIX,youtube.com.bd
|
||||
- DOMAIN-SUFFIX,youtube.com.bh
|
||||
- DOMAIN-SUFFIX,youtube.com.bo
|
||||
- DOMAIN-SUFFIX,youtube.com.br
|
||||
- DOMAIN-SUFFIX,youtube.com.by
|
||||
- DOMAIN-SUFFIX,youtube.com.co
|
||||
- DOMAIN-SUFFIX,youtube.com.do
|
||||
- DOMAIN-SUFFIX,youtube.com.ec
|
||||
- DOMAIN-SUFFIX,youtube.com.ee
|
||||
- DOMAIN-SUFFIX,youtube.com.eg
|
||||
- DOMAIN-SUFFIX,youtube.com.es
|
||||
- DOMAIN-SUFFIX,youtube.com.gh
|
||||
- DOMAIN-SUFFIX,youtube.com.gr
|
||||
- DOMAIN-SUFFIX,youtube.com.gt
|
||||
- DOMAIN-SUFFIX,youtube.com.hk
|
||||
- DOMAIN-SUFFIX,youtube.com.hn
|
||||
- DOMAIN-SUFFIX,youtube.com.hr
|
||||
- DOMAIN-SUFFIX,youtube.com.jm
|
||||
- DOMAIN-SUFFIX,youtube.com.jo
|
||||
- DOMAIN-SUFFIX,youtube.com.kw
|
||||
- DOMAIN-SUFFIX,youtube.com.lb
|
||||
- DOMAIN-SUFFIX,youtube.com.lv
|
||||
- DOMAIN-SUFFIX,youtube.com.ly
|
||||
- DOMAIN-SUFFIX,youtube.com.mk
|
||||
- DOMAIN-SUFFIX,youtube.com.mt
|
||||
- DOMAIN-SUFFIX,youtube.com.mx
|
||||
- DOMAIN-SUFFIX,youtube.com.my
|
||||
- DOMAIN-SUFFIX,youtube.com.ng
|
||||
- DOMAIN-SUFFIX,youtube.com.ni
|
||||
- DOMAIN-SUFFIX,youtube.com.om
|
||||
- DOMAIN-SUFFIX,youtube.com.pa
|
||||
- DOMAIN-SUFFIX,youtube.com.pe
|
||||
- DOMAIN-SUFFIX,youtube.com.ph
|
||||
- DOMAIN-SUFFIX,youtube.com.pk
|
||||
- DOMAIN-SUFFIX,youtube.com.pt
|
||||
- DOMAIN-SUFFIX,youtube.com.py
|
||||
- DOMAIN-SUFFIX,youtube.com.qa
|
||||
- DOMAIN-SUFFIX,youtube.com.ro
|
||||
- DOMAIN-SUFFIX,youtube.com.sa
|
||||
- DOMAIN-SUFFIX,youtube.com.sg
|
||||
- DOMAIN-SUFFIX,youtube.com.sv
|
||||
- DOMAIN-SUFFIX,youtube.com.tn
|
||||
- DOMAIN-SUFFIX,youtube.com.tr
|
||||
- DOMAIN-SUFFIX,youtube.com.tw
|
||||
- DOMAIN-SUFFIX,youtube.com.ua
|
||||
- DOMAIN-SUFFIX,youtube.com.uy
|
||||
- DOMAIN-SUFFIX,youtube.com.ve
|
||||
- DOMAIN-SUFFIX,youtube.cr
|
||||
- DOMAIN-SUFFIX,youtube.cz
|
||||
- DOMAIN-SUFFIX,youtube.de
|
||||
- DOMAIN-SUFFIX,youtube.dk
|
||||
- DOMAIN-SUFFIX,youtube.ee
|
||||
- DOMAIN-SUFFIX,youtube.es
|
||||
- DOMAIN-SUFFIX,youtube.fi
|
||||
- DOMAIN-SUFFIX,youtube.fr
|
||||
- DOMAIN-SUFFIX,youtube.ge
|
||||
- DOMAIN-SUFFIX,youtube.googleapis.com
|
||||
- DOMAIN-SUFFIX,youtube.gr
|
||||
- DOMAIN-SUFFIX,youtube.gt
|
||||
- DOMAIN-SUFFIX,youtube.hk
|
||||
- DOMAIN-SUFFIX,youtube.hr
|
||||
- DOMAIN-SUFFIX,youtube.hu
|
||||
- DOMAIN-SUFFIX,youtube.ie
|
||||
- DOMAIN-SUFFIX,youtube.in
|
||||
- DOMAIN-SUFFIX,youtube.iq
|
||||
- DOMAIN-SUFFIX,youtube.is
|
||||
- DOMAIN-SUFFIX,youtube.it
|
||||
- DOMAIN-SUFFIX,youtube.jo
|
||||
- DOMAIN-SUFFIX,youtube.jp
|
||||
- DOMAIN-SUFFIX,youtube.kr
|
||||
- DOMAIN-SUFFIX,youtube.kz
|
||||
- DOMAIN-SUFFIX,youtube.la
|
||||
- DOMAIN-SUFFIX,youtube.lk
|
||||
- DOMAIN-SUFFIX,youtube.lt
|
||||
- DOMAIN-SUFFIX,youtube.lu
|
||||
- DOMAIN-SUFFIX,youtube.lv
|
||||
- DOMAIN-SUFFIX,youtube.ly
|
||||
- DOMAIN-SUFFIX,youtube.ma
|
||||
- DOMAIN-SUFFIX,youtube.md
|
||||
- DOMAIN-SUFFIX,youtube.me
|
||||
- DOMAIN-SUFFIX,youtube.mk
|
||||
- DOMAIN-SUFFIX,youtube.mn
|
||||
- DOMAIN-SUFFIX,youtube.mx
|
||||
- DOMAIN-SUFFIX,youtube.my
|
||||
- DOMAIN-SUFFIX,youtube.ng
|
||||
- DOMAIN-SUFFIX,youtube.ni
|
||||
- DOMAIN-SUFFIX,youtube.nl
|
||||
- DOMAIN-SUFFIX,youtube.no
|
||||
- DOMAIN-SUFFIX,youtube.pa
|
||||
- DOMAIN-SUFFIX,youtube.pe
|
||||
- DOMAIN-SUFFIX,youtube.ph
|
||||
- DOMAIN-SUFFIX,youtube.pk
|
||||
- DOMAIN-SUFFIX,youtube.pl
|
||||
- DOMAIN-SUFFIX,youtube.pr
|
||||
- DOMAIN-SUFFIX,youtube.pt
|
||||
- DOMAIN-SUFFIX,youtube.qa
|
||||
- DOMAIN-SUFFIX,youtube.ro
|
||||
- DOMAIN-SUFFIX,youtube.rs
|
||||
- DOMAIN-SUFFIX,youtube.ru
|
||||
- DOMAIN-SUFFIX,youtube.sa
|
||||
- DOMAIN-SUFFIX,youtube.se
|
||||
- DOMAIN-SUFFIX,youtube.sg
|
||||
- DOMAIN-SUFFIX,youtube.si
|
||||
- DOMAIN-SUFFIX,youtube.sk
|
||||
- DOMAIN-SUFFIX,youtube.sn
|
||||
- DOMAIN-SUFFIX,youtube.soy
|
||||
- DOMAIN-SUFFIX,youtube.sv
|
||||
- DOMAIN-SUFFIX,youtube.tn
|
||||
- DOMAIN-SUFFIX,youtube.tv
|
||||
- DOMAIN-SUFFIX,youtube.ua
|
||||
- DOMAIN-SUFFIX,youtube.ug
|
||||
- DOMAIN-SUFFIX,youtube.uy
|
||||
- DOMAIN-SUFFIX,youtube.vn
|
||||
- DOMAIN-SUFFIX,youtubeeducation.com
|
||||
- DOMAIN-SUFFIX,youtubeembeddedplayer.googleapis.com
|
||||
- DOMAIN-SUFFIX,youtubefanfest.com
|
||||
- DOMAIN-SUFFIX,youtubegaming.com
|
||||
- DOMAIN-SUFFIX,youtubego.co.id
|
||||
- DOMAIN-SUFFIX,youtubego.co.in
|
||||
- DOMAIN-SUFFIX,youtubego.com
|
||||
- DOMAIN-SUFFIX,youtubego.com.br
|
||||
- DOMAIN-SUFFIX,youtubego.id
|
||||
- DOMAIN-SUFFIX,youtubego.in
|
||||
- DOMAIN-SUFFIX,youtubei.googleapis.com
|
||||
- DOMAIN-SUFFIX,youtubekids.com
|
||||
- DOMAIN-SUFFIX,youtubemobilesupport.com
|
||||
- DOMAIN-SUFFIX,yt.be
|
||||
- DOMAIN-SUFFIX,ytimg.com
|
||||
- DOMAIN-KEYWORD,youtube
|
||||
- IP-CIDR,172.110.32.0/21
|
||||
- IP-CIDR,216.73.80.0/20
|
||||
- IP-CIDR6,2620:120:e000::/40
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# NAME: YouTube
|
||||
# AUTHOR: gitea-shunt-rules
|
||||
# SOURCE: rule/Surge/YouTube/YouTube.list
|
||||
# UPDATED: 2026-04-06 05:01:32 UTC
|
||||
# UPDATED: 2026-04-06 05:38:50 UTC
|
||||
# DOMAIN-KEYWORD: 1
|
||||
# DOMAIN-SUFFIX: 179
|
||||
# IP-CIDR: 2
|
||||
|
||||
@@ -24,7 +24,10 @@ DEFAULT_LIMIT = 100
|
||||
UNSUPPORTED_CLASH_TYPES = {
|
||||
"USER-AGENT",
|
||||
"URL-REGEX",
|
||||
"DEST-PORT", # Surge alias, Clash usually uses DST-PORT
|
||||
}
|
||||
UNSUPPORTED_MIHOMO_TYPES = {
|
||||
"USER-AGENT",
|
||||
"URL-REGEX",
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +44,7 @@ class Config:
|
||||
include_categories: list[str]
|
||||
exclude_categories: list[str]
|
||||
clash_no_resolve: bool
|
||||
mihomo_no_resolve: bool
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -152,6 +156,7 @@ def load_config(path: Path) -> Config:
|
||||
include_categories=source.get("include_categories", []),
|
||||
exclude_categories=source.get("exclude_categories", []),
|
||||
clash_no_resolve=output.get("clash_no_resolve", False),
|
||||
mihomo_no_resolve=output.get("mihomo_no_resolve", False),
|
||||
)
|
||||
|
||||
|
||||
@@ -177,19 +182,25 @@ def parse_rules(content: str) -> list[RuleLine]:
|
||||
return rules
|
||||
|
||||
|
||||
def to_clash_payload_line(rule: RuleLine, no_resolve: bool) -> str | None:
|
||||
def to_payload_line(
|
||||
rule: RuleLine,
|
||||
no_resolve: bool,
|
||||
unsupported_types: set[str],
|
||||
type_mapping: dict[str, str] | None = None,
|
||||
) -> str | None:
|
||||
parts = [p.strip() for p in rule.raw.split(",") if p.strip()]
|
||||
if not parts:
|
||||
return None
|
||||
|
||||
rule_type = parts[0].upper()
|
||||
parts[0] = rule_type
|
||||
mapped_type = (type_mapping or {}).get(rule_type, rule_type)
|
||||
parts[0] = mapped_type
|
||||
|
||||
if rule_type in UNSUPPORTED_CLASH_TYPES:
|
||||
if rule_type in unsupported_types:
|
||||
return None
|
||||
|
||||
if rule_type in {"IP-CIDR", "IP-CIDR6"}:
|
||||
payload = [rule_type, parts[1]] if len(parts) >= 2 else parts
|
||||
if mapped_type in {"IP-CIDR", "IP-CIDR6"}:
|
||||
payload = [mapped_type, parts[1]] if len(parts) >= 2 else parts
|
||||
if no_resolve:
|
||||
payload.append("no-resolve")
|
||||
return ",".join(payload)
|
||||
@@ -217,7 +228,33 @@ def format_surge(name: str, rules: list[RuleLine], source_path: str) -> str:
|
||||
return "\n".join(header + body) + "\n"
|
||||
|
||||
|
||||
def format_clash(name: str, rules: list[RuleLine], source_path: str, no_resolve: bool) -> str:
|
||||
def format_loon(name: str, rules: list[RuleLine], source_path: str) -> str:
|
||||
now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")
|
||||
count = Counter(rule.rule_type for rule in rules)
|
||||
|
||||
header = [
|
||||
f"# NAME: {name}",
|
||||
"# AUTHOR: gitea-shunt-rules",
|
||||
f"# SOURCE: {source_path}",
|
||||
f"# UPDATED: {now}",
|
||||
]
|
||||
for k in sorted(count):
|
||||
header.append(f"# {k}: {count[k]}")
|
||||
header.append(f"# TOTAL: {len(rules)}")
|
||||
|
||||
body = [rule.raw for rule in rules]
|
||||
return "\n".join(header + body) + "\n"
|
||||
|
||||
|
||||
def format_yaml_payload(
|
||||
name: str,
|
||||
rules: list[RuleLine],
|
||||
source_path: str,
|
||||
no_resolve: bool,
|
||||
unsupported_types: set[str],
|
||||
type_mapping: dict[str, str] | None = None,
|
||||
author_name: str = "gitea-shunt-rules",
|
||||
) -> tuple[str, int]:
|
||||
now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")
|
||||
|
||||
payload: list[str] = []
|
||||
@@ -225,7 +262,12 @@ def format_clash(name: str, rules: list[RuleLine], source_path: str, no_resolve:
|
||||
skipped: Counter[str] = Counter()
|
||||
|
||||
for rule in rules:
|
||||
converted = to_clash_payload_line(rule, no_resolve=no_resolve)
|
||||
converted = to_payload_line(
|
||||
rule,
|
||||
no_resolve=no_resolve,
|
||||
unsupported_types=unsupported_types,
|
||||
type_mapping=type_mapping,
|
||||
)
|
||||
if converted is None:
|
||||
skipped[rule.rule_type] += 1
|
||||
continue
|
||||
@@ -234,7 +276,7 @@ def format_clash(name: str, rules: list[RuleLine], source_path: str, no_resolve:
|
||||
|
||||
lines = [
|
||||
f"# NAME: {name}",
|
||||
"# AUTHOR: gitea-shunt-rules",
|
||||
f"# AUTHOR: {author_name}",
|
||||
f"# SOURCE: {source_path}",
|
||||
f"# UPDATED: {now}",
|
||||
]
|
||||
@@ -246,7 +288,7 @@ def format_clash(name: str, rules: list[RuleLine], source_path: str, no_resolve:
|
||||
lines.append("payload:")
|
||||
lines.extend(f" - {item}" for item in payload)
|
||||
|
||||
return "\n".join(lines) + "\n"
|
||||
return "\n".join(lines) + "\n", len(payload)
|
||||
|
||||
|
||||
def should_include_category(name: str, cfg: Config, cli_names: set[str]) -> bool:
|
||||
@@ -285,7 +327,7 @@ def find_categories(client: GiteaClient, cfg: Config, cli_names: set[str]) -> li
|
||||
return sorted(categories)
|
||||
|
||||
|
||||
def build_one_category(client: GiteaClient, cfg: Config, name: str, base_out: Path) -> tuple[int, int]:
|
||||
def build_one_category(client: GiteaClient, cfg: Config, name: str, base_out: Path) -> tuple[int, int, int, int]:
|
||||
filename_base = cfg.source_filename_pattern.format(name=name)
|
||||
candidate_filenames = [
|
||||
filename_base,
|
||||
@@ -318,21 +360,48 @@ def build_one_category(client: GiteaClient, cfg: Config, name: str, base_out: Pa
|
||||
rules = parse_rules(source_content)
|
||||
|
||||
surge_out = base_out / "surge" / f"{name}.list"
|
||||
loon_out = base_out / "loon" / f"{name}.list"
|
||||
clash_out = base_out / "clash" / f"{name}.yaml"
|
||||
mihomo_out = base_out / "mihomo" / f"{name}.yaml"
|
||||
surge_out.parent.mkdir(parents=True, exist_ok=True)
|
||||
loon_out.parent.mkdir(parents=True, exist_ok=True)
|
||||
clash_out.parent.mkdir(parents=True, exist_ok=True)
|
||||
mihomo_out.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
surge_out.write_text(format_surge(name, rules, source_rel_path), encoding="utf-8")
|
||||
clash_out.write_text(
|
||||
format_clash(name, rules, source_rel_path, no_resolve=cfg.clash_no_resolve),
|
||||
loon_out.write_text(format_loon(name, rules, source_rel_path), encoding="utf-8")
|
||||
|
||||
clash_text, clash_cnt = format_yaml_payload(
|
||||
name,
|
||||
rules,
|
||||
source_rel_path,
|
||||
no_resolve=cfg.clash_no_resolve,
|
||||
unsupported_types=UNSUPPORTED_CLASH_TYPES,
|
||||
type_mapping={"DEST-PORT": "DST-PORT"},
|
||||
author_name="gitea-shunt-rules",
|
||||
)
|
||||
clash_out.write_text(clash_text, encoding="utf-8")
|
||||
|
||||
mihomo_text, mihomo_cnt = format_yaml_payload(
|
||||
name,
|
||||
rules,
|
||||
source_rel_path,
|
||||
no_resolve=cfg.mihomo_no_resolve,
|
||||
unsupported_types=UNSUPPORTED_MIHOMO_TYPES,
|
||||
type_mapping={"DEST-PORT": "DST-PORT"},
|
||||
author_name="gitea-shunt-rules-mihomo",
|
||||
)
|
||||
mihomo_out.write_text(
|
||||
mihomo_text,
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
return len(rules), sum(1 for r in rules if to_clash_payload_line(r, no_resolve=cfg.clash_no_resolve) is not None)
|
||||
# source and loon keep the same parsed set
|
||||
return len(rules), len(rules), clash_cnt, mihomo_cnt
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
p = argparse.ArgumentParser(description="Generate Surge/Clash rules from Gitea source repo.")
|
||||
p = argparse.ArgumentParser(description="Generate Surge/Loon/Clash/Mihomo rules from Gitea source repo.")
|
||||
p.add_argument("--config", default="config.toml", help="Path to config TOML file")
|
||||
p.add_argument("--names", default="", help="Comma-separated category names, e.g. YouTube,Netflix")
|
||||
return p.parse_args()
|
||||
@@ -354,19 +423,30 @@ def main() -> int:
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
total_source = 0
|
||||
total_loon = 0
|
||||
total_clash = 0
|
||||
total_mihomo = 0
|
||||
|
||||
print(f"Found {len(categories)} categories under {cfg.source_root}")
|
||||
for idx, name in enumerate(categories, start=1):
|
||||
try:
|
||||
s_cnt, c_cnt = build_one_category(client, cfg, name, out_dir)
|
||||
s_cnt, l_cnt, c_cnt, m_cnt = build_one_category(client, cfg, name, out_dir)
|
||||
total_source += s_cnt
|
||||
total_loon += l_cnt
|
||||
total_clash += c_cnt
|
||||
print(f"[{idx}/{len(categories)}] {name}: source={s_cnt}, clash={c_cnt}")
|
||||
total_mihomo += m_cnt
|
||||
print(f"[{idx}/{len(categories)}] {name}: source={s_cnt}, loon={l_cnt}, clash={c_cnt}, mihomo={m_cnt}")
|
||||
except Exception as exc:
|
||||
print(f"[{idx}/{len(categories)}] {name}: failed: {exc}", file=sys.stderr)
|
||||
|
||||
print(f"Done. source_rules={total_source}, clash_rules={total_clash}, output={out_dir.resolve()}")
|
||||
print(
|
||||
"Done. "
|
||||
f"source_rules={total_source}, "
|
||||
f"loon_rules={total_loon}, "
|
||||
f"clash_rules={total_clash}, "
|
||||
f"mihomo_rules={total_mihomo}, "
|
||||
f"output={out_dir.resolve()}"
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user