"""A collection of tools to build reports in controllers. """ import re from .list_postprocessing import (clean, highlight_my_authors, highlight_my_speaker, remove_undef) from gluon.storage import Storage from pydal.helpers.methods import smart_query def format_publication(template, record, funcs=[]): """Build the bibliographic string for the *record*. Args: template (str): template to build the bibliographic string. The database fields are identified by the pattern ``{tablename.fieldname}``. They will be replace by the corresponding value found in the *record*. record (gluon.DAL.Row): entry of the publications table. funcs (list): list of reference to functions. They are used to polish the bibliographic string. Returns: str: 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 def get_converter(row): """Get the converter dictionary for the axis label of the *list*. Args: row (gluon.dal.Row): one row of the database table *list*. Returns: dict: ``{value: "blabla, ....", value2: "foo", ....}`` """ di = {} if row.axis_label_converters: s = re.sub(r'" *, *', '"|', row.axis_label_converters) for el in s.split("|"): m = re.match(r' *(.+) *: *"(.+)"', el) if m: di[m.group(1)] = m.group(2) return di def get_sections(db, selector, row): """Get the section rows for the *list*. Args: db (gluon.dal.DAL): database connection selector (plugin_dbui.Selector): row (gluon.dal.Row): one row of the database table *list*. Returns: list: * A list of rows of the *sections* table. * Each row also contains the *query* and *orderby* directives taking into account *selector* criteria. * Each row contains also the renderer format and post processing functions """ publications = db.publications sections = [] for el in row.sections.split(","): # retrieve the section record el = el.strip() rows = db(db.sections.section == el).select() if not rows: continue section = rows.first() sections.append(section) # query directive to extract publications for this section # It includes foreign key constraints and user requirements # related to team, project, authors and year query = selector.query(publications) if selector.year_start and not selector.year_end: query &= publications.year == selector.year_start elif selector.year_start and selector.year_end: query &= publications.year >= selector.year_start query &= publications.year <= selector.year_end if selector.author: q_author = publications.authors_institute.contains(selector.author) query &= q_author # add to the query the directive coming from the section itself # the publication category and dedicated conditions if section.category_codes: q_cat = None codes = section.category_codes.replace(" ", "").split(",") if codes: q_cat = db.categories.code.belongs(codes) query &= q_cat if section.conditions: q_conditions = smart_query(publications, section.conditions) query &= q_conditions section.query = query # order by directive to order publication for this section # taking into account directive from the row and from the section orderby = [] for level in ("level_1", "level_2", "level_3", "level_4"): axis = "axis_%s" % level if not row[axis]: continue tablename = row[axis] fieldname = row["granularity_%s" % level] direction = row["direction_%s" % level] field = db[tablename][fieldname] if direction == "DESC": field = ~field orderby.append(field) section.orderby = tuple(orderby) # 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]) return sections def ref_url(name="List"): """Get the URL string uses to build the current request. Note: This function is useful in view Args: name (str): Returns: str: ``"http://..."`` """ li = [] for k, v in request.vars.items(): if k.startswith(name) and len(v): li.append("%s=%s" % (k, v)) pass pass t = (request.env.http_host, request.env.path_info, "&".join(li)) url = "http://%s%s?%s" % t return url def repr_team_project(db, selector): """Build the team/project string. Args: db (gluon.dal.DAL): database connection. selector (plugin_dbui.Selector): Returns: unicode: the pattern is "team" or "project" or "team/project". """ s = "" if selector.id_teams and not selector.id_projects: s = db.teams[selector.id_teams].team elif not selector.id_teams and selector.id_projects: s = db.projects[selector.id_projects].project 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) return s