callbacks.py 6.57 KB
Newer Older
LE GAC Renaud's avatar
LE GAC Renaud committed
1
# -*- coding: utf-8 -*-
LE GAC Renaud's avatar
LE GAC Renaud committed
2 3 4 5 6 7 8 9
"""a collections of functions to be used in _before_delete, before_insert
and _before_update callbacks.

"""
from check_tools import (duplicate_article,
                         duplicate_conference,
                         duplicate_report)
from gluon import current
10 11
from plugin_dbui import (CALLBACK_ERRORS,
                         get_id,
12 13 14
                         get_where_query)


LE GAC Renaud's avatar
LE GAC Renaud committed
15 16 17 18
MSG_DUPLICATE = \
    "Can't delete this record since several publications refer to it."


19
def INHIBIT_CASCADE_DELETE(set_records):
20
    """Inhibit the delete when the entry is referenced in another table(s).
21

22 23
    Args:
        set_records (gluon.dal.Set): set object used for delete.
24

25 26
    Returns:
        bool: ``True`` when the delete is inhibited
27

28 29
    """
    db, T = current.globalenv['db'], current.T
30
    field = set_records.query.first
31

32 33
    # protection
    # the query of the set should be "table.id == 45"
34
    if field._db._adapter.EQ != set_records.query.op:
35
        return False
36

37 38 39 40 41 42 43 44 45 46 47
    # protection
    # check that the table is ones of the publication reference tables
    tables = (db.authors_roles,
              db.categories,
              db.collaborations,
              db.countries,
              db.projects,
              db.publishers,
              db.reports,
              db.status,
              db.teams)
48

49 50
    if field._table not in tables:
        return False
51

52 53
    # inhibit the delete if publications use the reference field
    query = get_where_query(db.publications)
54
    query = (query) & (set_records.query)
55

56
    if db(query).count():
LE GAC Renaud's avatar
LE GAC Renaud committed
57
        field._table[CALLBACK_ERRORS] = T(MSG_DUPLICATE)
58 59 60
        return True

    return False
LE GAC Renaud's avatar
LE GAC Renaud committed
61 62 63 64


def INHIBIT_DUPLICATE_PUBLICATION(publication):
    """Inhibit the insert operation when the publication already exists.
65

66 67
    Args:
        publication (dict): publications fields passed to insert.
68

69 70
    Returns:
        bool: ``True`` when the insert is inhibited
71

LE GAC Renaud's avatar
LE GAC Renaud committed
72 73 74
    """
    db, T = current.globalenv['db'], current.T
    id_category = publication['id_categories']
75

LE GAC Renaud's avatar
LE GAC Renaud committed
76 77 78 79 80 81 82
    # articles
    id_cats = (get_id(db.categories, code='ACL'),
               get_id(db.categories, code='ACLN'))

    if id_category in id_cats:
        ids = duplicate_article(publication)
        if ids:
83

LE GAC Renaud's avatar
LE GAC Renaud committed
84
            db.publications[CALLBACK_ERRORS] = [
LE GAC Renaud's avatar
LE GAC Renaud committed
85 86 87 88 89 90
                T("Can't insert the article."),
                T("An article already exists with the same:"),
                T("• title, publisher, volume and pages"),
                T("• or publisher, volume and pages"),
                T("• or publisher and title."),
                T("See publication id(s) %s") % ', '.join(ids)]
91

LE GAC Renaud's avatar
LE GAC Renaud committed
92
            return True
93

LE GAC Renaud's avatar
LE GAC Renaud committed
94 95 96 97
    # talks and proceedings
    id_cats = (get_id(db.categories, code='ACTI'),
               get_id(db.categories, code='ACTN'),
               get_id(db.categories, code='COM'))
98

LE GAC Renaud's avatar
LE GAC Renaud committed
99 100 101 102 103
    if id_category in id_cats:
        ids = duplicate_conference(publication)
        if ids:

            db.publications[CALLBACK_ERRORS] = [
LE GAC Renaud's avatar
LE GAC Renaud committed
104 105 106 107 108 109
                T("Can't insert the talk/proceeding."),
                T("A talk/proceeding already exists with the same:"),
                T("• title, conference title, date and town"),
                T("• or title, conference date and town"),
                T("• or title, conference title and town"),
                T("See publication id(s) %s") % ', '.join(ids)]
110

LE GAC Renaud's avatar
LE GAC Renaud committed
111
            return True
112

LE GAC Renaud's avatar
LE GAC Renaud committed
113 114
    # reports
    id_cats = (get_id(db.categories, code='AP'),)
115

LE GAC Renaud's avatar
LE GAC Renaud committed
116 117 118 119 120
    if id_category in id_cats:
        ids = duplicate_report(publication)
        if ids:

            db.publications[CALLBACK_ERRORS] = [
LE GAC Renaud's avatar
LE GAC Renaud committed
121 122 123
                T("Can't insert the report."),
                T("A report already exists with the same title"),
                T("See publication id(s) %s") % ', '.join(ids)]
124

LE GAC Renaud's avatar
LE GAC Renaud committed
125
            return True
126 127 128 129 130 131 132 133

    return False


def INHIBIT_HARVESTER_ON_CATEGORY(harvester):
    """Inhibit the insert of similar harvesters.

    For a project, one automaton can only proceed publication
134 135
    of the same code, e.g ACL or ACLN but not both, but automatons
    can scan different stores.
136

137 138
    Args:
        harvester (dict): harvester fields passed to insert.
139

140 141
    Returns:
        bool: ``True`` when the insert is inhibited
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162

    """
    db, T = current.globalenv['db'], current.T

    # a new harvester
    id_harvester = get_id(db.harvesters,
                          controller=harvester['controller'],
                          id_projects=harvester['id_projects'],
                          id_teams=harvester['id_teams'])

    if not id_harvester:
        return False

    # for a project, one automaton can only proceed publication
    # of the same code, e.g ACL or ACLN but not both
    id_category = db.harvesters[id_harvester].id_categories
    if id_category != harvester['id_categories']:

        code = db.categories[id_category].code

        db.harvesters[CALLBACK_ERRORS] = [
LE GAC Renaud's avatar
LE GAC Renaud committed
163 164 165
            T("Can't insert the harvester."),
            T("Harvester already exists with the same automaton "),
            T("but with different category: %s") % code]
166 167 168

        return True

LE GAC Renaud's avatar
LE GAC Renaud committed
169 170 171 172 173
    return False


def INHIBIT_PUBLICATION_DELETE_ON_OK(s):
    """Inhibit the delete operation when the status of the publication is OK.
174

175 176
    Args:
        s (gluon.dal.Set]: set object used for delete.
177

178 179
    Returns:
        bool: ``True`` when the delete is inhibited.
180

LE GAC Renaud's avatar
LE GAC Renaud committed
181 182 183 184 185 186 187 188
    """
    db, T = current.globalenv['db'], current.T
    id_ok = get_id(db.status, code='OK')

    # also call in cascade delete (teams, ...)
    # in normal case the query is "publications.id = 567"
    # in cascade delete the query is "publications.id_teams IN (21)"

189
    if s.query.first is not db.publications.id:
190 191
        return False

192 193
    id_rec = s.query.second
    if db.publications[id_rec].id_status == id_ok:
194
        db.publications[CALLBACK_ERRORS] = \
LE GAC Renaud's avatar
LE GAC Renaud committed
195
            T("Can't delete a publication marked OK.")
196
        return True
197

LE GAC Renaud's avatar
LE GAC Renaud committed
198 199 200 201 202
    return False


def INHIBIT_PUBLICATION_UPDATE_ON_OK(s, f):
    """Inhibit the update operation when the status of the publication is OK.
203

204 205 206
    Args:
        s (gluon.dal.Set): set object used for update.
        f (dict): the dict of publications fields passed to update.
207

208 209
    Returns:
        bool: ``True`` when the update is inhibited.
210

LE GAC Renaud's avatar
LE GAC Renaud committed
211 212 213 214
    """
    db, T = current.globalenv['db'], current.T
    id_ok = get_id(db.status, code='OK')

215 216
    # protection
    # the query of the set should be "publications.id == 45"
217
    if s.query.first is not db.publications.id:
218 219
        return False

220
    id_rec = s.query.second
221

222
    if db.publications[id_rec].id_status == id_ok:
LE GAC Renaud's avatar
LE GAC Renaud committed
223
        db.publications[CALLBACK_ERRORS] = \
LE GAC Renaud's avatar
LE GAC Renaud committed
224
            T("Can't updated a publication marked OK.")
LE GAC Renaud's avatar
LE GAC Renaud committed
225
        return True
226

LE GAC Renaud's avatar
LE GAC Renaud committed
227
    return False