文档章节

OpenWrt luci添加上传下载及网络摄像头功能

娱乐你我
 娱乐你我
发布于 2014/10/11 09:51
字数 1113
阅读 4408
收藏 4

       花了几天时间给OpenWrt弄了个上传下载及网络摄像头功能。对lua及luci不熟,时间花的有点多。此软件包是纯luci应用,可以安装在任意平台,网络摄像头要依赖mjpg-streamer。效果图如下:

主要源码如下:

controller/updownload.lua文件:

--[[
Other module
Description: File upload / download, web camera
Author: yuleniwo  xzm2@qq.com  QQ:529698939
]]--

module("luci.controller.other", package.seeall)

function index()
	local page = entry({"admin", "system", "other"}, alias("admin", "system", "other", "updownload"), _("Other"), 89)
	entry({"admin", "system", "other", "updownload"}, form("updownload"), _("Upload / Download"))
	if nixio.fs.access("/etc/config/mjpg-streamer") then
		entry({"admin", "system", "other", "webcam"}, call("Webcam"), _("Web Camera"))
	end
	page.i18n = "other"
	page.dependent = true
end

local translate = luci.i18n.translate
local http = luci.http

function Webcam()
	local iframe = '<iframe src="http://%s:%s@%s:%s" frameborder="no" border="0" width="800" height="600" marginwidth="0" marginheight="0" allowtransparency="yes"></iframe>'
	local html, msg, status
	local act = http.formvalue("act")
	if act then
		if act == "start" then
			luci.sys.call("/etc/init.d/mjpg-streamer start")
		elseif act == "stop" then
			luci.sys.call("/etc/init.d/mjpg-streamer stop")
			luci.sys.call("sleep 1")
		end
	end
	local v = nixio.fs.glob("/dev/video[0-9]")()
	if v then
		if luci.sys.call("pidof mjpg_streamer > /dev/null") == 0 then
			local uci, user, pwd, ip, port
			uci = require "luci.model.uci".cursor()
			user = uci:get("mjpg-streamer", "core", "username")
			pwd = uci:get("mjpg-streamer", "core", "password")
			ip = uci:get("network", "lan", "ipaddr")
			port = uci:get("mjpg-streamer", "core", "port")
			html = string.format(iframe, user, pwd, ip, port)
			status = true
		else
			status = false
			msg = translate("Service 'mjpg_streamer' not started.")
		end
	else
		msg = translate("Video device not found.")
	end
	luci.template.render("webcam", {html = html, msg = msg, status = status})
end

model/cbi/updownload.lua文件:

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
			fd = nixio.open(dir .. meta.file, "w")
			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('<span style="color: red">%s</span>', r)
end

return ful, fdl, form

view/cbi/other_button.htm文件:

<%+cbi/valueheader%>
	<% if self:cfgvalue(section) ~= false then %>
		<input class="cbi-button cbi-input-<%=self.inputstyle or "button" %>" style="display: <%= display %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> />
	<% else %>
		-
	<% end %>
<%+cbi/valuefooter%>

view/cbi/other_dvalue.htm文件:

<%+cbi/valueheader%>
<span style="color: red">
<%
	local val = self:cfgvalue(section) or self.default or ""
	write(pcdata(val))
%>
</span>
<%+cbi/valuefooter%>

view/cbi/other_upload.htm文件:

<%+cbi/valueheader%>
	<label class="cbi-value" style="display:inline-block; width: 80px" for="ulfile"><%:Upload file:%></label>
	<input class="cbi-input-file" style="width: 400px" type="file" id="ulfile" name="ulfile" />
	<input type="submit" class="cbi-button cbi-input-apply" name="upload" value="<%:Upload%>" />
<%+cbi/valuefooter%>

view/cbi/other_download.htm文件:

<%+cbi/valueheader%>
	<label class="cbi-value" style="display:inline-block; width: 80px" for="dlfile"><%:Download file:%></label>
	<input class="cbi-input-file" style="width: 400px" type="text" id="dlfile" name="dlfile" />
	<input type="submit" class="cbi-button cbi-input-apply" name="download" value="<%:Download%>" />
<%+cbi/valuefooter%>

view/webcam.htm文件:

<%+header%>
<div class="cbi-section-error"<% if not msg then %> style="display:none"<% end %>><%=msg%></div>
<form method="post" action="<%=REQUEST_URI%>"<%if status == nil then %> style="display:none"<% end %>>
	<div class="cbi-section-node">
		<div class="cbi-value cbi-value-last">
			<input type="hidden" name="act" value="<% if status then write('stop') else write('start') end %>" />
			<div class="cbi-value-field">
				<input class="cbi-button cbi-input-<% if status then write('remove') else write('apply') end %>" type="submit" value="<% if status then write(translate('Stop')) else write(translate('Start')) end %>" />
			</div>
		</div>
	</div>
</form>
<div style="text-align: center">
	<% if html then write(html) end %>
</div>
<%+footer%>

为了使添加的软件包能在openwrt源码make menuconfig时识别出来,需要在./feeds/luci/contrib/package/luci/Makefile增加如下语句:

$(eval $(call application,other,luci my other application))


软件包下载地址:luci-app-other_0.12.ipk

完整源码下载地址:luci-other_src.tar.gz

© 著作权归作者所有

娱乐你我
粉丝 39
博文 32
码字总数 23759
作品 0
福州
程序员
私信 提问
加载中

评论(3)

娱乐你我
娱乐你我 博主

引用来自“狼圖騰”的评论

楼主啊,,
root@OpenWrt :/# opkg install ./luci-app-other_0.12.ipk
Unknown package 'luci-app-other'.
Collected errors:
* pkg_hash_fetch_best_installation_candidate: Packages for luci-app-other found, but incompatible with the architectures configured
* opkg_install_cmd: Cannot install package luci-app-other.
这是啥意思3
加--force-depends参数试试。如果还不行,可以直接编译进你的固件里(这个软件适用于BB版本的openwrt)。
狼圖騰
狼圖騰
楼主啊,,
root@OpenWrt :/# opkg install ./luci-app-other_0.12.ipk
Unknown package 'luci-app-other'.
Collected errors:
* pkg_hash_fetch_best_installation_candidate: Packages for luci-app-other found, but incompatible with the architectures configured
* opkg_install_cmd: Cannot install package luci-app-other.
这是啥意思3
OpenWrt系列教程汇总 & OpenWrt简体中文Wiki

OpenWrt系列教程汇总 OpenWrt简体中文Wiki 快速导航

AlphaJay
2011/07/26
42.7K
1
OpenWrt学习目标(更新)

最近在研究OpenWrt,总感觉这一看一点那也了解一点,没有目的,也没有重心。 这里,给自己拟定一个目标,就朝着这个目标去学。 目标:在OpenWrt上开发服务器软件,该软件可以通过LuCI进行控制...

临峰不畏
2015/05/01
3.6K
8
Ubuntu 12.04下编译Openwrt教程 推荐

搭建编译环境 Ubuntu x64 12.04下的命令: sudo apt-get install subversion sudo apt-get install git sudo apt-get install flex sudo apt-get install g++ sudo apt-get install gawk su......

枫影Xda
2012/10/30
9.1K
1
移植OpenWrt到RT5350

slider >>> Too few posts! (required minimum are 3) (the featured image may be missing) Previous 移植OpenWrt到CuHead Pro WiFi Posted by: zou, baozhu , 三月 13, 2014 CuHead Pro是一......

Pillar_zuo
2014/03/13
23.3K
5
极路由4刷OpenWrt(LEDE)

申请开发者模式 登录路由器后台 进入插件中间 选中路由器信息 申请开发者权限 安装开发者插件 刷 Bootloader 下载 的 Breed 通过SSH登录路由器 (必须安装开发者插件,端口 账号 密码 ) 通过...

dingdayu
02/24
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

nginx+tomcat配置https

1、nginx配置https和【proxy_set_header X-Forwarded-Proto $scheme;】 2、java代码: String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServe......

perofu
32分钟前
4
0
必看的Linux系统新手进阶老手心得

不知道从什么时候起,linux这个话题变得越来越普及,成为大家经常讨论的话题。无论在网络上还是实际生活中,竟然很多人都在纠结学习linux的问题。网络上给的答案千千万万,而却还有很多人踌躇...

Linux就该这么学
35分钟前
4
0
Spring Boot 配置元数据指南

1. 概览 在编写 Spring Boot 应用程序时,将配置属性映射到 Java bean 上是非常有用的。但是,记录这些属性的最好方法是什么呢? 在本教程中,我们将探讨 Spring Boot Configuration Proces...

liululee
38分钟前
3
0
foreach查找子类

$list = $menu_model -> menu_list();$parent_list = [];foreach ($list as $v){ if ($v['pid'] == 0) { $parent = $v; foreach ($list as $v1) ......

小小小壮
50分钟前
3
0
基于 HTML5 Canvas 实现的 TP-LINK 电信拓扑设备面板

前言 今天我们以真实的 TP-LINK 设备面板为模型,完成设备面板的搭建,和指示灯的闪烁和图元流动。 先来目睹下最终的实现效果:http://www.hightopo.com/demo/blog_tplink_20170511/index.h...

htdaydayup
56分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部