-
-
Notifications
You must be signed in to change notification settings - Fork 159
/
util.py
151 lines (114 loc) · 4.25 KB
/
util.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import calendar
import datetime
import logging
import re
import pytz
from datetime import datetime, date
from zenpy.lib.proxy import ProxyDict, ProxyList
FIRST_CAP_REGEX = re.compile('(.)([A-Z][a-z]+)')
ALL_CAP_REGEX = re.compile('([a-z0-9])([A-Z])')
log = logging.getLogger(__name__)
def to_snake_case(name):
""" Given a name in camelCase return in snake_case """
s1 = FIRST_CAP_REGEX.sub(r'\1_\2', name)
return ALL_CAP_REGEX.sub(r'\1_\2', s1).lower()
def to_unix_ts(start_time):
"""Given a datetime object, returns its value as a unix timestamp"""
if isinstance(start_time, datetime):
if is_timezone_aware(start_time):
start_time = start_time.astimezone(pytz.utc)
else:
log.warning(
"Non timezone-aware datetime object passed to IncrementalEndpoint. "
"The Zendesk API expects UTC time, if this is not the case results will be incorrect!"
)
unix_time = calendar.timegm(start_time.timetuple())
else:
unix_time = start_time
return int(unix_time)
def get_object_type(zenpy_object):
""" Given an instance of a Zenpy object, return it's object type """
return to_snake_case(zenpy_object.__class__.__name__)
def is_timezone_aware(datetime_obj):
"""
Determine whether or not a given datetime object is timezone aware.
"""
return datetime_obj.tzinfo is not None and datetime_obj.tzinfo.utcoffset(
datetime_obj) is not None
def is_iterable_but_not_string(obj):
"""
Determine whether or not obj is iterable but not a string (eg, a list, set, tuple etc).
"""
return hasattr(obj, '__iter__') and not isinstance(
obj, str) and not isinstance(obj, bytes)
def as_singular(result_key):
"""
Given a result key, return in the singular form
"""
if result_key.endswith('ies'):
return re.sub('ies$', 'y', result_key)
elif result_key.endswith('uses'):
return re.sub("uses$", "us", result_key)
elif result_key.endswith('addresses'): # Special case for '*addresses'
return result_key[:-2]
elif result_key.endswith('s'):
return result_key[:-1]
else:
return result_key
def as_plural(result_key):
"""
Given a result key, return in the plural form.
"""
# Not at all guaranteed to work in all cases...
if result_key.endswith('y'):
return re.sub("y$", "ies", result_key)
elif result_key.endswith('address'):
return result_key + 'es'
elif result_key.endswith('us'):
return re.sub("us$", "uses", result_key)
elif not result_key.endswith('s'):
return result_key + 's'
else:
return result_key
def get_endpoint_path(api, response):
""" Return the section of the URL from 'api/v2' to the end. """
return response.request.url.split(api.api_prefix)[-1]
def extract_id(*object_types):
"""
Decorator for extracting id from passed parameters for specific types.
"""
def outer(func):
def inner(*args, **kwargs):
def id_of(x):
return x.id if type(x) in object_types else x
new_args = [id_of(arg) for arg in args]
new_kwargs = {k: id_of(v) for k, v in kwargs.items()}
return func(*new_args, **new_kwargs)
return inner
return outer
def json_encode_for_zendesk(obj):
""" Only encode those attributes of Zenpy objects that have been modified. """
return json_encode(obj, serialize=True)
def json_encode_for_printing(obj):
""" Encode all attributes. """
return json_encode(obj, serialize=False)
def json_encode(obj, serialize):
""" Handle encoding complex types. """
if hasattr(obj, 'to_dict'):
return obj.to_dict(serialize=serialize)
elif isinstance(obj, datetime):
return obj.date().isoformat()
elif isinstance(obj, date):
return obj.isoformat()
elif isinstance(obj, ProxyDict):
return dict(obj)
elif isinstance(obj, ProxyList):
return list(obj)
elif is_iterable_but_not_string(obj):
return list(obj)
def all_are_none(*args):
""" Check if all args are none. """
return all(arg is None for arg in args)
def all_are_not_none(*args):
""" Check if all args are not none. """
return all(arg is not None for arg in args)