def decode(data): if not data: return None # Timezone if data[-1] == 'Z': data = data[:-1] tzinfo = fixed_offset(0) else: p_pos = data.find('+') m_pos = data.find('-') pos = m_pos * p_pos if pos > 0: tzinfo = None else: pos = -pos sign = data[pos] offset = data[pos + 1:] if ':' in offset: offset = offset.split(':') else: offset = [offset[0:2], offset[2:]] o_h = int(offset[0]) o_m = int(offset[1]) if offset[1] else 0 data = data[:pos] offset = (o_h * 60 + o_m) if sign == '-': offset = -offset tzinfo = fixed_offset(offset) # Extended formats if ':' in data: parts = data.split(':') n = len(parts) if n > 3: raise ValueError, 'unexpected time value "%s"' % data hour = int(parts[0]) minute = int(parts[1]) if n == 2: return time(hour, minute, tzinfo=tzinfo) second = int(parts[2]) return time(hour, minute, second, tzinfo=tzinfo) # Basic formats hour = int(data[:2]) data = data[2:] if not data: return time(hour, tzinfo=tzinfo) # Minute minute = int(data[:2]) data = data[2:] if not data: return time(hour, minute, tzinfo=tzinfo) # Second second = int(data) return time(hour, minute, second, tzinfo=tzinfo)
def decode(data): if not data: return None # Timezone if data[-1] == 'Z': data = data[:-1] tzinfo = fixed_offset(0) else: p_pos = data.find('+') m_pos = data.find('-') pos = m_pos * p_pos if pos > 0: tzinfo = None else: pos = -pos sign = data[pos] offset = data[pos+1:] if ':' in offset: offset = offset.split(':') else: offset = [offset[0:2], offset[2:]] o_h = int(offset[0]) o_m = int(offset[1]) if offset[1] else 0 data = data[:pos] offset = (o_h * 60 + o_m) if sign == '-': offset = -offset tzinfo = fixed_offset(offset) # Extended formats if ':' in data: parts = data.split(':') n = len(parts) if n > 3: raise ValueError, 'unexpected time value "%s"' % data hour = int(parts[0]) minute = int(parts[1]) if n == 2: return time(hour, minute, tzinfo=tzinfo) second = int(parts[2]) return time(hour, minute, second, tzinfo=tzinfo) # Basic formats hour = int(data[:2]) data = data[2:] if not data: return time(hour, tzinfo=tzinfo) # Minute minute = int(data[:2]) data = data[2:] if not data: return time(hour, minute, tzinfo=tzinfo) # Second second = int(data) return time(hour, minute, second, tzinfo=tzinfo)
def update_20101015(self): """Fix TagsAware pub_datetime Add tzinfo""" from pytz import timezone from itools.core import fixed_offset # Current server timezone paris = timezone('Europe/Paris') utc = fixed_offset(0) database = get_context().database for resource in self.traverse_resources(): if isinstance(resource, TagsAware): pub_datetime = resource.get_property('pub_datetime') if pub_datetime is None: continue if pub_datetime.tzinfo: return # localize date local_datetime = paris.localize(pub_datetime) utc_datetime = local_datetime - local_datetime.utcoffset() utc_datetime = utc_datetime.replace(tzinfo=utc) # Call metadata.set_property directly to avoid # comparison error 'TypeError' # -> can't compare offset-naive and offset-aware datetimes database.change_resource(resource) resource.metadata.set_property('pub_datetime', utc_datetime)
def http_get(self): n = len(Path(self.mount_path)) path = Path(self.path)[n:] path = '%s%s' % (self.local_path, path) # 404 Not Found if not isfile(path): return set_response(self.soup_message, 404) # 304 Not Modified mtime = getmtime(path) mtime = datetime.utcfromtimestamp(mtime) mtime = mtime.replace(microsecond=0) mtime = fixed_offset(0).localize(mtime) since = self.get_header('If-Modified-Since') if since and since >= mtime: return set_response(self.soup_message, 304) # 200 Ok # FIXME Check we set the encoding for text files mimetype = get_mimetype(basename(path)) data = open(path).read() self.soup_message.set_status(200) self.soup_message.set_response(mimetype, data) self.set_header('Last-Modified', mtime)
def GET(self, query, context): n = len(Path(self.mount_path)) path = Path(context.path)[n:] path = '%s%s' % (self.local_path, path) # 404 Not Found if not isfile(path): return context.set_default_response(404) # 304 Not Modified mtime = getmtime(path) mtime = datetime.utcfromtimestamp(mtime) mtime = mtime.replace(microsecond=0) mtime = fixed_offset(0).localize(mtime) since = context.get_header('If-Modified-Since') if since and since >= mtime: raise NotModified # 200 Ok # FIXME Check we set the encoding for text files mimetype = get_mimetype(basename(path)) # Get data with open(path, 'r') as f: data = f.read() # Response context.status = 200 context.set_content_type(mimetype) context.set_header('Last-Modified', mtime) return data
def get_fallback(self, resource, context): n = len(Path(self.mount_path)) path = Path(context.path)[n:] path = '%s%s' % (self.local_path, path) # 404 Not Found if not isfile(path): return context.set_default_response(404) # 304 Not Modified mtime = getmtime(path) mtime = datetime.utcfromtimestamp(mtime) mtime = mtime.replace(microsecond=0) mtime = fixed_offset(0).localize(mtime) since = context.get_header('If-Modified-Since') if since and since >= mtime: raise NotModified # 200 Ok # FIXME Check we set the encoding for text files mimetype = get_mimetype(basename(path)) # Get data with open(path, 'r') as f: data = f.read() # Response context.status = 200 context.set_content_type(mimetype) context.set_header('Last-Modified', mtime) return data
def _encode_simple_value(field_cls, value): # Integers (FIXME this doesn't work with the big integers) if issubclass(field_cls, Integer): return sortable_serialise(value) # Datetimes: normalize to UTC, so searching works if type(value) is datetime: value = value.astimezone(fixed_offset(0)) # A common field or a new field return field_cls.encode(value)
def _encode_simple_value(field_cls, value): # Integers (FIXME this doesn't work with the big integers) if issubclass(field_cls, Integer): return sortable_serialise(value) elif issubclass(field_cls, Decimal): # FIXME: We convert decimal->float so we lost precision return sortable_serialise(float(value)) # Datetimes: normalize to UTC, so searching works if type(value) is datetime: value = value.astimezone(fixed_offset(0)) # A common field or a new field return field_cls.encode(value)
def test_time_encode(self): gmt2 = fixed_offset(120) test_times = { (13, 45, 30): "13:45:30", (13, 45): "13:45:00", (13,): "13:00:00", (12, 34, 56): "12:34:56", (12, 34): "12:34:00", (9, 42, 17, 0, utc): "09:42:17Z", (17, 23, 27, 0, gmt2): "17:23:27+02:00", (2, 3, 5, 42, gmt2): "02:03:05+02:00", } for data, result in test_times.iteritems(): value = ISOTime.encode(time(*data)) expected = result self.assertEqual(value, expected)
def decode(data): """Decode dates in formats RFC 1123 (inc. 822), RFC-850, ANSI C's asctime() format, and non-standard formats sent by some HTTP clients. """ # Parse the date into a tuple, including the timezone parts = parsedate_tz(data) if parts is None: raise ValueError('date "%s" is not supported' % data) parts, tz = parts[:9], parts[9] # Get a naive datetime timestamp = mktime(parts) naive_dt = datetime.fromtimestamp(timestamp) # Return an aware datetime (if tz is None assume GMT) if tz is None: tz = 0 tz = fixed_offset(tz/60) return tz.localize(naive_dt)
def decode(data): """Decode dates in formats RFC 1123 (inc. 822), RFC-850, ANSI C's asctime() format, and non-standard formats sent by some HTTP clients. """ # Parse the date into a tuple, including the timezone parts = parsedate_tz(data) if parts is None: raise ValueError, 'date "%s" is not supported' % data parts, tz = parts[:9], parts[9] # Get a naive datetime timestamp = mktime(parts) naive_dt = datetime.fromtimestamp(timestamp) # Return an aware datetime (if tz is None assume GMT) if tz is None: tz = 0 tz = fixed_offset(tz/60) return tz.localize(naive_dt)
def decode(value): if value is None: return None date = value[:8] year, month, day = int(date[:4]), int(date[4:6]), int(date[6:8]) hour, min, sec = 0, 0, 0 # Default is a naive datetime tzinfo = None # Time can be omitted if 'T' in value: time = value[9:] if time[-1] == 'Z': tzinfo = fixed_offset(0) time = time[:-1] hour, min, sec = int(time[:2]), int(time[2:4]), int(time[4:6]) return datetime(year, month, day, hour, min, sec, tzinfo=tzinfo)
def test_time_decode(self): gmt2 = fixed_offset(120) test_times = { "13:45:30": (13, 45, 30), "13:45": (13, 45), "13": (13,), "123456": (12, 34, 56), "1234": (12, 34), "094217Z": (9, 42, 17, 0, utc), "09:42:17Z": (9, 42, 17, 0, utc), "17:23:27+0200": (17, 23, 27, 0, gmt2), "17:23:27+02:00": (17, 23, 27, 0, gmt2), "17:23:27+02": (17, 23, 27, 0, gmt2), "020305+0200": (2, 3, 5, 0, gmt2), "020305+02:00": (2, 3, 5, 0, gmt2), "020305+02": (2, 3, 5, 0, gmt2), } for data, result in test_times.iteritems(): value = ISOTime.decode(data) expected = time(*result) self.assertEqual(value, expected)
def get_from_template(self, resource, context): # FIXME Check we set the encoding for text files path = str(context.path) ts = context.server.timestamp path = path.replace('/cached/%s' % ts, '') template = context.get_template(path) # 404 Not Found if not template: return context.set_default_response(404) # 304 Not Modified mtime = template.get_mtime() mtime = fixed_offset(0).localize(mtime) since = context.get_header('If-Modified-Since') if since and since >= mtime: raise NotModified mimetype = template.get_mimetype() # Get data data = template.to_str() # Response context.status = 200 context.set_content_type(mimetype) context.set_header('Last-Modified', mtime) return data
def timestamp(self): return datetime.utcnow().replace(tzinfo=fixed_offset(0))
def get_handler_mtime(self, key): # FIXME return datetime.utcnow().replace(tzinfo=fixed_offset(0))
# Import from the Standard Library from datetime import time, date, datetime import decimal import random from unittest import TestCase, main # Import from itools from itools.core import fixed_offset from itools.datatypes import ISOTime, ISOCalendarDate, ISODateTime, HTTPDate from itools.datatypes import Integer, Decimal, Boolean, Unicode, URI, Email from itools.datatypes import QName, Tokens, Enumerate from itools.datatypes import XMLContent, XMLAttribute utc = fixed_offset(0) def datetime_utc2local(dt): """Given a naive datetime object in UTC, return a naive datetime object in local time. """ return utc.localize(dt) class BasicTypeTest(TestCase): def test_Integer(self): for x in range(-10, 11): data = Integer.encode(x) self.assertEqual(x, Integer.decode(data))