update 2024-10-14 08:36:44

This commit is contained in:
actions-user 2024-10-14 08:36:44 +08:00
parent 0022e675ef
commit 39cd4edaf8
19 changed files with 113 additions and 917 deletions

View File

@ -1,6 +1,8 @@
# 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
@ -9,6 +11,11 @@ LUCI_TITLE:=LuCI Support for FileBrowser
LUCI_DEPENDS:=+filebrowser
LUCI_PKGARCH:=all
PKG_NAME:=luci-app-filebrowser
PKG_VERSION:=snapshot
PKG_RELEASE:=118071b
PKG_LICENSE:=GPLv3
include $(TOPDIR)/feeds/luci/luci.mk

View File

@ -1,59 +1,19 @@
-- Copyright 2018-2020 Lienol <lawlienol@gmail.com>
-- Improve by xiaozhuai <xiaozhuai7@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
entry({"admin", "services"}, firstchild(), "Services", 44).dependent = false
entry({"admin", "services", "filebrowser"}, cbi("filebrowser/settings"),
_("File Browser"), 2).dependent = true
entry({"admin", "services", "filebrowser", "check"}, call("action_check")).leaf =
true
entry({"admin", "services", "filebrowser", "download"}, call("action_download")).leaf =
true
entry({"admin", "services", "filebrowser", "status"}, call("act_status")).leaf =
true
entry({"admin", "services", "filebrowser", "get_log"}, call("get_log")).leaf =
true
entry({"admin", "services", "filebrowser", "clear_log"}, call("clear_log")).leaf =
true
end
local function http_write_json(content)
http.prepare_content("application/json")
http.write_json(content or {code = 1})
end
function act_status()
local e = {}
e.status = luci.sys.call("ps -w | grep -v grep | grep 'filebrowser -a' >/dev/null") == 0
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
module("luci.controller.filebrowser", package.seeall)
function index()
if not nixio.fs.access("/etc/config/filebrowser") then
return
end
entry({"admin", "nas"}, firstchild(), _("NAS") , 45).dependent = false
local page
page = entry({"admin", "nas", "filebrowser"}, cbi("filebrowser"), _("文件管理器"), 100)
page.dependent = true
entry({"admin","nas","filebrowser","status"},call("act_status")).leaf=true
end
function act_status()
local e={}
e.running=luci.sys.call("pgrep filebrowser >/dev/null")==0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end

View File

@ -0,0 +1,42 @@
m = Map("filebrowser", translate("文件管理器"), translate("FileBrowser是一个基于Go的在线文件管理器助您方便的管理设备上的文件。"))
m:section(SimpleSection).template = "filebrowser/filebrowser_status"
s = m:section(TypedSection, "filebrowser")
s.addremove = false
s.anonymous = true
enable = s:option(Flag, "enabled", translate("启用"))
enable.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.placeholder = "/etc"
o.default = "/etc"
o.rmempty = false
o.description = translate("普通用户请勿随意更改")
o = s:option(Value, "db_name", translate("数据库名"))
o.placeholder = "filebrowser.db"
o.default = "filebrowser.db"
o.rmempty = false
o.description = translate("普通用户请勿随意更改")
return m

View File

@ -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 executable_directory =
uci_get_type("global", "executable_directory", "/tmp")
luci.sys.exec("mkdir -p " .. executable_directory)
local client_path = executable_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

View File

@ -1,59 +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, "address", translate("Listen address"))
o.default = "0.0.0.0"
o.rmempty = false
o = s:option(Value, "port", translate("Listen port"))
o.datatype = "port"
o.default = 8088
o.rmempty = false
o = s:option(Value, "database", translate("Database path"))
o.default = "/etc/filebrowser.db"
o.rmempty = false
o = s:option(Value, "username", translate("Initial username"))
o.default = "admin"
o.rmempty = false
o = s:option(Value, "password", translate("Initial password"))
o.default = "admin"
o.rmempty = false
o = s:option(Value, "ssl_cert", translate("SSL cert"))
o.default = ""
o = s:option(Value, "ssl_key", translate("SSL key"))
o.default = ""
o = s:option(Value, "root_path", translate("Root path"), translate(
"Point to a path to access your files in the web interface, default is /root"))
o.default = "/root"
o.rmempty = false
o = s:option(Value, "executable_directory", translate("Executable 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 executable 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

View File

@ -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/services/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/services/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%>

View File

@ -0,0 +1,32 @@
<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="openClient();" />';
tb.innerHTML = links;
} else {
tb.innerHTML = '<font color=red>Filebrowser <%:未运行%></font>';
}
}
}
);
function openClient() {
var curWwwPath = window.document.location.href;
var pathName = window.document.location.pathname;
var pos = curWwwPath.indexOf(pathName);
var localhostPath = curWwwPath.substring(0, pos);
var clientPort = window.document.getElementById("cbid.filebrowser.config.port").value
var url = localhostPath + ":" + clientPort;
window.open(url)
};
//]]>
</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>

View File

@ -1,31 +0,0 @@
<script type="text/javascript">
//<![CDATA[
function clear_log(btn) {
XHR.get('<%=url([[admin]], [[services]], [[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]], [[services]], [[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%>" style="margin-left: 10px;">
<textarea id="log_textarea" class="cbi-input-textarea" style="width: calc(100% - 20px); margin: 10px;" data-update="change" rows="5" wrap="off" readonly="readonly"></textarea>
</fieldset>

View File

@ -1,38 +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"><p><span><%:Collecting data...%></span></p></div>
</div>
</fieldset>
</fieldset>
<script type="text/javascript">//<![CDATA[
var _status = document.getElementById('_status');
XHR.poll(3,'<%=dsp.build_url("admin/services/filebrowser/status")%>', null,
function(x, json) {
if (x && x.status == 200) {
if (_status)
_status.innerHTML = json.status ? '<p><span style="color:green;"><%:RUNNING%></span> <input type="button" class="cbi-button cbi-input-apply" value="<%:Enter interface%>" onclick="openwebui()" /></p>' : '<p><span style="color:red;"><%:NOT RUNNING%></span></p>';
}
});
function openwebui(){
var url = window.location.host;
if (url.indexOf(':')) {
url = url.split(':')[0];
}
ssl_cert = "<%=luci.sys.exec("uci get filebrowser.@global[0].ssl_cert"):gsub("^%s*(.-)%s*$", "%1")%>";
ssl_key = "<%=luci.sys.exec("uci get filebrowser.@global[0].ssl_key"):gsub("^%s*(.-)%s*$", "%1")%>";
port = "<%=luci.sys.exec("uci get filebrowser.@global[0].port"):gsub("^%s*(.-)%s*$", "%1")%>";
protocol = 'http';
if (ssl_cert !== '' && ssl_key !== '') protocol = 'https';
window.open(protocol+'://'+url+':'+port,'target','');
}
//]]></script>

View File

@ -1,125 +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 address"
msgstr "监听地址"
msgid "Listen port"
msgstr "监听端口"
msgid "Initial username"
msgstr "初始账户"
msgid "Initial password"
msgstr "初始密码"
msgid "SSL cert"
msgstr "SSL 证书"
msgid "SSL key"
msgstr "SSL 私钥"
msgid "Database path"
msgstr "数据库路径"
msgid "Root path"
msgstr "指向路径"
msgid "Point to a path to access your files in the web interface, default is /root"
msgstr "指向一个路径可在web界面访问你的文件默认为 /root"
msgid "Executable 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 executable 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"

View File

@ -1,13 +0,0 @@
config global
option address '0.0.0.0'
option port '8088'
option database '/etc/filebrowser.db'
option username 'admin'
option password 'admin'
option ssl_cert ''
option ssl_key ''
option root_path '/root'
option executable_directory '/tmp'
option enable '0'

View File

@ -1,48 +0,0 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2018-2020 Lienol <lawlienol@gmail.com>
# Improve by xiaozhuai <xiaozhuai7@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
ADDRESS=$(config_t_get global address 0.0.0.0)
PORT=$(config_t_get global port 8088)
DATABASE=$(config_t_get global database /etc/filebrowser.db)
USERNAME=$(config_t_get global username admin)
PASSWORD=$(config_t_get global password admin)
SSL_CERT=$(config_t_get global ssl_cert)
SSL_KEY=$(config_t_get global ssl_key)
ROOT_PATH=$(config_t_get global root_path /root)
executable_directory=$(config_t_get global executable_directory /tmp)
[ ! -f "$executable_directory/filebrowser" ] && echolog "$executable_directory/filebrowser not exists, please download first" && exit
SSL_PARAMS=""
[ -n "$SSL_CERT" ] && [ -n "$SSL_KEY" ] && SSL_PARAMS="-t $SSL_CERT -k $SSL_KEY"
PASSWORD="$($executable_directory/filebrowser hash "$PASSWORD")"
$executable_directory/filebrowser -a $ADDRESS -p $PORT -r $ROOT_PATH -d "$DATABASE" --username $USERNAME --password $PASSWORD $SSL_PARAMS -l $LOG_PATH >/dev/null 2>&1 &
}
stop() {
ps -w | grep -v "grep" | grep "$executable_directory/filebrowser -a" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
rm -rf $LOG_PATH
}
restart() {
stop
sleep 1
start
}

View File

@ -1,11 +1,11 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@filebrowser[-1]
add ucitrack filebrowser
set ucitrack.@filebrowser[-1].init=filebrowser
commit ucitrack
EOF
rm -f /tmp/luci-indexcache
exit 0
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@filebrowser[-1]
add ucitrack filebrowser
set ucitrack.@filebrowser[-1].init=filebrowser
commit ucitrack
EOF
rm -f /tmp/luci-indexcache
exit 0

View File

@ -1,11 +0,0 @@
{
"luci-app-filebrowser": {
"description": "Grant UCI access for luci-app-filebrowser",
"read": {
"uci": [ "filebrowser" ]
},
"write": {
"uci": [ "filebrowser" ]
}
}
}

View File

@ -12,7 +12,6 @@ function index()
local page
page = entry({"admin", "services", "gost"}, cbi("gost"), _("Gost"), 100)
page.dependent = true
page.acl_depends = { "luci-app-gost" }
entry({"admin", "services", "gost", "status"},call("act_status")).leaf=true
end

View File

@ -1 +0,0 @@
zh_Hans

View File

@ -1,11 +0,0 @@
{
"luci-app-gost": {
"description": "Grant UCI access for luci-app-gost",
"read": {
"uci": [ "gost" ]
},
"write": {
"uci": [ "gost" ]
}
}
}