Commit 268a0de0 authored by Štěpán Henek's avatar Štěpán Henek 🌩

sample foris_plugin added

parent dbfea25c
Foris sample plugin
===================
This is a sample plugin for foris
Requirements
============
* foris
* foris-controller-sample-module
Installation
============
``python setup.py install``
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
import bottle
import os
from foris import fapi, validators
from foris.config import ConfigPageMixin, add_config_page
from foris.config_handlers import BaseConfigHandler
from foris.form import Number
from foris.plugins import ForisPlugin
#from foris.state import current_state
from foris.utils.translators import gettext_dummy as gettext, ugettext as _
class SamplePluginConfigHandler(BaseConfigHandler):
userfriendly_title = gettext("Sample")
###
slices = 10
###
def get_form(self):
#data= current_state.backend.perform("sample", "get_slices")
###
data = {"slices": SamplePluginConfigHandler.slices}
###
if self.data:
# Update from post
data.update(self.data)
form = fapi.ForisForm("sample", data)
section = form.add_section(
name="main_section",
title=self.userfriendly_title,
)
section.add_field(
Number, name="slices", label=_("Number of slices"), required=True,
validators=validators.InRange(2, 15)
)
def form_cb(data):
#res = current_state.backend.perform(
# "sample", "set_slices", {"slices": int(data["slices"])})
###
SamplePluginConfigHandler.slices = int(data["slices"])
res = {"result": True}
###
return "save_result", res # store {"result": ...} to be used in SamplePluginPage save() method
form.add_callback(form_cb)
return form
class SamplePluginPage(ConfigPageMixin, SamplePluginConfigHandler):
menu_order = 90 # Where it should be placed in the main menu
template = "sample/sample"
template_type = "jinja2"
def get_backend_data(self):
#data = current_state.backend.perform("sample", "list")
###
import random
res = {
"records":
enumerate([random.randint(0, 100) for _ in range(SamplePluginConfigHandler.slices)])
}
###
return res["records"]
def save(self, *args, **kwargs):
return super(SamplePluginPage, self).save(*args, **kwargs)
def _prepare_render_args(self, args):
args['PLUGIN_NAME'] = SamplePlugin.PLUGIN_NAME
args['PLUGIN_STYLES'] = SamplePlugin.PLUGIN_STYLES
args['PLUGIN_STATIC_SCRIPTS'] = SamplePlugin.PLUGIN_STATIC_SCRIPTS
args['PLUGIN_DYNAMIC_SCRIPTS'] = SamplePlugin.PLUGIN_DYNAMIC_SCRIPTS
args['records'] = self.get_backend_data()
def render(self, **kwargs):
self._prepare_render_args(kwargs)
return super(SamplePluginPage, self).render(**kwargs)
def _action_get_records(self):
records = self.get_backend_data()
return bottle.template(
"sample/_records.html.j2",
records=records,
template_adapter=bottle.Jinja2Template,
)
def call_ajax_action(self, action):
if action == "get_records":
return self._action_get_records()
raise ValueError("Unknown AJAX action.")
class SamplePlugin(ForisPlugin):
PLUGIN_NAME = "sample"
DIRNAME = os.path.dirname(os.path.abspath(__file__))
PLUGIN_STYLES = [
"css/sample.css",
]
PLUGIN_STATIC_SCRIPTS = [
"js/contrib/Chart.bundle.min.js",
"js/sample.js",
]
PLUGIN_DYNAMIC_SCRIPTS = [
"sample.js",
]
def __init__(self, app):
super(SamplePlugin, self).__init__(app)
add_config_page("sample", SamplePluginPage, top_level=True)
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
<title>icon / turris / dark</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Assets" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icon-/-turris-/-dark" fill="#595959">
<polygon id="Path" points="6.33888735 0 0 11 5.06435376 11 8.87106423 4.39428334 16.4675949 4.39428334 19 0"></polygon>
<polygon id="Path" points="14 11.9925632 20.4310855 23 23 18.6028832 19.1380606 11.9925632 22.9914323 5.39711679 20.4222863 1"></polygon>
<polygon id="Path" points="12.6666667 13 12.6497839 13 0 13 2.53105187 17.3998626 10.1413184 17.3998626 13.9378963 24 19 24 12.6723703 13"></polygon>
</g>
</g>
</svg>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
var make_chart = function() {
var graph_config = {
data: {
datasets: [
{
lineTension: 0,
label: Foris.sampleMessages.chartLabel,
data: graph_data,
},
],
fill: true,
},
options: {
responsive: true,
title: {
display: true,
text: Foris.sampleMessages.chartTitle
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: false,
scaleLabel: {
display: true,
labelString: Foris.sampleMessages.chartTimeAxis
}
}],
yAxes: [{
display: true,
ticks: {
suggestedMin: 0,
suggestedMax: 100,
},
scaleLabel: {
display: true,
labelString: Foris.sampleMessages.chartValueAxis
}
}],
},
},
};
var graph_ctx = document.getElementById("canvas").getContext("2d");
graph_config.options.scales.xAxes[0].ticks = {
min: graph_config.data.datasets[0].data[0].x,
max: graph_config.data.datasets[0].data[graph_config.data.datasets[0].data.length - 1].x,
};
Foris.lineChart = new Chart.Scatter(graph_ctx, graph_config);
Foris.lineChartData = graph_config.data;
Foris.lineChartOptions = graph_config.options;
}
var graph_data;
Foris.update_sample_chart = function() {
// Clear current chart
$("#canvas-container").empty();
$("#canvas-container").append('<canvas id="canvas"></canvas>');
// Set data
graph_data = [];
var idx = 0;
$("#records-table td.table-index").each(function(idx, item) {
graph_data[idx] = {x: parseInt($(item).text())};
idx++;
});
idx = 0;
$("#records-table td.table-value").each(function(idx, item) {
graph_data[idx]["y"] = parseInt($(item).text());
idx++;
});
// render chart
make_chart();
}
$(document).ready(function() {
Foris.update_sample_chart();
});
#records
td, th
padding: 0.3em 0.8em
border-bottom: 1px solid #fff
tr:first-child td
padding-top: 0.5em
tbody tr
&:nth-child(2n) td
background: #f2f2f2
&:hover td
border-bottom: 1px solid #00a2e2
th
font-weight: bold
border-bottom: 1px solid #ddd
margin-bottom: 2px
tbody td
&:nth-child(2), &:nth-child(3), &:nth-child(4)
text-align: right
Foris.sampleMessages = {
chartLabel: "{% trans %}Chart Data{% endtrans %}",
chartTitle: "{% trans %}Example chart{% endtrans %}",
chartTimeAxis: "{% trans %}Time axis{% endtrans %}",
chartValueAxis: "{% trans %}Value axis{% endtrans %}"
}
// Register on websockets events
// now after you insert `foris-notify-wrapper -n -m sample -a reload_chart '{}'` to
// routers console your chart will be reloaded
Foris.WS["sample"] = function(msg) {
switch(msg.action) {
case "reload_chart":
$.get('{{ url("config_ajax", page_name="sample") }}', {action: "get_records"})
.done((response) => {
$("#records-table").replaceWith(response);
Foris.update_sample_chart();
})
break;
}
}
<table id="records-table">
<thead><th>#</th><th>{% trans %}Value{% endtrans %}</th></thead>
<tbody>
{% for idx, value in records %}
<tr><td class="table-index">{{ idx }}</td><td class="table-value">{{ value }}</td></tr>
{% endfor %}
</tbody>
</table>
{% extends 'config/base.html.j2' %}
{% block config_base %}
<div id="page-sample-plugin" class="config-page">
{% for _ in range(20) %}
<img src="{{ static('plugins/sample/img/logo-dark.svg') }}"/>
{% endfor %}
{% include '_messages.html.j2' %}
<p>{% trans %}Some generic description what this plugin does.{% endtrans %}</p>
<form action="{{ request.fullpath }}" method="post" class="config-form">
<input type="hidden" name="csrf_token" value="{{ get_csrf_token() }}">
{% for field in form.active_fields %}
{% include '_field.html.j2' %}
{% endfor %}
<button type="submit" name="send">{% trans %}Update configuration{% endtrans %}</button>
</form>
<h3>{% trans %}Records{% endtrans %}</h3>
<div id="records">
{% include 'sample/_records.html.j2' %}
</div>
<h3>{% trans %}Chart{% endtrans %}</h3>
<div id="canvas-container"><canvas id="canvas"></canvas></div>
</div>
{% endblock %}
#!/usr/bin/env python
import copy
from setuptools import setup
from setuptools.command.build_py import build_py
class BuildCmd(build_py):
def run(self):
# build foris plugin files
from foris_plugins_distutils import build
cmd = build(copy.copy(self.distribution))
cmd.ensure_finalized()
cmd.run()
# build package
build_py.run(self)
setup(
name="Foris Sample Plugin",
version="0",
description="Sample plugin for foris web interface",
author="CZ.NIC, z. s. p. o.",
author_email="stepan.henek@nic.cz",
url="https://gitlab.labs.nic.cz/turris/foris-sample-plugin/",
license="GPL-3.0",
requires=[
"foris",
],
setup_requires=[
'babel',
'jinja2',
'libsass',
'foris_plugins_distutils',
],
provides=[
"foris_plugins.sample",
],
packages=[
"foris_plugins.sample",
],
package_data={
'': [
"templates/**",
"templates/**/*",
"templates/javascript/**",
"templates/javascript/**/*",
"locale/**/LC_MESSAGES/*.mo",
"static/css/*.css",
"static/fonts/*",
"static/img/*",
"static/js/*.js",
"static/js/contrib/*",
],
},
cmdclass={
"build_py": BuildCmd, # modify build_py to build the foris files as well
}
)
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