diff options
4 files changed, 165 insertions, 0 deletions
diff --git a/applications/luci-app-rosy-file-server/Makefile b/applications/luci-app-rosy-file-server/Makefile new file mode 100644 index 0000000000..93d9a3a669 --- /dev/null +++ b/applications/luci-app-rosy-file-server/Makefile @@ -0,0 +1,15 @@ +# +# Copyright (C) 2008-2014 The LuCI Team <luci@lists.subsignal.org> +# Copyright (C) 2018 Rosy Song <rosysong@rosinson.com> +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI Support for Rosy File Server +LUCI_DEPENDS:=+luci-base +rosy-file-server + +include ../../luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/applications/luci-app-rosy-file-server/luasrc/controller/rosy-file-server/rosy-file-server.lua b/applications/luci-app-rosy-file-server/luasrc/controller/rosy-file-server/rosy-file-server.lua new file mode 100644 index 0000000000..6c7c492089 --- /dev/null +++ b/applications/luci-app-rosy-file-server/luasrc/controller/rosy-file-server/rosy-file-server.lua @@ -0,0 +1,52 @@ +-- Copyright 2018 Rosy Song <rosysong@rosinson.com> +-- Licensed to the public under the Apache License 2.0. + +module("luci.controller.rosy-file-server.rosy-file-server", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/rosyfs") then + return + end + + local root = node() + if not root.target then + root.target = alias("httpfs") + root.index = true + end + + page = node() + page.lock = true + page.target = alias("httpfs") + page.subindex = true + page.index = false + + page = node("httpfs") + page.title = _("File-server") + page.target = alias("httpfs", "rosy-file-server") + page.order = 5 + page.setuser = "root" + page.setgroup = "root" + page.index = true + + entry({"httpfs", "rosy-file-server"}, + form("rosy-file-server/rosy-file-server"), _("Rosy File Server"), 10) + entry({"httpfs", "file-server-download"}, + post("action_download"), nil) + + entry({"admin", "services", "rosyfs"}, + cbi("rosy-file-server/rosyfs"), _("Rosy File Server"), 61) +end + +function action_download() + local p = luci.http.formvalue("path") or "" + local n = luci.http.formvalue("name") or "" + + if not p or not n then + luci.http.status(400, "Bad Request") + return + end + + luci.http.header('Content-Disposition', 'attachment; filename="%s"' % n) + luci.http.prepare_content("application/octet-stream") + luci.sys.process.exec({ "/bin/dd", "if=%s%s" % { p, n }, "conv=fsync,notrunc" }, luci.http.write) +end diff --git a/applications/luci-app-rosy-file-server/luasrc/model/cbi/rosy-file-server/rosy-file-server.lua b/applications/luci-app-rosy-file-server/luasrc/model/cbi/rosy-file-server/rosy-file-server.lua new file mode 100644 index 0000000000..703b4defc0 --- /dev/null +++ b/applications/luci-app-rosy-file-server/luasrc/model/cbi/rosy-file-server/rosy-file-server.lua @@ -0,0 +1,72 @@ +-- Copyright 2018 Rosy Song <rosysong@rosinson.com> +-- Licensed to the public under the Apache License 2.0. + +local uci = require "luci.model.uci".cursor() +local dis = uci:get("rosyfs", "default", "disabled") + +local targets = {} +local server_root = luci.http.formvalue("server_root") or "/www/rosyfs-share/" +local buffer = io.popen("/bin/busybox ls -ahLlp %s" % server_root) +if dis ~= '1' and buffer then + for l in buffer:lines() do + local _p, i, u, g, sz, mm, dd, tt, nm = l:match( + "^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+(.+)" + ) + local p = _p and string.sub(_p, 1, 1) or nil + if p and (p == '-' or p == 'd') and nm and (nm ~= "./") and + not (server_root == "/www/rosyfs-share/" and nm == "../") and + not (server_root == "/www/rosyfs-share/" and nm == "rosyfs-share/") then + targets[nm] = { + ['type'] = p, + ['size'] = sz, + ['last'] = "%s %s %s" % { mm, dd, tt }, + ['name'] = nm + } + end + end +end + +local title = uci:get("rosyfs", "default", "title") or nil + +m = SimpleForm("rosyfs", title or translate("Rosy File Server"), translate("This is rosy file server for luci.<br /><strong>Note: targets will be mapped at /www/rosyfs-share !</strong>")) +m.reset = false +m.submit = false + + +s = m:section(Table, targets) + +t = s:option(DummyValue, "type", translate("Type")) + +n = s:option(DummyValue, "name", translate("Name")) +n.rawhtml = true + +function n.cfgvalue(self, section) + local v = DummyValue.cfgvalue(self, section) + local hv = (v == "../") and "Parent Directory" or v + local t = targets[v]['type'] + + if t and t ~='d' then + -- File + return translatef("<a href='%s%s'>%s</a>", + string.sub(server_root, 5, #server_root), hv, hv); + elseif t then + -- Directory + if v == "../" then + local dir = luci.util.trim(luci.util.exec("dirname " .. server_root)) + + if dir ~= "/" then dir = dir .. "/" end + + return translatef("<a href='%s?server_root=%s'>%s</a>", + luci.dispatcher.build_url("httpfs/rosy-file-server"), dir, hv) + else + return translatef("<a href='%s?server_root=%s%s'>%s</a>", + luci.dispatcher.build_url("httpfs/rosy-file-server"), + server_root, hv, hv) + end + end +end + +l = s:option(DummyValue, "last", translate("Last Modified")) +sz = s:option(DummyValue, "size", translate("Size")) + +return m diff --git a/applications/luci-app-rosy-file-server/luasrc/model/cbi/rosy-file-server/rosyfs.lua b/applications/luci-app-rosy-file-server/luasrc/model/cbi/rosy-file-server/rosyfs.lua new file mode 100644 index 0000000000..51efa9e814 --- /dev/null +++ b/applications/luci-app-rosy-file-server/luasrc/model/cbi/rosy-file-server/rosyfs.lua @@ -0,0 +1,26 @@ +-- Copyright 2019 Rosy Song <rosysong@rosinson.com> +-- Licensed to the public under the Apache License 2.0. + +local uci = require("luci.model.uci").cursor() +local dis = uci:get("rosyfs", "default", "disabled") +local tgt = uci:get("rosyfs", "default", "target") +local tlt = uci:get("rosyfs", "default", "title") + +m = Map("rosyfs", translate("Rosy File Server Settings")) + +s = m:section(TypedSection, "rosyfs", nil) +s.addremove = false +s.anonymous = true + +e = s:option(Flag, "disabled", translate("Disable"), translate("Disable Rosy File Server")) +e.default = dis or e.disabled +e.rmempty = false + +a = s:option(Value, "target", translate("Target"), translate("Specify path to be mapped")) +a.default = tgt or "/www" +a.datatype = "directory" + +t = s:option(Value, "title", translate("Title"), translate("Title to be shown")) +t.default = tlt or "Rosy File Server" + +return m |