mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-11-09 21:48:03 +08:00
update 2026-10-17 16:12:15
This commit is contained in:
1 parent
fbf8d8b632
commit
63dbfd1d1b
167 files changed
+407
-38039
No files matched your search
@@ -100,10 +100,11 @@ function index()
|
||||
entry({"admin", "services", appname, "delete_select_shunt_rules"}, call("delete_select_shunt_rules")).leaf = true
|
||||
|
||||
--[[Components update]]
|
||||
entry({"admin", "services", appname, "check_passwall2"}, call("app_check")).leaf = true
|
||||
entry({"admin", "services", appname, "check_" .. appname}, call("app_check")).leaf = true
|
||||
entry({"admin", "services", appname, "update_" .. appname}, call("app_update")).leaf = true
|
||||
local coms = require "luci.passwall2.com"
|
||||
local com
|
||||
for com, _ in pairs(coms) do
|
||||
for _, com in ipairs(coms.order) do
|
||||
entry({"admin", "services", appname, "check_" .. com}, call("com_check", com)).leaf = true
|
||||
entry({"admin", "services", appname, "update_" .. com}, call("com_update", com)).leaf = true
|
||||
entry({"admin", "services", appname, "version_" .. com}, call("com_version", com)).leaf = true
|
||||
@@ -691,6 +692,30 @@ function app_check()
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function app_update()
|
||||
local id = http.formvalue("id")
|
||||
if not id or not id:match("^[%w_-]+$") then
|
||||
http_write_json({code = 1, error = i18n.translate("Invalid download task.")})
|
||||
return
|
||||
end
|
||||
local task = http.formvalue("task")
|
||||
local result
|
||||
if task == "progress" then
|
||||
result = api.to_download_progress(appname, id, http.formvalue("total_size"))
|
||||
elseif task == "install" then
|
||||
if not luci.dispatcher.test_post_security() then return end
|
||||
result = api.to_install_self(id, http.formvalue("force"), http.formvalue("languages"))
|
||||
else
|
||||
local part = tonumber(http.formvalue("part")) or 1
|
||||
if part < 1 or part > 5 or part ~= math.floor(part) then
|
||||
http_write_json({code = 1, error = i18n.translate("Invalid download task.")})
|
||||
return
|
||||
end
|
||||
result = api.to_download(appname, http.formvalue("url"), http.formvalue("size"), id .. part, part > 1)
|
||||
end
|
||||
http_write_json(result)
|
||||
end
|
||||
|
||||
function com_check(comname)
|
||||
local json = api.to_check("", comname)
|
||||
http_write_json(json)
|
||||
|
||||
@@ -18,8 +18,8 @@ o:value("https://ghproxy.cc/", "ghproxy.cc")
|
||||
o:value("https://mirror.ghproxy.com/", "ghproxy.com")
|
||||
o:value("https://ghfast.top/", "ghfast.top")
|
||||
|
||||
local k, v
|
||||
for k, v in pairs(com) do
|
||||
for _, k in ipairs(com.order) do
|
||||
local v = com[k]
|
||||
o = s:option(Value, k:gsub("%-","_") .. "_file", translatef("%s App Path", v.name))
|
||||
o.default = v.default_path or ("/usr/bin/" .. k)
|
||||
o.placeholder = o.default
|
||||
|
||||
@@ -208,10 +208,11 @@ function get_cache_var(key)
|
||||
return val
|
||||
end
|
||||
|
||||
function get_new_port(p)
|
||||
if not p then p = "auto" end
|
||||
local cmd_format = ". /usr/share/passwall2/utils.sh ; echo -n $(get_new_port %s tcp,udp)"
|
||||
return tonumber(sys.exec(string.format(cmd_format, p)))
|
||||
function get_new_port(start_port, protocol)
|
||||
start_port = tonumber(start_port) or "auto"
|
||||
if protocol ~= "tcp" and protocol ~= "udp" then protocol = "tcp,udp" end
|
||||
local cmd_format = ". /usr/share/passwall2/utils.sh ; echo -n $(get_new_port %s %s)"
|
||||
return tonumber(sys.exec(string.format(cmd_format, util.shellquote(tostring(start_port)), util.shellquote(protocol))))
|
||||
end
|
||||
|
||||
function exec_call(cmd)
|
||||
@@ -1102,9 +1103,16 @@ function compare_versions(ver1, comp, ver2)
|
||||
local n2 = table.getn(av2)
|
||||
if (max < n2) then max = n2 end
|
||||
|
||||
local function version_part(value)
|
||||
local number = tonumber(value)
|
||||
if number then return number end
|
||||
local revision = type(value) == "string" and value:match("^[rR](%d+)$")
|
||||
return tonumber(revision) or 0
|
||||
end
|
||||
|
||||
for i = 1, max, 1 do
|
||||
local s1 = tonumber(av1[i] or 0) or 0
|
||||
local s2 = tonumber(av2[i] or 0) or 0
|
||||
local s1 = version_part(av1[i] or 0)
|
||||
local s2 = version_part(av2[i] or 0)
|
||||
|
||||
if comp == "~=" and (s1 ~= s2) then return true end
|
||||
if (comp == "<" or comp == "<=") and (s1 < s2) then return true end
|
||||
@@ -1270,8 +1278,8 @@ function to_check(arch, app_name)
|
||||
}
|
||||
end
|
||||
|
||||
function to_download(app_name, url, size, task_id)
|
||||
local result = check_path(app_name)
|
||||
function to_download(app_name, url, size, task_id, keep_files)
|
||||
local result = app_name == appname and {code = 0} or check_path(app_name)
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
@@ -1280,7 +1288,7 @@ function to_download(app_name, url, size, task_id)
|
||||
return {code = 1, error = i18n.translate("Download url is required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -f /tmp/".. app_name .."_download.*")
|
||||
if not keep_files then sys.call("/bin/rm -f /tmp/".. app_name .."_download.*") end
|
||||
|
||||
local tmp_file
|
||||
if type(task_id) == "string" and task_id:match("^[%w_-]+$") then
|
||||
@@ -1329,6 +1337,12 @@ function to_download_progress(app_name, task_id, total_size)
|
||||
total_size = tonumber(total_size) or 0
|
||||
local tmp_file = "/tmp/" .. app_name .. "_download." .. task_id
|
||||
local downloaded = tonumber(fs.stat(tmp_file, "size")) or 0
|
||||
if app_name == appname then
|
||||
downloaded = 0
|
||||
for part = 1, 5 do
|
||||
downloaded = downloaded + (tonumber(fs.stat(tmp_file .. part, "size")) or 0)
|
||||
end
|
||||
end
|
||||
local percent
|
||||
if total_size > 0 then
|
||||
-- Leave 100% for the download request's success callback.
|
||||
@@ -1465,53 +1479,136 @@ function to_move(app_name,file)
|
||||
end
|
||||
|
||||
function get_version()
|
||||
local version = sys.exec("opkg list-installed luci-app-passwall2 2>/dev/null | awk '{print $3}'")
|
||||
if not version or #version == 0 then
|
||||
version = sys.exec("apk list luci-app-passwall2 2>/dev/null | awk '/installed/ {print $1}' | cut -d'-' -f4-")
|
||||
local version_file = CACHE_PATH .. "/passwall2_version"
|
||||
local version = trim(fs.readfile(version_file) or "")
|
||||
if version == "" then
|
||||
version = trim(sys.exec("opkg list-installed luci-app-passwall2 2>/dev/null | awk '{print $3}'") or "")
|
||||
if version == "" then
|
||||
version = trim(sys.exec("apk list luci-app-passwall2 2>/dev/null | awk '/installed/ {print $1}' | cut -d'-' -f4-") or "")
|
||||
end
|
||||
if version ~= "" then
|
||||
fs.mkdirr(CACHE_PATH)
|
||||
fs.writefile(version_file, version)
|
||||
end
|
||||
end
|
||||
return (version or ""):gsub("\n", ""):match("^([^-]+)")
|
||||
return (version:gsub("%-[rR](%d+)$", "-%1"))
|
||||
end
|
||||
|
||||
local function self_update_languages()
|
||||
local current = uci:get("luci", "main", "lang") or "auto"
|
||||
if current == "auto" then
|
||||
current = _G.L and _G.L.dispatcher and _G.L.dispatcher.lang
|
||||
if not current or current == "auto" then
|
||||
local ok, request, accept = pcall(function()
|
||||
local http = require "luci.http"
|
||||
return http.getenv("REQUEST_METHOD") or http.getenv("REQUEST_URI"), http.getenv("HTTP_ACCEPT_LANGUAGE")
|
||||
end)
|
||||
current = lang
|
||||
if ok and (request or accept) then
|
||||
current = "en"
|
||||
for item in (accept or ""):gmatch("[^,]+") do
|
||||
local code = item:match("^%s*([%w_-]+)")
|
||||
local quality = tonumber(item:match(";%s*q%s*=%s*([%d%.]+)")) or 1
|
||||
if code and quality > 0 then
|
||||
code = code:gsub("-", "_")
|
||||
local lower = code:lower()
|
||||
local alias = ({zh="zh_Hans", zh_cn="zh_Hans", zh_sg="zh_Hans", zh_tw="zh_Hant", zh_hk="zh_Hant", zh_mo="zh_Hant"})[lower]
|
||||
if lower:match("^zh_hans") then alias = "zh_Hans" end
|
||||
if lower:match("^zh_hant") then alias = "zh_Hant" end
|
||||
local matched
|
||||
for _, candidate in ipairs({code, lower, alias or "", code:match("^([^_]+)") or ""}) do
|
||||
if uci:get("luci", "languages", candidate) then current = candidate; matched = true; break end
|
||||
end
|
||||
if matched then break end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
current = (current or ""):lower():gsub("_", "-")
|
||||
if current == "zh" or current == "zh-cn" or current == "zh-sg" or current:match("^zh%-hans") then current = "zh-cn" end
|
||||
if current == "zh-tw" or current == "zh-hk" or current == "zh-mo" or current:match("^zh%-hant") then current = "zh-tw" end
|
||||
if current:match("^fa%-") then current = "fa" end
|
||||
if current:match("^ru%-") then current = "ru" end
|
||||
local languages = {}
|
||||
for _, code in ipairs({"fa", "ru", "zh-cn", "zh-tw"}) do
|
||||
if current == code or is_install("luci-i18n-" .. appname .. "-" .. code) then languages[#languages + 1] = code end
|
||||
end
|
||||
return languages
|
||||
end
|
||||
|
||||
function to_check_self()
|
||||
local url = "https://raw.githubusercontent.com/Openwrt-Passwall/openwrt-passwall2/main/luci-app-passwall2/Makefile"
|
||||
local tmp_file = "/tmp/passwall2_makefile"
|
||||
local gh_proxy = uci_get_c("@global_app[0]", "gh_proxy_url") or ""
|
||||
local return_code, result
|
||||
if gh_proxy ~= "" then
|
||||
url = gh_proxy .. url
|
||||
return_code, result = curl_direct(url, tmp_file, curl_args)
|
||||
else
|
||||
return_code, result = curl_auto(url, tmp_file, curl_args)
|
||||
local release = get_api_json(com[appname]:get_url())
|
||||
if type(release) == "table" and #release > 0 then release = release[1] end
|
||||
if type(release) ~= "table" or not release.tag_name then
|
||||
return {code = 1, error = i18n.translate("Get remote version info failed.")}
|
||||
end
|
||||
result = return_code == 0
|
||||
if not result then
|
||||
exec("/bin/rm", {"-f", tmp_file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Failed")
|
||||
}
|
||||
local local_version = get_version()
|
||||
local remote_version = release.tag_name:gsub("^v", ""):gsub("%-r(%d+)$", "-%1")
|
||||
local package_version = remote_version:gsub("%-(%d+)$", "-r%1")
|
||||
local language_version = remote_version:match("^(%d+%.%d+%.%d+)") or remote_version
|
||||
local apk = sys.call("command -v apk >/dev/null 2>&1") == 0
|
||||
local main_name = "luci-app-" .. appname .. (apk and "-" .. package_version .. ".apk" or "_" .. package_version .. "_all.ipk")
|
||||
local languages = self_update_languages()
|
||||
local wanted, found = {}, {}
|
||||
for _, code in ipairs(languages) do
|
||||
local name = "luci-i18n-" .. appname .. "-" .. code .. (apk and "-" .. language_version .. ".apk" or "_" .. language_version .. "_all.ipk")
|
||||
wanted[name] = code
|
||||
end
|
||||
local local_version = get_version()
|
||||
local remote_version = sys.exec("echo -n $(grep '^PKG_VERSION' /tmp/passwall2_makefile | head -n 1 | awk -F '=' '{print $2}')")
|
||||
exec("/bin/rm", {"-f", tmp_file})
|
||||
|
||||
local has_update = compare_versions(local_version, "<", remote_version)
|
||||
if not has_update then
|
||||
return {
|
||||
code = 0,
|
||||
local_version = local_version,
|
||||
remote_version = remote_version
|
||||
}
|
||||
local main
|
||||
for _, asset in ipairs(release.assets or {}) do
|
||||
if asset.name == main_name then main = asset end
|
||||
if wanted[asset.name] then found[wanted[asset.name]] = asset end
|
||||
end
|
||||
local selected = {}
|
||||
for _, code in ipairs(languages) do
|
||||
if not found[code] then return {code = 1, error = i18n.translate("Get remote version info failed.")} end
|
||||
selected[#selected + 1] = found[code]
|
||||
end
|
||||
if not main then return {code = 1, error = i18n.translate("Get remote version info failed.")} end
|
||||
return {
|
||||
code = 1,
|
||||
has_update = true,
|
||||
local_version = local_version,
|
||||
remote_version = remote_version,
|
||||
error = i18n.translatef("The latest version: %s, currently does not support automatic update, if you need to update, please compile or download the ipk and then manually install.", remote_version)
|
||||
code = 0, has_update = compare_versions(local_version, "<", remote_version),
|
||||
local_version = local_version, remote_version = remote_version, html_url = release.html_url,
|
||||
data = main, i18n = selected, languages = table.concat(languages, ",")
|
||||
}
|
||||
end
|
||||
|
||||
function to_install_self(id, force, languages)
|
||||
if type(id) ~= "string" or not id:match("^[%w_-]+$") or (languages and type(languages) ~= "string") then return {code = 1} end
|
||||
local selected, seen = {}, {}
|
||||
for code in (languages or ""):gmatch("[^,]+") do
|
||||
if not ({fa=true, ru=true, ["zh-cn"]=true, ["zh-tw"]=true})[code] or seen[code] then return {code = 1} end
|
||||
selected[#selected + 1], seen[code] = code, true
|
||||
end
|
||||
local dir = "/tmp/" .. appname .. "_luci_update." .. id
|
||||
local manager = sys.call("command -v apk >/dev/null 2>&1") == 0 and "apk" or "opkg"
|
||||
local extension = manager == "apk" and ".apk" or ".ipk"
|
||||
local status_dir = "/www/luci-static/resources/" .. appname .. "-update"
|
||||
local status = status_dir .. "/" .. id .. ".json"
|
||||
fs.mkdir(dir)
|
||||
fs.mkdir(status_dir)
|
||||
if exec("/bin/mv", {"/tmp/" .. appname .. "_download." .. id .. "1", dir .. "/luci-app-" .. appname .. extension}) ~= 0 then
|
||||
remove(dir)
|
||||
return {code = 1}
|
||||
end
|
||||
for part, code in ipairs(selected) do
|
||||
if exec("/bin/mv", {"/tmp/" .. appname .. "_download." .. id .. (part + 1), dir .. "/luci-i18n-" .. appname .. "-" .. code .. extension}) ~= 0 then
|
||||
remove(dir)
|
||||
return {code = 1}
|
||||
end
|
||||
end
|
||||
local script = dir .. "/luci_update.sh"
|
||||
if exec("/bin/cp", {"/usr/share/" .. appname .. "/luci_update.sh", script}) ~= 0 then
|
||||
remove(dir)
|
||||
return {code = 1}
|
||||
end
|
||||
chmod_755(script)
|
||||
fs.writefile(status, '{"installing":true}')
|
||||
sys.call("nohup " .. script .. " " .. dir .. " " .. status .. " " .. manager .. " " ..
|
||||
(force == "1" and "1" or "0") .. " >/dev/null 2>&1 </dev/null &")
|
||||
return {code = 0}
|
||||
end
|
||||
|
||||
function cacheFileCompareToLogic(file, str)
|
||||
local result = nil
|
||||
if file and str then
|
||||
|
||||
@@ -10,6 +10,18 @@ local function gh_pre_release_url(self)
|
||||
return "https://github.com/Openwrt-Passwall/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-pre-release-api.json"
|
||||
end
|
||||
|
||||
_M.order = {
|
||||
"geoview",
|
||||
"xray",
|
||||
"sing-box"
|
||||
}
|
||||
|
||||
-- The LuCI package has its own update flow and is not a binary component.
|
||||
_M.passwall2 = {
|
||||
name = "PassWall2",
|
||||
get_url = gh_release_url
|
||||
}
|
||||
|
||||
_M["sing-box"] = {
|
||||
name = "Sing-Box",
|
||||
repo = "SagerNet/sing-box",
|
||||
|
||||
@@ -7,6 +7,7 @@ local com = self.com
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var appname = '<%=api.appname%>';
|
||||
var appInfoList = new Array();
|
||||
var inProgressCount = 0;
|
||||
var tokenStr = '<%=token%>';
|
||||
@@ -22,6 +23,25 @@ local com = self.com
|
||||
var downloadingText = '<%:Downloading...%>';
|
||||
var decompressioningText = '<%:Unpacking...%>';
|
||||
var movingText = '<%:Moving...%>';
|
||||
var installingText = '<%:Installing...%>';
|
||||
var installingNotice = '<%:Do not refresh or switch pages during installation.%>';
|
||||
var updateFailedText = '<%:Update failed%>';
|
||||
var unknownErrorText = '<%:Unknown error%>';
|
||||
var componentUpdates = 0, luciUpdating = false;
|
||||
|
||||
function syncUpdateButtons() {
|
||||
var buttons = document.querySelectorAll('#app_version input[data-update-app]');
|
||||
for (var i = 0; i < buttons.length; i++) {
|
||||
var btn = buttons[i];
|
||||
btn.disabled = !!btn.updateDisabled || luciUpdating ||
|
||||
(btn.getAttribute('data-update-app') === appname && componentUpdates > 0);
|
||||
}
|
||||
}
|
||||
|
||||
function setButtonDisabled(btn, disabled) {
|
||||
btn.updateDisabled = disabled;
|
||||
syncUpdateButtons();
|
||||
}
|
||||
|
||||
//window.onload = function () {};
|
||||
|
||||
@@ -35,8 +55,11 @@ local com = self.com
|
||||
inProgressCount++;
|
||||
}
|
||||
|
||||
function removePageNotice() {
|
||||
function removePageNotice(app) {
|
||||
if (app === appname) luciUpdating = false;
|
||||
else if (app) componentUpdates--;
|
||||
inProgressCount--;
|
||||
syncUpdateButtons();
|
||||
if (inProgressCount === 0) {
|
||||
window.onbeforeunload = undefined;
|
||||
}
|
||||
@@ -46,21 +69,24 @@ local com = self.com
|
||||
if (btn) {
|
||||
btn.value = updateSuccessText;
|
||||
btn.placeholder = updateSuccessText;
|
||||
btn.disabled = true;
|
||||
setButtonDisabled(btn, true);
|
||||
}
|
||||
|
||||
if (inProgressCount === 0) {
|
||||
window.setTimeout(function () {
|
||||
window.location.reload();
|
||||
if (inProgressCount === 0 && !luciUpdating) window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function onRequestError(btn, errorMessage) {
|
||||
btn.disabled = false;
|
||||
function onRequestError(btn, errorMessage, checking) {
|
||||
setButtonDisabled(btn, false);
|
||||
btn.value = retryText;
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
var app = btn.getAttribute('data-update-app');
|
||||
var detailId = app === appname ? appname + '-check_btn' : '_' + app + '-check_btn';
|
||||
var ckeckDetailElm = document.getElementById(detailId + '-detail');
|
||||
if (app === appname && !checking) errorMessage = errorMessage ? updateFailedText : unknownErrorText;
|
||||
if (errorMessage && ckeckDetailElm) {
|
||||
ckeckDetailElm.textContent = errorMessage
|
||||
}
|
||||
@@ -75,7 +101,7 @@ local com = self.com
|
||||
}
|
||||
|
||||
function checkUpdate(btn, app) {
|
||||
btn.disabled = true;
|
||||
setButtonDisabled(btn, true);
|
||||
btn.value = inProgressText;
|
||||
|
||||
addPageNotice();
|
||||
@@ -89,13 +115,13 @@ local com = self.com
|
||||
arch: ''
|
||||
}, function (x, json) {
|
||||
removePageNotice();
|
||||
if (json.code) {
|
||||
if (!json || json.code) {
|
||||
appInfoList[app] = undefined;
|
||||
onRequestError(btn, json.error);
|
||||
onRequestError(btn, json && json.error, true);
|
||||
} else {
|
||||
appInfoList[app] = json;
|
||||
if (json.has_update) {
|
||||
btn.disabled = false;
|
||||
setButtonDisabled(btn, false);
|
||||
btn.value = clickToUpdateText;
|
||||
btn.placeholder = clickToUpdateText;
|
||||
|
||||
@@ -110,7 +136,7 @@ local com = self.com
|
||||
ckeckDetailElm.innerHTML = urlNode;
|
||||
}
|
||||
} else {
|
||||
btn.disabled = true;
|
||||
setButtonDisabled(btn, true);
|
||||
btn.value = noUpdateText;
|
||||
var forceBtn = document.getElementById('_' + app + '-force_btn');
|
||||
if (forceBtn) {
|
||||
@@ -122,7 +148,10 @@ local com = self.com
|
||||
}
|
||||
|
||||
function doUpdate(btn, app) {
|
||||
btn.disabled = true;
|
||||
if (luciUpdating || (app === appname && componentUpdates > 0)) return;
|
||||
if (app === appname) luciUpdating = true;
|
||||
else componentUpdates++;
|
||||
setButtonDisabled(btn, true);
|
||||
btn.value = downloadingText;
|
||||
|
||||
addPageNotice();
|
||||
@@ -130,7 +159,10 @@ local com = self.com
|
||||
var appUpdateUrl = '<%=api.url("update_")%>' + app;
|
||||
var appInfo = appInfoList[app];
|
||||
var downloadId = Date.now().toString(36) + Math.random().toString(36).substring(2, 8);
|
||||
var totalSize = appInfo && appInfo.data ? Number(appInfo.data.size) : 0;
|
||||
var downloadList = appInfo && appInfo.data ? [appInfo.data] : [];
|
||||
if (app === appname && Array.isArray(appInfo.i18n)) downloadList = downloadList.concat(appInfo.i18n);
|
||||
var totalSize = 0;
|
||||
for (var i = 0; i < downloadList.length; i++) totalSize += Number(downloadList[i].size) || 0;
|
||||
if (!isFinite(totalSize) || totalSize <= 0) {
|
||||
totalSize = 0;
|
||||
}
|
||||
@@ -169,41 +201,44 @@ local com = self.com
|
||||
progressTimer = setInterval(updateDownloadProgress, 1000);
|
||||
}
|
||||
|
||||
// Download file
|
||||
XHR.get(appUpdateUrl, {
|
||||
token: tokenStr,
|
||||
url: appInfo ? appInfo.data.browser_download_url : '',
|
||||
size: appInfo ? appInfo.data.size / 1024 : null,
|
||||
id: downloadId
|
||||
}, function (x, json) {
|
||||
stopDownloadProgress();
|
||||
if (json.code) {
|
||||
removePageNotice();
|
||||
onRequestError(btn, json.error);
|
||||
} else if (json.zip) {
|
||||
btn.value = decompressioningText;
|
||||
|
||||
// Extract file
|
||||
XHR.get(appUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'extract',
|
||||
file: json.file,
|
||||
subfix: appInfo ? appInfo.type : ''
|
||||
}, function (x, json) {
|
||||
if (json.code) {
|
||||
removePageNotice();
|
||||
onRequestError(btn, json.error);
|
||||
} else {
|
||||
move(btn, appUpdateUrl, json.file);
|
||||
}
|
||||
}, 300)
|
||||
} else {
|
||||
move(btn, appUpdateUrl, json.file);
|
||||
}
|
||||
}, 300)
|
||||
function download(part) {
|
||||
var asset = downloadList[part - 1];
|
||||
XHR.get(appUpdateUrl, {
|
||||
token: tokenStr, url: asset.browser_download_url,
|
||||
size: (app === appname && part === 1 ? totalSize : asset.size) / 1024,
|
||||
id: downloadId, part: part
|
||||
}, function (x, json) {
|
||||
if (json && !json.code && app === appname && part < downloadList.length) {
|
||||
download(part + 1);
|
||||
return;
|
||||
}
|
||||
stopDownloadProgress();
|
||||
if (!json || json.code) {
|
||||
removePageNotice(app);
|
||||
onRequestError(btn, json && (json.error || updateFailedText));
|
||||
} else if (app === appname) {
|
||||
installLuci(btn, appUpdateUrl, downloadId);
|
||||
} else if (json.zip) {
|
||||
btn.value = decompressioningText;
|
||||
XHR.get(appUpdateUrl, {
|
||||
token: tokenStr, task: 'extract', file: json.file, subfix: appInfo.type || ''
|
||||
}, function (x, json) {
|
||||
if (!json || json.code) {
|
||||
removePageNotice(app);
|
||||
onRequestError(btn, json && json.error);
|
||||
} else {
|
||||
move(btn, app, appUpdateUrl, json.file);
|
||||
}
|
||||
}, 300);
|
||||
} else {
|
||||
move(btn, app, appUpdateUrl, json.file);
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
download(1);
|
||||
}
|
||||
|
||||
function move(btn, url, file) {
|
||||
function move(btn, app, url, file) {
|
||||
btn.value = movingText;
|
||||
|
||||
// Move file to target dir
|
||||
@@ -212,14 +247,56 @@ local com = self.com
|
||||
task: 'move',
|
||||
file: file
|
||||
}, function (x, json) {
|
||||
removePageNotice();
|
||||
if (json.code) {
|
||||
onRequestError(btn, json.error);
|
||||
removePageNotice(app);
|
||||
if (!json || json.code) {
|
||||
onRequestError(btn, json && json.error);
|
||||
} else {
|
||||
onUpdateSuccess(btn);
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
function installLuci(btn, url, id) {
|
||||
btn.value = installingText;
|
||||
var detail = document.getElementById(appname + '-check_btn-detail');
|
||||
detail.textContent = installingNotice;
|
||||
// Read the tiny result file even if rpcd restart invalidates the session.
|
||||
var pending = false, finished = false;
|
||||
var timer = setInterval(function() {
|
||||
if (pending) return;
|
||||
pending = true;
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', '<%=resource%>/' + appname + '-update/' + id + '.json?_=' + Date.now(), true);
|
||||
xhr.timeout = 5000;
|
||||
xhr.onerror = xhr.ontimeout = function() { pending = false; };
|
||||
xhr.onload = function() {
|
||||
pending = false;
|
||||
if (finished) return;
|
||||
var json;
|
||||
try { json = JSON.parse(xhr.responseText); } catch (e) { return; }
|
||||
if (typeof json.code !== 'number') return;
|
||||
finished = true;
|
||||
clearInterval(timer);
|
||||
removePageNotice(appname);
|
||||
if (json.code) onRequestError(btn, updateFailedText);
|
||||
else {
|
||||
window.onbeforeunload = undefined;
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
}, 1000);
|
||||
XHR.post(url, {token: tokenStr, task: 'install', id: id,
|
||||
force: appInfoList[appname].has_update ? '0' : '1',
|
||||
languages: appInfoList[appname].languages || ''}, function(x, json) {
|
||||
if (!finished && json && json.code) {
|
||||
finished = true;
|
||||
clearInterval(timer);
|
||||
removePageNotice(appname);
|
||||
onRequestError(btn, updateFailedText);
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
@@ -228,14 +305,18 @@ local com = self.com
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-description">
|
||||
<span>【 <%=api.get_version()%> 】</span>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="passwall2-check_btn"
|
||||
onclick="onBtnClick(this,'passwall2');" value="<%:Check update%>" />
|
||||
<span id="passwall2-check_btn-detail"></span>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="<%=api.appname%>-check_btn" data-update-app="<%=api.appname%>"
|
||||
onclick="onBtnClick(this, appname);" value="<%:Check update%>" />
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="_<%=api.appname%>-force_btn" data-update-app="<%=api.appname%>"
|
||||
onclick="doUpdate(this, appname);" value="<%:Force update%>" style="display:none" />
|
||||
<span id="<%=api.appname%>-check_btn-detail"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%for k, v in pairs(com) do%>
|
||||
<%for _, k in ipairs(com.order) do
|
||||
local v = com[k]
|
||||
%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%=v.name%>
|
||||
<%:Version%>
|
||||
@@ -243,9 +324,9 @@ local com = self.com
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-description">
|
||||
<span>【 <span class="com_version" key="<%=k%>"><%=translate("Null")%></span> 】</span>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="_<%=k%>-check_btn"
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="_<%=k%>-check_btn" data-update-app="<%=k%>"
|
||||
onclick="onBtnClick(this,'<%=k%>');" value="<%:Check update%>" />
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="_<%=k%>-force_btn"
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="_<%=k%>-force_btn" data-update-app="<%=k%>"
|
||||
onclick="doUpdate(this,'<%=k%>');" value="<%:Force update%>" style="display:none"/>
|
||||
<span id="_<%=k%>-check_btn-detail"></span>
|
||||
</div>
|
||||
@@ -262,7 +343,7 @@ local com = self.com
|
||||
let key = coms[i].getAttribute("key");
|
||||
coms[i].innerHTML = "<%=translate("Collecting data...")%>";
|
||||
XHR.get('<%=api.url("version_")%>' + key, null, function(x, result) {
|
||||
if (x.status == 200 && result.code == 1) {
|
||||
if (x && x.status == 200 && result && result.code == 1) {
|
||||
let data = result.data;
|
||||
let t = "<%=translate("Null")%>";
|
||||
if (data && data != "")
|
||||
|
||||
Reference in new issue
Block a user