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) |
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)) |
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() |