utils.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 22 Oct 2010 18:08:05 +0200
branchstable
changeset 6603 1ba51b00fc44
parent 6406 39663630ca3c
child 6409 d75535983224
permissions -rw-r--r--
Added tag cubicweb-version-3.9.9 for changeset df0b2de62cec
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     1
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
6044
9e48ebd5400c [view] use the new magic js object to generate javascript func call for auto reload user callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5940
diff changeset
    18
"""Some utilities for CubicWeb server/clients."""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
4952
f32dcf3925d4 [web] get rid of spurious '[Errno 2] No such file or directory' on load
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4860
diff changeset
    22
import os
3316
c4c07aab1c39 backport old head
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3231 3155
diff changeset
    23
import sys
c4c07aab1c39 backport old head
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3231 3155
diff changeset
    24
import decimal
4466
8b0ca7904820 moved generic datetime manipulation function to lgc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4335
diff changeset
    25
import datetime
4653
ca11228a5268 import cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4652
diff changeset
    26
import random
5069
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
    27
from itertools import repeat
4833
41a78fb4107c 3.7 depends on python >= 2.5
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4693
diff changeset
    28
from uuid import uuid4
4830
10e8bc190695 [javascript] fix #736185: add_onload / jQuery.bind() vs. jQuery.one()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4693
diff changeset
    29
from warnings import warn
4653
ca11228a5268 import cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4652
diff changeset
    30
ca11228a5268 import cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4652
diff changeset
    31
from logilab.mtconverter import xml_escape
ca11228a5268 import cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4652
diff changeset
    32
from logilab.common.deprecation import deprecated
1549
f87561822e27 some basic calendar manipulation functions, delete-trailing-whitespace
sylvain.thenault@logilab.fr
parents: 1397
diff changeset
    33
4830
10e8bc190695 [javascript] fix #736185: add_onload / jQuery.bind() vs. jQuery.one()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4693
diff changeset
    34
_MARKER = object()
10e8bc190695 [javascript] fix #736185: add_onload / jQuery.bind() vs. jQuery.one()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4693
diff changeset
    35
1024
bb96289257bf remove unused working_hours function, new todate function since we can't compare date and datetime objects
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
    36
# initialize random seed from current time
4653
ca11228a5268 import cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4652
diff changeset
    37
random.seed()
1024
bb96289257bf remove unused working_hours function, new todate function since we can't compare date and datetime objects
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
    38
4880
fa6671e83639 [utils] make_uid imrovment: using .hex already remove '-', make key argument optional, document it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4879
diff changeset
    39
def make_uid(key=None):
fa6671e83639 [utils] make_uid imrovment: using .hex already remove '-', make key argument optional, document it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4879
diff changeset
    40
    """Return a unique identifier string.
4653
ca11228a5268 import cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4652
diff changeset
    41
4880
fa6671e83639 [utils] make_uid imrovment: using .hex already remove '-', make key argument optional, document it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4879
diff changeset
    42
    if specified, `key` is used to prefix the generated uid so it can be used
fa6671e83639 [utils] make_uid imrovment: using .hex already remove '-', make key argument optional, document it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4879
diff changeset
    43
    for instance as a DOM id or as sql table names.
4653
ca11228a5268 import cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4652
diff changeset
    44
4880
fa6671e83639 [utils] make_uid imrovment: using .hex already remove '-', make key argument optional, document it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4879
diff changeset
    45
    See uuid.uuid4 documentation for the shape of the generated identifier, but
fa6671e83639 [utils] make_uid imrovment: using .hex already remove '-', make key argument optional, document it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4879
diff changeset
    46
    this is basicallly a 32 bits hexadecimal string.
fa6671e83639 [utils] make_uid imrovment: using .hex already remove '-', make key argument optional, document it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4879
diff changeset
    47
    """
fa6671e83639 [utils] make_uid imrovment: using .hex already remove '-', make key argument optional, document it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4879
diff changeset
    48
    if key is None:
fa6671e83639 [utils] make_uid imrovment: using .hex already remove '-', make key argument optional, document it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4879
diff changeset
    49
        return uuid4().hex
fa6671e83639 [utils] make_uid imrovment: using .hex already remove '-', make key argument optional, document it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4879
diff changeset
    50
    return str(key) + uuid4().hex
3364
039d1694f36d fix uid generation for py >= 2.5
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3316
diff changeset
    51
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
def dump_class(cls, clsname):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
    """create copy of a class by creating an empty class inheriting
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
    from the given cls.
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
    Those class will be used as place holder for attribute and relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
    description
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
    # type doesn't accept unicode name
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
    # return type.__new__(type, str(clsname), (cls,), {})
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
    # __autogenerated__ attribute is just a marker
4881
39fc30001a20 [utils] improve dump_class by copying back original class doc and module name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4880
diff changeset
    63
    return type(str(clsname), (cls,), {'__autogenerated__': True,
39fc30001a20 [utils] improve dump_class by copying back original class doc and module name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4880
diff changeset
    64
                                       '__doc__': cls.__doc__,
39fc30001a20 [utils] improve dump_class by copying back original class doc and module name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4880
diff changeset
    65
                                       '__module__': cls.__module__})
1549
f87561822e27 some basic calendar manipulation functions, delete-trailing-whitespace
sylvain.thenault@logilab.fr
parents: 1397
diff changeset
    66
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
3882
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    68
# use networkX instead ?
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    69
# http://networkx.lanl.gov/reference/algorithms.traversal.html#module-networkx.algorithms.traversal.astar
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    70
def transitive_closure_of(entity, relname, _seen=None):
4317
b2093f8f0493 some docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    71
    """return transitive closure *for the subgraph starting from the given
b2093f8f0493 some docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    72
    entity* (eg 'parent' entities are not included in the results)
b2093f8f0493 some docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    73
    """
3882
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    74
    if _seen is None:
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    75
        _seen = set()
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    76
    _seen.add(entity.eid)
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    77
    yield entity
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    78
    for child in getattr(entity, relname):
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    79
        if child.eid in _seen:
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    80
            continue
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    81
        for subchild in transitive_closure_of(child, relname, _seen):
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    82
            yield subchild
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    83
addc715f4fcd backported from confman
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3851
diff changeset
    84
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
class SizeConstrainedList(list):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
    """simple list that makes sure the list does not get bigger
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
    than a given size.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
    when the list is full and a new element is added, the first
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
    element of the list is removed before appending the new one
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
    >>> l = SizeConstrainedList(2)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
    >>> l.append(1)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
    >>> l.append(2)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
    >>> l
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
    [1, 2]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
    >>> l.append(3)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
    [2, 3]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
    def __init__(self, maxsize):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
        self.maxsize = maxsize
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
    def append(self, element):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
        if len(self) == self.maxsize:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
            del self[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
        super(SizeConstrainedList, self).append(element)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
    def extend(self, sequence):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
        super(SizeConstrainedList, self).extend(sequence)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
        keepafter = len(self) - self.maxsize
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
        if keepafter > 0:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
            del self[:keepafter]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
    __iadd__ = extend
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
5069
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   117
class RepeatList(object):
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   118
    """fake a list with the same element in each row"""
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   119
    __slots__ = ('_size', '_item')
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   120
    def __init__(self, size, item):
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   121
        self._size = size
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   122
        self._item = item
5883
7a5f370c5be1 [utils] improve repr() of RepeatList
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 5726
diff changeset
   123
    def __repr__(self):
7a5f370c5be1 [utils] improve repr() of RepeatList
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 5726
diff changeset
   124
        return '<cubicweb.utils.RepeatList at %s item=%s size=%s>' % (
7a5f370c5be1 [utils] improve repr() of RepeatList
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 5726
diff changeset
   125
            id(self), self._item, self._size)
5069
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   126
    def __len__(self):
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   127
        return self._size
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   128
    def __nonzero__(self):
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   129
        return self._size
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   130
    def __iter__(self):
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   131
        return repeat(self._item, self._size)
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   132
    def __getitem__(self, index):
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   133
        return self._item
6374
5adf53edfe12 [rset] support for delitem on repeat list (may be necessary in pyro source)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6176
diff changeset
   134
    def __delitem__(self, idc):
5adf53edfe12 [rset] support for delitem on repeat list (may be necessary in pyro source)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6176
diff changeset
   135
        assert self._size > 0
5adf53edfe12 [rset] support for delitem on repeat list (may be necessary in pyro source)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6176
diff changeset
   136
        self._size -= 1
5069
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   137
    def __getslice__(self, i, j):
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   138
        # XXX could be more efficient, but do we bother?
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   139
        return ([self._item] * self._size)[i:j]
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   140
    def __add__(self, other):
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   141
        if isinstance(other, RepeatList):
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   142
            if other._item == self._item:
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   143
                return RepeatList(self._size + other._size, self._item)
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   144
            return ([self._item] * self._size) + other[:]
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   145
        return ([self._item] * self._size) + other
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   146
    def __radd__(self, other):
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   147
        if isinstance(other, RepeatList):
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   148
            if other._item == self._item:
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   149
                return RepeatList(self._size + other._size, self._item)
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   150
            return other[:] + ([self._item] * self._size)
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   151
        return other[:] + ([self._item] * self._size)
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   152
    def __eq__(self, other):
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   153
        if isinstance(other, RepeatList):
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   154
            return other._size == self.size and other._item == self.item
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   155
        return self[:] == other
5077
dc448c9ad9dd [rset] cubes such as iliane hi-jack rset description by poping some lines from it. Handle this on RepeatList
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5069
diff changeset
   156
    def pop(self, i):
dc448c9ad9dd [rset] cubes such as iliane hi-jack rset description by poping some lines from it. Handle this on RepeatList
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5069
diff changeset
   157
        self._size -= 1
5069
135c5d7b89d0 [querier] introduce RepeatList class, used to optimize size of data returned for result set description
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4961
diff changeset
   158
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
class UStringIO(list):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
    """a file wrapper which automatically encode unicode string to an encoding
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
    specifed in the constructor
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
    def __nonzero__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
        return True
1549
f87561822e27 some basic calendar manipulation functions, delete-trailing-whitespace
sylvain.thenault@logilab.fr
parents: 1397
diff changeset
   166
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
    def write(self, value):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
        assert isinstance(value, unicode), u"unicode required not %s : %s"\
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
                                     % (type(value).__name__, repr(value))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
        self.append(value)
1549
f87561822e27 some basic calendar manipulation functions, delete-trailing-whitespace
sylvain.thenault@logilab.fr
parents: 1397
diff changeset
   171
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
    def getvalue(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
        return u''.join(self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
    def __repr__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
        return '<%s at %#x>' % (self.__class__.__name__, id(self))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
class HTMLHead(UStringIO):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
    """wraps HTML header's stream
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
    Request objects use a HTMLHead instance to ease adding of
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
    javascripts and stylesheets
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
    js_unload_code = u'jQuery(window).unload(unloadPageData);'
6406
39663630ca3c xml-escape <script> tags generated by HTMLHead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6374
diff changeset
   186
    # Making <script> tag content work properly with all possible
39663630ca3c xml-escape <script> tags generated by HTMLHead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6374
diff changeset
   187
    # content-types (xml/html) and all possible browsers is very
39663630ca3c xml-escape <script> tags generated by HTMLHead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6374
diff changeset
   188
    # tricky, see http://www.hixie.ch/advocacy/xhtml for an in-depth discussion
39663630ca3c xml-escape <script> tags generated by HTMLHead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6374
diff changeset
   189
    xhtml_safe_script_opening = u'<script type="text/javascript"><!--//--><![CDATA[//><!--\n'
39663630ca3c xml-escape <script> tags generated by HTMLHead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6374
diff changeset
   190
    xhtml_safe_script_closing = u'\n//--><!]]></script>'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
    def __init__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
        super(HTMLHead, self).__init__()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   194
        self.jsvars = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
        self.jsfiles = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
        self.cssfiles = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
        self.ie_cssfiles = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
        self.post_inlined_scripts = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
        self.pagedata_unload = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
    def add_raw(self, rawheader):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
        self.write(rawheader)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
3838
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   205
    def define_var(self, var, value, override=True):
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   206
        """adds a javascript var declaration / assginment in the header
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   207
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   208
        :param var: the variable name
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   209
        :param value: the variable value (as a raw python value,
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   210
                      it will be jsonized later)
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   211
        :param override: if False, don't set the variable value if the variable
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   212
                         is already defined. Default is True.
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   213
        """
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   214
        self.jsvars.append( (var, value, override) )
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
    def add_post_inline_script(self, content):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
        self.post_inlined_scripts.append(content)
28
9b7067bfaa15 introduce html_headers.on_load() method as a shortcut for add_post_inline_script('''jQuery(document).ready(...''')
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
   218
4830
10e8bc190695 [javascript] fix #736185: add_onload / jQuery.bind() vs. jQuery.one()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4693
diff changeset
   219
    def add_onload(self, jscode, jsoncall=_MARKER):
10e8bc190695 [javascript] fix #736185: add_onload / jQuery.bind() vs. jQuery.one()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4693
diff changeset
   220
        if jsoncall is not _MARKER:
10e8bc190695 [javascript] fix #736185: add_onload / jQuery.bind() vs. jQuery.one()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4693
diff changeset
   221
            warn('[3.7] specifying jsoncall is not needed anymore',
10e8bc190695 [javascript] fix #736185: add_onload / jQuery.bind() vs. jQuery.one()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4693
diff changeset
   222
                 DeprecationWarning, stacklevel=2)
10e8bc190695 [javascript] fix #736185: add_onload / jQuery.bind() vs. jQuery.one()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4693
diff changeset
   223
        self.add_post_inline_script(u"""jQuery(CubicWeb).one('server-response', function(event) {
4903
627fcd90e08f fix bad conflict resolution
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4899
diff changeset
   224
%s});""" % jscode)
1549
f87561822e27 some basic calendar manipulation functions, delete-trailing-whitespace
sylvain.thenault@logilab.fr
parents: 1397
diff changeset
   225
f87561822e27 some basic calendar manipulation functions, delete-trailing-whitespace
sylvain.thenault@logilab.fr
parents: 1397
diff changeset
   226
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
    def add_js(self, jsfile):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
        """adds `jsfile` to the list of javascripts used in the webpage
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
        This function checks if the file has already been added
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
        :param jsfile: the script's URL
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
        if jsfile not in self.jsfiles:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
            self.jsfiles.append(jsfile)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
    def add_css(self, cssfile, media):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
        """adds `cssfile` to the list of javascripts used in the webpage
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
        This function checks if the file has already been added
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
        :param cssfile: the stylesheet's URL
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
        if (cssfile, media) not in self.cssfiles:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
            self.cssfiles.append( (cssfile, media) )
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
4860
cedb6afdb7da [web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4859
diff changeset
   245
    def add_ie_css(self, cssfile, media='all', iespec=u'[if lt IE 8]'):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
        """registers some IE specific CSS"""
4860
cedb6afdb7da [web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4859
diff changeset
   247
        if (cssfile, media, iespec) not in self.ie_cssfiles:
cedb6afdb7da [web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4859
diff changeset
   248
            self.ie_cssfiles.append( (cssfile, media, iespec) )
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
    def add_unload_pagedata(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   251
        """registers onunload callback to clean page data on server"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
        if not self.pagedata_unload:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   253
            self.post_inlined_scripts.append(self.js_unload_code)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
            self.pagedata_unload = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
643
616191014b8b [jsoncontroller] reorganize _html_exec (used by replacePageChunk) to output required css and js scripts
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 28
diff changeset
   256
    def getvalue(self, skiphead=False):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
        """reimplement getvalue to provide a consistent (and somewhat browser
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   258
        optimzed cf. http://stevesouders.com/cuzillion) order in external
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   259
        resources declaration
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
        w = self.write
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
        # 1/ variable declaration if any
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
        if self.jsvars:
6406
39663630ca3c xml-escape <script> tags generated by HTMLHead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6374
diff changeset
   264
            w(self.xhtml_safe_script_opening)
3838
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   265
            for var, value, override in self.jsvars:
5389
809d3b5b3d31 [python2.6] careful: json-py provides a json package. We don't want that.
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5377
diff changeset
   266
                vardecl = u'%s = %s;' % (var, json.dumps(value))
3838
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   267
                if not override:
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   268
                    vardecl = (u'if (typeof %s == "undefined") {%s}' %
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   269
                               (var, vardecl))
9cc134372bf8 [web] safety belt to avoid overriding pageid with loadxhtml()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3789
diff changeset
   270
                w(vardecl + u'\n')
6406
39663630ca3c xml-escape <script> tags generated by HTMLHead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6374
diff changeset
   271
            w(self.xhtml_safe_script_closing)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   272
        # 2/ css files
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
        for cssfile, media in self.cssfiles:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   274
            w(u'<link rel="stylesheet" type="text/css" media="%s" href="%s"/>\n' %
3091
c3d73cecb29e [html-head] escape js and css urls
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2678
diff changeset
   275
              (media, xml_escape(cssfile)))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
        # 3/ ie css if necessary
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   277
        if self.ie_cssfiles:
4860
cedb6afdb7da [web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4859
diff changeset
   278
            for cssfile, media, iespec in self.ie_cssfiles:
cedb6afdb7da [web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4859
diff changeset
   279
                w(u'<!--%s>\n' % iespec)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   280
                w(u'<link rel="stylesheet" type="text/css" media="%s" href="%s"/>\n' %
3091
c3d73cecb29e [html-head] escape js and css urls
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2678
diff changeset
   281
                  (media, xml_escape(cssfile)))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   282
            w(u'<![endif]--> \n')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   283
        # 4/ js files
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   284
        for jsfile in self.jsfiles:
3091
c3d73cecb29e [html-head] escape js and css urls
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2678
diff changeset
   285
            w(u'<script type="text/javascript" src="%s"></script>\n' %
c3d73cecb29e [html-head] escape js and css urls
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2678
diff changeset
   286
              xml_escape(jsfile))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   287
        # 5/ post inlined scripts (i.e. scripts depending on other JS files)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   288
        if self.post_inlined_scripts:
6406
39663630ca3c xml-escape <script> tags generated by HTMLHead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6374
diff changeset
   289
            w(self.xhtml_safe_script_opening)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   290
            w(u'\n\n'.join(self.post_inlined_scripts))
6406
39663630ca3c xml-escape <script> tags generated by HTMLHead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6374
diff changeset
   291
            w(self.xhtml_safe_script_closing)
643
616191014b8b [jsoncontroller] reorganize _html_exec (used by replacePageChunk) to output required css and js scripts
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 28
diff changeset
   292
        header = super(HTMLHead, self).getvalue()
616191014b8b [jsoncontroller] reorganize _html_exec (used by replacePageChunk) to output required css and js scripts
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 28
diff changeset
   293
        if skiphead:
616191014b8b [jsoncontroller] reorganize _html_exec (used by replacePageChunk) to output required css and js scripts
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 28
diff changeset
   294
            return header
616191014b8b [jsoncontroller] reorganize _html_exec (used by replacePageChunk) to output required css and js scripts
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 28
diff changeset
   295
        return u'<head>\n%s</head>\n' % header
1549
f87561822e27 some basic calendar manipulation functions, delete-trailing-whitespace
sylvain.thenault@logilab.fr
parents: 1397
diff changeset
   296
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   297
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   298
class HTMLStream(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   299
    """represents a HTML page.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   300
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   301
    This is used my main templates so that HTML headers can be added
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   302
    at any time during the page generation.
1549
f87561822e27 some basic calendar manipulation functions, delete-trailing-whitespace
sylvain.thenault@logilab.fr
parents: 1397
diff changeset
   303
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   304
    HTMLStream uses the (U)StringIO interface to be compliant with
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   305
    existing code.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   306
    """
1549
f87561822e27 some basic calendar manipulation functions, delete-trailing-whitespace
sylvain.thenault@logilab.fr
parents: 1397
diff changeset
   307
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   308
    def __init__(self, req):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   309
        # stream for <head>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   310
        self.head = req.html_headers
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   311
        # main stream
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   312
        self.body = UStringIO()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   313
        self.doctype = u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   314
        # xmldecl and html opening tag
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   315
        self.xmldecl = u'<?xml version="1.0" encoding="%s"?>\n' % req.encoding
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   316
        self.htmltag = u'<html xmlns="http://www.w3.org/1999/xhtml" ' \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   317
                       'xmlns:cubicweb="http://www.logilab.org/2008/cubicweb" ' \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   318
                       'xml:lang="%s" lang="%s">' % (req.lang, req.lang)
3094
978ed8c2c0e4 [googlemap] #344872 set request content-type to text/html
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3091
diff changeset
   319
        # keep main_stream's reference on req for easier text/html demoting
978ed8c2c0e4 [googlemap] #344872 set request content-type to text/html
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3091
diff changeset
   320
        req.main_stream = self
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   321
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   322
    def write(self, data):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   323
        """StringIO interface: this method will be assigned to self.w
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   324
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   325
        self.body.write(data)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   326
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   327
    def getvalue(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   328
        """writes HTML headers, closes </head> tag and writes HTML body"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   329
        return u'%s\n%s\n%s\n%s\n%s\n</html>' % (self.xmldecl, self.doctype,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   330
                                                 self.htmltag,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   331
                                                 self.head.getvalue(),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   332
                                                 self.body.getvalue())
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   333
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   334
3371
762a7bc3b73d this has probably be killed by a bad merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3364
diff changeset
   335
try:
5389
809d3b5b3d31 [python2.6] careful: json-py provides a json package. We don't want that.
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5377
diff changeset
   336
    # may not be there if cubicweb-web not installed
5940
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5883
diff changeset
   337
    if sys.version_info < (2, 6):
5389
809d3b5b3d31 [python2.6] careful: json-py provides a json package. We don't want that.
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5377
diff changeset
   338
        import simplejson as json
809d3b5b3d31 [python2.6] careful: json-py provides a json package. We don't want that.
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5377
diff changeset
   339
    else:
809d3b5b3d31 [python2.6] careful: json-py provides a json package. We don't want that.
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5377
diff changeset
   340
        import json
3371
762a7bc3b73d this has probably be killed by a bad merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3364
diff changeset
   341
except ImportError:
5940
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5883
diff changeset
   342
    json_dumps = None
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5883
diff changeset
   343
3371
762a7bc3b73d this has probably be killed by a bad merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3364
diff changeset
   344
else:
6134
272cfcc10a28 use logilab.common.date.ustrftime in json encoder to work around datetime.strftime limitation on dates < 1900
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6044
diff changeset
   345
    from logilab.common.date import ustrftime
6176
33ba2c1dbf10 [cw.utils] avoid spurious warning, ustrftime may be globally imported
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6134
diff changeset
   346
5389
809d3b5b3d31 [python2.6] careful: json-py provides a json package. We don't want that.
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5377
diff changeset
   347
    class CubicWebJsonEncoder(json.JSONEncoder):
5377
84d14ddfae13 [python2.6] prefer python2.6's builtin json module over simplejson
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5320
diff changeset
   348
        """define a json encoder to be able to encode yams std types"""
5320
848e92bb81cc [json] provide a custom json encoder for entities that includes eid in the json object
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5077
diff changeset
   349
3371
762a7bc3b73d this has probably be killed by a bad merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3364
diff changeset
   350
        def default(self, obj):
5726
c3b99606644d [json] fix json serialization for recent simplejson implementation, and test encoding of entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   351
            if hasattr(obj, 'eid'):
c3b99606644d [json] fix json serialization for recent simplejson implementation, and test encoding of entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   352
                d = obj.cw_attr_cache.copy()
c3b99606644d [json] fix json serialization for recent simplejson implementation, and test encoding of entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   353
                d['eid'] = obj.eid
c3b99606644d [json] fix json serialization for recent simplejson implementation, and test encoding of entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   354
                return d
4466
8b0ca7904820 moved generic datetime manipulation function to lgc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4335
diff changeset
   355
            if isinstance(obj, datetime.datetime):
6134
272cfcc10a28 use logilab.common.date.ustrftime in json encoder to work around datetime.strftime limitation on dates < 1900
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6044
diff changeset
   356
                return ustrftime(obj, '%Y/%m/%d %H:%M:%S')
4466
8b0ca7904820 moved generic datetime manipulation function to lgc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4335
diff changeset
   357
            elif isinstance(obj, datetime.date):
6134
272cfcc10a28 use logilab.common.date.ustrftime in json encoder to work around datetime.strftime limitation on dates < 1900
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6044
diff changeset
   358
                return ustrftime(obj, '%Y/%m/%d')
4466
8b0ca7904820 moved generic datetime manipulation function to lgc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4335
diff changeset
   359
            elif isinstance(obj, datetime.time):
3371
762a7bc3b73d this has probably be killed by a bad merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3364
diff changeset
   360
                return obj.strftime('%H:%M:%S')
4466
8b0ca7904820 moved generic datetime manipulation function to lgc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4335
diff changeset
   361
            elif isinstance(obj, datetime.timedelta):
4000
4b16a7c01a25 fix jsonization of interval
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3902
diff changeset
   362
                return (obj.days * 24 * 60 * 60) + obj.seconds
3371
762a7bc3b73d this has probably be killed by a bad merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3364
diff changeset
   363
            elif isinstance(obj, decimal.Decimal):
762a7bc3b73d this has probably be killed by a bad merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3364
diff changeset
   364
                return float(obj)
762a7bc3b73d this has probably be killed by a bad merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3364
diff changeset
   365
            try:
5389
809d3b5b3d31 [python2.6] careful: json-py provides a json package. We don't want that.
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5377
diff changeset
   366
                return json.JSONEncoder.default(self, obj)
3371
762a7bc3b73d this has probably be killed by a bad merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3364
diff changeset
   367
            except TypeError:
762a7bc3b73d this has probably be killed by a bad merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3364
diff changeset
   368
                # we never ever want to fail because of an unknown type,
762a7bc3b73d this has probably be killed by a bad merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3364
diff changeset
   369
                # just return None in those cases.
762a7bc3b73d this has probably be killed by a bad merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3364
diff changeset
   370
                return None
4652
7c41eea7fc30 restore 3.5 compat for date functions moved to lgc.date in 3.6 (closes #716055)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4511
diff changeset
   371
5940
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5883
diff changeset
   372
    def json_dumps(value):
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5883
diff changeset
   373
        return json.dumps(value, cls=CubicWebJsonEncoder)
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5883
diff changeset
   374
4879
56c16efedc51 deprecates merge_dicts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4844
diff changeset
   375
56c16efedc51 deprecates merge_dicts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4844
diff changeset
   376
@deprecated('[3.7] merge_dicts is deprecated')
56c16efedc51 deprecates merge_dicts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4844
diff changeset
   377
def merge_dicts(dict1, dict2):
56c16efedc51 deprecates merge_dicts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4844
diff changeset
   378
    """update a copy of `dict1` with `dict2`"""
56c16efedc51 deprecates merge_dicts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4844
diff changeset
   379
    dict1 = dict(dict1)
56c16efedc51 deprecates merge_dicts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4844
diff changeset
   380
    dict1.update(dict2)
56c16efedc51 deprecates merge_dicts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4844
diff changeset
   381
    return dict1
56c16efedc51 deprecates merge_dicts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4844
diff changeset
   382
4652
7c41eea7fc30 restore 3.5 compat for date functions moved to lgc.date in 3.6 (closes #716055)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4511
diff changeset
   383
from logilab.common import date
7c41eea7fc30 restore 3.5 compat for date functions moved to lgc.date in 3.6 (closes #716055)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4511
diff changeset
   384
_THIS_MOD_NS = globals()
7c41eea7fc30 restore 3.5 compat for date functions moved to lgc.date in 3.6 (closes #716055)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4511
diff changeset
   385
for funcname in ('date_range', 'todate', 'todatetime', 'datetime2ticks',
7c41eea7fc30 restore 3.5 compat for date functions moved to lgc.date in 3.6 (closes #716055)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4511
diff changeset
   386
                 'days_in_month', 'days_in_year', 'previous_month',
6176
33ba2c1dbf10 [cw.utils] avoid spurious warning, ustrftime may be globally imported
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6134
diff changeset
   387
                 'next_month', 'first_day', 'last_day',
4652
7c41eea7fc30 restore 3.5 compat for date functions moved to lgc.date in 3.6 (closes #716055)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4511
diff changeset
   388
                 'strptime'):
7c41eea7fc30 restore 3.5 compat for date functions moved to lgc.date in 3.6 (closes #716055)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4511
diff changeset
   389
    msg = '[3.6] %s has been moved to logilab.common.date' % funcname
7c41eea7fc30 restore 3.5 compat for date functions moved to lgc.date in 3.6 (closes #716055)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4511
diff changeset
   390
    _THIS_MOD_NS[funcname] = deprecated(msg)(getattr(date, funcname))