1 """ |
|
2 Some additional helpers |
|
3 """ |
|
4 |
|
5 import datetime |
|
6 import calendar as _calendar |
|
7 |
|
8 import qmsk.web.helpers |
|
9 |
|
10 import preferences, urls, config, version |
|
11 |
|
12 class Helpers (qmsk.web.helpers.Helpers) : |
|
13 """ |
|
14 Our set of helpers, inheriting from base helpers |
|
15 """ |
|
16 |
|
17 # set contructor... |
|
18 set = set |
|
19 |
|
20 # reference to calendar instance |
|
21 calendar = _calendar.Calendar() |
|
22 |
|
23 # list of (month_num, month_name) for the months in the year |
|
24 months = list(enumerate(_calendar.month_name))[1:] |
|
25 |
|
26 def version_link (self) : |
|
27 """ |
|
28 Returns a <a href> representing this version of the software |
|
29 """ |
|
30 |
|
31 return version.version_link_hg(config.HGWEB_URL, config.HG_WC_PATH) |
|
32 |
|
33 def tz_name (self, tz) : |
|
34 """ |
|
35 Returns a string describing the given timezone |
|
36 """ |
|
37 |
|
38 return self.now().strftime(config.TIMEZONE_FMT) |
|
39 |
|
40 def fmt_month (self, date) : |
|
41 """ |
|
42 Formats a month |
|
43 """ |
|
44 |
|
45 return date.strftime(config.MONTH_FMT) |
|
46 |
|
47 def fmt_weekday (self, wday) : |
|
48 """ |
|
49 Formats an abbreviated weekday name |
|
50 """ |
|
51 |
|
52 return _calendar.day_abbr[wday] |
|
53 |
|
54 def build_date (self, month, mday) : |
|
55 """ |
|
56 Returns a datetime.datetime for the given (month.year, month.month, mday) |
|
57 """ |
|
58 |
|
59 return self.ctx['prefs'][preferences.timezone].localize(datetime.datetime(month.year, month.month, mday)) |
|
60 |
|
61 def now (self) : |
|
62 """ |
|
63 Build current time |
|
64 """ |
|
65 |
|
66 return self.ctx['prefs'][preferences.timezone].localize(datetime.datetime.now()) |
|
67 |
|
68 def today (self) : |
|
69 """ |
|
70 Build today's date |
|
71 """ |
|
72 |
|
73 return self.now().date() |
|
74 |
|
75 def is_today (self, dt) : |
|
76 """ |
|
77 Checks if the given datetime.datetime is today |
|
78 """ |
|
79 |
|
80 # compare with current date |
|
81 return dt.date() == self.today() |
|
82 |
|
83 def is_this_month (self, month) : |
|
84 """ |
|
85 Checks the given month is the current month |
|
86 """ |
|
87 |
|
88 today = self.today() |
|
89 |
|
90 return (month.year == today.year and month.month == today.month) |
|
91 |
|
92 @staticmethod |
|
93 def _wrap_year (year, month) : |
|
94 """ |
|
95 Wraps month to between [1, 12], spilling overflow/underflow by to year. |
|
96 |
|
97 Returns (year, month) |
|
98 """ |
|
99 |
|
100 # underflow? |
|
101 if month == 0 : |
|
102 # wrap to previous year |
|
103 return (year - 1, 12) |
|
104 |
|
105 # overflow? |
|
106 elif month == 13 : |
|
107 # wrap to next year |
|
108 return (year + 1, 1) |
|
109 |
|
110 # sane value |
|
111 elif 1 <= month <= 12 : |
|
112 return (year, month) |
|
113 |
|
114 # insane value |
|
115 else : |
|
116 assert False, "invalid year/month: %d/%d" % (year, month) |
|
117 |
|
118 def prev_month (self, month) : |
|
119 """ |
|
120 Returns the month preceding the given one (as a datetime.datetime) |
|
121 """ |
|
122 |
|
123 # previous month |
|
124 y, m = self._wrap_year(month.year, month.month - 1) |
|
125 |
|
126 # build datetime |
|
127 return datetime.datetime(year=y, month=m, day=1, tzinfo=month.tzinfo) |
|
128 |
|
129 def next_month (self, month) : |
|
130 """ |
|
131 Returns the month following the given one (as a datetime.datetime) |
|
132 """ |
|
133 |
|
134 # previous month |
|
135 y, m = self._wrap_year(month.year, month.month + 1) |
|
136 |
|
137 # build datetime |
|
138 return datetime.datetime(year=y, month=m, day=1, tzinfo=month.tzinfo) |
|
139 |
|
140 def fmt_time (self, time=None) : |
|
141 """ |
|
142 Format given time, or current time |
|
143 """ |
|
144 |
|
145 # defaults |
|
146 if not time : |
|
147 time = self.now() |
|
148 |
|
149 return time.strftime(self.ctx['prefs'][preferences.time_format]) |
|
150 |
|
151 def fmt_date (self, date=None) : |
|
152 """ |
|
153 Format given date, or current date |
|
154 """ |
|
155 |
|
156 # defaults |
|
157 if not date : |
|
158 date = self.now() |
|
159 |
|
160 return date.strftime(self.ctx['prefs'][preferences.date_format]) |
|
161 |
|
162 def url (self, url, **params) : |
|
163 """ |
|
164 Build URL with our request object |
|
165 """ |
|
166 |
|
167 return url.build(self.ctx['req'], **params) |
|
168 |
|
169 # old name |
|
170 build_url = url |
|
171 |
|
172 def utc_timestamp (self, dtz) : |
|
173 """ |
|
174 Build an UTC timestamp from the given datetime |
|
175 """ |
|
176 |
|
177 return urls.types['ts'].build(dtz) |
|
178 |
|
179 def skip_next (self, count, skip) : |
|
180 """ |
|
181 Return skip offset for next page |
|
182 """ |
|
183 |
|
184 return count + skip |
|
185 |
|
186 def skip_page (self, count, page) : |
|
187 """ |
|
188 Skip to page |
|
189 """ |
|
190 |
|
191 if page : |
|
192 return count * page |
|
193 |
|
194 else : |
|
195 return None |
|
196 |
|
197 def skip_prev (self, count, skip) : |
|
198 """ |
|
199 Return skip offset for previous page, None for first page |
|
200 """ |
|
201 |
|
202 if skip > count : |
|
203 return skip - count |
|
204 |
|
205 else : |
|
206 return None |
|
207 |
|
208 def max (self, *values) : |
|
209 """ |
|
210 Returns the largest of the given values |
|
211 """ |
|
212 |
|
213 return max(values) |
|
214 |
|
215 def select_options (self, key_values, selected_key=None) : |
|
216 """ |
|
217 Render a series of <option> tags for <select>. |
|
218 |
|
219 The given key_values is an iterable of (key, value) pairs, key may be None if it's the same as value. |
|
220 """ |
|
221 |
|
222 return '\n'.join( |
|
223 '\t<option%s%s>%s</option>' % ( |
|
224 ' value="%s"' % key if key is not None else '', |
|
225 ' selected="selected"' if (key if key is not None else value) == selected_key else '', |
|
226 value |
|
227 ) for key, value in key_values |
|
228 ) |
|
229 |
|
230 def prev_date (self, date) : |
|
231 """ |
|
232 Returns the previous date for the given datetime-date |
|
233 """ |
|
234 |
|
235 return datetime.datetime(date.year, date.month, date.day, tzinfo=date.tzinfo) - datetime.timedelta(days=1) |
|
236 |
|
237 def next_date (self, date) : |
|
238 """ |
|
239 Returns the previous date for the given datetime-date |
|
240 """ |
|
241 |
|
242 return datetime.datetime(date.year, date.month, date.day, tzinfo=date.tzinfo) + datetime.timedelta(days=1) |
|
243 |
|