diff options
Diffstat (limited to 'applications/luci-app-opkg/luasrc')
-rw-r--r-- | applications/luci-app-opkg/luasrc/controller/opkg.lua | 100 | ||||
-rw-r--r-- | applications/luci-app-opkg/luasrc/view/opkg.htm | 140 |
2 files changed, 240 insertions, 0 deletions
diff --git a/applications/luci-app-opkg/luasrc/controller/opkg.lua b/applications/luci-app-opkg/luasrc/controller/opkg.lua new file mode 100644 index 0000000000..74aa166184 --- /dev/null +++ b/applications/luci-app-opkg/luasrc/controller/opkg.lua @@ -0,0 +1,100 @@ +-- Copyright 2018 Jo-Philipp Wich <jo@mein.io> +-- Licensed to the public under the Apache License 2.0. + +module("luci.controller.opkg", package.seeall) + +function index() + entry({"admin", "system", "opkg"}, template("opkg"), _("Software"), 30) + entry({"admin", "system", "opkg", "list"}, call("action_list")).leaf = true + entry({"admin", "system", "opkg", "exec"}, post("action_exec")).leaf = true + entry({"admin", "system", "opkg", "statvfs"}, call("action_statvfs")).leaf = true + entry({"admin", "system", "opkg", "config"}, post_on({ data = true }, "action_config")).leaf = true +end + +function action_list(mode) + local cmd + + if mode == "installed" then + cmd = { "/bin/cat", "/usr/lib/opkg/status" } + else + cmd = { "/bin/sh", "-c", [[find /tmp/opkg-lists/ -type f '!' -name '*.sig' | xargs -r gzip -cd]] } + end + + luci.http.prepare_content("text/plain; charset=utf-8") + luci.sys.process.exec(cmd, luci.http.write) +end + +function action_exec(command, package) + local sys = require "luci.sys" + local cmd = { "/bin/opkg", "--force-removal-of-dependent-packages", "--force-overwrite" } + local pkg = luci.http.formvalue("package") + + if luci.http.formvalue("autoremove") == "true" then + cmd[#cmd + 1] = "--autoremove" + end + + cmd[#cmd + 1] = command + + if pkg then + cmd[#cmd + 1] = pkg + end + + luci.http.prepare_content("application/json") + luci.http.write_json(sys.process.exec(cmd, true, true)) +end + +function action_statvfs() + local fs = require "nixio.fs" + + luci.http.prepare_content("application/json") + luci.http.write_json(fs.statvfs("/") or {}) +end + +function action_config() + local fs = require "nixio.fs" + local js = require "luci.jsonc" + local data = luci.http.formvalue("data") + + if data then + data = js.parse(data) + + if not data then + luci.http.status(400, "Bad Request") + return + end + + local file, content + for file, content in pairs(data) do + if type(content) ~= "string" or + (file ~= "opkg.conf" and not file:match("^opkg/[^/]+%.conf$")) + then + luci.http.status(400, "Bad Request") + return + end + + local path = "/etc/%s" % file + if not fs.access(path, "w") then + luci.http.status(403, "Permission denied") + return + end + + fs.writefile(path, content:gsub("\r\n", "\n")) + end + + luci.http.status(204, "Saved") + else + local rv = { ["opkg.conf"] = fs.readfile("/etc/opkg.conf") } + local entries = fs.dir("/etc/opkg") + if entries then + local entry + for entry in entries do + if entry:match("%.conf$") then + rv["opkg/%s" % entry] = fs.readfile("/etc/opkg/%s" % entry) + end + end + end + + luci.http.prepare_content("application/json") + luci.http.write_json(rv) + end +end diff --git a/applications/luci-app-opkg/luasrc/view/opkg.htm b/applications/luci-app-opkg/luasrc/view/opkg.htm new file mode 100644 index 0000000000..0d2a4e2920 --- /dev/null +++ b/applications/luci-app-opkg/luasrc/view/opkg.htm @@ -0,0 +1,140 @@ +<%# + Copyright 2018 Jo-Philipp Wich <jo@mein.io> + Licensed to the public under the Apache License 2.0. +-%> + +<%+header%> + +<style type="text/css"> + .controls { + display: flex; + margin: .5em 0 1em 0; + flex-wrap: wrap; + justify-content: space-around; + } + + .controls > * { + padding: .25em; + white-space: nowrap; + flex: 1 1 33%; + box-sizing: border-box; + display: flex; + flex-wrap: wrap; + } + + .controls > *:first-child, + .controls > * > label { + flex-basis: 100%; + min-width: 250px; + } + + .controls > * > .btn { + flex-basis: 20px; + text-align: center; + } + + .controls > * > * { + flex-grow: 1; + align-self: center; + } + + .controls > div > input { + width: auto; + } + + .td.version, + .td.size { + white-space: nowrap; + } + + ul.deps, ul.deps ul, ul.errors { + margin-left: 1em; + } + + ul.deps li, ul.errors li { + list-style: none; + } + + ul.deps li:before { + content: "↳"; + display: inline-block; + width: 1em; + margin-left: -1em; + } + + ul.deps li > span { + white-space: nowrap; + } + + ul.errors li { + color: #c44; + font-size: 90%; + font-weight: bold; + padding-left: 1.5em; + } + + ul.errors li:before { + content: "⚠"; + display: inline-block; + width: 1.5em; + margin-left: -1.5em; + } +</style> + +<h2><%:Software%></h2> + +<div class="controls"> + <div> + <label><%:Free space%>:</label> + <div class="cbi-progressbar" title="<%:unknown%>"> + <div> </div> + </div> + </div> + + <div> + <label><%:Filter%>:</label> + <input type="text" name="filter" placeholder="<%:Type to filter…%>"<%=attr("value", luci.http.formvalue("query") or "")%> /><!-- + --><button class="btn cbi-button" onclick="handleReset(event)"><%:Clear%></button> + </div> + + <div> + <label><%:Download and install package%>:</label> + <input type="text" name="install" placeholder="<%:Package name or URL…%>" onkeydown="if (event.keyCode === 13) handleManualInstall(event)" /><!-- + --><button class="btn cbi-button cbi-button-action" onclick="handleManualInstall(event)"><%:OK%></button> + </div> + + <div> + <label><%:Actions%>:</label> + <button class="btn cbi-button-positive" data-command="update" onclick="handleOpkg(event)"><%:Update lists…%></button> +   + <button class="btn cbi-button-neutral" onclick="handleConfig(event)"><%:Configure opkg…%></button> + </div> +</div> + +<ul class="cbi-tabmenu mode"> + <li data-mode="available" class="available cbi-tab"><a href="#"><%:Available%></a></li> + <li data-mode="installed" class="installed cbi-tab-disabled"><a href="#"><%:Installed%></a></li> + <li data-mode="updates" class="installed cbi-tab-disabled"><a href="#"><%:Updates%></a></li> +</ul> + +<div class="controls" style="display:none"> + <div id="pager" class="center"> + <button class="btn cbi-button-neutral prev" aria-label="<%:Previous page%>">«</button> + <div class="text">dummy</div> + <button class="btn cbi-button-neutral next" aria-label="<%:Next page%>">»</button> + </div> +</div> + +<div class="table" id="packages"> + <div class="tr cbi-section-table-titles"> + <div class="th col-2 left"><%:Package name%></div> + <div class="th col-2 left version"><%:Version%></div> + <div class="th col-1 center size"><%:Size (.ipk)%></div> + <div class="th col-10 left"><%:Description%></div> + <div class="th right"> </div> + </div> +</div> + +<script type="text/javascript" src="<%=resource%>/view/opkg.js"></script> + +<%+footer%> |