reporting_tools.py 5.94 KB
Newer Older
1
"""a collection of tools to build reports in controllers.
2

3
@author: R. Le Gac
4 5

"""
6 7 8 9 10 11 12
import re


from list_postprocessing import (clean,
                                 highlight_my_authors,
                                 highlight_my_speaker,
                                 remove_undef)
13
from gluon.dal import smart_query
14
from gluon.storage import Storage
15

16

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
def format_publication(template, record, funcs=[]):
    """Build the bibliographic string for the publication.

    @type template str:
    @param template str:

    @type record: gluon.DAL.Row
    @param record

    @type funcs: list
    @param funcs: list of functions to polish the bibliographic reference

    @rtype: str
    @return: the bibliographic reference

    """
    # format the record according to user requirement
    value = template.format(**record)

    # run post processing to polish/clean the value
    if funcs:
        for func in funcs:
            value = func(value, template, record)

    return value


44
def get_converter(row):
45
    """Get the converter dictionary for the axis label of the C{list}.
46

47 48
    @type row: gluon.dal.Row
    @param row: One row of the database table C{list}.
49

50
    @rtype: dict
51
    @return:
52
        - C{value: "blabla, ....", value2: "foo", ....}
53

54
    """
55
    di = {}
56
    if row.axis_label_converters:
57

58
        s = re.sub(r'" *, *', '"|', row.axis_label_converters)
59

60 61 62 63
        for el in s.split('|'):
            m = re.match(r' *(.+) *: *"(.+)"', el)
            if m:
                di[m.group(1)] = m.group(2)
64

65 66
    return di

67

68
def get_sections(db, selector, row):
69 70 71 72
    """Get the section rows for the C{list}.

    @type db: gluon.dal.DAL
    @param db:
73

74 75
    @type selector: plugin_dbui.Selector
    @param selector:
76

77 78
    @type row: gluon.dal.Row
    @param row: One row of the database table C{list}.
79

80
    @rtype: list
81
    @return:
82 83
        - a list of rows of the C{sections} table
        - each row also contains the C{query} and C{orderby}
84 85 86 87
          directive taking into account C{selector} directive.
        - each row contains also the renderer format and post
          processing functions

88
    """
LE GAC Renaud's avatar
LE GAC Renaud committed
89
    publications = db.publications
90
    sections = []
LE GAC Renaud's avatar
LE GAC Renaud committed
91

92
    for el in row.sections.split(','):
93

94
        # retrieve the section record
95 96
        el = el.strip()
        rows = db(db.sections.section == el).select()
97

98 99
        if not rows:
            continue
100 101

        section = rows.first()
102
        sections.append(section)
103

104 105 106
        # query directive to extract publications for this section
        # It includes foreign key constraints and user requirements
        # related to team, project, authors and year
LE GAC Renaud's avatar
LE GAC Renaud committed
107
        query = selector.query(publications)
108

109
        if selector.year_start and not selector.year_end:
LE GAC Renaud's avatar
LE GAC Renaud committed
110
            query = (query) & (publications.year == selector.year_start)
111

112
        elif selector.year_start and selector.year_end:
LE GAC Renaud's avatar
LE GAC Renaud committed
113 114
            q_start = publications.year >= selector.year_start
            q_end = publications.year <= selector.year_end
115
            query = (query) & ((q_start) & (q_end))
116

117
        if selector.author:
LE GAC Renaud's avatar
LE GAC Renaud committed
118
            q_author = publications.authors_institute.contains(selector.author)
119
            query = (query) & (q_author)
120

121 122
        # add to the query the directive coming from the section itself
        # the publication category and dedicated conditions
123 124
        if section.category_codes:
            q_cat = None
125
            codes = section.category_codes.replace(' ', '').split(',')
126 127
            if codes:
                q_cat = db.categories.code.belongs(codes)
128

129
            query = (query) & (q_cat)
130 131

        if section.conditions:
LE GAC Renaud's avatar
LE GAC Renaud committed
132
            q_conditions = smart_query(publications, section.conditions)
133
            query = (query) & (q_conditions)
134

135
        section.query = query
136

137
        # order by directive to order publication for this section
138
        # taking into account directive from the row and from the section
139
        orderby = []
140

141 142
        for level in ('level_1', 'level_2', 'level_3', 'level_4'):
            axis = 'axis_%s' % level
143

144
            if not row[axis]:
145
                continue
146

147 148 149
            tablename = row[axis]
            fieldname = row['granularity_%s' % level]
            direction = row["direction_%s" % level]
150

151
            field = db[tablename][fieldname]
LE GAC Renaud's avatar
LE GAC Renaud committed
152
            if direction == "DESC":
153
                field = ~field
154 155 156

            orderby.append(field)

157
        section.orderby = tuple(orderby)
158 159 160 161 162 163 164 165 166 167 168 169 170

        # the renderer format and post processing functions
        renderer = db.renderers[section.id_renderers]

        section.renderer = Storage()
        section.renderer.template = renderer.template
        section.renderer.funcs = []

        funcs = renderer.postprocessing.replace(' ', '').split(',')
        for func in funcs:
            if func in globals():
                section.renderer.funcs.append(globals()[func])

171 172 173
    return sections


174
def ref_url(name='List'):
175
    """Get the URL string uses to build the current request.
176

177
    @note: this function is useful in view
178

179 180
    @type name: str
    @param name:
181

182 183
    @rtype: str
    @return: C{"http://..."}
184

185
    """
186
    li = []
187 188
    for (k, v) in request.vars.iteritems():
        if k.startswith(name) and len(v):
189
            li.append("%s=%s" % (k, v))
190 191 192
        pass
    pass

193
    t = (request.env.http_host, request.env.path_info, '&'.join(li))
194
    url = "http://%s%s?%s" % t
195

196
    return url
197 198


199
def repr_team_project(db, selector):
200
    """Build the team/project string.
201

202 203
    @type db: gluon.dal.DAL
    @param db:
204

205 206
    @type selector: plugin_dbui.Selector
    @param selector:
207

208 209
    @rtype: unicode
    @return: the format is "team" or "project" or "team/project".
210 211
    """
    s = ''
212

213 214
    if selector.id_teams and not selector.id_projects:
        s = db.teams[selector.id_teams].team
215

216 217
    elif not selector.id_teams and selector.id_projects:
        s = db.projects[selector.id_projects].project
218

219 220 221 222
    elif selector.id_teams and selector.id_projects:
        team = db.teams[selector.id_teams].team
        project = db.projects[selector.id_projects].project
        s = "%s/%s" % (team, project)
223

LE GAC Renaud's avatar
LE GAC Renaud committed
224
    return s