luci-app-kodexplorer: sync to my upstream (#8657)

This commit is contained in:
Li2nOnline 2022-01-10 16:56:30 +08:00 committed by GitHub
parent 60e2759031
commit 58467b6c6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 512 additions and 442 deletions

View File

@ -1,4 +1,4 @@
# Copyright (C) 2018-2020 Lienol <lawlienol@gmail.com>
# Copyright (C) 2018-2022 Lienol <lawlienol@gmail.com>
#
# This is free software, licensed under the GNU General Public License v3.
#
@ -6,10 +6,10 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for KodExplorer
LUCI_DEPENDS:=+nginx-ssl +unzip +zoneinfo-asia +php8 +php8-fpm +php8-mod-curl +php8-mod-gd +php8-mod-iconv +php8-mod-mbstring +php8-mod-opcache +php8-mod-session +php8-mod-zip +php8-mod-sqlite3 +php8-mod-pdo +php8-mod-pdo-sqlite +php8-mod-pdo-mysql +php8-cgi +php8-mod-dom
LUCI_DEPENDS:=+nginx-ssl +unzip +zoneinfo-asia +php8 +php8-fastcgi +php8-fpm +php8-mod-curl +php8-mod-dom +php8-mod-gd +php8-mod-iconv +php8-mod-mbstring +php8-mod-opcache +php8-mod-session +php8-mod-zip +php8-mod-sqlite3 +php8-mod-pdo +php8-mod-pdo-sqlite +php8-mod-pdo-mysql +php8-mod-xml +php8-mod-xmlreader +php8-mod-xmlwriter
LUCI_PKGARCH:=all
PKG_VERSION:=14
PKG_DATE:=20210505
PKG_VERSION:=20220109
PKG_RELEASE:=1
include $(TOPDIR)/feeds/luci/luci.mk

View File

@ -1,16 +1,17 @@
-- Copyright 2018-2020 Lienol <lawlienol@gmail.com>
-- Copyright 2018-2022 Lienol <lawlienol@gmail.com>
module("luci.controller.kodexplorer", package.seeall)
local http = require "luci.http"
local api = require "luci.model.cbi.kodexplorer.api"
function index()
if not nixio.fs.access("/etc/config/kodexplorer") then
return
end
if not nixio.fs.access("/etc/config/kodexplorer") then return end
entry({"admin", "nas"}, firstchild(), "NAS", 44).dependent = false
entry({"admin", "nas", "kodexplorer"}, cbi("kodexplorer/settings"), _("KodExplorer"), 3).dependent = true
e = entry({"admin", "nas", "kodexplorer"}, cbi("kodexplorer/settings"), _("KodExplorer"), 3)
e.dependent = true
e.acl_depends = { "luci-app-kodexplorer" }
entry({"admin", "nas", "kodexplorer", "check"}, call("action_check")).leaf = true
entry({"admin", "nas", "kodexplorer", "download"}, call("action_download")).leaf = true

View File

@ -1,53 +1,96 @@
m = Map("kodexplorer")
m.title = translate("KodExplorer")
m.description = translate("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 = Map("kodexplorer", translate("KodExplorer"), translate("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"))
s = m:section(TypedSection, "global", translate("Global Settings"))
s = m:section(TypedSection, "global")
s.anonymous = true
s.addremove = false
o = s:option(Flag, "enable", translate("Enable"))
s:tab("global", translate("Global Settings"))
s:tab("template", translate("Edit Template"))
php_fpm = s:taboption("template", Value, "_php_fpm",
translatef("Edit the template that is used for generating the %s configuration.", "php-fpm"),
translatef("This is the content of the file '%s'", "/etc/kodexplorer/php-fpm.conf.template") ..
translatef("Values enclosed by pipe symbols ('|') should not be changed. They get their values from the '%s' tab.", translate("Global Settings")))
php_fpm.template = "cbi/tvalue"
php_fpm.rows = 10
function php_fpm.cfgvalue(self, section)
return nixio.fs.readfile("/etc/kodexplorer/php-fpm.conf.template")
end
function php_fpm.write(self, section, value)
value = value:gsub("\r\n?", "\n")
nixio.fs.writefile("/etc/kodexplorer/php-fpm.conf.template", value)
end
php = s:taboption("template", Value, "_php",
translatef("Edit the template that is used for generating the %s configuration.", "php"),
translatef("This is the content of the file '%s'", "/etc/kodexplorer/php.ini.template") ..
translatef("Values enclosed by pipe symbols ('|') should not be changed. They get their values from the '%s' tab.", translate("Global Settings")))
php.template = "cbi/tvalue"
php.rows = 10
function php.cfgvalue(self, section)
return nixio.fs.readfile("/etc/kodexplorer/php.ini.template")
end
function php.write(self, section, value)
value = value:gsub("\r\n?", "\n")
nixio.fs.writefile("/etc/kodexplorer/php.ini.template", value)
end
nginx = s:taboption("template", Value, "_nginx",
translatef("Edit the template that is used for generating the %s configuration.", "nginx"),
translatef("This is the content of the file '%s'", "/etc/kodexplorer/nginx.conf.template") ..
translatef("Values enclosed by pipe symbols ('|') should not be changed. They get their values from the '%s' tab.", translate("Global Settings")))
nginx.template = "cbi/tvalue"
nginx.rows = 10
function nginx.cfgvalue(self, section)
return nixio.fs.readfile("/etc/kodexplorer/nginx.conf.template")
end
function nginx.write(self, section, value)
value = value:gsub("\r\n?", "\n")
nixio.fs.writefile("/etc/kodexplorer/nginx.conf.template", value)
end
o = s:taboption("global", Flag, "enable", translate("Enable"))
o.rmempty = false
o = s:option(Value, "port", translate("Nginx Port"))
o = s:taboption("global", Flag, "ipv6", translate("Listen IPv6"))
o.rmempty = false
o = s:taboption("global", Value, "port", translate("Nginx Port"))
o.datatype = "port"
o.default = 8081
o.rmempty = false
o = s:option(Value, "memory_limit", translate("Maximum memory usage"))
o.description = translate("If your device has a lot of memory, you can increase it.")
o.default = "8M"
o = s:taboption("global", Flag, "https", translate("HTTPS"))
o.rmempty = false
o = s:option(Value, "post_max_size", translate("Maximum POST capacity"))
o.description = translate("This value cannot be greater than the maximum memory usage")
o.default = "12M"
o = s:taboption("global", FileUpload, "certificate", translate("certificate"))
o:depends("https", 1)
o = s:taboption("global", FileUpload, "key", translate("key"))
o:depends("https", 1)
o = s:taboption("global", Value, "memory_limit", translate("Maximum memory usage"), translate("If your device has a lot of memory, you can increase it."))
o.default = "32M"
o.rmempty = false
o = s:option(Value, "upload_max_filesize", translate("Maximum memory usage for uploading files"))
o.description = translate("This value cannot be greater than the POST maximum capacity")
o.default = "12M"
o = s:taboption("global", Value, "upload_max_filesize", translate("Maximum memory usage for uploading files"))
o.default = "32M"
o.rmempty = false
o = s:option(Value, "storage_device_path", translate("Storage device path"))
o.description = 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 = s:taboption("global", DynamicList, "open_basedir", translate("Accessible directory"))
o.rmempty = false
o = s:option(Value, "project_directory", translate("Project directory"))
o.description = translate("It is recommended to insert a usb flash drive or hard disk and enter the path. For example, /mnt/sda1/kodexplorer")
o = s:taboption("global", Value, "project_directory", translate("Project directory"), 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
s:append(Template("kodexplorer/version"))
o = s:option(Button, "_download", translate("Manually update"))
o.description = 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.inputstyle = "apply"
o.btnclick = "downloadClick(this);"
o.id = "download_btn"
o = s:taboption("global", Button, "_update")
o.template = "kodexplorer/version"
return m

View File

@ -1,175 +0,0 @@
<script type="text/javascript">
//<![CDATA[
var msgInfo;
var tokenStr = '<%=token%>';
var clickToDownloadText = '<%:Click to update%>';
var inProgressText = '<%:Updating...%>';
var downloadInProgressNotice = '<%:Updating, are you sure to close?%>';
var downloadSuccessText = '<%:Update successful%>';
var unexpectedErrorText = '<%:Unexpected error%>';
var downloadingText = '<%:Downloading...%>';
var decompressioningText = '<%:Unpacking...%>';
var movingText = '<%:Moving...%>';
var latestVersionText = '<%:The latest version:%>';
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) {
var text = btn.value;
btn.disabled = true;
btn.value = inProgressText;
addPageNotice();
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
doAjaxGet('<%=url([[admin]], [[nas]], [[kodexplorer]], [[check]])%>', {
token: tokenStr
}, function (json) {
removePageNotice();
if (json.code && json.data.server) {
var server = json.data.server;
eval('Info = json');
btn.disabled = false;
btn.value = clickToDownloadText;
btn.placeholder = clickToDownloadText;
if (ckeckDetailElm) {
var urlNode = '';
if (server.version) {
urlNode = '<em style="color:red;">' + latestVersionText + server.version + '</em>';
var html_url = 'https://kodcloud.com/download/';
if (html_url) {
urlNode = '<a href="' + html_url + '" target="_blank">' + urlNode + '</a>';
}
}
ckeckDetailElm.innerHTML = urlNode;
}
msgInfo = server;
} else {
removePageNotice();
btn.disabled = false;
btn.value = text;
alert(unexpectedErrorText);
}
});
}
function doDownload(btn) {
btn.disabled = true;
btn.value = downloadingText;
addPageNotice();
var UpdateUrl = '<%=url([[admin]], [[nas]], [[kodexplorer]], [[download]])%>';
// Download file
doAjaxGet(UpdateUrl, {
token: tokenStr,
url: msgInfo ? msgInfo.link : ''
}, function (json) {
if (json.code) {
removePageNotice();
onRequestError(btn, json.error);
} else {
btn.value = decompressioningText;
// Extract file
doAjaxGet(UpdateUrl, {
token: tokenStr,
task: 'extract',
file: json.file
}, function (json) {
if (json.code) {
removePageNotice();
onRequestError(btn, json.error);
} else {
btn.value = movingText;
// 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

@ -1,7 +1,3 @@
<%
local dsp = require "luci.dispatcher"
-%>
<fieldset class="cbi-section">
<legend><%:Running Status%></legend>
<fieldset class="cbi-section">
@ -13,17 +9,30 @@ local dsp = require "luci.dispatcher"
<label class="cbi-value-title">PHP <%:Status%></label>
<div class="cbi-value-field" id="_php_status"><%:Collecting data...%></div>
</div>
<div class="cbi-value">
<label class="cbi-value-title"></label>
<div class="cbi-value-field">
<font color="red" id="tips"></font>
</div>
</div>
</fieldset>
</fieldset>
<script type="text/javascript">//<![CDATA[
var nginx_status = document.getElementById('_nginx_status');
var php_status = document.getElementById('_php_status');
XHR.poll(3,'<%=dsp.build_url("admin/nas/kodexplorer/status")%>', null,
XHR.poll(3, '<%=url([[admin]], [[nas]], [[kodexplorer]], [[status]])%>', null,
function(x, json) {
if (x && x.status == 200) {
if (nginx_status) {
nginx_status.innerHTML = json.nginx_status ? '<font color="green"><%:RUNNING%> ✓</font><input type="button" class="cbi-button cbi-input-apply" value="<%:Enter interface%>" onclick="openwebui()" />' : '<font color="red"><%:NOT RUNNING%> X</font>';
var str = "";
if (json.nginx_status) {
document.getElementById("tips").innerHTML = '<%:If you need external network access, please open the port by yourself.%>';
str = '<font color="green"><%:RUNNING%> ✓</font><input type="button" class="cbi-button cbi-input-apply" value="<%:Enter interface%>" onclick="open_web()" />'
} else {
str = '<font color="red"><%:NOT RUNNING%> X</font>';
}
nginx_status.innerHTML = str;
}
if (php_status) {
php_status.innerHTML = json.php_status ? '<font color="green"><%:RUNNING%> ✓</font>' : '<font color="red"><%:NOT RUNNING%> X</font>';
@ -31,8 +40,13 @@ local dsp = require "luci.dispatcher"
}
}
);
function openwebui(){
var url = window.location.host+":<%=luci.sys.exec("uci -q get kodexplorer.@global[0].port"):gsub("^%s*(.-)%s*$", "%1")%>";
window.open('http://'+url,'target','');
function open_web(){
var port = '<%=luci.sys.exec("uci -q get kodexplorer.@global[0].port"):gsub("^%s*(.-)%s*$", "%1")%>';
var ishttps = '<%=luci.sys.exec("uci -q get kodexplorer.@global[0].https"):gsub("^%s*(.-)%s*$", "%1")%>';
var protocol = (ishttps == "1") ? "https://" : "http://";
var hostname = location.hostname;
var url = protocol + hostname + ":" + port;
window.open(url, 'target', '');
}
//]]></script>

View File

@ -1,10 +1,9 @@
<%
local api = require "luci.model.cbi.kodexplorer.api"
local app_version = api.get_version()
local app_version = require "luci.model.cbi.kodexplorer.api".get_version()
-%>
<% if app_version and app_version ~= "" then %>
<div class="cbi-value">
<div class="cbi-value">
<label class="cbi-value-title">
<%:Version%>
</label>
@ -13,5 +12,177 @@ local app_version = api.get_version()
<span><%=app_version%> 】</span>
</div>
</div>
</div>
</div>
<% else %>
<div class="cbi-value">
<label class="cbi-value-title">
<%:Manually update%>
</label>
<div class="cbi-value-field">
<input class="cbi-button cbi-input-apply" type="button" id="download_btn" value="<%:Manually update%>" onclick="downloadClick(this);">
<span id="download-detail"></span>
<div class="cbi-value-description">
<%: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>
</div>
</div>
</div>
<% end %>
<script type="text/javascript">
//<![CDATA[
var msgInfo;
var tokenStr = '<%=token%>';
var clickToDownloadText = '<%:Click to update%>';
var inProgressText = '<%:Updating...%>';
var downloadInProgressNotice = '<%:Updating, are you sure to close?%>';
var downloadSuccessText = '<%:Update successful%>';
var unexpectedErrorText = '<%:Unexpected error%>';
var downloadingText = '<%:Downloading...%>';
var decompressioningText = '<%:Unpacking...%>';
var movingText = '<%:Moving...%>';
var latestVersionText = '<%:The latest version:%>';
function addPageNotice() {
window.onbeforeunload = function (e) {
e.returnValue = downloadInProgressNotice;
return downloadInProgressNotice;
};
}
function removePageNotice() {
window.onbeforeunload = undefined;
}
function onRequestError(btn, errorMessage) {
btn.disabled = false;
btn.value = '<%:Manually update%>';
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) {
var text = btn.value;
btn.disabled = true;
btn.value = inProgressText;
addPageNotice();
var ckeckDetailElm = document.getElementById('download-detail');
doAjaxGet('<%=url([[admin]], [[nas]], [[kodexplorer]], [[check]])%>', {
token: tokenStr
}, function (json) {
removePageNotice();
if (json.code && json.data.server) {
var server = json.data.server;
eval('Info = json');
btn.disabled = false;
btn.value = clickToDownloadText;
btn.placeholder = clickToDownloadText;
if (ckeckDetailElm) {
var urlNode = '';
if (server.version) {
urlNode = '<em style="color:red;">' + latestVersionText + server.version + '</em>';
var html_url = 'https://kodcloud.com/download/';
if (html_url) {
urlNode = '<a href="' + html_url + '" target="_blank">' + urlNode + '</a>';
}
}
ckeckDetailElm.innerHTML = urlNode;
}
msgInfo = server;
} else {
removePageNotice();
btn.disabled = false;
btn.value = text;
onRequestError(btn, unexpectedErrorText);
}
});
}
function doDownload(btn) {
btn.disabled = true;
btn.value = downloadingText;
addPageNotice();
var UpdateUrl = '<%=url([[admin]], [[nas]], [[kodexplorer]], [[download]])%>';
// Download file
doAjaxGet(UpdateUrl, {
token: tokenStr,
url: msgInfo ? msgInfo.link : ''
}, function (json) {
if (json.code) {
removePageNotice();
onRequestError(btn, json.error);
} else {
btn.value = decompressioningText;
// Extract file
doAjaxGet(UpdateUrl, {
token: tokenStr,
task: 'extract',
file: json.file
}, function (json) {
if (json.code) {
removePageNotice();
onRequestError(btn, json.error);
} else {
btn.value = movingText;
// 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 {
alert(downloadSuccessText);
if (btn) {
btn.value = downloadSuccessText;
btn.placeholder = downloadSuccessText;
btn.disabled = true;
}
window.setTimeout(function () {
window.location.reload();
}, 1000);
}
})
}
})
}
})
}
//]]>
</script>

View File

@ -1,25 +1,45 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: dingpengyu <dingpengyu06@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: zh_CN\n"
"X-Generator: Poedit 2.3.1\n"
msgid "KodExplorer"
msgstr "可道云"
msgid "Running Status"
msgstr "运行状态"
msgid "Status"
msgstr "状态"
msgid "Collecting data..."
msgstr "正在收集数据..."
msgid "NOT RUNNING"
msgstr "未运行"
msgid "RUNNING"
msgstr "运行中"
msgid "If you need external network access, please open the port by yourself."
msgstr "如需外网访问,请自行放行端口。"
msgid "Global Settings"
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 "Edit Template"
msgstr "编辑模板"
msgid "Edit the template that is used for generating the %s configuration."
msgstr "编辑生成 %s 的模板"
msgid "This is the content of the file '%s'"
msgstr "这是文件内容:%s"
msgid "Values enclosed by pipe symbols ('|') should not be changed. They get their values from the '%s' tab."
msgstr "由管道符(“|”)包围的值不应更改。它们将从 '%s' 标签中获取其值。"
msgid "Listen IPv6"
msgstr "监听IPv6"
msgid "Nginx Port"
msgstr "Nginx监听端口"
@ -29,23 +49,11 @@ 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 "Accessible directory"
msgstr "可访问的目录"
msgid "Project directory"
msgstr "项目存放目录"
@ -53,8 +61,11 @@ 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 "Make sure you have enough space."
msgstr "请确保具有足够的空间。"
msgid "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!"
msgstr "第一次运行务必填好设备路径和存放路径,然后保存应用。再手动下载,否则无法使用!"
msgid "Manually update"
msgstr "手动更新"
@ -69,7 +80,7 @@ msgid "Click to update"
msgstr "点击更新"
msgid "Updating..."
msgstr "更新中..."
msgstr "更新中"
msgid "Unexpected error"
msgstr "意外错误"
@ -78,26 +89,20 @@ msgid "Updating, are you sure to close?"
msgstr "正在更新,你确认要关闭吗?"
msgid "Downloading..."
msgstr "下载中..."
msgstr "下载中"
msgid "Unpacking..."
msgstr "解压中..."
msgstr "解压中"
msgid "Moving..."
msgstr "移动中..."
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 "请指定下载地址。"
@ -107,14 +112,8 @@ 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,10 +1,11 @@
config global
option port '8080'
option storage_device_path '/opt/kodexplorer/'
option project_directory '/opt/kodexplorer'
option enable '0'
option memory_limit '120M'
option post_max_size '100M'
option upload_max_filesize '100M'
list open_basedir '/'
option https '0'
option project_directory '/opt/kodexplorer'
option ipv6 '0'
option memory_limit '120M'
option enable '0'

View File

@ -1,15 +1,15 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2018-2020 Lienol <lawlienol@gmail.com>
# Copyright (C) 2018-2022 Lienol <lawlienol@gmail.com>
START=99
CONFIG="kodexplorer"
TEMP_PATH="/var/etc/kodexplorer"
TEMP_PATH="/var/etc/$CONFIG"
NGINX_CONFIG="$TEMP_PATH/nginx.conf"
PHP_CONFIG="$TEMP_PATH/php.ini"
PHP_FPM_CONFIG="$TEMP_PATH/php-fpm.conf"
PHP_CONFIG="/etc/php.ini"
PHP_BACKUP_CONFIG="/etc/php.ini.backup"
PHP_FPM_SOCK="$TEMP_PATH/php-fpm.sock"
config_t_get() {
local index=0
@ -19,150 +19,58 @@ config_t_get() {
}
gen_nginx_config() {
ipv6=$(config_t_get global ipv6 0)
port=$(config_t_get global port)
project_directory=$(config_t_get global project_directory)
cat <<-EOF > $1
user root root;
worker_processes 1;
pid /var/run/nginx_kodexplorer.pid;
events {
worker_connections 1024;
[ "$(config_t_get global https 0)" == "1" ] && {
port="$port ssl"
ssl_certificate="ssl_certificate $(config_t_get global certificate);"
ssl_certificate_key="ssl_certificate_key $(config_t_get global key);"
}
http {
include /etc/nginx/mime.types;
sendfile on;
keepalive_timeout 65;
server {
listen $port;
listen [::]:$port;
server_name localhost;
location / {
root $project_directory;
index index.html index.htm index.php;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ \.php(.*)$ {
root $project_directory;
try_files \$uri = 404; # PHP 文件不存在返回404
fastcgi_pass unix:/var/run/php8-fpm.sock; # 通过 Unix 套接字执行 PHP
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; # 修复 Nginx fastcgi 漏洞
fastcgi_param PATH_INFO \$fastcgi_path_info;
include /etc/nginx/fastcgi_params;
}
}
}
EOF
sed -e "s#|PID|#$TEMP_PATH/nginx.pid#g" \
-e "s#|PORT|#$port#g" \
-e "s#|ssl_certificate|#$ssl_certificate#g" \
-e "s#|ssl_certificate_key|#$ssl_certificate_key#g" \
-e "s#|project_directory|#$project_directory#g" \
-e "s#|SOCK|#$PHP_FPM_SOCK#g" \
-e "s#|upload_max_filesize|#$upload_max_filesize#g" \
-e "s#|temp_path|#$TEMP_PATH/temp#g" \
/etc/$CONFIG/nginx.conf.template > $1
[ "$ipv6" = "0" ] && sed -i '/listen \[::\]:/d' $1
}
gen_php_config() {
storage_device_path=$(config_t_get global storage_device_path)
memory_limit=$(config_t_get global memory_limit)
post_max_size=$(config_t_get global post_max_size)
upload_max_filesize=$(config_t_get global upload_max_filesize)
cp $PHP_CONFIG $PHP_BACKUP_CONFIG
cat <<-EOF >$PHP_CONFIG
[PHP]
zend.ze1_compatibility_mode = Off
engine = On
precision = 12
y2k_compliance = On
output_buffering = Off
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = 100
sed -e "s#|project_directory|#$project_directory#g" \
-e "s#|open_basedir|#$open_basedir#g" \
-e "s#|memory_limit|#$memory_limit#g" \
-e "s#|upload_max_filesize|#$upload_max_filesize#g" \
/etc/$CONFIG/php.ini.template > $PHP_CONFIG
open_basedir = $storage_device_path:/tmp/:/proc/:/usr/bin/
disable_functions =
disable_classes =
expose_php = On
max_execution_time = 30
max_input_time = 60
memory_limit = $memory_limit
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT
display_errors = On
display_startup_errors = Off
log_errors = Off
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = Off
variables_order = "EGPCS"
request_order = "GP"
register_globals = Off
register_long_arrays = Off
register_argc_argv = On
auto_globals_jit = On
post_max_size = $post_max_size
magic_quotes_runtime = Off
magic_quotes_sybase = Off
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
;doc_root = "/www"
user_dir =
extension_dir = "/usr/lib/php"
enable_dl = On
cgi.fix_pathinfo=1
file_uploads = On
upload_tmp_dir = "/tmp"
upload_max_filesize = $upload_max_filesize
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60
EOF
cat <<-EOF >$PHP_FPM_CONFIG
[global]
pid = /var/run/kodexplorer_php8-fpm.pid
error_log = /var/log/kodexplorer_php8-fpm.log
[www]
user = root
listen = /var/run/php8-fpm.sock
listen.mode = 0666
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chdir = /
EOF
sed -e "s#|PID|#$TEMP_PATH/php-fpm.pid#g" \
-e "s#|ERROR_LOG|#$TEMP_PATH/php-fpm.log#g" \
-e "s#|SOCK|#$PHP_FPM_SOCK#g" \
/etc/$CONFIG/php-fpm.conf.template > $PHP_FPM_CONFIG
}
start() {
ENABLED=$(config_t_get global enable 0)
[ "$ENABLED" = "0" ] && return 0
mkdir -p $TEMP_PATH /var/log/nginx /var/lib/nginx
mkdir -p $TEMP_PATH $TEMP_PATH/temp /var/log/nginx /var/lib/nginx
memory_limit=$(config_t_get global memory_limit 64M)
upload_max_filesize=$(config_t_get global upload_max_filesize 64M)
project_directory=$(config_t_get global project_directory)
open_basedir=$(config_t_get global open_basedir "/")
open_basedir=$(echo $open_basedir | sed "s/ /:/g")
gen_php_config
/usr/bin/php-fpm -R -y $PHP_FPM_CONFIG -g "/var/run/php8-fpm.pid"
/usr/bin/php8-fpm -c $PHP_CONFIG -R -y $PHP_FPM_CONFIG
gen_nginx_config $NGINX_CONFIG
/usr/sbin/nginx -c $NGINX_CONFIG >/dev/null 2>&1 &
}
stop() {
/usr/sbin/nginx -c $NGINX_CONFIG -s stop >/dev/null 2>&1 &
killall -9 php-fpm >/dev/null 2>&1 &
rm -f /var/run/kodexplorer_php8-fpm.pid
rm -f /var/log/kodexplorer_php8-fpm.log
rm -f /var/run/php8-fpm.sock
[ -f "$PHP_BACKUP_CONFIG" -a -f "$PHP_CONFIG" ] && {
rm -f $PHP_CONFIG
cp $PHP_BACKUP_CONFIG $PHP_CONFIG
rm -f $PHP_BACKUP_CONFIG
}
/usr/sbin/nginx -c $NGINX_CONFIG -s stop >/dev/null 2>&1
[ -f "$TEMP_PATH/php-fpm.pid" ] && kill -2 $(cat $TEMP_PATH/php-fpm.pid) >/dev/null 2>&1
rm -rf $TEMP_PATH
}
restart() {

View File

@ -0,0 +1,38 @@
user root root;
worker_processes auto;
pid |PID|;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
sendfile on;
keepalive_timeout 65;
server {
listen |PORT|;
listen [::]:|PORT|;
|ssl_certificate|
|ssl_certificate_key|
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
server_name localhost;
root |project_directory|;
index index.html index.htm index.php;
location ~ \.php(.*)$ {
fastcgi_pass unix:|SOCK|; # 通过 Unix 套接字执行 PHP
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # 修复 Nginx fastcgi 漏洞
fastcgi_param PATH_INFO $fastcgi_path_info;
include /etc/nginx/fastcgi_params;
client_max_body_size |upload_max_filesize|;
client_body_temp_path |temp_path|;
client_body_timeout 3600s;
fastcgi_connect_timeout 3600s;
fastcgi_send_timeout 3600s;
fastcgi_read_timeout 3600s;
}
}
}

View File

@ -0,0 +1,14 @@
[global]
pid = |PID|
error_log = |ERROR_LOG|
[www]
user = root
listen = |SOCK|
listen.mode = 0666
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chdir = /

View File

@ -0,0 +1,55 @@
[PHP]
zend.ze1_compatibility_mode = Off
engine = On
precision = 12
y2k_compliance = On
output_buffering = Off
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = 100
open_basedir = /tmp:|project_directory|:|open_basedir|:/usr/bin/
disable_functions =
disable_classes =
expose_php = On
max_execution_time = 3600
max_input_time = 3600
memory_limit = |memory_limit|
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT
display_errors = On
display_startup_errors = Off
log_errors = Off
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = Off
variables_order = "EGPCS"
request_order = "GP"
register_globals = Off
register_long_arrays = Off
register_argc_argv = On
auto_globals_jit = On
post_max_size = |upload_max_filesize|
magic_quotes_runtime = Off
magic_quotes_sybase = Off
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
;doc_root = "/www"
user_dir =
extension_dir = "/usr/lib/php8"
enable_dl = On
cgi.fix_pathinfo=1
file_uploads = On
upload_tmp_dir = "/tmp"
upload_max_filesize = |upload_max_filesize|
max_file_uploads = 1000
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60

View File

@ -7,6 +7,7 @@ uci -q batch <<-EOF >/dev/null
commit ucitrack
EOF
/etc/init.d/php8-fpm disable && /etc/init.d/php8-fpm stop
rm -rf /tmp/luci-*
/etc/init.d/php8-fpm stop
/etc/init.d/php8-fpm disable
rm -rf /tmp/luci-*cache
exit 0