utils.py
branchtls-sprint
changeset 1549 f87561822e27
parent 1397 6cbc7bc8ea6d
child 1603 56217e741939
equal deleted inserted replaced
1548:bd225e776739 1549:f87561822e27
     6 """
     6 """
     7 __docformat__ = "restructuredtext en"
     7 __docformat__ = "restructuredtext en"
     8 
     8 
     9 import locale
     9 import locale
    10 from md5 import md5
    10 from md5 import md5
       
    11 from calendar import monthrange
    11 from datetime import datetime, timedelta, date
    12 from datetime import datetime, timedelta, date
    12 from time import time
    13 from time import time
    13 from random import randint, seed
    14 from random import randint, seed
    14     
    15 
    15 # initialize random seed from current time
    16 # initialize random seed from current time
    16 seed()
    17 seed()
    17 
    18 
    18 try:
    19 try:
    19     strptime = datetime.strptime
    20     strptime = datetime.strptime
    27     if isinstance(somedate, datetime):
    28     if isinstance(somedate, datetime):
    28         return date(somedate.year, somedate.month, somedate.day)
    29         return date(somedate.year, somedate.month, somedate.day)
    29     assert isinstance(somedate, date)
    30     assert isinstance(somedate, date)
    30     return date
    31     return date
    31 
    32 
       
    33 ONEDAY = timedelta(days=1)
       
    34 
       
    35 def days_in_month(date_):
       
    36     return monthrange(date_.year, date_.month)[1]
       
    37 
       
    38 def previous_month(date_):
       
    39     return first_day(date_) - ONEDAY
       
    40 
       
    41 def next_month(date_):
       
    42     return last_day(date_) + ONEDAY
       
    43 
       
    44 def first_day(date_):
       
    45     return date(date_.year, date_.month, 1)
       
    46 
       
    47 def last_day(date_):
       
    48     return date(date_.year, date_.month, days_in_month(date_))
       
    49 
    32 def date_range(begin, end, incr=1, include=None):
    50 def date_range(begin, end, incr=1, include=None):
    33     """yields each date between begin and end
    51     """yields each date between begin and end
    34     :param begin: the start date
    52     :param begin: the start date
    35     :param end: the end date
    53     :param end: the end date
    36     :param incr: the step to use to iterate over dates. Default is
    54     :param incr: the step to use to iterate over dates. Default is
    37                  one day.                 
    55                  one day.
    38     :param include: None (means no exclusion) or a function taking a
    56     :param include: None (means no exclusion) or a function taking a
    39                     date as parameter, and returning True if the date
    57                     date as parameter, and returning True if the date
    40                     should be included.
    58                     should be included.
    41     """
    59     """
    42     incr = timedelta(incr, 0, 0)
    60     incr = timedelta(incr, 0, 0)
    43     while begin <= end:
    61     while begin <= end:
    44         if include is None or include(begin): 
    62         if include is None or include(begin):
    45             yield begin
    63             yield begin
    46         begin += incr
    64         begin += incr
    47 
    65 
    48 def ustrftime(date, fmt='%Y-%m-%d'):
    66 def ustrftime(date, fmt='%Y-%m-%d'):
    49     """like strftime, but returns a unicode string instead of an encoded
    67     """like strftime, but returns a unicode string instead of an encoded
    50     string which may be problematic with localized date.
    68     string which may be problematic with localized date.
    51     
    69 
    52     encoding is guessed by locale.getpreferredencoding()
    70     encoding is guessed by locale.getpreferredencoding()
    53     """
    71     """
    54     # date format may depend on the locale
    72     # date format may depend on the locale
    55     encoding = locale.getpreferredencoding(do_setlocale=False) or 'UTF-8'
    73     encoding = locale.getpreferredencoding(do_setlocale=False) or 'UTF-8'
    56     return unicode(date.strftime(str(fmt)), encoding)
    74     return unicode(date.strftime(str(fmt)), encoding)
    77 def merge_dicts(dict1, dict2):
    95 def merge_dicts(dict1, dict2):
    78     """update a copy of `dict1` with `dict2`"""
    96     """update a copy of `dict1` with `dict2`"""
    79     dict1 = dict(dict1)
    97     dict1 = dict(dict1)
    80     dict1.update(dict2)
    98     dict1.update(dict2)
    81     return dict1
    99     return dict1
    82                 
   100 
    83 
   101 
    84 class SizeConstrainedList(list):
   102 class SizeConstrainedList(list):
    85     """simple list that makes sure the list does not get bigger
   103     """simple list that makes sure the list does not get bigger
    86     than a given size.
   104     than a given size.
    87 
   105 
   118     specifed in the constructor
   136     specifed in the constructor
   119     """
   137     """
   120 
   138 
   121     def __nonzero__(self):
   139     def __nonzero__(self):
   122         return True
   140         return True
   123     
   141 
   124     def write(self, value):
   142     def write(self, value):
   125         assert isinstance(value, unicode), u"unicode required not %s : %s"\
   143         assert isinstance(value, unicode), u"unicode required not %s : %s"\
   126                                      % (type(value).__name__, repr(value))
   144                                      % (type(value).__name__, repr(value))
   127         self.append(value)
   145         self.append(value)
   128         
   146 
   129     def getvalue(self):
   147     def getvalue(self):
   130         return u''.join(self)
   148         return u''.join(self)
   131 
   149 
   132     def __repr__(self):
   150     def __repr__(self):
   133         return '<%s at %#x>' % (self.__class__.__name__, id(self))
   151         return '<%s at %#x>' % (self.__class__.__name__, id(self))
   162 
   180 
   163     def add_onload(self, jscode):
   181     def add_onload(self, jscode):
   164         self.add_post_inline_script(u"""jQuery(document).ready(function () {
   182         self.add_post_inline_script(u"""jQuery(document).ready(function () {
   165  %s
   183  %s
   166  });""" % jscode)
   184  });""" % jscode)
   167         
   185 
   168     
   186 
   169     def add_js(self, jsfile):
   187     def add_js(self, jsfile):
   170         """adds `jsfile` to the list of javascripts used in the webpage
   188         """adds `jsfile` to the list of javascripts used in the webpage
   171 
   189 
   172         This function checks if the file has already been added
   190         This function checks if the file has already been added
   173         :param jsfile: the script's URL
   191         :param jsfile: the script's URL
   229             w(u'\n</script>\n')
   247             w(u'\n</script>\n')
   230         header = super(HTMLHead, self).getvalue()
   248         header = super(HTMLHead, self).getvalue()
   231         if skiphead:
   249         if skiphead:
   232             return header
   250             return header
   233         return u'<head>\n%s</head>\n' % header
   251         return u'<head>\n%s</head>\n' % header
   234         
   252 
   235 
   253 
   236 class HTMLStream(object):
   254 class HTMLStream(object):
   237     """represents a HTML page.
   255     """represents a HTML page.
   238 
   256 
   239     This is used my main templates so that HTML headers can be added
   257     This is used my main templates so that HTML headers can be added
   240     at any time during the page generation.
   258     at any time during the page generation.
   241     
   259 
   242     HTMLStream uses the (U)StringIO interface to be compliant with
   260     HTMLStream uses the (U)StringIO interface to be compliant with
   243     existing code.
   261     existing code.
   244     """
   262     """
   245     
   263 
   246     def __init__(self, req):
   264     def __init__(self, req):
   247         # stream for <head>
   265         # stream for <head>
   248         self.head = req.html_headers
   266         self.head = req.html_headers
   249         # main stream
   267         # main stream
   250         self.body = UStringIO()
   268         self.body = UStringIO()