mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-08 05:04:21 +08:00
🌈 Sync 2026-08-11 02:29:57
This commit is contained in:
1 parent
f8bdc4459f
commit
412c262edf
73 files changed
+9791
-5915
No files matched your search
@@ -0,0 +1,644 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
require "nixio"
|
||||
require "luci.model.uci"
|
||||
local fs = require "luci.openclash"
|
||||
local json = require "luci.jsonc"
|
||||
|
||||
local M = {}
|
||||
|
||||
local VERSION_CACHE_FILE = "/tmp/openclash_version_history.json"
|
||||
local CDN_CACHE_FILE = "/tmp/openclash_cdn_info.json"
|
||||
|
||||
local function trim(s)
|
||||
if not s then return "" end
|
||||
return (s:gsub("^%s+", ""):gsub("%s+$", ""))
|
||||
end
|
||||
|
||||
function M.is_valid_version(s)
|
||||
if not s or s == "" then return false end
|
||||
s = trim(s)
|
||||
if s == "" then return false end
|
||||
if s:match("^<") then return false end
|
||||
return true
|
||||
end
|
||||
|
||||
function M.is_oix_mode()
|
||||
local oix_token = fs.uci_get_config("config", "oix_token") or ""
|
||||
return oix_token ~= ""
|
||||
end
|
||||
|
||||
function try_read(fd, maxlen)
|
||||
local pfds = {
|
||||
{ fd = fd, events = nixio.poll_flags("in", "hup", "err") }
|
||||
}
|
||||
local nfds = nixio.poll(pfds, 0)
|
||||
if nfds and nfds > 0 then
|
||||
local buf = fd:read(maxlen or 4096)
|
||||
if buf and #buf > 0 then
|
||||
return buf
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function read_json(path)
|
||||
if not fs.access(path) then return nil end
|
||||
local raw = fs.readfile(path)
|
||||
if not raw or raw == "" then return nil end
|
||||
local ok, parsed = pcall(json.parse, raw)
|
||||
if ok and parsed and type(parsed) == "table" then
|
||||
return parsed
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function write_json(path, data)
|
||||
local tmp = path .. ".tmp"
|
||||
fs.writefile(tmp, json.stringify(data))
|
||||
os.rename(tmp, path)
|
||||
end
|
||||
|
||||
local function read_version_cache()
|
||||
return read_json(VERSION_CACHE_FILE)
|
||||
end
|
||||
|
||||
local function update_version_cache(updater)
|
||||
local parsed = read_version_cache() or {}
|
||||
updater(parsed)
|
||||
write_json(VERSION_CACHE_FILE, parsed)
|
||||
end
|
||||
|
||||
local DEFAULT_CDN_LIST = {
|
||||
"https://ghfast.top/",
|
||||
"https://github.dpik.top/",
|
||||
"https://gh-proxy.com/",
|
||||
"https://git.yylx.win/"
|
||||
}
|
||||
|
||||
local function cdn_list()
|
||||
local list = fs.cdn_list()
|
||||
if #list > 0 then return list end
|
||||
return DEFAULT_CDN_LIST
|
||||
end
|
||||
|
||||
local function raw_url(path)
|
||||
return "https://raw.githubusercontent.com/vernesong/OpenClash/" .. path
|
||||
end
|
||||
|
||||
local function build_fetch_urls(mod, path)
|
||||
if mod == "0" or mod == "" then
|
||||
local urls = { raw_url(path) }
|
||||
for _, cdn in ipairs(cdn_list()) do
|
||||
urls[#urls + 1] = cdn .. raw_url(path)
|
||||
end
|
||||
return urls
|
||||
end
|
||||
if mod == "https://cdn.jsdelivr.net/" or mod == "https://fastly.jsdelivr.net/" or mod == "https://testingcf.jsdelivr.net/" then
|
||||
return { mod .. "gh/vernesong/OpenClash@" .. path }
|
||||
end
|
||||
return { mod .. raw_url(path) }
|
||||
end
|
||||
|
||||
local function fork_curl(url, timeout)
|
||||
local fdi, fdo = nixio.pipe()
|
||||
if not fdi or not fdo then return nil end
|
||||
local cmd = string.format('curl -sL -m %d "%s" 2>/dev/null', timeout or 5, url)
|
||||
local child = nixio.fork()
|
||||
if child > 0 then
|
||||
fdo:close()
|
||||
return { pid = child, fdi = fdi, buf = "", done = false }
|
||||
elseif child == 0 then
|
||||
nixio.dup(fdo, nixio.stdout)
|
||||
fdi:close()
|
||||
fdo:close()
|
||||
nixio.exec("/bin/sh", "-c", cmd)
|
||||
else
|
||||
if fdi then fdi:close() end
|
||||
if fdo then fdo:close() end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local MAX_URL_BATCH = 3
|
||||
|
||||
local function try_fetch(urls, validator)
|
||||
if not urls or #urls == 0 then return "" end
|
||||
local timeout = (#urls > 1) and 5 or 10
|
||||
local delay = 50000000
|
||||
local max_wait = 100
|
||||
local jobs = {}
|
||||
local active = 0
|
||||
local idx = 1
|
||||
local function launch_batch()
|
||||
local n = 0
|
||||
while idx <= #urls and n < MAX_URL_BATCH do
|
||||
local job = fork_curl(urls[idx], timeout)
|
||||
if job then
|
||||
jobs[#jobs + 1] = job
|
||||
active = active + 1
|
||||
end
|
||||
idx = idx + 1
|
||||
n = n + 1
|
||||
end
|
||||
end
|
||||
launch_batch()
|
||||
for _ = 1, max_wait do
|
||||
local winner = ""
|
||||
for _, job in ipairs(jobs) do
|
||||
if not job.done then
|
||||
local ok_r, buf = pcall(try_read, job.fdi, 4096)
|
||||
if ok_r and buf then job.buf = job.buf .. buf end
|
||||
local ok_w, wpid = pcall(nixio.waitpid, job.pid, "nohang")
|
||||
if ok_w and wpid then
|
||||
while true do
|
||||
local ok_b, b = pcall(try_read, job.fdi, 4096)
|
||||
if not ok_b or not b then break end
|
||||
job.buf = job.buf .. b
|
||||
end
|
||||
pcall(job.fdi.close, job.fdi)
|
||||
job.done = true
|
||||
active = active - 1
|
||||
if winner == "" and job.buf ~= "" and (not validator or validator(job.buf)) then
|
||||
winner = job.buf
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if winner ~= "" then
|
||||
for _, job in ipairs(jobs) do
|
||||
if not job.done then
|
||||
pcall(job.fdi.close, job.fdi)
|
||||
nixio.kill(job.pid, 9)
|
||||
end
|
||||
end
|
||||
return trim(winner)
|
||||
end
|
||||
if active == 0 then
|
||||
if idx <= #urls then
|
||||
launch_batch()
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
nixio.nanosleep(0, delay)
|
||||
delay = math.min(delay * 2, 200000000)
|
||||
end
|
||||
for _, job in ipairs(jobs) do
|
||||
if not job.done then
|
||||
pcall(job.fdi.close, job.fdi)
|
||||
nixio.kill(job.pid, 9)
|
||||
end
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
function M.prepare_oix_cdn_data(force)
|
||||
if not M.is_oix_mode() then
|
||||
return false, "", ""
|
||||
end
|
||||
|
||||
local parsed = read_version_cache()
|
||||
if parsed and parsed.oix and parsed.oix.cached_at then
|
||||
local age = os.time() - parsed.oix.cached_at
|
||||
local ttl = parsed.oix.cache_ttl or 300
|
||||
if age < 5 or (not force and age < ttl) then
|
||||
return true, parsed.oix.ver or "", parsed.oix.error or ""
|
||||
end
|
||||
end
|
||||
|
||||
local function fork_oix_version(url)
|
||||
local fdi, fdo = nixio.pipe()
|
||||
if not fdi or not fdo then return nil end
|
||||
local cmd = string.format('curl -sL -m 3 --connect-timeout 3 "%s" 2>/dev/null', url)
|
||||
local child = nixio.fork()
|
||||
if child > 0 then
|
||||
fdo:close()
|
||||
return { pid = child, fdi = fdi, buf = "" }
|
||||
elseif child == 0 then
|
||||
nixio.dup(fdo, nixio.stdout)
|
||||
fdi:close()
|
||||
fdo:close()
|
||||
nixio.exec("/bin/sh", "-c", cmd)
|
||||
else
|
||||
if fdi then fdi:close() end
|
||||
if fdo then fdo:close() end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local jobs = {}
|
||||
local dl_job = fork_oix_version("https://dl.dler.io/mihomo-oix/version.txt?tag=Pre-Alpha")
|
||||
if dl_job then jobs[#jobs + 1] = dl_job end
|
||||
local gh_job = fork_oix_version("https://github.com/vernesong/mihomo-oix/releases/download/Pre-Alpha/version.txt")
|
||||
if gh_job then jobs[#jobs + 1] = gh_job end
|
||||
|
||||
if #jobs == 0 then
|
||||
return true, "", "error"
|
||||
end
|
||||
|
||||
local ver = ""
|
||||
local delay = 50000000
|
||||
local max_wait = 40
|
||||
for _ = 1, max_wait do
|
||||
for _, job in ipairs(jobs) do
|
||||
if not job.done then
|
||||
local ok_r, buf = pcall(try_read, job.fdi, 4096)
|
||||
if ok_r and buf then job.buf = job.buf .. buf end
|
||||
local ok_w, wpid = pcall(nixio.waitpid, job.pid, "nohang")
|
||||
if ok_w and wpid then
|
||||
while true do
|
||||
local ok_b, b = pcall(try_read, job.fdi, 4096)
|
||||
if not ok_b or not b then break end
|
||||
job.buf = job.buf .. b
|
||||
end
|
||||
pcall(job.fdi.close, job.fdi)
|
||||
job.done = true
|
||||
end
|
||||
end
|
||||
end
|
||||
for _, job in ipairs(jobs) do
|
||||
if job.done and ver == "" then
|
||||
local candidate = trim(job.buf:gsub("[\n\r]+", ""))
|
||||
if M.is_valid_version(candidate) then
|
||||
ver = candidate
|
||||
end
|
||||
end
|
||||
end
|
||||
if ver ~= "" then
|
||||
for _, job in ipairs(jobs) do
|
||||
if not job.done then
|
||||
pcall(job.fdi.close, job.fdi)
|
||||
nixio.kill(job.pid, 9)
|
||||
end
|
||||
end
|
||||
update_version_cache(function(p) p.oix = { ver = ver, error = "", cache_ttl = 300, cached_at = os.time() } end)
|
||||
return true, ver, ""
|
||||
end
|
||||
local all_done = true
|
||||
for _, job in ipairs(jobs) do
|
||||
if not job.done then all_done = false break end
|
||||
end
|
||||
if all_done then break end
|
||||
nixio.nanosleep(0, delay)
|
||||
delay = math.min(delay * 2, 200000000)
|
||||
end
|
||||
|
||||
for _, job in ipairs(jobs) do
|
||||
if not job.done then
|
||||
pcall(job.fdi.close, job.fdi)
|
||||
nixio.kill(job.pid, 9)
|
||||
end
|
||||
end
|
||||
|
||||
update_version_cache(function(p) p.oix = { ver = "", error = "error", cache_ttl = 5, cached_at = os.time() } end)
|
||||
return true, "", "error"
|
||||
end
|
||||
|
||||
local function fork_file_fetch(sha, file_path, mod)
|
||||
local urls = build_fetch_urls(mod, sha .. "/" .. file_path)
|
||||
if #urls == 0 then return nil end
|
||||
return { children = {}, idx = 1, buf = "", done = false, launched = false, sha = sha, urls = urls }
|
||||
end
|
||||
|
||||
local function launch_file_batch(job)
|
||||
local timeout = (#job.urls > 1) and 5 or 10
|
||||
local n = 0
|
||||
while job.idx <= #job.urls and n < MAX_URL_BATCH do
|
||||
local child = fork_curl(job.urls[job.idx], timeout)
|
||||
if child then job.children[#job.children + 1] = child end
|
||||
job.idx = job.idx + 1
|
||||
n = n + 1
|
||||
end
|
||||
end
|
||||
|
||||
local function collect_fork_results(jobs, max_jobs)
|
||||
local results = {}
|
||||
local active = 0
|
||||
local delay = 50000000
|
||||
local max_iter = 250
|
||||
|
||||
for _ = 1, max_iter do
|
||||
while active < max_jobs do
|
||||
local launched = false
|
||||
for _, job in ipairs(jobs) do
|
||||
if not job.launched then
|
||||
job.launched = true
|
||||
active = active + 1
|
||||
launched = true
|
||||
launch_file_batch(job)
|
||||
if #job.children == 0 then
|
||||
job.done = true
|
||||
active = active - 1
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
if not launched then break end
|
||||
end
|
||||
|
||||
for _, job in ipairs(jobs) do
|
||||
if job.launched and not job.done then
|
||||
local winner = ""
|
||||
local all_children_done = true
|
||||
for _, child in ipairs(job.children) do
|
||||
if not child.done then
|
||||
all_children_done = false
|
||||
local ok_r, buf = pcall(try_read, child.fdi, 4096)
|
||||
if ok_r and buf then child.buf = child.buf .. buf end
|
||||
local ok_w, wpid = pcall(nixio.waitpid, child.pid, "nohang")
|
||||
if ok_w and wpid then
|
||||
while true do
|
||||
local ok_b, b = pcall(try_read, child.fdi, 4096)
|
||||
if not ok_b or not b then break end
|
||||
child.buf = child.buf .. b
|
||||
end
|
||||
pcall(child.fdi.close, child.fdi)
|
||||
child.done = true
|
||||
if winner == "" and child.buf ~= "" then
|
||||
winner = child.buf
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if winner ~= "" then
|
||||
for _, child in ipairs(job.children) do
|
||||
if not child.done then
|
||||
pcall(child.fdi.close, child.fdi)
|
||||
nixio.kill(child.pid, 9)
|
||||
end
|
||||
end
|
||||
job.done = true
|
||||
active = active - 1
|
||||
results[job.sha] = trim(winner)
|
||||
elseif all_children_done then
|
||||
if job.idx <= #job.urls then
|
||||
launch_file_batch(job)
|
||||
else
|
||||
job.done = true
|
||||
active = active - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local all_done = true
|
||||
for _, job in ipairs(jobs) do
|
||||
if not job.done then all_done = false break end
|
||||
end
|
||||
if all_done then break end
|
||||
|
||||
nixio.nanosleep(0, delay)
|
||||
delay = math.min(delay * 2, 200000000)
|
||||
end
|
||||
|
||||
for _, job in ipairs(jobs) do
|
||||
if not job.done then
|
||||
if job.children then
|
||||
for _, child in ipairs(job.children) do
|
||||
if not child.done then
|
||||
pcall(child.fdi.close, child.fdi)
|
||||
nixio.kill(child.pid, 9)
|
||||
end
|
||||
end
|
||||
end
|
||||
job.done = true
|
||||
end
|
||||
end
|
||||
|
||||
return results
|
||||
end
|
||||
|
||||
local function html_unescape(s)
|
||||
if not s then return "" end
|
||||
s = s:gsub("&", "&")
|
||||
s = s:gsub("<", "<")
|
||||
s = s:gsub(">", ">")
|
||||
s = s:gsub(""", '"')
|
||||
s = s:gsub("'", "'")
|
||||
s = s:gsub("'", "'")
|
||||
return s
|
||||
end
|
||||
|
||||
local function build_feed_urls(mod, path)
|
||||
local feed = "https://github.com/vernesong/OpenClash/commits/" .. path .. ".atom"
|
||||
if mod == "0" or mod == "" then
|
||||
local urls = { feed }
|
||||
for _, cdn in ipairs(cdn_list()) do
|
||||
urls[#urls + 1] = cdn .. feed
|
||||
end
|
||||
return urls
|
||||
end
|
||||
if mod == "https://cdn.jsdelivr.net/" or mod == "https://fastly.jsdelivr.net/" or mod == "https://testingcf.jsdelivr.net/" then
|
||||
return { feed }
|
||||
end
|
||||
return { mod .. feed, feed }
|
||||
end
|
||||
|
||||
local function fetch_commit_feed(mod, path)
|
||||
return try_fetch(build_feed_urls(mod, path), function(buf)
|
||||
return buf:match("<entry") ~= nil
|
||||
end)
|
||||
end
|
||||
|
||||
local function parse_commit_feed(raw, max_count)
|
||||
local commits = {}
|
||||
if raw and raw ~= "" then
|
||||
local n = 0
|
||||
for entry in raw:gmatch("<entry>(.-)</entry>") do
|
||||
n = n + 1
|
||||
if n > max_count then break end
|
||||
local sha = entry:match("<id>[^<]*/([0-9a-f]+)</id>")
|
||||
if sha then
|
||||
local date = entry:match("<updated>(.-)</updated>") or ""
|
||||
local title = entry:match("<title>(.-)</title>") or ""
|
||||
title = trim(title)
|
||||
commits[#commits + 1] = { sha = sha, date = date, message = html_unescape(title) }
|
||||
end
|
||||
end
|
||||
end
|
||||
return commits
|
||||
end
|
||||
|
||||
function M.fetch_version_history(branch, force, cdn, latest_only)
|
||||
local result = { plugin = {}, core_meta = {}, core_smart = {}, latest = nil, error = nil, oix_ver = "" }
|
||||
local cur_oix = M.is_oix_mode()
|
||||
local skip_core = cur_oix
|
||||
local github_address_mod = fs.uci_get_config("config", "github_address_mod") or "0"
|
||||
if cdn and cdn ~= "" then
|
||||
github_address_mod = cdn
|
||||
if github_address_mod:match("raw%.githubusercontent%.com") then
|
||||
github_address_mod = "0"
|
||||
end
|
||||
end
|
||||
|
||||
if not force then
|
||||
local parsed = read_version_cache()
|
||||
if parsed and parsed[branch] and parsed[branch].cached_at then
|
||||
local blk = parsed[branch]
|
||||
local ttl = blk.cache_ttl or 300
|
||||
if os.time() - blk.cached_at < ttl and blk.oix == cur_oix then
|
||||
if latest_only then
|
||||
local lt = blk.latest
|
||||
if lt and lt.plugin and lt.plugin ~= "" and (cur_oix or (lt.core_meta and lt.core_meta ~= "")) then
|
||||
return blk
|
||||
end
|
||||
elseif blk.plugin and #blk.plugin > 0 then
|
||||
return blk
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if latest_only then
|
||||
local plugin_latest = ""
|
||||
local core_meta_latest = ""
|
||||
local core_smart_latest = ""
|
||||
|
||||
local plugin_raw = try_fetch(build_fetch_urls(github_address_mod, "package/" .. branch .. "/version"))
|
||||
if plugin_raw and plugin_raw ~= "" then
|
||||
plugin_latest = trim(plugin_raw:match("^[^\n\r]*") or "")
|
||||
end
|
||||
|
||||
if not cur_oix then
|
||||
local core_raw = try_fetch(build_fetch_urls(github_address_mod, "core/" .. branch .. "/core_version"))
|
||||
if core_raw and core_raw ~= "" then
|
||||
core_meta_latest = trim(core_raw:match("^[^\n\r]*") or "")
|
||||
local after = core_raw:match("[\n\r]+(.*)")
|
||||
if after then
|
||||
core_smart_latest = trim(after:match("^[^\n\r]*") or "")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
result.latest = { plugin = plugin_latest, core_meta = core_meta_latest, core_smart = core_smart_latest }
|
||||
if plugin_latest == "" then
|
||||
result.error = "network_error"
|
||||
end
|
||||
if cur_oix then
|
||||
M.prepare_oix_cdn_data(force)
|
||||
end
|
||||
result.cache_ttl = (plugin_latest == "") and 5 or 300
|
||||
result.cached_at = os.time()
|
||||
result.oix = cur_oix
|
||||
|
||||
update_version_cache(function(parsed)
|
||||
local blk = parsed[branch] or {}
|
||||
blk.latest = result.latest
|
||||
blk.error = result.error
|
||||
blk.cache_ttl = result.cache_ttl
|
||||
blk.cached_at = result.cached_at
|
||||
blk.oix = cur_oix
|
||||
blk.plugin = nil
|
||||
blk.core_meta = nil
|
||||
blk.core_smart = nil
|
||||
blk.oix_ver = nil
|
||||
parsed[branch] = blk
|
||||
end)
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
local plugin_feed = fetch_commit_feed(github_address_mod, "package/" .. branch .. "/version")
|
||||
local plugin_commits = parse_commit_feed(plugin_feed, 5)
|
||||
if #plugin_commits > 0 then
|
||||
local file_jobs = {}
|
||||
for _, c in ipairs(plugin_commits) do
|
||||
local job = fork_file_fetch(c.sha, branch .. "/version", github_address_mod)
|
||||
if job then file_jobs[#file_jobs + 1] = job end
|
||||
end
|
||||
|
||||
local file_results = collect_fork_results(file_jobs, 2)
|
||||
|
||||
for _, c in ipairs(plugin_commits) do
|
||||
local raw = file_results[c.sha]
|
||||
local ver
|
||||
if raw and raw ~= "" then
|
||||
ver = trim(raw:match("^[^\n\r]*") or "")
|
||||
if not M.is_valid_version(ver) then ver = nil end
|
||||
end
|
||||
result.plugin[#result.plugin + 1] = {
|
||||
version = ver,
|
||||
date = c.date,
|
||||
sha = c.sha,
|
||||
message = c.message
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
if not skip_core then
|
||||
local core_feed = fetch_commit_feed(github_address_mod, "core/" .. branch .. "/core_version")
|
||||
local core_commits = parse_commit_feed(core_feed, 5)
|
||||
if #core_commits > 0 then
|
||||
local file_jobs = {}
|
||||
for _, c in ipairs(core_commits) do
|
||||
local job = fork_file_fetch(c.sha, branch .. "/core_version", github_address_mod)
|
||||
if job then file_jobs[#file_jobs + 1] = job end
|
||||
end
|
||||
|
||||
local file_results = collect_fork_results(file_jobs, 2)
|
||||
|
||||
for _, c in ipairs(core_commits) do
|
||||
local content = file_results[c.sha]
|
||||
if content and content ~= "" then
|
||||
local meta_ver = content:match("^[^\n\r]*")
|
||||
local after_first = content:match("[\n\r]+(.*)")
|
||||
local smart_ver = after_first and after_first:match("^[^\n\r]*") or nil
|
||||
if meta_ver then
|
||||
meta_ver = trim(meta_ver)
|
||||
if M.is_valid_version(meta_ver) then
|
||||
result.core_meta[#result.core_meta + 1] = { version = meta_ver, date = c.date, sha = c.sha }
|
||||
end
|
||||
end
|
||||
if smart_ver then
|
||||
smart_ver = trim(smart_ver)
|
||||
if M.is_valid_version(smart_ver) then
|
||||
result.core_smart[#result.core_smart + 1] = { version = smart_ver, date = c.date, sha = c.sha }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
result.latest = {
|
||||
plugin = (result.plugin[1] and result.plugin[1].version) or "",
|
||||
core_meta = (result.core_meta[1] and result.core_meta[1].version) or "",
|
||||
core_smart = (result.core_smart[1] and result.core_smart[1].version) or ""
|
||||
}
|
||||
|
||||
if cur_oix then
|
||||
local _, oix_ver = M.prepare_oix_cdn_data(force)
|
||||
if oix_ver and oix_ver ~= "" then
|
||||
result.oix_ver = oix_ver
|
||||
end
|
||||
end
|
||||
|
||||
local cache_ttl = 300
|
||||
if #result.plugin == 0 then
|
||||
if not plugin_feed or plugin_feed == "" then
|
||||
result.error = "network_error"
|
||||
cache_ttl = 5
|
||||
else
|
||||
result.error = "parse_error"
|
||||
cache_ttl = 5
|
||||
end
|
||||
end
|
||||
|
||||
result.cache_ttl = cache_ttl
|
||||
result.cached_at = os.time()
|
||||
result.oix = cur_oix
|
||||
|
||||
update_version_cache(function(parsed)
|
||||
parsed[branch] = result
|
||||
end)
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
if arg and arg[0] and arg[0]:match("openclash_version%.lua$") then
|
||||
local branch = fs.uci_get_config("config", "release_branch") or "master"
|
||||
M.fetch_version_history(branch, arg[2], arg[1], arg[3] ~= "0")
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in new issue
Block a user