root / snf-common / synnefo / lib / parsedate.py @ 1c65202f
History | View | Annotate | Download (3.5 kB)
1 | 8acb1f97 | Kostas Papadimitriou | # Copyright (c) Django Software Foundation and individual contributors.
|
---|---|---|---|
2 | 8acb1f97 | Kostas Papadimitriou | # All rights reserved.
|
3 | 8acb1f97 | Kostas Papadimitriou | #
|
4 | 8acb1f97 | Kostas Papadimitriou | # Redistribution and use in source and binary forms, with or without modification,
|
5 | 8acb1f97 | Kostas Papadimitriou | # are permitted provided that the following conditions are met:
|
6 | 8acb1f97 | Kostas Papadimitriou | #
|
7 | 8acb1f97 | Kostas Papadimitriou | # 1. Redistributions of source code must retain the above copyright notice,
|
8 | 8acb1f97 | Kostas Papadimitriou | # this list of conditions and the following disclaimer.
|
9 | 8acb1f97 | Kostas Papadimitriou | #
|
10 | 8acb1f97 | Kostas Papadimitriou | # 2. Redistributions in binary form must reproduce the above copyright
|
11 | 8acb1f97 | Kostas Papadimitriou | # notice, this list of conditions and the following disclaimer in the
|
12 | 8acb1f97 | Kostas Papadimitriou | # documentation and/or other materials provided with the distribution.
|
13 | 8acb1f97 | Kostas Papadimitriou | #
|
14 | 8acb1f97 | Kostas Papadimitriou | # 3. Neither the name of Django nor the names of its contributors may be used
|
15 | 8acb1f97 | Kostas Papadimitriou | # to endorse or promote products derived from this software without
|
16 | 8acb1f97 | Kostas Papadimitriou | # specific prior written permission.
|
17 | 8acb1f97 | Kostas Papadimitriou | #
|
18 | 8acb1f97 | Kostas Papadimitriou | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
19 | 8acb1f97 | Kostas Papadimitriou | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
20 | 8acb1f97 | Kostas Papadimitriou | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21 | 8acb1f97 | Kostas Papadimitriou | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
22 | 8acb1f97 | Kostas Papadimitriou | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
23 | 8acb1f97 | Kostas Papadimitriou | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
24 | 8acb1f97 | Kostas Papadimitriou | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
25 | 8acb1f97 | Kostas Papadimitriou | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
26 | 8acb1f97 | Kostas Papadimitriou | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
27 | 8acb1f97 | Kostas Papadimitriou | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28 | 8acb1f97 | Kostas Papadimitriou | |
29 | 8acb1f97 | Kostas Papadimitriou | import re |
30 | 8acb1f97 | Kostas Papadimitriou | import datetime |
31 | 8acb1f97 | Kostas Papadimitriou | import calendar |
32 | 8acb1f97 | Kostas Papadimitriou | |
33 | 8acb1f97 | Kostas Papadimitriou | MONTHS = 'jan feb mar apr may jun jul aug sep oct nov dec'.split()
|
34 | 8acb1f97 | Kostas Papadimitriou | __D = r'(?P<day>\d{2})'
|
35 | 8acb1f97 | Kostas Papadimitriou | __D2 = r'(?P<day>[ \d]\d)'
|
36 | 8acb1f97 | Kostas Papadimitriou | __M = r'(?P<mon>\w{3})'
|
37 | 8acb1f97 | Kostas Papadimitriou | __Y = r'(?P<year>\d{4})'
|
38 | 8acb1f97 | Kostas Papadimitriou | __Y2 = r'(?P<year>\d{2})'
|
39 | 8acb1f97 | Kostas Papadimitriou | __T = r'(?P<hour>\d{2}):(?P<min>\d{2}):(?P<sec>\d{2})'
|
40 | 8acb1f97 | Kostas Papadimitriou | RFC1123_DATE = re.compile(r'^\w{3}, %s %s %s %s GMT$' % (__D, __M, __Y, __T))
|
41 | 8acb1f97 | Kostas Papadimitriou | RFC850_DATE = re.compile(r'^\w{6,9}, %s-%s-%s %s GMT$' % (__D, __M, __Y2, __T))
|
42 | 8acb1f97 | Kostas Papadimitriou | ASCTIME_DATE = re.compile(r'^\w{3} %s %s %s %s$' % (__M, __D2, __T, __Y))
|
43 | 8acb1f97 | Kostas Papadimitriou | |
44 | 8acb1f97 | Kostas Papadimitriou | def parse_http_date(date): |
45 | 8acb1f97 | Kostas Papadimitriou | """
|
46 | 8acb1f97 | Kostas Papadimitriou | Parses a date format as specified by HTTP RFC2616 section 3.3.1.
|
47 | 8acb1f97 | Kostas Papadimitriou |
|
48 | 8acb1f97 | Kostas Papadimitriou | The three formats allowed by the RFC are accepted, even if only the first
|
49 | 8acb1f97 | Kostas Papadimitriou | one is still in widespread use.
|
50 | 8acb1f97 | Kostas Papadimitriou |
|
51 | 8acb1f97 | Kostas Papadimitriou | Returns an floating point number expressed in seconds since the epoch, in
|
52 | 8acb1f97 | Kostas Papadimitriou | UTC.
|
53 | 8acb1f97 | Kostas Papadimitriou | """
|
54 | 8acb1f97 | Kostas Papadimitriou | # emails.Util.parsedate does the job for RFC1123 dates; unfortunately
|
55 | 8acb1f97 | Kostas Papadimitriou | # RFC2616 makes it mandatory to support RFC850 dates too. So we roll
|
56 | 8acb1f97 | Kostas Papadimitriou | # our own RFC-compliant parsing.
|
57 | 8acb1f97 | Kostas Papadimitriou | for regex in RFC1123_DATE, RFC850_DATE, ASCTIME_DATE: |
58 | 8acb1f97 | Kostas Papadimitriou | m = regex.match(date) |
59 | 8acb1f97 | Kostas Papadimitriou | if m is not None: |
60 | 8acb1f97 | Kostas Papadimitriou | break
|
61 | 8acb1f97 | Kostas Papadimitriou | else:
|
62 | 8acb1f97 | Kostas Papadimitriou | raise ValueError("%r is not in a valid HTTP date format" % date) |
63 | 8acb1f97 | Kostas Papadimitriou | try:
|
64 | 8acb1f97 | Kostas Papadimitriou | year = int(m.group('year')) |
65 | 8acb1f97 | Kostas Papadimitriou | if year < 100: |
66 | 8acb1f97 | Kostas Papadimitriou | if year < 70: |
67 | 8acb1f97 | Kostas Papadimitriou | year += 2000
|
68 | 8acb1f97 | Kostas Papadimitriou | else:
|
69 | 8acb1f97 | Kostas Papadimitriou | year += 1900
|
70 | 8acb1f97 | Kostas Papadimitriou | month = MONTHS.index(m.group('mon').lower()) + 1 |
71 | 8acb1f97 | Kostas Papadimitriou | day = int(m.group('day')) |
72 | 8acb1f97 | Kostas Papadimitriou | hour = int(m.group('hour')) |
73 | 8acb1f97 | Kostas Papadimitriou | min = int(m.group('min')) |
74 | 8acb1f97 | Kostas Papadimitriou | sec = int(m.group('sec')) |
75 | 8acb1f97 | Kostas Papadimitriou | result = datetime.datetime(year, month, day, hour, min, sec)
|
76 | 8acb1f97 | Kostas Papadimitriou | return calendar.timegm(result.utctimetuple())
|
77 | 8acb1f97 | Kostas Papadimitriou | except Exception: |
78 | 8acb1f97 | Kostas Papadimitriou | raise ValueError("%r is not a valid date" % date) |
79 | 8acb1f97 | Kostas Papadimitriou | |
80 | 8acb1f97 | Kostas Papadimitriou | def parse_http_date_safe(date): |
81 | 8acb1f97 | Kostas Papadimitriou | """
|
82 | 8acb1f97 | Kostas Papadimitriou | Same as parse_http_date, but returns None if the input is invalid.
|
83 | 8acb1f97 | Kostas Papadimitriou | """
|
84 | 8acb1f97 | Kostas Papadimitriou | try:
|
85 | 8acb1f97 | Kostas Papadimitriou | return parse_http_date(date)
|
86 | 8acb1f97 | Kostas Papadimitriou | except Exception: |
87 | 8acb1f97 | Kostas Papadimitriou | pass |