luci-app-kodexplorer : chinesization ()

This commit is contained in:
Lienol 2019-12-19 12:08:23 +08:00 committed by coolsnowwolf
parent 2252757369
commit 090f6ceee7
8 changed files with 334 additions and 216 deletions
package/lean/luci-app-kodexplorer
Makefile
luasrc
controller
model/cbi/kodexplorer
view/kodexplorer
po/zh-cn
root/etc/init.d

@ -1,4 +1,4 @@
# Copyright (C) 2018-2019 Lienol # Copyright (C) 2018-2020 Lienol <lawlienol@gmail.com>
# #
# This is free software, licensed under the Apache License, Version 2.0 . # This is free software, licensed under the Apache License, Version 2.0 .
# #
@ -9,7 +9,7 @@ LUCI_TITLE:=LuCI support for KodExplorer
LUCI_DEPENDS:=+nginx +zoneinfo-asia +php7 +php7-fpm +php7-mod-curl +php7-mod-gd +php7-mod-iconv +php7-mod-json +php7-mod-mbstring +php7-mod-opcache +php7-mod-session +php7-mod-zip LUCI_DEPENDS:=+nginx +zoneinfo-asia +php7 +php7-fpm +php7-mod-curl +php7-mod-gd +php7-mod-iconv +php7-mod-json +php7-mod-mbstring +php7-mod-opcache +php7-mod-session +php7-mod-zip
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
PKG_VERSION:=1.0 PKG_VERSION:=1.0
PKG_RELEASE:=5-20190518 PKG_RELEASE:=9-20191217
include $(TOPDIR)/feeds/luci/luci.mk include $(TOPDIR)/feeds/luci/luci.mk

@ -1,29 +1,37 @@
-- Copyright 2018-2020 Lienol <lawlienol@gmail.com>
module("luci.controller.kodexplorer", package.seeall) module("luci.controller.kodexplorer", package.seeall)
local http = require "luci.http" local http = require "luci.http"
local api = require "luci.model.cbi.kodexplorer.api" local api = require "luci.model.cbi.kodexplorer.api"
function index() function index()
if not nixio.fs.access("/etc/config/kodexplorer") then if not nixio.fs.access("/etc/config/kodexplorer") then return end
return
end
entry({"admin","nas","kodexplorer"},cbi("kodexplorer/settings"),_("KodExplorer"),3).dependent=true entry({"admin", "nas"}, firstchild(), "NAS", 44).dependent = false
entry({"admin", "nas", "kodexplorer"}, cbi("kodexplorer/settings"),
_("KodExplorer"), 3).dependent = true
entry({"admin","nas","kodexplorer","check"},call("action_check")).leaf=true entry({"admin", "nas", "kodexplorer", "check"}, call("action_check")).leaf =
entry({"admin","nas","kodexplorer","download"},call("action_download")).leaf=true true
entry({"admin","nas","kodexplorer","status"},call("act_status")).leaf=true entry({"admin", "nas", "kodexplorer", "download"}, call("action_download")).leaf =
true
entry({"admin", "nas", "kodexplorer", "status"}, call("act_status")).leaf =
true
end end
local function http_write_json(content) local function http_write_json(content)
http.prepare_content("application/json") http.prepare_content("application/json")
http.write_json(content or { code = 1 }) http.write_json(content or {code = 1})
end end
function act_status() function act_status()
local e={} local e = {}
e.nginx_status=luci.sys.call("ps -w | grep nginx | grep kodexplorer | grep -v grep > /dev/null") == 0 e.nginx_status = luci.sys.call(
e.php_status=luci.sys.call("ps -w | grep php | grep kodexplorer | grep -v grep > /dev/null") == 0 "ps -w | grep nginx | grep kodexplorer | grep -v grep > /dev/null") ==
0
e.php_status = luci.sys.call(
"ps -w | grep php | grep kodexplorer | grep -v grep > /dev/null") ==
0
http_write_json(e) http_write_json(e)
end end

@ -1,24 +1,25 @@
local fs = require "nixio.fs" local fs = require "nixio.fs"
local sys = require "luci.sys" local sys = require "luci.sys"
local uci = require "luci.model.uci".cursor() local uci = require"luci.model.uci".cursor()
local util = require "luci.util" local util = require "luci.util"
local i18n = require "luci.i18n" local i18n = require "luci.i18n"
module("luci.model.cbi.kodexplorer.api", package.seeall) module("luci.model.cbi.kodexplorer.api", package.seeall)
local api_url = "https://api.github.com/repos/kalcaddle/KodExplorer/releases/latest" local api_url =
"https://api.github.com/repos/kalcaddle/KodExplorer/releases/latest"
local download_url = "https://github.com/kalcaddle/KodExplorer/archive/" local download_url = "https://github.com/kalcaddle/KodExplorer/archive/"
local wget = "/usr/bin/wget" local wget = "/usr/bin/wget"
local wget_args = { "--no-check-certificate", "--quiet", "--timeout=10", "--tries=2" } local wget_args = {
"--no-check-certificate", "--quiet", "--timeout=10", "--tries=2"
}
local curl = "/usr/bin/curl" local curl = "/usr/bin/curl"
local command_timeout = 40 local command_timeout = 40
local function _unpack(t, i) local function _unpack(t, i)
i = i or 1 i = i or 1
if t[i] ~= nil then if t[i] ~= nil then return t[i], _unpack(t, i + 1) end
return t[i], _unpack(t, i + 1)
end
end end
local function exec(cmd, args, writer, timeout) local function exec(cmd, args, writer, timeout)
@ -48,13 +49,9 @@ local function exec(cmd, args, writer, timeout)
local wpid, stat, code = nixio.waitpid(pid, "nohang") local wpid, stat, code = nixio.waitpid(pid, "nohang")
if wpid and stat == "exited" then if wpid and stat == "exited" then return code end
return code
end
if not writer and timeout then if not writer and timeout then nixio.nanosleep(1) end
nixio.nanosleep(1)
end
end end
else else
local wpid, stat, code = nixio.waitpid(pid) local wpid, stat, code = nixio.waitpid(pid)
@ -78,9 +75,7 @@ local function compare_versions(ver1, comp, ver2)
local max = table.getn(av1) local max = table.getn(av1)
local n2 = table.getn(av2) local n2 = table.getn(av2)
if (max < n2) then if (max < n2) then max = n2 end
max = n2
end
for i = 1, max, 1 do for i = 1, max, 1 do
local s1 = av1[i] or "" local s1 = av1[i] or ""
@ -98,22 +93,22 @@ end
local function get_api_json(url) local function get_api_json(url)
local jsonc = require "luci.jsonc" local jsonc = require "luci.jsonc"
local output = { } local output = {}
--exec(wget, { "-O-", url, _unpack(wget_args) }, -- exec(wget, { "-O-", url, _unpack(wget_args) },
-- function(chunk) output[#output + 1] = chunk end) -- function(chunk) output[#output + 1] = chunk end)
--local json_content = util.trim(table.concat(output)) -- local json_content = util.trim(table.concat(output))
local json_content = luci.sys.exec(curl.." -sL "..url) local json_content = luci.sys.exec(curl .. " -sL " .. url)
if json_content == "" then if json_content == "" then return {} end
return { }
end
return jsonc.parse(json_content) or { } return jsonc.parse(json_content) or {}
end end
function get_project_directory() function get_project_directory()
return uci:get("kodexplorer", "global", "project_directory") or luci.sys.exec("echo -n `uci get kodexplorer.@global[0].project_directory`") return uci:get("kodexplorer", "global", "project_directory") or
luci.sys.exec(
"echo -n `uci get kodexplorer.@global[0].project_directory`")
end end
function to_check() function to_check()
@ -126,92 +121,77 @@ function to_check()
end end
local remote_version = json.tag_name local remote_version = json.tag_name
local html_url = json.html_url local html_url = json.html_url
download_url = download_url..json.tag_name..".tar.gz" download_url = download_url .. json.tag_name .. ".tar.gz"
if not download_url then if not download_url then
return { return {
code = 1, code = 1,
version = remote_version, version = remote_version,
html_url = html_url, html_url = html_url,
error = i18n.translate("New version found, but failed to get new version download url.") error = i18n.translate(
"New version found, but failed to get new version download url.")
} }
end end
return { return {
code = 0, code = 0,
version = remote_version, version = remote_version,
url = { url = {html = html_url, download = download_url}
html = html_url,
download = download_url
}
} }
end end
function to_download(url) function to_download(url)
if not url or url == "" then if not url or url == "" then
return { return {code = 1, error = i18n.translate("Download url is required.")}
code = 1,
error = i18n.translate("Download url is required.")
}
end end
sys.call("/bin/rm -f /tmp/kodexplorer_download.*") sys.call("/bin/rm -f /tmp/kodexplorer_download.*")
local tmp_file = util.trim(util.exec("mktemp -u -t kodexplorer_download.XXXXXX")) local tmp_file = util.trim(util.exec(
"mktemp -u -t kodexplorer_download.XXXXXX"))
local result = exec(wget, { local result = exec(wget, {"-O", tmp_file, url, _unpack(wget_args)}, nil,
"-O", tmp_file, url, _unpack(wget_args) }, nil, command_timeout) == 0 command_timeout) == 0
if not result then if not result then
exec("/bin/rm", { "-f", tmp_file }) exec("/bin/rm", {"-f", tmp_file})
return { return {
code = 1, code = 1,
error = i18n.translatef("File download failed or timed out: %s", url) error = i18n.translatef("File download failed or timed out: %s", url)
} }
end end
return { return {code = 0, file = tmp_file}
code = 0,
file = tmp_file
}
end end
function to_extract(file) function to_extract(file)
if not file or file == "" or not fs.access(file) then if not file or file == "" or not fs.access(file) then
return { return {code = 1, error = i18n.translate("File path required.")}
code = 1,
error = i18n.translate("File path required.")
}
end end
sys.call("/bin/rm -rf /tmp/kodexplorer_extract.*") sys.call("/bin/rm -rf /tmp/kodexplorer_extract.*")
local tmp_dir = util.trim(util.exec("mktemp -d -t kodexplorer_extract.XXXXXX")) local tmp_dir = util.trim(util.exec(
"mktemp -d -t kodexplorer_extract.XXXXXX"))
local output = { } local output = {}
exec("/bin/tar", { "-C", tmp_dir, "-zxvf", file }, exec("/bin/tar", {"-C", tmp_dir, "-zxvf", file},
function(chunk) output[#output + 1] = chunk end) function(chunk) output[#output + 1] = chunk end)
local files = util.split(table.concat(output)) local files = util.split(table.concat(output))
exec("/bin/rm", { "-f", file }) exec("/bin/rm", {"-f", file})
return { return {code = 0, file = tmp_dir}
code = 0,
file = tmp_dir
}
end end
function to_move(file) function to_move(file)
if not file or file == "" or not fs.access(file) then if not file or file == "" or not fs.access(file) then
sys.call("/bin/rm -rf /tmp/kodexplorer_extract.*") sys.call("/bin/rm -rf /tmp/kodexplorer_extract.*")
return { return {code = 1, error = i18n.translate("Client file is required.")}
code = 1,
error = i18n.translate("Client file is required.")
}
end end
local client_file = get_project_directory() local client_file = get_project_directory()
sys.call("mkdir -p "..client_file) sys.call("mkdir -p " .. client_file)
sys.call("cp -R "..file.."/KodExplorer*/* "..client_file) sys.call("cp -R " .. file .. "/KodExplorer*/* " .. client_file)
sys.call("/bin/rm -rf /tmp/kodexplorer_extract.*") sys.call("/bin/rm -rf /tmp/kodexplorer_extract.*")
return { code = 0 } return {code = 0}
end end

@ -1,44 +1,56 @@
m = Map("kodexplorer", translate("KodExplorer"), translate(
m = Map("kodexplorer",translate("KodExplorer"),translate("KodExplorer是一款快捷高效的私有云和在线文档管理系统为个人网站、企业私有云部署、网络存储、在线文档管理、在线办公等提供安全可控简便易用、可高度定制的私有云产品。采用windows风格界面、操作习惯无需适应即可快速上手支持几百种常用文件格式的在线预览可扩展易定制。")) "KodExplorer is a fast and efficient private cloud and online document management system that provides secure, controllable, easy-to-use and highly customizable private cloud products for personal websites, enterprise private cloud deployment, network storage, online document management, and online office. With Windows style interface and operation habits, it can be used quickly without adaptation. It supports online preview of hundreds of common file formats and is extensible and easy to customize."))
m:append(Template("kodexplorer/status")) m:append(Template("kodexplorer/status"))
s = m:section(TypedSection,"global",translate("Global Setting")) s = m:section(TypedSection, "global", translate("Global Setting"))
s.anonymous = true s.anonymous = true
s.addremove = false s.addremove = false
o = s:option(Flag,"enable",translate("Enable")) o = s:option(Flag, "enable", translate("Enable"))
o.rmempty = false o.rmempty = false
o = s:option(Value, "port", translate("Nginx监听端口")) o = s:option(Value, "port", translate("Nginx Port"))
o.datatype="port" o.datatype = "port"
o.default=81 o.default = 8081
o.rmempty = false o.rmempty = false
o = s:option(Value, "memory_limit", translate("内存最大使用"), translate("如果你的设备内存较大的话,可以适当增加。")) o = s:option(Value, "memory_limit", translate("Maximum memory usage"),
o.default="8M" translate(
"If your device has a lot of memory, you can increase it."))
o.default = "8M"
o.rmempty = false o.rmempty = false
o = s:option(Value, "post_max_size", translate("POST最大容量"), translate("该值不能大于 内存最大使用")) o = s:option(Value, "post_max_size", translate("Maximum POST capacity"),
o.default="12M" translate(
"This value cannot be greater than the maximum memory usage"))
o.default = "12M"
o.rmempty = false o.rmempty = false
o = s:option(Value, "upload_max_filesize", translate("上传文件最大使用内存"), translate("该值不能大于 POST最大容量")) o = s:option(Value, "upload_max_filesize",
o.default="12M" translate("Maximum memory usage for uploading files"), translate(
"This value cannot be greater than the POST maximum capacity"))
o.default = "12M"
o.rmempty = false o.rmempty = false
o = s:option(Value, "storage_device_path", translate("存储设备路径"), translate("建议插入U盘或硬盘然后输入路径。例如/mnt/sda1/")) o = s:option(Value, "storage_device_path", translate("Storage device path"),
o.default="/mnt/sda1/" translate(
"It is recommended to insert a usb flash drive or hard disk and enter the path. For example, /mnt/sda1/"))
o.default = "/mnt/sda1/"
o.rmempty = false o.rmempty = false
o = s:option(Value, "project_directory", translate("项目存放目录"), translate("建议插入U盘或硬盘然后输入路径。例如/mnt/sda1/kodexplorer")) o = s:option(Value, "project_directory", translate("Project directory"),
o.default="/mnt/sda1/kodexplorer" translate(
"It is recommended to insert a usb flash drive or hard disk and enter the path. For example, /mnt/sda1/kodexplorer"))
o.default = "/mnt/sda1/kodexplorer"
o.rmempty = false o.rmempty = false
o = s:option(Button, "_download", translate("手动下载"), s:append(Template("kodexplorer/version"))
translate("请确保具有足够的空间。<br /><font style='color:red'>第一次运行务必填好设备路径和存放路径,然后保存应用。再手动下载,否则无法使用!</font>"))
o = s:option(Button, "_download", translate("Manually update"), translate(
"Make sure you have enough space.<br /><font style='color:red'>Be sure to fill out the device path and store path for the first run, and then save the application. Then manually download, otherwise can not use!</font>"))
o.template = "kodexplorer/download" o.template = "kodexplorer/download"
o.inputstyle = "apply" o.inputstyle = "apply"
o.btnclick = "downloadClick(this);" o.btnclick = "downloadClick(this);"
o.id="download_btn" o.id = "download_btn"
return m return m

@ -1,8 +1,3 @@
<%#
Copyright (C) 2018-2019 Lienol
Licensed to the public under the Apache License 2.0.
-%>
<% <%
local dsp = require "luci.dispatcher" local dsp = require "luci.dispatcher"
-%> -%>
@ -11,11 +6,15 @@ local dsp = require "luci.dispatcher"
var msgInfo; var msgInfo;
var tokenStr = '<%=token%>'; var tokenStr = '<%=token%>';
var clickToDownloadText = '<%:点击下载%>'; var clickToDownloadText = '<%:Click to update%>';
var inProgressText = '<%:正在下载...%>'; var inProgressText = '<%:Updating...%>';
var downloadInProgressNotice = '<%:正在下载,你确认要关闭吗?%>'; var downloadInProgressNotice = '<%:Updating, are you sure to close?%>';
var downloadSuccessText = '<%:下载成功.%>'; var downloadSuccessText = '<%:Update successful%>';
var unexpectedErrorText = '<%:意外错误.%>'; var unexpectedErrorText = '<%:Unexpected error%>';
var downloadingText = '<%:Downloading...%>';
var decompressioningText = '<%:Unpacking...%>';
var movingText = '<%:Moving...%>';
var latestVersionText = '<%:The latest version:%>';
function addPageNotice() { function addPageNotice() {
window.onbeforeunload = function(e) { window.onbeforeunload = function(e) {
@ -97,7 +96,7 @@ local dsp = require "luci.dispatcher"
if (ckeckDetailElm) { if (ckeckDetailElm) {
var urlNode = ''; var urlNode = '';
if (json.version) { if (json.version) {
urlNode = '<em style="color:red;">最新版本号:' + json.version + '</em>'; urlNode = '<em style="color:red;">' + latestVersionText + json.version + '</em>';
if (json.url && json.url.html) { if (json.url && json.url.html) {
urlNode = '<a href="' + json.url.html + '" target="_blank">' + urlNode + '</a>'; urlNode = '<a href="' + json.url.html + '" target="_blank">' + urlNode + '</a>';
} }
@ -110,7 +109,7 @@ local dsp = require "luci.dispatcher"
function doDownload(btn) { function doDownload(btn) {
btn.disabled = true; btn.disabled = true;
btn.value = '<%:下载中...%>'; btn.value = downloadingText;
addPageNotice(); addPageNotice();
@ -124,7 +123,7 @@ local dsp = require "luci.dispatcher"
removePageNotice(); removePageNotice();
onRequestError(btn, json.error); onRequestError(btn, json.error);
} else { } else {
btn.value = '<%:解压中...%>'; btn.value = decompressioningText;
// Extract file // Extract file
doAjaxGet(UpdateUrl, { doAjaxGet(UpdateUrl, {
@ -136,7 +135,7 @@ local dsp = require "luci.dispatcher"
removePageNotice(); removePageNotice();
onRequestError(btn, json.error); onRequestError(btn, json.error);
} else { } else {
btn.value = '<%:移动中...%>'; btn.value = movingText;
// Move file to target dir // Move file to target dir
doAjaxGet(UpdateUrl, { doAjaxGet(UpdateUrl, {

@ -0,0 +1,17 @@
<%
local kodexplorer_path = luci.sys.exec("echo -n `uci get kodexplorer.@global[0].project_directory`")
local kodexplorer_version = luci.sys.exec("[ -f '" .. kodexplorer_path .. "/ChangeLog.md' ] && echo -n `cat " .. kodexplorer_path .. "/ChangeLog.md | head -1 | awk '{print $2}'`")
-%>
<% if kodexplorer_version ~= nil and kodexplorer_version~="" then %>
<div class="cbi-value">
<label class="cbi-value-title">
<%:Version%>
</label>
<div class="cbi-value-field">
<div class="cbi-value-description">
<span><%=kodexplorer_version%> 】</span>
</div>
</div>
</div>
<% end %>

@ -1,2 +1,104 @@
msgid "KodExplorer" msgid "KodExplorer"
msgstr "可道云" msgstr "可道云"
msgid "KodExplorer is a fast and efficient private cloud and online document management system that provides secure, controllable, easy-to-use and highly customizable private cloud products for personal websites, enterprise private cloud deployment, network storage, online document management, and online office. With Windows style interface and operation habits, it can be used quickly without adaptation. It supports online preview of hundreds of common file formats and is extensible and easy to customize."
msgstr "KodExplorer是一款快捷高效的私有云和在线文档管理系统为个人网站、企业私有云部署、网络存储、在线文档管理、在线办公等提供安全可控简便易用、可高度定制的私有云产品。采用windows风格界面、操作习惯无需适应即可快速上手支持几百种常用文件格式的在线预览可扩展易定制。"
msgid "Nginx Port"
msgstr "Nginx监听端口"
msgid "Maximum memory usage"
msgstr "内存最大使用"
msgid "If your device has a lot of memory, you can increase it."
msgstr "如果你的设备内存较大的话,可以适当增加。"
msgid "Maximum POST capacity"
msgstr "POST最大容量"
msgid "This value cannot be greater than the maximum memory usage"
msgstr "该值不能大于 内存最大使用"
msgid "Maximum memory usage for uploading files"
msgstr "上传文件最大使用内存"
msgid "This value cannot be greater than the POST maximum capacity"
msgstr "该值不能大于 POST最大容量"
msgid "Storage device path"
msgstr "存储设备路径"
msgid "It is recommended to insert a usb flash drive or hard disk and enter the path. For example, /mnt/sda1/"
msgstr "建议插入U盘或硬盘然后输入路径。例如/mnt/sda1/"
msgid "Project directory"
msgstr "项目存放目录"
msgid "It is recommended to insert a usb flash drive or hard disk and enter the path. For example, /mnt/sda1/kodexplorer"
msgstr "建议插入U盘或硬盘然后输入路径。例如/mnt/sda1/kodexplorer"
msgid "Make sure you have enough space.<br /><font style='color:red'>Be sure to fill out the device path and store path for the first run, and then save the application. Then manually download, otherwise can not use!</font>"
msgstr "请确保具有足够的空间。<br /><font style='color:red'>第一次运行务必填好设备路径和存放路径,然后保存应用。再手动下载,否则无法使用!</font>"
msgid "Manually update"
msgstr "手动更新"
msgid "It is the latest version"
msgstr "已是最新版本"
msgid "Update successful"
msgstr "更新成功"
msgid "Click to update"
msgstr "点击更新"
msgid "Updating..."
msgstr "更新中"
msgid "Unexpected error"
msgstr "意外错误"
msgid "Updating, 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,5 +1,5 @@
#!/bin/sh /etc/rc.common #!/bin/sh /etc/rc.common
# Copyright (C) 2018-2019 Lienol # Copyright (C) 2018-2020 Lienol <lawlienol@gmail.com>
START=99 START=99