Compare commits

...

20 Commits

Author SHA1 Message Date
zu1k
0b6eea08d1 add gen bindata shell 2020-08-30 13:45:10 +08:00
zu1k
37797cba06 update bindata 2020-08-30 13:40:24 +08:00
zu1k
100f3d5431 update html 2020-08-30 13:33:32 +08:00
zu1k
80276f4b4d add ru country 2020-08-30 11:37:03 +08:00
zu1k
e149b1cc18 add more country to clash 2020-08-30 08:38:34 +08:00
zu1k
8fe4d7e7db update clash config file 2020-08-29 21:28:47 +08:00
zu1k
27c936fbe0 update clash config file 2020-08-29 21:22:00 +08:00
zu1k
65b0eb3798 Bump version 2020-08-29 20:50:21 +08:00
zu1k
54b72a9324 add noneed country filter 2020-08-29 20:49:27 +08:00
zu1k
3c6304b8c2 update example config file 2020-08-29 20:28:45 +08:00
zu1k
ca12fc149b remove fanqiangdang 2020-08-29 14:33:06 +08:00
zu1k
7de03fce79 add statistic 2020-08-29 14:10:10 +08:00
zu1k
03cf8c6c22 fix name reindex 2020-08-26 13:41:12 +08:00
zu1k
60009fedea fix country filter 2020-08-26 13:26:18 +08:00
zu1k
6421e09c8e Bump version 2020-08-26 13:09:16 +08:00
zu1k
c3698f8ed5 Add flags.json to bindata and use map instead of slices 2020-08-26 13:07:30 +08:00
zu1k
84d037c0b8 Merge pull request #11 from sparkyvxcx/develop
Add country flag emoji before country code in each proxy name field, some typo fix
2020-08-26 12:49:01 +08:00
Sparkvix
ff52fc0ed1 Add getFlag method for GeoIP struct 2020-08-26 00:10:00 -04:00
Sparkvix
2f731b0acb Add country flag emoji before country code in each proxy name field, some typo fix 2020-08-25 13:41:59 -04:00
zu1k
cedd5b4ec4 update readme 2020-08-25 14:37:15 +08:00
25 changed files with 2290 additions and 1769 deletions

View File

@@ -30,8 +30,7 @@ jobs:
if: startsWith(github.ref, 'refs/tags/')
run: |
go get -u github.com/go-bindata/go-bindata/...
go-bindata -o internal/bindata/geoip/geoip.go -pkg bingeoip assets/GeoLite2-City.mmdb
go-bindata -o internal/bindata/html/html.go -pkg binhtml assets/html/
go-bindata -o internal/bindata/geoip/geoip.go -pkg bingeoip assets/GeoLite2-City.mmdb assets/flags.json
- name: Build
if: startsWith(github.ref, 'refs/tags/')

2
.gitignore vendored
View File

@@ -21,4 +21,4 @@ vendor
# macOS file
.DS_Store
*.exe
assets/html/

View File

@@ -53,8 +53,6 @@ $ go get -u -v github.com/zu1k/proxypool
从这里下载预编译好的程序 [release](https://github.com/zu1k/proxypool/releases)
除了编译好的二进制程序,你还需要下载仓库 `assets` 文件夹,放置在可执行文件同目录
### 使用docker
```sh

View File

@@ -13,14 +13,14 @@ import (
"github.com/zu1k/proxypool/pkg/provider"
)
const version = "v0.3.2"
const version = "v0.3.4"
var router *gin.Engine
func setupRouter() {
gin.SetMode(gin.ReleaseMode)
router = gin.New()
router.Use(gin.Logger(), gin.Recovery())
router.Use(gin.Recovery())
temp, err := loadTemplate()
if err != nil {
panic(err)
@@ -69,8 +69,9 @@ func setupRouter() {
router.GET("/clash/proxies", func(c *gin.Context) {
proxyTypes := c.DefaultQuery("type", "")
proxyCountry := c.DefaultQuery("c", "")
proxyNotCountry := c.DefaultQuery("nc", "")
text := ""
if proxyTypes == "" && proxyCountry == "" {
if proxyTypes == "" && proxyCountry == "" && proxyNotCountry == "" {
text = cache.GetString("clashproxies")
if text == "" {
proxies := cache.GetProxies("proxies")
@@ -80,11 +81,21 @@ func setupRouter() {
}
} else if proxyTypes == "all" {
proxies := cache.GetProxies("allproxies")
clash := provider.Clash{Proxies: proxies, Types: proxyTypes, Country: proxyCountry}
clash := provider.Clash{
Proxies: proxies,
Types: proxyTypes,
Country: proxyCountry,
NotCountry: proxyNotCountry,
}
text = clash.Provide()
} else {
proxies := cache.GetProxies("proxies")
clash := provider.Clash{Proxies: proxies, Types: proxyTypes, Country: proxyCountry}
clash := provider.Clash{
Proxies: proxies,
Types: proxyTypes,
Country: proxyCountry,
NotCountry: proxyNotCountry,
}
text = clash.Provide()
}
c.String(200, text)

2000
assets/flags.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,129 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="HandheldFriendly" content="True">
<title>免费Clash节点</title>
<style type='text/css'>
body {
background-color: white;
color: #333333;
font-family: Arial, sans-serif;
margin: 0;
padding: 36px;
line-height: 1;
font-size: 14px;
}
.section {
margin-bottom: 36px;
}
.section.friendly {
color: #222222;
}
.section.friendly h1 {
font-size: 26px;
background-color: #dad8e4;
padding: 18px 22px 15px 22px;
margin: 0;
overflow: hidden;
}
.section.friendly h1 strong {
display: inline-block;
float: left;
}
.section.friendly h1 small {
display: inline-block;
float: right;
text-align: right;
font-size: 18px;
padding-top: 4px;
color: #333333;
}
.section.friendly .article {
border: 4px solid #dad8e4;
padding: 24px 18px 18px 18px;
}
.section.friendly .article h3 {
font-size: 20px;
margin: 0 0 18px 0;
}
.section.friendly .article a {
color: #6b6ceb;
}
.section.friendly .article a:visited {
color: #1d1d3b;
}
.section.friendly .article p {
font-size: 14px;
}
.section.friendly .article ul {
list-style-type: square;
}
.section.original {
background-color: #eeeeee;
color: #444444;
}
.section.original h2 {
background-color: #dddddd;
margin: 0;
padding: 18px 22px 18px 22px;
font-size: 20px;
}
.section.original pre {
margin: 0;
padding: 18px 22px 18px 22px;
overflow: auto;
font-family: monaco, monospaced;
}
.section.original pre code {
display: block;
font-size: 11px;
width: 100%;
}
</style>
</head>
<body>
<div class='container'>
<div class='section friendly'>
<h1><strong>免费Clash节点</strong></h1>
<div class='article'>
<p>自动抓取tg频道、订阅地址、公开互联网上的ss、ssr、vmess、trojan节点信息聚合去重后提供clash配置每15分钟更新</p>
<br>
<p>Clash配置文件https://{{ .domain }}/clash/config <a href="clash://install-config?url=https://{{ .domain }}/clash/config">一键导入</a></p>
<p>Clash proxy-provider(Shadowrocket添加订阅方式可用)<a href="https://{{ .domain }}/clash/proxies">https://{{ .domain }}/clash/proxies</a></p>
<br>
<p>筛选代理类型(此种方式你只能自己维护配置文件)https://{{ .domain }}/clash/proxies?type=ss,ssr,vmess</p>
<p>筛选国家(此种方式你只能自己维护配置文件)https://{{ .domain }}/clash/proxies?type=ss,ssr,vmess&c=HK,TW,US</p>
<p>所有节点的Provider(不是都可以用)<a href="https://{{ .domain }}/clash/proxies?type=all">https://{{ .domain }}/clash/proxies?type=all</a></p>
<br>
<p>抓取程序已开源:<a href="https://github.com/zu1k/proxypool">https://github.com/zu1k/proxypool</a></p>
</div>
</div>
</div>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-DC6CR61FHE"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-DC6CR61FHE');
</script>
</body>
</html>

View File

@@ -1,148 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="HandheldFriendly" content="True">
<title>免费节点</title>
<meta property="og:site_name" content="免费节点">
<meta property="og:description" content="免费ss,免费ssr,免费v2ray,免费vmess,免费vless,免费shadowsocks,免费shadowsocksr,免费shadowsocksrr,免费shadowrocket,免费quan,免费quanx,免费surge,免费小火箭,白嫖ss,白嫖ssr,白嫖v2ray,白嫖vmess,白嫖vless,白嫖shadowsocks,白嫖shadowsocksr,白嫖shadowsocksrr,白嫖shadowrocket,白嫖quan,白嫖quanx,白嫖surge,白嫖小火箭,高速ss,高速ssr,高速v2ray,高速vmess,高速vless,高速shadowsocks,高速shadowsocksr,高速shadowsocksrr,高速shadowrocket,高速quan,高速quanx,高速surge,高速小火箭,公益ss,公益ssr,公益v2ray,公益vmess,公益vless,公益shadowsocks,公益shadowsocksr,公益shadowsocksrr,公益shadowrocket,公益quan,公益quanx,公益surge,公益小火箭,windowsss,windowsssr,windowsv2ray,windowsvmess,windowsvless,windowsshadowsocks,windowsshadowsocksr,windowsshadowsocksrr,windowsshadowrocket,windowsquan,windowsquanx,windowssurge,windows小火箭,androidss,androidssr,androidv2ray,androidvmess,androidvless,androidshadowsocks,androidshadowsocksr,androidshadowsocksrr,androidshadowrocket,androidquan,androidquanx,androidsurge,android小火箭,iosss,iosssr,iosv2ray,iosvmess,iosvless,iosshadowsocks,iosshadowsocksr,iosshadowsocksrr,iosshadowrocket,iosquan,iosquanx,iossurge,ios小火箭,macss,macssr,macv2ray,macvmess,macvless,macshadowsocks,macshadowsocksr,macshadowsocksrr,macshadowrocket,macquan,macquanx,macsurge,mac小火箭,苹果ss,苹果ssr,苹果v2ray,苹果vmess,苹果vless,苹果shadowsocks,苹果shadowsocksr,苹果shadowsocksrr,苹果shadowrocket,苹果quan,苹果quanx,苹果surge,苹果小火箭,安卓ss,安卓ssr,安卓v2ray,安卓vmess,安卓vless,安卓shadowsocks,安卓shadowsocksr,安卓shadowsocksrr,安卓shadowrocket,安卓quan,安卓quanx,安卓surge,安卓小火箭">
<meta name="keywords" content="免费ss,免费ssr,免费v2ray,免费vmess,免费vless,免费shadowsocks,免费shadowsocksr,免费shadowsocksrr,免费shadowrocket,免费quan,免费quanx,免费surge,免费小火箭,白嫖ss,白嫖ssr,白嫖v2ray,白嫖vmess,白嫖vless,白嫖shadowsocks,白嫖shadowsocksr,白嫖shadowsocksrr,白嫖shadowrocket,白嫖quan,白嫖quanx,白嫖surge,白嫖小火箭,高速ss,高速ssr,高速v2ray,高速vmess,高速vless,高速shadowsocks,高速shadowsocksr,高速shadowsocksrr,高速shadowrocket,高速quan,高速quanx,高速surge,高速小火箭,公益ss,公益ssr,公益v2ray,公益vmess,公益vless,公益shadowsocks,公益shadowsocksr,公益shadowsocksrr,公益shadowrocket,公益quan,公益quanx,公益surge,公益小火箭,windowsss,windowsssr,windowsv2ray,windowsvmess,windowsvless,windowsshadowsocks,windowsshadowsocksr,windowsshadowsocksrr,windowsshadowrocket,windowsquan,windowsquanx,windowssurge,windows小火箭,androidss,androidssr,androidv2ray,androidvmess,androidvless,androidshadowsocks,androidshadowsocksr,androidshadowsocksrr,androidshadowrocket,androidquan,androidquanx,androidsurge,android小火箭,iosss,iosssr,iosv2ray,iosvmess,iosvless,iosshadowsocks,iosshadowsocksr,iosshadowsocksrr,iosshadowrocket,iosquan,iosquanx,iossurge,ios小火箭,macss,macssr,macv2ray,macvmess,macvless,macshadowsocks,macshadowsocksr,macshadowsocksrr,macshadowrocket,macquan,macquanx,macsurge,mac小火箭,苹果ss,苹果ssr,苹果v2ray,苹果vmess,苹果vless,苹果shadowsocks,苹果shadowsocksr,苹果shadowsocksrr,苹果shadowrocket,苹果quan,苹果quanx,苹果surge,苹果小火箭,安卓ss,安卓ssr,安卓v2ray,安卓vmess,安卓vless,安卓shadowsocks,安卓shadowsocksr,安卓shadowsocksrr,安卓shadowrocket,安卓quan,安卓quanx,安卓surge,安卓小火箭">
<style type='text/css'>
body {
background-color: white;
color: #333333;
font-family: Arial, sans-serif;
margin: 0;
padding: 36px;
line-height: 1;
font-size: 14px;
}
.section {
margin-bottom: 36px;
}
.section.friendly {
color: #222222;
}
.section.friendly h1 {
font-size: 26px;
background-color: #dad8e4;
padding: 18px 22px 15px 22px;
margin: 0;
overflow: hidden;
}
.section.friendly h1 strong {
display: inline-block;
float: left;
}
.section.friendly h1 small {
display: inline-block;
float: right;
text-align: right;
font-size: 18px;
padding-top: 4px;
color: #333333;
}
.section.friendly .article {
border: 4px solid #dad8e4;
padding: 24px 18px 18px 18px;
}
.section.friendly .article h3 {
font-size: 20px;
margin: 0 0 18px 0;
}
.section.friendly .article a {
color: #6b6ceb;
}
.section.friendly .article a:visited {
color: #1d1d3b;
}
.section.friendly .article p {
font-size: 14px;
}
.section.friendly .article ul {
list-style-type: square;
}
.section.original {
background-color: #eeeeee;
color: #444444;
}
.section.original h2 {
background-color: #dddddd;
margin: 0;
padding: 18px 22px 18px 22px;
font-size: 20px;
}
.section.original pre {
margin: 0;
padding: 18px 22px 18px 22px;
overflow: auto;
font-family: monaco, monospaced;
}
.section.original pre code {
display: block;
font-size: 11px;
width: 100%;
}
</style>
</head>
<body>
<div class='container'>
<div class='section friendly'>
<h1><strong>免费节点</strong></h1>
<div class='article'>
<p>自动抓取tg频道、订阅地址、公开互联网上的ss、ssr、vmess、trojan节点信息聚合去重后提供节点列表每15分钟更新目前共有{{.getters_count}}个抓取源</p>
<p>汇总节点数量:{{ .all_proxies_count }}</p>
<p>ss节点数量{{ .ss_proxies_count }}</p>
<p>ssr节点数量{{ .ssr_proxies_count }}</p>
<p>vmess节点数量{{ .vmess_proxies_count }}</p>
<p>trojan节点数量{{ .trojan_proxies_count }}</p>
<p>可用节点数量:{{ .useful_proxies_count }}</p>
<p>最后更新时间:{{ .last_crawl_time }}</p>
<br>
<h4><a href="/clash">Clash</a></h4>
<p>Clash配置文件https://{{ .domain }}/clash/config <a
href="clash://install-config?url=https://{{ .domain }}/clash/config">一键导入</a></p>
<p>Clash proxy-provider(Shadowrocket添加订阅方式可用)<a href="https://{{ .domain }}/clash/proxies">https://{{ .domain }}/clash/proxies</a>
</p>
<p>筛选代理类型https://{{ .domain }}/clash/proxies?type=ss,ssr,vmess</p>
<p>筛选国家https://{{ .domain }}/clash/proxies?c=HK,TW,US</p>
<br>
<h4><a href="/surge">Surge</a></h4>
<p>Surge配置文件https://{{ .domain }}/surge/config <a
href="surge3:///install-config?url=https://{{ .domain }}/surge/config">一键导入</a></p>
<p>Surge proxy list<a href="https://{{ .domain }}/surge/proxies">https://{{ .domain }}/surge/proxies</a>
</p>
<br>
{{- /* 所有使用本代码提供服务的禁止删除该行*/}}
<p>欢迎关注tg频道<a href="https://t.me/peekfun">@peekfun</a></p>
<p>抓取程序已开源:<a href="https://github.com/zu1k/proxypool">https://github.com/zu1k/proxypool</a> {{ .version }}</p>
</div>
</div>
</div>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-DC6CR61FHE"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-DC6CR61FHE');
</script>
</body>
</html>

View File

@@ -1,45 +0,0 @@
[Proxy]
Direct = direct
[Proxy Group]
Proxy = select, 延迟最低, 失败切换, 手动选择
延迟最低 = url-test, policy-path=https://{{ .domain }}/surge/proxies, url=http://www.qualcomm.cn/generate_204, update-interval=3600, interval = 600s, tolerance = 100ms, timeout = 5s, evaluate-before-use = true
失败切换 = fallback, policy-path=https://{{ .domain }}/surge/proxies, url=http://www.qualcomm.cn/generate_204, update-interval=3600, interval = 600s, tolerance = 100ms, timeout = 5s, evaluate-before-use = true
手动选择 = select, policy-path=https://{{ .domain }}/surge/proxies, url=http://www.qualcomm.cn/generate_204, update-interval=3600, interval = 600s, tolerance = 100ms, timeout = 5s, evaluate-before-use = true
Apple = select, Direct, Proxy
Adblock = select, Direct, REJECT, REJECT-TINYGIF
[Rule]
# RULESET
RULE-SET,SYSTEM,Direct
#
# Unbreak 后续规则修正
RULE-SET,https://github.com/DivineEngine/Profiles/raw/master/Surge/Ruleset/Unbreak.list,Adblock
# Advertising 广告
RULE-SET,https://github.com/DivineEngine/Profiles/raw/master/Surge/Ruleset/Guard/Advertising.list,Adblock
# Privacy 隐私
# RULE-SET,https://github.com/DivineEngine/Profiles/raw/master/Surge/Ruleset/Guard/Privacy.list,Adblock
# Hijacking 运营商劫持或恶意网站
RULE-SET,https://github.com/DivineEngine/Profiles/raw/master/Surge/Ruleset/Guard/Hijacking.list,Adblock
#
# Apple
RULE-SET,https://github.com/DivineEngine/Profiles/raw/master/Surge/Ruleset/Extra/Apple/Apple.list,Apple
#
# 代理
# Streaming 国际流媒体服务
RULE-SET,https://github.com/DivineEngine/Profiles/raw/master/Surge/Ruleset/StreamingMedia/Streaming.list,Proxy
# StreamingSE 中国流媒体服务(面向海外版本)
RULE-SET,https://github.com/DivineEngine/Profiles/raw/master/Surge/Ruleset/StreamingMedia/StreamingSE.list,Proxy
# Global 全球加速
RULE-SET,https://github.com/DivineEngine/Profiles/raw/master/Surge/Ruleset/Global.list,Proxy
#
RULE-SET,https://github.com/Hackl0us/SS-Rule-Snippet/raw/master/Rulesets/App/social/Telegram.list,Proxy
RULE-SET,https://github.com/Hackl0us/SS-Rule-Snippet/raw/master/Rulesets/App/social/WhatsApp.list,Proxy
RULE-SET,https://github.com/Hackl0us/SS-Rule-Snippet/raw/master/Rulesets/App/social/LINE.list,Proxy
#
# Direct
RULE-SET,https://github.com/DivineEngine/Profiles/raw/master/Surge/Ruleset/Extra/ChinaIP.list,Direct
#
RULE-SET,LAN,Direct
# GEOIP,CN,Direct
FINAL,Proxy,dns-failed

View File

@@ -1,95 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="HandheldFriendly" content="True">
<title>免费Surge节点</title>
<style type='text/css'>
body {
background-color: white;
color: #333333;
font-family: Arial, sans-serif;
margin: 0;
padding: 36px;
line-height: 1;
font-size: 14px; }
.section {
margin-bottom: 36px; }
.section.friendly {
color: #222222; }
.section.friendly h1 {
font-size: 26px;
background-color: #dad8e4;
padding: 18px 22px 15px 22px;
margin: 0;
overflow: hidden; }
.section.friendly h1 strong {
display: inline-block;
float: left; }
.section.friendly h1 small {
display: inline-block;
float: right;
text-align: right;
font-size: 18px;
padding-top: 4px;
color: #333333; }
.section.friendly .article {
border: 4px solid #dad8e4;
padding: 24px 18px 18px 18px; }
.section.friendly .article h3 {
font-size: 20px;
margin: 0 0 18px 0; }
.section.friendly .article a {
color: #6b6ceb; }
.section.friendly .article a:visited {
color: #1d1d3b; }
.section.friendly .article p {
font-size: 14px; }
.section.friendly .article ul {
list-style-type: square; }
.section.original {
background-color: #eeeeee;
color: #444444; }
.section.original h2 {
background-color: #dddddd;
margin: 0;
padding: 18px 22px 18px 22px;
font-size: 20px; }
.section.original pre {
margin: 0;
padding: 18px 22px 18px 22px;
overflow: auto;
font-family: monaco, monospaced; }
.section.original pre code {
display: block;
font-size: 11px;
width: 100%; }
</style>
</head>
<body>
<div class='container'>
<div class='section friendly'>
<h1><strong>免费Surge节点</strong></h1>
<div class='article'>
<p>自动抓取tg频道、订阅地址、公开互联网上的ss、vmess节点信息聚合去重后提供Surge节点列表每15分钟更新</p>
<br>
<p>Surge配置文件https://{{ .domain }}/surge/config <a href="surge3:///install-config?url=https://{{ .domain }}/surge/config">一键导入</a></p>
<p>Surge proxy list<a href="https://{{ .domain }}/surge/proxies">https://{{ .domain }}/surge/proxies</a></p>
<br>
<p>抓取程序已开源:<a href="https://github.com/zu1k/proxypool">https://github.com/zu1k/proxypool</a></p>
</div>
</div>
</div>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-DC6CR61FHE"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-DC6CR61FHE');
</script>
</body>
</html>

View File

@@ -1,6 +1,13 @@
# your domain
domain: example.com
# cloudflare api
cf_email: ""
cf_key: ""
# source definition file
source-files:
- ./source.yaml
# use local file
- source.yaml
# use web file
- https://example.com/source.yaml

View File

@@ -20,9 +20,9 @@
num: 200
# 翻墙党论坛抓取
- type: web-fanqiangdang-rss
- type: web-fanqiangdang
options:
url: https://fanqiangdang.com/forum.php?mod=rss&fid=50&auth=0
url: https://fanqiangdang.com/forum-48-1.html
# 某个网站抓取
- type: web-freessrxyz

2
docs/genbindata.sh Normal file
View File

@@ -0,0 +1,2 @@
go-bindata -o internal/bindata/html/html.go -pkg binhtml assets/html/
go-bindata -o internal/bindata/geoip/geoip.go -pkg bingeoip assets/GeoLite2-City.mmdb assets/flags.json

View File

@@ -51,9 +51,9 @@ func CrawlGo() {
cache.LastCrawlTime = time.Now().In(location).Format("2006-01-02 15:04:05")
// 可用性检测
log.Println("Now check proxy health...")
log.Println("Now proceed proxy health check...")
proxies = proxy.CleanBadProxiesWithGrpool(proxies)
log.Println("CrawlGo clash usefull node count:", len(proxies))
log.Println("CrawlGo clash usable node count:", len(proxies))
proxies.NameReIndex()
cache.SetProxies("proxies", proxies)
cache.UsefullProxiesCount = proxies.Len()

View File

@@ -1,6 +1,7 @@
// Code generated for package bingeoip by go-bindata DO NOT EDIT. (@generated)
// sources:
// assets/GeoLite2-City.mmdb
// assets/flags.json
package bingeoip
import (
@@ -43,6 +44,24 @@ func assetsGeolite2CityMmdb() (*asset, error) {
return a, err
}
// assetsFlagsJson reads file data from disk. It returns an error on failure.
func assetsFlagsJson() (*asset, error) {
path := "assets/flags.json"
name := "assets/flags.json"
bytes, err := bindataRead(path, name)
if err != nil {
return nil, err
}
fi, err := os.Stat(path)
if err != nil {
err = fmt.Errorf("Error reading asset info %s at %s: %v", name, path, err)
}
a := &asset{bytes: bytes, info: fi}
return a, err
}
// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
@@ -96,6 +115,7 @@ func AssetNames() []string {
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
"assets/GeoLite2-City.mmdb": assetsGeolite2CityMmdb,
"assets/flags.json": assetsFlagsJson,
}
// AssetDir returns the file names below a certain
@@ -141,6 +161,7 @@ type bintree struct {
var _bintree = &bintree{nil, map[string]*bintree{
"assets": &bintree{nil, map[string]*bintree{
"GeoLite2-City.mmdb": &bintree{assetsGeolite2CityMmdb, map[string]*bintree{}},
"flags.json": &bintree{assetsFlagsJson, map[string]*bintree{}},
}},
}}

File diff suppressed because one or more lines are too long

View File

@@ -2,6 +2,7 @@ package getter
import (
"io/ioutil"
"log"
"strings"
"sync"
@@ -41,6 +42,7 @@ func (s *Subscribe) Get() proxy.ProxyList {
func (s *Subscribe) Get2Chan(pc chan proxy.Proxy, wg *sync.WaitGroup) {
defer wg.Done()
nodes := s.Get()
log.Printf("STATISTIC: Subscribe\tcount=%d\turl=%s\n", len(nodes), s.Url)
for _, node := range nodes {
pc <- node
}

View File

@@ -2,6 +2,7 @@ package getter
import (
"fmt"
"log"
"sync"
"github.com/gocolly/colly"
@@ -79,6 +80,7 @@ func (g *TGChannelGetter) Get() proxy.ProxyList {
func (g *TGChannelGetter) Get2Chan(pc chan proxy.Proxy, wg *sync.WaitGroup) {
defer wg.Done()
nodes := g.Get()
log.Printf("STATISTIC: TGChannel\tcount=%d\turl=%s\n", len(nodes), g.Url)
for _, node := range nodes {
pc <- node
}

View File

@@ -2,6 +2,7 @@ package getter
import (
"fmt"
"log"
"strings"
"sync"
@@ -11,7 +12,6 @@ import (
)
func init() {
Register("web-fanqiangdang-rss", NewWebFanqiangdangRSSGetter)
Register("web-fanqiangdang", NewWebFanqiangdangGetter)
}
@@ -65,54 +65,7 @@ func (w *WebFanqiangdang) Get() proxy.ProxyList {
func (w *WebFanqiangdang) Get2Chan(pc chan proxy.Proxy, wg *sync.WaitGroup) {
defer wg.Done()
nodes := w.Get()
for _, node := range nodes {
pc <- node
}
}
type WebFanqiangdangRSS struct {
c *colly.Collector
Url string
results []string
}
func NewWebFanqiangdangRSSGetter(options tool.Options) (getter Getter, err error) {
urlInterface, found := options["url"]
if found {
url, err := AssertTypeStringNotNull(urlInterface)
if err != nil {
return nil, err
}
return &WebFanqiangdangRSS{
c: tool.GetColly(),
Url: url,
}, nil
}
return nil, ErrorUrlNotFound
}
func (w *WebFanqiangdangRSS) Get() proxy.ProxyList {
w.results = make([]string, 0)
w.c.OnHTML("td.t_f", func(e *colly.HTMLElement) {
w.results = append(w.results, GrepLinksFromString(e.Text)...)
})
w.c.OnXML("//item//link", func(e *colly.XMLElement) {
_ = e.Request.Visit(e.Text)
})
w.results = make([]string, 0)
err := w.c.Visit(w.Url)
if err != nil {
_ = fmt.Errorf("%s", err.Error())
}
return StringArray2ProxyArray(w.results)
}
func (w *WebFanqiangdangRSS) Get2Chan(pc chan proxy.Proxy, wg *sync.WaitGroup) {
defer wg.Done()
nodes := w.Get()
log.Printf("STATISTIC: Fanqiangdang\tcount=%d\turl=%s\n", len(nodes), w.Url)
for _, node := range nodes {
pc <- node
}

View File

@@ -3,6 +3,7 @@ package getter
import (
"encoding/json"
"io/ioutil"
"log"
"sync"
"github.com/zu1k/proxypool/pkg/proxy"
@@ -34,6 +35,7 @@ func (w *WebFreessrXyz) Get() proxy.ProxyList {
func (w *WebFreessrXyz) Get2Chan(pc chan proxy.Proxy, wg *sync.WaitGroup) {
defer wg.Done()
nodes := w.Get()
log.Printf("STATISTIC: FreeSSRxyz\tcount=%d\turl=%s\n", len(nodes), "api.free-ssr.xyz")
for _, node := range nodes {
pc <- node
}

View File

@@ -2,6 +2,7 @@ package getter
import (
"io/ioutil"
"log"
"sync"
"github.com/zu1k/proxypool/pkg/proxy"
@@ -33,6 +34,7 @@ func (w *WebFuzz) Get() proxy.ProxyList {
func (w *WebFuzz) Get2Chan(pc chan proxy.Proxy, wg *sync.WaitGroup) {
defer wg.Done()
nodes := w.Get()
log.Printf("STATISTIC: WebFuzz\tcount=%d\turl=%s\n", len(nodes), w.Url)
for _, node := range nodes {
pc <- node
}

View File

@@ -2,6 +2,7 @@ package getter
import (
"io/ioutil"
"log"
"regexp"
"sync"
@@ -39,6 +40,7 @@ func (w *WebFuzzSub) Get() proxy.ProxyList {
func (w *WebFuzzSub) Get2Chan(pc chan proxy.Proxy, wg *sync.WaitGroup) {
defer wg.Done()
nodes := w.Get()
log.Printf("STATISTIC: WebFuzzSub\tcount=%d\turl=%s\n", len(nodes), w.Url)
for _, node := range nodes {
pc <- node
}

View File

@@ -7,9 +7,10 @@ import (
)
type Clash struct {
Proxies proxy.ProxyList `yaml:"proxies"`
Types string `yaml:"type"`
Country string `yaml:"country"`
Proxies proxy.ProxyList `yaml:"proxies"`
Types string `yaml:"type"`
Country string `yaml:"country"`
NotCountry string `yaml:"not_country"`
}
func (c Clash) CleanProxies() (proxies proxy.ProxyList) {
@@ -26,44 +27,63 @@ func (c Clash) Provide() string {
var resultBuilder strings.Builder
resultBuilder.WriteString("proxies:\n")
noNeedFilterType := false
noNeedFilterCountry := false
needFilterType := true
needFilterCountry := true
needFilterNotCountry := true
if c.Types == "" || c.Types == "all" {
noNeedFilterType = true
needFilterType = false
}
if c.Country == "" || c.Country == "all" {
noNeedFilterCountry = true
needFilterCountry = false
}
if c.NotCountry == "" {
needFilterNotCountry = false
}
types := strings.Split(c.Types, ",")
countries := strings.Split(c.Country, ",")
notCountries := strings.Split(c.NotCountry, ",")
for _, p := range c.Proxies {
if !checkClashSupport(p) {
continue
}
typeOk := false
countryOk := false
if !noNeedFilterType {
if needFilterType {
typeOk := false
for _, t := range types {
if p.TypeName() == t {
typeOk = true
break
}
}
if !typeOk {
goto exclude
}
}
if !noNeedFilterCountry {
for _, c := range countries {
if strings.HasPrefix(p.BaseInfo().Name, c) {
countryOk = true
break
if needFilterNotCountry {
for _, c := range notCountries {
if strings.Contains(p.BaseInfo().Name, c) {
goto exclude
}
}
}
if (noNeedFilterType || typeOk) && (noNeedFilterCountry || countryOk) {
resultBuilder.WriteString(p.ToClash() + "\n")
if needFilterCountry {
countryOk := false
for _, c := range countries {
if strings.Contains(p.BaseInfo().Name, c) {
countryOk = true
break
}
}
if !countryOk {
goto exclude
}
}
resultBuilder.WriteString(p.ToClash() + "\n")
exclude:
}
return resultBuilder.String()

View File

@@ -1,6 +1,9 @@
package proxy
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net"
"os"
@@ -16,27 +19,61 @@ func InitGeoIpDB() {
if err != nil {
panic(err)
}
geoIp = NewGeoIP("assets/GeoLite2-City.mmdb")
err = bingeoip.RestoreAsset("", "assets/flags.json")
if err != nil {
panic(err)
}
geoIp = NewGeoIP("assets/GeoLite2-City.mmdb", "assets/flags.json")
}
// GeoIP2
type GeoIP struct {
db *geoip2.Reader
db *geoip2.Reader
emojiMap map[string]string
}
type CountryEmoji struct {
Code string `json:"code"`
Emoji string `json:"emoji"`
}
// new geoip from db file
func NewGeoIP(filePath string) (geoip GeoIP) {
func NewGeoIP(geodb, flags string) (geoip GeoIP) {
// 判断文件是否存在
_, err := os.Stat(filePath)
_, err := os.Stat(geodb)
if err != nil && os.IsNotExist(err) {
log.Println("文件不存在,请自行下载 Geoip2 City库并保存在", filePath)
log.Println("文件不存在,请自行下载 Geoip2 City库并保存在", geodb)
os.Exit(1)
} else {
db, err := geoip2.Open(filePath)
db, err := geoip2.Open(geodb)
if err != nil {
log.Fatal(err)
}
geoip = GeoIP{db: db}
geoip.db = db
}
_, err = os.Stat(flags)
if err != nil && os.IsNotExist(err) {
log.Println("flags 文件不存在,请自行下载 flags.json并保存在", flags)
os.Exit(1)
} else {
data, err := ioutil.ReadFile(flags)
if err != nil {
log.Fatal(err)
return
}
var countryEmojiList = make([]CountryEmoji, 0)
err = json.Unmarshal(data, &countryEmojiList)
if err != nil {
log.Fatalln(err.Error())
return
}
emojiMap := make(map[string]string)
for _, i := range countryEmojiList {
emojiMap[i.Code] = i.Emoji
}
geoip.emojiMap = emojiMap
}
return
}
@@ -47,10 +84,22 @@ func (g GeoIP) Find(ipORdomain string) (ip, country string, err error) {
if err != nil {
return "", "", err
}
ipData := net.ParseIP(ips[0].String())
record, err := g.db.City(ipData)
ip = ips[0].String()
var record *geoip2.City
record, err = g.db.City(ips[0])
if err != nil {
return "", "", err
return
}
return ips[0].String(), record.Country.IsoCode, nil
countryIsoCode := record.Country.IsoCode
if countryIsoCode == "" {
country = fmt.Sprintf("🏁 ZZ")
}
emoji, found := g.emojiMap[countryIsoCode]
if found {
country = fmt.Sprintf("%v %v", emoji, countryIsoCode)
} else {
country = fmt.Sprintf("🏁 ZZ")
}
return
}

View File

@@ -3,6 +3,7 @@ package proxy
import (
"fmt"
"sort"
"strings"
"sync"
)
@@ -71,8 +72,8 @@ func (ps ProxyList) NameAddCounrty() ProxyList {
go func() {
defer wg.Done()
_, country, err := geoIp.Find(ps[ii].BaseInfo().Server)
if err != nil || country == "" {
country = "ZZ"
if err != nil {
country = "🏁 ZZ"
}
ps[ii].SetName(fmt.Sprintf("%s", country))
//ps[ii].SetIP(ip)
@@ -85,7 +86,7 @@ func (ps ProxyList) NameAddCounrty() ProxyList {
func (ps ProxyList) NameAddIndex() ProxyList {
num := len(ps)
for i := 0; i < num; i++ {
ps[i].SetName(fmt.Sprintf("%s_%d", ps[i].BaseInfo().Name, i+1))
ps[i].SetName(fmt.Sprintf("%s_%+02v", ps[i].BaseInfo().Name, i+1))
}
return ps
}
@@ -94,8 +95,8 @@ func (ps ProxyList) NameReIndex() ProxyList {
num := len(ps)
for i := 0; i < num; i++ {
originName := ps[i].BaseInfo().Name
country := string([]rune(originName)[:2])
ps[i].SetName(fmt.Sprintf("%s_%d", country, i+1))
country := strings.SplitN(originName, "_", 2)[0]
ps[i].SetName(fmt.Sprintf("%s_%+02v", country, i+1))
}
return ps
}