Passed
Push — master ( db2481...3bd527 )
by Fabio
03:28
created

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

Complexity

Conditions 2

Size

Total Lines 5
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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