sobjects/hooks.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 22 Dec 2009 21:02:37 +0100
branchstable
changeset 4195 86dcaf6bb92f
parent 3690 a5ef45850d23
child 4212 ab6573088b4a
permissions -rw-r--r--
closes #601987 1) sqlutils.restore_from_file have to use its confirm argument when a command fail, to propose to continue there (this can't be handled by the caller) 2) source.restore method hence needs to take this confirmation callback as argument 3) properly fix places where 'drop' was given instead of 'confirm'
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
"""various library content hooks
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     2
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     3
:organization: Logilab
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1802
diff changeset
     4
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1802
diff changeset
     6
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     7
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     9
2499
26fb72e0af23 missing import
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2498
diff changeset
    10
from datetime import datetime
26fb72e0af23 missing import
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2498
diff changeset
    11
2498
5fb8aabb0448 missing import
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2497
diff changeset
    12
from cubicweb import RepositoryError
1098
739d4dce9b19 * turn tidy_html_hook into a regular application hook
sylvain.thenault@logilab.fr
parents: 0
diff changeset
    13
from cubicweb.common.uilib import soup2xhtml
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    14
from cubicweb.server.hooksmanager import Hook
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    15
from cubicweb.server.pool import PreCommitOperation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    16
1098
739d4dce9b19 * turn tidy_html_hook into a regular application hook
sylvain.thenault@logilab.fr
parents: 0
diff changeset
    17
2497
07d20d5da4e3 boulet...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2495
diff changeset
    18
class SetModificationDateOnStateChange(Hook):
2495
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    19
    """update entity's modification date after changing its state"""
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    20
    events = ('after_add_relation',)
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    21
    accepts = ('in_state',)
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    22
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    23
    def call(self, session, fromeid, rtype, toeid):
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    24
        if fromeid in session.transaction_data.get('neweids', ()):
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    25
            # new entity, not needed
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    26
            return
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    27
        entity = session.entity_from_eid(fromeid)
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    28
        try:
2878
03244a6d0283 we should use unsafe_execute here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2499
diff changeset
    29
            entity.set_attributes(modification_date=datetime.now(),
03244a6d0283 we should use unsafe_execute here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2499
diff changeset
    30
                                  _cw_unsafe=True)
2495
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    31
        except RepositoryError, ex:
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    32
            # usually occurs if entity is coming from a read-only source
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    33
            # (eg ldap user)
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    34
            self.warning('cant change modification date for %s: %s', entity, ex)
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    35
abcbadcc110a #343839: update entity's modification date after changing its state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
    36
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1138
diff changeset
    37
class AddUpdateCWUserHook(Hook):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
    """ensure user logins are stripped"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
    events = ('before_add_entity', 'before_update_entity',)
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1138
diff changeset
    40
    accepts = ('CWUser',)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
    41
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
    def call(self, session, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
        if 'login' in entity and entity['login']:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
            entity['login'] = entity['login'].strip()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
class AutoDeleteBookmark(PreCommitOperation):
1138
22f634977c95 make pylint happy, fix some bugs on the way
sylvain.thenault@logilab.fr
parents: 1101
diff changeset
    48
    beid = None # make pylint happy
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
    def precommit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
        session = self.session
2101
08003e0354a7 update transaction data api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    51
        if not self.beid in session.transaction_data.get('pendingeids', ()):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
            if not session.unsafe_execute('Any X WHERE X bookmarked_by U, X eid %(x)s',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
                                          {'x': self.beid}, 'x'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
                session.unsafe_execute('DELETE Bookmark X WHERE X eid %(x)s',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
                                       {'x': self.beid}, 'x')
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
    56
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
class DelBookmarkedByHook(Hook):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
    """ensure user logins are stripped"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
    events = ('after_delete_relation',)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
    accepts = ('bookmarked_by',)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
    61
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
    def call(self, session, subj, rtype, obj):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
        AutoDeleteBookmark(session, beid=subj)
1098
739d4dce9b19 * turn tidy_html_hook into a regular application hook
sylvain.thenault@logilab.fr
parents: 0
diff changeset
    64
739d4dce9b19 * turn tidy_html_hook into a regular application hook
sylvain.thenault@logilab.fr
parents: 0
diff changeset
    65
739d4dce9b19 * turn tidy_html_hook into a regular application hook
sylvain.thenault@logilab.fr
parents: 0
diff changeset
    66
class TidyHtmlFields(Hook):
739d4dce9b19 * turn tidy_html_hook into a regular application hook
sylvain.thenault@logilab.fr
parents: 0
diff changeset
    67
    """tidy HTML in rich text strings"""
739d4dce9b19 * turn tidy_html_hook into a regular application hook
sylvain.thenault@logilab.fr
parents: 0
diff changeset
    68
    events = ('before_add_entity', 'before_update_entity')
739d4dce9b19 * turn tidy_html_hook into a regular application hook
sylvain.thenault@logilab.fr
parents: 0
diff changeset
    69
    accepts = ('Any',)
739d4dce9b19 * turn tidy_html_hook into a regular application hook
sylvain.thenault@logilab.fr
parents: 0
diff changeset
    70
739d4dce9b19 * turn tidy_html_hook into a regular application hook
sylvain.thenault@logilab.fr
parents: 0
diff changeset
    71
    def call(self, session, entity):
3690
a5ef45850d23 skip tidy hook for super session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2878
diff changeset
    72
        if session.is_super_session:
a5ef45850d23 skip tidy hook for super session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2878
diff changeset
    73
            return
1101
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    74
        metaattrs = entity.e_schema.meta_attributes()
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    75
        for metaattr, (metadata, attr) in metaattrs.iteritems():
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    76
            if metadata == 'format':
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    77
                try:
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    78
                    value = entity[attr]
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    79
                except KeyError:
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    80
                    continue # no text to tidy
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    81
                if isinstance(value, unicode): # filter out None and Binary
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    82
                    if self.event == 'before_add_entity':
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    83
                        fmt = entity.get(metaattr)
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    84
                    else:
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    85
                        fmt = entity.get_value(metaattr)
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    86
                    if fmt == 'text/html':
0c067de38e46 unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents: 1098
diff changeset
    87
                        entity[attr] = soup2xhtml(value, session.encoding)