mirror of https://github.com/fail2ban/fail2ban
				
				
				
			ENH: iso8601 - remove default_timezone set to UTC, isn't valid any more - calculate from local timezone. Enforce T date/time separator in iso8601 regex. Make minutes in timezone optional as per ISO8601. Use consistant regex for ISO8601
							parent
							
								
									a0676cdd1e
								
							
						
					
					
						commit
						37de5462be
					
				| 
						 | 
				
			
			@ -300,10 +300,7 @@ class DateISO8601(DateTemplate):
 | 
			
		|||
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		DateTemplate.__init__(self)
 | 
			
		||||
		date_re = "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}" \
 | 
			
		||||
		".[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?" \
 | 
			
		||||
		"(Z|(([-+])([0-9]{2}):([0-9]{2})))?"
 | 
			
		||||
		self.setRegex(date_re)
 | 
			
		||||
		self.setRegex(iso8601.ISO8601_REGEX_RAW)
 | 
			
		||||
	
 | 
			
		||||
	def getDate(self, line):
 | 
			
		||||
		dateMatch = self.matchDate(line)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,17 +32,17 @@ datetime.datetime(2007, 1, 25, 12, 0, tzinfo=<iso8601.iso8601.Utc ...>)
 | 
			
		|||
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from datetime import datetime, timedelta, tzinfo
 | 
			
		||||
from datetime import datetime, timedelta, tzinfo, time
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
__all__ = ["parse_date", "ParseError"]
 | 
			
		||||
 | 
			
		||||
# Adapted from http://delete.me.uk/2005/03/iso8601.html
 | 
			
		||||
ISO8601_REGEX = re.compile(r"(?P<year>[0-9]{4})(-(?P<month>[0-9]{1,2})(-(?P<day>[0-9]{1,2})"
 | 
			
		||||
    r"((?P<separator>.)(?P<hour>[0-9]{2}):(?P<minute>[0-9]{2})(:(?P<second>[0-9]{2})(\.(?P<fraction>[0-9]+))?)?"
 | 
			
		||||
    r"(?P<timezone>Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?"
 | 
			
		||||
)
 | 
			
		||||
TIMEZONE_REGEX = re.compile("(?P<prefix>[+-])(?P<hours>[0-9]{2}).(?P<minutes>[0-9]{2})")
 | 
			
		||||
ISO8601_REGEX_RAW = "(?P<year>[0-9]{4})-(?P<month>[0-9]{1,2})-(?P<day>[0-9]{1,2})" \
 | 
			
		||||
    "T(?P<hour>[0-9]{2}):(?P<minute>[0-9]{2})(:(?P<second>[0-9]{2})(\.(?P<fraction>[0-9]+))?)?" \
 | 
			
		||||
    "(?P<timezone>Z|(([-+])([0-9]{2}):([0-9]{2})))?"
 | 
			
		||||
ISO8601_REGEX = re.compile(ISO8601_REGEX_RAW)
 | 
			
		||||
TIMEZONE_REGEX = re.compile("(?P<prefix>[+-])(?P<hours>[0-9]{2}):?(?P<minutes>[0-9]{2})?")
 | 
			
		||||
 | 
			
		||||
class ParseError(Exception):
 | 
			
		||||
    """Raised when there is a problem parsing a date string"""
 | 
			
		||||
| 
						 | 
				
			
			@ -67,8 +67,8 @@ class FixedOffset(tzinfo):
 | 
			
		|||
    """Fixed offset in hours and minutes from UTC
 | 
			
		||||
    
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, offset_hours, offset_minutes, name):
 | 
			
		||||
        self.__offset = timedelta(hours=offset_hours, minutes=offset_minutes)
 | 
			
		||||
    def __init__(self, name, offset_hours, offset_minutes, offset_seconds=0):
 | 
			
		||||
        self.__offset = timedelta(hours=offset_hours, minutes=offset_minutes, seconds=offset_seconds)
 | 
			
		||||
        self.__name = name
 | 
			
		||||
 | 
			
		||||
    def utcoffset(self, dt):
 | 
			
		||||
| 
						 | 
				
			
			@ -83,26 +83,30 @@ class FixedOffset(tzinfo):
 | 
			
		|||
    def __repr__(self):
 | 
			
		||||
        return "<FixedOffset %r>" % self.__name
 | 
			
		||||
 | 
			
		||||
def parse_timezone(tzstring, default_timezone=UTC):
 | 
			
		||||
def parse_timezone(tzstring):
 | 
			
		||||
    """Parses ISO 8601 time zone specs into tzinfo offsets
 | 
			
		||||
    
 | 
			
		||||
    """
 | 
			
		||||
    if tzstring == "Z":
 | 
			
		||||
        return default_timezone
 | 
			
		||||
    # This isn't strictly correct, but it's common to encounter dates without
 | 
			
		||||
    # timezones so I'll assume the default (which defaults to UTC).
 | 
			
		||||
    # Addresses issue 4.
 | 
			
		||||
        return UTC
 | 
			
		||||
 | 
			
		||||
    if tzstring is None:
 | 
			
		||||
        return default_timezone
 | 
			
		||||
        zone_sec = -time.timezone 
 | 
			
		||||
        return FixedOffset(name=time.tzname[0],hours=(zone_sec / 3600),minutes=(zone_sec % 3600)/60,seconds=zone_sec % 60)
 | 
			
		||||
 | 
			
		||||
    m = TIMEZONE_REGEX.match(tzstring)
 | 
			
		||||
    prefix, hours, minutes = m.groups()
 | 
			
		||||
    hours, minutes = int(hours), int(minutes)
 | 
			
		||||
    if minutes is None:
 | 
			
		||||
        minutes = 0
 | 
			
		||||
    else:
 | 
			
		||||
        minutes = int(minutes)
 | 
			
		||||
    hours = int(hours)
 | 
			
		||||
    if prefix == "-":
 | 
			
		||||
        hours = -hours
 | 
			
		||||
        minutes = -minutes
 | 
			
		||||
    return FixedOffset(hours, minutes, tzstring)
 | 
			
		||||
    return FixedOffset(tzstring, hours, minutes)
 | 
			
		||||
 | 
			
		||||
def parse_date(datestring, default_timezone=UTC):
 | 
			
		||||
def parse_date(datestring):
 | 
			
		||||
    """Parses ISO 8601 dates into datetime objects
 | 
			
		||||
    
 | 
			
		||||
    The timezone is parsed from the date string. However it is quite common to
 | 
			
		||||
| 
						 | 
				
			
			@ -116,7 +120,7 @@ def parse_date(datestring, default_timezone=UTC):
 | 
			
		|||
    if not m:
 | 
			
		||||
        raise ParseError("Unable to parse date string %r" % datestring)
 | 
			
		||||
    groups = m.groupdict()
 | 
			
		||||
    tz = parse_timezone(groups["timezone"], default_timezone=default_timezone)
 | 
			
		||||
    tz = parse_timezone(groups["timezone"])
 | 
			
		||||
    if groups["fraction"] is None:
 | 
			
		||||
        groups["fraction"] = 0
 | 
			
		||||
    else:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue