luci-app-olsr-services: migrate to js
authorAndreas Bräu <ab@andi95.de>
Tue, 26 Oct 2021 22:46:28 +0000 (00:46 +0200)
committerAndreas Bräu <ab@andi95.de>
Tue, 26 Oct 2021 22:49:07 +0000 (00:49 +0200)
Signed-off-by: Andreas Bräu <ab@andi95.de>
applications/luci-app-olsr-services/htdocs/luci-static/resources/view/freifunk-services/services.js [new file with mode: 0644]
applications/luci-app-olsr-services/luasrc/controller/services.lua [deleted file]
applications/luci-app-olsr-services/luasrc/view/freifunk-services/services.htm [deleted file]
applications/luci-app-olsr-services/root/usr/libexec/rpcd/olsr-services [new file with mode: 0755]
applications/luci-app-olsr-services/root/usr/share/luci/menu.d/luci-app-olsr-services.json [new file with mode: 0644]
applications/luci-app-olsr-services/root/usr/share/rpcd/acl.d/luci-app-olsr-services.json [new file with mode: 0644]

diff --git a/applications/luci-app-olsr-services/htdocs/luci-static/resources/view/freifunk-services/services.js b/applications/luci-app-olsr-services/htdocs/luci-static/resources/view/freifunk-services/services.js
new file mode 100644 (file)
index 0000000..3a3d11a
--- /dev/null
@@ -0,0 +1,82 @@
+'use strict';
+'require rpc';
+'require view';
+'require poll';
+
+const tableHead = '<div class="tr cbi-section-table-titles">' +
+    '<div class="th cbi-section-table-cell">' + _('Url') + '</div>' +
+    '<div class="th cbi-section-table-cell">' + _('Protocol') + '</div>' +
+    '<div class="th cbi-section-table-cell">' + _('Source') + '</div>' +
+    '</div>';
+
+var getOlsrd4Services = rpc.declare({
+    object: 'olsr-services',
+    method: 'services4',
+    expect: {}
+});
+
+var getOlsrd6Services = rpc.declare({
+    object: 'olsr-services',
+    method: 'services6',
+    expect: {}
+});
+
+function updateServicesTable(servicesArray) {
+    var table = document.getElementById("olsr_services");
+    var tempElement = document.createElement('div');
+    tempElement.innerHTML = tableHead;
+    table.replaceChildren(tempElement.firstChild);
+    servicesArray.forEach(function (service, index) {
+        var node = document.createElement('div');
+        var index = 1 + index % 2;
+        var sourceUrl = service.isIpv6 ? '[' + service.source + ']' : service.source;
+        node.classList.add('tr', 'cbi-section-table-row', 'cbi-rowstyle-' + index);
+        node.innerHTML =
+            '<div class="td cbi-section-table-cell left"><a href="' + service.url + '">' + service.description + '</a></div>' +
+            '<div class="td cbi-section-table-cell left">' + service.protocol + '</div>' +
+            '<div class="td cbi-section-table-cell left"><a href="http://' + sourceUrl + '/cgi-bin-status.html">' + service.source + '</a></div>';
+        table.appendChild(node);
+    });
+}
+
+function extractServiceInformation(results) {
+    var servicesArray = [];
+    results.forEach(function(result) {
+        if (result.configured && result.services != "") {
+            var isIpv6 = result.source == "olsrd6";
+            var services = result.services.split('\n');
+            services.forEach(function (service) {
+                var source = service.split('#')[1];
+                var serviceRawDescription = service.replace(/\t/g, '').split('#')[0].split('|');
+                var url = serviceRawDescription[0];
+                var protocol = serviceRawDescription[1];
+                var description = serviceRawDescription[2];
+                servicesArray.push({ "source": source, "url": url, "protocol": protocol, "description": description, "isIpv6": isIpv6 });
+            });
+        }
+    });
+    return servicesArray;
+}
+
+return view.extend({
+    handleSaveApply: null,
+    handleSave: null,
+    handleReset: null,
+    render: function (data) {
+        poll.add(function () {
+            Promise.all([getOlsrd4Services(), getOlsrd6Services()]).then(function (results) {
+                var servicesArray = extractServiceInformation(results);
+                updateServicesTable(servicesArray);
+            });
+        }, 30);
+        return E([], {}, [
+            E('h2', { 'name': 'content' }, [_('Services')]),
+            E('legend', {}, [_('Internal services')]),
+            E('fieldset', { 'class': 'cbi-section' }, [
+                E('div', { 'class': 'table cbi-section-table', 'id': 'olsr_services' }, [
+                    E(tableHead)
+                ])
+            ]),
+        ]);
+    }
+});
diff --git a/applications/luci-app-olsr-services/luasrc/controller/services.lua b/applications/luci-app-olsr-services/luasrc/controller/services.lua
deleted file mode 100644 (file)
index 7a543d3..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-module "luci.controller.services"
-
-function index()
-       local uci = require "luci.model.uci".cursor()
-
-       uci:foreach("olsrd", "LoadPlugin", function(s)
-               if s.library == "olsrd_nameservice" then
-                       has_serv = true
-               end
-       end)
-
-       if has_serv then
-               entry({"freifunk", "services"}, template("freifunk-services/services"), _("Services"), 60)
-       end
-end
-
diff --git a/applications/luci-app-olsr-services/luasrc/view/freifunk-services/services.htm b/applications/luci-app-olsr-services/luasrc/view/freifunk-services/services.htm
deleted file mode 100644 (file)
index 0aac36d..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-<%#
- Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
- Licensed to the public under the Apache License 2.0.
--%>
-
-<%
-local fs  = require "nixio.fs"
-local utl = require "luci.util"
-local last_update
-local i = 1
-local rawdata
-local rawdata6
-local services_file_empty = true
-local has_services = false
-local uci = require "luci.model.uci".cursor()
-local ip = require "luci.ip"
-
-uci:foreach("olsrd", "LoadPlugin", function(s)
-       if s.library == "olsrd_nameservice" then
-               local services_file=s.services_file
-               if services_file and fs.access(services_file) then
-                       has_services = true
-                       rawdata = fs.readfile(s.services_file)
-               else
-                       services_file="/var/run/services_olsr"
-                       if fs.access(services_file) then
-                               has_services = true
-                               rawdata = fs.readfile(services_file)
-                       end
-               end
-               services_file=services_file..".ipv6"
-               if services_file and fs.access(services_file) then
-                       has_services = true
-                       rawdata6 = fs.readfile(services_file)
-               else
-                       services_file="/var/run/services_olsr.ipv6"
-                       if fs.access(services_file) then
-                               has_services = true
-                               rawdata6 = fs.readfile(services_file)
-                       end
-               end
-               if rawdata and #rawdata ~= 0 then
-                       services_file_empty = nil
-               end
-               if rawdata6 and #rawdata6 ~= 0 then
-                       services_file_empty = nil
-               end
-       end
-end)
-
-
-if not has_services or services_file_empty then
-%>
-       <%+header%>
-       <br />
-       <%:No services can be shown, because olsrd is not running or the olsrd-nameservice Plugin is not loaded.%>
-       <%+footer%>
-<%
-       return
-end
-
-function fetch_services()
-       local tables = {}
-       if rawdata and #rawdata ~= 0 then
-               tables = utl.split(utl.trim(rawdata), "\n", nil, true)
-               -- remove first 3 lines
-               for i = 1,3 do
-                       table.remove(tables,1)
-               end
-       end
-       local tables6 = {}
-       if rawdata6 and #rawdata6 ~= 0 then
-               tables6 = utl.split(utl.trim(rawdata6), "\n", nil, true)
-               -- remove first 3 lines
-               for i = 1,3 do
-                       table.remove(tables6,1)
-               end
-       end
-
-       -- store last line in last_update and remove it, then remove another empty line at the end
-       last_update=table.remove(tables)
-       table.remove(tables)
-       last_update=table.remove(tables6)
-       table.remove(tables6)
-       for k, v in ipairs(tables6) do
-               table.insert(tables, v)
-       end
-       return tables
-end
-local services = fetch_services()
-
-if luci.http.formvalue("status") == "1" then
-       local rv = {}
-       for k, line in ipairs(services) do
-               local field = utl.split(line, "[#|]", split, true)
-               local origin_lnk = ip.IPv6(pcdata(field[4]))
-               local origin_link = ""
-               if origin_lnk and origin_lnk:is6() then
-                       origin_link = "["..origin_lnk:string().."]"
-               else
-                       origin_link = pcdata(field[4])
-               end
-               local url, proto, descr, origin = pcdata(field[1]), pcdata(field[2]), utl.trim(pcdata(field[3])), pcdata(field[4])
-               rv[#rv+1] = {
-                       url = url,
-                       proto = proto,
-                       origin = origin,
-                       origin_link = origin_link,
-                       descr = descr,
-                       }
-       end
-       luci.http.prepare_content("application/json")
-       luci.http.write_json(rv)
-       return
-end
-
-%>
-
-<%+header%>
-
-<script type="text/javascript">//<![CDATA[
-
-       XHR.poll(10 , '<%=REQUEST_URI%>', { status: 1 },
-               function(x, info)
-               {
-               var tbody = document.getElementById('olsr_services');
-                       if (tbody)
-                       {
-                               var s = '<div class="tr cbi-section-table-titles">' +
-                               '<div class="th cbi-section-table-cell"><%:Url%></div>' +
-                               '<div class="th cbi-section-table-cell"><%:Protocol%></div>' +
-                               '<div class="th cbi-section-table-cell"><%:Source%></div>' +
-                               '</div>';
-
-                               for (var idx = 0; idx < info.length; idx++)
-                               {
-                               var service = info[idx];
-                               s += String.format(
-                                       '<div class="tr cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+'">' +
-                                               '<div class="td cbi-section-table-cell left"><a href="%s">%s</a></div>' +
-                                               '<div class="td cbi-section-table-cell left">%s</div>' +
-                                               '<div class="td cbi-section-table-cell left"><a href="http://%s/cgi-bin-status.html">%s</a></div>' +
-                                       '</div>',
-                                       service.url, service.descr, service.proto, service.origin_link, service.origin || '?'
-                                       );
-                               }
-                               tbody.innerHTML = s;
-                       }
-               }
-       );
-//]]></script>
-       
-
-
-
-       <h2 name="content"><%:Services%></h2>
-
-       <fieldset class="cbi-section">
-       <legend><%:Internal services%></legend>
-       <div class="table cbi-section-table" id="olsr_services">
-                       <div class="tr cbi-section-table-titles">
-                               <div class="th cbi-section-table-cell"><%:Url%></div>
-                               <div class="th cbi-section-table-cell"><%:Protocol%></div>
-                               <div class="th cbi-section-table-cell"><%:Source%></div>
-                       </div>
-
-       <%
-               for k, line in ipairs(services) do
-                       local field = {}
-                       -- split line at # and |, 1=url, 2=proto, 3=description, 4=source
-                       local field = utl.split(line, "[#|]", split, true)
-                       local origin_lnk = ip.IPv6(pcdata(field[4]))
-                       local origin_link
-                       if origin_lnk and origin_lnk:is6() then
-                               origin_link = "["..origin_lnk:string().."]"
-                       else
-                               origin_link = pcdata(field[4])
-                       end
-                       local url, proto, descr, origin = pcdata(field[1]), pcdata(field[2]), utl.trim(pcdata(field[3])), pcdata(field[4])
-                       %>
-
-                       <div class="tr cbi-section-table-row cbi-rowstyle-<%=i%>">
-                               <div class="td cbi-section-table-cell left"><a href="<%=url%>"><%=descr%></a></div>
-                               <div class="td cbi-section-table-cell left"><%=proto%></div>
-                               <div class="td cbi-section-table-cell left"><a href="http://<%=origin_link%>/cgi-bin-status.html"><%=origin%></a></div>
-                       </div>
-                       <% i = ((i % 2) + 1)
-               end %>
-       </div>
-       <br />
-       <%=last_update%>
-       </fieldset>
-<%+footer%>
diff --git a/applications/luci-app-olsr-services/root/usr/libexec/rpcd/olsr-services b/applications/luci-app-olsr-services/root/usr/libexec/rpcd/olsr-services
new file mode 100755 (executable)
index 0000000..4309f9c
--- /dev/null
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+. /usr/share/libubox/jshn.sh
+. /lib/functions.sh
+
+SERVICESFILE="-1"
+
+find_service_config() {
+  local cfg="$1"
+
+  config_get library "$cfg" library
+  if [ "$library" != "olsrd_nameservice" ]; then
+    return 1
+  fi
+  config_get services_file "$cfg" services_file
+  SERVICESFILE=$services_file
+}
+
+load_services() {
+  local olsrd="$1"
+  config_load $olsrd
+  config_foreach find_service_config LoadPlugin
+  local services_configured=0
+  if [ "$SERVICESFILE" != "-1" ]; then
+    services_configured=1
+  fi
+  local services=$(cat $SERVICESFILE|grep -ve "^###"|grep -ve "^$")
+  json_init
+  json_add_boolean configured $services_configured
+  json_add_string source "$olsrd"
+  json_add_string services "$services"
+  echo $(json_dump)
+}
+
+case "$1" in
+  list)
+    # List method must return the list of methods and parameters that the daemon will accept. Only methods listed here will available to call.
+    echo '{ "services4": { }, "services6": { } }'
+  ;;
+  call)
+    case "$2" in
+      services4)
+        echo $(load_services "olsrd")
+      ;;
+      services6)
+        echo $(load_services "olsrd6")
+      ;;
+    esac
+  ;;
+esac
diff --git a/applications/luci-app-olsr-services/root/usr/share/luci/menu.d/luci-app-olsr-services.json b/applications/luci-app-olsr-services/root/usr/share/luci/menu.d/luci-app-olsr-services.json
new file mode 100644 (file)
index 0000000..7559088
--- /dev/null
@@ -0,0 +1,13 @@
+{
+       "freifunk/services": {
+               "title": "Services",
+               "order": 1,
+        "depends": {
+            "uci" : {"olsrd": {"@LoadPlugin": {"library": "olsrd_nameservice"  }}}
+        },
+               "action": {
+                       "type": "view",
+                       "path": "freifunk-services/services"
+               }
+       }
+}
\ No newline at end of file
diff --git a/applications/luci-app-olsr-services/root/usr/share/rpcd/acl.d/luci-app-olsr-services.json b/applications/luci-app-olsr-services/root/usr/share/rpcd/acl.d/luci-app-olsr-services.json
new file mode 100644 (file)
index 0000000..e337f61
--- /dev/null
@@ -0,0 +1,13 @@
+{
+       "unauthenticated": {
+               "description": "Grant access to OLSRd config and services file",
+               "read": {
+                       "ubus": {
+                               "olsr-services": [
+                                       "services4",
+                                       "services6"
+                               ]
+                       }
+               }
+       }
+}
\ No newline at end of file