Commit e065b90d authored by Jan Čermák's avatar Jan Čermák

about page + Nuci module for Stats; short instructions on login page

parent 91b12d9d
......@@ -18,6 +18,8 @@ from bottle import Bottle, request, template
import bottle
from config_handlers import *
import logging
from nuci import client
from nuci.client import filters
from utils import login_required
from collections import OrderedDict
from utils.bottle_csrf import CSRFPlugin
......@@ -66,6 +68,34 @@ class SystemPasswordConfigPage(ConfigPageMixin, SystemPasswordHandler):
pass
class AboutConfigPage(ConfigPageMixin):
template = "config/about"
# {{ _("About") }} - for translation
userfriendly_title = "About"
def _action_registration_code(self):
return client.get_registration()
def call_action(self, action):
"""Call AJAX action.
:param action:
:return: dict of picklable AJAX results
"""
if action == "registration_code":
regnum = self._action_registration_code()
if regnum:
data = regnum.value
else:
data = None
return dict(success=regnum is not None, data=data)
raise ValueError("Unknown AJAX action.")
def render(self, **kwargs):
stats = client.get(filter=filters.stats).find_child("stats")
return self.default_template(stats=stats.data, **kwargs)
class ConfigPageMapItems(OrderedDict):
def display_names(self):
return [{'slug': k, 'name': self[k].userfriendly_title} for k in self.keys()]
......@@ -79,6 +109,7 @@ config_page_map = ConfigPageMapItems((
('lan', LanConfigPage),
('wifi', WifiConfigPage),
('system-password', SystemPasswordConfigPage),
('about', AboutConfigPage),
))
......
......@@ -18,7 +18,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Foris 0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-12-05 15:48+0100\n"
"POT-Creation-Date: 2013-12-06 13:27+0100\n"
"PO-Revision-Date: 2013-10-31 14:43+0100\n"
"Last-Translator: Jan Cermak <jan.cermak@nic.cz>\n"
"Language-Team: Czech <>\n"
......@@ -33,6 +33,13 @@ msgstr "Project:Turris"
msgid "Log out"
msgstr "Odhlásit se"
msgid ""
"Enter your password. If this is the first time you are accessing this "
"administration interface, simply click on the Log in button to continue."
msgstr ""
"Zadejte Vaše heslo. Pokud jste v tomto rozhraní poprvé, pro pokračování "
"jednoduše klikněte na tlačítko Přihlásit se."
msgid "Password"
msgstr "Heslo"
......@@ -61,6 +68,48 @@ msgstr "Zahodit změny"
msgid "Save changes"
msgstr "Uložit změny"
msgid "About"
msgstr "O routeru"
msgid "Device"
msgstr "Zařízení"
msgid "Router Turris - model RTRS01"
msgstr "Router Turris - model RTRS01"
msgid "Kernel version"
msgstr "Verze jádra"
msgid "Device registration"
msgstr "Registrace zařízení"
#, python-format
msgid ""
"If you did not register your device before, click on the following button to "
"obtain a registration code. This code must be submitted on the Turris site "
"in your user profile available at: <a href=\"%(url)s\">%(url)s</a>."
msgstr ""
"Pokud ještě nemáte Vaše zařízení zaregistrované v systému Turris, klikněte "
"na následující tlačítko pro vygenerování registračního kódu. Ten následně "
"vyplňte ve Vašem uživatelském profilu v systému Turris na adrese <a href="
"\"%(url)s\">%(url)s</a>"
msgid "Registration code"
msgstr "Registrační kód"
msgid ""
"Unfortunately, it wasn't possible to generate the registration code. This "
"usually means the router is not connected to the internet. Please, try "
"registering later. If the problem persists, contact the support."
msgstr ""
"Při pokusu o vygenerování registračního kódu bohužel došlo k chybě. To "
"většinou znamená, že Váš router není připojen k internetu. Prosím, zkuste "
"registrační kód vygenerovat později v administračním rozhraní. Pokud problém "
"přetrvává, kontaktujte prosím podporu."
msgid "Get registration code"
msgstr "Získat registrační kód"
msgid "Connection test and check for new updates."
msgstr "Test připojení a kontrola aktualizací"
......@@ -118,9 +167,6 @@ msgstr "Probíhá synchronizace času s internetovým serverem."
msgid "Time was successfully synchronized, you can move to the next step."
msgstr "Čas byl úspěšně synchronizován, můžete postoupit k dalšímu kroku."
msgid "Device registration"
msgstr "Registrace zařízení"
msgid ""
"Device was succesfully installed. Last step that is reqiured is a "
"registration of your device in your user profile on the Turris site <a href="
......@@ -143,23 +189,13 @@ msgid ""
"interface</a>. You can use it to activate LuCI interface for setting the "
"advanced configuration."
msgstr ""
"Jakékoli z předchozích nastavení můžete kdykoli měnit v <a href=\"%(url)s\">"
"konfiguračním rozhraní</a>. Tam také můžete aktivovat rozhraní LuCI pro "
"Jakékoli z předchozích nastavení můžete kdykoli měnit v <a href=\"%(url)s"
"\">konfiguračním rozhraní</a>. Tam také můžete aktivovat rozhraní LuCI pro "
"pokročilé nastavení systému."
msgid "Registration failure"
msgstr "Chyba při registraci"
msgid ""
"Unfortunately, it wasn't possible to generate the registration code. This "
"usually means the router is not connected to the internet. Please, try "
"registering later. If the problem persists, contact the support."
msgstr ""
"Při pokusu o vygenerování registračního kódu bohužel došlo k chybě. To "
"většinou znamená, že Váš router není připojen k internetu. Prosím, zkuste "
"registrační kód vygenerovat později v administračním rozhraní. Pokud problém "
"přetrvává, kontaktujte prosím podporu."
msgid ""
"Set your password for this administation site. The password must be at least "
"6 charaters long."
......
......@@ -22,6 +22,8 @@ import logging
from modules import password as password_module, registration, uci_raw, time, updater
from modules.base import Data, YinElement
from nuci import filters
from nuci.modules import stats
logger = logging.getLogger("nuci.client")
......@@ -45,6 +47,8 @@ def get(filter=None):
reply_data.add(time.Time.from_element(elem))
elif elem.tag == updater.Updater.qual_tag("updater"):
reply_data.add(updater.Updater.from_element(elem))
elif elem.tag == stats.Stats.qual_tag("stats"):
reply_data.add(stats.Stats.from_element(elem))
return reply_data
......@@ -107,7 +111,7 @@ def check_updates():
def get_updater_status():
data = get(filter=ET.Element(updater.Updater.qual_tag("updater")))
data = get(filter=filters.updater)
updater_status = data.find_child("updater")
if updater_status.running:
......
......@@ -19,7 +19,7 @@ This module contains filters used for subtree filtering in nuci client. Filter i
an XML element that is passed to client.get() function and appropriate subtree is returned.
"""
from nuci.modules import time, uci_raw, updater
from nuci.modules import stats, time, uci_raw, updater
import xml.etree.cElementTree as ET
......@@ -27,6 +27,7 @@ import xml.etree.cElementTree as ET
uci = ET.Element(uci_raw.Uci.qual_tag("uci"))
updater = ET.Element(updater.Updater.qual_tag("updater"))
time = ET.Element(time.Time.qual_tag("time"))
stats = ET.Element(stats.Stats.qual_tag("stats"))
# factory for uci configs
......
# Foris - web administration interface for OpenWrt based on NETCONF
# Copyright (C) 2013 CZ.NIC, z.s.p.o. <http://www.nic.cz>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from base import YinElement
from xml.etree import cElementTree as ET
from nuci.utils import unqualify
class Stats(YinElement):
"""Stats element, contains information about runtime data.
Data stored in dictionary Stats.data with following structure:
Stats.data:
-- 'uptime': system uptime (string)
-- 'kernel-version': kernel version (string)
-- 'meminfo': dict of memory information
---- 'MemTotal': total RAM
---- 'MemFree': free RAM
---- etc... (depending on content of meminfo element)
"""
tag = "stats"
NS_URI = "http://www.nic.cz/ns/router/stats"
def __init__(self):
super(Stats, self).__init__()
self.data = {}
@staticmethod
def from_element(element):
stats = Stats()
for elem in element.findall("./*"):
if elem.tag == Stats.qual_tag("uptime"):
stats.data['uptime'] = elem.text
elif elem.tag == Stats.qual_tag("kernel-version"):
stats.data['kernel-version'] = elem.text
elif elem.tag == Stats.qual_tag("meminfo"):
stats.data['meminfo'] = {}
for meminfo_elem in elem:
stats.data['meminfo'][unqualify(meminfo_elem.tag)] = meminfo_elem.text
logging.info(unicode(stats.data))
return stats
@property
def key(self):
return "stats"
def __str__(self):
return "Device stats"
####################################################################################################
ET.register_namespace("stats", Stats.NS_URI)
......@@ -65,9 +65,6 @@ h2
h3
+adjust-font-size-to(26px)
button
border: none
a
color: $highlight-color
......@@ -98,7 +95,13 @@ body, html
width: 60em
.button
/* -------------------------------------------------------------------------
/* Common config interface elements
button
border: none
.button, button
background-color: $button-color
color: #fff
display: inline-block
......@@ -120,6 +123,13 @@ body, html
&:before
background-color: $button-color-active
&.grayed, &[disabled]
background-color: $button-color-grayed
&:hover
background-color: lighten(desaturate($button-color-grayed, 20), 15)
.button-arrow-right
@extend .button
......@@ -136,8 +146,6 @@ body, html
+transform(rotate(45deg))
z-index: -1
/* -------------------------------------------------------------------------
/* Common config interface elements
.button-next
@extend .button-arrow-right
float: right
......@@ -266,6 +274,10 @@ input[type="checkbox"]
padding-top: 2em
text-align: center
p
margin: 0 auto 2em auto
width: 30em
label
display: none
......@@ -347,8 +359,37 @@ input[type="checkbox"]
line-height: 3em
margin-right: 0.5em
&.grayed
background-color: $button-color-grayed
/* -------------------------------------------------------------------------
/* "About" page
#page-about
p
margin-bottom: 1em
table
width: 100%
th, td
padding: 0.2em 0
th
font-weight: bold
#registration-code-update
vertical-align: middle
&:hover
background-color: lighten(desaturate($button-color-grayed, 20), 15)
\ No newline at end of file
#registration-code-loader
vertical-align: middle
#registration-code-fail
border: 1px solid $error-color
color: $error-color
display: none
margin-bottom: 1em
padding: 1em
p:last-child
margin-bottom: 0
#registration-code
font-size: 130%
font-weight: bold
%# Foris - web administration interface for OpenWrt based on NETCONF
%# Copyright (C) 2013 CZ.NIC, z.s.p.o. <http://www.nic.cz>
%#
%# This program is free software: you can redistribute it and/or modify
%# it under the terms of the GNU General Public License as published by
%# the Free Software Foundation, either version 3 of the License, or
%# (at your option) any later version.
%#
%# This program is distributed in the hope that it will be useful,
%# but WITHOUT ANY WARRANTY; without even the implied warranty of
%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%# GNU General Public License for more details.
%#
%# You should have received a copy of the GNU General Public License
%# along with this program. If not, see <http://www.gnu.org/licenses/>.
%#
%rebase config/base **locals()
<div id="page-about">
<h2>{{ _("About") }}</h2>
<table>
<tbody>
<tr>
<th>{{ _("Device") }}</th>
<td>{{ _("Router Turris - model RTRS01") }}</td>
</tr>
<tr>
<th>{{ _("Kernel version") }}</th>
<td>{{ stats['kernel-version'] }}</td>
</tr>
</tbody>
</table>
<h2>{{ _("Device registration") }}</h2>
<div class="about-description">
<p>
{{! _("If you did not register your device before, click on the following button to obtain a registration code. This code must be submitted on the Turris site in your user profile available at: <a href=\"%(url)s\">%(url)s</a>.") % {'url': "https://www.turris.cz/"} }}
</p>
<p>
{{ _("Registration code") }}: <span id="registration-code">????????</span>
</p>
<div id="registration-code-fail">
<p>
{{ _("Unfortunately, it wasn't possible to generate the registration code. This usually means the router is not connected to the internet. Please, try registering later. If the problem persists, contact the support.") }}
</p>
</div>
<button id="registration-code-update" class="button">{{ _("Get registration code") }}</button>
</div>
</div>
<script>
$(document).ready(function() {
$("#registration-code-update").click(function(e) {
var self = $(this);
e.preventDefault();
self.attr("disabled", "disabled");
self.after('<img src="/static/img/icon-loading.gif" id="registration-code-loader" alt="Loading...">');
$.get("/config/about/ajax", {action: "registration_code"})
.done(function(response) {
if (response.success) {
$("#registration-code").text(response.data).show();
$("#registration-code-fail").hide();
}
else {
$("#registration-code").text("????????");
$("#registration-code-fail").show();
}
})
.fail(function() {
$("#registration-code").text("????????");
$("#registration-code-fail").show();
})
.always(function() {
$("#registration-code-loader").remove();
self.removeAttr("disabled");
});
});
});
</script>
......@@ -21,6 +21,7 @@
%if user_authenticated():
<a href="{{ url("logout") }}">{{ _("Log out") }}</a>
%else:
<p>{{ _("Enter your password. If this is the first time you are accessing this administration interface, simply click on the Log in button to continue.") }}</p>
<form action="{{ request.fullpath }}" method="POST">
%if request.GET.get("next"):
<input type="hidden" name="next" value="{{ request.GET['next'] }}">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment