-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutilities.py
109 lines (97 loc) · 3.5 KB
/
utilities.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import re
import calendar
import datetime
import time
def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, logger=None):
"""Retry calling the decorated function using an exponential backoff.
http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry
:param ExceptionToCheck: the exception to check. may be a tuple of
excpetions to check
:type ExceptionToCheck: Exception or tuple
:param tries: number of times to try (not retry) before giving up
:type tries: int
:param delay: initial delay between retries in seconds
:type delay: int
:param backoff: backoff multiplier e.g. value of 2 will double the delay
each retry
:type backoff: int
:param logger: logger to use. If None, print
:type logger: logging.Logger instance
"""
def deco_retry(f):
def f_retry(*args, **kwargs):
mtries, mdelay = tries, delay
try_one_last_time = True
while mtries > 1:
try:
return f(*args, **kwargs)
try_one_last_time = False
break
except ExceptionToCheck, e:
msg = "%s, Retrying in %d seconds..." % (str(e), mdelay)
if logger:
logger.warning(msg)
else:
print msg
time.sleep(mdelay)
mtries -= 1
mdelay *= backoff
if try_one_last_time:
return f(*args, **kwargs)
return
return f_retry # true decorator
return deco_retry
def parse_date(date_string):
date_obj = None
day = False
month = False
date_formats = [('%d %B %Y', True, True),
('%d %b %Y', True, True),
('%d %b. %Y', True, True),
('%B %Y', False, True),
('%b %Y', False, True),
('%Y', False, False),
]
for date_format in date_formats:
try:
date_obj = datetime.datetime.strptime(date_string, date_format[0])
except ValueError:
pass
else:
day = date_format[1]
month = date_format[2]
break
return {'date': date_obj, 'day': day, 'month': month}
def process_date_string(date_string):
'''
Takes a date range in a string and returns date objects,
and booleans indicating if values for month and day exist.
'''
dates = date_string.split('-')
if dates:
start_date = parse_date(dates[0].strip())
try:
end_date = parse_date(dates[1].strip())
except IndexError:
end_date = None
return {'date_str': date_string, 'start_date': start_date, 'end_date': end_date}
def convert_date_to_iso(date_dict):
'''
Simple ISO date formatting.
Not dependent on strftime and its year limits.
'''
date_obj = date_dict['date']
if date_obj:
if date_dict['day']:
iso_date = '{0.year}-{0.month:02d}-{0.day:02d}'.format(date_obj)
elif date_dict['month']:
iso_date = '{0.year}-{0.month:02d}'.format(date_obj)
else:
iso_date = '{0.year}'.format(date_obj)
else:
iso_date = None
return iso_date
def format_iso_date(iso_date):
year, month, day = iso_date.split('-')
return '{} {} {}'.format(int(day), calendar.month_abbr[int(month)], year)