Mercurial > bottledash
changeset 16:f89ad628f831
adding the renamed files
author | sean |
---|---|
date | Wed, 05 Aug 2015 13:33:15 +0200 |
parents | 82d66f4488cd |
children | 09e3c38a7802 |
files | modules/web_view/__init__.py modules/web_view/collect_issues.py modules/web_view/display_issues.py modules/web_view/display_issues_techintern.py modules/web_view/graph.html modules/web_view/roundup_content_data/__init__.py modules/web_view/roundup_content_data/tech_intern.db modules/web_view/roundup_content_data/test_reference.db modules/web_view/webview_template.py views/bottledash_view.tpl |
diffstat | 10 files changed, 1074 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/web_view/__init__.py Wed Aug 05 13:33:15 2015 +0200 @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +""" supplys the data needed to comunicate with the roundup-server, +and the sqlite database. Represents the types of errors used in roundup. + +author: Sascha L. Teichmann <sascha.teichmann@intevation.de> +author: Bernhard Reiter <bernhard@intevation.de> +author: Sean Engelhardt <sean.engelhardt@intevation.de> + +(c) 2010,2015 by Intevation GmbH + +This is Free Software unter the terms of the +GNU GENERAL PUBLIC LICENSE Version 3 or later. +See http://www.gnu.org/licenses/gpl-3.0.txt for details +""" +import importlib + +def make_chart(chart_data_file, target_div_name): + mod = importlib.import_module("web_view." + chart_data_file) + + return mod.get_chart(target_div_name)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/web_view/collect_issues.py Wed Aug 05 13:33:15 2015 +0200 @@ -0,0 +1,158 @@ +#!/usr/bin/env python3 + +""" Fetch issues from a roundup-tracker and save them in a databse. + +author: Sascha L. Teichmann <sascha.teichmann@intevation.de> +author: Bernhard Reiter <bernhard@intevation.de> +author: Sean Engelhardt <sean.engelhardt@intevation.de> + +(c) 2010,2015 by Intevation GmbH + +This is Free Software unter the terms of the +GNU GENERAL PUBLIC LICENSE Version 3 or later. +See http://www.gnu.org/licenses/gpl-3.0.txt for details + + +##USAGE EXAMPLE: ## + +BASE_URL_DEMO = "http://localhost:8917/demo/" +SEARCH_URL_DEMO = "issue?@action=export_csv&@columns=title,priority&@filter=status&@pagesize=50&@startwith=0&status=-1,1,2,3,4,5,6,7" + +LOGIN_PARAMETERS_DEMO = ( + ("__login_name", "demo"), + ("__login_password", "demo"), + ("@action", "Login"), + ) + +save_stats_in_db(LOGIN_PARAMETERS_DEMO, BASE_URL_DEMO, rcd.DATABASE_DEMO, rcd.COLUMNS, rcd.CREATE_DB, rcd.INSERT_NEW, SEARCH_URL_DEMO) +""" + +import http.cookiejar +import urllib.parse +import urllib.request +import csv +import io +import sqlite3 as db +import os +import web_view.roundup_content_data as rcd + + +CHECK_ROUNDUP_ORDER = "priority?@action=export_csv&@columns=id,order" +CHECK_ROUNDUP_SEARCH_VALUES = "status?@action=export_csv&@columns=id&@filter=open&open=1" +SEARCH_ROUNDUP = "issue?@action=export_csv&@columns=priority&@filter=status&@pagesize=500&@startwith=0&status=-1,{search_values}" + + +def connect_to_server(params, baseurl): + enc_data = urllib.parse.urlencode(params).encode() + cj = http.cookiejar.CookieJar() + opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj)) + req = urllib.request.Request(url=baseurl, data=enc_data) + opener.open(req) + return opener + + +def get_csv_from_server(opener, roundup_url, sub_url): + csv_req = urllib.request.Request(url=roundup_url+sub_url) + f = opener.open(csv_req) + csv_reader = csv.DictReader(io.TextIOWrapper(f)) + return csv_reader + + +def set_search_paramters_on_URL(url, search_param_csv): + + id_list = [] + + for row in search_param_csv: + id_list.append(row["id"]) + + new_url = url.format(search_values = ",".join(id_list)) + + return new_url + + +def check_create_database(database_file, sql_create_db): + if not os.path.isfile(database_file): + con = None + cur = None + try: + con = db.connect(database_file) + cur = con.cursor() + try: + cur.execute(sql_create_db) + con.commit() + os.chmod(database_file, 0o644) + except: + con.rollback() + raise + finally: + if cur: + cur.close() + if con: + con.close() + + +def issues_to_quantities(issue_csv, columns, orders_csv): + + quantities = [0] * len(columns) + order_dict = {} + + #convert the csv-dict reader to real dict + for row in orders_csv: + order_dict[row["id"]] = int(float(row["order"])) # int(float()) because the order-value is indeed "1.0, 2.0" etc + + for issue in issue_csv: + priority = issue["priority"] + + if priority.isdigit() == True : + quantities[order_dict[priority] -1 ] += 1 + + # print("quantities : " + str(quantities)) + + return quantities + + +def save_issues_to_db(quantities, database_file, sql_create_db, sql_insert_in_db): + check_create_database(database_file, sql_create_db) + + cur = None + con = None + + try: + con = db.connect(database_file) + cur = con.cursor() + try: + cur.execute(sql_insert_in_db, quantities) + con.commit() + except: + con.rollback() + raise + finally: + if cur: + cur.close() + if con: + con.close() + + +def save_stats_in_db(login_parmeters, baseurl, db_file, columns, sql_create_db, sql_insert_in_db, searchurl=False): + try: + + opener = connect_to_server(login_parmeters, baseurl) + + search_operators_csv = get_csv_from_server(opener, baseurl, CHECK_ROUNDUP_SEARCH_VALUES) + order_csv = get_csv_from_server(opener, baseurl, CHECK_ROUNDUP_ORDER) + + if searchurl == False: + formated_search_url = set_search_paramters_on_URL(SEARCH_ROUNDUP, search_operators_csv) + else: + formated_search_url = searchurl + + current_issues_csv = get_csv_from_server(opener, baseurl, formated_search_url) + + opener.close() + + quantities = issues_to_quantities(current_issues_csv, columns, order_csv) + + save_issues_to_db(quantities, db_file, sql_create_db, sql_insert_in_db) + + except urllib.error.URLError as e: + print("No Valid Connection to server : " + baseurl + "\nerror: " + str(e))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/web_view/display_issues.py Wed Aug 05 13:33:15 2015 +0200 @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 + +""" Display previously saved issues from a database on webpage via CGI. + +author: Sascha L. Teichmann <sascha.teichmann@intevation.de> +author: Bernhard Reiter <bernhard@intevation.de> +author: Sean Engelhardt <sean.engelhardt@intevation.de> + +(c) 2010,2015 by Intevation GmbH + +This is Free Software unter the terms of the +GNU GENERAL PUBLIC LICENSE Version 3 or later. +See http://www.gnu.org/licenses/gpl-3.0.txt for details + + +##Usage Example: ## + +render_db_stats_as_html(rcd.DATABASE_DEMO, rcd.SELECT_ALL) +""" + +import sqlite3 as db +import cgitb, os, sys, inspect +import web_view.roundup_content_data as rcd + +PATH = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +HTML_DATA = "graph.html" +PATH_TO_HTML = PATH + "/" + HTML_DATA + +def make_js_object_string(array): + formated = [] + + for item in array: + formated.append("{points: " + str(item) + "}") + + return ",".join(formated) + + +def make_js_object_date(array): + formated = [] + + for item in array: + formated.append("{date : new Date('" + str(item) + "')}") + + return ", ".join(formated) + + +def get_webpage(): + + with open(PATH_TO_HTML, "r") as html_chart_file: + base_html_data = html_chart_file.read() + + base_html_data = (base_html_data + .replace("var critical=[];", "var critical=[" + make_js_object_string(rcd.data_dict["critical"]) + "]") + .replace("var urgent=[];", "var urgent=[" + make_js_object_string(rcd.data_dict["urgent"]) + "]") + .replace("var bug=[];", "var bug=[" + make_js_object_string(rcd.data_dict["bug"]) + "]") + .replace("var feature=[];", "var feature=[" + make_js_object_string(rcd.data_dict["feature"]) + "]") + .replace("var wish=[];", "var wish=[" + make_js_object_string(rcd.data_dict["wish"]) + "]") + .replace("var timestamp=[];", "var timestamp=[" + make_js_object_date(rcd.data_dict["date"]) + "]")) + + return base_html_data + + +# def render_webpage(content): +# webpage_string = "" +# for line in content.split("\n"): +# print(line) + + +def render_db_stats_as_html(db_file, sql_select): + + con = None + cur = None + + try: + con = db.connect(db_file) + cur = con.cursor() + cur.execute(sql_select) + + for row in cur.fetchall(): + rcd.data_dict["date"].append(row[0]) + rcd.data_dict["critical"].append(row[1]) + rcd.data_dict["urgent"].append(row[2]) + rcd.data_dict["bug"].append(row[3]) + rcd.data_dict["feature"].append(row[4]) + rcd.data_dict["wish"].append(row[5]) + finally: + if cur: + cur.close() + if con: + con.close() + + # render_webpage(get_webpage()) + # print(get_webpage()) + return get_webpage() + +# cgitb.enable() +# print("Content-Type: text/html") +# print()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/web_view/display_issues_techintern.py Wed Aug 05 13:33:15 2015 +0200 @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +""" Fetch issues from a roundup-tracker and save them in a databse. + +author: Sascha L. Teichmann <sascha.teichmann@intevation.de> +author: Bernhard Reiter <bernhard@intevation.de> +author: Sean Engelhardt <sean.engelhardt@intevation.de> + +(c) 2010,2015 by Intevation GmbH + +This is Free Software unter the terms of the +GNU GENERAL PUBLIC LICENSE Version 3 or later. +See http://www.gnu.org/licenses/gpl-3.0.txt for details +""" + +import importlib + +def get_chart(target_div_name): + display = importlib.import_module("web_view.display_issues") + rcd = importlib.import_module("web_view.roundup_content_data") + # print(display_issues.render_db_stats_as_html(roundup_content_data.DATABASE_TECH_INTERN, roundup_content_data.SELECT_ALL)) + # print (display.render_db_stats_as_html(rcd.DATABASE_TECH_INTERN, rcd.SELECT_ALL)) + html_string = display.render_db_stats_as_html(rcd.DATABASE_TECH_INTERN, rcd.SELECT_ALL) + + html_string = html_string.replace( + 'var d3jsInjectionTarget="X";', 'var d3jsInjectionTarget="' + target_div_name + '";') + + # print(html_string) + + return html_string + +# get_chart();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/web_view/graph.html Wed Aug 05 13:33:15 2015 +0200 @@ -0,0 +1,412 @@ +<style type = text/css> + + * { + font-family: "Sans-serif"; + font-size: 14px; + } + + .svg div{ + font: 10px; + text-align: right; + float: left; + display: block; + padding: 10px; + margin: 10px; + color: white; + } + + .axis path, + + .axis line { + fill: none; + stroke: lightgrey; + /*opacity: 0.7;*/ + stroke-width: 1px; + } + + .y.axis path { + display: none; + } + + .line { + fill: none; + stroke-width: 3px; + opacity: 1; + } + + .line.critical { + stroke: red; + } + + .line.critical.legend { + fill: red; + } + + .line.urgent { + stroke: orange; + } + + .line.urgent.legend { + fill: orange; + } + + .line.bug { + stroke: violet; + } + + .line.bug.legend { + fill: violet; + } + + .line.feature { + stroke: chartreuse; + style: stroke-dasharray; + } + + .line.feature.legend { + fill: chartreuse; + } + + .line.wish { + stroke: blue; + } + + .line.wish.legend { + fill: blue; + } + + .grid .tick { + stroke: lightgrey; + /*opacity: 0.7;*/ + } + + .grid path { + stroke-width: 0; + } + +</style> + +<!-- <div id="content" style="display: inline-block"></div> --> +<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script> +<script type="text/javascript"> + + // window.onresize = function(){ + // document.getElementsByClassName("chart")[0].innerHTML = ""; + // makeChart(); + // }; + + var d3jsInjectionTarget="X"; + + var critical=[]; + var urgent=[]; + var bug=[]; + var feature=[]; + var wish=[]; + var timestamp=[]; + + // var critical=[ + // {points: 4}, + // {points: 12}, + // {points: 8}, + // {points: 2} + // ] + // + // var urgent=[ + // {points: 3}, + // {points: 24}, + // {points: 17}, + // {points: 19} + // ] + // + // var bug=[ + // {points: 10}, + // {points: 2}, + // {points: 2}, + // {points: 12} + // ] + // + // var feature=[ + // {points: 4}, + // {points: 21}, + // {points: 12}, + // {points: 4} + // ] + // + // var wish=[ + // {points: 22}, + // {points: 18}, + // {points: 32}, + // {points: 10} + // ] + // + // + // var timestamp=[ + // {date : new Date('2015-06-30T12:36:47')}, + // {date : new Date('2015-07-01T12:37:26')}, + // {date : new Date('2015-07-02T12:38:26')}, + // {date : new Date('2015-07-03T12:39:26')} + // ] + + document.addEventListener("DOMContentLoaded", function(event) { + makeChart(); + }); + + function assignIssueToDate(issueArray, dateArray){ + a = []; + for (var i = 0; i < issueArray.length; i++) { + a.push({points: issueArray[i].points, date : dateArray[i].date}); + } + + return a; + } + + function limitDatesOnXAxis(limit){ + if (timestamp.length < limit){ + return timestamp.length; + } else { + return limit; + } + } + + function maxInObject( array ){ + var maxVal = 0; + for (var i = 0; i < array.length; i++) { + if (maxVal < array[i].points){ + maxVal = array[i].points; + } + } + return maxVal; + } + + + function getMaxIssues(){ + maxIssuesOfAllArrays = []; + maxIssuesOfAllArrays.push(maxInObject(critical)); + maxIssuesOfAllArrays.push(maxInObject(urgent)); + maxIssuesOfAllArrays.push(maxInObject(bug)); + maxIssuesOfAllArrays.push(maxInObject(feature)); + maxIssuesOfAllArrays.push(maxInObject(wish)); + + return Math.max.apply(Math, maxIssuesOfAllArrays)+1; + } + + + function dayDifference(first, second) { + "use strict"; + var difference = (second - first) / (1000 * 60 * 60 * 24); + + // just to avoid the get thousands of lines... would look ugly. + if (difference > 60){ + difference = 60; + } + + return difference; + } + + + // function for the grid lines + function makeGrid(direction, orientation, ticknumber) { + return d3.svg.axis() + .scale(direction) + .orient(orientation) + .ticks( ticknumber ); + } + + + //append a svg_path. pretty generic + function draw_line(svg, data_array, css_class, line_object, lineShape){ + svg.append("path") + .datum(assignIssueToDate(data_array, timestamp)) + .attr("class", css_class) + .style("stroke-dasharray", (lineShape)) + .attr("d", line_object); + } + + + function makeLegend(svg, width){ + + var legend_distance = width+40; + var top_distance = 20; + var distance_steps = 50; + + + function set_propper_distance(steps){ + top_distance += steps; + return top_distance; + } + + function draw_legend_line(svg, width, Ypos, text, issues){ + svg.append("svg:text") + .attr("class", "legend") + .attr("x", width-30 ) + .attr("y", Ypos) + .text(text + ":"); + + svg.append("svg:text") + .attr("class", "legend") + .attr("x", width+35 ) + .attr("y", Ypos) + .text(issues); + + svg.append("rect") + .attr("class", "line " + text.toLowerCase() + " legend") + .attr("x", width-30) + .attr("y", Ypos-20) + .attr("width", 100) + .attr("height", 2); + } + + draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Critical", critical[critical.length-1].points); + draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Urgent", urgent[urgent.length-1].points); + draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Bug", bug[bug.length-1].points); + draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Feature", feature[feature.length-1].points); + draw_legend_line(svg, legend_distance, set_propper_distance(distance_steps), "Wish", wish[wish.length-1].points); + } + + + + //draw the chart + function makeChart(div_name){ + + //declaration + var sizeOfSystemBorders = 20; + // var margin = {top: 20, right: 100, bottom: 90, left: 60}; + // var margin = {top: 0, right: 0, bottom: 0, left: 0} + + var width = document.getElementsByClassName("chart")[0].clientWidth; + var height = document.getElementsByClassName("chart")[0].clientHeight; + // var width = (document.documentElement.clientWidth-sizeOfSystemBorders) - margin.left - margin.right; + // var height = (document.documentElement.clientHeight-sizeOfSystemBorders) - margin.top - margin.bottom; + + var x = d3.time.scale() + .range([0, width]); + + var y = d3.scale.linear() + .range([height, 0]); + + var base_line = d3.svg.line() + .x(function(d) { return x(d.date); }) + .y(function(d) { return y(d.points); }); + + //lines + var criticalLine = base_line; + var urgentLine = base_line; + var bugLine = base_line; + var featureLine = base_line; + var wishLine = base_line; + var timestampLine = base_line; + + + //set domain of y axis + var yDomain = [ ]; + yDomain[0] = 0; + yDomain[1] = getMaxIssues(); + y.domain(d3.extent(yDomain, function(d){return d; })); + + //set domain of y axis + x.domain(d3.extent(timestamp, function(d){return d.date; })); + + + var xAxis = d3.svg.axis() + .scale(x) + .orient("bottom") + .ticks(limitDatesOnXAxis(10)) + .tickFormat(d3.time.format("%d.%m")); + // .tickFormat(d3.time.format("%d.%m:%H:%M")); + // .tickFormat(d3.time.format("%X")); + // .tickFormat(d3.time.format.iso); + + + var yAxis = d3.svg.axis() + .scale(y) + .orient("left"); + + + var svg = d3.select("." + d3jsInjectionTarget) + .append("svg") + .attr("class", "svg") + // .attr("width", width) + // .attr("height", height) + .attr("width", width-20) + .attr("height", height-10) + .append("g") + // .attr("transform", "translate( +50,+0,+0,+0)"); + .attr("transform", "translate(40 , 0)"); + + + // creation + + + // Draw the x Grid lines + // svg.append("g") + // .attr("class", "grid") + // .attr("transform", "translate(0," + height + ")") + // .call(makeGrid(x, "bottom", timestamp.length) + // .tickSize(-height, 0, 0) + // .tickFormat("") + // ); + + + // Draw the y Grid lines + svg.append("g") + .attr("class", "grid") + .call(makeGrid(y, "left", function(){return Math.min(getMaxIssues(), 10);}()) + .tickSize(-width, 0, 0) + .tickFormat("") + ); + + + // Draw the x-axis + svg.append("g") + .attr("class", "x axis") + // .attr("transform", "translate(0, " + 20-height + ")") + .call(xAxis) + .selectAll("text") + .style("text-anchor", "end") + // .attr("dx", "-.5em") + // .attr("dy", ".1em") + // .attr("transform", function() { + // return "rotate(-30)"; + // }); + + + // Draw the y-axis + svg.append("g") + .attr("class", "y axis") + .call(yAxis) + .append("text") + .attr("transform", "rotate(-90)") + .attr("y", 6) + .attr("dy", ".71em") + .style("text-anchor", "end"); + + + // Text for y-axis + // svg.append("text") + // .attr("transform", "rotate(-90)") + // .attr("y", 10 - margin.left) + // .attr("x", 0 - (height / 2)) + // .attr("dy", "1em") + // .style("text-anchor", "middle") + // .text("Issues"); + + + //Titel und Legende + // svg.append("svg:text") + // .attr("class", "text") + // .attr("x", 10) + // .attr("y", -5) + // .text("Issues Nach Zeit"); + + draw_line(svg, wish, "line wish", wishLine, "0, 0"); + draw_line(svg, feature, "line feature", featureLine, "3, 3"); + draw_line(svg, bug, "line bug", bugLine, "7, 7"); + draw_line(svg, urgent, "line urgent", urgentLine, "13, 13"); + draw_line(svg, critical, "line critical", criticalLine, "17, 17"); + + + // makeLegend(svg, width); + } + + +</script>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/web_view/roundup_content_data/__init__.py Wed Aug 05 13:33:15 2015 +0200 @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +""" supplys the data needed to comunicate with the roundup-server, +and the sqlite database. Represents the types of errors used in roundup. + +author: Sascha L. Teichmann <sascha.teichmann@intevation.de> +author: Bernhard Reiter <bernhard@intevation.de> +author: Sean Engelhardt <sean.engelhardt@intevation.de> + +(c) 2010,2015 by Intevation GmbH + +This is Free Software unter the terms of the +GNU GENERAL PUBLIC LICENSE Version 3 or later. +See http://www.gnu.org/licenses/gpl-3.0.txt for details +""" + +import os + +#Add desired sqlite databases here +DATABASE_REFERENCCE = os.path.dirname(os.path.realpath(__file__)) + "/test_reference.db" +DATABASE_DEMO = os.path.dirname(os.path.realpath(__file__)) + "/demo.db" +DATABASE_ERRORDB = os.path.dirname(os.path.realpath(__file__)) + "/errordatabase.db" +DATABASE_TECH_INTERN = os.path.dirname(os.path.realpath(__file__)) + "/tech_intern.db" +DATABASE_INT_TEST = os.path.dirname(os.path.realpath(__file__)) + "/int_test.db" + +COLUMNS= [ + "critical", "urgent", "bug", "feature", "wish", +] + +data_dict = { + "date": [], + "critical": [], + "urgent": [], + "bug": [], + "feature": [], + "wish": [] +} + +#SQL + +#DEMO System +SELECT_ALL = """ +SELECT strftime("%Y-%m-%dT%H:%M:%S", timestamp), + critical, + urgent, + bug, + feature, + wish +FROM issues +ORDER BY timestamp +""" + + +CREATE_DB = """ +CREATE TABLE issues ( + timestamp TIMESTAMP NOT NULL UNIQUE DEFAULT current_timestamp, + critical INTEGER NOT NULL DEFAULT 0, + urgent INTEGER NOT NULL DEFAULT 0, + bug INTEGER NOT NULL DEFAULT 0, + feature INTEGER NOT NULL DEFAULT 0, + wish INTEGER NOT NULL DEFAULT 0 +) +""" + + +INSERT_NEW = """ + INSERT INTO issues (critical, urgent, bug, feature, wish) + VALUES (?, ?, ?, ?, ?) +""" + +#Referecen DB: +SELECT_ALL_REFERENCE = """ +SELECT strftime("%Y-%m-%dT%H:%M:%S", sample_time), + critical, + major, + crash, + normal, + minor, + wishlist +FROM issues +ORDER BY sample_time +""" \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/web_view/webview_template.py Wed Aug 05 13:33:15 2015 +0200 @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +""" Simple Template to use the Web-View Module + +author: Sean Engelhardt <sean.engelhardt@intevation.de> + +(c) 2010,2015 by Intevation GmbH + +This is Free Software unter the terms of the +GNU GENERAL PUBLIC LICENSE Version 3 or later. +See http://www.gnu.org/licenses/gpl-3.0.txt for details + +--- +How to write a web-view module? +--- + +declare a specific tile in the dash.conf. for example: + +--- +[tile5] +type=d3js +div_name=webview_test +script=webview_template +--- +(this will work for this file, see dash.conf for details) + +bottledash will look for a "get_chart(target_div_name)"-methode wich shall +return valid HTML-code (as string!). + +the "target_div_name" is the "div_name" you delared in the dash.conf-file. +In our case, "tile5" would be in the css-class "webview_test". You can use +the "target_div_name" for dynamic DOM-Manipulations (like with d3js and jQuery) + +If you want to use a python import, please use "importlib" inside the +get_chart-function. + +see <https://docs.python.org/3/library/importlib.html> for details + +To not try to import your own modules using the regular +python import-keyword! You can however import every regular +python-standard-library using the "import" keyword + +""" + +import importlib + +def get_chart(target_div_name): + html_string = """ +<style type = text/css> + +.%s { + color: red; +} + +</style> + +<div id = "hello"> + Hello World! +</div> + """ % target_div_name + + return html_string
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/views/bottledash_view.tpl Wed Aug 05 13:33:15 2015 +0200 @@ -0,0 +1,209 @@ +<!-- This tempalte is a part of bottledash +author: sean engelhardt >sean.engelhardt@intevation.de +License: GNU GPL >= v2. See LICENSE for details. --> + +<% + + + import math, os, sys, subprocess, html.parser + from datetime import date + + PATH = os.path.abspath(os.path.dirname(sys.argv[0])) + sys.path.append(PATH + "/modules") + import web_view + + ################# + # settings # + ################# + + show_top_bar = settings["show_top_bar"] + + ################# + # date and time # + ################# + + today = date.today() + weekday = ("Montag", "Dienstag", "Mittwoch", "Donnerstag", + "Freitag", "Samstag", "Sonntag")[today.weekday()] + month_name = ("Januar", "Februar", "März", "Aprill", "Mai", + "Juni", "Juli", "August", "September", "Oktober", + "November", "Dezember")[today.month-1] + + number_of_rows = 1 + + ################# + # viewport size # + ################# + vp_size = "17px" + #if len(tiles) <= 2: + # vp_size = "6vw" + #elif len(tiles) >2 and len(tiles) <=4 : + # vp_size = "5vw" + #elif len(tiles) >4 and len(tiles) <=6 : + # vp_size = "4vw" + #elif len(tiles) >6 and len(tiles) <=8 : + # vp_size = "3vw" + #end +%> + +<script type="text/javascript"> + + var global_width; + var global_height; + var tile_width; + var tile_height; + + var tiles = document.getElementsByClassName("tile"); + var border_width = 1; + var space_between_tiles = 8; + + var space_lr_borders; + var space_lr_margin; + + function calc_tile_with(){ + var tiles_per_row = Math.floor(tiles.length / {{number_of_rows}}); + var distance = (space_between_tiles*2) + (border_width*2); + var tile_width = ((global_width / tiles_per_row ) - distance); + return tile_width; + } + + function calc_tile_height(){ + var distance = (space_between_tiles*2) + (border_width*2); + var tile_height = ((global_height / {{number_of_rows}} ) - distance); + return tile_height; + } + + function resize_content(){ + global_width = document.getElementById("content").clientWidth; + global_height = document.getElementById("content").clientHeight; + + + tile_width = calc_tile_with(); + tile_height = calc_tile_height(); + + for(var tile = 0; tile < tiles.length; tile++){ + tiles[tile].style.width= tile_width + 'px'; + tiles[tile].style.height= tile_height + 'px'; + } + } + + window.onresize = function(){ + resize_content(); + } + + document.addEventListener("DOMContentLoaded", function(event) { + resize_content(); + }); + +</script> + +<style> + *{ + margin: 0 auto; + padding: 0 auto; + font-family: "Lucida Console", Monaco, monospace; + } + + body { + overflow: hidden; + } + + #wrapper{ + background-color: #F2F2F2; + color: black; + min-width: 100%; + min-height: 100%; + } + + #topbar{ + min-width: auto; + padding-left: 8px; + padding-top: 8px; + padding-bottom: 8px; + /*height: 5%;*/ + font-family: Arial, Helvetica, sans-serif; + } + + #content{ + min-width: 100%; + % if show_top_bar == "True": + height: 95%; + % else : + height: 100%; + %end + } + + .tile{ + float: left; + margin: 8px; + background-color: #FFFFFF; + border: 1px solid #999999; + border: none; + text-align:center; + vertical-align: middle; + } + + .clear{ + height: 0px; + clear: both; + } + + /*tiles types*/ + + .statusmon{ + color: white; + font-size: {{vp_size}}; + } + + .chart{ + font-size: {{vp_size}}; + } + + .active{ + border: 1px solid #00cc00; + background-color: #009900; + } + + .dead{ + border: 1px solid #cc0000; + background-color: #990000; + } + +</style> + +<div id = "wrapper"> + % if show_top_bar == "True" : + <div id = "topbar"> + <b>{{weekday}}</b> {{today.day}}. {{month_name}} + </div> + % end + + <div id = "content"> + <% + for tile in tiles : + type = "" + tile_content = "" + status = "" + if tile["type"] == "mon" : + type = "statusmon" + tile_content = tile["source"] + if tile["status"] == "up" : + status = "active" + elif tile["status"] == "down" : + status = "dead" + end + elif tile["type"] == "d3js" : + type = "chart" + status = tile["div_name"] + tile_content = web_view.make_chart(tile["script"], tile["div_name"]) + end + %> + + <div class = "tile {{type}} {{status}}"> + {{!tile_content}} + </div> + + % end + + </div> +</div>