mirror of
https://github.com/kenzok8/small-package.git
synced 2026-02-08 07:37:13 +08:00
update 2023-03-21 16:22:45
This commit is contained in:
@@ -6116,7 +6116,6 @@
|
||||
88cdn.com
|
||||
88chuangyewang.com
|
||||
88dushu.com
|
||||
88eq.com
|
||||
88fenxiao.com
|
||||
88h3.com
|
||||
88hd.com
|
||||
@@ -6605,7 +6604,6 @@
|
||||
94afx.com
|
||||
94cb.com
|
||||
94cto.com
|
||||
94dreamer.com
|
||||
94dwc.com
|
||||
94he38.com
|
||||
94i5.com
|
||||
@@ -22842,7 +22840,6 @@ fzn.cc
|
||||
fzrsrc.com
|
||||
fzshbx.org
|
||||
fzsjob.com
|
||||
fzswy.com
|
||||
fzwcn.com
|
||||
fzxiaomange.com
|
||||
fzxyyqd.com
|
||||
@@ -23056,7 +23053,6 @@ gaochengnews.net
|
||||
gaochun.info
|
||||
gaodabio.com
|
||||
gaodage.com
|
||||
gaodalei.com
|
||||
gaode.com
|
||||
gaodilicai.com
|
||||
gaoding.com
|
||||
@@ -23418,7 +23414,6 @@ gelonghui.com
|
||||
gelu.me
|
||||
gemchina.com
|
||||
gemdale.com
|
||||
gemgsx.com
|
||||
gemii.cc
|
||||
gemini-galaxy.com
|
||||
gemini530.net
|
||||
@@ -23639,7 +23634,6 @@ gimhoy.com
|
||||
gimmgimm.com
|
||||
gimoo.net
|
||||
ginshio.org
|
||||
gio.ren
|
||||
giocdn.com
|
||||
gionee.com
|
||||
gionee.net
|
||||
@@ -28841,7 +28835,6 @@ ibtsat.com
|
||||
ibuick.com
|
||||
ibuscloud.com
|
||||
ibuychem.com
|
||||
ibuying.com
|
||||
ibw.cc
|
||||
ibytedapm.com
|
||||
ic-ldo.com
|
||||
@@ -29253,7 +29246,6 @@ iegcom.com
|
||||
iegee.net
|
||||
iegourl.com
|
||||
iejiu.com
|
||||
ielts68.com
|
||||
ieltschn.com
|
||||
iemblog.com
|
||||
iemiq.com
|
||||
@@ -37546,7 +37538,6 @@ maiwe.com
|
||||
maiweikj.com
|
||||
maixhub.com
|
||||
maixiaba.com
|
||||
maixj.net
|
||||
maixuewen.com
|
||||
maiya91.com
|
||||
maiyaole.com
|
||||
@@ -39881,7 +39872,6 @@ mysinamail.com
|
||||
mysipo.com
|
||||
mysiteres.com
|
||||
mysmth.net
|
||||
mysodao.com
|
||||
mysongktv.com
|
||||
mysore-yoga.com
|
||||
myspain.org
|
||||
@@ -41785,7 +41775,6 @@ ourjg.com
|
||||
ourjiangsu.com
|
||||
ourjs.com
|
||||
ourjz.com
|
||||
ourku.com
|
||||
ourlife365.com
|
||||
ourlinc.com
|
||||
ourpalm.com
|
||||
@@ -47438,7 +47427,6 @@ shijueju.com
|
||||
shikang.net
|
||||
shikee.com
|
||||
shiku.co
|
||||
shilawyer.com
|
||||
shileizcc.com
|
||||
shileizuji.com
|
||||
shilian.com
|
||||
@@ -48536,7 +48524,6 @@ sm160.net
|
||||
sm688801.com
|
||||
sm688839.com
|
||||
sm96596.com
|
||||
smabaike.com
|
||||
smalljun.com
|
||||
smallk.net
|
||||
smallpdfer.com
|
||||
@@ -49108,7 +49095,6 @@ spdl.com
|
||||
spdydns.com
|
||||
specialcdnstatus.com
|
||||
speed-dns.cc
|
||||
speed-idc.com
|
||||
speedcdns.com
|
||||
speednt.com
|
||||
speedpan.net
|
||||
@@ -50591,7 +50577,6 @@ tanyu.mobi
|
||||
tanyuantech.com
|
||||
tanzhouedu.com
|
||||
tanzhoujiaoyu.com
|
||||
tanzhouvip.com
|
||||
tao-jiujiu.com
|
||||
tao-star.com
|
||||
tao-studio.net
|
||||
@@ -55501,7 +55486,6 @@ wetaoke.com
|
||||
wetest.net
|
||||
wetherm.com
|
||||
weti.me
|
||||
wetogame.com
|
||||
weton.net
|
||||
wetruetech.com
|
||||
wetsd.com
|
||||
@@ -58482,7 +58466,6 @@ xinyisemi.com
|
||||
xinyitt.com
|
||||
xinyo100.com
|
||||
xinyongbuy.com
|
||||
xinyongqingdao.com
|
||||
xinyou.com
|
||||
xinyour.com
|
||||
xinyouw.org
|
||||
@@ -61911,7 +61894,6 @@ yulorepages.com
|
||||
yulu1.com
|
||||
yulu5.com
|
||||
yulucn.com
|
||||
yuluzhongde.com
|
||||
yumaoshu.com
|
||||
yumchina.com
|
||||
yumenikki.info
|
||||
@@ -63948,7 +63930,6 @@ zhuoshixiong.com
|
||||
zhuotingwl.com
|
||||
zhuotujiaoyu.com
|
||||
zhuoyi.com
|
||||
zhuoyicp.com
|
||||
zhuoyigame.com
|
||||
zhuoyigame.site
|
||||
zhuoyixuan.com
|
||||
@@ -64049,7 +64030,6 @@ ziguhonglan.com
|
||||
zihai0351.com
|
||||
zihai0535.com
|
||||
zihai0591.com
|
||||
zihai0595.com
|
||||
zihai24.com
|
||||
zihaixiaochengxu.com
|
||||
zihexin.net
|
||||
|
||||
@@ -580,6 +580,7 @@
|
||||
18qiu.com
|
||||
18qt.com
|
||||
18schoolgirlz.me
|
||||
18sex.org
|
||||
18soo.com
|
||||
18virginsex.com
|
||||
18x8bet.com
|
||||
@@ -817,6 +818,7 @@
|
||||
249057.cc
|
||||
2493598.com
|
||||
24hdrama.net
|
||||
24hjav.com
|
||||
24k88.com
|
||||
24porn.com
|
||||
24porn.pro
|
||||
@@ -1203,6 +1205,8 @@
|
||||
3utilities.com
|
||||
3x3avalanche.com
|
||||
3xplanet.com
|
||||
3xplanet.net
|
||||
3xplanetimg.com
|
||||
40030d.com
|
||||
400ks.com
|
||||
4022011.com
|
||||
@@ -3428,6 +3432,7 @@ alternate-tools.com
|
||||
alternativeto.net
|
||||
altmd.com
|
||||
altmetric.com
|
||||
altporn.net
|
||||
altrec.com
|
||||
altt.me
|
||||
altvpn.com
|
||||
@@ -3826,6 +3831,7 @@ aopshc.com
|
||||
aorus.com
|
||||
aosintegrity.com
|
||||
aouwe.com
|
||||
aoxx69.net
|
||||
ap-bangkok.myqcloud.com
|
||||
ap-hongkong.myqcloud.com
|
||||
ap-jakarta.myqcloud.com
|
||||
@@ -4297,6 +4303,7 @@ asproexapi.com
|
||||
asredas.com
|
||||
ass4all.com
|
||||
assembla.com
|
||||
assesphoto.com
|
||||
assetsadobe.com
|
||||
assetshare.box.com
|
||||
asshole.com
|
||||
@@ -4483,6 +4490,7 @@ avbuy.cc
|
||||
avcar.vip
|
||||
avcens.xyz
|
||||
avcity.tv
|
||||
avcnn.com
|
||||
avcolle.ml
|
||||
avcool.com
|
||||
avcrempie.com
|
||||
@@ -4561,6 +4569,7 @@ avstar9.com
|
||||
avstry.com
|
||||
avt-global.com
|
||||
avwong.com
|
||||
avwto.com
|
||||
avxde.org
|
||||
avxhm.is
|
||||
avxlive.icu
|
||||
@@ -7248,6 +7257,7 @@ catbombmusic.com
|
||||
catcatforum.com
|
||||
catch22.net
|
||||
catchgod.com
|
||||
catchplay.com
|
||||
catchvideo.net
|
||||
catfi.com
|
||||
cathay.com
|
||||
@@ -11605,6 +11615,7 @@ filmporno.it
|
||||
filmschoolrejects.com
|
||||
filmsexeporno.com
|
||||
filterbypass.me
|
||||
filtercams.com
|
||||
filtersbypass.com
|
||||
filthdump.com
|
||||
fimfiction.net
|
||||
@@ -14532,6 +14543,7 @@ holdemstripem.com
|
||||
holeinthewallhosting.net
|
||||
holeyfuck.com
|
||||
holloporn.com
|
||||
hollyrandall.com
|
||||
hololens.com
|
||||
holymountaincn.com
|
||||
holyshit.com
|
||||
@@ -15004,6 +15016,7 @@ huobiasia.vip
|
||||
huobigroup.com
|
||||
huobipro.com
|
||||
huobitoken.com
|
||||
huohaore.net
|
||||
huomie.com
|
||||
huoqiang.club
|
||||
huping.net
|
||||
@@ -16204,6 +16217,7 @@ jasmin.com
|
||||
jasoncoyne.com
|
||||
jav-1080.com
|
||||
jav-720p.com
|
||||
jav-angel.net
|
||||
jav-legend.com
|
||||
jav-onlines.com
|
||||
jav-subtitles.com
|
||||
@@ -16327,6 +16341,7 @@ javmost.xyz
|
||||
javmuch.com
|
||||
javnew.net
|
||||
javocado.com
|
||||
javopen.co
|
||||
javout.co
|
||||
javplatform.com
|
||||
javpop.com
|
||||
@@ -16350,6 +16365,7 @@ javsharing.com
|
||||
javsin.com
|
||||
javsin.tv
|
||||
javspanking.com
|
||||
javstar.club
|
||||
javtag.com
|
||||
javtag.net
|
||||
javtasty.com
|
||||
@@ -16656,6 +16672,7 @@ jp-sex.com
|
||||
jp.hao123.com
|
||||
jp01-28.ssv4.net
|
||||
jpavcom.com
|
||||
jpbabe.com
|
||||
jpboy1069.net
|
||||
jpg4.biz
|
||||
jpg4.info
|
||||
@@ -16700,6 +16717,7 @@ jsdelivr.net
|
||||
jsfiddle.net
|
||||
jsok369.com
|
||||
jstor.org
|
||||
jsz91.com
|
||||
jtbc.joins.com
|
||||
jtfx.mobi
|
||||
jtube.space
|
||||
@@ -17961,6 +17979,7 @@ lovedolltorso.com
|
||||
lovegirls.cam
|
||||
loveherbsoap.com
|
||||
lovehomeporn.com
|
||||
lovejav.net
|
||||
loveloveskill.com
|
||||
lovemarca.com
|
||||
lovemov.cc
|
||||
@@ -18235,6 +18254,7 @@ ma
|
||||
ma.hao123.com
|
||||
ma1lib.org
|
||||
ma8009.com
|
||||
maa1815.com
|
||||
maasstadbv.com
|
||||
mabelleepoque.ch
|
||||
mabutou.com
|
||||
@@ -18899,6 +18919,7 @@ microsoftadvertising.com
|
||||
microsoftadvertisingregionalawards.com
|
||||
microsoftaffiliates.com
|
||||
microsoftapp.net
|
||||
microsoftazuresponsorships.com
|
||||
microsoftcloud.com
|
||||
microsoftcloudsummit.com
|
||||
microsoftcloudworkshop.com
|
||||
@@ -20823,6 +20844,7 @@ nudekenya.com
|
||||
nudelive.com
|
||||
nudematurewomenpics.com
|
||||
nudes7.com
|
||||
nudespree.com
|
||||
nudeteen.org
|
||||
nudeteenboys.net
|
||||
nudeteenladies.com
|
||||
@@ -21881,6 +21903,7 @@ pecelmadiun.web.id
|
||||
pedophiles.org
|
||||
peeasian.com
|
||||
peekier.com
|
||||
peekvids.com
|
||||
peepholecam.com
|
||||
peerj.com
|
||||
peersfer.com
|
||||
@@ -22426,6 +22449,7 @@ pornfactory.info
|
||||
pornfidelity.com
|
||||
pornfind.org
|
||||
pornfinder.biz
|
||||
pornflip.com
|
||||
pornfoolery.com
|
||||
pornfromczech.com
|
||||
pornfu.tv
|
||||
@@ -22464,7 +22488,10 @@ pornheli.com
|
||||
pornhits.com
|
||||
pornhoho.com
|
||||
pornhost.com
|
||||
pornhub-deutsch.info
|
||||
pornhub-deutsch.net
|
||||
pornhub-german.com
|
||||
pornhub-sexfilme.net
|
||||
pornhub.com
|
||||
pornhub.it
|
||||
pornhub.net
|
||||
@@ -22478,6 +22505,7 @@ pornhubpremium.com
|
||||
pornhubs.video
|
||||
pornhubselect.com
|
||||
pornhun.xyz
|
||||
pornhutdeutsch.com
|
||||
pornhuub.xyz
|
||||
pornicom.com
|
||||
pornimg.xyz
|
||||
@@ -24611,6 +24639,8 @@ sexy-word.com
|
||||
sexy.com
|
||||
sexy3dtoon.com
|
||||
sexyandfunny.com
|
||||
sexyavenue.com
|
||||
sexybabesz.com
|
||||
sexycandidgirls.com
|
||||
sexyculo.com
|
||||
sexyfeet.tv
|
||||
@@ -25201,6 +25231,7 @@ softbankworld.com
|
||||
softether-download.com
|
||||
softether.org
|
||||
softfamous.com
|
||||
softmodels.net
|
||||
softnology.biz
|
||||
softs.fun
|
||||
softsmirror.cf
|
||||
@@ -26652,6 +26683,7 @@ thestuarts.ch
|
||||
thesunbehindtheclouds.com
|
||||
theteenhome.com
|
||||
thetend.com
|
||||
thethothub.com
|
||||
thetibetcenter.org
|
||||
thetibetconnection.org
|
||||
thetibetmuseum.org
|
||||
@@ -27014,6 +27046,7 @@ topadultgames.biz
|
||||
topalbums.club
|
||||
topanime.biz
|
||||
topartporn.com
|
||||
topbabesblog.org
|
||||
topbeatsbydrdreoutlet.com
|
||||
topbeatsdealer.com
|
||||
topbeatsforsale.com
|
||||
@@ -33673,6 +33706,7 @@ xjtravelguide.com
|
||||
xk.freepac.pw
|
||||
xkeezmovies.com
|
||||
xknoop.com
|
||||
xkontakt18.com
|
||||
xkorean.cam
|
||||
xl-gaytube.com
|
||||
xlecx.org
|
||||
|
||||
@@ -8,11 +8,6 @@ local ucic = luci.model.uci.cursor()
|
||||
local http = require "luci.http"
|
||||
local util = require "luci.util"
|
||||
local i18n = require "luci.i18n"
|
||||
local brook = require("luci.passwall.brook")
|
||||
local v2ray = require("luci.passwall.v2ray")
|
||||
local xray = require("luci.passwall.xray")
|
||||
local trojan_go = require("luci.passwall.trojan_go")
|
||||
local hysteria = require("luci.passwall.hysteria")
|
||||
|
||||
function index()
|
||||
appname = require "luci.passwall.api".appname
|
||||
@@ -72,16 +67,14 @@ function index()
|
||||
entry({"admin", "services", appname, "clear_all_nodes"}, call("clear_all_nodes")).leaf = true
|
||||
entry({"admin", "services", appname, "delete_select_nodes"}, call("delete_select_nodes")).leaf = true
|
||||
entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true
|
||||
entry({"admin", "services", appname, "brook_check"}, call("brook_check")).leaf = true
|
||||
entry({"admin", "services", appname, "brook_update"}, call("brook_update")).leaf = true
|
||||
entry({"admin", "services", appname, "v2ray_check"}, call("v2ray_check")).leaf = true
|
||||
entry({"admin", "services", appname, "v2ray_update"}, call("v2ray_update")).leaf = true
|
||||
entry({"admin", "services", appname, "xray_check"}, call("xray_check")).leaf = true
|
||||
entry({"admin", "services", appname, "xray_update"}, call("xray_update")).leaf = true
|
||||
entry({"admin", "services", appname, "trojan_go_check"}, call("trojan_go_check")).leaf = true
|
||||
entry({"admin", "services", appname, "trojan_go_update"}, call("trojan_go_update")).leaf = true
|
||||
entry({"admin", "services", appname, "hysteria_check"}, call("hysteria_check")).leaf = true
|
||||
entry({"admin", "services", appname, "hysteria_update"}, call("hysteria_update")).leaf = true
|
||||
|
||||
--[[Components update]]
|
||||
local coms = require "luci.passwall.com"
|
||||
local com
|
||||
for com, _ in pairs(coms) 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
|
||||
end
|
||||
end
|
||||
|
||||
local function http_write_json(content)
|
||||
@@ -410,94 +403,21 @@ function server_clear_log()
|
||||
luci.sys.call("echo '' > /tmp/log/passwall_server.log")
|
||||
end
|
||||
|
||||
function brook_check()
|
||||
local json = brook.to_check("")
|
||||
function com_check(comname)
|
||||
local json = api.to_check("",comname)
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function brook_update()
|
||||
local json = nil
|
||||
local task = http.formvalue("task")
|
||||
if task == "move" then
|
||||
json = brook.to_move(http.formvalue("file"))
|
||||
else
|
||||
json = brook.to_download(http.formvalue("url"), http.formvalue("size"))
|
||||
end
|
||||
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function v2ray_check()
|
||||
local json = v2ray.to_check("")
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function v2ray_update()
|
||||
function com_update(comname)
|
||||
local json = nil
|
||||
local task = http.formvalue("task")
|
||||
if task == "extract" then
|
||||
json = v2ray.to_extract(http.formvalue("file"), http.formvalue("subfix"))
|
||||
json = api.to_extract(comname, http.formvalue("file"), http.formvalue("subfix"))
|
||||
elseif task == "move" then
|
||||
json = v2ray.to_move(http.formvalue("file"))
|
||||
json = api.to_move(comname, http.formvalue("file"))
|
||||
else
|
||||
json = v2ray.to_download(http.formvalue("url"), http.formvalue("size"))
|
||||
json = api.to_download(comname, http.formvalue("url"), http.formvalue("size"))
|
||||
end
|
||||
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function xray_check()
|
||||
local json = xray.to_check("")
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function xray_update()
|
||||
local json = nil
|
||||
local task = http.formvalue("task")
|
||||
if task == "extract" then
|
||||
json = xray.to_extract(http.formvalue("file"), http.formvalue("subfix"))
|
||||
elseif task == "move" then
|
||||
json = xray.to_move(http.formvalue("file"))
|
||||
else
|
||||
json = xray.to_download(http.formvalue("url"), http.formvalue("size"))
|
||||
end
|
||||
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function trojan_go_check()
|
||||
local json = trojan_go.to_check("")
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function trojan_go_update()
|
||||
local json = nil
|
||||
local task = http.formvalue("task")
|
||||
if task == "extract" then
|
||||
json = trojan_go.to_extract(http.formvalue("file"), http.formvalue("subfix"))
|
||||
elseif task == "move" then
|
||||
json = trojan_go.to_move(http.formvalue("file"))
|
||||
else
|
||||
json = trojan_go.to_download(http.formvalue("url"), http.formvalue("size"))
|
||||
end
|
||||
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function hysteria_check()
|
||||
local json = hysteria.to_check("")
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function hysteria_update()
|
||||
local json = nil
|
||||
local task = http.formvalue("task")
|
||||
if task == "move" then
|
||||
json = hysteria.to_move(http.formvalue("file"))
|
||||
else
|
||||
json = hysteria.to_download(http.formvalue("url"), http.formvalue("size"))
|
||||
end
|
||||
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
|
||||
@@ -9,31 +9,15 @@ s = m:section(TypedSection, "global_app", translate("App Update"),
|
||||
translate("Please confirm that your firmware supports FPU.") ..
|
||||
"</font>")
|
||||
s.anonymous = true
|
||||
s:append(Template(appname .. "/app_update/v2ray_version"))
|
||||
s:append(Template(appname .. "/app_update/xray_version"))
|
||||
s:append(Template(appname .. "/app_update/trojan_go_version"))
|
||||
s:append(Template(appname .. "/app_update/brook_version"))
|
||||
s:append(Template(appname .. "/app_update/hysteria_version"))
|
||||
s:append(Template(appname .. "/app_update/app_version"))
|
||||
|
||||
o = s:option(Value, "v2ray_file", translatef("%s App Path", "V2ray"))
|
||||
o.default = "/usr/bin/v2ray"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "xray_file", translatef("%s App Path", "Xray"))
|
||||
o.default = "/usr/bin/xray"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "trojan_go_file", translatef("%s App Path", "Trojan-Go"))
|
||||
o.default = "/usr/bin/trojan-go"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "brook_file", translatef("%s App Path", "Brook"))
|
||||
o.default = "/usr/bin/brook"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "hysteria_file", translatef("%s App Path", "Hysteria"))
|
||||
o.default = "/usr/bin/hysteria"
|
||||
o.rmempty = false
|
||||
local k, v
|
||||
local com = require "luci.passwall.com"
|
||||
for k, v in pairs(com) do
|
||||
o = s:option(Value, k:gsub("%-","_") .. "_file", translatef("%s App Path", v.name))
|
||||
o.default = v.default_path or ("/usr/bin/"..k)
|
||||
o.rmempty = false
|
||||
end
|
||||
|
||||
o = s:option(DummyValue, "tips", " ")
|
||||
o.rawhtml = true
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
module("luci.passwall.api", package.seeall)
|
||||
local com = require "luci.passwall.com"
|
||||
fs = require "nixio.fs"
|
||||
sys = require "luci.sys"
|
||||
uci = require"luci.model.uci".cursor()
|
||||
@@ -10,8 +11,8 @@ i18n = require "luci.i18n"
|
||||
appname = "passwall"
|
||||
curl_args = { "-skfL", "--connect-timeout 3", "--retry 3", "-m 60" }
|
||||
command_timeout = 300
|
||||
LEDE_BOARD = nil
|
||||
DISTRIB_TARGET = nil
|
||||
OPENWRT_ARCH = nil
|
||||
DISTRIB_ARCH = nil
|
||||
|
||||
LOG_FILE = "/tmp/log/" .. appname .. ".log"
|
||||
CACHE_PATH = "/tmp/etc/" .. appname .. "_tmp"
|
||||
@@ -360,7 +361,7 @@ function uci_get_type_id(id, config, default)
|
||||
return value
|
||||
end
|
||||
|
||||
function chmod_755(file)
|
||||
local function chmod_755(file)
|
||||
if file and file ~= "" then
|
||||
if not fs.access(file, "rwx", "rx", "rx") then
|
||||
fs.chmod(file, 755)
|
||||
@@ -393,7 +394,7 @@ function clone(org)
|
||||
return res
|
||||
end
|
||||
|
||||
function get_bin_version_cache(file, cmd)
|
||||
local function get_bin_version_cache(file, cmd)
|
||||
sys.call("mkdir -p /tmp/etc/passwall_tmp")
|
||||
if fs.access(file) then
|
||||
chmod_755(file)
|
||||
@@ -411,62 +412,17 @@ function get_bin_version_cache(file, cmd)
|
||||
return ""
|
||||
end
|
||||
|
||||
function get_v2ray_path()
|
||||
local path = uci_get_type("global_app", "v2ray_file")
|
||||
function get_app_path(app_name)
|
||||
local path = uci_get_type("global_app", app_name:gsub("%-","_") .. "_file")
|
||||
return path
|
||||
end
|
||||
|
||||
function get_v2ray_version(file)
|
||||
if file == nil then file = get_v2ray_path() end
|
||||
local cmd = "version | awk '{print $2}' | sed -n 1P"
|
||||
return get_bin_version_cache(file, cmd)
|
||||
function get_app_version(app_name, file)
|
||||
if file == nil then file = get_app_path(app_name) end
|
||||
return get_bin_version_cache(file, com[app_name].cmd_version)
|
||||
end
|
||||
|
||||
function get_xray_path()
|
||||
local path = uci_get_type("global_app", "xray_file")
|
||||
return path
|
||||
end
|
||||
|
||||
function get_xray_version(file)
|
||||
if file == nil then file = get_xray_path() end
|
||||
local cmd = "-version | awk '{print $2}' | sed -n 1P"
|
||||
return get_bin_version_cache(file, cmd)
|
||||
end
|
||||
|
||||
function get_trojan_go_path()
|
||||
local path = uci_get_type("global_app", "trojan_go_file")
|
||||
return path
|
||||
end
|
||||
|
||||
function get_trojan_go_version(file)
|
||||
if file == nil then file = get_trojan_go_path() end
|
||||
local cmd = "-version | awk '{print $2}' | sed -n 1P"
|
||||
return get_bin_version_cache(file, cmd)
|
||||
end
|
||||
|
||||
function get_brook_path()
|
||||
local path = uci_get_type("global_app", "brook_file")
|
||||
return path
|
||||
end
|
||||
|
||||
function get_brook_version(file)
|
||||
if file == nil then file = get_brook_path() end
|
||||
local cmd = "-v | awk '{print $3}'"
|
||||
return get_bin_version_cache(file, cmd)
|
||||
end
|
||||
|
||||
function get_hysteria_path()
|
||||
local path = uci_get_type("global_app", "hysteria_file")
|
||||
return path
|
||||
end
|
||||
|
||||
function get_hysteria_version(file)
|
||||
if file == nil then file = get_hysteria_path() end
|
||||
local cmd = "-v | awk '{print $3}'"
|
||||
return get_bin_version_cache(file, cmd)
|
||||
end
|
||||
|
||||
function is_file(path)
|
||||
local function is_file(path)
|
||||
if path and #path > 1 then
|
||||
if sys.exec('[ -f "%s" ] && echo -n 1' % path) == "1" then
|
||||
return true
|
||||
@@ -475,7 +431,7 @@ function is_file(path)
|
||||
return nil
|
||||
end
|
||||
|
||||
function is_dir(path)
|
||||
local function is_dir(path)
|
||||
if path and #path > 1 then
|
||||
if sys.exec('[ -d "%s" ] && echo -n 1' % path) == "1" then
|
||||
return true
|
||||
@@ -484,7 +440,7 @@ function is_dir(path)
|
||||
return nil
|
||||
end
|
||||
|
||||
function get_final_dir(path)
|
||||
local function get_final_dir(path)
|
||||
if is_dir(path) then
|
||||
return path
|
||||
else
|
||||
@@ -492,7 +448,7 @@ function get_final_dir(path)
|
||||
end
|
||||
end
|
||||
|
||||
function get_free_space(dir)
|
||||
local function get_free_space(dir)
|
||||
if dir == nil then dir = "/" end
|
||||
if sys.call("df -k " .. dir .. " >/dev/null 2>&1") == 0 then
|
||||
return tonumber(sys.exec("echo -n $(df -k " .. dir .. " | awk 'NR>1' | awk '{print $4}')"))
|
||||
@@ -500,7 +456,7 @@ function get_free_space(dir)
|
||||
return 0
|
||||
end
|
||||
|
||||
function get_file_space(file)
|
||||
local function get_file_space(file)
|
||||
if file == nil then return 0 end
|
||||
if fs.access(file) then
|
||||
return tonumber(sys.exec("echo -n $(du -k " .. file .. " | awk '{print $1}')"))
|
||||
@@ -524,7 +480,7 @@ function table_join(t, s)
|
||||
return str
|
||||
end
|
||||
|
||||
function exec(cmd, args, writer, timeout)
|
||||
local function exec(cmd, args, writer, timeout)
|
||||
local os = require "os"
|
||||
local nixio = require "nixio"
|
||||
|
||||
@@ -569,7 +525,7 @@ function exec(cmd, args, writer, timeout)
|
||||
end
|
||||
end
|
||||
|
||||
function compare_versions(ver1, comp, ver2)
|
||||
local function compare_versions(ver1, comp, ver2)
|
||||
local table = table
|
||||
|
||||
if not ver1 then ver1 = "" end
|
||||
@@ -595,27 +551,37 @@ function compare_versions(ver1, comp, ver2)
|
||||
return not (comp == "<" or comp == ">")
|
||||
end
|
||||
|
||||
function auto_get_arch()
|
||||
local function auto_get_arch()
|
||||
local arch = nixio.uname().machine or ""
|
||||
if fs.access("/usr/lib/os-release") then
|
||||
LEDE_BOARD = sys.exec("echo -n $(grep 'LEDE_BOARD' /usr/lib/os-release | awk -F '[\\042\\047]' '{print $2}')")
|
||||
if not OPENWRT_ARCH and fs.access("/usr/lib/os-release") then
|
||||
OPENWRT_ARCH = sys.exec("echo -n $(grep 'OPENWRT_ARCH' /usr/lib/os-release | awk -F '[\\042\\047]' '{print $2}')")
|
||||
if OPENWRT_ARCH == "" then OPENWRT_ARCH = nil end
|
||||
end
|
||||
if fs.access("/etc/openwrt_release") then
|
||||
DISTRIB_TARGET = sys.exec("echo -n $(grep 'DISTRIB_TARGET' /etc/openwrt_release | awk -F '[\\042\\047]' '{print $2}')")
|
||||
if not DISTRIB_ARCH and fs.access("/etc/openwrt_release") then
|
||||
DISTRIB_ARCH = sys.exec("echo -n $(grep 'DISTRIB_ARCH' /etc/openwrt_release | awk -F '[\\042\\047]' '{print $2}')")
|
||||
if DISTRIB_ARCH == "" then DISTRIB_ARCH = nil end
|
||||
end
|
||||
|
||||
if arch == "mips" then
|
||||
if LEDE_BOARD and LEDE_BOARD ~= "" then
|
||||
if string.match(LEDE_BOARD, "ramips") == "ramips" then
|
||||
arch = "ramips"
|
||||
else
|
||||
arch = sys.exec("echo '" .. LEDE_BOARD .. "' | grep -oE 'ramips|ar71xx'")
|
||||
if arch:match("^i[%d]86$") then
|
||||
arch = "x86"
|
||||
elseif arch:match("armv5") then -- armv5l
|
||||
arch = "armv5"
|
||||
elseif arch:match("armv6") then
|
||||
arch = "armv6"
|
||||
elseif arch:match("armv7") then -- armv7l
|
||||
arch = "armv7"
|
||||
end
|
||||
elseif DISTRIB_TARGET and DISTRIB_TARGET ~= "" then
|
||||
if string.match(DISTRIB_TARGET, "ramips") == "ramips" then
|
||||
arch = "ramips"
|
||||
else
|
||||
arch = sys.exec("echo '" .. DISTRIB_TARGET .. "' | grep -oE 'ramips|ar71xx'")
|
||||
|
||||
if OPENWRT_ARCH or DISTRIB_ARCH then
|
||||
if arch == "mips" then
|
||||
if OPENWRT_ARCH and OPENWRT_ARCH:match("mipsel") == "mipsel"
|
||||
or DISTRIB_ARCH and DISTRIB_ARCH:match("mipsel") == "mipsel" then
|
||||
arch = "mipsel"
|
||||
end
|
||||
elseif arch == "armv7" then
|
||||
if OPENWRT_ARCH and not OPENWRT_ARCH:match("vfp") and not OPENWRT_ARCH:match("neon")
|
||||
or DISTRIB_ARCH and not DISTRIB_ARCH:match("vfp") and not DISTRIB_ARCH:match("neon") then
|
||||
arch = "armv5"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -623,44 +589,59 @@ function auto_get_arch()
|
||||
return util.trim(arch)
|
||||
end
|
||||
|
||||
function get_file_info(arch)
|
||||
local file_tree = ""
|
||||
local sub_version = ""
|
||||
local default_file_tree = {
|
||||
x86_64 = "amd64",
|
||||
x86 = "386",
|
||||
aarch64 = "arm64",
|
||||
mips = "mips",
|
||||
mipsel = "mipsle",
|
||||
armv5 = "arm.*5",
|
||||
armv6 = "arm.*6[^4]*",
|
||||
armv7 = "arm.*7",
|
||||
armv8 = "arm64"
|
||||
}
|
||||
|
||||
if arch == "x86_64" then
|
||||
file_tree = "amd64"
|
||||
elseif arch == "aarch64" then
|
||||
file_tree = "arm64"
|
||||
elseif arch == "ramips" then
|
||||
file_tree = "mipsle"
|
||||
elseif arch == "ar71xx" then
|
||||
file_tree = "mips"
|
||||
elseif arch:match("^i[%d]86$") then
|
||||
file_tree = "386"
|
||||
elseif arch:match("^armv[5-8]") then
|
||||
file_tree = "arm"
|
||||
sub_version = arch:match("[5-8]")
|
||||
if LEDE_BOARD and string.match(LEDE_BOARD, "bcm53xx") == "bcm53xx" then
|
||||
sub_version = "5"
|
||||
elseif DISTRIB_TARGET and string.match(DISTRIB_TARGET, "bcm53xx") ==
|
||||
"bcm53xx" then
|
||||
sub_version = "5"
|
||||
end
|
||||
sub_version = "5"
|
||||
end
|
||||
|
||||
return file_tree, sub_version
|
||||
end
|
||||
|
||||
function get_api_json(url)
|
||||
local function get_api_json(url)
|
||||
local jsonc = require "luci.jsonc"
|
||||
local return_code, content = curl_logic(url, nil, curl_args)
|
||||
if return_code ~= 0 or content == "" then return {} end
|
||||
return jsonc.parse(content) or {}
|
||||
end
|
||||
|
||||
function common_to_check(api_url, local_version, match_file_name)
|
||||
local json = get_api_json(api_url)
|
||||
local function check_path(app_name)
|
||||
local path = get_app_path(app_name) or ""
|
||||
if path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", app_name)
|
||||
}
|
||||
end
|
||||
return {
|
||||
code = 0,
|
||||
app_path = path
|
||||
}
|
||||
end
|
||||
|
||||
function to_check(arch, app_name)
|
||||
local result = check_path(app_name)
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not arch or arch == "" then arch = auto_get_arch() end
|
||||
|
||||
local file_tree = com[app_name].file_tree[arch] or default_file_tree[arch] or ""
|
||||
|
||||
if file_tree == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Can't determine ARCH, or ARCH not supported.")
|
||||
}
|
||||
end
|
||||
|
||||
local local_version = get_app_version(app_name)
|
||||
local match_file_name = string.format(com[app_name].match_fmt_str, file_tree)
|
||||
local json = get_api_json(com[app_name]:get_url())
|
||||
|
||||
if #json > 0 then
|
||||
json = json[1]
|
||||
@@ -711,3 +692,142 @@ function common_to_check(api_url, local_version, match_file_name)
|
||||
data = asset
|
||||
}
|
||||
end
|
||||
|
||||
function to_download(app_name, url, size)
|
||||
local result = check_path(app_name)
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not url or url == "" then
|
||||
return {code = 1, error = i18n.translate("Download url is required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -f /tmp/".. app_name .."_download.*")
|
||||
|
||||
local tmp_file = util.trim(util.exec("mktemp -u -t ".. app_name .."_download.XXXXXX"))
|
||||
|
||||
if size then
|
||||
local kb1 = get_free_space("/tmp")
|
||||
if tonumber(size) > tonumber(kb1) then
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")}
|
||||
end
|
||||
end
|
||||
|
||||
local return_code, result = curl_logic(url, tmp_file, curl_args)
|
||||
result = return_code == 0
|
||||
|
||||
if not result then
|
||||
exec("/bin/rm", {"-f", tmp_file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("File download failed or timed out: %s", url)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0, file = tmp_file, zip = com[app_name].zipped }
|
||||
end
|
||||
|
||||
function to_extract(app_name, file, subfix)
|
||||
local result = check_path(app_name)
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not file or file == "" or not fs.access(file) then
|
||||
return {code = 1, error = i18n.translate("File path required.")}
|
||||
end
|
||||
|
||||
if sys.exec("echo -n $(opkg list-installed | grep -c unzip)") ~= "1" then
|
||||
exec("/bin/rm", {"-f", file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Not installed unzip, Can't unzip!")
|
||||
}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/".. app_name .."_extract.*")
|
||||
|
||||
local new_file_size = get_file_space(file)
|
||||
local tmp_free_size = get_free_space("/tmp")
|
||||
if tmp_free_size <= 0 or tmp_free_size <= new_file_size then
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")}
|
||||
end
|
||||
|
||||
local tmp_dir = util.trim(util.exec("mktemp -d -t ".. app_name .."_extract.XXXXXX"))
|
||||
|
||||
local output = {}
|
||||
exec("/usr/bin/unzip", {"-o", file, app_name, "-d", tmp_dir},
|
||||
function(chunk) output[#output + 1] = chunk end)
|
||||
|
||||
local files = util.split(table.concat(output))
|
||||
|
||||
exec("/bin/rm", {"-f", file})
|
||||
|
||||
return {code = 0, file = tmp_dir}
|
||||
end
|
||||
|
||||
function to_move(app_name,file)
|
||||
local result = check_path(app_name)
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
local app_path = result.app_path
|
||||
local bin_path = file
|
||||
local cmd_rm_tmp = "/bin/rm -rf /tmp/" .. app_name .. "_download.*"
|
||||
if fs.stat(file, "type") == "dir" then
|
||||
bin_path = file .. "/" .. app_name
|
||||
cmd_rm_tmp = "/bin/rm -rf /tmp/" .. app_name .. "_extract.*"
|
||||
end
|
||||
|
||||
if not file or file == "" then
|
||||
sys.call(cmd_rm_tmp)
|
||||
return {code = 1, error = i18n.translate("Client file is required.")}
|
||||
end
|
||||
|
||||
local new_version = get_app_version(app_name, bin_path)
|
||||
if new_version == "" then
|
||||
sys.call(cmd_rm_tmp)
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("The client file is not suitable for current device.")..app_name.."__"..bin_path
|
||||
}
|
||||
end
|
||||
|
||||
local flag = sys.call('pgrep -af "passwall/.*'.. app_name ..'" >/dev/null')
|
||||
if flag == 0 then
|
||||
sys.call("/etc/init.d/passwall stop")
|
||||
end
|
||||
|
||||
local old_app_size = 0
|
||||
if fs.access(app_path) then
|
||||
old_app_size = get_file_space(app_path)
|
||||
end
|
||||
local new_app_size = get_file_space(bin_path)
|
||||
local final_dir = get_final_dir(app_path)
|
||||
local final_dir_free_size = get_free_space(final_dir)
|
||||
if final_dir_free_size > 0 then
|
||||
final_dir_free_size = final_dir_free_size + old_app_size
|
||||
if new_app_size > final_dir_free_size then
|
||||
sys.call(cmd_rm_tmp)
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", final_dir)}
|
||||
end
|
||||
end
|
||||
|
||||
result = exec("/bin/mv", { "-f", bin_path, app_path }, nil, command_timeout) == 0
|
||||
|
||||
sys.call(cmd_rm_tmp)
|
||||
if flag == 0 then
|
||||
sys.call("/etc/init.d/passwall restart >/dev/null 2>&1 &")
|
||||
end
|
||||
|
||||
if not result or not fs.access(app_path) then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Can't move new file to path: %s", app_path)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0}
|
||||
end
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
module("luci.passwall.brook", package.seeall)
|
||||
local api = require "luci.passwall.api"
|
||||
local fs = api.fs
|
||||
local sys = api.sys
|
||||
local util = api.util
|
||||
local i18n = api.i18n
|
||||
|
||||
local pre_release_url = "https://api.github.com/repos/txthinking/brook/releases?per_page=1"
|
||||
local release_url = "https://api.github.com/repos/txthinking/brook/releases/latest"
|
||||
local api_url = release_url
|
||||
local app_path = api.get_brook_path() or ""
|
||||
|
||||
function check_path()
|
||||
if app_path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", "Brook")
|
||||
}
|
||||
end
|
||||
return {
|
||||
code = 0
|
||||
}
|
||||
end
|
||||
|
||||
function to_check(arch)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not arch or arch == "" then arch = api.auto_get_arch() end
|
||||
|
||||
local file_tree, sub_version = api.get_file_info(arch)
|
||||
|
||||
if file_tree == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Can't determine ARCH, or ARCH not supported.")
|
||||
}
|
||||
end
|
||||
|
||||
return api.common_to_check(api_url, api.get_brook_version(), "linux_" .. file_tree .. sub_version)
|
||||
end
|
||||
|
||||
function to_download(url, size)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not url or url == "" then
|
||||
return {code = 1, error = i18n.translate("Download url is required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -f /tmp/brook_download.*")
|
||||
|
||||
local tmp_file = util.trim(util.exec("mktemp -u -t brook_download.XXXXXX"))
|
||||
|
||||
if size then
|
||||
local kb1 = api.get_free_space("/tmp")
|
||||
if tonumber(size) > tonumber(kb1) then
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")}
|
||||
end
|
||||
end
|
||||
|
||||
local return_code, result = api.curl_logic(url, tmp_file, api.curl_args)
|
||||
result = return_code == 0
|
||||
|
||||
if not result then
|
||||
api.exec("/bin/rm", {"-f", tmp_file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("File download failed or timed out: %s", url)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0, file = tmp_file}
|
||||
end
|
||||
|
||||
function to_move(file)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not file or file == "" or not fs.access(file) then
|
||||
sys.call("/bin/rm -rf /tmp/brook_download.*")
|
||||
return {code = 1, error = i18n.translate("Client file is required.")}
|
||||
end
|
||||
|
||||
local new_version = api.get_brook_version(file)
|
||||
if new_version == "" then
|
||||
sys.call("/bin/rm -rf /tmp/brook_download.*")
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("The client file is not suitable for current device.")
|
||||
}
|
||||
end
|
||||
|
||||
local flag = sys.call('pgrep -af "passwall/.*brook" >/dev/null')
|
||||
if flag == 0 then
|
||||
sys.call("/etc/init.d/passwall stop")
|
||||
end
|
||||
|
||||
local old_app_size = 0
|
||||
if fs.access(app_path) then
|
||||
old_app_size = api.get_file_space(app_path)
|
||||
end
|
||||
local new_app_size = api.get_file_space(file)
|
||||
local final_dir = api.get_final_dir(app_path)
|
||||
local final_dir_free_size = api.get_free_space(final_dir)
|
||||
if final_dir_free_size > 0 then
|
||||
final_dir_free_size = final_dir_free_size + old_app_size
|
||||
if new_app_size > final_dir_free_size then
|
||||
sys.call("/bin/rm -rf /tmp/brook_download.*")
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", final_dir)}
|
||||
end
|
||||
end
|
||||
|
||||
result = api.exec("/bin/mv", {"-f", file, app_path}, nil, api.command_timeout) == 0
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/brook_download.*")
|
||||
if flag == 0 then
|
||||
sys.call("/etc/init.d/passwall restart >/dev/null 2>&1 &")
|
||||
end
|
||||
|
||||
if not result or not fs.access(app_path) then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Can't move new file to path: %s", app_path)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0}
|
||||
end
|
||||
99
luci-app-passwall/luasrc/passwall/com.lua
Normal file
99
luci-app-passwall/luasrc/passwall/com.lua
Normal file
@@ -0,0 +1,99 @@
|
||||
local _M = {}
|
||||
|
||||
local function gh_release_url(self)
|
||||
return "https://api.github.com/repos/" .. self.repo .. "/releases/latest"
|
||||
end
|
||||
|
||||
local function gh_pre_release_url(self)
|
||||
return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1"
|
||||
end
|
||||
|
||||
_M.brook = {
|
||||
name = "Brook",
|
||||
repo = "txthinking/brook",
|
||||
get_url = gh_release_url,
|
||||
cmd_version = "-v | awk '{print $3}'",
|
||||
zipped = false,
|
||||
default_path = "/usr/bin/brook",
|
||||
match_fmt_str = "linux_%s$",
|
||||
file_tree = {}
|
||||
}
|
||||
|
||||
_M.hysteria = {
|
||||
name = "Hysteria",
|
||||
repo = "HyNetwork/hysteria",
|
||||
get_url = gh_release_url,
|
||||
cmd_version = "-v | awk '{print $3}'",
|
||||
zipped = false,
|
||||
default_path = "/usr/bin/hysteria",
|
||||
match_fmt_str = "linux%%-%s$",
|
||||
file_tree = {
|
||||
armv6 = "arm",
|
||||
armv7 = "arm"
|
||||
}
|
||||
}
|
||||
|
||||
_M["trojan-go"] = {
|
||||
name = "Trojan-Go",
|
||||
repo = "p4gefau1t/trojan-go",
|
||||
get_url = gh_release_url,
|
||||
cmd_version = "-version | awk '{print $2}' | sed -n 1P",
|
||||
zipped = true,
|
||||
default_path = "/usr/bin/trojan-go",
|
||||
match_fmt_str = "linux%%-%s%%.zip",
|
||||
file_tree = {
|
||||
aarch64 = "armv8",
|
||||
armv8 = "armv8",
|
||||
mips = "mips%-hardfloat",
|
||||
mipsel = "mipsle%-hardfloat"
|
||||
}
|
||||
}
|
||||
|
||||
_M.v2ray = {
|
||||
name = "V2ray",
|
||||
repo = "v2fly/v2ray-core",
|
||||
get_url = gh_pre_release_url,
|
||||
cmd_version = "version | awk '{print $2}' | sed -n 1P",
|
||||
zipped = true,
|
||||
default_path = "/usr/bin/v2ray",
|
||||
match_fmt_str = "linux%%-%s",
|
||||
file_tree = {
|
||||
x86_64 = "64",
|
||||
x86 = "32",
|
||||
mips = "mips32",
|
||||
mipsel = "mips32le"
|
||||
}
|
||||
}
|
||||
|
||||
_M.xray = {
|
||||
name = "Xray",
|
||||
repo = "XTLS/Xray-core",
|
||||
get_url = gh_pre_release_url,
|
||||
cmd_version = _M.v2ray.cmd_version,
|
||||
zipped = true,
|
||||
default_path = "/usr/bin/xray",
|
||||
match_fmt_str = _M.v2ray.match_fmt_str,
|
||||
file_tree = _M.v2ray.file_tree
|
||||
}
|
||||
|
||||
_M["chinadns-ng"] = {
|
||||
name = "ChinaDNS-NG",
|
||||
repo = "zfl9/chinadns-ng",
|
||||
get_url = gh_pre_release_url,
|
||||
cmd_version = "-V | awk '{print $2}'",
|
||||
zipped = false,
|
||||
default_path = "/usr/bin/chinadns-ng",
|
||||
match_fmt_str = "%s$",
|
||||
file_tree = {
|
||||
x86_64 = "x86_64",
|
||||
x86 = "i686",
|
||||
mipsel = "mipsel",
|
||||
aarch64 = "aarch64",
|
||||
armv5 = "arm%-eabi",
|
||||
armv6 = "armv6%-eabihf",
|
||||
armv7 = "armv7l%-eabihf",
|
||||
armv8 = "aarch64"
|
||||
}
|
||||
}
|
||||
|
||||
return _M
|
||||
@@ -1,135 +0,0 @@
|
||||
module("luci.passwall.hysteria", package.seeall)
|
||||
local api = require "luci.passwall.api"
|
||||
local fs = api.fs
|
||||
local sys = api.sys
|
||||
local util = api.util
|
||||
local i18n = api.i18n
|
||||
|
||||
local pre_release_url = "https://api.github.com/repos/HyNetwork/hysteria/releases?per_page=1"
|
||||
local release_url = "https://api.github.com/repos/HyNetwork/hysteria/releases/latest"
|
||||
local api_url = release_url
|
||||
local app_path = api.get_hysteria_path() or ""
|
||||
|
||||
function check_path()
|
||||
if app_path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", "hysteria")
|
||||
}
|
||||
end
|
||||
return {
|
||||
code = 0
|
||||
}
|
||||
end
|
||||
|
||||
function to_check(arch)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not arch or arch == "" then arch = api.auto_get_arch() end
|
||||
|
||||
local file_tree, sub_version = api.get_file_info(arch)
|
||||
|
||||
if file_tree == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Can't determine ARCH, or ARCH not supported.")
|
||||
}
|
||||
end
|
||||
|
||||
return api.common_to_check(api_url, api.get_hysteria_version(), "linux%-" .. file_tree .. sub_version)
|
||||
end
|
||||
|
||||
function to_download(url, size)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not url or url == "" then
|
||||
return {code = 1, error = i18n.translate("Download url is required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -f /tmp/hysteria_download.*")
|
||||
|
||||
local tmp_file = util.trim(util.exec("mktemp -u -t hysteria_download.XXXXXX"))
|
||||
|
||||
if size then
|
||||
local kb1 = api.get_free_space("/tmp")
|
||||
if tonumber(size) > tonumber(kb1) then
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")}
|
||||
end
|
||||
end
|
||||
|
||||
local return_code, result = api.curl_logic(url, tmp_file, api.curl_args)
|
||||
result = return_code == 0
|
||||
|
||||
if not result then
|
||||
api.exec("/bin/rm", {"-f", tmp_file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("File download failed or timed out: %s", url)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0, file = tmp_file}
|
||||
end
|
||||
|
||||
function to_move(file)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not file or file == "" or not fs.access(file) then
|
||||
sys.call("/bin/rm -rf /tmp/hysteria_download.*")
|
||||
return {code = 1, error = i18n.translate("Client file is required.")}
|
||||
end
|
||||
|
||||
local new_version = api.get_hysteria_version(file)
|
||||
if new_version == "" then
|
||||
sys.call("/bin/rm -rf /tmp/hysteria_download.*")
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("The client file is not suitable for current device.")
|
||||
}
|
||||
end
|
||||
|
||||
local flag = sys.call('pgrep -af "passwall/.*hysteria" >/dev/null')
|
||||
if flag == 0 then
|
||||
sys.call("/etc/init.d/passwall stop")
|
||||
end
|
||||
|
||||
local old_app_size = 0
|
||||
if fs.access(app_path) then
|
||||
old_app_size = api.get_file_space(app_path)
|
||||
end
|
||||
local new_app_size = api.get_file_space(file)
|
||||
local final_dir = api.get_final_dir(app_path)
|
||||
local final_dir_free_size = api.get_free_space(final_dir)
|
||||
if final_dir_free_size > 0 then
|
||||
final_dir_free_size = final_dir_free_size + old_app_size
|
||||
if new_app_size > final_dir_free_size then
|
||||
sys.call("/bin/rm -rf /tmp/hysteria_download.*")
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", final_dir)}
|
||||
end
|
||||
end
|
||||
|
||||
result = api.exec("/bin/mv", {"-f", file, app_path}, nil, api.command_timeout) == 0
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/hysteria_download.*")
|
||||
if flag == 0 then
|
||||
sys.call("/etc/init.d/passwall restart >/dev/null 2>&1 &")
|
||||
end
|
||||
|
||||
if not result or not fs.access(app_path) then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Can't move new file to path: %s", app_path)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0}
|
||||
end
|
||||
@@ -144,10 +144,10 @@ local function start()
|
||||
bin = ln_run("/usr/bin/ssserver", "ssserver", "-c " .. config_file, log_path)
|
||||
elseif type == "V2ray" then
|
||||
config = require(require_dir .. "util_xray").gen_config_server(user)
|
||||
bin = ln_run(api.get_v2ray_path(), "v2ray", "run -c " .. config_file, log_path)
|
||||
bin = ln_run(api.get_app_path("v2ray"), "v2ray", "run -c " .. config_file, log_path)
|
||||
elseif type == "Xray" then
|
||||
config = require(require_dir .. "util_xray").gen_config_server(user)
|
||||
bin = ln_run(api.get_xray_path(), "xray", "run -c " .. config_file, log_path)
|
||||
bin = ln_run(api.get_app_path("xray"), "xray", "run -c " .. config_file, log_path)
|
||||
elseif type == "Trojan" then
|
||||
config = require(require_dir .. "util_trojan").gen_config_server(user)
|
||||
bin = ln_run("/usr/sbin/trojan", "trojan", "-c " .. config_file, log_path)
|
||||
@@ -156,7 +156,7 @@ local function start()
|
||||
bin = ln_run("/usr/sbin/trojan-plus", "trojan-plus", "-c " .. config_file, log_path)
|
||||
elseif type == "Trojan-Go" then
|
||||
config = require(require_dir .. "util_trojan").gen_config_server(user)
|
||||
bin = ln_run(api.get_trojan_go_path(), "trojan-go", "-config " .. config_file, log_path)
|
||||
bin = ln_run(api.get_app_path("trojan-go"), "trojan-go", "-config " .. config_file, log_path)
|
||||
elseif type == "Brook" then
|
||||
local brook_protocol = user.protocol
|
||||
local brook_password = user.password
|
||||
@@ -165,10 +165,10 @@ local function start()
|
||||
if brook_protocol == "wsserver" and brook_path then
|
||||
brook_path_arg = " --path " .. brook_path
|
||||
end
|
||||
bin = ln_run(api.get_brook_path(), "brook_" .. id, string.format("--debug %s -l :%s -p %s%s", brook_protocol, port, brook_password, brook_path_arg), log_path)
|
||||
bin = ln_run(api.get_app_path("brook"), "brook_" .. id, string.format("--debug %s -l :%s -p %s%s", brook_protocol, port, brook_password, brook_path_arg), log_path)
|
||||
elseif type == "Hysteria" then
|
||||
config = require(require_dir .. "util_hysteria").gen_config_server(user)
|
||||
bin = ln_run(api.get_hysteria_path(), "hysteria", "-c " .. config_file .. " server", log_path)
|
||||
bin = ln_run(api.get_app_path("hysteria"), "hysteria", "-c " .. config_file .. " server", log_path)
|
||||
end
|
||||
|
||||
if next(config) then
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
module("luci.passwall.trojan_go", package.seeall)
|
||||
local api = require "luci.passwall.api"
|
||||
local fs = api.fs
|
||||
local sys = api.sys
|
||||
local util = api.util
|
||||
local i18n = api.i18n
|
||||
|
||||
local pre_release_url = "https://api.github.com/repos/p4gefau1t/trojan-go/releases?per_page=1"
|
||||
local release_url = "https://api.github.com/repos/p4gefau1t/trojan-go/releases/latest"
|
||||
local api_url = release_url
|
||||
local app_path = api.get_trojan_go_path() or ""
|
||||
|
||||
function check_path()
|
||||
if app_path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", "Trojan-GO")
|
||||
}
|
||||
end
|
||||
return {
|
||||
code = 0
|
||||
}
|
||||
end
|
||||
|
||||
function to_check(arch)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not arch or arch == "" then arch = api.auto_get_arch() end
|
||||
|
||||
local file_tree, sub_version = api.get_file_info(arch)
|
||||
|
||||
if file_tree == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Can't determine ARCH, or ARCH not supported.")
|
||||
}
|
||||
end
|
||||
|
||||
if file_tree == "mips" then file_tree = "mips%-hardfloat" end
|
||||
if file_tree == "mipsle" then file_tree = "mipsle%-hardfloat" end
|
||||
if file_tree == "arm64" then
|
||||
file_tree = "armv8"
|
||||
else
|
||||
if sub_version and sub_version:match("^[5-8]$") then file_tree = file_tree .. "v" .. sub_version end
|
||||
end
|
||||
|
||||
return api.common_to_check(api_url, api.get_trojan_go_version(), "linux%-" .. file_tree .. "%.zip")
|
||||
end
|
||||
|
||||
function to_download(url, size)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not url or url == "" then
|
||||
return {code = 1, error = i18n.translate("Download url is required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -f /tmp/trojan-go_download.*")
|
||||
|
||||
local tmp_file = util.trim(util.exec("mktemp -u -t trojan-go_download.XXXXXX"))
|
||||
|
||||
if size then
|
||||
local kb1 = api.get_free_space("/tmp")
|
||||
if tonumber(size) > tonumber(kb1) then
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")}
|
||||
end
|
||||
end
|
||||
|
||||
local return_code, result = api.curl_logic(url, tmp_file, api.curl_args)
|
||||
result = return_code == 0
|
||||
|
||||
if not result then
|
||||
api.exec("/bin/rm", {"-f", tmp_file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("File download failed or timed out: %s", url)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0, file = tmp_file}
|
||||
end
|
||||
|
||||
function to_extract(file, subfix)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not file or file == "" or not fs.access(file) then
|
||||
return {code = 1, error = i18n.translate("File path required.")}
|
||||
end
|
||||
|
||||
if sys.exec("echo -n $(opkg list-installed | grep -c unzip)") ~= "1" then
|
||||
api.exec("/bin/rm", {"-f", file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Not installed unzip, Can't unzip!")
|
||||
}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/trojan-go_extract.*")
|
||||
|
||||
local new_file_size = api.get_file_space(file)
|
||||
local tmp_free_size = api.get_free_space("/tmp")
|
||||
if tmp_free_size <= 0 or tmp_free_size <= new_file_size then
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")}
|
||||
end
|
||||
|
||||
local tmp_dir = util.trim(util.exec("mktemp -d -t trojan-go_extract.XXXXXX"))
|
||||
|
||||
local output = {}
|
||||
api.exec("/usr/bin/unzip", {"-o", file, "-d", tmp_dir},
|
||||
function(chunk) output[#output + 1] = chunk end)
|
||||
|
||||
local files = util.split(table.concat(output))
|
||||
|
||||
api.exec("/bin/rm", {"-f", file})
|
||||
|
||||
return {code = 0, file = tmp_dir}
|
||||
end
|
||||
|
||||
function to_move(file)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not file or file == "" then
|
||||
sys.call("/bin/rm -rf /tmp/trojan-go_extract.*")
|
||||
return {code = 1, error = i18n.translate("Client file is required.")}
|
||||
end
|
||||
|
||||
local bin_path = file .. "/trojan-go"
|
||||
|
||||
local new_version = api.get_trojan_go_version(bin_path)
|
||||
if new_version == "" then
|
||||
sys.call("/bin/rm -rf /tmp/trojan-go_extract.*")
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("The client file is not suitable for current device.")
|
||||
}
|
||||
end
|
||||
|
||||
local flag = sys.call('pgrep -af "passwall/.*trojan-go" >/dev/null')
|
||||
if flag == 0 then
|
||||
sys.call("/etc/init.d/passwall stop")
|
||||
end
|
||||
|
||||
local old_app_size = 0
|
||||
if fs.access(app_path) then
|
||||
old_app_size = api.get_file_space(app_path)
|
||||
end
|
||||
local new_app_size = api.get_file_space(bin_path)
|
||||
local final_dir = api.get_final_dir(app_path)
|
||||
local final_dir_free_size = api.get_free_space(final_dir)
|
||||
if final_dir_free_size > 0 then
|
||||
final_dir_free_size = final_dir_free_size + old_app_size
|
||||
if new_app_size > final_dir_free_size then
|
||||
sys.call("/bin/rm -rf /tmp/trojan-go_extract.*")
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", final_dir)}
|
||||
end
|
||||
end
|
||||
|
||||
result = api.exec("/bin/mv", { "-f", bin_path, app_path }, nil, api.command_timeout) == 0
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/trojan-go_extract.*")
|
||||
if flag == 0 then
|
||||
sys.call("/etc/init.d/passwall restart >/dev/null 2>&1 &")
|
||||
end
|
||||
|
||||
if not result or not fs.access(app_path) then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Can't move new file to path: %s", app_path)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0}
|
||||
end
|
||||
@@ -1,182 +0,0 @@
|
||||
module("luci.passwall.v2ray", package.seeall)
|
||||
local api = require "luci.passwall.api"
|
||||
local fs = api.fs
|
||||
local sys = api.sys
|
||||
local util = api.util
|
||||
local i18n = api.i18n
|
||||
|
||||
local pre_release_url = "https://api.github.com/repos/v2fly/v2ray-core/releases?per_page=1"
|
||||
local release_url = "https://api.github.com/repos/v2fly/v2ray-core/releases/latest"
|
||||
local api_url = pre_release_url
|
||||
local app_path = api.get_v2ray_path() or ""
|
||||
|
||||
function check_path()
|
||||
if app_path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", "V2ray")
|
||||
}
|
||||
end
|
||||
return {
|
||||
code = 0
|
||||
}
|
||||
end
|
||||
|
||||
function to_check(arch)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not arch or arch == "" then arch = api.auto_get_arch() end
|
||||
|
||||
local file_tree, sub_version = api.get_file_info(arch)
|
||||
|
||||
if file_tree == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Can't determine ARCH, or ARCH not supported.")
|
||||
}
|
||||
end
|
||||
|
||||
if file_tree == "amd64" then file_tree = "64" end
|
||||
if file_tree == "386" then file_tree = "32" end
|
||||
if file_tree == "mipsle" then file_tree = "mips32le" end
|
||||
if file_tree == "mips" then file_tree = "mips32" end
|
||||
if file_tree == "arm" then file_tree = "arm32" end
|
||||
|
||||
return api.common_to_check(api_url, api.get_v2ray_version(), "linux%-" .. file_tree .. (sub_version ~= "" and ".+" .. sub_version or ""))
|
||||
end
|
||||
|
||||
function to_download(url, size)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not url or url == "" then
|
||||
return {code = 1, error = i18n.translate("Download url is required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -f /tmp/v2ray_download.*")
|
||||
|
||||
local tmp_file = util.trim(util.exec("mktemp -u -t v2ray_download.XXXXXX"))
|
||||
|
||||
if size then
|
||||
local kb1 = api.get_free_space("/tmp")
|
||||
if tonumber(size) > tonumber(kb1) then
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")}
|
||||
end
|
||||
end
|
||||
|
||||
local return_code, result = api.curl_logic(url, tmp_file, api.curl_args)
|
||||
result = return_code == 0
|
||||
|
||||
if not result then
|
||||
api.exec("/bin/rm", {"-f", tmp_file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("File download failed or timed out: %s", url)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0, file = tmp_file}
|
||||
end
|
||||
|
||||
function to_extract(file, subfix)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not file or file == "" or not fs.access(file) then
|
||||
return {code = 1, error = i18n.translate("File path required.")}
|
||||
end
|
||||
|
||||
if sys.exec("echo -n $(opkg list-installed | grep -c unzip)") ~= "1" then
|
||||
api.exec("/bin/rm", {"-f", file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Not installed unzip, Can't unzip!")
|
||||
}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/v2ray_extract.*")
|
||||
|
||||
local new_file_size = api.get_file_space(file)
|
||||
local tmp_free_size = api.get_free_space("/tmp")
|
||||
if tmp_free_size <= 0 or tmp_free_size <= new_file_size then
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")}
|
||||
end
|
||||
|
||||
local tmp_dir = util.trim(util.exec("mktemp -d -t v2ray_extract.XXXXXX"))
|
||||
|
||||
local output = {}
|
||||
api.exec("/usr/bin/unzip", {"-o", file, "v2ray", "-d", tmp_dir},
|
||||
function(chunk) output[#output + 1] = chunk end)
|
||||
|
||||
local files = util.split(table.concat(output))
|
||||
|
||||
api.exec("/bin/rm", {"-f", file})
|
||||
|
||||
return {code = 0, file = tmp_dir}
|
||||
end
|
||||
|
||||
function to_move(file)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not file or file == "" then
|
||||
sys.call("/bin/rm -rf /tmp/v2ray_extract.*")
|
||||
return {code = 1, error = i18n.translate("Client file is required.")}
|
||||
end
|
||||
|
||||
local bin_path = file .. "/v2ray"
|
||||
|
||||
local new_version = api.get_v2ray_version(bin_path)
|
||||
if new_version == "" then
|
||||
sys.call("/bin/rm -rf /tmp/v2ray_extract.*")
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("The client file is not suitable for current device.")
|
||||
}
|
||||
end
|
||||
|
||||
local flag = sys.call('pgrep -af "passwall/.*v2ray" >/dev/null')
|
||||
if flag == 0 then
|
||||
sys.call("/etc/init.d/passwall stop")
|
||||
end
|
||||
|
||||
local old_app_size = 0
|
||||
if fs.access(app_path) then
|
||||
old_app_size = api.get_file_space(app_path)
|
||||
end
|
||||
local new_app_size = api.get_file_space(bin_path)
|
||||
local final_dir = api.get_final_dir(app_path)
|
||||
local final_dir_free_size = api.get_free_space(final_dir)
|
||||
if final_dir_free_size > 0 then
|
||||
final_dir_free_size = final_dir_free_size + old_app_size
|
||||
if new_app_size > final_dir_free_size then
|
||||
sys.call("/bin/rm -rf /tmp/v2ray_extract.*")
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", final_dir)}
|
||||
end
|
||||
end
|
||||
|
||||
result = api.exec("/bin/mv", { "-f", bin_path, app_path }, nil, api.command_timeout) == 0
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/v2ray_extract.*")
|
||||
if flag == 0 then
|
||||
sys.call("/etc/init.d/passwall restart >/dev/null 2>&1 &")
|
||||
end
|
||||
|
||||
if not result or not fs.access(app_path) then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Can't move new file to path: %s", app_path)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0}
|
||||
end
|
||||
@@ -1,182 +0,0 @@
|
||||
module("luci.passwall.xray", package.seeall)
|
||||
local api = require "luci.passwall.api"
|
||||
local fs = api.fs
|
||||
local sys = api.sys
|
||||
local util = api.util
|
||||
local i18n = api.i18n
|
||||
|
||||
local pre_release_url = "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=1"
|
||||
local release_url = "https://api.github.com/repos/XTLS/Xray-core/releases/latest"
|
||||
local api_url = pre_release_url
|
||||
local app_path = api.get_xray_path() or ""
|
||||
|
||||
function check_path()
|
||||
if app_path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", "Xray")
|
||||
}
|
||||
end
|
||||
return {
|
||||
code = 0
|
||||
}
|
||||
end
|
||||
|
||||
function to_check(arch)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not arch or arch == "" then arch = api.auto_get_arch() end
|
||||
|
||||
local file_tree, sub_version = api.get_file_info(arch)
|
||||
|
||||
if file_tree == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Can't determine ARCH, or ARCH not supported.")
|
||||
}
|
||||
end
|
||||
|
||||
if file_tree == "amd64" then file_tree = "64" end
|
||||
if file_tree == "386" then file_tree = "32" end
|
||||
if file_tree == "mipsle" then file_tree = "mips32le" end
|
||||
if file_tree == "mips" then file_tree = "mips32" end
|
||||
if file_tree == "arm" then file_tree = "arm32" end
|
||||
|
||||
return api.common_to_check(api_url, api.get_xray_version(), "linux%-" .. file_tree .. (sub_version ~= "" and ".+" .. sub_version or ""))
|
||||
end
|
||||
|
||||
function to_download(url, size)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not url or url == "" then
|
||||
return {code = 1, error = i18n.translate("Download url is required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -f /tmp/xray_download.*")
|
||||
|
||||
local tmp_file = util.trim(util.exec("mktemp -u -t xray_download.XXXXXX"))
|
||||
|
||||
if size then
|
||||
local kb1 = api.get_free_space("/tmp")
|
||||
if tonumber(size) > tonumber(kb1) then
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")}
|
||||
end
|
||||
end
|
||||
|
||||
local return_code, result = api.curl_logic(url, tmp_file, api.curl_args)
|
||||
result = return_code == 0
|
||||
|
||||
if not result then
|
||||
api.exec("/bin/rm", {"-f", tmp_file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("File download failed or timed out: %s", url)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0, file = tmp_file}
|
||||
end
|
||||
|
||||
function to_extract(file, subfix)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not file or file == "" or not fs.access(file) then
|
||||
return {code = 1, error = i18n.translate("File path required.")}
|
||||
end
|
||||
|
||||
if sys.exec("echo -n $(opkg list-installed | grep -c unzip)") ~= "1" then
|
||||
api.exec("/bin/rm", {"-f", file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Not installed unzip, Can't unzip!")
|
||||
}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/xray_extract.*")
|
||||
|
||||
local new_file_size = api.get_file_space(file)
|
||||
local tmp_free_size = api.get_free_space("/tmp")
|
||||
if tmp_free_size <= 0 or tmp_free_size <= new_file_size then
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")}
|
||||
end
|
||||
|
||||
local tmp_dir = util.trim(util.exec("mktemp -d -t xray_extract.XXXXXX"))
|
||||
|
||||
local output = {}
|
||||
api.exec("/usr/bin/unzip", {"-o", file, "xray", "-d", tmp_dir},
|
||||
function(chunk) output[#output + 1] = chunk end)
|
||||
|
||||
local files = util.split(table.concat(output))
|
||||
|
||||
api.exec("/bin/rm", {"-f", file})
|
||||
|
||||
return {code = 0, file = tmp_dir}
|
||||
end
|
||||
|
||||
function to_move(file)
|
||||
local result = check_path()
|
||||
if result.code ~= 0 then
|
||||
return result
|
||||
end
|
||||
|
||||
if not file or file == "" then
|
||||
sys.call("/bin/rm -rf /tmp/xray_extract.*")
|
||||
return {code = 1, error = i18n.translate("Client file is required.")}
|
||||
end
|
||||
|
||||
local bin_path = file .. "/xray"
|
||||
|
||||
local new_version = api.get_xray_version(bin_path)
|
||||
if new_version == "" then
|
||||
sys.call("/bin/rm -rf /tmp/xray_extract.*")
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("The client file is not suitable for current device.")
|
||||
}
|
||||
end
|
||||
|
||||
local flag = sys.call('pgrep -af "passwall/.*xray" >/dev/null')
|
||||
if flag == 0 then
|
||||
sys.call("/etc/init.d/passwall stop")
|
||||
end
|
||||
|
||||
local old_app_size = 0
|
||||
if fs.access(app_path) then
|
||||
old_app_size = api.get_file_space(app_path)
|
||||
end
|
||||
local new_app_size = api.get_file_space(bin_path)
|
||||
local final_dir = api.get_final_dir(app_path)
|
||||
local final_dir_free_size = api.get_free_space(final_dir)
|
||||
if final_dir_free_size > 0 then
|
||||
final_dir_free_size = final_dir_free_size + old_app_size
|
||||
if new_app_size > final_dir_free_size then
|
||||
sys.call("/bin/rm -rf /tmp/xray_extract.*")
|
||||
return {code = 1, error = i18n.translatef("%s not enough space.", final_dir)}
|
||||
end
|
||||
end
|
||||
|
||||
result = api.exec("/bin/mv", { "-f", bin_path, app_path }, nil, api.command_timeout) == 0
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/xray_extract.*")
|
||||
if flag == 0 then
|
||||
sys.call("/etc/init.d/passwall restart >/dev/null 2>&1 &")
|
||||
end
|
||||
|
||||
if not result or not fs.access(app_path) then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Can't move new file to path: %s", app_path)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0}
|
||||
end
|
||||
@@ -0,0 +1,193 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local com = require "luci.passwall.com"
|
||||
local version = {}
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var appInfoList = new Array();
|
||||
var inProgressCount = 0;
|
||||
var tokenStr = '<%=token%>';
|
||||
var manuallyUpdateText = '<%:Manually update%>';
|
||||
var noUpdateText = '<%:It is the latest version%>';
|
||||
var updateSuccessText = '<%:Update successful%>';
|
||||
var clickToUpdateText = '<%:Click to update%>';
|
||||
var inProgressText = '<%:Updating...%>';
|
||||
var unexpectedErrorText = '<%:Unexpected error%>';
|
||||
var updateInProgressNotice = '<%:Updating, are you sure to close?%>';
|
||||
var downloadingText = '<%:Downloading...%>';
|
||||
var decompressioningText = '<%:Unpacking...%>';
|
||||
var movingText = '<%:Moving...%>';
|
||||
|
||||
//window.onload = function () {};
|
||||
|
||||
function addPageNotice() {
|
||||
if (inProgressCount === 0) {
|
||||
window.onbeforeunload = function (e) {
|
||||
e.returnValue = updateInProgressNotice;
|
||||
return updateInProgressNotice;
|
||||
};
|
||||
}
|
||||
inProgressCount++;
|
||||
}
|
||||
|
||||
function removePageNotice() {
|
||||
inProgressCount--;
|
||||
if (inProgressCount === 0) {
|
||||
window.onbeforeunload = undefined;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onUpdateSuccess(btn) {
|
||||
if (btn) {
|
||||
btn.value = updateSuccessText;
|
||||
btn.placeholder = updateSuccessText;
|
||||
btn.disabled = true;
|
||||
}
|
||||
|
||||
if (inProgressCount === 0) {
|
||||
window.setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function onRequestError(btn, errorMessage) {
|
||||
btn.disabled = false;
|
||||
btn.value = manuallyUpdateText;
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
if (errorMessage && ckeckDetailElm) {
|
||||
ckeckDetailElm.textContent = errorMessage
|
||||
}
|
||||
}
|
||||
|
||||
function onBtnClick(btn, app) {
|
||||
if (appInfoList[app] === undefined) {
|
||||
checkUpdate(btn, app);
|
||||
} else {
|
||||
doUpdate(btn, app);
|
||||
}
|
||||
}
|
||||
|
||||
function checkUpdate(btn, app) {
|
||||
btn.disabled = true;
|
||||
btn.value = inProgressText;
|
||||
|
||||
addPageNotice();
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
if (ckeckDetailElm) {
|
||||
ckeckDetailElm.textContent = "";
|
||||
}
|
||||
XHR.get('<%=api.url("check_")%>' + app, {
|
||||
token: tokenStr,
|
||||
arch: ''
|
||||
}, function (x, json) {
|
||||
removePageNotice();
|
||||
if (json.code) {
|
||||
appInfoList[app] = undefined;
|
||||
onRequestError(btn, json.error);
|
||||
} else {
|
||||
if (json.has_update) {
|
||||
appInfoList[app] = json;
|
||||
btn.disabled = false;
|
||||
btn.value = clickToUpdateText;
|
||||
btn.placeholder = clickToUpdateText;
|
||||
|
||||
if (ckeckDetailElm) {
|
||||
var urlNode = '';
|
||||
if (json.remote_version) {
|
||||
urlNode = '<em style="color:red;">' + json.remote_version + '</em>';
|
||||
if (json.html_url) {
|
||||
urlNode = '<a href="' + json.html_url + '" target="_blank">' + urlNode + '</a>';
|
||||
}
|
||||
}
|
||||
ckeckDetailElm.innerHTML = urlNode;
|
||||
}
|
||||
} else {
|
||||
btn.disabled = true;
|
||||
btn.value = noUpdateText;
|
||||
}
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
||||
function doUpdate(btn, app) {
|
||||
btn.disabled = true;
|
||||
btn.value = downloadingText;
|
||||
|
||||
addPageNotice();
|
||||
|
||||
var appUpdateUrl = '<%=api.url("update_")%>' + app;
|
||||
var appInfo = appInfoList[app];
|
||||
// Download file
|
||||
XHR.get(appUpdateUrl, {
|
||||
token: tokenStr,
|
||||
url: appInfo ? appInfo.data.browser_download_url : '',
|
||||
size: appInfo ? appInfo.data.size / 1024 : null
|
||||
}, function (x, json) {
|
||||
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 move(btn, url, file) {
|
||||
btn.value = movingText;
|
||||
|
||||
// Move file to target dir
|
||||
XHR.get(url, {
|
||||
token: tokenStr,
|
||||
task: 'move',
|
||||
file: file
|
||||
}, function (x, json) {
|
||||
removePageNotice();
|
||||
if (json.code) {
|
||||
onRequestError(btn, json.error);
|
||||
} else {
|
||||
onUpdateSuccess(btn);
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<%for k, v in pairs(com) do
|
||||
version[k] = api.get_app_version(k)%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%=v.name%>
|
||||
<%:Version%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-description">
|
||||
<span>【 <%=version[k] ~="" and version[k] or translate("Null") %> 】</span>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="_<%=k%>-check_btn"
|
||||
onclick="onBtnClick(this,'<%=k%>');" value="<%:Manually update%>" />
|
||||
<span id="_<%=k%>-check_btn-detail"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%end%>
|
||||
@@ -1,159 +0,0 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local brook_version = api.get_brook_version()
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var brookInfo;
|
||||
var tokenStr = '<%=token%>';
|
||||
var manuallyUpdateText = '<%:Manually update%>';
|
||||
var noUpdateText = '<%:It is the latest version%>';
|
||||
var updateSuccessText = '<%:Update successful%>';
|
||||
var clickToUpdateText = '<%:Click to update%>';
|
||||
var inProgressText = '<%:Updating...%>';
|
||||
var unexpectedErrorText = '<%:Unexpected error%>';
|
||||
var updateInProgressNotice = '<%:Updating, are you sure to close?%>';
|
||||
var downloadingText = '<%:Downloading...%>';
|
||||
var decompressioningText = '<%:Unpacking...%>';
|
||||
var movingText = '<%:Moving...%>';
|
||||
|
||||
window.onload = function () {
|
||||
var brookCheckBtn = document.getElementById('_brook-check_btn');
|
||||
var brookDetailElm = document.getElementById('_brook-check_btn-detail');
|
||||
};
|
||||
|
||||
function addPageNotice_brook() {
|
||||
window.onbeforeunload = function (e) {
|
||||
e.returnValue = updateInProgressNotice;
|
||||
return updateInProgressNotice;
|
||||
};
|
||||
}
|
||||
|
||||
function removePageNotice_brook() {
|
||||
window.onbeforeunload = undefined;
|
||||
}
|
||||
|
||||
function onUpdateSuccess_brook(btn) {
|
||||
alert(updateSuccessText);
|
||||
|
||||
if (btn) {
|
||||
btn.value = updateSuccessText;
|
||||
btn.placeholder = updateSuccessText;
|
||||
btn.disabled = true;
|
||||
}
|
||||
|
||||
window.setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function onRequestError_brook(btn, errorMessage) {
|
||||
btn.disabled = false;
|
||||
btn.value = manuallyUpdateText;
|
||||
|
||||
if (errorMessage) {
|
||||
alert(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function onBtnClick_brook(btn) {
|
||||
if (brookInfo === undefined) {
|
||||
checkUpdate_brook(btn);
|
||||
} else {
|
||||
doUpdate_brook(btn);
|
||||
}
|
||||
}
|
||||
|
||||
function checkUpdate_brook(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = inProgressText;
|
||||
|
||||
addPageNotice_brook();
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
|
||||
XHR.get('<%=api.url("brook_check")%>', {
|
||||
token: tokenStr,
|
||||
arch: ''
|
||||
}, function (x, json) {
|
||||
removePageNotice_brook();
|
||||
|
||||
if (json.code) {
|
||||
brookInfo = undefined;
|
||||
onRequestError_brook(btn, json.error);
|
||||
} else {
|
||||
if (json.has_update) {
|
||||
brookInfo = json;
|
||||
btn.disabled = false;
|
||||
btn.value = clickToUpdateText;
|
||||
btn.placeholder = clickToUpdateText;
|
||||
|
||||
if (ckeckDetailElm) {
|
||||
var urlNode = '';
|
||||
if (json.remote_version) {
|
||||
urlNode = '<em style="color:red;">' + json.remote_version + '</em>';
|
||||
if (json.html_url) {
|
||||
urlNode = '<a href="' + json.html_url + '" target="_blank">' + urlNode + '</a>';
|
||||
}
|
||||
}
|
||||
ckeckDetailElm.innerHTML = urlNode;
|
||||
}
|
||||
} else {
|
||||
btn.disabled = true;
|
||||
btn.value = noUpdateText;
|
||||
}
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
||||
function doUpdate_brook(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = downloadingText;
|
||||
|
||||
addPageNotice_brook();
|
||||
|
||||
var brookUpdateUrl = '<%=api.url("brook_update")%>';
|
||||
// Download file
|
||||
XHR.get(brookUpdateUrl, {
|
||||
token: tokenStr,
|
||||
url: brookInfo ? brookInfo.data.browser_download_url : '',
|
||||
size: brookInfo ? brookInfo.data.size / 1024 : null
|
||||
}, function (x, json) {
|
||||
if (json.code) {
|
||||
removePageNotice_brook();
|
||||
onRequestError_brook(btn, json.error);
|
||||
} else {
|
||||
btn.value = decompressioningText;
|
||||
// Move file to target dir
|
||||
XHR.get(brookUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'move',
|
||||
file: json.file
|
||||
}, function (x, json) {
|
||||
removePageNotice_brook();
|
||||
if (json.code) {
|
||||
onRequestError_brook(btn, json.error);
|
||||
} else {
|
||||
onUpdateSuccess_brook(btn);
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">Brook
|
||||
<%:Version%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-description">
|
||||
<span>【 <%=brook_version ~="" and brook_version or translate("Null") %> 】</span>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="_brook-check_btn"
|
||||
onclick="onBtnClick_brook(this);" value="<%:Manually update%>" />
|
||||
<span id="_brook-check_btn-detail"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,159 +0,0 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local hysteria_version = api.get_hysteria_version()
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var hysteriaInfo;
|
||||
var tokenStr = '<%=token%>';
|
||||
var manuallyUpdateText = '<%:Manually update%>';
|
||||
var noUpdateText = '<%:It is the latest version%>';
|
||||
var updateSuccessText = '<%:Update successful%>';
|
||||
var clickToUpdateText = '<%:Click to update%>';
|
||||
var inProgressText = '<%:Updating...%>';
|
||||
var unexpectedErrorText = '<%:Unexpected error%>';
|
||||
var updateInProgressNotice = '<%:Updating, are you sure to close?%>';
|
||||
var downloadingText = '<%:Downloading...%>';
|
||||
var decompressioningText = '<%:Unpacking...%>';
|
||||
var movingText = '<%:Moving...%>';
|
||||
|
||||
window.onload = function () {
|
||||
var hysteriaCheckBtn = document.getElementById('_hysteria-check_btn');
|
||||
var hysteriaDetailElm = document.getElementById('_hysteria-check_btn-detail');
|
||||
};
|
||||
|
||||
function addPageNotice_hysteria() {
|
||||
window.onbeforeunload = function (e) {
|
||||
e.returnValue = updateInProgressNotice;
|
||||
return updateInProgressNotice;
|
||||
};
|
||||
}
|
||||
|
||||
function removePageNotice_hysteria() {
|
||||
window.onbeforeunload = undefined;
|
||||
}
|
||||
|
||||
function onUpdateSuccess_hysteria(btn) {
|
||||
alert(updateSuccessText);
|
||||
|
||||
if (btn) {
|
||||
btn.value = updateSuccessText;
|
||||
btn.placeholder = updateSuccessText;
|
||||
btn.disabled = true;
|
||||
}
|
||||
|
||||
window.setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function onRequestError_hysteria(btn, errorMessage) {
|
||||
btn.disabled = false;
|
||||
btn.value = manuallyUpdateText;
|
||||
|
||||
if (errorMessage) {
|
||||
alert(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function onBtnClick_hysteria(btn) {
|
||||
if (hysteriaInfo === undefined) {
|
||||
checkUpdate_hysteria(btn);
|
||||
} else {
|
||||
doUpdate_hysteria(btn);
|
||||
}
|
||||
}
|
||||
|
||||
function checkUpdate_hysteria(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = inProgressText;
|
||||
|
||||
addPageNotice_hysteria();
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
|
||||
XHR.get('<%=api.url("hysteria_check")%>', {
|
||||
token: tokenStr,
|
||||
arch: ''
|
||||
}, function (x, json) {
|
||||
removePageNotice_hysteria();
|
||||
|
||||
if (json.code) {
|
||||
hysteriaInfo = undefined;
|
||||
onRequestError_hysteria(btn, json.error);
|
||||
} else {
|
||||
if (json.has_update) {
|
||||
hysteriaInfo = json;
|
||||
btn.disabled = false;
|
||||
btn.value = clickToUpdateText;
|
||||
btn.placeholder = clickToUpdateText;
|
||||
|
||||
if (ckeckDetailElm) {
|
||||
var urlNode = '';
|
||||
if (json.remote_version) {
|
||||
urlNode = '<em style="color:red;">' + json.remote_version + '</em>';
|
||||
if (json.html_url) {
|
||||
urlNode = '<a href="' + json.html_url + '" target="_blank">' + urlNode + '</a>';
|
||||
}
|
||||
}
|
||||
ckeckDetailElm.innerHTML = urlNode;
|
||||
}
|
||||
} else {
|
||||
btn.disabled = true;
|
||||
btn.value = noUpdateText;
|
||||
}
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
||||
function doUpdate_hysteria(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = downloadingText;
|
||||
|
||||
addPageNotice_hysteria();
|
||||
|
||||
var hysteriaUpdateUrl = '<%=api.url("hysteria_update")%>';
|
||||
// Download file
|
||||
XHR.get(hysteriaUpdateUrl, {
|
||||
token: tokenStr,
|
||||
url: hysteriaInfo ? hysteriaInfo.data.browser_download_url : '',
|
||||
size: hysteriaInfo ? hysteriaInfo.data.size / 1024 : null
|
||||
}, function (x, json) {
|
||||
if (json.code) {
|
||||
removePageNotice_hysteria();
|
||||
onRequestError_hysteria(btn, json.error);
|
||||
} else {
|
||||
btn.value = decompressioningText;
|
||||
// Move file to target dir
|
||||
XHR.get(hysteriaUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'move',
|
||||
file: json.file
|
||||
}, function (x, json) {
|
||||
removePageNotice_hysteria();
|
||||
if (json.code) {
|
||||
onRequestError_hysteria(btn, json.error);
|
||||
} else {
|
||||
onUpdateSuccess_hysteria(btn);
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">Hysteria
|
||||
<%:Version%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-description">
|
||||
<span>【 <%=hysteria_version ~="" and hysteria_version or translate("Null") %> 】</span>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="_hysteria-check_btn"
|
||||
onclick="onBtnClick_hysteria(this);" value="<%:Manually update%>" />
|
||||
<span id="_hysteria-check_btn-detail"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,175 +0,0 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local trojan_go_version = api.get_trojan_go_version()
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var trojanInfo;
|
||||
var tokenStr = '<%=token%>';
|
||||
var manuallyUpdateText = '<%:Manually update%>';
|
||||
var noUpdateText = '<%:It is the latest version%>';
|
||||
var updateSuccessText = '<%:Update successful%>';
|
||||
var clickToUpdateText = '<%:Click to update%>';
|
||||
var inProgressText = '<%:Updating...%>';
|
||||
var unexpectedErrorText = '<%:Unexpected error%>';
|
||||
var updateInProgressNotice = '<%:Updating, are you sure to close?%>';
|
||||
var downloadingText = '<%:Downloading...%>';
|
||||
var decompressioningText = '<%:Unpacking...%>';
|
||||
var movingText = '<%:Moving...%>';
|
||||
|
||||
window.onload = function () {
|
||||
var trojanCheckBtn = document.getElementById('_trojan-check_btn');
|
||||
var trojanDetailElm = document.getElementById('_trojan-check_btn-detail');
|
||||
};
|
||||
|
||||
function addPageNotice_trojan() {
|
||||
window.onbeforeunload = function (e) {
|
||||
e.returnValue = updateInProgressNotice;
|
||||
return updateInProgressNotice;
|
||||
};
|
||||
}
|
||||
|
||||
function removePageNotice_trojan() {
|
||||
window.onbeforeunload = undefined;
|
||||
}
|
||||
|
||||
function onUpdateSuccess_trojan(btn) {
|
||||
alert(updateSuccessText);
|
||||
|
||||
if (btn) {
|
||||
btn.value = updateSuccessText;
|
||||
btn.placeholder = updateSuccessText;
|
||||
btn.disabled = true;
|
||||
}
|
||||
|
||||
window.setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function onRequestError_trojan(btn, errorMessage) {
|
||||
btn.disabled = false;
|
||||
btn.value = manuallyUpdateText;
|
||||
|
||||
if (errorMessage) {
|
||||
alert(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function onBtnClick_trojan(btn) {
|
||||
if (trojanInfo === undefined) {
|
||||
checkUpdate_trojan(btn);
|
||||
} else {
|
||||
doUpdate_trojan(btn);
|
||||
}
|
||||
}
|
||||
|
||||
function checkUpdate_trojan(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = inProgressText;
|
||||
|
||||
addPageNotice_trojan();
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
|
||||
XHR.get('<%=api.url("trojan_go_check")%>', {
|
||||
token: tokenStr,
|
||||
arch: ''
|
||||
}, function (x, json) {
|
||||
removePageNotice_trojan();
|
||||
|
||||
if (json.code) {
|
||||
trojanInfo = undefined;
|
||||
onRequestError_trojan(btn, json.error);
|
||||
} else {
|
||||
if (json.has_update) {
|
||||
trojanInfo = json;
|
||||
btn.disabled = false;
|
||||
btn.value = clickToUpdateText;
|
||||
btn.placeholder = clickToUpdateText;
|
||||
|
||||
if (ckeckDetailElm) {
|
||||
var urlNode = '';
|
||||
if (json.remote_version) {
|
||||
urlNode = '<em style="color:red;">' + json.remote_version + '</em>';
|
||||
if (json.html_url) {
|
||||
urlNode = '<a href="' + json.html_url + '" target="_blank">' + urlNode + '</a>';
|
||||
}
|
||||
}
|
||||
ckeckDetailElm.innerHTML = urlNode;
|
||||
}
|
||||
} else {
|
||||
btn.disabled = true;
|
||||
btn.value = noUpdateText;
|
||||
}
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
||||
function doUpdate_trojan(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = downloadingText;
|
||||
|
||||
addPageNotice_trojan();
|
||||
|
||||
var trojanUpdateUrl = '<%=api.url("trojan_go_update")%>';
|
||||
// Download file
|
||||
XHR.get(trojanUpdateUrl, {
|
||||
token: tokenStr,
|
||||
url: trojanInfo ? trojanInfo.data.browser_download_url : '',
|
||||
size: trojanInfo ? trojanInfo.data.size / 1024 : null
|
||||
}, function (x, json) {
|
||||
if (json.code) {
|
||||
removePageNotice_trojan();
|
||||
onRequestError_trojan(btn, json.error);
|
||||
} else {
|
||||
btn.value = decompressioningText;
|
||||
|
||||
// Extract file
|
||||
XHR.get(trojanUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'extract',
|
||||
file: json.file,
|
||||
subfix: trojanInfo ? trojanInfo.type : ''
|
||||
}, function (x, json) {
|
||||
if (json.code) {
|
||||
removePageNotice_trojan();
|
||||
onRequestError_trojan(btn, json.error);
|
||||
} else {
|
||||
btn.value = movingText;
|
||||
|
||||
// Move file to target dir
|
||||
XHR.get(trojanUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'move',
|
||||
file: json.file
|
||||
}, function (x, json) {
|
||||
removePageNotice_trojan();
|
||||
if (json.code) {
|
||||
onRequestError_trojan(btn, json.error);
|
||||
} else {
|
||||
onUpdateSuccess_trojan(btn);
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">Trojan-Go
|
||||
<%:Version%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-description">
|
||||
<span>【 <%=trojan_go_version ~="" and trojan_go_version or translate("Null") %> 】</span>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="_trojan-check_btn"
|
||||
onclick="onBtnClick_trojan(this);" value="<%:Manually update%>" />
|
||||
<span id="_trojan-check_btn-detail"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,175 +0,0 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local v2ray_version = api.get_v2ray_version()
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var v2rayInfo;
|
||||
var tokenStr = '<%=token%>';
|
||||
var manuallyUpdateText = '<%:Manually update%>';
|
||||
var noUpdateText = '<%:It is the latest version%>';
|
||||
var updateSuccessText = '<%:Update successful%>';
|
||||
var clickToUpdateText = '<%:Click to update%>';
|
||||
var inProgressText = '<%:Updating...%>';
|
||||
var unexpectedErrorText = '<%:Unexpected error%>';
|
||||
var updateInProgressNotice = '<%:Updating, are you sure to close?%>';
|
||||
var downloadingText = '<%:Downloading...%>';
|
||||
var decompressioningText = '<%:Unpacking...%>';
|
||||
var movingText = '<%:Moving...%>';
|
||||
|
||||
window.onload = function () {
|
||||
var v2rayCheckBtn = document.getElementById('_v2ray-check_btn');
|
||||
var v2rayDetailElm = document.getElementById('_v2ray-check_btn-detail');
|
||||
};
|
||||
|
||||
function addPageNotice_v2ray() {
|
||||
window.onbeforeunload = function (e) {
|
||||
e.returnValue = updateInProgressNotice;
|
||||
return updateInProgressNotice;
|
||||
};
|
||||
}
|
||||
|
||||
function removePageNotice_v2ray() {
|
||||
window.onbeforeunload = undefined;
|
||||
}
|
||||
|
||||
function onUpdateSuccess_v2ray(btn) {
|
||||
alert(updateSuccessText);
|
||||
|
||||
if (btn) {
|
||||
btn.value = updateSuccessText;
|
||||
btn.placeholder = updateSuccessText;
|
||||
btn.disabled = true;
|
||||
}
|
||||
|
||||
window.setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function onRequestError_v2ray(btn, errorMessage) {
|
||||
btn.disabled = false;
|
||||
btn.value = manuallyUpdateText;
|
||||
|
||||
if (errorMessage) {
|
||||
alert(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function onBtnClick_v2ray(btn) {
|
||||
if (v2rayInfo === undefined) {
|
||||
checkUpdate_v2ray(btn);
|
||||
} else {
|
||||
doUpdate_v2ray(btn);
|
||||
}
|
||||
}
|
||||
|
||||
function checkUpdate_v2ray(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = inProgressText;
|
||||
|
||||
addPageNotice_v2ray();
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
|
||||
XHR.get('<%=api.url("v2ray_check")%>', {
|
||||
token: tokenStr,
|
||||
arch: ''
|
||||
}, function (x, json) {
|
||||
removePageNotice_v2ray();
|
||||
|
||||
if (json.code) {
|
||||
v2rayInfo = undefined;
|
||||
onRequestError_v2ray(btn, json.error);
|
||||
} else {
|
||||
if (json.has_update) {
|
||||
v2rayInfo = json;
|
||||
btn.disabled = false;
|
||||
btn.value = clickToUpdateText;
|
||||
btn.placeholder = clickToUpdateText;
|
||||
|
||||
if (ckeckDetailElm) {
|
||||
var urlNode = '';
|
||||
if (json.remote_version) {
|
||||
urlNode = '<em style="color:red;">' + json.remote_version + '</em>';
|
||||
if (json.html_url) {
|
||||
urlNode = '<a href="' + json.html_url + '" target="_blank">' + urlNode + '</a>';
|
||||
}
|
||||
}
|
||||
ckeckDetailElm.innerHTML = urlNode;
|
||||
}
|
||||
} else {
|
||||
btn.disabled = true;
|
||||
btn.value = noUpdateText;
|
||||
}
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
||||
function doUpdate_v2ray(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = downloadingText;
|
||||
|
||||
addPageNotice_v2ray();
|
||||
|
||||
var v2rayUpdateUrl = '<%=api.url("v2ray_update")%>';
|
||||
// Download file
|
||||
XHR.get(v2rayUpdateUrl, {
|
||||
token: tokenStr,
|
||||
url: v2rayInfo ? v2rayInfo.data.browser_download_url : '',
|
||||
size: v2rayInfo ? v2rayInfo.data.size / 1024 : null
|
||||
}, function (x, json) {
|
||||
if (json.code) {
|
||||
removePageNotice_v2ray();
|
||||
onRequestError_v2ray(btn, json.error);
|
||||
} else {
|
||||
btn.value = decompressioningText;
|
||||
|
||||
// Extract file
|
||||
XHR.get(v2rayUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'extract',
|
||||
file: json.file,
|
||||
subfix: v2rayInfo ? v2rayInfo.type : ''
|
||||
}, function (x, json) {
|
||||
if (json.code) {
|
||||
removePageNotice_v2ray();
|
||||
onRequestError_v2ray(btn, json.error);
|
||||
} else {
|
||||
btn.value = movingText;
|
||||
|
||||
// Move file to target dir
|
||||
XHR.get(v2rayUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'move',
|
||||
file: json.file
|
||||
}, function (x, json) {
|
||||
removePageNotice_v2ray();
|
||||
if (json.code) {
|
||||
onRequestError_v2ray(btn, json.error);
|
||||
} else {
|
||||
onUpdateSuccess_v2ray(btn);
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">V2ray
|
||||
<%:Version%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-description">
|
||||
<span>【 <%=v2ray_version ~="" and v2ray_version or translate("Null") %> 】</span>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="_v2ray-check_btn"
|
||||
onclick="onBtnClick_v2ray(this);" value="<%:Manually update%>" />
|
||||
<span id="_v2ray-check_btn-detail"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,175 +0,0 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local xray_version = api.get_xray_version()
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var xrayInfo;
|
||||
var tokenStr = '<%=token%>';
|
||||
var manuallyUpdateText = '<%:Manually update%>';
|
||||
var noUpdateText = '<%:It is the latest version%>';
|
||||
var updateSuccessText = '<%:Update successful%>';
|
||||
var clickToUpdateText = '<%:Click to update%>';
|
||||
var inProgressText = '<%:Updating...%>';
|
||||
var unexpectedErrorText = '<%:Unexpected error%>';
|
||||
var updateInProgressNotice = '<%:Updating, are you sure to close?%>';
|
||||
var downloadingText = '<%:Downloading...%>';
|
||||
var decompressioningText = '<%:Unpacking...%>';
|
||||
var movingText = '<%:Moving...%>';
|
||||
|
||||
window.onload = function () {
|
||||
var xrayCheckBtn = document.getElementById('_xray-check_btn');
|
||||
var xrayDetailElm = document.getElementById('_xray-check_btn-detail');
|
||||
};
|
||||
|
||||
function addPageNotice_xray() {
|
||||
window.onbeforeunload = function (e) {
|
||||
e.returnValue = updateInProgressNotice;
|
||||
return updateInProgressNotice;
|
||||
};
|
||||
}
|
||||
|
||||
function removePageNotice_xray() {
|
||||
window.onbeforeunload = undefined;
|
||||
}
|
||||
|
||||
function onUpdateSuccess_xray(btn) {
|
||||
alert(updateSuccessText);
|
||||
|
||||
if (btn) {
|
||||
btn.value = updateSuccessText;
|
||||
btn.placeholder = updateSuccessText;
|
||||
btn.disabled = true;
|
||||
}
|
||||
|
||||
window.setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function onRequestError_xray(btn, errorMessage) {
|
||||
btn.disabled = false;
|
||||
btn.value = manuallyUpdateText;
|
||||
|
||||
if (errorMessage) {
|
||||
alert(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function onBtnClick_xray(btn) {
|
||||
if (xrayInfo === undefined) {
|
||||
checkUpdate_xray(btn);
|
||||
} else {
|
||||
doUpdate_xray(btn);
|
||||
}
|
||||
}
|
||||
|
||||
function checkUpdate_xray(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = inProgressText;
|
||||
|
||||
addPageNotice_xray();
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
|
||||
XHR.get('<%=api.url("xray_check")%>', {
|
||||
token: tokenStr,
|
||||
arch: ''
|
||||
}, function (x, json) {
|
||||
removePageNotice_xray();
|
||||
|
||||
if (json.code) {
|
||||
xrayInfo = undefined;
|
||||
onRequestError_xray(btn, json.error);
|
||||
} else {
|
||||
if (json.has_update) {
|
||||
xrayInfo = json;
|
||||
btn.disabled = false;
|
||||
btn.value = clickToUpdateText;
|
||||
btn.placeholder = clickToUpdateText;
|
||||
|
||||
if (ckeckDetailElm) {
|
||||
var urlNode = '';
|
||||
if (json.remote_version) {
|
||||
urlNode = '<em style="color:red;">' + json.remote_version + '</em>';
|
||||
if (json.html_url) {
|
||||
urlNode = '<a href="' + json.html_url + '" target="_blank">' + urlNode + '</a>';
|
||||
}
|
||||
}
|
||||
ckeckDetailElm.innerHTML = urlNode;
|
||||
}
|
||||
} else {
|
||||
btn.disabled = true;
|
||||
btn.value = noUpdateText;
|
||||
}
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
||||
function doUpdate_xray(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = downloadingText;
|
||||
|
||||
addPageNotice_xray();
|
||||
|
||||
var xrayUpdateUrl = '<%=api.url("xray_update")%>';
|
||||
// Download file
|
||||
XHR.get(xrayUpdateUrl, {
|
||||
token: tokenStr,
|
||||
url: xrayInfo ? xrayInfo.data.browser_download_url : '',
|
||||
size: xrayInfo ? xrayInfo.data.size / 1024 : null
|
||||
}, function (x, json) {
|
||||
if (json.code) {
|
||||
removePageNotice_xray();
|
||||
onRequestError_xray(btn, json.error);
|
||||
} else {
|
||||
btn.value = decompressioningText;
|
||||
|
||||
// Extract file
|
||||
XHR.get(xrayUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'extract',
|
||||
file: json.file,
|
||||
subfix: xrayInfo ? xrayInfo.type : ''
|
||||
}, function (x, json) {
|
||||
if (json.code) {
|
||||
removePageNotice_xray();
|
||||
onRequestError_xray(btn, json.error);
|
||||
} else {
|
||||
btn.value = movingText;
|
||||
|
||||
// Move file to target dir
|
||||
XHR.get(xrayUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'move',
|
||||
file: json.file
|
||||
}, function (x, json) {
|
||||
removePageNotice_xray();
|
||||
if (json.code) {
|
||||
onRequestError_xray(btn, json.error);
|
||||
} else {
|
||||
onUpdateSuccess_xray(btn);
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">Xray
|
||||
<%:Version%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-description">
|
||||
<span>【 <%=xray_version ~="" and xray_version or translate("Null") %> 】</span>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="_xray-check_btn"
|
||||
onclick="onBtnClick_xray(this);" value="<%:Manually update%>" />
|
||||
<span id="_xray-check_btn-detail"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -21,13 +21,13 @@ define Download/geoip
|
||||
HASH:=30e7bd8478f9ab601b755e46c2a410467640c57fca9926e8ab9e4899e014c862
|
||||
endef
|
||||
|
||||
GEOSITE_VER:=20230320093818
|
||||
GEOSITE_VER:=20230321023207
|
||||
GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
|
||||
define Download/geosite
|
||||
URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
|
||||
URL_FILE:=dlc.dat
|
||||
FILE:=$(GEOSITE_FILE)
|
||||
HASH:=876d1b667019fa0b2594e0e1e5be0c998672f8f76441f4de344871dab7e25af2
|
||||
HASH:=a96a9b3c5cc7dc10f94810e3c7aec79436563a95deb695a93812fd2ebb8d2b6f
|
||||
endef
|
||||
|
||||
define Package/v2ray-geodata/template
|
||||
|
||||
Reference in New Issue
Block a user