update 2026-09-24 16:56:26

This commit is contained in:
action committed 2026-09-24 16:56:26 +08:00
1 parent b31a5c3878
commit e4cee331e9
6885 files changed
+3240523

No files matched your search

+13
View File
@@ -0,0 +1,13 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI for UniShare
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+unishare
PKG_VERSION:=1.0.2-r1
PKG_RELEASE:=
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
@@ -0,0 +1,13 @@
module("luci.controller.unishare", package.seeall)
function index()
if not nixio.fs.access("/etc/config/unishare") then
return
end
entry({"admin", "nas", "unishare"}, alias("admin", "nas", "unishare", "index"), _("UniShare"), 2).dependent = true
entry({"admin", "nas", "unishare", "index"}, cbi("unishare/index"), _("UniShare"), 1)
entry({"admin", "nas", "unishare", "users"}, cbi("unishare/users"), _("Users"), 2)
entry({"admin", "nas", "unishare", "share"}, cbi("unishare/share", {hideapplybtn=true})).leaf = true
end
@@ -0,0 +1,101 @@
local xml = require "luci.xml"
local pcdata = xml.pcdata
local uci = luci.model.uci.cursor()
local usersmap = {}
usersmap["everyone"] = "{" .. translate("Everyone") .. "}"
usersmap["users"] = "{" .. translate("Logged Users") .. "}"
uci:foreach("unishare", "user", function(e)
local username = e["username"]
if not username or username == "" then
return
end
local comment = e["comment"]
usersmap[username] = username .. (comment and (" (" .. comment .. ")") or "")
end)
m = Map("unishare", nil, translate("Configure multiple file sharing protocols in one page (Samba, WebDAV, maybe more in the future?)"))
s = m:section(TypedSection, "global", translate("Global"))
s:tab("general", translate("General Setup"))
s:tab("webdav", translate("WebDAV"))
s.anonymous = true
s.addremove = false
o = s:taboption("general", Flag, "enabled", translate("Enabled"))
o.default = 0
o = s:taboption("general", Flag, "anonymous", translate("Allow Anonymous"),
translatef("For logged in users, please manage on the '%s' page",
"<a href=\""..luci.dispatcher.build_url("admin", "nas", "unishare", "users").."\" >"..translate("Users").."</a>"))
o.default = 0
o = s:taboption("webdav", Value, "webdav_port", translate("WebDAV Port"))
o.datatype = "port"
s = m:section(TypedSection, "share", translate("Shares"), translate("(The user marked in <b>Bold</b> has write access)"))
s.anonymous = true
s.addremove = true
s.template = "cbi/tblsection"
s.extedit = luci.dispatcher.build_url("admin", "nas", "unishare", "share", "%s")
function s.create(...)
local sid = TypedSection.create(...)
luci.http.redirect(s.extedit % sid)
end
local path = s:option(Value, "path", translate("Path"))
path.datatype = "string"
path.rmempty = false
local name = s:option(Value, "name", translate("Name"))
name.datatype = "string"
name.rmempty = true
name.validate = function(self, value, section)
if value and string.match(value, "[`&|;<>/\\*?$#]") then
return nil, translatef("Name must not contains '%s'", "`&|;<>/\\*?$#")
end
return AbstractValue.validate(self, value, section)
end
path.validate = function(self, value, section)
if value then
if value == "/" or string.match(value, "^/.+[^/]$") then
if value == "/" and (nil == name:formvalue(section) or "" == name:formvalue(section)) then
return nil, translate("Name cannot be empty when Path is /")
end
return value
else
return nil, translate("Path must starts with '/' and not ends with '/'")
end
end
return AbstractValue.validate(self, value, section)
end
local function uci2string(v, s)
if v == nil then
return "&#8212;"
end
if type(v) == "table" then
local i, u
local d = {}
for i, u in ipairs(v) do
d[#d+1] = pcdata(usersmap[u] or u)
end
return table.concat(d, s)
else
return pcdata(usersmap[v] or v)
end
end
o = s:option(DummyValue, "users", translate("Users"))
o.rawhtml = true
function o.cfgvalue(self, s)
return "<b>" .. uci2string(self.map:get(s, "rw"), " ") .. "</b><br><i>" .. uci2string(self.map:get(s, "ro"), " ") .. "</i>"
end
o = s:option(StaticList, "proto", translate("Protocol"))
o:value("samba", "Samba")
o:value("webdav", "WebDAV")
return m
@@ -0,0 +1,74 @@
local uci = luci.model.uci.cursor()
local users = {}
uci:foreach("unishare", "user", function(e)
local username = e["username"]
if not username or username == "" then
return
end
local comment = e["comment"]
users[#users+1] = {username=username, displayname=username .. (comment and (" (" .. comment .. ")") or "")}
end)
m = Map("unishare", translate("Configure Share"))
m.redirect = luci.dispatcher.build_url("admin", "nas", "unishare", "index")
function m.on_save()
luci.http.redirect(m.redirect)
end
s = m:section(NamedSection, arg[1], "share", "")
s.addremove = false
s.dynamic = false
local path = s:option(Value, "path", translate("Path"),
translate("Note: '/mnt' is not suitable as a writable share, because Windows will recognize the wrong capacity"))
path.datatype = "string"
path.rmempty = false
local name = s:option(Value, "name", translate("Name"))
name.datatype = "string"
name.rmempty = true
name.validate = function(self, value, section)
if value and string.match(value, "[`&|;<>/\\*?$#]") then
return nil, translatef("Name must not contains '%s'", "`&|;<>/\\*?$#")
end
return AbstractValue.validate(self, value, section)
end
path.validate = function(self, value, section)
if value then
if value == "/" or string.match(value, "^/.+[^/]$") then
if value == "/" and (nil == name:formvalue(section) or "" == name:formvalue(section)) then
return nil, translate("Name cannot be empty when Path is /")
end
return value
else
return nil, translate("Path must starts with '/' and not ends with '/'")
end
end
return AbstractValue.validate(self, value, section)
end
local i, u
o = s:option(StaticList, "rw", translate("Read/Write Users"),
translatef("'Everyone' includes anonymous if enabled, 'Logged Users' includes all users configured in '%s' tab",
"<a href=\""..luci.dispatcher.build_url("admin", "nas", "unishare", "users").."\" >"..translate("Users").."</a>"))
o:value("everyone", "{" .. translate("Everyone") .. "}")
o:value("users", "{" .. translate("Logged Users") .. "}")
for i, u in ipairs(users) do
o:value(u.username, u.displayname)
end
o = s:option(StaticList, "ro", translate("Read Only Users"))
o:value("everyone", "{" .. translate("Everyone") .. "}")
o:value("users", "{" .. translate("Logged Users") .. "}")
for i, u in ipairs(users) do
o:value(u.username, u.displayname)
end
o = s:option(StaticList, "proto", translate("Protocol"))
o:value("samba", "Samba")
o:value("webdav", "WebDAV")
return m
@@ -0,0 +1,29 @@
m = Map("unishare")
s = m:section(TypedSection, "user", translate("Users"))
s.anonymous = true
s.addremove = true
s.template = "cbi/tblsection"
o = s:option(Value, "username", translate("Username"),
translate("Note: Do not use the 'root' user, as Samba forbids 'root' user login by default"))
o.datatype = "string"
o.rmempty = false
o.validate = function(self, value)
if value and string.match(value, "^%l[%l%d_-]*$") then
return value
else
return nil, translatef("Username must matchs regex '%s'", "^[a-z][a-z0-9_-]*$")
end
end
o = s:option(Value, "password", translate("Password"))
o.datatype = "string"
o.password = true
o.rmempty = true
o = s:option(Value, "comment", translate("Comment"))
o.datatype = "string"
return m
+65
View File
@@ -0,0 +1,65 @@
msgid ""
msgstr ""
msgid "UniShare"
msgstr "统一文件共享"
msgid "Configure multiple file sharing protocols in one page (Samba, WebDAV, maybe more in the future?)"
msgstr "在一个页面中配置多种文件共享协议(Samba,WebDAV,也许以后会支持更多?)"
msgid "Global"
msgstr "全局"
msgid "Allow Anonymous"
msgstr "允许匿名用户"
msgid "For logged in users, please manage on the '%s' page"
msgstr "对于登录用户,请在 '%s' 页面进行管理"
msgid "WebDAV Port"
msgstr "WebDAV 端口"
msgid "Shares"
msgstr "共享"
msgid "(The user marked in <b>Bold</b> has write access)"
msgstr "(<b>加粗</b>的用户具有写权限)"
msgid "Users"
msgstr "用户"
msgid "Configure Share"
msgstr "配置共享"
msgid "Read/Write Users"
msgstr "读写用户"
msgid "Read Only Users"
msgstr "只读用户"
msgid "Everyone"
msgstr "任何人"
msgid "Logged Users"
msgstr "登录用户"
msgid "'Everyone' includes anonymous if enabled, 'Logged Users' includes all users configured in '%s' tab"
msgstr "'任何人'包括所有登录用户和匿名用户(如果允许匿名用户),'登录用户'包括所有在'%s'标签页配置的用户"
msgid "Note: '/mnt' is not suitable as a writable share, because Windows will recognize the wrong capacity"
msgstr "注意:'/mnt' 不适合作为可写共享,因为 Windows 会认错容量"
msgid "Name cannot be empty when Path is /"
msgstr "路径是/时,名称不能为空"
msgid "Path must starts with '/' and not ends with '/'"
msgstr "路径必须以/开头,且不能以/结尾"
msgid "Name must not contains '%s'"
msgstr "名称不能包含这些特殊字符'%s'"
msgid "Username must matchs regex '%s'"
msgstr "用户名必须满足正则表达式'%s'"
msgid "Note: Do not use the 'root' user, as Samba forbids 'root' user login by default"
msgstr "注意:不要使用 'root' 用户,因为 Samba 默认禁止 'root' 用户登录"
+1
View File
@@ -0,0 +1 @@
zh-cn