# HG changeset patch # User sean # Date 1438774395 -7200 # Node ID f89ad628f831065aa9614cb57480fe609c5f2c56 # Parent 82d66f4488cdf5a6a9b1043a0b1c492c226c276f adding the renamed files diff -r 82d66f4488cd -r f89ad628f831 modules/web_view/__init__.py --- /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 +author: Bernhard Reiter +author: Sean Engelhardt + +(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) diff -r 82d66f4488cd -r f89ad628f831 modules/web_view/collect_issues.py --- /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 +author: Bernhard Reiter +author: Sean Engelhardt + +(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)) diff -r 82d66f4488cd -r f89ad628f831 modules/web_view/display_issues.py --- /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 +author: Bernhard Reiter +author: Sean Engelhardt + +(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() diff -r 82d66f4488cd -r f89ad628f831 modules/web_view/display_issues_techintern.py --- /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 +author: Bernhard Reiter +author: Sean Engelhardt + +(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(); diff -r 82d66f4488cd -r f89ad628f831 modules/web_view/graph.html --- /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 @@ + + + + + diff -r 82d66f4488cd -r f89ad628f831 modules/web_view/roundup_content_data/__init__.py --- /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 +author: Bernhard Reiter +author: Sean Engelhardt + +(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 diff -r 82d66f4488cd -r f89ad628f831 modules/web_view/roundup_content_data/tech_intern.db Binary file modules/web_view/roundup_content_data/tech_intern.db has changed diff -r 82d66f4488cd -r f89ad628f831 modules/web_view/roundup_content_data/test_reference.db Binary file modules/web_view/roundup_content_data/test_reference.db has changed diff -r 82d66f4488cd -r f89ad628f831 modules/web_view/webview_template.py --- /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 + +(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 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 = """ + + +
+ Hello World! +
+ """ % target_div_name + + return html_string diff -r 82d66f4488cd -r f89ad628f831 views/bottledash_view.tpl --- /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 @@ + + +<% + + + 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 +%> + + + + + +
+ % if show_top_bar == "True" : +
+ {{weekday}} {{today.day}}. {{month_name}} +
+ % end + +
+ <% + 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 + %> + +
+ {{!tile_content}} +
+ + % end + +
+