diff --git a/package/lean/luci-app-filetransfer/Makefile b/package/lean/luci-app-filetransfer/Makefile new file mode 100644 index 000000000..dae88c85d --- /dev/null +++ b/package/lean/luci-app-filetransfer/Makefile @@ -0,0 +1,18 @@ +# +# Copyright (C) 2008-2014 The LuCI Team +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI page for IPK upload +LUCI_DEPENDS:=+luci-lib-fs +PKG_VERSION:=1 +PKG_RELEASE:=2 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + + diff --git a/package/lean/luci-app-filetransfer/etc/uci-defaults/luci-filetransfer b/package/lean/luci-app-filetransfer/etc/uci-defaults/luci-filetransfer new file mode 100755 index 000000000..935d7c8be --- /dev/null +++ b/package/lean/luci-app-filetransfer/etc/uci-defaults/luci-filetransfer @@ -0,0 +1,6 @@ +#!/bin/sh + +sed -i 's/cbi.submit\"] = true/cbi.submit\"] = \"1\"/g' /usr/lib/lua/luci/dispatcher.lua + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-filetransfer/luasrc/controller/filetransfer.lua b/package/lean/luci-app-filetransfer/luasrc/controller/filetransfer.lua new file mode 100644 index 000000000..727042786 --- /dev/null +++ b/package/lean/luci-app-filetransfer/luasrc/controller/filetransfer.lua @@ -0,0 +1,12 @@ +--[[ +luci-app-filetransfer +Description: File upload / download +Author: yuleniwo xzm2@qq.com QQ:529698939 +Modify: ayongwifi@126.com www.openwrtdl.com +]]-- + +module("luci.controller.filetransfer", package.seeall) + +function index() + entry({"admin", "system", "filetransfer"}, cbi("updownload"), _("FileTransfer"),89) +end diff --git a/package/lean/luci-app-filetransfer/luasrc/model/cbi/updownload.lua b/package/lean/luci-app-filetransfer/luasrc/model/cbi/updownload.lua new file mode 100644 index 000000000..7b487cb21 --- /dev/null +++ b/package/lean/luci-app-filetransfer/luasrc/model/cbi/updownload.lua @@ -0,0 +1,148 @@ +local fs = require "luci.fs" +local http = luci.http + +ful = SimpleForm("upload", translate("Upload"), nil) +ful.reset = false +ful.submit = false + +sul = ful:section(SimpleSection, "", translate("Upload file to '/tmp/upload/'")) +fu = sul:option(FileUpload, "") +fu.template = "cbi/other_upload" +um = sul:option(DummyValue, "", nil) +um.template = "cbi/other_dvalue" + +fdl = SimpleForm("download", translate("Download"), nil) +fdl.reset = false +fdl.submit = false +sdl = fdl:section(SimpleSection, "", translate("Download file")) +fd = sdl:option(FileUpload, "") +fd.template = "cbi/other_download" +dm = sdl:option(DummyValue, "", nil) +dm.template = "cbi/other_dvalue" + +function Download() + local sPath, sFile, fd, block + sPath = http.formvalue("dlfile") + sFile = nixio.fs.basename(sPath) + if luci.fs.isdirectory(sPath) then + fd = io.popen('tar -C "%s" -cz .' % {sPath}, "r") + sFile = sFile .. ".tar.gz" + else + fd = nixio.open(sPath, "r") + end + if not fd then + dm.value = translate("Couldn't open file: ") .. sPath + return + end + dm.value = nil + http.header('Content-Disposition', 'attachment; filename="%s"' % {sFile}) + http.prepare_content("application/octet-stream") + while true do + block = fd:read(nixio.const.buffersize) + if (not block) or (#block ==0) then + break + else + http.write(block) + end + end + fd:close() + http.close() +end + +local dir, fd +dir = "/tmp/upload/" +nixio.fs.mkdir(dir) +http.setfilehandler( + function(meta, chunk, eof) + if not fd then + if not meta then return end + + if meta and chunk then fd = nixio.open(dir .. meta.file, "w") end + + if not fd then + um.value = translate("Create upload file error.") + return + end + end + if chunk and fd then + fd:write(chunk) + end + if eof and fd then + fd:close() + fd = nil + um.value = translate("File saved to") .. ' "/tmp/upload/' .. meta.file .. '"' + end + end +) + +if luci.http.formvalue("upload") then + + + local f = luci.http.formvalue("ulfile") + if #f <= 0 then + um.value = translate("No specify upload file.") + end +elseif luci.http.formvalue("download") then + Download() +end + +local inits, attr = {} +for i, f in ipairs(fs.glob("/tmp/upload/*")) do + attr = fs.stat(f) + if attr then + inits[i] = {} + inits[i].name = fs.basename(f) + inits[i].mtime = os.date("%Y-%m-%d %H:%M:%S", attr.mtime) + inits[i].modestr = attr.modestr + inits[i].size = tostring(attr.size) + inits[i].remove = 0 + inits[i].install = false + end +end + +form = SimpleForm("filelist", translate("Upload file list"), nil) +form.reset = false +form.submit = false + +tb = form:section(Table, inits) +nm = tb:option(DummyValue, "name", translate("File name")) +mt = tb:option(DummyValue, "mtime", translate("Modify time")) +ms = tb:option(DummyValue, "modestr", translate("Mode string")) +sz = tb:option(DummyValue, "size", translate("Size")) +btnrm = tb:option(Button, "remove", translate("Remove")) +btnrm.render = function(self, section, scope) + self.inputstyle = "remove" + Button.render(self, section, scope) +end + +btnrm.write = function(self, section) + local v = luci.fs.unlink("/tmp/upload/" .. luci.fs.basename(inits[section].name)) + if v then table.remove(inits, section) end + return v +end + +function IsIpkFile(name) + name = name or "" + local ext = string.lower(string.sub(name, -4, -1)) + return ext == ".ipk" +end + +btnis = tb:option(Button, "install", translate("Install")) +btnis.template = "cbi/other_button" +btnis.render = function(self, section, scope) + if not inits[section] then return false end + if IsIpkFile(inits[section].name) then + scope.display = "" + else + scope.display = "none" + end + self.inputstyle = "apply" + Button.render(self, section, scope) +end + +btnis.write = function(self, section) + local r = luci.sys.exec(string.format('opkg --force-depends install "/tmp/upload/%s"', inits[section].name)) + form.description = string.format('%s', r) +end + +return ful, fdl, form diff --git a/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_button.htm b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_button.htm new file mode 100644 index 000000000..1c391ad98 --- /dev/null +++ b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_button.htm @@ -0,0 +1,7 @@ +<%+cbi/valueheader%> + <% if self:cfgvalue(section) ~= false then %> + " style="display: <%= display %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> /> + <% else %> + - + <% end %> +<%+cbi/valuefooter%> diff --git a/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_download.htm b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_download.htm new file mode 100644 index 000000000..c14728632 --- /dev/null +++ b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_download.htm @@ -0,0 +1,5 @@ +<%+cbi/valueheader%> + + + +<%+cbi/valuefooter%> diff --git a/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_dvalue.htm b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_dvalue.htm new file mode 100644 index 000000000..296c61e4d --- /dev/null +++ b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_dvalue.htm @@ -0,0 +1,8 @@ +<%+cbi/valueheader%> + +<% + local val = self:cfgvalue(section) or self.default or "" + write(pcdata(val)) +%> + +<%+cbi/valuefooter%> diff --git a/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_upload.htm b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_upload.htm new file mode 100644 index 000000000..bb56f444f --- /dev/null +++ b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_upload.htm @@ -0,0 +1,5 @@ +<%+cbi/valueheader%> + + + +<%+cbi/valuefooter%> diff --git a/package/lean/luci-app-filetransfer/po/zh-cn/filetransfer.po b/package/lean/luci-app-filetransfer/po/zh-cn/filetransfer.po new file mode 100644 index 000000000..829c7d285 --- /dev/null +++ b/package/lean/luci-app-filetransfer/po/zh-cn/filetransfer.po @@ -0,0 +1,56 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "Choose local file:" +msgstr "选择本地文件:" + +msgid "Couldn't open file:" +msgstr "无法打开文件:" + +msgid "Create upload file error." +msgstr "创建上传文件失败。" + +msgid "Download" +msgstr "下载" + +msgid "Download file" +msgstr "下载文件" + +msgid "File name" +msgstr "文件名" + +msgid "File saved to" +msgstr "文件保存到" + +msgid "FileTransfer" +msgstr "文件传输" + +msgid "Install" +msgstr "安装" + +msgid "Mode string" +msgstr "模式字符串" + +msgid "Modify time" +msgstr "修改时间" + +msgid "No specify upload file." +msgstr "未指定上传文件" + +msgid "Path on Route:" +msgstr "路由上目录" + +msgid "Remove" +msgstr "移除" + +msgid "Size" +msgstr "大小" + +msgid "Upload" +msgstr "上传" + +msgid "Upload file list" +msgstr "上传文件列表" + +msgid "Upload file to '/tmp/upload/'" +msgstr "将文件上传到'/tmp/upload/'" diff --git a/package/lean/luci-lib-fs/Makefile b/package/lean/luci-lib-fs/Makefile new file mode 100644 index 000000000..9d78a2971 --- /dev/null +++ b/package/lean/luci-lib-fs/Makefile @@ -0,0 +1,49 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-lib-fs +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/luci-lib-fs + SUBMENU:=Lua + SECTION:=lang + CATEGORY:=Languages + TITLE:=luci-lib-fs + PKGARCH:=all + URL:=https://github.com/lbthomsen/openwrt-luci + DEPENDS:=+luci +luci-lib-nixio +endef + +define Package/luci-lib-fs/description + luci-lib-fs +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Build/Install +endef + + +define Package/luci-lib-fs/install + $(INSTALL_DIR) $(1)/usr/lib/lua/luci + $(CP) ./files/*.lua $(1)/usr/lib/lua/luci + +endef + +$(eval $(call BuildPackage,luci-lib-fs)) diff --git a/package/lean/luci-lib-fs/files/fs.lua b/package/lean/luci-lib-fs/files/fs.lua new file mode 100644 index 000000000..a81ff675d --- /dev/null +++ b/package/lean/luci-lib-fs/files/fs.lua @@ -0,0 +1,244 @@ +--[[ +LuCI - Filesystem tools + +Description: +A module offering often needed filesystem manipulation functions + +FileId: +$Id$ + +License: +Copyright 2008 Steven Barth + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +]]-- + +local io = require "io" +local os = require "os" +local ltn12 = require "luci.ltn12" +local fs = require "nixio.fs" +local nutil = require "nixio.util" + +local type = type + +--- LuCI filesystem library. +module "luci.fs" + +--- Test for file access permission on given path. +-- @class function +-- @name access +-- @param str String value containing the path +-- @return Number containing the return code, 0 on sucess or nil on error +-- @return String containing the error description (if any) +-- @return Number containing the os specific errno (if any) +access = fs.access + +--- Evaluate given shell glob pattern and return a table containing all matching +-- file and directory entries. +-- @class function +-- @name glob +-- @param filename String containing the path of the file to read +-- @return Table containing file and directory entries or nil if no matches +-- @return String containing the error description (if no matches) +-- @return Number containing the os specific errno (if no matches) +function glob(...) + local iter, code, msg = fs.glob(...) + if iter then + return nutil.consume(iter) + else + return nil, code, msg + end +end + +--- Checks wheather the given path exists and points to a regular file. +-- @param filename String containing the path of the file to test +-- @return Boolean indicating wheather given path points to regular file +function isfile(filename) + return fs.stat(filename, "type") == "reg" +end + +--- Checks wheather the given path exists and points to a directory. +-- @param dirname String containing the path of the directory to test +-- @return Boolean indicating wheather given path points to directory +function isdirectory(dirname) + return fs.stat(dirname, "type") == "dir" +end + +--- Read the whole content of the given file into memory. +-- @param filename String containing the path of the file to read +-- @return String containing the file contents or nil on error +-- @return String containing the error message on error +readfile = fs.readfile + +--- Write the contents of given string to given file. +-- @param filename String containing the path of the file to read +-- @param data String containing the data to write +-- @return Boolean containing true on success or nil on error +-- @return String containing the error message on error +writefile = fs.writefile + +--- Copies a file. +-- @param source Source file +-- @param dest Destination +-- @return Boolean containing true on success or nil on error +copy = fs.datacopy + +--- Renames a file. +-- @param source Source file +-- @param dest Destination +-- @return Boolean containing true on success or nil on error +rename = fs.move + +--- Get the last modification time of given file path in Unix epoch format. +-- @param path String containing the path of the file or directory to read +-- @return Number containing the epoch time or nil on error +-- @return String containing the error description (if any) +-- @return Number containing the os specific errno (if any) +function mtime(path) + return fs.stat(path, "mtime") +end + +--- Set the last modification time of given file path in Unix epoch format. +-- @param path String containing the path of the file or directory to read +-- @param mtime Last modification timestamp +-- @param atime Last accessed timestamp +-- @return 0 in case of success nil on error +-- @return String containing the error description (if any) +-- @return Number containing the os specific errno (if any) +function utime(path, mtime, atime) + return fs.utimes(path, atime, mtime) +end + +--- Return the last element - usually the filename - from the given path with +-- the directory component stripped. +-- @class function +-- @name basename +-- @param path String containing the path to strip +-- @return String containing the base name of given path +-- @see dirname +basename = fs.basename + +--- Return the directory component of the given path with the last element +-- stripped of. +-- @class function +-- @name dirname +-- @param path String containing the path to strip +-- @return String containing the directory component of given path +-- @see basename +dirname = fs.dirname + +--- Return a table containing all entries of the specified directory. +-- @class function +-- @name dir +-- @param path String containing the path of the directory to scan +-- @return Table containing file and directory entries or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +function dir(...) + local iter, code, msg = fs.dir(...) + if iter then + local t = nutil.consume(iter) + t[#t+1] = "." + t[#t+1] = ".." + return t + else + return nil, code, msg + end +end + +--- Create a new directory, recursively on demand. +-- @param path String with the name or path of the directory to create +-- @param recursive Create multiple directory levels (optional, default is true) +-- @return Number with the return code, 0 on sucess or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +function mkdir(path, recursive) + return recursive and fs.mkdirr(path) or fs.mkdir(path) +end + +--- Remove the given empty directory. +-- @class function +-- @name rmdir +-- @param path String containing the path of the directory to remove +-- @return Number with the return code, 0 on sucess or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +rmdir = fs.rmdir + +local stat_tr = { + reg = "regular", + dir = "directory", + lnk = "link", + chr = "character device", + blk = "block device", + fifo = "fifo", + sock = "socket" +} +--- Get information about given file or directory. +-- @class function +-- @name stat +-- @param path String containing the path of the directory to query +-- @return Table containing file or directory properties or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +function stat(path, key) + local data, code, msg = fs.stat(path) + if data then + data.mode = data.modestr + data.type = stat_tr[data.type] or "?" + end + return key and data and data[key] or data, code, msg +end + +--- Set permissions on given file or directory. +-- @class function +-- @name chmod +-- @param path String containing the path of the directory +-- @param perm String containing the permissions to set ([ugoa][+-][rwx]) +-- @return Number with the return code, 0 on sucess or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +chmod = fs.chmod + +--- Create a hard- or symlink from given file (or directory) to specified target +-- file (or directory) path. +-- @class function +-- @name link +-- @param path1 String containing the source path to link +-- @param path2 String containing the destination path for the link +-- @param symlink Boolean indicating wheather to create a symlink (optional) +-- @return Number with the return code, 0 on sucess or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +function link(src, dest, sym) + return sym and fs.symlink(src, dest) or fs.link(src, dest) +end + +--- Remove the given file. +-- @class function +-- @name unlink +-- @param path String containing the path of the file to remove +-- @return Number with the return code, 0 on sucess or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +unlink = fs.unlink + +--- Retrieve target of given symlink. +-- @class function +-- @name readlink +-- @param path String containing the path of the symlink to read +-- @return String containing the link target or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +readlink = fs.readlink