~launchpad-p-s/sofastatistics/main

« back to all changes in this revision

Viewing changes to rawtables.py

  • Committer: Grant Paton-Simpson
  • Date: 2009-05-19 04:21:43 UTC
  • Revision ID: g@ubuntu-20090519042143-p561mbokz3inefvd
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import os
 
2
import datetime
 
3
 
 
4
import util
 
5
import tabreports
 
6
import getdata
 
7
 
 
8
DEF_CSS = r"c:\projects\css\SOFA_Default_Style.css"
 
9
 
 
10
 
 
11
class RawTable(object):
 
12
    """
 
13
    Simple table which basically displays contents of source SQL.
 
14
    Can add totals row.
 
15
    Can have the first column formatted as labels
 
16
    """
 
17
    def __init__(self, titles, dbe, col_names, col_labels, flds, 
 
18
                 var_labels, val_dics, datasource, cur, subtitles=None, 
 
19
                 add_total_row=False, first_col_as_label=False):
 
20
        """
 
21
        Set up table details required to make output.
 
22
        dbe - only here so can use the same interface for all table types
 
23
        """
 
24
        self.titles = titles
 
25
        if subtitles:
 
26
            self.subtitles = subtitles
 
27
        else:
 
28
            self.subtitles = []
 
29
        self.col_names = col_names
 
30
        self.col_labels = col_labels
 
31
        self.flds = flds
 
32
        self.var_labels = var_labels
 
33
        self.val_dics = val_dics
 
34
        self.datasource = datasource
 
35
        self.cur = cur
 
36
        self.add_total_row = add_total_row
 
37
        self.first_col_as_label = first_col_as_label
 
38
 
 
39
    def hasColMeasures(self):
 
40
        return False
 
41
 
 
42
    def getHdrDets(self, col_labels):
 
43
        """
 
44
        Set up titles, subtitles, and col labels into table header.
 
45
        """
 
46
        # titles and subtitles
 
47
        titles_html = "\n<p class='tbltitle'>"
 
48
        for title in self.titles:
 
49
            titles_html += "%s<br>" % title
 
50
        titles_html += "</p>"
 
51
        if self.subtitles != [""]:
 
52
            subtitles_html = "\n<p class='tblsubtitle'>"
 
53
            for subtitle in self.subtitles:
 
54
                subtitles_html += "%s<br>" % subtitle
 
55
            subtitles_html += "</p>"
 
56
        else:
 
57
            subtitles_html = ""
 
58
        title_dets_html = titles_html + subtitles_html
 
59
        hdr_html = "\n<thead>\n<tr><th class='tbltitlecell' colspan='%s'>" % \
 
60
            len(col_labels) + \
 
61
            "%s</th></tr>" % title_dets_html
 
62
        # col labels
 
63
        hdr_html += "\n<tr>"
 
64
        for col_label in col_labels:
 
65
            hdr_html += "<th class='firstcolvar'>%s</th>" % col_label
 
66
        hdr_html += "</tr>\n</thead>"
 
67
        return hdr_html
 
68
 
 
69
    def getHTML(self, page_break_after=False):
 
70
        """
 
71
        Get HTML for table.
 
72
        SELECT statement lists values in same order
 
73
            as col names.
 
74
        When adding totals, will only do it if all values are numeric (Or None).
 
75
        """
 
76
        html = ""
 
77
        html += "<table cellspacing='0'>\n" # IE6 doesn't support CSS borderspacing
 
78
        hdr_html = self.getHdrDets(self.col_labels)
 
79
        body_html = "\n\n<tbody>"
 
80
        row_tots = [0 for x in self.col_names]
 
81
        if self.first_col_as_label:
 
82
            del row_tots[0] # ignore label col
 
83
        SQL_get_data = "SELECT %s FROM %s" % (", ".join(self.col_names), 
 
84
                                              self.datasource)
 
85
        self.cur.execute(SQL_get_data)   
 
86
        rows = self.cur.fetchall()
 
87
        cols_n = len(self.col_names)
 
88
        # pre-store val dics for each column where possible
 
89
        col_val_dics = []
 
90
        for col_name in self.col_names:
 
91
            if self.val_dics.get(col_name):
 
92
                col_val_dic = self.val_dics[col_name]
 
93
                col_val_dics.append(col_val_dic)
 
94
            else:
 
95
                col_val_dics.append(None)
 
96
        # pre-store css class(es) for each column
 
97
        col_class_lsts = [[] for x in self.col_names]
 
98
        if self.first_col_as_label:
 
99
            col_class_lsts[0] = [tabreports.CSS_LBL]
 
100
        for i, col_name in enumerate(self.col_names):
 
101
            if self.flds[col_name][getdata.FLD_BOLNUMERIC] \
 
102
                    and not col_val_dics[i]:
 
103
                col_class_lsts[i].append(tabreports.CSS_ALIGN_RIGHT)
 
104
        if self.add_total_row:
 
105
            row_tots = [0 for x in self.col_names] # initialise
 
106
        for row in rows:
 
107
            row_tds = []
 
108
            for i in range(cols_n):
 
109
                # process row data to display
 
110
                # cell contents
 
111
                if col_val_dics[i]: # has a label dict
 
112
                    row_val = col_val_dics[i].get(row[i], "-") # label from dic
 
113
                else:
 
114
                    if row[i] or row[i] in ("", 0):
 
115
                        row_val = row[i]
 
116
                    elif row[i] == None:
 
117
                        row_val = "-"
 
118
                # cell format
 
119
                col_class_names = "\"" + ", ".join(col_class_lsts[i]) + "\""
 
120
                col_classes = "class = %s" % col_class_names if col_class_names else ""
 
121
                row_tds.append("<td %s>%s</td>" % (col_classes, row_val))
 
122
                # process totals
 
123
                if self.add_total_row:
 
124
                    # Skip if first col as val and this is first col
 
125
                    # Skip if prev was a Null ("-")
 
126
                    # Add to running total if a number (and prev was a number)
 
127
                    # If not adding, set to blank html cell string
 
128
                    if (self.first_col_as_label and i == 0) or \
 
129
                        row_val == "-":
 
130
                        pass
 
131
                    elif util.isNumeric(row_val) and \
 
132
                            util.isNumeric(row_tots[i]):
 
133
                        row_tots[i] += row_val
 
134
                    else:
 
135
                        row_tots[i] = "&nbsp;&nbsp;"
 
136
            html += "\n<tr>" + "".join(row_tds) + "</td></tr>"
 
137
        if self.add_total_row:
 
138
            row_tot_vals = [str(x) for x in row_tots]
 
139
            if self.first_col_as_label:
 
140
                tot_cell = "<td class='%s'>TOTAL</td>" % tabreports.CSS_LBL
 
141
                row_tot_vals.pop(0)
 
142
            else:
 
143
                tot_cell = ""
 
144
            # never a displayed total for strings (whether orig data or labels)
 
145
            joiner = "</td><td class=\"%s\">" % tabreports.CSS_ALIGN_RIGHT
 
146
            body_html += "\n<tr class='total-row'>" + \
 
147
                tot_cell + "<td class=\"%s\">"  % tabreports.CSS_ALIGN_RIGHT + \
 
148
                joiner.join(row_tot_vals) + "</td></tr>"
 
149
        body_html += "\n</tbody>"        
 
150
        html += hdr_html
 
151
        html += body_html
 
152
        html += "\n</table>"
 
153
        if page_break_after:
 
154
            html += "<br><hr><br><div class='page-break-before'></div>"
 
155
        return html