Mercurial > bottledash
changeset 42:8935152f5e19
Remove roundup_cc fork; import from embedded roundup_cc clone
author | Gernot Schulz <gernot@intevation.de> |
---|---|
date | Sun, 31 Jan 2016 13:18:51 +0100 |
parents | bbd4eab7cb1e |
children | 2e2981af7d2d |
files | 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 |
diffstat | 7 files changed, 13 insertions(+), 714 deletions(-) [+] |
line wrap: on
line diff
--- a/modules/web_view/collect_issues.py Wed Nov 18 13:41:42 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,158 +0,0 @@ -#!/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))
--- a/modules/web_view/display_issues.py Wed Nov 18 13:41:42 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -#!/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()
--- a/modules/web_view/display_issues_techintern.py Wed Nov 18 13:41:42 2015 +0100 +++ b/modules/web_view/display_issues_techintern.py Sun Jan 31 13:18:51 2016 +0100 @@ -13,20 +13,24 @@ See http://www.gnu.org/licenses/gpl-3.0.txt for details """ -import importlib +from sys import path +import os + +path.append( + os.path.join(os.path.dirname(os.path.realpath(__file__)), 'roundup_cc') + ) + +from display_issues import * 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 = compile_db_stats_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(); +# print(get_chart('techintern'))
--- a/modules/web_view/graph.html Wed Nov 18 13:41:42 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,367 +0,0 @@ -<style type = text/css> - - * { - font-family: "Sans-serif"; - /*font-size: 20px;*/ - } - - .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: 4px; - 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" src="static/d3.v3.min.js"></script> - -<script type="text/javascript"> - - var d3jsInjectionTarget="X"; - - // window.onresize = function(){ - // document.getElementById(d3jsInjectionTarget).innerHTML = ""; - // makeChart(); - // }; - - var critical=[]; - var urgent=[]; - var bug=[]; - var feature=[]; - var wish=[]; - var timestamp=[]; - - document.addEventListener("DOMContentLoaded", function(event) { - try { - document.getElementById(d3jsInjectionTarget).getElementsByClassName("svg")[0].innerHTML = "" - } catch (e) { - } - 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){ - svg.append("path") - .datum(assignIssueToDate(data_array, timestamp)) - .attr("class", css_class) - .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 targetDiv = document.getElementById(d3jsInjectionTarget) - // var sizeOfSystemBorders = 20; - - var margin = {top: 20, right: 10, bottom: 50, left:50} - - var width = targetDiv.clientWidth - margin.left - margin.right - var height = targetDiv.clientHeight - 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")); - - var yAxis = d3.svg.axis() - .scale(y) - .orient("left"); - - var svg = d3.select("#" + d3jsInjectionTarget) - .append("svg") - .attr("class", "svg") - .attr("width", width + margin.left + margin.right) - .attr("height", height + margin.top + margin.bottom) - .append("g") - .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); - - - // 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 + ")") - .attr("transform", "translate(0," + 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); - draw_line(svg, feature, "line feature", featureLine); - draw_line(svg, bug, "line bug", bugLine); - draw_line(svg, urgent, "line urgent", urgentLine); - draw_line(svg, critical, "line critical", criticalLine); - - - // makeLegend(svg, width); - } - // makeChart(); - -</script>
--- a/modules/web_view/roundup_content_data/__init__.py Wed Nov 18 13:41:42 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -#!/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