mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-09-13 20:04:45 +08:00
350 lines
11 KiB
Lua
350 lines
11 KiB
Lua
|
|
local m, s, o
|
|
local openclash = "openclash"
|
|
local uci = luci.model.uci.cursor()
|
|
local fs = require "luci.openclash"
|
|
local sys = require "luci.sys"
|
|
local json = require "luci.jsonc"
|
|
local HTTP = require "luci.http"
|
|
local DISP = require "luci.dispatcher"
|
|
local sid = arg[1]
|
|
local age_section
|
|
local backend_version_status = [[
|
|
<div class="oc">
|
|
<div id="subconverter-version-status-cbi" class="subconverter-version-status" data-state="idle" hidden>
|
|
<span class="subconverter-version-label"></span>
|
|
<span class="subconverter-version-text"></span>
|
|
</div>
|
|
</div>
|
|
]]
|
|
|
|
font_red = [[<b style=color:red>]]
|
|
font_off = [[</b>]]
|
|
bold_on = [[<strong>]]
|
|
bold_off = [[</strong>]]
|
|
|
|
|
|
m = Map(openclash, translate("Config Subscribe Edit"))
|
|
m.pageaction = false
|
|
m.description=translate("Convert Subscribe function of Online is Supported By subconverter Written By tindy X") ..
|
|
"<br/>"..
|
|
"<br/>"..translate("Subconverter external configuration (subscription conversion template) Description: https://github.com/tindy2013/subconverter#external-configuration-file")..
|
|
"<br/>"..
|
|
"<br/>"..translate("If you need to customize the external configuration file (subscription conversion template), please write it according to the instructions, upload it to the accessible location of the external network, and fill in the address correctly when using it")..
|
|
"<br/>"..
|
|
"<br/>"..translate("If you have a recommended external configuration file (subscription conversion template), you can modify by following The file format of /usr/share/openclash/res/sub_ini.list and pr")
|
|
m.redirect = DISP.build_url("admin/services/openclash/config-subscribe")
|
|
if m.uci:get(openclash, sid) ~= "config_subscribe" then
|
|
HTTP.redirect(m.redirect)
|
|
return
|
|
end
|
|
|
|
-- [[ Config Subscribe Setting ]]--
|
|
s = m:section(NamedSection, sid, "config_subscribe")
|
|
s.anonymous = true
|
|
s.addremove = false
|
|
|
|
---- name
|
|
o = s:option(Value, "name", translate("Config Alias"))
|
|
o.description = font_red..bold_on..translate("Name For Distinguishing")..bold_off..font_off
|
|
o.placeholder = translate("config")
|
|
o.rmempty = true
|
|
|
|
---- address
|
|
o = s:option(Value, "address", translate("Subscribe Address"))
|
|
o.template = "cbi/tvalue"
|
|
o.rows = 10
|
|
o.wrap = "off"
|
|
o.description = font_red..bold_on..translate("SS/SSR/Vmess or Other Link And Subscription Address is Supported When Online Subscription Conversion is Enabled, Multiple Links Should be One Per Line or Separated By |")..bold_off..font_off
|
|
o.placeholder = translate("Not Null")
|
|
o.rmempty = false
|
|
function o.validate(self, value)
|
|
if value then
|
|
value = value:gsub("\r\n?", "\n")
|
|
value = value:gsub("%c*$", "")
|
|
end
|
|
return value
|
|
end
|
|
|
|
---- UA
|
|
o = s:option(Value, "sub_ua", "User-Agent")
|
|
o.default = "clash-verge/v2.4.5"
|
|
o.description = font_red..bold_on..translate("Used for Downloading Subscriptions, Defaults to").." "..o.default..bold_off..font_off
|
|
o:value("clash-verge/v2.4.5")
|
|
o:value("clash.meta/1.19.20")
|
|
o:value("Clash")
|
|
o.rmempty = true
|
|
|
|
---- Custom Headers
|
|
o = s:option(DynamicList, "sub_headers", translate("Custom Headers"))
|
|
o.description = font_red..bold_on..translate("Custom HTTP request headers, one per line, format: Header-Name: value")..bold_off..font_off
|
|
o.rmempty = true
|
|
o.placeholder = "x-hwid: my-device-id"
|
|
|
|
o = s:option(ListValue, "config_age_algo", translate("Age Key Type"))
|
|
o.description = font_red..bold_on..translate("Age Encryption For Config, Click For More:")..bold_off..font_off.." ".."<a href='javascript:void(0)' onclick='javascript:return winOpen(\"https://wiki.metacubex.one/config/proxy-providers/?age-secret-key#age-secret-key\")'>"..translate("Age Encryption Introduce").."</a>"
|
|
o:value("keygen", "x25519")
|
|
o:value("pq", "PQ (mlkem768-x25519)")
|
|
o.rmempty = true
|
|
function o.cfgvalue(self, section)
|
|
local name = m.uci:get(openclash, section, "name") or section
|
|
local v = ""
|
|
m.uci:foreach(openclash, "config_age_secret", function(s)
|
|
if s.name == name then
|
|
v = s.algo or ""
|
|
age_section = s['.name']
|
|
return false
|
|
end
|
|
end)
|
|
return v
|
|
end
|
|
function o.write(self, section, value)
|
|
local name = m.uci:get(openclash, section, "name") or section
|
|
m.uci:foreach(openclash, "config_age_secret", function(s)
|
|
if s.name == name then
|
|
age_section = s['.name']
|
|
return false
|
|
end
|
|
end)
|
|
if not age_section and value and value ~= "" then
|
|
age_section = m.uci:add(openclash, "config_age_secret")
|
|
if age_section then m.uci:set(openclash, age_section, "name", name) end
|
|
end
|
|
if age_section then
|
|
if value and value ~= "" then
|
|
m.uci:set(openclash, age_section, "algo", value)
|
|
else
|
|
m.uci:delete(openclash, age_section, "algo")
|
|
end
|
|
end
|
|
end
|
|
function o.remove(self, section)
|
|
self:write(section, "")
|
|
end
|
|
|
|
o = s:option(Value, "config_age_secret", translate("Secret Key"))
|
|
o.rmempty = true
|
|
o.placeholder = "AGE-SECRET-KEY-..."
|
|
function o.cfgvalue(self, section)
|
|
local name = m.uci:get(openclash, section, "name") or section
|
|
local v = ""
|
|
m.uci:foreach(openclash, "config_age_secret", function(s)
|
|
if s.name == name then
|
|
v = s.secret or ""
|
|
age_section = s['.name']
|
|
return false
|
|
end
|
|
end)
|
|
return v
|
|
end
|
|
function o.write(self, section, value)
|
|
local name = m.uci:get(openclash, section, "name") or section
|
|
m.uci:foreach(openclash, "config_age_secret", function(s)
|
|
if s.name == name then
|
|
age_section = s['.name']
|
|
return false
|
|
end
|
|
end)
|
|
if not age_section and value and value ~= "" then
|
|
age_section = m.uci:add(openclash, "config_age_secret")
|
|
if age_section then m.uci:set(openclash, age_section, "name", name) end
|
|
end
|
|
if age_section then
|
|
if value and value ~= "" then
|
|
m.uci:set(openclash, age_section, "secret", value)
|
|
else
|
|
m.uci:delete(openclash, age_section, "secret")
|
|
end
|
|
end
|
|
end
|
|
function o.remove(self, section)
|
|
self:write(section, "")
|
|
end
|
|
|
|
o = s:option(Value, "config_age_public", translate("Public Key"))
|
|
o.rmempty = true
|
|
o.placeholder = "age..."
|
|
function o.cfgvalue(self, section)
|
|
local name = m.uci:get(openclash, section, "name") or section
|
|
local v = ""
|
|
m.uci:foreach(openclash, "config_age_secret", function(s)
|
|
if s.name == name then
|
|
v = s.public or ""
|
|
age_section = s['.name']
|
|
return false
|
|
end
|
|
end)
|
|
return v
|
|
end
|
|
function o.write(self, section, value)
|
|
local name = m.uci:get(openclash, section, "name") or section
|
|
m.uci:foreach(openclash, "config_age_secret", function(s)
|
|
if s.name == name then
|
|
age_section = s['.name']
|
|
return false
|
|
end
|
|
end)
|
|
if not age_section and value and value ~= "" then
|
|
age_section = m.uci:add(openclash, "config_age_secret")
|
|
if age_section then m.uci:set(openclash, age_section, "name", name) end
|
|
end
|
|
if age_section then
|
|
if value and value ~= "" then
|
|
m.uci:set(openclash, age_section, "public", value)
|
|
else
|
|
m.uci:delete(openclash, age_section, "public")
|
|
end
|
|
end
|
|
end
|
|
function o.remove(self, section)
|
|
self:write(section, "")
|
|
end
|
|
|
|
o = s:option(DummyValue, "_generate_age_btn", "")
|
|
o.template = "openclash/generate_age"
|
|
|
|
---- subconverter
|
|
o = s:option(Flag, "sub_convert", translate("Subscribe Convert Online"))
|
|
o.description = translate("Convert Subscribe Online With Template")
|
|
o.default = 0
|
|
|
|
---- Convert Address
|
|
o = s:option(Value, "convert_address", translate("Convert Address"))
|
|
o.rmempty = true
|
|
o.description = backend_version_status..font_red..bold_on..translate("Note: There is A Risk of Privacy Leakage in Online Convert")..bold_off..font_off
|
|
o:depends("sub_convert", "1")
|
|
o:value("https://api.asailor.org/sub", translate("api.asailor.org"))
|
|
o:value("https://api.wcc.best/sub", translate("api.wcc.best"))
|
|
o.default = "https://api.asailor.org/sub"
|
|
o.placeholder = "https://api.asailor.org/sub"
|
|
|
|
---- Template
|
|
o = s:option(ListValue, "template", translate("Template Name"))
|
|
o.rmempty = true
|
|
o:depends("sub_convert", "1")
|
|
file = io.open("/usr/share/openclash/res/sub_ini.list", "r");
|
|
for l in file:lines() do
|
|
if l ~= "" and l ~= nil then
|
|
o:value(string.sub(luci.sys.exec(string.format("echo '%s' |awk -F ',' '{print $1}' 2>/dev/null",l)),1,-2))
|
|
end
|
|
end
|
|
file:close()
|
|
o:value("0", translate("Custom Template"))
|
|
|
|
---- Custom Template
|
|
o = s:option(Value, "custom_template_url", translate("Custom Template URL"))
|
|
o.rmempty = true
|
|
o.placeholder = translate("Not Null")
|
|
o.datatype = "or(host, string)"
|
|
o:depends("template", "0")
|
|
|
|
---- emoji
|
|
o = s:option(ListValue, "emoji", translate("Emoji"))
|
|
o.rmempty = false
|
|
o:value("false", translate("Disable"))
|
|
o:value("true", translate("Enable"))
|
|
o.default = "false"
|
|
o:depends("sub_convert", "1")
|
|
|
|
---- udp
|
|
o = s:option(ListValue, "udp", translate("UDP Enable"))
|
|
o.rmempty = false
|
|
o:value("false", translate("Disable"))
|
|
o:value("true", translate("Enable"))
|
|
o.default = "false"
|
|
o:depends("sub_convert", "1")
|
|
|
|
---- skip-cert-verify
|
|
o = s:option(ListValue, "skip_cert_verify", translate("skip-cert-verify"))
|
|
o.rmempty = false
|
|
o:value("false", translate("Disable"))
|
|
o:value("true", translate("Enable"))
|
|
o.default = "false"
|
|
o:depends("sub_convert", "1")
|
|
|
|
---- sort
|
|
o = s:option(ListValue, "sort", translate("Sort"))
|
|
o.rmempty = false
|
|
o:value("false", translate("Disable"))
|
|
o:value("true", translate("Enable"))
|
|
o.default = "false"
|
|
o:depends("sub_convert", "1")
|
|
|
|
---- node type
|
|
o = s:option(ListValue, "node_type", translate("Append Node Type"))
|
|
o.rmempty = false
|
|
o:value("false", translate("Disable"))
|
|
o:value("true", translate("Enable"))
|
|
o.default = "false"
|
|
o:depends("sub_convert", "1")
|
|
|
|
---- rule provider
|
|
o = s:option(ListValue, "rule_provider", translate("Use Rule Provider"))
|
|
o.description = font_red..bold_on..translate("Note: Please Make Sure Backend Service Supports This Feature")..bold_off..font_off
|
|
o.rmempty = false
|
|
o:value("false", translate("Disable"))
|
|
o:value("true", translate("Enable"))
|
|
o.default = "false"
|
|
o:depends("sub_convert", "1")
|
|
|
|
---- custom params
|
|
o = s:option(DynamicList, "custom_params", translate("Custom Params"))
|
|
o.description = font_red..bold_on..translate("eg: \"rename=match@replace\" , \"rename=\\s+([2-9])[xX]@ (HIGH:$1)\"")..bold_off..font_off
|
|
o.rmempty = false
|
|
o:depends("sub_convert", "1")
|
|
|
|
---- key
|
|
o = s:option(DynamicList, "keyword", font_red..bold_on..translate("Keyword Match")..bold_off..font_off)
|
|
o.description = font_red..bold_on..translate("eg: hk or tw&bgp")..bold_off..font_off
|
|
o.rmempty = true
|
|
|
|
---- exkey
|
|
o = s:option(DynamicList, "ex_keyword", font_red..bold_on..translate("Exclude Keyword Match")..bold_off..font_off)
|
|
o.description = font_red..bold_on..translate("eg: hk or tw&bgp")..bold_off..font_off
|
|
o.rmempty = true
|
|
|
|
---- de_exkey
|
|
o = s:option(MultiValue, "de_ex_keyword", font_red..bold_on..translate("Exclude Keyword Match Default")..bold_off..font_off)
|
|
o.rmempty = true
|
|
o:value(translate("Expire"))
|
|
o:value(translate("Traffic"))
|
|
o:value(translate("Plan"))
|
|
o:value(translate("Official"))
|
|
|
|
local t = {
|
|
{Commit, Back}
|
|
}
|
|
a = m:section(Table, t)
|
|
|
|
o = a:option(Button,"Commit", " ")
|
|
o.inputtitle = translate("Commit Settings")
|
|
o.inputstyle = "apply"
|
|
o.write = function()
|
|
local to_delete = {}
|
|
m.uci:foreach(openclash, "config_age_secret", function(s)
|
|
local pub = m.uci:get(openclash, s['.name'], "public") or ""
|
|
local sec = m.uci:get(openclash, s['.name'], "secret") or ""
|
|
if (pub == "" or pub == nil) and (sec == "" or sec == nil) then
|
|
table.insert(to_delete, s['.name'])
|
|
end
|
|
end)
|
|
for _, n in ipairs(to_delete) do
|
|
m.uci:delete(openclash, n)
|
|
end
|
|
m.uci:commit(openclash)
|
|
HTTP.redirect(m.redirect)
|
|
end
|
|
|
|
o = a:option(Button,"Back", " ")
|
|
o.inputtitle = translate("Back Settings")
|
|
o.inputstyle = "reset"
|
|
o.write = function()
|
|
m.uci:revert(openclash, sid)
|
|
m.uci:revert(openclash, age_section)
|
|
HTTP.redirect(m.redirect)
|
|
end
|
|
|
|
m:append(Template("openclash/toolbar_show"))
|
|
m:append(Template("openclash/subconverter_version"))
|
|
return m
|