diff options
Diffstat (limited to 'vstf/vstf/controller/reporters/report')
15 files changed, 0 insertions, 2254 deletions
diff --git a/vstf/vstf/controller/reporters/report/__init__.py b/vstf/vstf/controller/reporters/report/__init__.py deleted file mode 100644 index 547db686..00000000 --- a/vstf/vstf/controller/reporters/report/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - - diff --git a/vstf/vstf/controller/reporters/report/candy_generator.py b/vstf/vstf/controller/reporters/report/candy_generator.py deleted file mode 100644 index ea296550..00000000 --- a/vstf/vstf/controller/reporters/report/candy_generator.py +++ /dev/null @@ -1,138 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - -from vstf.controller.settings.template_settings import TemplateSettings -from vstf.controller.reporters.report.data_factory import TaskData -from vstf.controller.database.dbinterface import DbManage -import vstf.common.candy_text as candy -import logging -LOG = logging.getLogger(__name__) - - -class CandyGenerator(object): - def __init__(self, task): - self._task = task - - def create(self, scenario): - context = {} - - sn = 1 - chapterid = 1 - name = candy.tuple2text(sn, candy.chapter, chapterid) - context[name] = self.create_env() - - sn += 1 - chapterid += 1 - name = candy.tuple2text(sn, candy.chapter, chapterid) - context[name] = self.create_scenario(scenario) - - template = TemplateSettings() - template.set_context(context) - LOG.info(template.settings) - - def create_all(self): - context = {} - - sn = 1 - chapterid = 1 - name = candy.tuple2text(sn, candy.chapter, chapterid) - context[name] = self.create_env() - - scenarios = self._task.common.get_scenariolist() - for scenario in scenarios: - sn += 1 - chapterid += 1 - name = candy.tuple2text(sn, candy.chapter, chapterid) - context[name] = self.create_scenario(scenario) - - template = TemplateSettings() - template.set_context(context) - LOG.info(template.settings) - - def create_env(self): - env = { - "01##title#1": ["System Environment"], - "02##table#2": self._task.common.get_systeminfo() - } - return env - - def create_scenario(self, scenario): - scenario_chapter = { - "01##title#1": ["Scenario Result"] - } - scenario_data = getattr(self._task, scenario) - test_list = scenario_data.get_testlist() - sectionid = 0 - sn = 1 - for test in test_list: - sn += 1 - sectionid += 1 - name = candy.tuple2text(sn, candy.section, sectionid) - testid = test.TestID - case = test.CaseTag.decode() - ttype = test.Type.decode() - - params_info = [ - " Case: " + case, - " Test tool: " + test.Tools.decode(), - " vSwitch: " + test.Switch.decode(), - " Protocol: " + test.Protocol.decode(), - " Type: " + ttype - ] - if ttype in ["frameloss", "throughput"]: - draw = { - "style": 1, - "node": candy.plot, - "data": scenario_data.get_framerate_chartdata(case, ttype) - } - table = scenario_data.get_ratedata(testid, ttype) - else: - draw = { - "style": 1, - "node": candy.chart, - "data": scenario_data.get_latency_bardata(case) - } - table = scenario_data.get_latency_tabledata(case) - test_section = self.create_test(sectionid, params_info, table, draw) - scenario_chapter[name] = test_section - - return scenario_chapter - - def create_test(self, section, info, table, draw): - """ - - :rtype : dict - """ - sn = 7 - draw_name = candy.tuple2text(sn, draw["node"], draw["style"]) - case_section = { - "01##title#2": ["Test ID: %s" % section], - "02##paragraph#2": ["Parameter"], - "03##paragraph#3": info, - "04##paragraph#2": ["Result"], - "05##table#2": table, - "06##space#2": 2, - draw_name: draw["data"] - } - return case_section - - -def main(): - from vstf.common.log import setup_logging - setup_logging(level=logging.DEBUG, log_file="/var/log/vstf/vstf-candy.log", clevel=logging.INFO) - - dbase = DbManage() - taskid = dbase.get_last_taskid() - task = TaskData(taskid, dbase) - creator = CandyGenerator(task) - - creator.create("Tn") -if __name__ == '__main__': - main() - diff --git a/vstf/vstf/controller/reporters/report/data_factory.py b/vstf/vstf/controller/reporters/report/data_factory.py deleted file mode 100644 index f9fc69d9..00000000 --- a/vstf/vstf/controller/reporters/report/data_factory.py +++ /dev/null @@ -1,441 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - -from vstf.controller.database.dbinterface import DbManage -import vstf.common.constants as cst - - -class DataProvider(object): - def __init__(self, taskid, dbase): - self._dbase = dbase - self._taskid = taskid - - -class CommonData(DataProvider): - def get_taskname(self): - return self._dbase.query_taskname(self._taskid) - - def get_systeminfo(self): - systable = [ - ['Host', 'Server', 'CPU', 'MEM', 'NIC', 'OS'], - ] - query = self._dbase.query_task_host_list(self._taskid) - query = map(lambda x: list(x), query) - # rows = len(query) - # cols = len(zip(*query)) - # for i in range(rows): - # for j in range(cols): - # query[i][j] = query[i][j].replace('\",','\"\n') - systable += query - systable = map(lambda x: list(x), zip(*systable)) - return systable - - def get_introduct_tabledata(self): - result = [ - ["Type", "Case", "Name", "Direction", "Configure"] - ] - query = self._dbase.query_caseinfo() - result += map(lambda x: list(x), query) - return result - - def get_scenariolist(self): - query = self._dbase.query_scenariolist(self._taskid) - result = map(lambda x: list(x), zip(*query)) - if result: - return result[0] - else: - return result - - def is_scenario_start(self): - scenarioList = self.get_scenariolist() - print "scenarioList: ", scenarioList - if scenarioList: - return True - return False - - def get_casename(self, case): - return self._dbase.query_casename(case) - - def get_casefigure(self, case, tools): - return self._dbase.query_casefigure(case, tools) - - -class ScenarioData(DataProvider): - def __init__(self, taskid, dbase, scenario): - print "ScenarioData in" - DataProvider.__init__(self, taskid, dbase) - self._scenario = scenario - - def get_test_tools(self, case): - query = self._dbase.query_casetools(self._taskid, case) - result = map(lambda x: list(x), query) - if result: - return result[0][0] - else: - return result - - def get_caselist(self): - query = self._dbase.query_caselist(self._taskid, self._scenario) - result = map(lambda x: list(x), zip(*query)) - if result: - return result[0] - else: - return result - - def get_testlist(self): - query = self._dbase.query_testlist(self._taskid, self._scenario) - result = [] - for item in query: - result.append(item.__dict__) - return query - - def is_provider_start(self, case, provider): - count = self._dbase.query_case_provider_count(self._taskid, case, provider) - if count: - return True - return False - - def is_type_provider_start(self, case, provider, ptype): - count = self._dbase.query_case_type_provider_count(self._taskid, case, provider, ptype) - if count: - return True - return False - - def is_type_start(self, case, ptype): - count = self._dbase.query_case_type_count(self._taskid, case, ptype) - if count: - return True - return False - - def is_throughput_start(self, case): - test_type = "throughput" - return self.is_type_start(case, test_type) - - def is_frameloss_start(self, case): - test_type = "frameloss" - return self.is_type_start(case, test_type) - - def is_latency_start(self, case): - test_type = "latency" - return self.is_type_start(case, test_type) - - def get_summary_throughput_data(self, case, provider): - test_type = "throughput" - return self.get_summary_tabledata(case, provider, test_type) - - def get_summary_frameLoss_data(self, case, provider): - test_type = "frameloss" - return self.get_summary_tabledata(case, provider, test_type) - - def get_summary_tabledata(self, case, provider, test_type, table_type='pdf'): - table_head = [] - table_body = [] - type_title = { - "frameloss": "Load", - "throughput": "Load" - } - tools = self.get_test_tools(case) - if "spirent" in tools: - table_body = self._dbase.query_summary_table(self._taskid, case, provider, test_type) - if 'pdf' == table_type: - table_head = [ - ["FrameSize (byte)", test_type, "", "", "", "Latency(uSec)", "", ""], - ["", " Mpps ", " " + type_title[test_type] + " (%) ", "CPU Used (%)", " Mpps/Ghz ", - " Min ", " Max ", " Avg "] - ] - else: - table_head = [ - ["FrameSize (byte)", " Mpps ", " " + type_title[test_type] + " (%) ", "CPU Used (%)", - " Mpps/Ghz ", "MinLatency(uSec)", "MaxLatency(uSec)", "AvgLatency(uSec)"], - ] - else: - table_body = self._dbase.query_summary_simpletable(self._taskid, case, provider, test_type) - if 'pdf' == table_type: - table_head = [ - ["FrameSize (byte)", test_type, "", "", "", "Latency(uSec)"], - ["", " Mpps ", " " + type_title[test_type] + " (%)", "CPU Used (%)", " Mpps/Ghz ", - " Avg "] - ] - else: - table_head = [ - ["FrameSize (byte)", " Mpps ", " " + type_title[test_type] + " (%) ", "CPU Used (%)", - " Mpps/Ghz ", "AvgLatency(uSec)"], - ] - return table_head + table_body - - def get_ratedata(self, testid, test_type): - table_head = [ - ["FrameSize (bytes)", "Bandwidth(Mpps)", "Load (%)", "CPU Usage(%)", "Mpps/Ghz", "AvgLatency(uSec)"], - ] - query = self._dbase.query_testdata(testid, test_type) - table_body = [] - for item in query: - table_body.append([item.AvgFrameSize, item.Bandwidth, item.OfferedLoad, item.CPU, item.MppspGhz, - item.AverageLatency]) - result = [] - if table_body: - result = table_head + table_body - return result - - def get_tabledata(self, case, test_type, item): - type_dict = { - "FrameSize": "FrameSize (byte)", - "fastlink": "fastlink", - "l2switch": "l2switch", - "rdp": "kernel rdp", - None: "ovs", - "line": "line speed" - } - item_dict = { - "Percent": " ", - "Mpps": " ", - "Avg": " ", - } - table = [] - line_speed = 20.0 if case in ["Tn-2v", "Tn-2"] else 10.0 - - for provider in cst.PROVIDERS: - if self.is_provider_start(case, provider): - if item == 'Percent': - query = self._dbase.query_load(self._taskid, case, provider, test_type) - elif item == 'Mpps': - query = self._dbase.query_bandwidth(self._taskid, case, provider, test_type) - else: - query = self._dbase.query_avglatency(self._taskid, case, provider, test_type) - query = map(lambda x: list(x), zip(*query)) - if query: - table_head = [[type_dict["FrameSize"]] + map(lambda x: " %4d " % (x), query[0])] - if item == "Avg": - data = map(lambda x: item_dict[item] + "%.1f" % x + item_dict[item], query[1]) - else: - data = map(lambda x: item_dict[item] + "%.2f" % x + item_dict[item], query[1]) - if item == "Mpps": - line_table = map(lambda x: "%.2f" % (line_speed * 1000 / (8 * (x + 20))), query[0]) - table.append([type_dict[provider]] + data) - if table: - if item == "Mpps": - table.append([type_dict["line"]] + line_table) - table = table_head + table - return table - - def get_frameloss_tabledata(self, case, test_type): - item = "Percent" - table = self.get_tabledata(case, test_type, item) - return table - - def get_frameloss_chartdata(self, case, test_type): - result = self.get_frameloss_tabledata(case, test_type) - result = map(list, zip(*result)) - return result - - def get_framerate_tabledata(self, case, test_type): - item = "Mpps" - table = self.get_tabledata(case, test_type, item) - return table - - def get_framerate_chartdata(self, case, test_type): - result = self.get_framerate_tabledata(case, test_type) - result = map(list, zip(*result)) - return result - - def get_latency_tabledata(self, case): - test_type = "latency" - item = "Avg" - table = self.get_tabledata(case, test_type, item) - return table - - def get_latency_chartdata(self, case): - result = self.get_latency_tabledata(case) - result = map(list, zip(*result)) - return result - - def get_latency_bardata(self, case): - table_data = self.get_latency_tabledata(case) - result = [] - if table_data: - ytitle = "Average Latency (uSec)" - category_names = map(lambda x: "FS:%4d" % int(float(x)) + "LOAD:50", table_data[0][1:]) - bar_ = map(lambda x: x[0], table_data[1:]) - data = map(lambda x: x[1:], table_data[1:]) - result = [ytitle, category_names, bar_, data] - return result - - def get_bardata(self, case, provider, test_type): - if test_type == "latency": - query = self._dbase.query_avglatency(self._taskid, case, provider, test_type) - item = "Avg" - else: - query = self._dbase.query_load(self._taskid, case, provider, test_type) - item = "Percent" - - title_dict = { - "Avg": "Latency (uSec)", - "Percent": test_type + " (%)" - } - name_dict = { - "Avg": " LOAD:50", - "Percent": " OF:100 " - } - color_dict = { - "Avg": "latency", - "Percent": "loss" - } - ytitle = title_dict[item] - query = map(lambda x: list(x), zip(*query)) - result = [] - if query: - category_names = map(lambda x: "FS:%4d" % x + name_dict[item], query[0]) - data = query[1:] - bar_ = [color_dict[item]] - result = [ytitle, category_names, bar_, data] - return result - - -class TaskData(object): - def __init__(self, taskid, dbase): - self.__common = CommonData(taskid, dbase) - scenario_list = self.__common.get_scenariolist() - scenario_dic = {} - for scenario in scenario_list: - scenario_dic[scenario] = ScenarioData(taskid, dbase, scenario) - self.__dict__.update(scenario_dic) - - @property - def common(self): - return self.__common - - -class HistoryData(DataProvider): - def get_data(self, task_list, case, provider, ttype, item): - """ - @provider in ["fastlink", "rdp", "l2switch", ""] - @ttype in ["throughput", "frameloss", "latency"] - @item in ["avg", "ratep", "load"] - """ - table = [] - table_head = [] - datas = [] - sizes = [] - for taskid in task_list: - if item == 'ratep': - query = self._dbase.query_bandwidth(taskid, case, provider, ttype) - else: - query = self._dbase.query_avglatency(taskid, case, provider, ttype) - - if query: - data = {} - for size, value in query: - data[size] = value - sizes.extend(data.keys()) - sizes = {}.fromkeys(sizes).keys() - sizes.sort() - datas.append({taskid: data}) - - result = [] - for data in datas: - print data - taskid = data.keys()[0] - data_th = self._dbase.query_taskdate(taskid) - testdata = data[taskid] - item = [data_th] - for size in sizes: - item.append(str(testdata.get(size, ''))) - result.append(item) - - if result: - head_th = "FrameSize (byte)" - table_head = [[head_th] + map(lambda x: " %4d " % (x), sizes)] - table = table_head + result - - return table - - def get_tasklist(self, count=5): - task_list = [] - query = self._dbase.query_tasklist() - if query: - for item in query: - if item.TaskID <= self._taskid: - task_list.append(item.TaskID) - - task_list = task_list[-count:] - return task_list - - def get_history_info(self, case): - provider_dict = {"fastlink": "Fast Link ", "l2switch": "L2Switch ", "rdp": "Kernel RDP "} - ttype_dict = { - "throughput": "Throughput Testing ", - "frameloss": "Frame Loss Testing ", - "latency": "Latency Testing " - } - - items_dict = { - "ratep": "RX Frame Rate(Mpps) ", - "avg": "Average Latency (uSec) " - } - - task_list = self.get_tasklist() - result = [] - - for ttype in cst.TTYPES: - content = {} - if ttype == "latency": - item = "avg" - else: - item = "ratep" - - for provider in cst.PROVIDERS: - table_data = self.get_data(task_list, case, provider, ttype, item) - if table_data: - data = { - "title": provider_dict[provider] + items_dict[item], - "data": table_data - } - content["title"] = ttype_dict[ttype] - content.setdefault("data", []) - content["data"].append(data) - if content: - result.append(content) - print result - return result - - -def unit_test(): - dbase = DbManage() - taskid = dbase.get_last_taskid() - hdata = HistoryData(taskid, dbase) - task_list = hdata.get_tasklist() - - cdata = CommonData(taskid, dbase) - scenario_list = cdata.get_scenariolist() - print scenario_list - - scenario = "Tn" - sdata = ScenarioData(taskid, dbase, scenario) - - case_list = sdata.get_caselist() - print case_list - - case = "Tn-1" - - ttypes = ["throughput", "frameloss"] - items = ["ratep", "load"] - - for provider in cst.PROVIDERS: - for ttype in ttypes: - for item in items: - print provider - print ttype - print item - print hdata.get_data(task_list, case, provider, ttype, item) - - hdata.get_history_info(case) - - -if __name__ == '__main__': - unit_test() diff --git a/vstf/vstf/controller/reporters/report/html/__init__.py b/vstf/vstf/controller/reporters/report/html/__init__.py deleted file mode 100644 index df7d24d0..00000000 --- a/vstf/vstf/controller/reporters/report/html/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - diff --git a/vstf/vstf/controller/reporters/report/html/html_base.py b/vstf/vstf/controller/reporters/report/html/html_base.py deleted file mode 100644 index 5769da79..00000000 --- a/vstf/vstf/controller/reporters/report/html/html_base.py +++ /dev/null @@ -1,43 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - - -import os -import vstf.common.pyhtml as pyhtm - - -class HtmlBase(object): - def __init__(self, provider): - self._page = pyhtm.PyHtml('Html Text') - self._provider = provider - - def save(self, ofile): - if ofile: - os.system('rm -rf %s' % ofile) - self._page.output(ofile) - - def as_string(self): - return self._page.as_string() - - def add_table(self, data): - if data and zip(*data): - self._page.add_table(data) - - def add_style(self): - style = self._provider.get_style - self._page.add_style(style) - - def create(self, ofile='text.html'): - self.add_style() - self.create_story() - self.save(ofile) - return self.as_string() - - def create_story(self): - raise NotImplementedError("abstract HtmlBase") diff --git a/vstf/vstf/controller/reporters/report/html/htmlcreator.py b/vstf/vstf/controller/reporters/report/html/htmlcreator.py deleted file mode 100644 index 695ea37f..00000000 --- a/vstf/vstf/controller/reporters/report/html/htmlcreator.py +++ /dev/null @@ -1,84 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - - -import logging - -import vstf.common.candy_text as candy -from vstf.controller.reporters.report.provider.html_provider import HtmlProvider -from vstf.controller.settings.template_settings import TemplateSettings -from vstf.controller.settings.html_settings import HtmlSettings -from vstf.controller.reporters.report.html.html_base import HtmlBase, pyhtm - -LOG = logging.getLogger(__name__) - - -class HtmlCreator(HtmlBase): - def create_story(self): - self.add_context() - - def add_context(self): - context = self._provider.get_context - self._raw_context(context) - - def _raw_context(self, context, ci=0, si=0, ui=0, level=-1): - _story = [] - for key, value in sorted(context.items()): - LOG.info(key) - LOG.info(value) - _sn, _node, _style = candy.text2tuple(key) - if _node in candy.dom: - if _node == candy.chapter: - ci = _style - elif _node == candy.section: - si = _style - else: - ui = _style - self._raw_context(value, ci, si, ui, level + 1) - - else: - LOG.info("node: %s %s" % (_node, candy.title)) - if _node == candy.title: - assert value - if level in range(len(candy.dom)): - if level == 0: - value[0] = "Chapter %s %s" % (ci, value[0]) - for title in value: - self._page << pyhtm.H2(title) - elif level == 1: - value[0] = "%s.%s %s" % (ci, si, value[0]) - for title in value: - self._page << pyhtm.H3(title) - else: - value[0] = "%s.%s.%s %s" % (ci, si, ui, value[0]) - for title in value: - self._page << pyhtm.H3(title) - - elif _node == candy.table: - self.add_table(value) - elif _node == candy.paragraph: - for para in value: - para = pyhtm.space(2) + para - self._page << pyhtm.P(para) - - -def unit_test(): - from vstf.common.log import setup_logging - setup_logging(level=logging.DEBUG, log_file="/var/log/html-creator.log", clevel=logging.INFO) - - out_file = "vstf_report.html" - - info = TemplateSettings() - html_settings = HtmlSettings() - provider = HtmlProvider(info.settings, html_settings.settings) - reporter = HtmlCreator(provider) - reporter.create(out_file) - -if __name__ == '__main__': - unit_test() diff --git a/vstf/vstf/controller/reporters/report/pdf/__init__.py b/vstf/vstf/controller/reporters/report/pdf/__init__.py deleted file mode 100644 index df7d24d0..00000000 --- a/vstf/vstf/controller/reporters/report/pdf/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - diff --git a/vstf/vstf/controller/reporters/report/pdf/element.py b/vstf/vstf/controller/reporters/report/pdf/element.py deleted file mode 100644 index ef8b54df..00000000 --- a/vstf/vstf/controller/reporters/report/pdf/element.py +++ /dev/null @@ -1,785 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - - -__doc__ = """ -it contains the base element for pdf -eImage is used to draw picture on the pdf document -eDataTable is used to draw table on the pdf document -eGraphicsTable is used to draw plot on the pdf document -eParagraph is used to draw text on the pdf document -""" -from reportlab.platypus import Image, Table -from reportlab.graphics.shapes import Drawing -from reportlab.graphics.charts.lineplots import LinePlot -from reportlab.graphics.charts.linecharts import HorizontalLineChart -from reportlab.platypus.paragraph import Paragraph -from reportlab.graphics.widgets.markers import makeMarker -from reportlab.graphics.charts.legends import Legend -from reportlab.graphics.charts.textlabels import Label -from reportlab.graphics.charts.axes import XValueAxis -from reportlab.graphics.shapes import Group -from reportlab.graphics.charts.barcharts import VerticalBarChart -from vstf.controller.reporters.report.pdf.styles import * - - -class eImage(Image): - """ an image(digital picture)which contains the function of auto zoom picture """ - - def __init__(self, filename, width=None, height=None, kind='direct', mask="auto", lazy=1, hAlign='CENTRE', - vAlign='BOTTOM'): - Image.__init__(self, filename, None, None, kind, mask, lazy) - print height, width - print self.drawHeight, self.drawWidth - if self.drawWidth * height > self.drawHeight * width: - self.drawHeight = width * self.drawHeight / self.drawWidth - self.drawWidth = width - else: - self.drawWidth = height * self.drawWidth / self.drawHeight - self.drawHeight = height - self.hAlign = hAlign - self.vAlign = vAlign - print self.drawHeight, self.drawWidth - - -class eTable(object): - """ an abstract table class, which is contains the base functions to create table """ - - def __init__(self, data, style=TableStyle(name="default")): - self._tablestyle = style - self._table = [] - self._spin = False - self._colWidths = None - self._data = self.analysisData(data) - if self._data: - self.create() - - def analysisData(self, data): - raise NotImplementedError("abstract eTable") - - def create(self): - self._table = Table(self._data, style=self._style, splitByRow=1) - self._table.hAlign = self._tablestyle.table_hAlign - self._table.vAlign = self._tablestyle.table_vAlign - self._table.colWidths = self._tablestyle.table_colWidths - if self._spin or self._colWidths: - self._table.colWidths = self._colWidths - self._table.rowHeights = self._tablestyle.table_rowHeights - - @property - def table(self): - return self._table - - -class eCommonTable(eTable): - def analysisData(self, data): - self._style = [ - ('ALIGN', (0, 0), (-1, -1), 'CENTER'), - ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), - ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), - ('BOX', (0, 0), (-1, -1), 1.2, colors.black) - ] - return data - - -class eConfigTable(eTable): - def analysisData(self, data): - self._style = [ - ('ALIGN', (0, 0), (-1, -1), 'CENTER'), - ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), - ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), - ('BOX', (0, 0), (-1, -1), 1, colors.black), - ('SPAN', (2, 0), (3, 0)), - ('SPAN', (2, 1), (3, 1)), - ('SPAN', (2, 8), (3, 8)), - ('SPAN', (2, 9), (3, 9)), - ('SPAN', (2, 10), (3, 10)), - ('SPAN', (0, 0), (0, 7)), - ('SPAN', (0, 8), (0, 10)), - ('SPAN', (0, 11), (0, 19)), - ('SPAN', (1, 2), (1, 6)), - ('SPAN', (1, 12), (1, 13)), - ('SPAN', (1, 14), (1, 16)), - ('SPAN', (1, 17), (1, 19)), - ('SPAN', (2, 3), (2, 6)) - ] - return data - - -class eSummaryTable(eTable): - def analysisData(self, data): - self._style = [ - ('ALIGN', (0, 0), (-1, -1), 'CENTER'), - ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), - ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), - ('BOX', (0, 0), (-1, -1), 1, colors.black), - ('SPAN', (0, 0), (0, 1)), - ('SPAN', (1, 0), (4, 0)), - ('SPAN', (5, 0), (-1, 0)) - ] - return data - - -class eGitInfoTable(eTable): - def analysisData(self, data): - self._style = [ - ('ALIGN', (0, 0), (-1, -1), 'CENTER'), - ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), - ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), - ('BOX', (0, 0), (-1, -1), 1, colors.black), - ('SPAN', (0, 0), (0, 2)), - ('SPAN', (0, 3), (0, 5)), - ('SPAN', (0, 6), (0, 8)) - ] - return data - - -class eScenarioTable(eTable): - def analysisData(self, data): - self._style = [ - ('ALIGN', (0, 0), (-1, -1), 'CENTER'), - ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), - ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), - ('BOX', (0, 0), (-1, -1), 1, colors.black), - ('ALIGN', (2, 1), (-1, -1), 'LEFT'), - ('SPAN', (0, 1), (0, 6)), - ('SPAN', (0, 7), (0, 12)), - ('SPAN', (0, 13), (0, 16)), - ('SPAN', (0, 17), (0, 20)) - ] - return data - - -class eOptionsTable(eTable): - def analysisData(self, data): - self._style = [ - ('ALIGN', (0, 0), (-1, -1), 'CENTER'), - ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), - ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), - ('BOX', (0, 0), (-1, -1), 1, colors.black), - ('SPAN', (2, 0), (4, 0)), - ('SPAN', (2, 1), (4, 1)), - ('SPAN', (0, 0), (0, -1)), - ('SPAN', (1, 2), (1, 16)), - ('SPAN', (1, 17), (1, 19)), - ('SPAN', (1, 20), (1, 22)), - ('SPAN', (1, 23), (1, 24)), - ('SPAN', (2, 2), (2, 4)), - ('SPAN', (2, 5), (2, 12)), - ('SPAN', (2, 13), (2, 16)), - ('SPAN', (2, 17), (2, 19)), - ('SPAN', (2, 20), (2, 22)), - ('SPAN', (2, 23), (2, 24)) - ] - return data - - -class eProfileTable(eTable): - def analysisData(self, data): - self._style = [ - ('ALIGN', (0, 0), (-1, -1), 'CENTER'), - ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), - ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), - ('BOX', (0, 0), (-1, -1), 1, colors.black), - ('SPAN', (0, 1), (0, -1)), - ('SPAN', (1, 0), (2, 0)), - ] - return data - - -class eDataTable(eTable): - def analysisData(self, data): - result = data - self._style = [ - ('ALIGN', (0, 0), (-1, -1), 'CENTER'), - ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), - ('LEADING', (0, 0), (-1, -1), 18), - ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), - ('BOX', (0, 0), (-1, -1), 1, colors.black), - ('LINEBEFORE', (1, 0), (1, -1), 0.8, colors.black), - # ('LINEBEFORE', (3, 0), (3, -1), 1, colors.black), - # ('LINEBEFORE', (5, 0), (5, -1), 1, colors.black), - ('LINEBELOW', (0, 0), (-1, 0), 0.8, colors.black), - # ('SPAN', (0, 0), (0, 1)), - # ('SPAN', (1, 0), (2, 0)), - # ('SPAN', (3, 0), (4, 0)) - ] - if self._spin is True: - print "start spin" - result = map(list, zip(*result)) - style = [] - for value in self._style: - value = list(value) - value[1] = (value[1][1], value[1][0]) - value[2] = (value[2][1], value[2][0]) - if value[0] == 'LINEBELOW': - value[0] = 'LINEAFTER' - elif value[0] == 'LINEBEFORE': - value[0] = 'LINEABOVE' - value = tuple(value) - style.append(value) - self._style = style - return result - - -class eGraphicsTable(eTable): - def analysisData(self, data): - self._style = [ - ('ALIGN', (0, 0), (-1, -1), 'CENTER'), - ('VALIGN', (0, 0), (-1, -1), 'MIDDLE') - ] - return data - - -class noScaleXValueAxis(XValueAxis): - def __init__(self): - XValueAxis.__init__(self) - - def makeTickLabels(self): - g = Group() - if not self.visibleLabels: return g - - f = self._labelTextFormat # perhaps someone already set it - if f is None: - f = self.labelTextFormat or (self._allIntTicks() and '%.0f' or str) - elif f is str and self._allIntTicks(): - f = '%.0f' - elif hasattr(f, 'calcPlaces'): - f.calcPlaces(self._tickValues) - post = self.labelTextPostFormat - scl = self.labelTextScale - pos = [self._x, self._y] - d = self._dataIndex - pos[1 - d] = self._labelAxisPos() - labels = self.labels - if self.skipEndL != 'none': - if self.isXAxis: - sk = self._x - else: - sk = self._y - if self.skipEndL == 'start': - sk = [sk] - else: - sk = [sk, sk + self._length] - if self.skipEndL == 'end': - del sk[0] - else: - sk = [] - - nticks = len(self._tickValues) - nticks1 = nticks - 1 - for i, tick in enumerate(self._tickValues): - label = i - nticks - if label in labels: - label = labels[label] - else: - label = labels[i] - if f and label.visible: - v = self.scale(i) - if sk: - for skv in sk: - if abs(skv - v) < 1e-6: - v = None - break - if v is not None: - if scl is not None: - t = tick * scl - else: - t = tick - if isinstance(f, str): - txt = f % t - elif isSeq(f): - # it's a list, use as many items as we get - if i < len(f): - txt = f[i] - else: - txt = '' - elif hasattr(f, '__call__'): - if isinstance(f, TickLabeller): - txt = f(self, t) - else: - txt = f(t) - else: - raise ValueError('Invalid labelTextFormat %s' % f) - if post: txt = post % txt - pos[d] = v - label.setOrigin(*pos) - label.setText(txt) - - # special property to ensure a label doesn't project beyond the bounds of an x-axis - if self.keepTickLabelsInside: - if isinstance(self, XValueAxis): # not done yet for y axes - a_x = self._x - if not i: # first one - x0, y0, x1, y1 = label.getBounds() - if x0 < a_x: - label = label.clone(dx=label.dx + a_x - x0) - if i == nticks1: # final one - a_x1 = a_x + self._length - x0, y0, x1, y1 = label.getBounds() - if x1 > a_x1: - label = label.clone(dx=label.dx - x1 + a_x1) - g.add(label) - - return g - - def ___calcScaleFactor(self): - """Calculate the axis' scale factor. - This should be called only *after* the axis' range is set. - Returns a number. - """ - self._scaleFactor = self._length / (len(self._tickValues) + 1) - return self._scaleFactor - - def scale(self, value): - """Converts a numeric value to a plotarea position. - The chart first configures the axis, then asks it to - """ - assert self._configured, "Axis cannot scale numbers before it is configured" - if value is None: value = 0 - # this could be made more efficient by moving the definition of org and sf into the configuration - org = (self._x, self._y)[self._dataIndex] - sf = self._length / (len(self._tickValues) + 1) - if self.reverseDirection: - sf = -sf - org += self._length - return org + sf * (value + 1) - - -class noScaleLinePlot(LinePlot): - def __init__(self): - LinePlot.__init__(self) - self.xValueAxis = noScaleXValueAxis() - - def calcPositions(self): - """Works out where they go. - - Sets an attribute _positions which is a list of - lists of (x, y) matching the data. - """ - self._seriesCount = len(self.data) - self._rowLength = max(map(len, self.data)) - - self._positions = [] - for rowNo in range(len(self.data)): - line = [] - len_row = len(self.data[rowNo]) - for colNo in range(len_row): - datum = self.data[rowNo][colNo] # x, y value - x = self.x + self.width / (len_row + 1) * (colNo + 1) - self.xValueAxis.labels[colNo].x = self.x + self.width / (len_row + 1) * (colNo + 1) - y = self.yValueAxis.scale(datum[1]) - # print self.width, " ", x - line.append((x, y)) - self._positions.append(line) - - -# def _innerDrawLabel(self, rowNo, colNo, x, y): -# return None -class eLinePlot(object): - def __init__(self, data, style): - self._lpstyle = style - self._linename = data[0] - self._data = self.analysisData(data[1:]) - if self._data: - self.create() - - @property - def draw(self): - return self._draw - - def analysisData(self, data): - columns = len(data) - # print data - data = map(list, zip(*data)) - rows = len(data) - - for i in range(rows): - for j in range(columns): - data[i][j] = float(data[i][j]) - self._linename = self._linename[1:] - """ - delcnt = 0 - delrows = [] - for i in range(columns): - delrows.append(0.0) - del_line = [self._linename[0]] - for i in range(rows): - for j in range(columns): - data[i][j] = float(data[i][j]) - if data[i] == delrows: - delcnt += 1 - del_line.append(self._linename[i]) - for i in range(delcnt): - data.remove(delrows) - for name in del_line: - self._linename.remove(name) - - rows = len(data) - """ - # print rows - # print data - xvalueSteps = data[0] - xvalueMin = data[0][0] - xvalueMax = data[0][0] - yvalueMin = data[1][0] - yvalueMax = data[1][0] - yvalueSteps = [] - result = [] - for j in range(columns): - if xvalueMin > data[0][j]: - xvalueMin = data[0][j] - if xvalueMax < data[0][j]: - xvalueMax = data[0][j] - - for i in range(rows - 1): - lst = [] - for j in range(columns): - lst.append((data[0][j], data[i + 1][j])) - if yvalueMin > data[i + 1][j]: - yvalueMin = data[i + 1][j] - if yvalueMax < data[i + 1][j]: - yvalueMax = data[i + 1][j] - yvalueSteps.append(int(data[i + 1][j] * 2.5) / 2.5) - result.append(tuple(lst)) - xvalueMin = int(xvalueMin) / 100 * 100 - xvalueMax = int(xvalueMax) / 100 * 100 + 200 - yvalueMin = int(yvalueMin) * 1.0 - 1 - if yvalueMin < 0: - yvalueMin = 0.0 - yvalueMax = int(yvalueMax) + 2.0 - yvalueSteps.append(yvalueMin) - yvalueSteps.append(yvalueMax) - yvalueSteps = {}.fromkeys(yvalueSteps).keys() - - self._xvalue = (xvalueMin, xvalueMax, xvalueSteps) - self._yvalue = (yvalueMin, yvalueMax, yvalueSteps) - print result - return result - - def create(self): - lpw = self._lpstyle.width - lph = self._lpstyle.height - draw = Drawing(lpw, lph) - line_cnts = len(self._linename) - # lp = noScaleLinePlot() - lp = LinePlot() - lg_line = (line_cnts + 3) / 4 - lp.x = self._lpstyle.left - lp.y = self._lpstyle.bottom - - lp.height = lph - self._lpstyle.bottom * (lg_line + 1.5) - lp.width = lpw - lp.x * 2 - lp.data = self._data - lp.joinedLines = 1 - lp.strokeWidth = self._lpstyle.strokeWidth - line_cnts = len(self._data) - sytle_cnts = len(self._lpstyle.linestyle) - color_paris = [] - for i in range(line_cnts): - styleIndex = i % sytle_cnts - lp.lines[i].strokeColor = self._lpstyle.linestyle[styleIndex][0] - lp.lines[i].symbol = makeMarker(self._lpstyle.linestyle[styleIndex][1]) - lp.lines[i].strokeWidth = self._lpstyle.linestyle[styleIndex][2] - color_paris.append((self._lpstyle.linestyle[styleIndex][0], self._linename[i])) - # lp.lineLabels[i].strokeColor = self._lpstyle.linestyle[styleIndex][0] - - lp.lineLabelFormat = self._lpstyle.format[0] - - lp.strokeColor = self._lpstyle.strokeColor - - lp.xValueAxis.valueMin, lp.xValueAxis.valueMax, lp.xValueAxis.valueSteps = self._xvalue - # valueMin, valueMax, xvalueSteps = self._xvalue - # lp.xValueAxis.valueStep = (lp.xValueAxis.valueMax - lp.xValueAxis.valueMin)/len(xvalueSteps) - # lp.xValueAxis.valueSteps = map(lambda x: str(x), xvalueSteps) - - lp.yValueAxis.valueMin, lp.yValueAxis.valueMax, lp.yValueAxis.valueSteps = self._yvalue - - - - # lp.xValueAxis.forceZero = 0 - # lp.xValueAxis.avoidBoundFrac = 1 - # lp.xValueAxis.tickDown = 3 - # lp.xValueAxis.visibleGrid = 1 - # lp.xValueAxis.categoryNames = '64 256 512 1400 1500 4096'.split(' ') - - lp.xValueAxis.labelTextFormat = self._lpstyle.format[1] - lp.yValueAxis.labelTextFormat = self._lpstyle.format[2] - - delsize = int(lp.xValueAxis.valueMax / 2000) - lp.xValueAxis.labels.fontSize = self._lpstyle.labelsfont - lp.xValueAxis.labels.angle = 25 - - lp.yValueAxis.labels.fontSize = self._lpstyle.labelsfont - lp.lineLabels.fontSize = self._lpstyle.labelsfont - delsize - draw.add(lp) - - lg = Legend() - lg.colorNamePairs = color_paris - lg.fontName = 'Helvetica' - lg.fontSize = 7 - - lg.x = self._lpstyle.left * 3 - lg.y = self._lpstyle.bottom * (1 + lg_line) + lp.height - - lg.dxTextSpace = 5 - lg.dy = 5 - lg.dx = 20 - lg.deltax = 60 - lg.deltay = 0 - lg.columnMaximum = 1 - lg.alignment = 'right' - draw.add(lg) - self._draw = draw - - -class eHorizontalLineChart(object): - def __init__(self, data, style): - self._lcstyle = style - if len(data) < 1: - return - self._linename = data[0] - self._data = self.analysisData(data[1:]) - if self._data: - self.create() - - @property - def draw(self): - return self._draw - - def analysisData(self, data): - columns = len(data) - data = map(list, zip(*data)) - self._catNames = data[0] - self._linename = self._linename[1:] - data = data[1:] - rows = len(data) - - yvalueMin = float(data[0][0]) - yvalueMax = float(data[0][0]) - yvalueSteps = [] - result = [] - - for rowNo in range(rows): - for columnNo in range(columns): - data[rowNo][columnNo] = float(data[rowNo][columnNo]) - if yvalueMin > data[rowNo][columnNo]: - yvalueMin = data[rowNo][columnNo] - if yvalueMax < data[rowNo][columnNo]: - yvalueMax = data[rowNo][columnNo] - yvalueSteps.append(int(data[rowNo][columnNo] * 1.0) / 1.0) - result.append(tuple(data[rowNo])) - - yvalueMin = int(yvalueMin) * 1.0 - 1 - if yvalueMin < 0: - yvalueMin = 0.0 - yvalueMax = int(yvalueMax) + 2.0 - yvalueSteps.append(yvalueMin) - yvalueSteps.append(yvalueMax) - yvalueSteps = {}.fromkeys(yvalueSteps).keys() - - self._value = (yvalueMin, yvalueMax, yvalueSteps) - print result - return result - - def create(self): - dw = self._lcstyle.width - dh = self._lcstyle.height - draw = Drawing(dw, dh) - - lc = HorizontalLineChart() - line_cnts = len(self._linename) - - lg_line = (line_cnts + 3) / 4 - lc.height = dh - self._lcstyle.bottom * (lg_line + 1.5) - lc.width = dw - lc.x * 2 - lc.x = self._lcstyle.left - lc.y = self._lcstyle.bottom - - lc.data = self._data - - lc.strokeColor = self._lcstyle.strokeColor - lc.strokeWidth = self._lcstyle.strokeWidth - lc.useAbsolute = 1 - lc.groupSpacing = lc.width * 2.0 / len(self._catNames) - lc.joinedLines = 1 - lc.lineLabelFormat = self._lcstyle.format[0] - - lc.valueAxis.valueMin, lc.valueAxis.valueMax, lc.valueAxis.valueSteps = self._value - lc.valueAxis.labelTextFormat = self._lcstyle.format[1] - lc.valueAxis.labels.fontSize = self._lcstyle.labelsfont - - lc.categoryAxis.categoryNames = self._catNames - lc.categoryAxis.labels.boxAnchor = 'ne' - lc.categoryAxis.labels.dx = lc.width / 2.0 / len(self._catNames) - lc.categoryAxis.labels.dy = -6 - lc.categoryAxis.labels.angle = 10 - lc.categoryAxis.labels.fontSize = self._lcstyle.labelsfont - # lc.categoryAxis.visibleGrid = 1 - # lc.categoryAxis.tickUp = 100 - # lc.categoryAxis.tickDown = 50 - # lc.categoryAxis.gridEnd = dh - sytle_cnts = len(self._lcstyle.linestyle) - color_paris = [] - for i in range(line_cnts): - styleIndex = i % sytle_cnts - lc.lines[i].strokeColor = self._lcstyle.linestyle[styleIndex][0] - lc.lines[i].symbol = makeMarker(self._lcstyle.linestyle[styleIndex][1]) - lc.lines[i].strokeWidth = self._lcstyle.linestyle[styleIndex][2] - color_paris.append((self._lcstyle.linestyle[styleIndex][0], self._linename[i])) - - lc.lineLabels.fontSize = self._lcstyle.labelsfont - 2 - - draw.add(lc) - - lg = Legend() - lg.colorNamePairs = color_paris - lg.fontName = 'Helvetica' - lg.fontSize = 7 - # lg.x = dw /2 - # lg.y = self._lcstyle.bottom *(1.5 + lg_line) - - lg.x = self._lcstyle.left * 3 - lg.y = self._lcstyle.bottom * (1 + lg_line) + lc.height - - lg.dxTextSpace = 5 - lg.dy = 5 - lg.dx = 20 - lg.deltax = 60 - lg.deltay = 0 - lg.columnMaximum = 1 - lg.alignment = 'right' - draw.add(lg) - self._draw = draw - - -class eBarChartColumn(object): - def __init__(self, data, style): - self._bcstyle = style - if len(data) < 4: - return - self._data = self.analysisData(data) - if self._data: - self.create() - - @property - def draw(self): - return self._draw - - def analysisData(self, data): - self._ytitle = data[0] - self._name = data[1] - self._bar = data[2] - bar_data = data[3] - result = [] - for bar in bar_data: - bar = map(lambda x: float(x), bar) - result.append(tuple(bar)) - return result - - def create(self): - dw = self._bcstyle.width - dh = self._bcstyle.height - draw = Drawing(dw, dh) - - bc = VerticalBarChart() - bar_cnt = len(self._bar) - lg_line = (bar_cnt + 3) / 4 - - bc.width = dw - self._bcstyle.left - self._bcstyle.right - bc.height = dh - self._bcstyle.top - self._bcstyle.bottom - if bar_cnt > 1: - bc.height -= lg_line * 15 - - bc.x = self._bcstyle.left - bc.y = self._bcstyle.bottom - color_paris = [] - for i in range(bar_cnt): - bc.bars[i].fillColor = self._bcstyle.pillarstyle[self._bar[i]][0] - color_paris.append((self._bcstyle.pillarstyle[self._bar[i]][0], self._bar[i])) - - bc.fillColor = self._bcstyle.background - bc.barLabels.fontName = 'Helvetica' - bc.barLabelFormat = self._bcstyle.pillarstyle[self._bar[0]][1] - bc.barLabels.fontSize = self._bcstyle.labelsfont - bc.barLabels.dy = self._bcstyle.labelsfont - bc.valueAxis.labels.fontName = 'Helvetica' - bc.valueAxis.labels.fontSize = self._bcstyle.labelsfont - bc.valueAxis.forceZero = 1 - bc.valueAxis.valueMin = 0 - - bc.data = self._data - bc.barSpacing = self._bcstyle.barSpacing - bc.groupSpacing = self._bcstyle.groupSpacing / bar_cnt - bc.valueAxis.avoidBoundFrac = 1 - bc.valueAxis.gridEnd = dw - self._bcstyle.right - bc.valueAxis.tickLeft = self._bcstyle.tick - bc.valueAxis.visibleGrid = 1 - bc.categoryAxis.categoryNames = self._name - bc.categoryAxis.tickDown = self._bcstyle.tick - bc.categoryAxis.labels.fontName = 'Helvetica' - bc.categoryAxis.labels.fontSize = self._bcstyle.labelsfont - bc.categoryAxis.labels.dy = -27 - bc.categoryAxis.labels.angle = -90 - draw.add(bc) - lb = Label() - lb.fontName = 'Helvetica' - lb.fontSize = 7 - lb.x = 12 - lb.y = 80 - lb.angle = 90 - lb.textAnchor = 'middle' - lb.maxWidth = 100 - lb.height = 20 - lb._text = self._ytitle - draw.add(lb) - if bar_cnt > 1: - lg = Legend() - lg.colorNamePairs = color_paris - lg.fontName = 'Helvetica' - lg.fontSize = 7 - - lg.x = self._bcstyle.left + bc.width / (bar_cnt + 1) - lg.y = dh - self._bcstyle.top - lg_line * 5 - - lg.dxTextSpace = 5 - lg.dy = 5 - lg.dx = 25 - lg.deltax = 80 - lg.deltay = 0 - lg.columnMaximum = 1 - lg.alignment = 'right' - draw.add(lg) - - self._draw = draw - - -class eParagraph(object): - def __init__(self, data, style): - self._pstyle = style - self._data = self.analysisData(data) - self.create() - - def analysisData(self, data): - result = "" - for dstr in data: - if self._pstyle.name == 'ps_body': - # dstr = "<i>" + dstr + "</i><br/>" - dstr = dstr + "<br/>" - else: - dstr = dstr + "<br/>" - result += dstr - return result - - def create(self): - self._para = Paragraph(self._data, self._pstyle) - - @property - def para(self): - return self._para diff --git a/vstf/vstf/controller/reporters/report/pdf/pdfcreator.py b/vstf/vstf/controller/reporters/report/pdf/pdfcreator.py deleted file mode 100644 index c33974ec..00000000 --- a/vstf/vstf/controller/reporters/report/pdf/pdfcreator.py +++ /dev/null @@ -1,127 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - - -from vstf.controller.reporters.report.pdf.pdftemplate import PdfVswitch -from vstf.controller.reporters.report.pdf.story import TitleStory, SpaceStory, ImageStory, TableStory, \ - LinePlotStory, Story, TableOfContentsStory, PageBreakStory, ParagraphStory, BarChartStory -import vstf.common.candy_text as candy -from vstf.controller.reporters.report.provider.pdf_provider import PdfProvider -from vstf.controller.settings.template_settings import TemplateSettings - -import os -import logging - -LOG = logging.getLogger(__name__) - - -class PdfCreator(object): - def __init__(self, provider): - self._provider = provider - self._story = [] - self._pdf = None - - def create_pdf(self): - theme = self._provider.get_theme - self._pdf = PdfVswitch(theme["title"], - theme["logo"], - theme["header"], - theme["footer"], - theme["note"], - theme["style"]) - - def save_pdf(self, ofile): - self._pdf.generate(self._story, ofile) - - def add_coverpage(self): - story = Story() - story = PageBreakStory(story) - self._story += story.storylist - - def add_contents(self): - if self._provider.ifcontents: - story = Story() - story = TableOfContentsStory(story) - self._story += story.storylist - - def create_story(self): - self.add_coverpage() - self.add_contents() - self.add_context() - - def create(self, ofile): - self.create_pdf() - self.create_story() - self.save_pdf(ofile) - - def add_context(self): - context = self._provider.get_context - self._story += self._raw_context(context) - - def _raw_context(self, context, ci=0, si=0, ui=0, level=-1): - _story = [] - for key, value in sorted(context.items()): - LOG.info(key) - LOG.info(value) - _sn, _node, _style = candy.text2tuple(key) - if _node in candy.dom: - if _node == candy.chapter: - ci = _style - elif _node == candy.section: - si = _style - else: - ui = _style - _story += self._raw_context(value, ci, si, ui, level + 1) - - else: - story = Story() - LOG.info("node: %s %s" % (_node, candy.title)) - if _node == candy.title: - assert value - if level in range(len(candy.dom)): - if level == 0: - value[0] = "Chapter %s %s" % (ci, value[0]) - story = PageBreakStory(story) - elif level == 1: - value[0] = "%s.%s %s" % (ci, si, value[0]) - else: - value[0] = "%s.%s.%s %s" % (ci, si, ui, value[0]) - LOG.info(value) - story = TitleStory(story, data=value, style=_style) - elif _node == candy.table: - story = TableStory(story, data=value, style=_style) - elif _node == candy.figure: - story = ImageStory(story, data=value, style=_style) - elif _node == candy.paragraph: - story = ParagraphStory(story, data=value, style=_style) - elif _node == candy.plot: - story = LinePlotStory(story, data=value, style=_style) - elif _node == candy.chart: - story = BarChartStory(story, data=value, style=_style) - elif _node == candy.space: - assert isinstance(value, int) - for i in range(value): - story = SpaceStory(story) - _story += story.storylist - return _story - - -def main(): - from vstf.common.log import setup_logging - setup_logging(level=logging.DEBUG, log_file="/var/log/pdf-creator.log", clevel=logging.INFO) - - out_file = "vstf_report.pdf" - - info = TemplateSettings() - provider = PdfProvider(info.settings) - reporter = PdfCreator(provider) - reporter.create(out_file) - -if __name__ == '__main__': - main() diff --git a/vstf/vstf/controller/reporters/report/pdf/pdftemplate.py b/vstf/vstf/controller/reporters/report/pdf/pdftemplate.py deleted file mode 100644 index 69c65401..00000000 --- a/vstf/vstf/controller/reporters/report/pdf/pdftemplate.py +++ /dev/null @@ -1,114 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - -import time - -from reportlab.platypus.doctemplate import SimpleDocTemplate -from reportlab.platypus import PageBreak -from vstf.controller.reporters.report.pdf.styles import TemplateStyle, ps_head_lv1, ps_head_lv2, ps_head_lv3 -import vstf.common.constants as cst - - -class BaseDocTemplate(SimpleDocTemplate): - def __init__(self, filename, **kw): - self.allowSplitting = 0 - SimpleDocTemplate.__init__(self, filename, **kw) - - def afterFlowable(self, flowable): - """Registers TOC entries.""" - if flowable.__class__.__name__ == 'Paragraph': - text = flowable.getPlainText() - style = flowable.style.name - if style == ps_head_lv1.name: - self.notify('TOCEntry', (0, text, self.page - 1)) - elif style == ps_head_lv2.name: - self.notify('TOCEntry', (1, text, self.page - 1)) - elif style == ps_head_lv3.name: - self.notify('TOCEntry', (2, text, self.page - 1)) - - -class PdfTemplate(object): - def __init__(self, title, logo, header, footer, note=[], style="default"): - self._style = TemplateStyle(name=style) - self._title = title - self._logo = logo[0] - #self._header = header[0] - self._footer = footer - self._note = note - info = " Generated on %s " % time.strftime(cst.TIME_FORMAT2, time.localtime()) - self._note += [info] - - def myFirstPage(self, canvas, doc): - raise NotImplementedError("abstract StoryDecorator") - - def myLaterPages(self, canvas, doc): - raise NotImplementedError("abstract StoryDecorator") - - def generate(self, story, output): - sizes = (self._style.page_wight, self._style.page_height) - doc = BaseDocTemplate(output, pagesize=sizes) - # doc.build(story, onFirstPage=self.myFirstPage, onLaterPages=self.myLaterPages) - doc.multiBuild(story, onFirstPage=self.myFirstPage, onLaterPages=self.myLaterPages) - - -class PdfVswitch(PdfTemplate): - def myFirstPage(self, canvas, doc): - canvas.saveState() - title_lines = len(self._title) - line_size = [self._style.title_size] * title_lines - line_size.append(0) - - canvas.drawImage(self._logo, - (self._style.page_wight - self._style.logo_width) / 2.0, - self._style.page_height / 2.0 + (1 + self._style.title_leading) * reduce(lambda x, y: x + y, - line_size), - self._style.logo_width, - self._style.logo_height - ) - for i in range(title_lines): - canvas.setFont(self._style.title_font, line_size[i]) - canvas.drawCentredString(self._style.page_wight / 2.0, - self._style.page_height / 2.0 + (1 + self._style.title_leading) * reduce( - lambda x, y: x + y, line_size[i + 1:]), - self._title[i] - ) - size = self._style.body_size - canvas.setFont(self._style.body_font, size) - note_line = len(self._note) - - for i in range(note_line): - print self._note[i] - canvas.drawCentredString(self._style.page_wight / 2.0, - self._style.page_height / 5.0 + (1 + self._style.body_leading) * size * ( - note_line - i - 1), - self._note[i] - ) - size = self._style.body_size - 2 - canvas.setFont(self._style.body_font, size) - canvas.drawCentredString(self._style.page_wight / 2.0, - self._style.page_bottom / 2.0 + (1 + self._style.body_leading) * size, - self._footer[0]) - canvas.restoreState() - - def myLaterPages(self, canvas, doc): - canvas.saveState() - canvas.setLineWidth(self._style.line_width) - canvas.line(self._style.page_left, - self._style.page_height - self._style.page_top, - self._style.page_wight - self._style.page_right, - self._style.page_height - self._style.page_top - ) - size = self._style.body_size - 2 - canvas.setFont(self._style.body_font, size) - canvas.drawCentredString(self._style.page_wight / 2.0, - self._style.page_bottom - 24, - "%s%s Page %2d " % (self._footer[0], " " * 8, doc.page - 1) - ) - canvas.restoreState() - diff --git a/vstf/vstf/controller/reporters/report/pdf/story.py b/vstf/vstf/controller/reporters/report/pdf/story.py deleted file mode 100644 index 940c20fb..00000000 --- a/vstf/vstf/controller/reporters/report/pdf/story.py +++ /dev/null @@ -1,186 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - -__doc__ = """ -Story Decorator contains ImageStory, HeaderStory, PageBreakStory, -TableStory, LinePlotStory, TitleStory, ParagraphStory -""" -import sys -import os -from reportlab.platypus import PageBreak -from reportlab.lib import colors -from reportlab.platypus.tableofcontents import TableOfContents -from styles import * -from element import * - - -class Story(object): - def __init__(self): - self._storylist = [] - - @property - def storylist(self): - return self._storylist - - -class StoryDecorator(Story): - def __init__(self, story, data=None, style=None): - self._story = story - self._data = data - self._style = style - print self._data - self.new_story() - - # print self._story.storylist - @property - def storylist(self): - return self._story.storylist - - def new_story(self): - raise NotImplementedError("abstract StoryDecorator") - - -class ImageStory(StoryDecorator): - def new_story(self): - print "Image Story" - for filename in self._data: - if os.path.exists(filename) == False: - print "not find %s" % filename - continue - if 'Traffic-types' in filename: - style = is_traffic - image_height = style.image_height - image_width = style.image_width - image_hAlign = style.image_hAlign - image_vAlign = style.image_vAlign - self._story.storylist.append( - eImage(filename, image_width, image_height, hAlign=image_hAlign, vAlign=image_vAlign)) - else: - style = is_default - image_height = style.image_height - image_width = style.image_width - image_hAlign = style.image_hAlign - image_vAlign = style.image_vAlign - # self._story.storylist.append(eGraphicsTable([[' ' * 5, eImage(filename, image_width, image_height, hAlign=image_hAlign, vAlign=image_vAlign)]], ts_left).table) - self._story.storylist.append( - eImage(filename, image_width, image_height, hAlign=image_hAlign, vAlign=image_vAlign)) - - -class HeaderStory(StoryDecorator): - def new_story(self): - print "header story" - self._story.storylist.append(PageBreak()) - - -class PageBreakStory(StoryDecorator): - def new_story(self): - print "PageBreak story" - self._story.storylist.append(PageBreak()) - - -class TableOfContentsStory(StoryDecorator): - def new_story(self): - print "TableOfContents story" - self._data = [" ", " ", "Table Of Contents", ""] - style = ps_head_lv4 - self._story.storylist.append(eParagraph(self._data, style).para) - toc = TableOfContents() - toc.levelStyles = [ps_head_lv7, ps_head_lv8, ps_head_lv9] - self._story.storylist.append(toc) - - -class SpaceStory(StoryDecorator): - def new_story(self): - style = ps_space - self._story.storylist.append(eParagraph([" ", " "], style).para) - - -class TableStory(StoryDecorator): - def new_story(self): - print "table story" - style = ts_default - if self._style == 1: - self._story.storylist.append(eDataTable(self._data, style).table) - elif self._style ==2: - style = ts_left - self._story.storylist.append(eCommonTable(self._data, style).table) - elif self._style == 3: - self._story.storylist.append(eConfigTable(self._data, style).table) - elif self._style == 4: - self._story.storylist.append(eOptionsTable(self._data, style).table) - elif self._style == 5: - self._story.storylist.append(eProfileTable(self._data, style).table) - elif self._style == 6: - self._story.storylist.append(eSummaryTable(self._data, style).table) - elif self._style == 7: - self._story.storylist.append(eScenarioTable(self._data, style).table) - elif self._style == 8: - self._story.storylist.append(eGitInfoTable(self._data, style).table) - - -class LinePlotStory(StoryDecorator): - def new_story(self): - print "LinePlot" - style = lps_default - if not self._data: - print "data error " - return - data = eGraphicsTable([[eLinePlot(self._data, style).draw]]).table - if data: - self._story.storylist.append(data) - - -class LineChartStory(StoryDecorator): - def new_story(self): - print "LineChartStory: " - style = lcs_default - if not self._data: - print "data error " - return - data = eGraphicsTable([[eHorizontalLineChart(self._data, style).draw]]).table - if data: - self._story.storylist.append(data) - - -class BarChartStory(StoryDecorator): - def new_story(self): - print "BarChartStory: " - style = bcs_default - if not self._data: - print "data error " - return - - data = eGraphicsTable([[eBarChartColumn(self._data, style).draw]]).table - if data: - self._story.storylist.append(data) - - -class ParagraphStory(StoryDecorator): - def new_story(self): - print "Paragraph Story" - style = ps_body - if not self._data: - print "data error " - return - data = eParagraph(self._data, style).para - if data: - self._story.storylist.append(data) - - -class TitleStory(StoryDecorator): - def new_story(self): - print "Paragraph Story" - if self._style - 1 in range(9): - style = eval("ps_head_lv" + "%d" % self._style) - else: - style = ps_body - # print style - # print self._data - - self._story.storylist.append(eParagraph(self._data, style).para) diff --git a/vstf/vstf/controller/reporters/report/pdf/styles.py b/vstf/vstf/controller/reporters/report/pdf/styles.py deleted file mode 100644 index 2860c245..00000000 --- a/vstf/vstf/controller/reporters/report/pdf/styles.py +++ /dev/null @@ -1,206 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - -from reportlab.lib.styles import PropertySet -from reportlab.lib.pagesizes import A4 -from reportlab.lib import colors -from reportlab.lib.styles import ParagraphStyle -import reportlab.lib.enums as ens - - -class TemplateStyle(PropertySet): - defaults = dict( - page_height=A4[1], - page_wight=A4[0], - page_left=78, - page_top=60, - page_bottom=70, - page_right=78, - title_size=16, - title_leading=1.25, - title_font='Courier-Bold', - body_size=10, - body_leading=0.8, - body_font='Courier', - line_width=1, - logo_width=131.2, - logo_height=127.7 - ) - - -class ImageStyle(PropertySet): - defaults = dict( - image_height=165, - image_width=175, - image_hAlign='CENTRE', # LEFT,CENTRE or RIGHT - image_vAlign='MIDDLE' # BOTTOM,MIDDLE or TOP - ) - - -class TableStyle(PropertySet): - defaults = dict( - table_hAlign='CENTRE', # LEFT,CENTRE or RIGHT - table_vAlign='MIDDLE', # BOTTOM,MIDDLE or TOP - table_colWidths=None, - table_rowHeights=None - ) - - -class LinePlotStyle(PropertySet): - defaults = dict( - width=430, - height=400, - left=30, - bottom=20, - strokeColor=colors.black, - strokeWidth=1, - format=('%4.2f', '%4.0f', '%3.1f'), - labelsfont=7, - linestyle=[ - (colors.red, 'Circle', 1.5), - (colors.blue, 'Diamond', 1.5), - (colors.gold, 'Square', 1.5), - (colors.green, 'Triangle', 1.5), - (colors.pink, 'FilledCircle', 1.5), - (colors.lightblue, 'FilledDiamond', 1.5), - (colors.lightgreen, 'FilledTriangle', 1.5) - ] - ) - - -class LineChartStyle(PropertySet): - defaults = dict( - width=430, - height=400, - left=30, - bottom=20, - strokeColor=colors.lightgrey, - strokeWidth=1, - format=('%4.2f', '%3.1f'), - labelsfont=8, - linestyle=[ - (colors.red, 'Circle', 1.5), - (colors.blue, 'Diamond', 1.5), - (colors.gold, 'Square', 1.5), - (colors.green, 'Triangle', 1.5), - (colors.pink, 'FilledCircle', 1.5), - (colors.lightblue, 'FilledDiamond', 1.5), - (colors.lightgreen, 'FilledTriangle', 1.5) - ] - ) - - -class BarChartStyle(PropertySet): - defaults = dict( - width=430, - height=135, - left=30, - bottom=50, - top=0, - right=30, - groupSpacing=32, - barSpacing=4, - tick=3, - strokeColor=colors.lightgrey, - strokeWidth=1, - pillarstyle={ - "loss": (colors.lightgreen, '%4.2f'), - "latency": (colors.indianred, '%4.1f'), - "fastlink": (colors.pink, '%4.1f'), - "l2switch": (colors.lightblue, '%4.1f'), - "kernel rdp": (colors.lightgreen, '%4.1f'), - "ovs": (colors.purple, '%4.1f') - }, - background=colors.lightgrey, - labelsfont=6, - ) - - -tes_default = TemplateStyle(name='default') -is_default = ImageStyle(name='default') -is_traffic = ImageStyle(name='traffic', - image_height=150, - image_width=360, - image_hAlign='CENTRE') - -ts_default = TableStyle(name='default') -ts_left = TableStyle( - name='left', - table_hAlign='LEFT', # LEFT,CENTRE or RIGHT - table_vAlign='BOTTOM', # BOTTOM,MIDDLE or TOP - table_colWidths=None, - table_rowHeights=None -) -lps_default = LinePlotStyle(name='default') -lcs_default = LineChartStyle(name='default') -bcs_default = BarChartStyle(name='default') -ps_head_lv1 = ParagraphStyle(name='ps_head_lv1', - fontName='Courier-Bold', - alignment=ens.TA_CENTER, # TA_LEFT, TA_RIGHT - fontSize=13, - leading=22, - leftIndent=0) - -ps_head_lv2 = ParagraphStyle(name='ps_head_lv2', - fontName='Courier', - fontSize=12, - leading=20, - leftIndent=16) - -ps_head_lv3 = ParagraphStyle(name='ps_head_lv3', - fontSize=11, - fontName='Courier', - leading=20, - leftIndent=16) - -ps_head_lv4 = ParagraphStyle(name='ps_head_lv4', - fontSize=13, - fontName='Courier-Bold', - leading=22, - leftIndent=0) - -ps_head_lv5 = ParagraphStyle(name='ps_head_lv5', - fontSize=12, - fontName='Courier', - leading=20, - leftIndent=16) - -ps_head_lv6 = ParagraphStyle(name='ps_head_lv6', - fontSize=11, - fontName='Courier', - leading=20, - leftIndent=16) - -ps_head_lv7 = ParagraphStyle(name='ps_head_lv7', - fontSize=11, - fontName='Courier', - leading=18, - leftIndent=0) - -ps_head_lv8 = ParagraphStyle(name='ps_head_lv8', - fontSize=11, - fontName='Courier', - leading=18, - leftIndent=16) - -ps_head_lv9 = ParagraphStyle(name='ps_head_lv9', - fontSize=11, - fontName='Courier', - leading=18, - leftIndent=32) - -ps_body = ParagraphStyle(name='ps_body', - fontSize=11, - fontName='Courier', - leading=18, - leftIndent=32) - -ps_space = ParagraphStyle(name='ps_space', - fontSize=5, - leading=5) diff --git a/vstf/vstf/controller/reporters/report/provider/__init__.py b/vstf/vstf/controller/reporters/report/provider/__init__.py deleted file mode 100644 index 83b8d15d..00000000 --- a/vstf/vstf/controller/reporters/report/provider/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## diff --git a/vstf/vstf/controller/reporters/report/provider/html_provider.py b/vstf/vstf/controller/reporters/report/provider/html_provider.py deleted file mode 100644 index 74c4c593..00000000 --- a/vstf/vstf/controller/reporters/report/provider/html_provider.py +++ /dev/null @@ -1,45 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - -import logging - -LOG = logging.getLogger(__name__) -from vstf.controller.settings.html_settings import HtmlSettings -from vstf.controller.settings.template_settings import TemplateSettings - - -class HtmlProvider(object): - def __init__(self, info, style): - self._info = info - self._style = style - - @property - def get_style(self): - assert "style" in self._style - return self._style["style"] - - @property - def get_context(self): - assert "context" in self._info - return self._info["context"] - - -def main(): - from vstf.common.log import setup_logging - setup_logging(level=logging.DEBUG, log_file="/var/log/html-provder.log", clevel=logging.INFO) - - html_settings = HtmlSettings() - LOG.info(html_settings.settings) - info = TemplateSettings() - provider = HtmlProvider(info.settings, html_settings.settings) - LOG.info(provider.get_style) - LOG.info(provider.get_context) - -if __name__ == '__main__': - main()
\ No newline at end of file diff --git a/vstf/vstf/controller/reporters/report/provider/pdf_provider.py b/vstf/vstf/controller/reporters/report/provider/pdf_provider.py deleted file mode 100644 index e1cb09ef..00000000 --- a/vstf/vstf/controller/reporters/report/provider/pdf_provider.py +++ /dev/null @@ -1,49 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - - -import logging - -LOG = logging.getLogger(__name__) -from vstf.controller.settings.template_settings import TemplateSettings - - -class PdfProvider(object): - def __init__(self, info): - self._info = info - - @property - def get_theme(self): - assert "theme" in self._info - return self._info["theme"] - - @property - def ifcontents(self): - assert "contents" in self._info - assert "enable" in self._info["contents"] - return self._info["contents"]["enable"] - - @property - def get_context(self): - assert "context" in self._info - return self._info["context"] - - -def main(): - from vstf.common.log import setup_logging - setup_logging(level=logging.DEBUG, log_file="/var/log/pdf-provider.log", clevel=logging.INFO) - - info = TemplateSettings() - provider = PdfProvider(info.settings) - LOG.info(provider.get_theme) - LOG.info(provider.ifcontents) - LOG.info(provider.get_context) - -if __name__ == '__main__': - main()
\ No newline at end of file |