Docker-in-Docker (DinD) capabilities of public runners deactivated. More info

Commit d81542db authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Merge branch 'master' into 'production'

Release 0.7.0

See merge request !32
parents 1d2efd3a 8d155af3
......@@ -2,206 +2,104 @@
"""plugin_event controllers
"""
import traceback
import urllib
import json
import re
from datetime import datetime
from plugin_dbui import get_id, INLINE_ALERT
from plugin_event import (do_title,
Graph,
from plugin_event import (Graph,
List,
Metric1D,
Metric2D,
ReportException)
from plugin_event import EvtSelector, SelectorActiveItemsException
ReportException,
Source)
MSG = T(" - %s entry(ies) modified in the history table. <br>"
" - DO NOT FORGET TO MODIFIED THE REPORT CONFIGURATION.")
MSG_CVT = T(" - Conversion error: %s.")
def grid():
"""The list is rendered such as an ``Ext.grid.Panel`` widget.
Its context menu allows to export the content of the table as a CSV, LaTeX
or PDF format.
def graph_mpl():
"""Plot list or metric using the matplotlib library
The controller extracts the configuration of the report from the database.
It builds the DataFrame, extracts the configuration for the
``Ext.data.Store`` as well as the ``Ext.grid.Panel``. The former contains
the data displayed in the grid.
"""
# build the graph
try:
graph = Graph(db.graphs, request.vars.id_graphs)
except (IndexError, TypeError, ValueError) as e:
return INLINE_ALERT % ("GRAPH Error", e)
# build the report title
title = do_title(graph)
# extract the image
# encode special character to be used in the image URI
extension = request.extension
if extension == "html":
data = graph.to_svg()
data = urllib.quote(data)
elif extension == "pdf":
data = graph.to_pdf()
elif extension == "png":
data = graph.to_png()
report = List(request.vars.id_list)
store = report.get_store_configuration()
grid = report.get_grid_configuration()
title = report.get_title()
# delegate the rendering to the view
return dict(data=data, title=title)
except (IndexError, ReportException, TypeError, ValueError):
return CODE(traceback.format_exc()).xml()
response.view = "plugin_event/grid.html"
return dict(cfg_store=store, grid=grid, title=title)
def grid():
"""Render the report through the C{Dbui.grid.Panel}.
The report can be a list, a metrics 1d or 2d.
The controller extracts the configuration of the report form the database.
It builds the DataFrame, extracts the the configuration
for the C{Ext.data.Store} as well as the C{Dbui.grid.Panel}.
The former contains the data displayed in the grid.
def metric2d():
"""The metric 2D is a 2D table rendered by an ``Ext.grid.Panel`` widget
and a graph rendered as an image. The context menu associated to the grid
allows to export the content of the table as a CSV, LaTeX or PDF format.
The context menu associated to the image allow to export in PNG or PDF
format.
The report identifier is defined in the viewport
and send using the baseParams techniques. Possible identifiers
are C{id_lists], C{id_metrics1d} and C{id_metrics2d}.
The identifier is used to instantiate the proper class.
The controller extracts the configuration of the report from the database.
It builds the DataFrame, extracts the the configuration for the
``Ext.data.Store`` as well as the ``Ext.grid.Panel`` and generated
the graph.
"""
# build the report
extension = request.extension
try:
if "id_lists" in request.vars:
report = List(db.lists, request.vars.id_lists)
report = Metric2D(request.vars.id_metric2d)
elif "id_metrics1d" in request.vars:
report = Metric1D(db.metrics1d, request.vars.id_metrics1d)
graph = Graph(report)
title = report.get_title()
elif "id_metrics2d" in request.vars:
report = Metric2D(db.metrics2d, request.vars.id_metrics2d)
if extension == "html":
store = report.get_store_configuration()
grid = report.get_grid_configuration()
else:
return INLINE_ALERT % ("Error", "Report id is not defined.")
if graph.ax is not None:
img = graph.to_svg()
img = urllib.quote(img)
except (IndexError, ReportException, TypeError, ValueError) as e:
return INLINE_ALERT % ("REPORT Error...", e)
response.view = "plugin_event/grid_and_graph.html"
return dict(cfg_store=store, grid=grid, img=img, title=title)
# extract the configurations for the Ext.data.Store and Dbui.grid.Panel.
store = report.to_store()
grid = report.to_grid()
else:
response.view = "plugin_event/grid.html"
return dict(cfg_store=store, grid=grid, title=title)
# build the report title
title = do_title(report)
elif extension == "pdf":
data = graph.to_pdf()
response.view = "plugin_event/graph.pdf"
return dict(data=data, title=title)
# delegate the grid rendering to the view
return dict(cfg_store=store, grid=grid, title=title)
elif extension == "png":
data = graph.to_png()
response.view = "plugin_event/graph.png"
return dict(data=data, title=title)
except (IndexError, ReportException, TypeError, ValueError):
return CODE(traceback.format_exc()).xml()
def userModelConsistency():
""" A user data block is associated to each event.
It is configurable by the user and defined in the events table.
The definition of the user data block (model) and the content
of the history.data field have to be kept in synchronization.
This job is done by this controller.
def source():
"""Display the content of a source via an ``Ext.grid.Panel``.
Values send by the selector are used to filter the content of the source.
"""
# decode the request
changes = json.loads(request.vars.changes)
event = request.vars.fieldEvent
model = json.loads(request.vars.fieldData)
# build a map of the modified keys.
# each operation is a list containing (action, old key, new key).
# the action is equal to: add, destroy, update
#
# NOTE: add and delete action are handle via dictionary copy.
#
#
update_keys = {}
for action, oldkey, newkey in changes:
if action != "update":
continue
# simplify the case where key1 > key2 > key3 to key1 > key3
# remove the case where key1 > key2 > ... > key1
if update_keys:
ok = False
for k, v in update_keys.iteritems():
if oldkey == v:
update_keys[k] = newkey
ok = True
if k == newkey:
del update_keys[k]
break
if ok:
continue
# basic case
update_keys[oldkey] = newkey
# get the event id
id_event = get_id(db.events, event=event)
if id_event == None:
return
# set-up the default values dealing with data conversion
for key in model:
value = model[key]["value"]
type = model[key]["type"]
if value:
try:
if type == "boolean":
value = value.lower() in ("true", "vrai", "y", "yes", "1")
elif type == "date":
value = datetime.strptime(value, "%Y-%m-%d")
value = value.isoformat()
elif type == "float":
value = float(value)
elif type == "integer":
value = int(value)
if type == "string" and value[0] == "[" and value[-1] == "]":
# reference to a set, pick the first value as default
li = json.loads(value)
value = (li[0] if li else None)
elif type == "reference":
value = None
except ValueError as e:
return MSG_CVT % e
model[key]["value"] = value
# scan and modify the history table
# the delete of old key is implicit since they are not copied
query = db.history.id_events == id_event
rows = db(query).select()
for row in rows:
data = {}
rd = (row.data if isinstance(row.data, dict) else dict())
# copy existing key or add new key
for key in model:
data[key] = (rd[key] if key in rd else model[key]["value"])
# modify key name
for oldkey, newkey in update_keys.iteritems():
if oldkey in rd:
data[newkey] = rd[oldkey]
db(db.history.id == row.id).update(data=data)
return MSG % len(rows)
try:
report = Source(request.vars.source)
store = report.get_store_configuration()
grid = report.get_grid_configuration()
title = report.get_title()
except (IndexError, ReportException, TypeError, ValueError):
return CODE(traceback.format_exc()).xml()
response.view = "plugin_event/grid.html"
return dict(cfg_store=store, grid=grid, title=title)
......@@ -13,3 +13,5 @@ Functions
:toctree: generated/
INHIBIT_CASCADE_DELETE
ON_CREATE_LISTS2
ON_UPDATE_LISTS2
# -*- coding: utf-8 -*-
#
# track_event api documentation build configuration file, created by
# plugin_event api documentation build configuration file, created by
# sphinx-quickstart on Sat Apr 11 11:17:03 2015.
#
# This file is execfile()d with the current directory set to its containing dir.
......@@ -78,9 +78,9 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
app = 'track_events'
app = 'plugin_event'
now = datetime.now()
project = u'track_events API'
project = u'plugin_event API'
copyright = u'2012-%s, R. Le Gac, licensed under CeCILL' % now.year
author = u'R. Le Gac'
......
Dataframes
-----------
A collection of classes and functions to build and to manipulate the sources.
.. currentmodule:: plugin_event
.. autosummary::
:toctree: generated/
active_period
coverage
db2df
debug_df
expand_per_year
full_name
get_column_names
get_items
get_items_per_year
get_items_small
get_items_small_per_year
get_objectlike_items
get_objectlike_items_per_year
get_peoplelike_items
get_peoplelike_items_per_year
get_people_per_year
is_end
is_start
normalize_history_data
query_history
Timer
to_extjs_gridcolumns
to_items_per_year
\ No newline at end of file
plugin_event.BaseReport.to_df
plugin_event.Event.get_source
=============================
.. currentmodule:: plugin_event
.. automethod:: BaseReport.to_df
\ No newline at end of file
.. automethod:: Event.get_source
\ No newline at end of file
plugin_event.Selector.selector
plugin_event.Event.get_sources
==============================
.. currentmodule:: plugin_event
.. automethod:: Selector.selector
\ No newline at end of file
.. automethod:: Event.get_sources
\ No newline at end of file
plugin_event.ViewportUi.graph_node
plugin_event.Event.register_source
==================================
.. currentmodule:: plugin_event
.. automethod:: ViewportUi.graph_node
\ No newline at end of file
.. automethod:: Event.register_source
\ No newline at end of file
plugin_event.SelectorUi.selector
plugin_event.Event.register_sources
===================================
.. currentmodule:: plugin_event
.. automethod:: SelectorUi.selector
\ No newline at end of file
.. automethod:: Event.register_sources
\ No newline at end of file
plugin_event.Report.lists
=========================
.. currentmodule:: plugin_event
.. automethod:: Report.lists
\ No newline at end of file
plugin_event.Report.graphs
plugin_event.Report.lists2
==========================
.. currentmodule:: plugin_event
.. automethod:: Report.graphs
\ No newline at end of file
.. automethod:: Report.lists2
\ No newline at end of file
plugin_event.Metric1D.to_store
plugin_event.Report.metrics2d2
==============================
.. currentmodule:: plugin_event
.. automethod:: Metric1D.to_store
\ No newline at end of file
.. automethod:: Report.metrics2d2
\ No newline at end of file
plugin_event.ViewportUi.object_node
plugin_event.Selector.selector_list
===================================
.. currentmodule:: plugin_event
.. automethod:: ViewportUi.object_node
\ No newline at end of file
.. automethod:: Selector.selector_list
\ No newline at end of file
plugin_event.Selector.selector_metric2d
=======================================
.. currentmodule:: plugin_event
.. automethod:: Selector.selector_metric2d
\ No newline at end of file
plugin_event.ViewportUi.metric1d_node
plugin_event.Selector.selector_source
=====================================
.. currentmodule:: plugin_event
.. automethod:: ViewportUi.metric1d_node
\ No newline at end of file
.. automethod:: Selector.selector_source
\ No newline at end of file
......@@ -12,8 +12,9 @@ plugin_event.BaseReport
.. autosummary::
:toctree: report/
~BaseReport.to_df
~BaseReport.get_grid_configuration
~BaseReport.get_store_configuration
~BaseReport.get_title
......
......@@ -12,6 +12,11 @@ plugin_event.Event
:toctree: model/
~Event.define_paths
~Event.get_source
~Event.get_sources
~Event.register_source
~Event.register_sources
......
plugin_event.EvtSelector
========================
.. currentmodule:: plugin_event
.. autoclass:: EvtSelector
:show-inheritance:
.. rubric:: Methods
.. autosummary::
:toctree: selector/
~EvtSelector.query
~EvtSelector.reset_extra_queries
......@@ -11,7 +11,8 @@ plugin_event.Graph
.. autosummary::
:toctree: report/
~Graph.to_df
~Graph.bar_like
~Graph.line_like
~Graph.to_pdf
~Graph.to_png
~Graph.to_svg
......
......@@ -11,10 +11,6 @@ plugin_event.List
.. autosummary::
:toctree: report/
~List.to_df
~List.to_grid
~List.to_store
......
......@@ -11,9 +11,7 @@ plugin_event.Metric2D
.. autosummary::
:toctree: report/
~Metric2D.to_df
~Metric2D.to_grid
~Metric2D.to_store
~Metric2D.summaries
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment