mirror of
https://github.com/vvbbnn00/WARP-Clash-API.git
synced 2026-06-12 21:02:18 +08:00
feat: Add support for selecting 'proxy & proxy group' and 'only proxy' subscription return formats, passed through URL parameters. Additionally, consider deprecating the original 'only_proxy' interface in the future.
This commit is contained in:
parent
a3bebe3d65
commit
ae6d43da73
@ -29,12 +29,12 @@ GEOIP = GeoIP('./config/geolite/GeoLite2-Country.mmdb')
|
||||
def generateClashSubFile(account: Account = None,
|
||||
logger=logging.getLogger(__name__),
|
||||
best=False,
|
||||
only_proxies=False,
|
||||
proxy_format='full',
|
||||
random_name=False):
|
||||
"""
|
||||
Generate Clash subscription file
|
||||
:param random_name: Whether to use random name
|
||||
:param only_proxies: If this is True, only generate proxies
|
||||
:param proxy_format: full - full config, with_groups - only proxies and proxy-groups, only_proxies - only proxies
|
||||
:param account:
|
||||
:param logger:
|
||||
:param best: Whether to use the best entrypoints
|
||||
@ -74,8 +74,12 @@ def generateClashSubFile(account: Account = None,
|
||||
proxy_group["proxies"] += [proxy["name"] for proxy in user_config]
|
||||
|
||||
# Generate YAML file
|
||||
if only_proxies:
|
||||
clash_yaml = yaml.dump({'proxies': clash_json['proxies'], 'proxy-groups': clash_json['proxy-groups']},
|
||||
if proxy_format == 'only_proxies':
|
||||
clash_yaml = yaml.dump({'proxies': clash_json['proxies']},
|
||||
allow_unicode=True)
|
||||
elif proxy_format == 'with_groups':
|
||||
clash_yaml = yaml.dump({'proxies': clash_json['proxies'],
|
||||
'proxy-groups': clash_json['proxy-groups']},
|
||||
allow_unicode=True)
|
||||
else:
|
||||
clash_yaml = yaml.dump(clash_json, allow_unicode=True)
|
||||
@ -115,12 +119,12 @@ PersistentKeepalive = 25
|
||||
def generateSurgeSubFile(account: Account = None,
|
||||
logger=logging.getLogger(__name__),
|
||||
best=False,
|
||||
only_proxies=False,
|
||||
proxy_format='full',
|
||||
random_name=False):
|
||||
"""
|
||||
Generate Surge subscription file
|
||||
:param random_name: Whether to use random name
|
||||
:param only_proxies: If this is True, only generate proxies
|
||||
:param proxy_format: full - full config, with_groups - only proxies and proxy-groups, only_proxies - only proxies
|
||||
:param account:
|
||||
:param logger:
|
||||
:param best: Whether to use the best entrypoints
|
||||
@ -174,7 +178,7 @@ def generateSurgeSubFile(account: Account = None,
|
||||
surge_ini = temp_file.read()
|
||||
|
||||
# Generate INI file
|
||||
if only_proxies:
|
||||
if proxy_format == 'with_groups' or proxy_format == 'only_proxies':
|
||||
pass
|
||||
else:
|
||||
surge_ini += SURGE_RULE
|
||||
|
||||
@ -121,9 +121,14 @@ def attachEndpoints(app: Flask):
|
||||
account = getCurrentAccount(logger)
|
||||
best = request.args.get('best', 'false').lower() == "true" or False
|
||||
random_name = request.args.get('randomName', 'false').lower() == "true" or False
|
||||
proxy_format = request.args.get('proxyFormat', 'full').lower()
|
||||
|
||||
if sub_type == "clash": # Clash
|
||||
fileData = generateClashSubFile(account, logger, best=best, only_proxies=False, random_name=random_name)
|
||||
fileData = generateClashSubFile(account,
|
||||
logger,
|
||||
best=best,
|
||||
proxy_format=proxy_format,
|
||||
random_name=random_name)
|
||||
headers = {
|
||||
'Content-Type': 'application/x-yaml; charset=utf-8',
|
||||
'Content-Disposition': f'attachment; filename=Clash-{fake.color_name()}.yaml',
|
||||
@ -137,7 +142,11 @@ def attachEndpoints(app: Flask):
|
||||
'Content-Disposition': f'attachment; filename={fake.lexify("????????????").lower()}.conf'
|
||||
}
|
||||
elif sub_type == "surge": # Surge
|
||||
fileData = generateSurgeSubFile(account, logger, best=best, random_name=random_name)
|
||||
fileData = generateSurgeSubFile(account,
|
||||
logger,
|
||||
best=best,
|
||||
random_name=random_name,
|
||||
proxy_format=proxy_format)
|
||||
headers = {
|
||||
'Content-Type': 'text/plain; charset=utf-8',
|
||||
'Content-Disposition': 'attachment; filename=surge.conf',
|
||||
@ -152,8 +161,10 @@ def attachEndpoints(app: Flask):
|
||||
"Subscription-Userinfo": f"upload=0; download={account.usage}; total={account.quota}; "
|
||||
f"expire=253388144714"
|
||||
}
|
||||
# This might be deprecated in the future.
|
||||
elif sub_type == "only_proxies": # Only proxies
|
||||
fileData = generateClashSubFile(account, logger, best=best, only_proxies=True, random_name=random_name)
|
||||
fileData = generateClashSubFile(account, logger, best=best, proxy_format='with_groups',
|
||||
random_name=random_name)
|
||||
headers = {
|
||||
'Content-Type': 'application/x-yaml; charset=utf-8',
|
||||
'Content-Disposition': f'attachment; filename=Clash-{fake.color_name()}.yaml',
|
||||
|
||||
@ -59,8 +59,10 @@
|
||||
border: none;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
textarea:focus {
|
||||
@ -101,10 +103,10 @@
|
||||
</div>
|
||||
|
||||
<h1>WARP Clash 订阅地址生成器</h1>
|
||||
<form>
|
||||
<form action="javascript:generateLink()">
|
||||
<div>
|
||||
<label for="passwordInput"></label>
|
||||
<input type="password" id="passwordInput" placeholder="输入您的SECRET_KEY" oninput="generateLink()">
|
||||
<input type="password" name="password" id="passwordInput" placeholder="输入您的SECRET_KEY">
|
||||
</div>
|
||||
<div>
|
||||
<label>
|
||||
@ -114,30 +116,32 @@
|
||||
<input type="checkbox" id="randomName" onchange="generateLink()" checked> 随机节点名称
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<br/>
|
||||
<label for="proxyFormat">订阅格式:</label>
|
||||
<select id="proxyFormat" onchange="generateLink()">
|
||||
<option value="full">完整订阅</option>
|
||||
<option value="with_groups">Proxies & Proxy Groups</option>
|
||||
<option value="only_proxies">仅包含Proxies</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
<center>
|
||||
<h2>自动判断订阅类型</h2>
|
||||
<textarea id="autoSubscriptionLink" rows="1" readonly onclick="copyText('autoSubscriptionLink')"></textarea>
|
||||
<textarea id="autoSubscriptionLink" rows="3" readonly onclick="copyText('autoSubscriptionLink')"></textarea>
|
||||
<div id="qrcode_auto"></div>
|
||||
<h2>Clash</h2>
|
||||
<textarea id="subscriptionLink" rows="1" readonly onclick="copyText('subscriptionLink')"></textarea>
|
||||
<textarea id="subscriptionLink" rows="3" readonly onclick="copyText('subscriptionLink')"></textarea>
|
||||
<div id="qrcode_clash"></div>
|
||||
<h2>ShadowRocket</h2>
|
||||
<textarea id="subShadowRocketSubscriptionLink" rows="1" readonly
|
||||
<textarea id="subShadowRocketSubscriptionLink" rows="3" readonly
|
||||
onclick="copyText('subShadowRocketSubscriptionLink')"></textarea>
|
||||
<div id="qrcode_sr"></div>
|
||||
<h2>Surge</h2>
|
||||
<textarea id="subSurgeScriptionLink" rows="1" readonly onclick="copyText('subSurgeScriptionLink')"></textarea>
|
||||
<textarea id="subSurgeScriptionLink" rows="3" readonly onclick="copyText('subSurgeScriptionLink')"></textarea>
|
||||
<h2>Wireguard</h2>
|
||||
<textarea id="WireguardLink" rows="1" readonly onclick="copyText('WireguardLink')"></textarea>
|
||||
<textarea id="WireguardLink" rows="3" readonly onclick="copyText('WireguardLink')"></textarea>
|
||||
<div id="qrcode_wg"></div>
|
||||
<h2>Only Proxies & Proxies Group</h2>
|
||||
<div class="tip">
|
||||
该链接仅包含节点信息,不包含规则信息,适用于自定义规则的用户。
|
||||
</div>
|
||||
<textarea id="onlyProxyLink" rows="1" readonly onclick="copyText('onlyProxyLink')"></textarea>
|
||||
<a onclick="getOnlyProxy()" href="javascript:">点击复制节点信息</a>
|
||||
<textarea id="onlyProxyInfo" rows="0" style="height: 0; width: 0;"></textarea>
|
||||
<h2>账户信息</h2>
|
||||
<a href="#" title="账户信息" target="_blank" id="AccountLink">点击查看</a>
|
||||
</center>
|
||||
@ -155,10 +159,12 @@
|
||||
const password = document.getElementById('passwordInput').value;
|
||||
const best = document.getElementById('alwaysBest').checked;
|
||||
const randomName = document.getElementById('randomName').checked;
|
||||
const proxyFormat = document.getElementById('proxyFormat').value;
|
||||
const baseUrl = location.protocol + '//' + location.host + '/';
|
||||
const queryParams = new URLSearchParams({
|
||||
best,
|
||||
randomName
|
||||
randomName,
|
||||
proxyFormat
|
||||
});
|
||||
|
||||
if (password.length) {
|
||||
@ -171,7 +177,6 @@
|
||||
document.getElementById('subSurgeScriptionLink').textContent = baseUrl + "api/surge?" + queryParams.toString();
|
||||
document.getElementById('WireguardLink').textContent = baseUrl + "api/wireguard?" + queryParams.toString();
|
||||
document.getElementById('AccountLink').href = baseUrl + "api/account?" + queryParams.toString();
|
||||
document.getElementById('onlyProxyLink').textContent = baseUrl + "api/only_proxies?" + queryParams.toString();
|
||||
|
||||
const qrcodeContainerClash = document.getElementById('qrcode_clash');
|
||||
qrcodeContainerClash.innerHTML = '';
|
||||
@ -217,18 +222,6 @@
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function getOnlyProxy() {
|
||||
const url = document.getElementById('onlyProxyLink').textContent;
|
||||
fetch(url, {
|
||||
method: 'GET',
|
||||
}).then(res => res.text()).then(res => {
|
||||
document.getElementById('onlyProxyInfo').textContent = res;
|
||||
copyText('onlyProxyInfo');
|
||||
}).catch(err => {
|
||||
showToast(`Error ${err.status}: ${err.statusText}`)
|
||||
});
|
||||
}
|
||||
|
||||
function getQrCodeWg() {
|
||||
const qrcodeContainerWg = document.getElementById('qrcode_wg');
|
||||
const url = document.getElementById('WireguardLink').textContent;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user