appobject.py
author Nicolas Chauvat <nicolas.chauvat@logilab.fr>
Wed, 29 Jul 2009 00:12:43 +0200
changeset 2547 f32af375339d
parent 2476 1294a6bdf3bf
child 2613 5e19c2bb370e
permissions -rw-r--r--
[doc] fix FAQ layout
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
"""Base class for dynamically loaded objects manipulated in the web interface
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: 1756
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: 1756
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
2002
031414d88003 be stricter on catched exception, fix Time parsing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2001
diff changeset
    10
from datetime import datetime, timedelta, time
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    11
699
cc149f4def1e __selectors__ compat
sylvain.thenault@logilab.fr
parents: 692
diff changeset
    12
from logilab.common.decorators import classproperty
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
from logilab.common.deprecation import obsolete
447
0e52d72104a6 pylint fixes
sylvain.thenault@logilab.fr
parents: 237
diff changeset
    14
0e52d72104a6 pylint fixes
sylvain.thenault@logilab.fr
parents: 237
diff changeset
    15
from rql.nodes import VariableRef, SubQuery
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    16
from rql.stmts import Union, Select
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    17
1174
7dac5aeafb86 missing import
sylvain.thenault@logilab.fr
parents: 1144
diff changeset
    18
from cubicweb import Unauthorized, NoSelectableObject
726
88a74f590986 improve __selectors__() so that it always return a tuple
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 721
diff changeset
    19
from cubicweb.vregistry import VObject, AndSelector
692
800592b8d39b replace deprecated cubicweb.common.selectors by its new module path (cubicweb.selectors)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 683
diff changeset
    20
from cubicweb.selectors import yes
2001
c6bb482f40c6 fix import
Florent <florent@secondweb.fr>
parents: 1985
diff changeset
    21
from cubicweb.utils import UStringIO, ustrftime, strptime, todate, todatetime
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 875
diff changeset
    23
ONESECOND = timedelta(0, 1, 0)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    25
class Cache(dict):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
    def __init__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
        super(Cache, self).__init__()
2099
0cba78f4fa12 [CWCache] yet another bugfix in cwcache: proper initalization of Cache.creation_date
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2098
diff changeset
    28
        _now = datetime.now()
0cba78f4fa12 [CWCache] yet another bugfix in cwcache: proper initalization of Cache.creation_date
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2098
diff changeset
    29
        self.cache_creation_date = _now
0cba78f4fa12 [CWCache] yet another bugfix in cwcache: proper initalization of Cache.creation_date
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2098
diff changeset
    30
        self.latest_cache_lookup = _now
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    31
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
CACHE_REGISTRY = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
class AppRsetObject(VObject):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
    """This is the base class for CubicWeb application objects
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
    which are selected according to a request and result set.
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    37
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
    Classes are kept in the vregistry and instantiation is done at selection
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
    time.
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    40
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
    At registration time, the following attributes are set on the class:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
    :vreg:
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2144
diff changeset
    43
      the instance's registry
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
    :schema:
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2144
diff changeset
    45
      the instance's schema
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
    :config:
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2144
diff changeset
    47
      the instance's configuration
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
    At instantiation time, the following attributes are set on the instance:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
    :req:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
      current request
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
    :rset:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
      result set on which the object is applied
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
    """
805
6e99feeba28b set a default selector on base app objects class
sylvain.thenault@logilab.fr
parents: 802
diff changeset
    55
    __select__ = yes()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
    @classmethod
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
    def registered(cls, vreg):
721
sylvain.thenault@logilab.fr
parents: 719
diff changeset
    59
        super(AppRsetObject, cls).registered(vreg)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
        cls.vreg = vreg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
        cls.schema = vreg.schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
        cls.config = vreg.config
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
        cls.register_properties()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
        return cls
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    65
1282
272d8ec6f308 * print vreg content once fully initialized (require move of print code from vregistry to cwvreg)
sylvain.thenault@logilab.fr
parents: 1174
diff changeset
    66
    @classmethod
272d8ec6f308 * print vreg content once fully initialized (require move of print code from vregistry to cwvreg)
sylvain.thenault@logilab.fr
parents: 1174
diff changeset
    67
    def vreg_initialization_completed(cls):
272d8ec6f308 * print vreg content once fully initialized (require move of print code from vregistry to cwvreg)
sylvain.thenault@logilab.fr
parents: 1174
diff changeset
    68
        pass
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    69
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
    @classmethod
683
4f4a34346e9b fix initializers
sylvain.thenault@logilab.fr
parents: 662
diff changeset
    71
    def selected(cls, *args, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
        """by default web app objects are usually instantiated on
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
        selection according to a request, a result set, and optional
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
        row and col
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        """
875
dd83bd56deae assert select()
sylvain.thenault@logilab.fr
parents: 805
diff changeset
    76
        assert len(args) <= 2
1143
8d097defbf2c change the way selected/__init__ are used for AppRsetObject
sylvain.thenault@logilab.fr
parents: 1130
diff changeset
    77
        return cls(*args, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
    # Eproperties definition:
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    80
    # key: id of the property (the actual CWProperty key is build using
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
    #      <registry name>.<obj id>.<property id>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
    # value: tuple (property type, vocabfunc, default value, property description)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
    #        possible types are those used by `logilab.common.configuration`
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
    #
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
    # notice that when it exists multiple objects with the same id (adaptation,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
    # overriding) only the first encountered definition is considered, so those
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
    # objects can't try to have different default values for instance.
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    88
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
    property_defs = {}
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    90
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
    @classmethod
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
    def register_properties(cls):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
        for propid, pdef in cls.property_defs.items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
            pdef = pdef.copy() # may be shared
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
            pdef['default'] = getattr(cls, propid, pdef['default'])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
            pdef['sitewide'] = getattr(cls, 'site_wide', pdef.get('sitewide'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
            cls.vreg.register_property(cls.propkey(propid), **pdef)
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    98
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
    @classmethod
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
    def propkey(cls, propid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
        return '%s.%s.%s' % (cls.__registry__, cls.id, propid)
699
cc149f4def1e __selectors__ compat
sylvain.thenault@logilab.fr
parents: 692
diff changeset
   102
cc149f4def1e __selectors__ compat
sylvain.thenault@logilab.fr
parents: 692
diff changeset
   103
    @classproperty
cc149f4def1e __selectors__ compat
sylvain.thenault@logilab.fr
parents: 692
diff changeset
   104
    @obsolete('use __select__ and & or | operators')
cc149f4def1e __selectors__ compat
sylvain.thenault@logilab.fr
parents: 692
diff changeset
   105
    def __selectors__(cls):
726
88a74f590986 improve __selectors__() so that it always return a tuple
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 721
diff changeset
   106
        selector = cls.__select__
88a74f590986 improve __selectors__() so that it always return a tuple
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 721
diff changeset
   107
        if isinstance(selector, AndSelector):
732
45c3414ac002 __selectors__ must return a tuple
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 726
diff changeset
   108
            return tuple(selector.selectors)
726
88a74f590986 improve __selectors__() so that it always return a tuple
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 721
diff changeset
   109
        if not isinstance(selector, tuple):
88a74f590986 improve __selectors__() so that it always return a tuple
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 721
diff changeset
   110
            selector = (selector,)
88a74f590986 improve __selectors__() so that it always return a tuple
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 721
diff changeset
   111
        return selector
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   112
1143
8d097defbf2c change the way selected/__init__ are used for AppRsetObject
sylvain.thenault@logilab.fr
parents: 1130
diff changeset
   113
    def __init__(self, req=None, rset=None, row=None, col=None, **extra):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
        super(AppRsetObject, self).__init__()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
        self.req = req
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
        self.rset = rset
1143
8d097defbf2c change the way selected/__init__ are used for AppRsetObject
sylvain.thenault@logilab.fr
parents: 1130
diff changeset
   117
        self.row = row
8d097defbf2c change the way selected/__init__ are used for AppRsetObject
sylvain.thenault@logilab.fr
parents: 1130
diff changeset
   118
        self.col = col
8d097defbf2c change the way selected/__init__ are used for AppRsetObject
sylvain.thenault@logilab.fr
parents: 1130
diff changeset
   119
        self.extra_kwargs = extra
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   120
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
    def get_cache(self, cachename):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
        NOTE: cachename should be dotted names as in :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
        - cubicweb.mycache
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   125
        - cubes.blog.mycache
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
        - etc.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
        if cachename in CACHE_REGISTRY:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
            cache = CACHE_REGISTRY[cachename]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
        else:
2098
13aab3775af7 [CWCache] fix CWCache validity test
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2002
diff changeset
   131
            cache = CACHE_REGISTRY[cachename] = Cache()
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 875
diff changeset
   132
        _now = datetime.now()
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 875
diff changeset
   133
        if _now > cache.latest_cache_lookup + ONESECOND:
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   134
            ecache = self.req.execute('Any C,T WHERE C is CWCache, C name %(name)s, C timestamp T',
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
                                      {'name':cachename}).get_entity(0,0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
            cache.latest_cache_lookup = _now
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
            if not ecache.valid(cache.cache_creation_date):
1130
17ff4d4bfbd0 should call clear, not empth (thanks pylint)
sylvain.thenault@logilab.fr
parents: 1129
diff changeset
   138
                cache.clear()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
                cache.cache_creation_date = _now
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
        return cache
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
    def propval(self, propid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
        assert self.req
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
        return self.req.property_value(self.propkey(propid))
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   145
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
    def limited_rql(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
        """return a printable rql for the result set associated to the object,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
        with limit/offset correctly set according to maximum page size and
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
        currently displayed page when necessary
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
        # try to get page boundaries from the navigation component
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
        # XXX we should probably not have a ref to this component here (eg in
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
        #     cubicweb.common)
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2002
diff changeset
   154
        nav = self.vreg.select_object('components', 'navigation', self.req,
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2002
diff changeset
   155
                                      rset=self.rset)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
        if nav:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   157
            start, stop = nav.page_boundaries()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
            rql = self._limit_offset_rql(stop - start, start)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
        # result set may have be limited manually in which case navigation won't
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
        # apply
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
        elif self.rset.limited:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
            rql = self._limit_offset_rql(*self.rset.limited)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
        # navigation component doesn't apply and rset has not been limited, no
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
        # need to limit query
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
            rql = self.rset.printable_rql()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
        return rql
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   168
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
    def _limit_offset_rql(self, limit, offset):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
        rqlst = self.rset.syntax_tree()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
        if len(rqlst.children) == 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
            select = rqlst.children[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
            olimit, ooffset = select.limit, select.offset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
            select.limit, select.offset = limit, offset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
            rql = rqlst.as_string(kwargs=self.rset.args)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
            # restore original limit/offset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
            select.limit, select.offset = olimit, ooffset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
            newselect = Select()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
            newselect.limit = limit
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
            newselect.offset = offset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
            aliases = [VariableRef(newselect.get_variable(vref.name, i))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
                       for i, vref in enumerate(rqlst.selection)]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
            newselect.set_with([SubQuery(aliases, rqlst)], check=False)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
            newunion = Union()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
            newunion.append(newselect)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   187
            rql = rqlst.as_string(kwargs=self.rset.args)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
            rqlst.parent = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
        return rql
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   190
1144
654047cd0c30 move .view method on AppRsetObject, move initialize_varmaker method on View
sylvain.thenault@logilab.fr
parents: 1143
diff changeset
   191
    def view(self, __vid, rset=None, __fallback_vid=None, **kwargs):
1985
9c1db4e06095 move view method's logic on the registry, so it's easier to call it from outside an appobject. Also make rset argument optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1984
diff changeset
   192
        """shortcut to self.vreg.view method avoiding to pass self.req"""
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2002
diff changeset
   193
        return self.vreg.render(__vid, self.req, __fallback_vid, rset=rset,
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2002
diff changeset
   194
                                **kwargs)
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   195
1756
42d87dedd631 move initialize_varmaker impl to base app object
sylvain.thenault@logilab.fr
parents: 1723
diff changeset
   196
    def initialize_varmaker(self):
42d87dedd631 move initialize_varmaker impl to base app object
sylvain.thenault@logilab.fr
parents: 1723
diff changeset
   197
        varmaker = self.req.get_page_data('rql_varmaker')
42d87dedd631 move initialize_varmaker impl to base app object
sylvain.thenault@logilab.fr
parents: 1723
diff changeset
   198
        if varmaker is None:
42d87dedd631 move initialize_varmaker impl to base app object
sylvain.thenault@logilab.fr
parents: 1723
diff changeset
   199
            varmaker = self.req.varmaker
42d87dedd631 move initialize_varmaker impl to base app object
sylvain.thenault@logilab.fr
parents: 1723
diff changeset
   200
            self.req.set_page_data('rql_varmaker', varmaker)
42d87dedd631 move initialize_varmaker impl to base app object
sylvain.thenault@logilab.fr
parents: 1723
diff changeset
   201
        self.varmaker = varmaker
42d87dedd631 move initialize_varmaker impl to base app object
sylvain.thenault@logilab.fr
parents: 1723
diff changeset
   202
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
    # url generation methods ##################################################
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   204
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
    controller = 'view'
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   206
2059
af33833d7571 absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2058
diff changeset
   207
    def build_url(self, *args, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
        """return an absolute URL using params dictionary key/values as URL
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
        parameters. Values are automatically URL quoted, and the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
        publishing method to use may be specified or will be guessed.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
        """
2059
af33833d7571 absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2058
diff changeset
   212
        # use *args since we don't want first argument to be "anonymous" to
af33833d7571 absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2058
diff changeset
   213
        # avoid potential clash with kwargs
af33833d7571 absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2058
diff changeset
   214
        if args:
af33833d7571 absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2058
diff changeset
   215
            assert len(args) == 1, 'only 0 or 1 non-named-argument expected'
af33833d7571 absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2058
diff changeset
   216
            method = args[0]
af33833d7571 absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2058
diff changeset
   217
        else:
af33833d7571 absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2058
diff changeset
   218
            method = None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
        # XXX I (adim) think that if method is passed explicitly, we should
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
        #     not try to process it and directly call req.build_url()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
        if method is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
            method = self.controller
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
            if method == 'view' and self.req.from_controller() == 'view' and \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
                   not '_restpath' in kwargs:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
                method = self.req.relative_path(includeparams=False) or 'view'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
        return self.req.build_url(method, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
    # various resources accessors #############################################
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   229
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
    def entity(self, row, col=0):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
        """short cut to get an entity instance for a particular row/column
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
        (col default to 0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
        return self.rset.get_entity(row, col)
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   235
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
    def complete_entity(self, row, col=0, skip_bytes=True):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
        """short cut to get an completed entity instance for a particular
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
        row (all instance's attributes have been fetched)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
        entity = self.entity(row, col)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
        entity.complete(skip_bytes=skip_bytes)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
        return entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
    def user_rql_callback(self, args, msg=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
        """register a user callback to execute some rql query and return an url
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
        to call it ready to be inserted in html
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
        def rqlexec(req, rql, args=None, key=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
            req.execute(rql, args, key)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
        return self.user_callback(rqlexec, args, msg)
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   251
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
    def user_callback(self, cb, args, msg=None, nonify=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   253
        """register the given user callback and return an url to call it ready to be
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
        inserted in html
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
        """
1635
866563e2d0fc don't depends on simplejson outside web/
sylvain.thenault@logilab.fr
parents: 1524
diff changeset
   256
        from simplejson import dumps
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
        self.req.add_js('cubicweb.ajax.js')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   258
        cbname = self.req.register_onetime_callback(cb, *args)
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   259
        msg = dumps(msg or '')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
        return "javascript:userCallbackThenReloadPage('%s', %s)" % (
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
            cbname, msg)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
    # formating methods #######################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   264
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
    def tal_render(self, template, variables):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
        """render a precompiled page template with variables in the given
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
        dictionary as context
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
        """
1637
f5f6f25c2602 fix import
sylvain.thenault@logilab.fr
parents: 1635
diff changeset
   269
        from cubicweb.ext.tal import CubicWebContext
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
        context = CubicWebContext()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   271
        context.update({'self': self, 'rset': self.rset, '_' : self.req._,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   272
                        'req': self.req, 'user': self.req.user})
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
        context.update(variables)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   274
        output = UStringIO()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   275
        template.expand(context, output)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
        return output.getvalue()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   277
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   278
    def format_date(self, date, date_format=None, time=False):
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2144
diff changeset
   279
        """return a string for a date time according to instance's
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   280
        configuration
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   282
        if date:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   283
            if date_format is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   284
                if time:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   285
                    date_format = self.req.property_value('ui.datetime-format')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   286
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   287
                    date_format = self.req.property_value('ui.date-format')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   288
            return ustrftime(date, date_format)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   289
        return u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   290
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   291
    def format_time(self, time):
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2144
diff changeset
   292
        """return a string for a time according to instance's
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   293
        configuration
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   294
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   295
        if time:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   296
            return ustrftime(time, self.req.property_value('ui.time-format'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   297
        return u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   298
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   299
    def format_float(self, num):
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2144
diff changeset
   300
        """return a string for floating point number according to instance's
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   301
        configuration
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   302
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   303
        if num:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   304
            return self.req.property_value('ui.float-format') % num
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   305
        return u''
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   306
1984
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   307
    def parse_datetime(self, value, etype='Datetime'):
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   308
        """get a datetime or time from a string (according to etype)
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   309
        Datetime formatted as Date are accepted
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   310
        """
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   311
        assert etype in ('Datetime', 'Date', 'Time'), etype
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   312
        # XXX raise proper validation error
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   313
        if etype == 'Datetime':
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   314
            format = self.req.property_value('ui.datetime-format')
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   315
            try:
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   316
                return todatetime(strptime(value, format))
2002
031414d88003 be stricter on catched exception, fix Time parsing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2001
diff changeset
   317
            except ValueError:
1984
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   318
                pass
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   319
        elif etype == 'Time':
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   320
            format = self.req.property_value('ui.time-format')
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   321
            try:
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   322
                # (adim) I can't find a way to parse a Time with a custom format
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   323
                date = strptime(value, format) # this returns a DateTime
2002
031414d88003 be stricter on catched exception, fix Time parsing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2001
diff changeset
   324
                return time(date.hour, date.minute, date.second)
031414d88003 be stricter on catched exception, fix Time parsing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2001
diff changeset
   325
            except ValueError:
1984
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   326
                raise ValueError('can\'t parse %r (expected %s)' % (value, format))
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   327
        try:
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   328
            format = self.req.property_value('ui.date-format')
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   329
            dt = strptime(value, format)
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   330
            if etype == 'Datetime':
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   331
                return todatetime(dt)
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   332
            return todate(dt)
2002
031414d88003 be stricter on catched exception, fix Time parsing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2001
diff changeset
   333
        except ValueError:
1984
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   334
            raise ValueError('can\'t parse %r (expected %s)' % (value, format))
8d571df6012a move parse_datetime on appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   335
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   336
    # security related methods ################################################
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   337
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   338
    def ensure_ro_rql(self, rql):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   339
        """raise an exception if the given rql is not a select query"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   340
        first = rql.split(' ', 1)[0].lower()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   341
        if first in ('insert', 'set', 'delete'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   342
            raise Unauthorized(self.req._('only select queries are authorized'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   343
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   344
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   345
class AppObject(AppRsetObject):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   346
    """base class for application objects which are not selected
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   347
    according to a result set, only by their identifier.
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   348
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   349
    Those objects may not have req, rset and cursor set.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   350
    """
1524
1d7575f5deaf delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   351
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   352
    @classmethod
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   353
    def selected(cls, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   354
        """by default web app objects are usually instantiated on
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   355
        selection
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   356
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   357
        return cls(*args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   358
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   359
    def __init__(self, req=None, rset=None, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   360
        self.req = req
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   361
        self.rset = rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
        self.__dict__.update(kwargs)