mytools.py 3.46 KB
Newer Older
LE GAC Renaud's avatar
LE GAC Renaud committed
1
""" mytool controllers
2 3 4 5 6

A collection of tools specific to the applications

"""
import json
7 8 9

from datetime import datetime
from plugin_dbui import get_id
10

11 12
MSG = T(" - %s entry(ies) modified in the history table. <br>"
        " - DO NOT FORGET TO MODIFIED THE REPORT CONFIGURATION.")
13

14 15 16
MSG_CVT = T(" - Conversion error: %s.")


17 18 19
def userModelConsistency():
    """ A user data block is associated to each event.
    It is configurable by the user and defined in the events table.
LE GAC Renaud's avatar
LE GAC Renaud committed
20

21 22 23
    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.
LE GAC Renaud's avatar
LE GAC Renaud committed
24

25 26 27 28 29
    """
    # decode the request
    changes = json.loads(request.vars.changes)
    event = request.vars.fieldEvent
    model = json.loads(request.vars.fieldData)
LE GAC Renaud's avatar
LE GAC Renaud committed
30

31 32 33 34 35 36 37 38 39
    # 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:
LE GAC Renaud's avatar
LE GAC Renaud committed
40

41 42
        if action != 'update':
            continue
LE GAC Renaud's avatar
LE GAC Renaud committed
43

44 45 46 47
        # simplify the case where key1 > key2 > key3 to key1 > key3
        # remove the case where key1 > key2 > ... > key1
        if update_keys:
            ok = False
LE GAC Renaud's avatar
LE GAC Renaud committed
48

49 50 51 52 53 54 55
            for k, v in update_keys.iteritems():
                if oldkey == v:
                    update_keys[k] = newkey
                    ok = True
                    if k == newkey:
                        del update_keys[k]
                    break
LE GAC Renaud's avatar
LE GAC Renaud committed
56

57 58
            if ok:
                continue
LE GAC Renaud's avatar
LE GAC Renaud committed
59

60 61
        # basic case
        update_keys[oldkey] = newkey
LE GAC Renaud's avatar
LE GAC Renaud committed
62

63
    # get the event id
64
    id_event = get_id(db.events, event=event)
65 66
    if id_event == None:
        return
LE GAC Renaud's avatar
LE GAC Renaud committed
67

68
    # set-up the default values dealing with data conversion
69 70
    for key in model:
        value = model[key]['value']
LE GAC Renaud's avatar
LE GAC Renaud committed
71 72
        type = model[key]['type']

73
        if value:
LE GAC Renaud's avatar
LE GAC Renaud committed
74

75 76 77
            try:
                if type == "boolean":
                    value = value.lower() in ('true', 'vrai', 'y', 'yes', '1')
LE GAC Renaud's avatar
LE GAC Renaud committed
78

79 80 81
                elif type == "date":
                    value = datetime.strptime(value, "%Y-%m-%d")
                    value = value.isoformat()
LE GAC Renaud's avatar
LE GAC Renaud committed
82

83 84
                elif type == "float":
                    value = float(value)
LE GAC Renaud's avatar
LE GAC Renaud committed
85

86 87
                elif type == "integer":
                    value = int(value)
LE GAC Renaud's avatar
LE GAC Renaud committed
88

89 90 91 92
                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)
LE GAC Renaud's avatar
LE GAC Renaud committed
93

94 95 96 97 98
                elif type == "reference":
                    value = None

            except ValueError as e:
                return MSG_CVT % e
LE GAC Renaud's avatar
LE GAC Renaud committed
99

100
            model[key]['value'] = value
LE GAC Renaud's avatar
LE GAC Renaud committed
101

102
    # scan and modify the history table
103
    # the delete of old key is implicit since they are not copied
104 105
    query = db.history.id_events == id_event
    rows = db(query).select()
LE GAC Renaud's avatar
LE GAC Renaud committed
106

107 108
    for row in rows:
        data = {}
LE GAC Renaud's avatar
LE GAC Renaud committed
109
        rd = (row.data if isinstance(row.data, dict) else dict())
LE GAC Renaud's avatar
LE GAC Renaud committed
110

111
        # copy existing key or add new key
112
        for key in model:
113
            data[key] = (rd[key] if key in rd else model[key]['value'])
LE GAC Renaud's avatar
LE GAC Renaud committed
114

115 116
        # modify key name
        for oldkey, newkey in update_keys.iteritems():
117 118
            if oldkey in rd:
                data[newkey] = rd[oldkey]
LE GAC Renaud's avatar
LE GAC Renaud committed
119

LE GAC Renaud's avatar
LE GAC Renaud committed
120
        db(db.history.id == row.id).update(data=data)
LE GAC Renaud's avatar
LE GAC Renaud committed
121

122
    return MSG % len(rows)