Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate luci-mod-freifunk to js #54

Merged
merged 5 commits into from
Dec 15, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>

<head>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
crossorigin="" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"
integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
crossorigin="">
</script>
<title>Map</title>
</head>

<body style="margin:0">
<div id="ffmap" style="position:relative; width:100%; height:640px;"></div>
<script type="text/javascript">

var INFINITE = 99.99;

var map = L.map('ffmap').setView([52.48, 12], 13);

var osmUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib = 'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
var osm = new L.TileLayer(osmUrl, { attribution: osmAttrib });
map.addLayer(osm);

var alias = new Array;
var points = new Array;
var unkpos = new Array;
var lineid = 0;
onload = new Function("if(null!=window.ffmapinit)ffmapinit();");
console.log(document.getElementById('mapframe'));

function Mid(mainip, aliasip) {
alias[aliasip] = mainip;
}

function Node(mainip, lat, lon, ishna, hnaip, name) {
points[mainip] = [lat, lon];
var marker = L.circleMarker([lat, lon]).addTo(map);
marker.bindPopup(
'Node: ' + name
+
'<br>IP: ' + mainip
+ '<br>DefGW: ' + hnaip
);
}

function Self(mainip, lat, lon, ishna, hnaip, name) {
Node(mainip, lat, lon, ishna, hnaip, name);
map.setView([lat, lon], 13)
}

function Link(fromip, toip, lq, nlq, etx) {
if (0 == lineid && null != window.ffmapstatic) ffmapstatic();
if (null != alias[toip]) toip = alias[toip];
if (null != alias[fromip]) fromip = alias[fromip];
if (null != points[fromip] && null != points[toip]) {
var color;
var red = 240;
var green = 0;
var blue = 0;
var w = 1

if (etx < 100) { red = 252; green = 102; blue = 0; w = 2 };
if (etx < 10) { red = 255; green = 203; blue = 5; w = 3 };
if (etx < 4) { red = 240; green = 255; blue = 0; w = 4 };
if (etx < 2) { red = 0; green = 204; blue = 0; w = 5 };
if (etx < 1) { red = 80; green = 0; blue = 0; w = 1 };
var polyline = L.polyline([points[fromip], points[toip]], {
color:
'rgb(' + red + ', ' + green + ', ' + blue + ')'
})
.addTo(map);
polyline.bindPopup(
fromip + " - " + toip + "<br>"
+ "ETX: " + etx + "<br>"
+ "LQ: " + lq + "<br>"
+ "NLQ: " + nlq + "<br>"
);


}
else {
if (null == points[toip]) unkpos[toip] = '';
if (null == points[fromip]) unkpos[fromip] = '';
}
lineid++;
}

function PLink(fromip, toip, lq, nlq, etx, lata, lona, ishnaa, latb, lonb, ishnab) {
Link(fromip, toip, lq, nlq, etx);
}

function ffmapinit() {
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "/ubus/?" + Date.now(), true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onload = () => {
if (xhttp.status >= 200 && xhttp.status < 300) {
// parse JSON and
const response = JSON.parse(xhttp.responseText);
response[0].result[1].data.split(/\n/).forEach((line) => {
eval(line);
})
} else {
console.log("error getting latlon data from router")
}

};
var data = [{ "jsonrpc": "2.0", "id": 1, "method": "call", "params": ["00000000000000000000000000000000", "ffmap", "getdata", {}] }];
xhttp.send(JSON.stringify(data));



/* <%
local fd
local uci = require "luci.model.uci".cursor()

uci:foreach("olsrd", "LoadPlugin", function(s)
if s.library == "olsrd_nameservice" and s.latlon_file then
fd = io.open(s.latlon_file)
end
end)

if fd then
local data = fd:read("*a")
fd:close()

if data then
local line
for line in data:gmatch("[^\n]+") do
if line:match(";$") then
write(line .. "\n")
else
break
end
end
end
end
%>*/
}


</script>
</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use strict';
'require view';
'require form';
'require fs';
'require uci';

return view.extend({
load: () => {
return Promise.all([
fs.list('/etc/config/').then((configs) => {
let communities = configs
.filter(file => file.name.startsWith('profile_'));
return communities;
}).then((communities) => {
communities.forEach(community => {
uci.load(community.name);
});
return communities;
})
])
},
render: (communities) => {
let communityMap, communitySection, communityOption;

communityMap = new form.Map('freifunk', _('Community'));

communitySection = communityMap.section(form.NamedSection, 'community', 'public', null, _('These are the basic settings for your local wireless community. These settings define the default values for the wizard and DO NOT affect the actual configuration of the router.'));

communityOption = communitySection.option(form.ListValue, 'name', _('Community'));
communityOption.rmempty = false;
communities[0].forEach(community => {
let communityName = uci.get_first(community.name, 'community', 'name');
communityOption.value(community.name.replace('profile_', ''), communityName);
});

let systemMap, systemSection, option;

systemMap = new form.Map('system', _('Basic system settings'));

systemSection = systemMap.section(form.TypedSection, 'system');
systemSection.anonymous = true;

option = systemSection.option(form.Value, 'hostname', _('Hostname'));
option.rmempty = false;

option = systemSection.option(form.Value, 'location', _('Location'));
option.optional = true;
option.rmempty = false;

option = systemSection.option(form.Value, 'latitude', _('Latitude'), _('e.g.') + ' 48.12345');
option.optional = true;
option.rmempty = false;

option = systemSection.option(form.Value, 'longitude', _('Longitude'), _('e.g.') + ' 10.12345');
option.optional = true;
option.rmempty = false;


return Promise.all([communityMap.render(), systemMap.render()]);
}
})

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';
'require view';
'require form';

return view.extend({
render: () => {
let freifunkMap, contactSection;

freifunkMap = new form.Map('freifunk', _('Contact'),
_('Please fill in your contact details below.'));

contactSection = freifunkMap.section(form.NamedSection, 'contact', 'public', '');

contactSection.option(form.Value, 'nickname', _('Nickname'));

contactSection.option(form.Value, 'name', _('Realname'));

contactSection.option(form.DynamicList, 'homepage', _('Homepage'));

contactSection.option(form.Value, 'mail', _('E-Mail'));

contactSection.option(form.Value, 'phone', _('Phone'));

contactSection.option(form.TextValue, 'note', _('Notice'));

return freifunkMap.render();

}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict';
'require uci';
'require view';

return view.extend({
handleReset: null,
handleSave: null,
handleSaveApply: null,
load: () => {
return Promise.all([
uci.load('freifunk'),
uci.load('system')
])
},
render: () => {
let nickname = uci.get('freifunk', 'contact', 'nickname');
let name = uci.get('freifunk', 'contact', 'name');
let mail = uci.get('freifunk', 'contact', 'mail');
let contacturl = L.url('admin/freifunk/contact');
let hostname = uci.get_first('system', 'system', 'hostname');
let latitude = uci.get_first('system', 'system', 'latitude');
let longitude = uci.get_first('system', 'system', 'longitude');
let location = uci.get_first('system', 'system', 'location');
let basicsurl = L.url('admin/freifunk/basics');
let basicSettingsWarning = (hostname == null || latitude == null || longitude == null)? E('div', {'class': 'label warning'}, [
_('Basic settings are incomplete. Please go to'),
' ',
E('a', {'href': basicsurl}, _('Basic settings')),
' ',
_('and fill out all required fields.'),
E('p')
]): E([]);
let contactWarning = (nickname == null && name == null && email == null)? E('div', {'class': 'label warning'}, [
_('Contact information is incomplete. Please go to'),
' ',
E('a', {'href': contacturl}, _('Contact')),
' ',
_('and fill out all required fields.'),
E('p')
]): E([]);
return E([], {}, [
E('h2', {}, _('Freifunk Overview')),
_('These pages will assist you in setting up your router for Freifunk or similar wireless community networks.'),
E('p'),
basicSettingsWarning,

]);
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
'use strict';
'require view';
'require uci';
'require form';

return view.extend({
load: () => {
return Promise.all([
uci.load('freifunk').then(() => {
let communityName = uci.get('freifunk', 'community', 'name');
uci.load('profile_' + communityName);
return communityName;
}),
])
},
render: (data) => {
let communityName = data[0];
if (communityName == null) {
const errorUrl = L.url('admin/freifunk/profile_error');
window.location.replace(errorUrl);
return;
}
let profileMap, profileSection, o;

profileMap = new form.Map('profile_' + communityName, _('Community settings'),
_('These are the settings of your local community.'));

profileSection = profileMap.section(form.NamedSection, 'profile', 'community');

let name = profileSection.option(form.Value, 'name', 'Name');
name.rmempty = false;

profileSection.option(form.Value, 'homepage', _('Homepage'));

let countryCode = profileSection.option(form.Value, 'country', _('Country code'));
countryCode.cfgvalue = () => {
return uci.get('profile_' + communityName, 'wifi_device', 'country');
};
countryCode.write = (sectionId, value) => {
if (value) {
uci.set('profile_' + communityName, 'wifi_device', 'country', value);
uci.save('profile_' + communityName);
}
};

let ssid = profileSection.option(form.Value, 'ssid', _('ESSID'));
ssid.rmempty = false;

let meshNet = profileSection.option(form.Value, 'mesh_network', _('Mesh prefix'));
meshNet.datatype = 'ip4addr';
meshNet.rmempty = false;

let splashNet = profileSection.option(form.Value, 'splash_network', _('Network for client DHCP addresses'));
splashNet.datatype = 'ip4addr';
splashNet.optional = true;
splashNet.rmempty = false;

let splashPrefix = profileSection.option(form.Value, 'splash_prefix', _('Client network size'));
splashPrefix.datatype = 'range(0,32)';
splashPrefix.optional = true;
splashPrefix.rmempty = false;

profileSection.option(form.Flag, 'ipv6', _('Enable IPv6'));

let ipv6Config = profileSection.option(form.ListValue, 'ipv6_config', _('IPv6 Config'));
ipv6Config.depends('ipv6', '1');
ipv6Config.value('static');

let ipv6Prefix = profileSection.option(form.Value, 'ipv6_prefix', _('IPv6 Prefix'), _('IPv6 network in CIDR notation.'));
ipv6Prefix.datatype = 'ip6addr';
ipv6Prefix.depends('ipv6', '1');

profileSection.option(form.Flag, 'vap', _('VAP'), _('Enable a virtual access point (VAP) by default if possible.'));

let latitude = profileSection.option(form.Value, 'latitude', _('Latitude'));
latitude.datatype = 'range(-180,180)';
latitude.rmempty = false;

let longitude = profileSection.option(form.Value, 'longitude', _('Longitude'));
longitude.rmempty = false;

return profileMap.render();
}
});
Loading