Completed
Push — master ( 691f67...42518b )
by Fabio
04:47
created

benedict.dicts.parse.parse_util.parse_uuid()   A

Complexity

Conditions 2

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 2
nop 1
1
# -*- coding: utf-8 -*-
2
3
from benedict.serializers import JSONSerializer
4
from benedict.utils import type_util
5
6
from datetime import datetime
7
from dateutil import parser as date_parser
8
from decimal import Decimal, DecimalException
9
from MailChecker import MailChecker
10
from phonenumbers import phonenumberutil, PhoneNumberFormat
11
from six import text_type
12
from slugify import slugify
13
14
import ftfy
15
import phonenumbers
16
import re
17
18
19
def _parse_with(val, type_checker, parser, **kwargs):
20
    if val is None:
21
        return None
22
    if callable(type_checker) and type_checker(val):
23
        return val
24
    s = text_type(val)
25
    if not len(s):
26
        return None
27
    return parser(s, **kwargs)
28
29
30
def _parse_bool(val):
31
    val = val.lower()
32
    if val in ['1', 'true', 'yes', 'ok', 'on']:
33
        return True
34
    elif val in ['0', 'false', 'no', 'ko', 'off']:
35
        return False
36
    return None
37
38
39
def parse_bool(val):
40
    return _parse_with(val, type_util.is_bool, _parse_bool)
41
42
43
def _parse_datetime_with_format(val, format):
44
    try:
45
        return datetime.strptime(val, format)
46
    except Exception:
47
        return None
48
49
50
def _parse_datetime_without_format(val):
51
    try:
52
        return date_parser.parse(val)
53
    except Exception:
54
        return _parse_datetime_from_timestamp(val)
55
56
57
def _parse_datetime_from_timestamp(val):
58
    try:
59
        return datetime.fromtimestamp(float(val))
60
    except Exception:
61
        return None
62
63
64
def parse_datetime(val, format=None):
65
    if type_util.is_datetime(val):
66
        return val
67
    s = text_type(val)
68
    if format:
69
        return _parse_datetime_with_format(s, format)
70
    else:
71
        return _parse_datetime_without_format(s)
72
73
74
def _parse_decimal(val):
75
    try:
76
        return Decimal(val)
77
    except (ValueError, DecimalException):
78
        return None
79
80
81
def parse_decimal(val):
82
    return _parse_with(val, type_util.is_decimal, _parse_decimal)
83
84
85
def _parse_dict(val):
86
    serializer = JSONSerializer()
87
    try:
88
        d = serializer.decode(val)
89
        if type_util.is_dict(d):
90
            return d
91
        return None
92
    except Exception:
93
        return None
94
95
96
def parse_dict(val):
97
    return _parse_with(val, type_util.is_dict, _parse_dict)
98
99
100
def _parse_float(val):
101
    try:
102
        return float(val)
103
    except ValueError:
104
        return None
105
106
107
def parse_float(val):
108
    return _parse_with(val, type_util.is_float, _parse_float)
109
110
111
def _parse_email(val, check_blacklist=True):
112
    val = val.lower()
113
    if check_blacklist:
114
        if not MailChecker.is_valid(val):
115
            return None
116
    else:
117
        if not MailChecker.is_valid_email_format(val):
118
            return None
119
    return val
120
121
122
def parse_email(val, check_blacklist=True):
123
    return _parse_with(
124
        val, None, _parse_email, check_blacklist=check_blacklist)
125
126
127
def _parse_int(val):
128
    try:
129
        return int(val)
130
    except ValueError:
131
        return None
132
133
134
def parse_int(val):
135
    return _parse_with(val, type_util.is_integer, _parse_int)
136
137
138
def _parse_list(val, separator=None):
139
    serializer = JSONSerializer()
140
    try:
141
        l = serializer.decode(val)
142
        if type_util.is_list(l):
143
            return l
144
    except Exception:
145
        if separator:
146
            l = list(val.split(separator))
147
            return l
148
    return None
149
150
151
def parse_list(val, separator=None):
152
    val = _parse_with(val, type_util.is_list_or_tuple,
153
                      _parse_list, separator=separator)
154
    return list(val) if type_util.is_list_or_tuple(val) else val
155
156
157
def _parse_phonenumber(val, country_code=None):
158
    try:
159
        phone_obj = phonenumbers.parse(val, country_code)
160
        if phonenumbers.is_valid_number(phone_obj):
161
            return {
162
                'e164': phonenumbers.format_number(
163
                    phone_obj, PhoneNumberFormat.E164),
164
                'international': phonenumbers.format_number(
165
                    phone_obj, PhoneNumberFormat.INTERNATIONAL),
166
                'national': phonenumbers.format_number(
167
                    phone_obj, PhoneNumberFormat.NATIONAL),
168
            }
169
        return None
170
    except phonenumberutil.NumberParseException:
171
        return None
172
173
174
def parse_phonenumber(val, country_code=None):
175
    s = parse_str(val)
176
    if not s:
177
        return None
178
    phone_raw = re.sub(r'[^0-9\+]', ' ', s)
179
    phone_raw = phone_raw.strip()
180
    if phone_raw.startswith('00'):
181
        phone_raw = '+{}'.format(phone_raw[2:])
182
    if country_code and len(country_code) >= 2:
183
        country_code = country_code[0:2].upper()
184
    return _parse_with(
185
        phone_raw, None, _parse_phonenumber, country_code=country_code)
186
187
188
def _parse_slug(val):
189
    return slugify(val)
190
191
192
def parse_slug(val):
193
    s = parse_str(val)
194
    return _parse_slug(s)
195
196
197
def parse_str(val):
198
    if type_util.is_string(val):
199
        try:
200
            val = ftfy.fix_text(val)
201
        except UnicodeError:
202
            pass
203
    else:
204
        val = text_type(val)
205
    val = val.strip()
206
    val = ' '.join(val.split())
207
    return val
208
209
210
def parse_uuid(val):
211
    s = parse_str(val)
212
    return s if type_util.is_uuid(s) else None
213