1.1 --- a/EventAggregatorSupport.py Sun Mar 14 23:21:52 2010 +0100
1.2 +++ b/EventAggregatorSupport.py Tue Mar 16 00:58:18 2010 +0100
1.3 @@ -45,7 +45,7 @@
1.4 month_regexp_str = ur'(?P<year>[0-9]{4})-(?P<month>[0-9]{2})'
1.5 date_regexp_str = ur'(?P<year>[0-9]{4})-(?P<month>[0-9]{2})-(?P<day>[0-9]{2})'
1.6 time_regexp_str = ur'(?P<hour>[0-2][0-9]):(?P<minute>[0-5][0-9])(?::(?P<second>[0-6][0-9]))?'
1.7 -timezone_offset_str = ur'(?:UTC)?(?P<sign>[-+])(?P<hours>[0-9]{2})(?::?(?P<minutes>[0-9]{2}))?'
1.8 +timezone_offset_str = ur'(UTC)?(?:(?P<sign>[-+])(?P<hours>[0-9]{2})(?::?(?P<minutes>[0-9]{2}))?)?'
1.9 timezone_regexp_str = ur'(?P<zone>' + timezone_offset_str + ')'
1.10 datetime_regexp_str = date_regexp_str + ur'(?:\s+' + time_regexp_str + ur'(?:\s+' + timezone_regexp_str + ur')?)?'
1.11
1.12 @@ -890,6 +890,15 @@
1.13
1.14 "A simple year-month-day representation."
1.15
1.16 + def constrain(self):
1.17 + year, month, day = self.as_tuple()[:3]
1.18 +
1.19 + month = max(min(month, 12), 1)
1.20 + wd, last_day = calendar.monthrange(year, month)
1.21 + day = max(min(day, last_day), 1)
1.22 +
1.23 + self.data[1:3] = month, day
1.24 +
1.25 def __str__(self):
1.26 return "%04d-%02d-%02d" % self.as_tuple()[:3]
1.27
1.28 @@ -943,8 +952,19 @@
1.29
1.30 "A simple date plus time representation."
1.31
1.32 - def __init__(self, data):
1.33 - Date.__init__(self, data)
1.34 + def constrain(self):
1.35 + Date.constrain(self)
1.36 +
1.37 + hour, minute, second = self.as_tuple()[3:6]
1.38 +
1.39 + if self.has_time():
1.40 + hour = max(min(hour, 23), 0)
1.41 + minute = max(min(minute, 59), 0)
1.42 +
1.43 + if second is not None:
1.44 + second = max(min(second, 60), 0) # support leap seconds
1.45 +
1.46 + self.data[3:6] = hour, minute, second
1.47
1.48 def __str__(self):
1.49 if self.has_time():
1.50 @@ -1034,6 +1054,11 @@
1.51 if not zone:
1.52 return None
1.53
1.54 + # Support explicit UTC zones.
1.55 +
1.56 + if zone == "UTC":
1.57 + return 0, 0
1.58 +
1.59 # Attempt to return a UTC offset where an explicit offset has been set.
1.60
1.61 match = timezone_offset_regexp.match(zone)
2.1 --- a/actions/EventAggregatorNewEvent.py Sun Mar 14 23:21:52 2010 +0100
2.2 +++ b/actions/EventAggregatorNewEvent.py Tue Mar 16 00:58:18 2010 +0100
2.3 @@ -14,8 +14,6 @@
2.4 from MoinMoin.Page import Page
2.5 from MoinMoin.PageEditor import PageEditor
2.6 import EventAggregatorSupport
2.7 -import calendar
2.8 -import re
2.9
2.10 Dependencies = ['pages']
2.11
2.12 @@ -31,8 +29,12 @@
2.13 def _get_selected_for_list(self, value, input_values):
2.14 return value in input_values and 'selected="selected"' or ''
2.15
2.16 - def _get_input(self, form, name, default):
2.17 - return int(form.get(name, [None])[0] or default)
2.18 + def _get_input(self, form, name, default=None):
2.19 + value = form.get(name, [None])[0]
2.20 + if not value: # true if 0 obtained
2.21 + return default
2.22 + else:
2.23 + return int(value)
2.24
2.25 def get_form_html(self, buttons_html):
2.26 _ = self._
2.27 @@ -77,6 +79,36 @@
2.28 del topics[i]
2.29 break
2.30
2.31 + # Initialise hour and minute lists.
2.32 +
2.33 + start_hour_list = []
2.34 + start_hour_list.append('<option value=""></option>')
2.35 + start_minute_list = []
2.36 + start_minute_list.append('<option value=""></option>')
2.37 + end_hour_list = []
2.38 + end_hour_list.append('<option value=""></option>')
2.39 + end_minute_list = []
2.40 + end_minute_list.append('<option value=""></option>')
2.41 +
2.42 + start_hour = self._get_input(form, "start-hour")
2.43 + end_hour = self._get_input(form, "end-hour")
2.44 + start_minute = self._get_input(form, "start-minute")
2.45 + end_minute = self._get_input(form, "end-minute")
2.46 +
2.47 + # Prepare hour and minute lists, selecting specified values.
2.48 +
2.49 + for hour in range(0, 24):
2.50 + selected = self._get_selected(hour, start_hour)
2.51 + start_hour_list.append('<option value="%02d" %s>%02d</option>' % (hour, selected, hour))
2.52 + selected = self._get_selected(hour, end_hour)
2.53 + end_hour_list.append('<option value="%02d" %s>%02d</option>' % (hour, selected, hour))
2.54 +
2.55 + for minute in range(0, 60):
2.56 + selected = self._get_selected(minute, start_minute)
2.57 + start_minute_list.append('<option value="%02d" %s>%02d</option>' % (minute, selected, minute))
2.58 + selected = self._get_selected(minute, end_minute)
2.59 + end_minute_list.append('<option value="%02d" %s>%02d</option>' % (minute, selected, minute))
2.60 +
2.61 # Initialise month lists.
2.62
2.63 start_month_list = []
2.64 @@ -104,14 +136,27 @@
2.65 "buttons_html" : buttons_html,
2.66 "category_label" : _("Categories"),
2.67 "category_list" : "\n".join(category_list),
2.68 +
2.69 "start_month_list" : "\n".join(start_month_list),
2.70 + "start_hour_list" : "\n".join(start_hour_list),
2.71 + "start_minute_list" : "\n".join(start_minute_list),
2.72 +
2.73 "end_month_list" : "\n".join(end_month_list),
2.74 + "end_hour_list" : "\n".join(end_hour_list),
2.75 + "end_minute_list" : "\n".join(end_minute_list),
2.76 +
2.77 "start_label" : _("Start date (day, month, year)"),
2.78 "start_day_default" : form.get("start-day", [""])[0],
2.79 "start_year_default" : form.get("start-year", [""])[0] or EventAggregatorSupport.getCurrentYear(),
2.80 + "start_time_label" : _("Start time (hour, minute, second)"),
2.81 + "start_second_default" : form.get("start-second", [""])[0],
2.82 +
2.83 "end_label" : _("End date (day, month, year) - if different"),
2.84 "end_day_default" : form.get("end-day", [""])[0],
2.85 "end_year_default" : form.get("end-year", [""])[0],
2.86 + "end_time_label" : _("End time (hour, minute, second)"),
2.87 + "end_second_default" : form.get("end-second", [""])[0],
2.88 +
2.89 "title_label" : _("Event title/summary"),
2.90 "title_default" : form.get("title", [""])[0],
2.91 "description_label" : _("Event description"),
2.92 @@ -120,13 +165,16 @@
2.93 "location_default" : form.get("location", [""])[0],
2.94 "link_label" : _("Event URL"),
2.95 "link_default" : form.get("link", [""])[0],
2.96 +
2.97 "topics_label" : _("Topics"),
2.98 "add_topic_label" : _("Add topic"),
2.99 "remove_topic_label" : _("Remove topic"),
2.100 +
2.101 "template_label" : _("Event template"),
2.102 "template_default" : form.get("template", [""])[0] or template_default,
2.103 "parent_label" : _("Parent page"),
2.104 "parent_default" : form.get("parent", [""])[0],
2.105 +
2.106 "advanced_label" : _("Show advanced options"),
2.107 "basic_label" : _("Show basic options"),
2.108 }
2.109 @@ -152,6 +200,18 @@
2.110 </td>
2.111 </tr>
2.112 <tr>
2.113 + <td class="label"><label>%(start_time_label)s</label></td>
2.114 + <td>
2.115 + <select name="start-hour">
2.116 + %(start_hour_list)s
2.117 + </select>
2.118 + <select name="start-minute">
2.119 + %(start_minute_list)s
2.120 + </select>
2.121 + <input name="start-second" type="text" value="%(start_second_default)s" size="2" />
2.122 + </td>
2.123 + </tr>
2.124 + <tr>
2.125 <td class="label"><label>%(end_label)s</label></td>
2.126 <td>
2.127 <input name="end-day" type="text" value="%(end_day_default)s" size="2" />
2.128 @@ -162,6 +222,18 @@
2.129 </td>
2.130 </tr>
2.131 <tr>
2.132 + <td class="label"><label>%(end_time_label)s</label></td>
2.133 + <td>
2.134 + <select name="end-hour">
2.135 + %(end_hour_list)s
2.136 + </select>
2.137 + <select name="end-minute">
2.138 + %(end_minute_list)s
2.139 + </select>
2.140 + <input name="end-second" type="text" value="%(end_second_default)s" size="2" />
2.141 + </td>
2.142 + </tr>
2.143 + <tr>
2.144 <td class="label"><label>%(description_label)s</label></td>
2.145 <td>
2.146 <input name="description" type="text" size="40" value="%(description_default)s" />
2.147 @@ -305,13 +377,19 @@
2.148 link = form.get("link", [None])[0]
2.149 topics = form.get("topics", [])
2.150
2.151 + start_zone = form.get("start-zone", [None])[0]
2.152 + end_zone = form.get("end-zone", [None])[0]
2.153 +
2.154 # Validate certain fields.
2.155
2.156 try:
2.157 title = form["title"][0]
2.158 template = form["template"][0]
2.159 parent = form["parent"][0]
2.160 + except (KeyError, IndexError):
2.161 + return 0, _("Event title or template missing.")
2.162
2.163 + try:
2.164 start_day = self._get_input(form, "start-day", 0)
2.165 start_month = self._get_input(form, "start-month", 0)
2.166 start_year = self._get_input(form, "start-year", 0)
2.167 @@ -319,25 +397,38 @@
2.168 end_month = self._get_input(form, "end-month", start_month)
2.169 end_year = self._get_input(form, "end-year", start_year)
2.170
2.171 - start_year, start_month, start_day = self.constrain_date(start_year, start_month, start_day)
2.172 - end_year, end_month, end_day = self.constrain_date(end_year, end_month, end_day)
2.173 -
2.174 except (TypeError, ValueError):
2.175 return 0, _("Days and years must be numbers yielding a valid date!")
2.176
2.177 - except (KeyError, IndexError):
2.178 - return 0, _("Event title or template missing.")
2.179 + try:
2.180 + start_hour = self._get_input(form, "start-hour")
2.181 + start_minute = self._get_input(form, "start-minute")
2.182 + start_second = self._get_input(form, "start-second")
2.183 +
2.184 + end_hour = self._get_input(form, "end-hour")
2.185 + end_minute = self._get_input(form, "end-minute")
2.186 + end_second = self._get_input(form, "end-second")
2.187
2.188 - start_date = self.make_date_string(start_year, start_month, start_day)
2.189 - end_date = self.make_date_string(end_year, end_month, end_day)
2.190 + except (TypeError, ValueError):
2.191 + return 0, _("Hours, minutes and seconds must be numbers yielding a valid time!")
2.192 +
2.193 + start_date = EventAggregatorSupport.DateTime(
2.194 + (start_year, start_month, start_day, start_hour, start_minute, start_second, start_zone)
2.195 + )
2.196 + start_date.constrain()
2.197 +
2.198 + end_date = EventAggregatorSupport.DateTime(
2.199 + (end_year, end_month, end_day, end_hour, end_minute, end_second, end_zone)
2.200 + )
2.201 + end_date.constrain()
2.202
2.203 # An elementary date ordering check.
2.204
2.205 - if start_date > end_date:
2.206 + if (start_date.as_date() != end_date.as_date() or start_date.has_time() and end_date.has_time()) and start_date > end_date:
2.207 start_date, end_date = end_date, start_date
2.208
2.209 event_details = {
2.210 - "start" : start_date, "end" : end_date,
2.211 + "start" : str(start_date), "end" : str(end_date),
2.212 "title" : title, "summary" : title,
2.213 "description" : description, "location" : location, "link" : link,
2.214 "topics" : [topic for topic in topics if topic]
2.215 @@ -372,19 +463,6 @@
2.216 request.http_redirect(new_page.url(request, query))
2.217 return 1, None
2.218
2.219 - def make_date_string(self, year, month, day):
2.220 - return "%s-%s-%s" % (
2.221 - year and ("%04d" % year) or "YYYY",
2.222 - month and ("%02d" % month) or "MM",
2.223 - day and ("%02d" % day) or "DD"
2.224 - )
2.225 -
2.226 - def constrain_date(self, year, month, day):
2.227 - if year and month and day:
2.228 - wd, last_day = calendar.monthrange(year, month)
2.229 - day = max(min(day, last_day), 1)
2.230 - return year, month, day
2.231 -
2.232 # Action function.
2.233
2.234 def execute(pagename, request):