utils.py
branchtls-sprint
changeset 1715 cba9f175da2d
parent 1711 182536159750
child 1751 59e9a4f5bfea
equal deleted inserted replaced
1714:a721966779be 1715:cba9f175da2d
     9 import locale
     9 import locale
    10 from md5 import md5
    10 from md5 import md5
    11 from datetime import datetime, timedelta, date
    11 from datetime import datetime, timedelta, date
    12 from time import time
    12 from time import time
    13 from random import randint, seed
    13 from random import randint, seed
    14     
    14 from calendar import monthrange
       
    15 
    15 # initialize random seed from current time
    16 # initialize random seed from current time
    16 seed()
    17 seed()
    17 
       
    18 try:
    18 try:
    19     strptime = datetime.strptime
    19     strptime = datetime.strptime
    20 except AttributeError: # py < 2.5
    20 except AttributeError: # py < 2.5
    21     from time import strptime as time_strptime
    21     from time import strptime as time_strptime
    22     def strptime(value, format):
    22     def strptime(value, format):
    24 
    24 
    25 def todate(somedate):
    25 def todate(somedate):
    26     """return a date from a date (leaving unchanged) or a datetime"""
    26     """return a date from a date (leaving unchanged) or a datetime"""
    27     if isinstance(somedate, datetime):
    27     if isinstance(somedate, datetime):
    28         return date(somedate.year, somedate.month, somedate.day)
    28         return date(somedate.year, somedate.month, somedate.day)
    29     assert isinstance(somedate, date)
    29     assert isinstance(somedate, date), repr(somedate)
    30     return date
    30     return somedate
    31 
    31 
    32 def date_range(begin, end, incr=1, include=None):
    32 def todatetime(somedate):
       
    33     """return a date from a date (leaving unchanged) or a datetime"""
       
    34     if isinstance(somedate, date):
       
    35         return datetime(somedate.year, somedate.month, somedate.day)
       
    36     assert isinstance(somedate, datetime), repr(somedate)
       
    37     return somedate
       
    38 
       
    39 ONEDAY = timedelta(days=1)
       
    40 ONEWEEK = timedelta(days=7)
       
    41 
       
    42 def days_in_month(date_):
       
    43     return monthrange(date_.year, date_.month)[1]
       
    44 
       
    45 def previous_month(date_, nbmonth=1):
       
    46     while nbmonth:
       
    47         date_ = first_day(date_) - ONEDAY
       
    48         nbmonth -= 1
       
    49     return date_
       
    50 
       
    51 def next_month(date_, nbmonth=1):
       
    52     while nbmonth:
       
    53         date_ = last_day(date_) + ONEDAY
       
    54         nbmonth -= 1
       
    55     return date_
       
    56 
       
    57 def first_day(date_):
       
    58     return date(date_.year, date_.month, 1)
       
    59 
       
    60 def last_day(date_):
       
    61     return date(date_.year, date_.month, days_in_month(date_))
       
    62 
       
    63 def date_range(begin, end, incday=None, incmonth=None):
    33     """yields each date between begin and end
    64     """yields each date between begin and end
    34     :param begin: the start date
    65     :param begin: the start date
    35     :param end: the end date
    66     :param end: the end date
    36     :param incr: the step to use to iterate over dates. Default is
    67     :param incr: the step to use to iterate over dates. Default is
    37                  one day.                 
    68                  one day.
    38     :param include: None (means no exclusion) or a function taking a
    69     :param include: None (means no exclusion) or a function taking a
    39                     date as parameter, and returning True if the date
    70                     date as parameter, and returning True if the date
    40                     should be included.
    71                     should be included.
    41     """
    72     """
    42     incr = timedelta(incr, 0, 0)
    73     assert not (incday and incmonth)
    43     while begin <= end:
    74     begin = todate(begin)
    44         if include is None or include(begin): 
    75     end = todate(end)
       
    76     if incmonth:
       
    77         while begin < end:
       
    78             begin = next_month(begin, incmonth)
    45             yield begin
    79             yield begin
    46         begin += incr
    80     else:
       
    81         if not incday:
       
    82             incr = ONEDAY
       
    83         else:
       
    84             incr = timedelta(incday)
       
    85         while begin <= end:
       
    86            yield begin
       
    87            begin += incr
    47 
    88 
    48 def ustrftime(date, fmt='%Y-%m-%d'):
    89 def ustrftime(date, fmt='%Y-%m-%d'):
    49     """like strftime, but returns a unicode string instead of an encoded
    90     """like strftime, but returns a unicode string instead of an encoded
    50     string which may be problematic with localized date.
    91     string which' may be problematic with localized date.
    51     
    92 
    52     encoding is guessed by locale.getpreferredencoding()
    93     encoding is guessed by locale.getpreferredencoding()
    53     """
    94     """
    54     # date format may depend on the locale
    95     # date format may depend on the locale
    55     encoding = locale.getpreferredencoding(do_setlocale=False) or 'UTF-8'
    96     encoding = locale.getpreferredencoding(do_setlocale=False) or 'UTF-8'
    56     return unicode(date.strftime(str(fmt)), encoding)
    97     return unicode(date.strftime(str(fmt)), encoding)
    77 def merge_dicts(dict1, dict2):
   118 def merge_dicts(dict1, dict2):
    78     """update a copy of `dict1` with `dict2`"""
   119     """update a copy of `dict1` with `dict2`"""
    79     dict1 = dict(dict1)
   120     dict1 = dict(dict1)
    80     dict1.update(dict2)
   121     dict1.update(dict2)
    81     return dict1
   122     return dict1
    82                 
   123 
    83 
   124 
    84 class SizeConstrainedList(list):
   125 class SizeConstrainedList(list):
    85     """simple list that makes sure the list does not get bigger
   126     """simple list that makes sure the list does not get bigger
    86     than a given size.
   127     than a given size.
    87 
   128 
   118     specifed in the constructor
   159     specifed in the constructor
   119     """
   160     """
   120 
   161 
   121     def __nonzero__(self):
   162     def __nonzero__(self):
   122         return True
   163         return True
   123     
   164 
   124     def write(self, value):
   165     def write(self, value):
   125         assert isinstance(value, unicode), u"unicode required not %s : %s"\
   166         assert isinstance(value, unicode), u"unicode required not %s : %s"\
   126                                      % (type(value).__name__, repr(value))
   167                                      % (type(value).__name__, repr(value))
   127         self.append(value)
   168         self.append(value)
   128         
   169 
   129     def getvalue(self):
   170     def getvalue(self):
   130         return u''.join(self)
   171         return u''.join(self)
   131 
   172 
   132     def __repr__(self):
   173     def __repr__(self):
   133         return '<%s at %#x>' % (self.__class__.__name__, id(self))
   174         return '<%s at %#x>' % (self.__class__.__name__, id(self))
   162 
   203 
   163     def add_onload(self, jscode):
   204     def add_onload(self, jscode):
   164         self.add_post_inline_script(u"""jQuery(document).ready(function () {
   205         self.add_post_inline_script(u"""jQuery(document).ready(function () {
   165  %s
   206  %s
   166  });""" % jscode)
   207  });""" % jscode)
   167         
   208 
   168     
   209 
   169     def add_js(self, jsfile):
   210     def add_js(self, jsfile):
   170         """adds `jsfile` to the list of javascripts used in the webpage
   211         """adds `jsfile` to the list of javascripts used in the webpage
   171 
   212 
   172         This function checks if the file has already been added
   213         This function checks if the file has already been added
   173         :param jsfile: the script's URL
   214         :param jsfile: the script's URL
   229             w(u'\n</script>\n')
   270             w(u'\n</script>\n')
   230         header = super(HTMLHead, self).getvalue()
   271         header = super(HTMLHead, self).getvalue()
   231         if skiphead:
   272         if skiphead:
   232             return header
   273             return header
   233         return u'<head>\n%s</head>\n' % header
   274         return u'<head>\n%s</head>\n' % header
   234         
   275 
   235 
   276 
   236 class HTMLStream(object):
   277 class HTMLStream(object):
   237     """represents a HTML page.
   278     """represents a HTML page.
   238 
   279 
   239     This is used my main templates so that HTML headers can be added
   280     This is used my main templates so that HTML headers can be added
   240     at any time during the page generation.
   281     at any time during the page generation.
   241     
   282 
   242     HTMLStream uses the (U)StringIO interface to be compliant with
   283     HTMLStream uses the (U)StringIO interface to be compliant with
   243     existing code.
   284     existing code.
   244     """
   285     """
   245     
   286 
   246     def __init__(self, req):
   287     def __init__(self, req):
   247         # stream for <head>
   288         # stream for <head>
   248         self.head = req.html_headers
   289         self.head = req.html_headers
   249         # main stream
   290         # main stream
   250         self.body = UStringIO()
   291         self.body = UStringIO()