mirror of
https://github.com/kenzok8/small-package
synced 2025-01-08 13:27:36 +08:00
update 2022-07-01 09:02:09
This commit is contained in:
parent
463fab328c
commit
2924df6e98
24
luci-app-aliddns/Makefile
Normal file
24
luci-app-aliddns/Makefile
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (C) 2018 chenhw2 <https://github.com/chenhw2/>
|
||||
#
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI Support for aliddns
|
||||
LUCI_DESCRIPTION:=LuCI Support for ALiDDNS.
|
||||
LUCI_DEPENDS:=+openssl-util +curl
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_NAME:=luci-app-aliddns
|
||||
PKG_VERSION:=0.3.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
PKG_MAINTAINER:=chenhw2 <https://github.com/chenhw2/>
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
11
luci-app-aliddns/luasrc/controller/aliddns.lua
Normal file
11
luci-app-aliddns/luasrc/controller/aliddns.lua
Normal file
@ -0,0 +1,11 @@
|
||||
module("luci.controller.aliddns", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/aliddns") then
|
||||
return
|
||||
end
|
||||
|
||||
local page = entry({"admin", "services", "aliddns"}, cbi("aliddns"), _("AliDDNS"), 58)
|
||||
page.dependent = true
|
||||
page.acl_depends = { "luci-app-aliddns" }
|
||||
end
|
57
luci-app-aliddns/luasrc/model/cbi/aliddns.lua
Normal file
57
luci-app-aliddns/luasrc/model/cbi/aliddns.lua
Normal file
@ -0,0 +1,57 @@
|
||||
local a = require"luci.sys"
|
||||
local e = luci.model.uci.cursor()
|
||||
local e = require"nixio.fs"
|
||||
require("luci.sys")
|
||||
local t, e ,o
|
||||
|
||||
t = Map("aliddns", translate("AliDDNS"))
|
||||
|
||||
e = t:section(TypedSection, "base", translate("Base"))
|
||||
e.anonymous = true
|
||||
|
||||
enable = e:option(Flag, "enable", translate("enable"))
|
||||
enable.rmempty = false
|
||||
|
||||
enable = e:option(Flag, "clean", translate("Clean Before Update"))
|
||||
enable.rmempty = false
|
||||
|
||||
token = e:option(Value, "app_key", translate("Access Key ID"))
|
||||
email = e:option(Value, "app_secret", translate("Access Key Secret"))
|
||||
|
||||
iface = e:option(ListValue, "interface", translate("WAN-IP Source"), translate("Select the WAN-IP Source for AliDDNS, like wan/internet"))
|
||||
iface:value("", translate("Select WAN-IP Source"))
|
||||
iface:value("internet")
|
||||
iface:value("wan")
|
||||
|
||||
iface.rmempty = false
|
||||
main = e:option(Value, "main_domain", translate("Main Domain"), translate("For example: test.github.com -> github.com"))
|
||||
main.rmempty = false
|
||||
sub = e:option(Value, "sub_domain", translate("Sub Domain"), translate("For example: test.github.com -> test"))
|
||||
sub.rmempty = false
|
||||
time = e:option(Value, "time", translate("Inspection Time"), translate("Unit: Minute, Range: 1-59"))
|
||||
time.rmempty = false
|
||||
|
||||
e = t:section(TypedSection, "base", translate("Update Log"))
|
||||
e.anonymous = true
|
||||
local a = "/var/log/aliddns.log"
|
||||
tvlog = e:option(TextValue,"sylogtext")
|
||||
tvlog.rows = 16
|
||||
tvlog.readonly = "readonly"
|
||||
tvlog.wrap = "off"
|
||||
|
||||
function tvlog.cfgvalue(e,e)
|
||||
sylogtext = ""
|
||||
if a and nixio.fs.access(a) then
|
||||
sylogtext = luci.sys.exec("tail -n 100 %s"%a)
|
||||
end
|
||||
return sylogtext
|
||||
end
|
||||
|
||||
tvlog.write = function(e,e,e)
|
||||
end
|
||||
local e = luci.http.formvalue("cbi.apply")
|
||||
if e then
|
||||
io.popen("/etc/init.d/aliddns restart")
|
||||
end
|
||||
|
||||
return t
|
1
luci-app-aliddns/po/zh-cn
Symbolic link
1
luci-app-aliddns/po/zh-cn
Symbolic link
@ -0,0 +1 @@
|
||||
zh_Hans
|
44
luci-app-aliddns/po/zh_Hans/aliddns.po
Normal file
44
luci-app-aliddns/po/zh_Hans/aliddns.po
Normal file
@ -0,0 +1,44 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
msgid "AliDDNS"
|
||||
msgstr "阿里DDNS"
|
||||
|
||||
msgid "enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Clean Before Update"
|
||||
msgstr "清除所有同名记录"
|
||||
|
||||
msgid "Base"
|
||||
msgstr "基本设置"
|
||||
|
||||
msgid "WAN-IP Source"
|
||||
msgstr "WAN-IP来源"
|
||||
|
||||
msgid "Select WAN-IP Source"
|
||||
msgstr "选择WAN-IP来源"
|
||||
|
||||
msgid "Select the WAN-IP Source for AliDDNS, like wan/internet"
|
||||
msgstr "动态域名的IP来源,如wan/internet"
|
||||
|
||||
msgid "Main Domain"
|
||||
msgstr "主域名"
|
||||
|
||||
msgid "Sub Domain"
|
||||
msgstr "子域名"
|
||||
|
||||
msgid "For example: test.github.com -> github.com"
|
||||
msgstr "例如: test.github.com 则填: github.com"
|
||||
|
||||
msgid "For example: test.github.com -> test"
|
||||
msgstr "例如: test.github.com, 则填: test"
|
||||
|
||||
msgid "Inspection Time"
|
||||
msgstr "检查时间"
|
||||
|
||||
msgid "Unit: Minute, Range: 1-59"
|
||||
msgstr "域名检查间隔时间,单位分钟,范围1-59"
|
||||
|
||||
msgid "Update Log"
|
||||
msgstr "更新记录"
|
4
luci-app-aliddns/root/etc/config/aliddns
Normal file
4
luci-app-aliddns/root/etc/config/aliddns
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
config base 'base'
|
||||
option enable '0'
|
||||
option time '10'
|
64
luci-app-aliddns/root/etc/init.d/aliddns
Executable file
64
luci-app-aliddns/root/etc/init.d/aliddns
Executable file
@ -0,0 +1,64 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=80
|
||||
NAME=aliddns
|
||||
|
||||
NE_TIPS='AliDDNS NOT ENABLED'
|
||||
|
||||
restart() {
|
||||
start
|
||||
}
|
||||
|
||||
uci_get_by_name() {
|
||||
local ret=$(uci get $NAME.$1.$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
|
||||
uci_bool_by_name() {
|
||||
case "$(uci_get_by_name $1 $2)" in
|
||||
1|on|true|yes|enabled) return 0;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
add_hotplug() {
|
||||
cat <<EOF > "/etc/hotplug.d/iface/${START}-${NAME}"
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
[ "Z\$ACTION" = "Zifup" -a "Z\$INTERFACE" = "Zwan" ] || exit 0
|
||||
|
||||
DATE=\$(date +'%Y-%m-%d %H:%M:%S')
|
||||
( sleep 10 && ( echo "\$DATE IFUP-WAN" && /usr/sbin/aliddns ) >> /var/log/aliddns.log 2>&1 ) &
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
chmod +x "/etc/hotplug.d/iface/${START}-${NAME}"
|
||||
}
|
||||
|
||||
start() {
|
||||
$(uci_bool_by_name base enable) || {
|
||||
stop
|
||||
return 0
|
||||
}
|
||||
|
||||
add_hotplug
|
||||
|
||||
sed -i "/${NE_TIPS}/d" /var/log/aliddns.log
|
||||
|
||||
time=$(uci_get_by_name base time 10)
|
||||
[ 0 -lt $time -a $time -lt 60 ] || time=10
|
||||
|
||||
[ -f /etc/crontabs/root ] || mkdir -p /etc/crontabs && touch /etc/crontabs/root
|
||||
sed -i '/aliddns/d' /etc/crontabs/root
|
||||
echo "*/$time * * * * /usr/sbin/aliddns >> /var/log/aliddns.log 2>&1" >> /etc/crontabs/root
|
||||
/etc/init.d/cron restart
|
||||
|
||||
( /usr/sbin/aliddns >> /var/log/aliddns.log 2>&1 ) &
|
||||
}
|
||||
|
||||
stop() {
|
||||
rm -rf "/etc/hotplug.d/iface/${START}-${NAME}"
|
||||
sed -i '/aliddns/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
/etc/init.d/cron restart
|
||||
echo "${NE_TIPS}" > /var/log/aliddns.log
|
||||
}
|
10
luci-app-aliddns/root/etc/uci-defaults/luci-aliddns
Executable file
10
luci-app-aliddns/root/etc/uci-defaults/luci-aliddns
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@aliddns[-1]
|
||||
add ucitrack aliddns
|
||||
set ucitrack.@aliddns[-1].init=aliddns
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
exit 0
|
164
luci-app-aliddns/root/usr/sbin/aliddns
Executable file
164
luci-app-aliddns/root/usr/sbin/aliddns
Executable file
@ -0,0 +1,164 @@
|
||||
#!/bin/sh
|
||||
|
||||
NAME=aliddns
|
||||
log_file=/var/log/$NAME.log
|
||||
|
||||
uci_get_by_name() {
|
||||
local ret=$(uci get $NAME.$1.$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
|
||||
uci_bool_by_name() {
|
||||
case "$(uci_get_by_name $1 $2)" in
|
||||
1|on|true|yes|enabled) return 0;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
intelnetip() {
|
||||
tmp_ip=`curl -sL --connect-timeout 3 ns1.dnspod.net:6666`
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`curl -sL --connect-timeout 3 members.3322.org/dyndns/getip`
|
||||
fi
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`curl -sL --connect-timeout 3 14.215.150.17:6666`
|
||||
fi
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`curl -sL --connect-timeout 3 whatismyip.akamai.com`
|
||||
fi
|
||||
echo -n $tmp_ip
|
||||
}
|
||||
|
||||
resolve2ip() {
|
||||
# resolve2ip domain<string>
|
||||
domain=$1
|
||||
tmp_ip=`nslookup $domain ns1.alidns.com 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -n1`
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`nslookup $domain ns2.alidns.com 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -n1`
|
||||
fi
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`nslookup $domain 114.114.115.115 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -n1`
|
||||
fi
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`curl -sL --connect-timeout 3 "119.29.29.29/d?dn=$domain"`
|
||||
fi
|
||||
echo -n $tmp_ip
|
||||
}
|
||||
|
||||
check_aliddns() {
|
||||
echo "$DATE WAN-IP: ${ip}"
|
||||
if [ "Z$ip" == "Z" ]; then
|
||||
echo "$DATE ERROR, cant get WAN-IP..."
|
||||
return 0
|
||||
fi
|
||||
current_ip=$(resolve2ip "$sub_dm.$main_dm")
|
||||
if [ "Z$current_ip" == "Z" ]; then
|
||||
rrid='' # NO Resolve IP Means new Record_ID
|
||||
fi
|
||||
echo "$DATE DOMAIN-IP: ${current_ip}"
|
||||
if [ "Z$ip" == "Z$current_ip" ]; then
|
||||
echo "$DATE IP dont need UPDATE..."
|
||||
return 0
|
||||
else
|
||||
echo "$DATE UPDATING..."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
urlencode() {
|
||||
# urlencode url<string>
|
||||
out=''
|
||||
for c in $(echo -n $1 | sed 's/[^\n]/&\n/g'); do
|
||||
case $c in
|
||||
[a-zA-Z0-9._-]) out="$out$c" ;;
|
||||
*) out="$out$(printf '%%%02X' "'$c")" ;;
|
||||
esac
|
||||
done
|
||||
echo -n $out
|
||||
}
|
||||
|
||||
send_request() {
|
||||
# send_request action<string> args<string>
|
||||
local args="AccessKeyId=$ak_id&Action=$1&Format=json&$2&Version=2015-01-09"
|
||||
local hash=$(urlencode $(echo -n "GET&%2F&$(urlencode $args)" | openssl dgst -sha1 -hmac "$ak_sec&" -binary | openssl base64))
|
||||
curl -sSL --connect-timeout 5 "http://alidns.aliyuncs.com/?$args&Signature=$hash"
|
||||
}
|
||||
|
||||
get_recordid() {
|
||||
sed 's/RR/\n/g' | sed -n 's/.*RecordId[^0-9]*\([0-9]*\).*/\1\n/p' | sort -ru | sed /^$/d
|
||||
}
|
||||
|
||||
query_recordid() {
|
||||
send_request "DescribeSubDomainRecords" "SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&SubDomain=$sub_dm.$main_dm&Timestamp=$timestamp"
|
||||
}
|
||||
|
||||
update_record() {
|
||||
send_request "UpdateDomainRecord" "RR=$sub_dm&RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp&Type=A&Value=$ip"
|
||||
}
|
||||
|
||||
add_record() {
|
||||
send_request "AddDomainRecord&DomainName=$main_dm" "RR=$sub_dm&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp&Type=A&Value=$ip"
|
||||
}
|
||||
|
||||
del_record() {
|
||||
send_request "DeleteDomainRecord" "RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp"
|
||||
}
|
||||
|
||||
do_ddns_record() {
|
||||
if uci_bool_by_name base clean ; then
|
||||
query_recordid | get_recordid | while read rr; do
|
||||
echo "$DATE Clean record $sub_dm.$main_dm: $rr"
|
||||
del_record $rr >/dev/null
|
||||
timestamp=$(date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ")
|
||||
done
|
||||
rrid=''
|
||||
fi
|
||||
if [ "Z$rrid" == "Z" ]; then
|
||||
rrid=`query_recordid | get_recordid`
|
||||
fi
|
||||
if [ "Z$rrid" == "Z" ]; then
|
||||
rrid=`add_record | get_recordid`
|
||||
echo "$DATE ADD record $rrid"
|
||||
else
|
||||
update_record $rrid >/dev/null 2>&1
|
||||
echo "$DATE UPDATE record $rrid"
|
||||
fi
|
||||
if [ "Z$rrid" == "Z" ]; then
|
||||
# failed
|
||||
echo "$DATE # ERROR, Please Check Config/Time"
|
||||
else
|
||||
# save rrid
|
||||
uci set aliddns.base.record_id=$rrid
|
||||
uci commit aliddns
|
||||
echo "$DATE # UPDATED($ip)"
|
||||
fi
|
||||
}
|
||||
|
||||
clean_log() {
|
||||
if [ $(cat $log_file 2>/dev/null | wc -l) -ge 16 ]; then
|
||||
rm -f $log_file && touch $log_file
|
||||
echo "$DATE Log Cleaned"
|
||||
fi
|
||||
}
|
||||
|
||||
[ -x /usr/bin/openssl -a -x /usr/bin/curl -a -x /bin/sed ] ||
|
||||
( echo "Need [ openssl + curl + sed ]" && exit 1 )
|
||||
|
||||
ak_id=$(uci_get_by_name base app_key)
|
||||
ak_sec=$(uci_get_by_name base app_secret)
|
||||
rrid=$(uci_get_by_name base record_id)
|
||||
main_dm=$(uci_get_by_name base main_domain)
|
||||
sub_dm=$(uci_get_by_name base sub_domain)
|
||||
|
||||
iface=$(uci_get_by_name base interface)
|
||||
if [ "Z$iface" == "Zinternet" -o "Z$iface" == "Z" ]; then
|
||||
ip=$(intelnetip)
|
||||
else
|
||||
ip=$(ubus call network.interface.$iface status | grep '"address"' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
|
||||
fi
|
||||
|
||||
DATE=$(date +'%Y-%m-%d %H:%M:%S')
|
||||
timestamp=$(date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ")
|
||||
|
||||
clean_log
|
||||
check_aliddns || do_ddns_record
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-aliddns": {
|
||||
"description": "Grant UCI access for luci-app-aliddns",
|
||||
"read": {
|
||||
"uci": [ "aliddns" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "aliddns" ]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,17 +1,22 @@
|
||||
# Copyright (C) 2018-2020 Lienol <lawlienol@gmail.com>
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
# Copyright (C) 2021 ImmortalWrt
|
||||
# <https://immortalwrt.org>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for FileBrowser
|
||||
LUCI_TITLE:=LuCI Support for FileBrowser
|
||||
LUCI_DEPENDS:=+filebrowser
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_NAME:=luci-app-filebrowser
|
||||
PKG_VERSION:=snapshot
|
||||
PKG_RELEASE:=118071b
|
||||
|
||||
PKG_LICENSE:=GPLv3
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
||||
|
||||
|
@ -1,61 +1,22 @@
|
||||
-- Copyright 2018-2020 Lienol <lawlienol@gmail.com>
|
||||
module("luci.controller.filebrowser", package.seeall)
|
||||
|
||||
local http = require "luci.http"
|
||||
local api = require "luci.model.cbi.filebrowser.api"
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/filebrowser") then return end
|
||||
if not nixio.fs.access("/etc/config/filebrowser") then
|
||||
return
|
||||
end
|
||||
|
||||
entry({"admin", "nas"}, firstchild(), "NAS", 44).dependent = false
|
||||
entry({"admin", "nas", "filebrowser"}, cbi("filebrowser/settings"),
|
||||
_("File Browser"), 2).dependent = true
|
||||
entry({"admin", "nas"}, firstchild(), _("NAS"), 45).dependent = false
|
||||
|
||||
entry({"admin", "nas", "filebrowser", "check"}, call("action_check")).leaf =
|
||||
true
|
||||
entry({"admin", "nas", "filebrowser", "download"}, call("action_download")).leaf =
|
||||
true
|
||||
entry({"admin", "nas", "filebrowser", "status"}, call("act_status")).leaf =
|
||||
true
|
||||
entry({"admin", "nas", "filebrowser", "get_log"}, call("get_log")).leaf =
|
||||
true
|
||||
entry({"admin", "nas", "filebrowser", "clear_log"}, call("clear_log")).leaf =
|
||||
true
|
||||
end
|
||||
local page = entry({"admin", "nas", "filebrowser"}, cbi("filebrowser"), _("文件管理器"), 100)
|
||||
page.dependent = true
|
||||
page.acl_depends = { "luci-app-filebrowser" }
|
||||
|
||||
local function http_write_json(content)
|
||||
http.prepare_content("application/json")
|
||||
http.write_json(content or {code = 1})
|
||||
entry({"admin", "nas", "filebrowser", "status"}, call("act_status")).leaf = true
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e = {}
|
||||
e.status = luci.sys.call(
|
||||
"ps -w | grep -v grep | grep 'filebrowser -a 0.0.0.0' >/dev/null") ==
|
||||
0
|
||||
http_write_json(e)
|
||||
local e = {}
|
||||
e.running = luci.sys.call("pgrep filebrowser >/dev/null") == 0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function action_check()
|
||||
local json = api.to_check()
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function action_download()
|
||||
local json = nil
|
||||
local task = http.formvalue("task")
|
||||
if task == "extract" then
|
||||
json = api.to_extract(http.formvalue("file"))
|
||||
elseif task == "move" then
|
||||
json = api.to_move(http.formvalue("file"))
|
||||
else
|
||||
json = api.to_download(http.formvalue("url"))
|
||||
end
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function get_log()
|
||||
luci.http.write(luci.sys.exec(
|
||||
"[ -f '/var/log/filebrowser.log' ] && cat /var/log/filebrowser.log"))
|
||||
end
|
||||
function clear_log() luci.sys.call("echo '' > /var/log/filebrowser.log") end
|
||||
|
43
luci-app-filebrowser/luasrc/model/cbi/filebrowser.lua
Normal file
43
luci-app-filebrowser/luasrc/model/cbi/filebrowser.lua
Normal file
@ -0,0 +1,43 @@
|
||||
m = Map("filebrowser", translate("文件管理器"))
|
||||
m.description = translate("FileBrowser是一个基于Go的在线文件管理器,助您方便的管理设备上的文件。")
|
||||
|
||||
m:section(SimpleSection).template = "filebrowser/filebrowser_status"
|
||||
|
||||
s = m:section(TypedSection, "filebrowser")
|
||||
s.addremove = false
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(Flag, "enabled", translate("启用"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "addr_type", translate("监听地址"))
|
||||
o:value("local", translate("监听本机地址"))
|
||||
o:value("lan", translate("监听局域网地址"))
|
||||
o:value("wan", translate("监听全部地址"))
|
||||
o.default = "lan"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "port", translate("监听端口"))
|
||||
o.placeholder = 8989
|
||||
o.default = 8989
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "root_dir", translate("开放目录"))
|
||||
o.placeholder = "/"
|
||||
o.default = "/"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "db_dir", translate("数据库目录"))
|
||||
o.description = translate("普通用户请勿随意更改")
|
||||
o.placeholder = "/etc"
|
||||
o.default = "/etc"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "db_name", translate("数据库名"))
|
||||
o.description = translate("普通用户请勿随意更改")
|
||||
o.placeholder = "filebrowser.db"
|
||||
o.default = "filebrowser.db"
|
||||
o.rmempty = false
|
||||
|
||||
return m
|
@ -1,338 +0,0 @@
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local uci = require"luci.model.uci".cursor()
|
||||
local util = require "luci.util"
|
||||
local i18n = require "luci.i18n"
|
||||
|
||||
module("luci.model.cbi.filebrowser.api", package.seeall)
|
||||
|
||||
local appname = "filebrowser"
|
||||
local api_url =
|
||||
"https://api.github.com/repos/filebrowser/filebrowser/releases/latest"
|
||||
|
||||
local wget = "/usr/bin/wget"
|
||||
local wget_args = {
|
||||
"--no-check-certificate", "--quiet", "--timeout=10", "--tries=2"
|
||||
}
|
||||
local command_timeout = 300
|
||||
|
||||
local LEDE_BOARD = nil
|
||||
local DISTRIB_TARGET = nil
|
||||
|
||||
function uci_get_type(type, config, default)
|
||||
value = uci:get_first(appname, type, config, default) or sys.exec(
|
||||
"echo -n `uci -q get " .. appname .. ".@" .. type .. "[0]." ..
|
||||
config .. "`")
|
||||
if (value == nil or value == "") and (default and default ~= "") then
|
||||
value = default
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
local function _unpack(t, i)
|
||||
i = i or 1
|
||||
if t[i] ~= nil then return t[i], _unpack(t, i + 1) end
|
||||
end
|
||||
|
||||
local function exec(cmd, args, writer, timeout)
|
||||
local os = require "os"
|
||||
local nixio = require "nixio"
|
||||
|
||||
local fdi, fdo = nixio.pipe()
|
||||
local pid = nixio.fork()
|
||||
|
||||
if pid > 0 then
|
||||
fdo:close()
|
||||
|
||||
if writer or timeout then
|
||||
local starttime = os.time()
|
||||
while true do
|
||||
if timeout and os.difftime(os.time(), starttime) >= timeout then
|
||||
nixio.kill(pid, nixio.const.SIGTERM)
|
||||
return 1
|
||||
end
|
||||
|
||||
if writer then
|
||||
local buffer = fdi:read(2048)
|
||||
if buffer and #buffer > 0 then
|
||||
writer(buffer)
|
||||
end
|
||||
end
|
||||
|
||||
local wpid, stat, code = nixio.waitpid(pid, "nohang")
|
||||
|
||||
if wpid and stat == "exited" then return code end
|
||||
|
||||
if not writer and timeout then nixio.nanosleep(1) end
|
||||
end
|
||||
else
|
||||
local wpid, stat, code = nixio.waitpid(pid)
|
||||
return wpid and stat == "exited" and code
|
||||
end
|
||||
elseif pid == 0 then
|
||||
nixio.dup(fdo, nixio.stdout)
|
||||
fdi:close()
|
||||
fdo:close()
|
||||
nixio.exece(cmd, args, nil)
|
||||
nixio.stdout:close()
|
||||
os.exit(1)
|
||||
end
|
||||
end
|
||||
|
||||
local function compare_versions(ver1, comp, ver2)
|
||||
local table = table
|
||||
|
||||
local av1 = util.split(ver1, "[%.%-]", nil, true)
|
||||
local av2 = util.split(ver2, "[%.%-]", nil, true)
|
||||
|
||||
local max = table.getn(av1)
|
||||
local n2 = table.getn(av2)
|
||||
if (max < n2) then max = n2 end
|
||||
|
||||
for i = 1, max, 1 do
|
||||
local s1 = av1[i] or ""
|
||||
local s2 = av2[i] or ""
|
||||
|
||||
if comp == "~=" and (s1 ~= s2) then return true end
|
||||
if (comp == "<" or comp == "<=") and (s1 < s2) then return true end
|
||||
if (comp == ">" or comp == ">=") and (s1 > s2) then return true end
|
||||
if (s1 ~= s2) then return false end
|
||||
end
|
||||
|
||||
return not (comp == "<" or comp == ">")
|
||||
end
|
||||
|
||||
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}'`")
|
||||
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}'`")
|
||||
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'")
|
||||
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'")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return util.trim(arch)
|
||||
end
|
||||
|
||||
local function get_file_info(arch)
|
||||
local file_tree = ""
|
||||
local sub_version = ""
|
||||
|
||||
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 = "armv"
|
||||
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
|
||||
|
||||
local function get_api_json(url)
|
||||
local jsonc = require "luci.jsonc"
|
||||
|
||||
local output = {}
|
||||
-- exec(wget, { "-O-", url, _unpack(wget_args) },
|
||||
-- function(chunk) output[#output + 1] = chunk end)
|
||||
-- local json_content = util.trim(table.concat(output))
|
||||
|
||||
local json_content = luci.sys.exec(wget ..
|
||||
" --no-check-certificate --timeout=10 -t 1 -O- " ..
|
||||
url)
|
||||
|
||||
if json_content == "" then return {} end
|
||||
|
||||
return jsonc.parse(json_content) or {}
|
||||
end
|
||||
|
||||
function get_version() return uci_get_type("global", "version", "0") end
|
||||
|
||||
function to_check(arch)
|
||||
if not arch or arch == "" then arch = auto_get_arch() end
|
||||
|
||||
local file_tree, sub_version = get_file_info(arch)
|
||||
|
||||
if file_tree == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate(
|
||||
"Can't determine ARCH, or ARCH not supported.")
|
||||
}
|
||||
end
|
||||
|
||||
local json = get_api_json(api_url)
|
||||
|
||||
if json.tag_name == nil then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Get remote version info failed.")
|
||||
}
|
||||
end
|
||||
|
||||
local remote_version = json.tag_name:match("[^v]+")
|
||||
|
||||
local needs_update = compare_versions(get_version(), "<", remote_version)
|
||||
local html_url, download_url
|
||||
|
||||
if needs_update then
|
||||
html_url = json.html_url
|
||||
for _, v in ipairs(json.assets) do
|
||||
if v.name and v.name:match("linux%-" .. file_tree .. sub_version) then
|
||||
download_url = v.browser_download_url
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if needs_update and not download_url then
|
||||
return {
|
||||
code = 1,
|
||||
version = remote_version,
|
||||
html_url = html_url,
|
||||
error = i18n.translate(
|
||||
"New version found, but failed to get new version download url.")
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
code = 0,
|
||||
update = needs_update,
|
||||
version = remote_version,
|
||||
url = {html = html_url, download = download_url}
|
||||
}
|
||||
end
|
||||
|
||||
function to_download(url)
|
||||
if not url or url == "" then
|
||||
return {code = 1, error = i18n.translate("Download url is required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -f /tmp/filebrowser_download.*")
|
||||
|
||||
local tmp_file = util.trim(util.exec(
|
||||
"mktemp -u -t filebrowser_download.XXXXXX"))
|
||||
|
||||
local result = exec(wget, {"-O", tmp_file, url, _unpack(wget_args)}, nil,
|
||||
command_timeout) == 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}
|
||||
end
|
||||
|
||||
function to_extract(file, subfix)
|
||||
if not file or file == "" or not fs.access(file) then
|
||||
return {code = 1, error = i18n.translate("File path required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/filebrowser_extract.*")
|
||||
local tmp_dir = util.trim(util.exec(
|
||||
"mktemp -d -t filebrowser_extract.XXXXXX"))
|
||||
|
||||
local output = {}
|
||||
exec("/bin/tar", {"-C", tmp_dir, "-zxvf", file},
|
||||
function(chunk) output[#output + 1] = chunk end)
|
||||
|
||||
local files = util.split(table.concat(output))
|
||||
|
||||
exec("/bin/rm", {"-f", file})
|
||||
|
||||
if not new_file then
|
||||
for _, f in pairs(files) do
|
||||
if f:match("filebrowser") then
|
||||
new_file = tmp_dir .. "/" .. util.trim(f)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not new_file then
|
||||
exec("/bin/rm", {"-rf", tmp_dir})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Can't find client in file: %s", file)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0, file = new_file}
|
||||
end
|
||||
|
||||
function to_move(file)
|
||||
if not file or file == "" or not fs.access(file) then
|
||||
sys.call("/bin/rm -rf /tmp/filebrowser_extract.*")
|
||||
return {code = 1, error = i18n.translate("Client file is required.")}
|
||||
end
|
||||
local project_directory =
|
||||
uci_get_type("global", "project_directory", "/tmp")
|
||||
luci.sys.exec("mkdir -p " .. project_directory)
|
||||
local client_path = project_directory .. "/" .. appname
|
||||
local client_path_bak
|
||||
|
||||
if fs.access(client_path) then
|
||||
client_path_bak = "/tmp/" .. appname .. ".bak"
|
||||
exec("/bin/mv", {"-f", client_path, client_path_bak})
|
||||
end
|
||||
|
||||
local result = exec("/bin/mv", {"-f", file, client_path}, nil,
|
||||
command_timeout) == 0
|
||||
|
||||
if not result or not fs.access(client_path) then
|
||||
if client_path_bak then
|
||||
exec("/bin/mv", {"-f", client_path_bak, client_path})
|
||||
end
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Can't move new file to path: %s",
|
||||
client_path)
|
||||
}
|
||||
end
|
||||
|
||||
exec("/bin/chmod", {"755", client_path})
|
||||
|
||||
if client_path_bak then exec("/bin/rm", {"-f", client_path_bak}) end
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/filebrowser_extract.*")
|
||||
|
||||
return {code = 0}
|
||||
end
|
@ -1,37 +0,0 @@
|
||||
m = Map("filebrowser", translate("FileBrowser"), translate(
|
||||
"File explorer is software that creates your own cloud that you can install on a server, point it to a path, and then access your files through a beautiful web interface. You have many features available!"))
|
||||
m:append(Template("filebrowser/status"))
|
||||
|
||||
s = m:section(TypedSection, "global", translate("Global Settings"))
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
|
||||
o = s:option(Flag, "enable", translate("Enable"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "port", translate("Listen port"))
|
||||
o.datatype = "port"
|
||||
o.default = 8088
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "root_path", translate("Root path"), translate(
|
||||
"Point to a path to access your files in the web interface, default is /"))
|
||||
o.default = "/"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "project_directory", translate("Project directory"),
|
||||
translate(
|
||||
"The file size is large, requiring at least 32M space. It is recommended to insert a usb flash drive or hard disk, or use it in the tmp directory<br />For example, /mnt/sda1<br />For example, /tmp"))
|
||||
o.default = "/tmp"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Button, "_download", translate("Manually download"), translate(
|
||||
"Make sure you have enough space. <br /><font style='color:red'>Be sure to fill out the project storage directory the first time you run it, and then save the application. Then manually download, otherwise can not use!</font>"))
|
||||
o.template = "filebrowser/download"
|
||||
o.inputstyle = "apply"
|
||||
o.btnclick = "downloadClick(this);"
|
||||
o.id = "download_btn"
|
||||
|
||||
m:append(Template("filebrowser/log"))
|
||||
|
||||
return m
|
@ -1,169 +0,0 @@
|
||||
<%
|
||||
local dsp = require "luci.dispatcher"
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var msgInfo;
|
||||
|
||||
var tokenStr = '<%=token%>';
|
||||
var clickToDownloadText = '<%:Click to download%>';
|
||||
var inProgressText = '<%:Downloading...%>';
|
||||
var downloadInProgressNotice = '<%:Download, are you sure to close?%>';
|
||||
var downloadSuccessText = '<%:Download successful%>';
|
||||
var unexpectedErrorText = '<%:Unexpected error%>';
|
||||
|
||||
function addPageNotice() {
|
||||
window.onbeforeunload = function(e) {
|
||||
e.returnValue = downloadInProgressNotice;
|
||||
return downloadInProgressNotice;
|
||||
};
|
||||
}
|
||||
|
||||
function removePageNotice() {
|
||||
window.onbeforeunload = undefined;
|
||||
}
|
||||
|
||||
function onUpdateSuccess(btn) {
|
||||
alert(downloadSuccessText);
|
||||
|
||||
if (btn) {
|
||||
btn.value = downloadSuccessText;
|
||||
btn.placeholder = downloadSuccessText;
|
||||
btn.disabled = true;
|
||||
}
|
||||
|
||||
window.setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function onRequestError(btn, errorMessage) {
|
||||
btn.disabled = false;
|
||||
btn.value = btn.placeholder;
|
||||
|
||||
if (errorMessage) {
|
||||
alert(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function doAjaxGet(url, data, onResult) {
|
||||
new XHR().get(url, data, function(_, json) {
|
||||
var resultJson = json || {
|
||||
'code': 1,
|
||||
'error': unexpectedErrorText
|
||||
};
|
||||
|
||||
if (typeof onResult === 'function') {
|
||||
onResult(resultJson);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function downloadClick(btn) {
|
||||
if (msgInfo === undefined) {
|
||||
checkUpdate(btn);
|
||||
} else {
|
||||
doDownload(btn);
|
||||
}
|
||||
}
|
||||
|
||||
function checkUpdate(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = inProgressText;
|
||||
|
||||
addPageNotice();
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
|
||||
doAjaxGet('<%=dsp.build_url("admin/nas/filebrowser/check")%>/', {
|
||||
token: tokenStr
|
||||
}, function (json) {
|
||||
removePageNotice();
|
||||
if (json.code) {
|
||||
eval('Info = undefined');
|
||||
onRequestError(btn, json.error);
|
||||
} else {
|
||||
eval('Info = json');
|
||||
btn.disabled = false;
|
||||
btn.value = clickToDownloadText;
|
||||
btn.placeholder = clickToDownloadText;
|
||||
}
|
||||
|
||||
if (ckeckDetailElm) {
|
||||
var urlNode = '';
|
||||
if (json.version) {
|
||||
urlNode = '<em style="color:red;"><%:The latest version:%>' + json.version + '</em>';
|
||||
if (json.url && json.url.html) {
|
||||
urlNode = '<a href="' + json.url.html + '" target="_blank">' + urlNode + '</a>';
|
||||
}
|
||||
}
|
||||
ckeckDetailElm.innerHTML = urlNode;
|
||||
}
|
||||
msgInfo = json;
|
||||
});
|
||||
}
|
||||
|
||||
function doDownload(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = '<%:Downloading...%>';
|
||||
|
||||
addPageNotice();
|
||||
|
||||
var UpdateUrl = '<%=dsp.build_url("admin/nas/filebrowser/download")%>';
|
||||
// Download file
|
||||
doAjaxGet(UpdateUrl, {
|
||||
token: tokenStr,
|
||||
url: msgInfo ? msgInfo.url.download : ''
|
||||
}, function (json) {
|
||||
if (json.code) {
|
||||
removePageNotice();
|
||||
onRequestError(btn, json.error);
|
||||
} else {
|
||||
btn.value = '<%:Unpacking...%>';
|
||||
|
||||
// Extract file
|
||||
doAjaxGet(UpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'extract',
|
||||
file: json.file
|
||||
}, function (json) {
|
||||
if (json.code) {
|
||||
removePageNotice();
|
||||
onRequestError(btn, json.error);
|
||||
} else {
|
||||
btn.value = '<%:Moving...%>';
|
||||
|
||||
// Move file to target dir
|
||||
doAjaxGet(UpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'move',
|
||||
file: json.file
|
||||
}, function (json) {
|
||||
removePageNotice();
|
||||
if (json.code) {
|
||||
onRequestError(btn, json.error);
|
||||
} else {
|
||||
onUpdateSuccess(btn);
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
//]]></script>
|
||||
|
||||
<%+cbi/valueheader%>
|
||||
<% if self:cfgvalue(section) ~= false then %>
|
||||
<input class="cbi-button cbi-input-<%=self.inputstyle or "button" %>" type="button"<%=
|
||||
attr("name", cbid) ..
|
||||
attr("id", self.id or cbid) ..
|
||||
attr("value", self.inputtitle or self.title) ..
|
||||
ifattr(self.btnclick, "onclick", self.btnclick) ..
|
||||
ifattr(self.placeholder, "placeholder")
|
||||
%> />
|
||||
<span id="<%=self.id or cbid%>-detail"></span>
|
||||
<% else %>
|
||||
-
|
||||
<% end %>
|
||||
<%+cbi/valuefooter%>
|
@ -0,0 +1,27 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(1, '<%=url([[admin]], [[nas]], [[filebrowser]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('filebrowser_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
var links = '<font color=green>Filebrowser <%:运行中%></font><input class="cbi-button mar-10" type="button" value="<%:打开管理界面%>" onclick="openwebui();" />';
|
||||
tb.innerHTML = links;
|
||||
} else {
|
||||
tb.innerHTML = '<font color=red>Filebrowser <%:未运行%></font>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function openwebui(){
|
||||
var url = window.location.host+":<%=luci.sys.exec("uci -q get filebrowser.config.port"):gsub("^%s*(.-)%s*$", "%1")%>";
|
||||
window.open('http://'+url,'target','');
|
||||
};
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="filebrowser_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
@ -1,31 +0,0 @@
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function clear_log(btn) {
|
||||
XHR.get('<%=url([[admin]], [[nas]], [[filebrowser]], [[clear_log]])%>', null,
|
||||
function(x, data) {
|
||||
if(x && x.status == 200) {
|
||||
var log_textarea = document.getElementById('log_textarea');
|
||||
log_textarea.innerHTML = "";
|
||||
log_textarea.scrollTop = log_textarea.scrollHeight;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
XHR.poll(3, '<%=url([[admin]], [[nas]], [[filebrowser]], [[get_log]])%>', null,
|
||||
function(x, data) {
|
||||
if(x && x.status == 200) {
|
||||
var log_textarea = document.getElementById('log_textarea');
|
||||
log_textarea.innerHTML = x.responseText;
|
||||
log_textarea.scrollTop = log_textarea.scrollHeight;
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<fieldset class="cbi-section" id="_log_fieldset">
|
||||
<legend>
|
||||
<%:Logs%>
|
||||
</legend>
|
||||
<input class="cbi-button cbi-input-remove" type="button" onclick="clear_log()" value="<%:Clear logs%>">
|
||||
<textarea id="log_textarea" class="cbi-input-textarea" style="width: 100%;margin-top: 10px;" data-update="change" rows="5" wrap="off" readonly="readonly"></textarea>
|
||||
</fieldset>
|
@ -1,29 +0,0 @@
|
||||
<%
|
||||
local dsp = require "luci.dispatcher"
|
||||
-%>
|
||||
|
||||
<fieldset class="cbi-section">
|
||||
<legend><%:Running Status%></legend>
|
||||
<fieldset class="cbi-section">
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field" id="_status"><%:Collecting data...%></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var _status = document.getElementById('_status');
|
||||
XHR.poll(3,'<%=dsp.build_url("admin/nas/filebrowser/status")%>', null,
|
||||
function(x, json) {
|
||||
if (x && x.status == 200) {
|
||||
if (_status)
|
||||
_status.innerHTML = json.status ? '<font color="green"><%:RUNNING%> ✓</font><p><input type="button" class="cbi-button cbi-input-apply" value="<%:Enter interface%>" onclick="openwebui()" /></p>' : '<font color="red"><%:NOT RUNNING%> X</font>';
|
||||
}
|
||||
});
|
||||
|
||||
function openwebui(){
|
||||
var url = window.location.host+":<%=luci.sys.exec("uci get filebrowser.@global[0].port"):gsub("^%s*(.-)%s*$", "%1")%>";
|
||||
window.open('http://'+url,'target','');
|
||||
}
|
||||
//]]></script>
|
@ -1,107 +0,0 @@
|
||||
msgid "File Browser"
|
||||
msgstr "文件浏览器"
|
||||
|
||||
msgid "File explorer is software that creates your own cloud that you can install on a server, point it to a path, and then access your files through a beautiful web interface. You have many features available!"
|
||||
msgstr "文件浏览器是一种创建你自己的云的软件,你可以在服务器上安装它,将它指向一个路径,然后通过一个漂亮的web界面访问你的文件。您有许多可用的特性!"
|
||||
|
||||
msgid "RUNNING"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "Enter interface"
|
||||
msgstr "进入界面"
|
||||
|
||||
msgid "Global Settings"
|
||||
msgstr "全局设置"
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Listen port"
|
||||
msgstr "监听端口"
|
||||
|
||||
msgid "Root path"
|
||||
msgstr "指向路径"
|
||||
|
||||
msgid "Point to a path to access your files in the web interface, default is /"
|
||||
msgstr "指向一个路径,可在web界面访问你的文件,默认为 /"
|
||||
|
||||
msgid "Project directory"
|
||||
msgstr "项目存放目录"
|
||||
|
||||
msgid "The file size is large, requiring at least 32M space. It is recommended to insert a usb flash drive or hard disk, or use it in the tmp directory<br />For example, /mnt/sda1<br />For example, /tmp"
|
||||
msgstr "文件较大,至少需要32M空间。建议插入U盘或硬盘,或放入tmp目录里使用<br />例如:/mnt/sda1<br />例如:/tmp"
|
||||
|
||||
msgid "Manually download"
|
||||
msgstr "手动下载"
|
||||
|
||||
msgid "Make sure you have enough space. <br /><font style='color:red'>Be sure to fill out the project storage directory the first time you run it, and then save the application. Then manually download, otherwise can not use!</font>"
|
||||
msgstr "请确保具有足够的空间。<br /><font style='color:red'>第一次运行务必填好项目存放目录,然后保存应用。再手动下载,否则无法使用!</font>"
|
||||
|
||||
msgid "Logs"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "Clear logs"
|
||||
msgstr "清空日志"
|
||||
|
||||
msgid "It is the latest version"
|
||||
msgstr "已是最新版本"
|
||||
|
||||
msgid "Download successful"
|
||||
msgstr "下载成功"
|
||||
|
||||
msgid "Click to download"
|
||||
msgstr "点击下载"
|
||||
|
||||
msgid "Updating..."
|
||||
msgstr "更新中"
|
||||
|
||||
msgid "Unexpected error"
|
||||
msgstr "意外错误"
|
||||
|
||||
msgid "Download, are you sure to close?"
|
||||
msgstr "正在下载,你确认要关闭吗?"
|
||||
|
||||
msgid "Downloading..."
|
||||
msgstr "下载中"
|
||||
|
||||
msgid "Unpacking..."
|
||||
msgstr "解压中"
|
||||
|
||||
msgid "Moving..."
|
||||
msgstr "移动中"
|
||||
|
||||
msgid "The latest version:"
|
||||
msgstr "最新版本:"
|
||||
|
||||
msgid "Can't determine ARCH, or ARCH not supported."
|
||||
msgstr "无法确认ARCH架构,或是不支持。"
|
||||
|
||||
msgid "Get remote version info failed."
|
||||
msgstr "获取远程版本信息失败。"
|
||||
|
||||
msgid "New version found, but failed to get new version download url."
|
||||
msgstr "发现新版本,但未能获得新版本的下载地址。"
|
||||
|
||||
msgid "Download url is required."
|
||||
msgstr "请指定下载地址。"
|
||||
|
||||
msgid "File download failed or timed out: %s"
|
||||
msgstr "文件下载失败或超时:%s"
|
||||
|
||||
msgid "File path required."
|
||||
msgstr "请指定文件路径。"
|
||||
|
||||
msgid "Can't find client in file: %s"
|
||||
msgstr "无法在文件中找到客户端:%s"
|
||||
|
||||
msgid "Client file is required."
|
||||
msgstr "请指定客户端文件。"
|
||||
|
||||
msgid "The client file is not suitable for current device."
|
||||
msgstr "客户端文件不适合当前设备。"
|
||||
|
||||
msgid "Can't move new file to path: %s"
|
||||
msgstr "无法移动新文件到:%s"
|
@ -1 +0,0 @@
|
||||
zh-cn
|
@ -1,7 +0,0 @@
|
||||
|
||||
config global
|
||||
option port '8088'
|
||||
option root_path '/'
|
||||
option project_directory '/tmp'
|
||||
option enable '0'
|
||||
|
@ -1,38 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2018-2020 Lienol <lawlienol@gmail.com>
|
||||
|
||||
START=99
|
||||
|
||||
LOG_PATH="/var/log/filebrowser.log"
|
||||
|
||||
echolog() {
|
||||
echo -e "$(date "+%Y-%m-%d %H:%M:%S"): $1" >> $LOG_PATH
|
||||
}
|
||||
|
||||
config_t_get() {
|
||||
local index=0
|
||||
[ -n "$4" ] && index=$4
|
||||
local ret=$(uci get filebrowser.@$1[$index].$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
start() {
|
||||
ENABLED=$(config_t_get global enable 0)
|
||||
[ "$ENABLED" = "0" ] && return
|
||||
PORT=$(config_t_get global port 8088)
|
||||
ROOT_PATH=$(config_t_get global root_path /)
|
||||
project_directory=$(config_t_get global project_directory /tmp)
|
||||
[ ! -f "$project_directory/filebrowser" ] && echolog "在$project_directory找不到FileBrowser主程序,请下载。" && exit
|
||||
export HOME="/root"
|
||||
$project_directory/filebrowser -a 0.0.0.0 -p $PORT -r $ROOT_PATH -d ${ROOT_PATH}filebrowser.db -l $LOG_PATH >/dev/null 2>&1 &
|
||||
}
|
||||
|
||||
stop() {
|
||||
ps -w | grep -v "grep" | grep "$project_directory/filebrowser -a 0.0.0.0" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
|
||||
rm -rf $LOG_PATH
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
sleep 1
|
||||
start
|
||||
}
|
@ -885,6 +885,7 @@
|
||||
170yy.com
|
||||
171.246.c752sa3k9oeb2eg2ehpgc8fnhkeyyyyyn.domsearch.net
|
||||
1711427.5.d.mytopgames.net
|
||||
1717.1000uc.com
|
||||
17173im.allyes.com
|
||||
1717gs.com
|
||||
171a60540b.com
|
||||
@ -9947,6 +9948,7 @@ adv-adserver.com
|
||||
adv-banner.libero.it
|
||||
adv-ettoday.cdn.hinet.net
|
||||
adv-feedback.adsterra.com
|
||||
adv-front.devpnd.com
|
||||
adv-id-data.startappservice.com
|
||||
adv-links.com
|
||||
adv-mydarkness.ggcorp.me
|
||||
@ -13576,6 +13578,7 @@ api.ireaderm.net
|
||||
api.itaoxiaoshuo.com
|
||||
api.iterable.com
|
||||
api.iterative.ly
|
||||
api.itpub.cloud
|
||||
api.itv.letv.com
|
||||
api.ivymobile.com
|
||||
api.jpush.cn
|
||||
@ -16958,6 +16961,7 @@ bam.eu01.nr-data.net
|
||||
bam.nr-data.net
|
||||
bamagamalama.com
|
||||
bamashmous.sa
|
||||
bamassociates.net
|
||||
bamayad.com
|
||||
bambluagamgona.com
|
||||
bamcsfm.com
|
||||
@ -19089,6 +19093,7 @@ bleopi.com
|
||||
blessedwin.life
|
||||
blessgarments.com
|
||||
blessingsome.com
|
||||
blessingsource.com
|
||||
blidattlenoined.com
|
||||
bliink.io
|
||||
blimpdigital.com
|
||||
@ -19258,6 +19263,7 @@ bluedawning.com
|
||||
bluedcrwth.com
|
||||
bluedeathvalley.com
|
||||
bluedict.com
|
||||
blueeyesintelligence.org
|
||||
blueflamemarket.com
|
||||
bluefly.speedera.net
|
||||
bluejayfacette.com
|
||||
@ -19267,6 +19273,7 @@ bluemarblepayroll.actonservice.com
|
||||
bluematrixs.com
|
||||
bluematt.me
|
||||
bluemaulpuffs.com
|
||||
blueomatic.com
|
||||
blueoyster.click
|
||||
blueparrot.media
|
||||
blueprod.amobee.com
|
||||
@ -20042,6 +20049,7 @@ bridalmasks.com
|
||||
bridalplums.com
|
||||
bridge.lga1.admarketplace.net
|
||||
bridge.sfo1.admarketplace.net
|
||||
bridgesfoundationrepair.com
|
||||
bridgetobalance.com
|
||||
bridgetrack.com
|
||||
bridgevine.com
|
||||
@ -21501,6 +21509,7 @@ camaravotuporanga.sp.gov.br
|
||||
camatalowes.com
|
||||
camatasisal.com
|
||||
cambrianter.club
|
||||
camcha.cl
|
||||
camcrush.com
|
||||
camdough.com
|
||||
camduty.com
|
||||
@ -21720,6 +21729,7 @@ carambo.la
|
||||
caramel.press
|
||||
carapusgyal.com
|
||||
carasalegres.org
|
||||
caravanasitsaso.es
|
||||
carbinz.ml
|
||||
carbonads.com
|
||||
carbonads.net
|
||||
@ -23318,6 +23328,7 @@ cfasync.ga
|
||||
cfasync.ml
|
||||
cfasync.tk
|
||||
cfatceaikgxdhv.com
|
||||
cfbenchcl.com
|
||||
cfboo.com
|
||||
cfc553b16f.com
|
||||
cfcalda.com.br
|
||||
@ -26680,6 +26691,7 @@ consulturias.com
|
||||
consumable.com
|
||||
consumer.exacttargetapis.com
|
||||
consumer.krxd.net
|
||||
consumerfinanceguide.com
|
||||
consumergenepool.com
|
||||
consumergoodnight.com
|
||||
consumerproductsusa.com
|
||||
@ -27020,6 +27032,7 @@ cooladata.com
|
||||
cooladata.kampyle.com
|
||||
coolbook.cc
|
||||
coolbrowsering.xyz
|
||||
coolcraft.at
|
||||
coolerads.com
|
||||
coolfenxi.com
|
||||
coolfuture.xyz
|
||||
@ -28048,6 +28061,7 @@ crtv.wbidder.online
|
||||
crtv.wbidr.com
|
||||
crtx.info
|
||||
crtxbebfhp.com
|
||||
cruced.com
|
||||
crudeartfulrecreate.com
|
||||
crudenergyllc.com
|
||||
crudesoothing.com
|
||||
@ -28163,6 +28177,7 @@ cs04.fast-hunter.com
|
||||
cs05.fast-hunter.com
|
||||
cs1.wpc.v0cdn.net
|
||||
cs12d.com
|
||||
cs14productions.com
|
||||
cs15.livetex.ru
|
||||
csad.cc
|
||||
csaimall.com
|
||||
@ -30240,6 +30255,7 @@ dca-tg.com
|
||||
dca.ads.nexage.com
|
||||
dca.as.nexage.com
|
||||
dcads.sina.com.cn
|
||||
dcai7bdiz5toz.cloudfront.net
|
||||
dcaingenieria.com.co
|
||||
dcapps.disney.go.com
|
||||
dcba.popcash.net
|
||||
@ -30883,6 +30899,7 @@ descgkfypyhc.xyz
|
||||
descobriraurora.com.br
|
||||
descontador.com.br
|
||||
descrepush.com
|
||||
descriptiveimmortalityconveyed.com
|
||||
descz.ovh
|
||||
desekansr.com
|
||||
desembobelinons.site
|
||||
@ -31207,6 +31224,7 @@ dharmacomunicacao.com.br
|
||||
dhawtqebxbgk.xyz
|
||||
dhb8psqhvz9a.com
|
||||
dhcguxefkuhfkhi.com
|
||||
dhcmart.com
|
||||
dhdgkj.com
|
||||
dhejr.cn
|
||||
dhenr54m.com
|
||||
@ -32874,6 +32892,7 @@ drjgjngf.com
|
||||
drkarnikatiwari.com
|
||||
drkfnygqsgewdsn.xyz
|
||||
drkkydnkdvfosd.xyz
|
||||
drldgfscmjgim.com
|
||||
drlimmode9ddd.cloudfront.net
|
||||
drlphsvpybieyie.xyz
|
||||
drluisholguin.com
|
||||
@ -37430,6 +37449,7 @@ eylxxvilppj.com
|
||||
eymiwj.cancan.ro
|
||||
eynaaxnshpf.com
|
||||
eyouv.cn
|
||||
eypgovh0oe3pfm.xyz
|
||||
eyqeipls.com
|
||||
eytenenergy.us.com
|
||||
eywvmnf.cn
|
||||
@ -44734,6 +44754,7 @@ herbaijansob.club
|
||||
herbalcircumstantial.com
|
||||
herbalife.tt.omtrdc.net
|
||||
herbtytox.com
|
||||
herchinfitout.com.sg
|
||||
hercules.iad.appboy.com
|
||||
herdailylife.com
|
||||
herdarta.net
|
||||
@ -46060,6 +46081,7 @@ hsdn.org
|
||||
hsdptnefgmkik.xyz
|
||||
hseyycgljjcbakl.com
|
||||
hsh51nvkrv.com
|
||||
hsiaik.com
|
||||
hsjaymodoopsr.xyz
|
||||
hsjwnmdcjb.com
|
||||
hskj.net
|
||||
@ -49587,6 +49609,7 @@ ir.mail.126.com
|
||||
ir.mail.163.com
|
||||
ir.mail.yeah.net
|
||||
iraithiz.com
|
||||
iranparsa-novin.com
|
||||
iranregal.ir
|
||||
irardijjyawmool.xyz
|
||||
iratelyveinlet.com
|
||||
@ -53836,6 +53859,7 @@ laserveradedomaina.com
|
||||
lashquivercakes.com
|
||||
lashsketch.com
|
||||
lasinka.000webhostapp.com
|
||||
lassampy.com
|
||||
lasteventf.tubemogul.com
|
||||
lasticalsdeb.xyz
|
||||
lastminutehotelbooking.com
|
||||
@ -53866,6 +53890,8 @@ lativahgreene.com
|
||||
latoniankeen.pro
|
||||
latrinehelves.com
|
||||
latterinconvenient.com
|
||||
latticescience.com
|
||||
latticescipub.com
|
||||
latuga.com
|
||||
latvianswived.com
|
||||
laufke.se
|
||||
@ -75253,6 +75279,7 @@ pulverizehinder.com
|
||||
puma-api.iqiyi.com
|
||||
puma.api.iqiyi.com
|
||||
pumdfferpkin5hs454r43eeds.com
|
||||
pumeu25uj.xyz
|
||||
pumiceprutah.com
|
||||
pumolt.com
|
||||
pumpbead.com
|
||||
@ -77090,6 +77117,7 @@ ralphabnegation.com
|
||||
ramainfotech.in
|
||||
ramanalysis.r.xoxknct.com
|
||||
ramanalysis.s.xoxknct.com
|
||||
ramankumarynr.com
|
||||
ramatering.club
|
||||
rambibelk.com
|
||||
rambleconcernedscar.com
|
||||
@ -83802,6 +83830,7 @@ simon184.cn
|
||||
simonsignal.com
|
||||
simontok.app
|
||||
simpan.online
|
||||
simpant.sc.ug
|
||||
simpasa.cn
|
||||
simpio.com
|
||||
simple-backupbooster.com
|
||||
@ -89576,6 +89605,7 @@ sunnimiq5.cf
|
||||
sunnimiq6.cf
|
||||
sunnybluecoral.com
|
||||
sunnycategoryopening.com
|
||||
sunnyseries.com
|
||||
sunnysmedia.com
|
||||
sunnysun.co
|
||||
sunonesearch.112.2o7.net
|
||||
@ -89597,6 +89627,7 @@ sunyujia.top
|
||||
suo.lp.mydas.mobi
|
||||
suocloud.com
|
||||
suoksm.cn
|
||||
suomicgeyser.com
|
||||
suoooi.cn
|
||||
suozmtcc.com
|
||||
sup.adfox.ru
|
||||
@ -95343,6 +95374,7 @@ tracking.netzathleten-media.de
|
||||
tracking.newyorklifeinvestments.com
|
||||
tracking.nextdoor.com
|
||||
tracking.nissan-dubai.com
|
||||
tracking.nmemails.com
|
||||
tracking.noen.at
|
||||
tracking.nokai.jp
|
||||
tracking.notizie.it
|
||||
@ -98556,6 +98588,7 @@ utrosy.com
|
||||
uts-front.line-apps.com
|
||||
uts.auction.co.kr
|
||||
uts.kingoapp.com
|
||||
utt.impactcdn.com
|
||||
uttclimber.com
|
||||
utteredtheatresaround.com
|
||||
uttermosthobbies.com
|
||||
@ -102848,6 +102881,7 @@ worldgravity.com
|
||||
worldh5.gamehz.cn
|
||||
worldlogger.com
|
||||
worldmedicsky.info
|
||||
worldmedpilldeliver.com
|
||||
worldpile.com
|
||||
worldpush.co
|
||||
worldsbestcams.com
|
||||
@ -104364,6 +104398,7 @@ www.challengehurts.com
|
||||
www.chanet.com.cn
|
||||
www.chapadaomaquinas.com
|
||||
www.chapesx.site
|
||||
www.charmingsoftech.com
|
||||
www.chartbeat.com
|
||||
www.chartboost.com
|
||||
www.chartercare.plus.com
|
||||
@ -104920,6 +104955,7 @@ www.favouritesuitable.com
|
||||
www.faxlcahosa.com
|
||||
www.fbookindia.com
|
||||
www.fccxgjg.com
|
||||
www.fcstradesolutions.com
|
||||
www.fearwild.com
|
||||
www.featbooksterile.com
|
||||
www.featurespossessed.com
|
||||
@ -104943,6 +104979,7 @@ www.filezilla.fr
|
||||
www.fillerstore.ru
|
||||
www.filter.adright.co
|
||||
www.fimi.net
|
||||
www.financialchile.com
|
||||
www.findingupsetabstinence.com
|
||||
www.finedqueerrigid.com
|
||||
www.finlite.com.ua
|
||||
@ -105164,6 +105201,7 @@ www.gpbaru.net
|
||||
www.gpsindia.biz
|
||||
www.grabify.link
|
||||
www.graduate.cmru.ac.th
|
||||
www.graficadupress.com.br
|
||||
www.granddadknitbravely.com
|
||||
www.granddaughterfashioned.com
|
||||
www.grandfurniture.com
|
||||
@ -105633,6 +105671,7 @@ www.kpremium.com
|
||||
www.kqzyfj.com
|
||||
www.krouniforms.com
|
||||
www.ksnews.info
|
||||
www.kspintidana.com
|
||||
www.kudifish.com
|
||||
www.kuguopush.com
|
||||
www.kuhdi.com
|
||||
@ -105920,6 +105959,7 @@ www.mobclix.com
|
||||
www.mobfox.com
|
||||
www.mobid.cn
|
||||
www.mobileads.ero-advertising.com
|
||||
www.mobiles-photostudio.com
|
||||
www.mobilhondabandung.net
|
||||
www.mobjump.com
|
||||
www.mochibot.com
|
||||
@ -106217,6 +106257,7 @@ www.performancetrustednetwork.com
|
||||
www.perfunctoryfrugal.com
|
||||
www.periljuicywary.com
|
||||
www.perimeterx.net
|
||||
www.periodistesgolf.cat
|
||||
www.perpetratoronpour.com
|
||||
www.perpetualprovoke.com
|
||||
www.persgroepadvertising.nl
|
||||
@ -106885,6 +106926,7 @@ www.suffocatepremise.com
|
||||
www.suitedeadlockhandsome.com
|
||||
www.summerhamster.com
|
||||
www.sun-inet.or.jp
|
||||
www.sunnyseries.com
|
||||
www.suozmtcc.com
|
||||
www.supera.com.br
|
||||
www.superbrewards.com
|
||||
@ -107572,6 +107614,7 @@ www.yzaosite.com
|
||||
www.yzlwuuzzehjh.com
|
||||
www.z8o.cn
|
||||
www.zabavazaodrasle.com
|
||||
www.zablimconsultancy.co.ke
|
||||
www.zamora.axiatraders.com
|
||||
www.zamplus.com
|
||||
www.zardamarine.com
|
||||
|
@ -12,7 +12,7 @@ local ss_encrypt_method_list = {
|
||||
local ss_rust_encrypt_method_list = {
|
||||
"plain", "none",
|
||||
"aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
||||
"2022-blake3-aes-128-gcm","2022-blake3-aes-256-gcm","2022-blake3-chacha8-poly1305","2022-blake3-chacha20-poly1305"
|
||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha8-poly1305", "2022-blake3-chacha20-poly1305"
|
||||
}
|
||||
|
||||
local ssr_encrypt_method_list = {
|
||||
|
@ -995,10 +995,10 @@ msgid "IV Check"
|
||||
msgstr "IV 检查"
|
||||
|
||||
msgid "UDP over TCP"
|
||||
msgstr "TCP封装UDP"
|
||||
msgstr "TCP 封装 UDP"
|
||||
|
||||
msgid "Need Xray server side with Shadowsocks-2022 protocol"
|
||||
msgstr "需要Xray作服务器端的Shadowsocks-2022协议"
|
||||
msgstr "需要 Xray 作服务器端的 Shadowsocks-2022 协议"
|
||||
|
||||
msgid "Connection Timeout"
|
||||
msgstr "连接超时时间"
|
||||
@ -1280,7 +1280,7 @@ msgid "Early data length"
|
||||
msgstr "前置数据最大长度"
|
||||
|
||||
msgid "Early data header name"
|
||||
msgstr "前置数据HTTP头名"
|
||||
msgstr "前置数据 HTTP 头名"
|
||||
|
||||
msgid "Recommended value: Sec-WebSocket-Protocol"
|
||||
msgstr "推荐值:Sec-WebSocket-Protocol"
|
||||
|
@ -5,7 +5,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=mosdns
|
||||
PKG_VERSION:=259bb47
|
||||
PKG_VERSION:=533ada5
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE:=mosdns-$(PKG_VERSION).tar.gz
|
||||
|
@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=naiveproxy
|
||||
PKG_VERSION:=103.0.5060.53-1
|
||||
PKG_VERSION:=103.0.5060.53-2
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/klzgrad/naiveproxy/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=ffafe4cd5bc5a79b659520f071514db3d78531b5004c441d4b3da16c9c371ff1
|
||||
PKG_HASH:=68830ad9d363e24bf1006fe6781c22c00fe6fdafe6c6faf98fb6cbdb80810499
|
||||
|
||||
PKG_LICENSE:=BSD 3-Clause
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
Loading…
Reference in New Issue
Block a user