[CalendarServer-changes] [14027] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Tue Sep 30 04:58:08 PDT 2014
Revision: 14027
http://trac.calendarserver.org//changeset/14027
Author: cdaboo at apple.com
Date: 2014-09-30 04:58:08 -0700 (Tue, 30 Sep 2014)
Log Message:
-----------
Update to latest tzdist draft.
Modified Paths:
--------------
CalendarServer/trunk/requirements-stable.txt
CalendarServer/trunk/twistedcaldav/ical.py
CalendarServer/trunk/twistedcaldav/timezonestdservice.py
Modified: CalendarServer/trunk/requirements-stable.txt
===================================================================
--- CalendarServer/trunk/requirements-stable.txt 2014-09-30 11:58:01 UTC (rev 14026)
+++ CalendarServer/trunk/requirements-stable.txt 2014-09-30 11:58:08 UTC (rev 14027)
@@ -7,7 +7,7 @@
-e .
-e svn+http://svn.calendarserver.org/repository/calendarserver/twext/trunk@14020#egg=twextpy
-e svn+http://svn.calendarserver.org/repository/calendarserver/PyKerberos/trunk@13420#egg=kerberos
--e svn+http://svn.calendarserver.org/repository/calendarserver/PyCalendar/trunk@13802#egg=pycalendar
+-e svn+http://svn.calendarserver.org/repository/calendarserver/PyCalendar/trunk@14025#egg=pycalendar
# Specify specific versions of our dependencies so that we're all testing the same config.
Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py 2014-09-30 11:58:01 UTC (rev 14026)
+++ CalendarServer/trunk/twistedcaldav/ical.py 2014-09-30 11:58:08 UTC (rev 14027)
@@ -3733,7 +3733,7 @@
-def tzexpandlocal(tzdata, start, end):
+def tzexpandlocal(tzdata, start, end, utc_onset=False):
"""
Expand a timezone to get onset(local)/utc-offset-from/utc-offset-to/name observance tuples within the specified
time range.
@@ -3744,6 +3744,8 @@
@type start: C{date}
@param end: date for the end of the expansion.
@type end: C{date}
+ @param utc_onset: whether or not onset values are in UTC.
+ @type utc_onset: C{bool}
@return: a C{list} of tuples
"""
@@ -3778,9 +3780,9 @@
tzcomp._pycalendar.getTimezoneOffsetSeconds(start),
tzcomp._pycalendar.getTimezoneDescriptor(start),
))
- for tzstart, _ignore_utctzstart, tzoffsetfrom, tzoffsetto, name in tzexpanded:
+ for tzstart, utctzstart, tzoffsetfrom, tzoffsetto, name in tzexpanded:
results.append((
- tzstart,
+ utctzstart if utc_onset else tzstart,
tzoffsetfrom,
tzoffsetto,
name,
Modified: CalendarServer/trunk/twistedcaldav/timezonestdservice.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/timezonestdservice.py 2014-09-30 11:58:01 UTC (rev 14026)
+++ CalendarServer/trunk/twistedcaldav/timezonestdservice.py 2014-09-30 11:58:08 UTC (rev 14027)
@@ -17,7 +17,7 @@
"""
Timezone service resource and operations.
-This is based on http://tools.ietf.org/html/draft-douglass-timezone-service which is the CalConnect
+This is based on http://tools.ietf.org/html/draft-ietf-tzdist-service which is the IETF
proposal for a standard timezone service.
"""
@@ -29,7 +29,7 @@
from txweb2 import responsecode
from txweb2.dav.method.propfind import http_PROPFIND
from txweb2.dav.noneprops import NonePropertyStore
-from txweb2.http import HTTPError, JSONResponse
+from txweb2.http import HTTPError, JSONResponse, StatusResponse
from txweb2.http import Response
from txweb2.http_headers import MimeType
from txweb2.stream import MemoryStream
@@ -196,18 +196,13 @@
http_PROPFIND = http_PROPFIND
- def http_GET(self, request):
- """
- The timezone service POST method.
- """
+ def http_POST(self, request):
+ raise HTTPError(StatusResponse(responsecode.NOT_ALLOWED, "Method not allowed"))
- # GET and POST do the same thing
- return self.http_POST(request)
-
- def http_POST(self, request):
+ def http_GET(self, request):
"""
- The timezone service POST method.
+ The timezone service GET method.
"""
# Check authentication and access controls
@@ -234,6 +229,7 @@
"list" : self.doList,
"get" : self.doGet,
"expand" : self.doExpand,
+ "find" : self.doFind,
}.get(action, None)
if action is None:
@@ -290,6 +286,12 @@
{"name": "end", "required": False, "multi": False, },
],
},
+ {
+ "name": "find",
+ "parameters": [
+ {"name": "pattern", "required": True, "multi": False, },
+ ],
+ },
]
}
return JSONResponse(responsecode.OK, result, pretty=config.TimezoneService.PrettyPrintJSON)
@@ -416,11 +418,14 @@
if len(start) > 1:
raise ValueError()
elif len(start) == 1:
- start = DateTime.parseText("{}0101".format(int(start[0])))
+ if len(start[0]) != 20:
+ raise ValueError()
+ start = DateTime.parseText(start[0], fullISO=True)
else:
- start = DateTime.getToday()
+ start = DateTime.getNowUTC()
start.setDay(1)
start.setMonth(1)
+ start.setHHMMSS(0, 0, 0)
except ValueError:
raise HTTPError(JSONResponse(
responsecode.BAD_REQUEST,
@@ -436,11 +441,14 @@
if len(end) > 1:
raise ValueError()
elif len(end) == 1:
- end = DateTime.parseText("{}0101".format(int(end[0])))
+ if len(end[0]) != 20:
+ raise ValueError()
+ end = DateTime.parseText(end[0], fullISO=True)
else:
- end = DateTime.getToday()
+ end = DateTime.getNowUTC()
end.setDay(1)
end.setMonth(1)
+ start.setHHMMSS(0, 0, 0)
end.offsetYear(10)
if end <= start:
raise ValueError()
@@ -469,12 +477,13 @@
# Now do the expansion (but use a cache to avoid re-calculating TZs)
observances = self.expandcache.get((tzid, start, end), None)
if observances is None:
- observances = tzexpandlocal(tzdata, start, end)
+ observances = tzexpandlocal(tzdata, start, end, utc_onset=True)
self.expandcache[(tzid, start, end)] = observances
# Turn into JSON
result = {
"dtstamp": self.timezones.dtstamp,
+ "tzid": tzid,
"observances": [
{
"name": name,
@@ -487,7 +496,81 @@
return JSONResponse(responsecode.OK, result, pretty=config.TimezoneService.PrettyPrintJSON)
+ def doFind(self, request):
+ """
+ Return a list of all timezones matching a pattern.
+ """
+ pattern = request.args.get("pattern", ())
+ if len(pattern) != 1:
+ raise HTTPError(JSONResponse(
+ responsecode.BAD_REQUEST,
+ {
+ "error": "invalid-pattern",
+ "description": "Invalid pattern query parameter",
+ },
+ pretty=config.TimezoneService.PrettyPrintJSON,
+ ))
+ pattern = pattern[0]
+
+ def _comp_is(pattern, s):
+ return pattern == s
+ def _comp_startswith(pattern, s):
+ return s.startswith(pattern)
+ def _comp_endswith(pattern, s):
+ return s.endswith(pattern)
+ def _comp_contains(pattern, s):
+ return pattern in s
+
+ def _normalize(s):
+ return s.replace("_", " ").lower()
+
+ if pattern.startswith("*") and pattern.endswith("*"):
+ pattern = pattern[1:-1]
+ comparator = _comp_contains
+ elif pattern.endswith("*"):
+ pattern = pattern[:-1]
+ comparator = _comp_startswith
+ elif pattern.startswith("*"):
+ pattern = pattern[1:]
+ comparator = _comp_endswith
+ else:
+ comparator = _comp_is
+ pattern = _normalize(pattern)
+
+ if not pattern:
+ raise HTTPError(JSONResponse(
+ responsecode.BAD_REQUEST,
+ {
+ "error": "invalid-pattern",
+ "description": "Invalid pattern query parameter",
+ },
+ pretty=config.TimezoneService.PrettyPrintJSON,
+ ))
+
+ timezones = []
+ for tz in self.timezones.listTimezones(None):
+ matched = comparator(pattern, _normalize(tz.tzid))
+ if not matched:
+ for alias in tz.aliases:
+ if comparator(pattern, _normalize(alias)):
+ matched = True
+ break
+ if matched:
+ timezones.append({
+ "tzid": tz.tzid,
+ "last-modified": tz.dtstamp,
+ "aliases": tz.aliases,
+ })
+
+ result = {
+ "dtstamp": self.timezones.dtstamp,
+ "timezones": timezones,
+ }
+ return JSONResponse(responsecode.OK, result, pretty=config.TimezoneService.PrettyPrintJSON)
+
+
+
class TimezoneInfo(object):
"""
Maintains information from an on-disk store of timezone files.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140930/be79eb6d/attachment-0001.html>
More information about the calendarserver-changes
mailing list