Skip to content

Commit f1f7446

Browse files
authored
Merge pull request #93 from nossas/hotfix/normalization-problem
Fixed normalize responses
2 parents bae7cdd + 89f21ec commit f1f7446

File tree

1 file changed

+92
-197
lines changed

1 file changed

+92
-197
lines changed

action-network/web/normalize.py

Lines changed: 92 additions & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -5,224 +5,119 @@
55
from typings import Donation, Form, Payload, Pressure, Plip
66
from utils import only_digits, get_field, find_by_ddd
77

8+
def normalize_phone(phone):
9+
phone = only_digits(phone)
10+
patterns = [
11+
(r'^(\d{2})(\d{1})(\d{4})(\d{4})$', r'+55 (\1) \2 \3 \4'),
12+
(r'^(\d{1})(\d{4})(\d{4})$', r'+55 (xx) \1 \2 \3'),
13+
(r'^(\d{2})(\d{4})(\d{4})$', r'+55 (\1) 9 \2 \3'),
14+
(r'^(\d{4})(\d{4})$', r'+55 (xx) 9 \1 \2')
15+
]
16+
for pattern, replacement in patterns:
17+
phone = re.sub(pattern, replacement, phone)
18+
return phone
19+
20+
def clean_response(item):
21+
return {key: value for key, value in item.items() if value}
22+
23+
def normalize_name(name, given_name, family_name):
24+
name = name.title() if name else ""
25+
given_name = given_name or name.split(" ")[0]
26+
family_name = family_name or " ".join(name.split(" ")[1:])
27+
return name, given_name.title(), family_name.title()
28+
29+
def normalize_region(region):
30+
if region and '(' in region:
31+
region = re.sub(r'[\w Á-ù]+\((\w{2})\)', r'\1', region)
32+
return region
33+
834
def form(payload: Form):
9-
"""form"""
1035
fields = json.loads(payload.fields)
36+
item = {
37+
'given_name': get_field(r'(nombre|first[\s\-\_]?name|seu nome|nome|name|primeiro[\s\-\_]?nome)', fields),
38+
'family_name': get_field(r'(sobre[\s\-\_]?nome|seu sobre[\s\-\_]?nome|surname|last[\s\-\_]?name|apellido)', fields),
39+
'email': get_field(r'(e-?mail|correo electr(o|ó)nico|email|seu.*email)', fields),
40+
'locality': get_field(r'(cidade|city|ciudad)', fields),
41+
'phone': get_field(r'(celular|mobile|portable|whatsapp)', fields),
42+
'region': get_field(r'(estado|state)', fields),
43+
'gender': get_field(r'(gen[e|ê]ro|orienta[ç|c][a|ã]o sexual|identifica)', fields),
44+
'color': get_field(r'(cor|ra[ç|c]a|etnia)', fields),
45+
'birthday': get_field(r'(data[de ]*nascimento|idade|[ano]*[de ]*nascimento)', fields)
46+
}
47+
48+
item['region'] = normalize_region(item['region'])
49+
item['name'], item['given_name'], item['family_name'] = normalize_name(
50+
f"{item['given_name']} {item['family_name']}".strip(), item['given_name'], item['family_name']
51+
)
52+
if item['phone']:
53+
item['phone'] = normalize_phone(item['phone'])
1154

12-
item = dict()
13-
14-
item['given_name'] = get_field(
15-
r'(nombre|first[\s\-\_]?name|seu nome|nome|name|primeiro[\s\-\_]?nome)', fields)
16-
item['family_name'] = get_field(
17-
r'(sobre[\s\-\_]?nome|seu sobre[\s\-\_]?nome|surname|last[\s\-\_]?name|apellido)', fields)
18-
item['email'] = get_field(
19-
r'(e-?mail|correo electr(o|ó)nico|email|seu.*email)', fields)
20-
item['locality'] = get_field(r'(cidade|city|ciudad)', fields)
21-
item['phone'] = get_field(r'(celular|mobile|portable|whatsapp)', fields)
22-
item['region'] = get_field(r'(estado|state)', fields)
23-
item['gender'] = get_field(
24-
r'(gen[e|ê]ro|orienta[ç|c][a|ã]o sexual|identifica)', fields)
25-
item['color'] = get_field(r'(cor|ra[ç|c]a|etnia)', fields)
26-
item['birthday'] = get_field(
27-
r'(data[de ]*nascimento|idade|[ano]*[de ]*nascimento)', fields)
28-
29-
item['name'] = item['given_name'] + \
30-
f" {item['family_name']}" if item['family_name'] else item['given_name']
31-
32-
# normalizando os state
33-
item['locality'] = item['locality'].lstrip(
34-
) if item['locality'] else item['locality']
35-
36-
item['region'] = re.sub(
37-
r'[\w Á-ù]+\((\w{2})\)', r'\1', item['region']) if '(' in (item['region'] or '') \
38-
else item['region']
39-
40-
# Normalizando nomes
41-
item['name'] = item['given_name'] + \
42-
(f" {item['family_name']}" or '') if '{' in (
43-
item['name'] or '') else item['name']
44-
45-
# Remove item wihtout name ou email
4655
if not item['name'] or not item['email']:
4756
return None
4857

49-
item['given_name'] = item['name'].split(
50-
" ")[0] if not item['given_name'] else item['given_name']
51-
item['family_name'] = " ".join(item['name'].split(
52-
" ")[1:]) if not item['family_name'] else item['family_name']
53-
54-
# Removendo espaco em branco no inicio da string
55-
item['given_name'] = item['given_name'].lstrip()
56-
57-
item['given_name'] = item['given_name'].split(" ")[0] if len(
58-
item['given_name'].split(" ")) > 1 else item['given_name']
59-
60-
item['name'] = item['name'].title()
61-
item['given_name'] = item['given_name'].title()
62-
item['family_name'] = item['family_name'].title()
63-
64-
65-
if item['phone']:
66-
item['phone'] = only_digits(item['phone'])
67-
item['phone'] = re.sub(
68-
r'^(\d{2})(\d{1})(\d{4})(\d{4})$', r'+55 (\1) \2 \3 \4', item['phone'])
69-
item['phone'] = re.sub(
70-
r'^(\d{1})(\d{4})(\d{4})$', r'+55 (xx) \1 \2 \3', item['phone'])
71-
item['phone'] = re.sub(
72-
r'^(\d{2})(\d{4})(\d{4})$', r'+55 (\1) 9 \2 \3', item['phone'])
73-
item['phone'] = re.sub(
74-
r'^(\d{4})(\d{4})$', r'+55 (xx) 9 \1 \2', item['phone'])
75-
76-
# Clean response
77-
response = dict()
78-
for key, value in item.items():
79-
if value:
80-
response[key] = value
81-
return response
82-
58+
return clean_response(item)
8359

8460
def donation(payload: Donation):
85-
"""donation"""
86-
87-
if not payload.transaction_status:
88-
raise Exception("not_transaction_status")
89-
90-
if not payload.payment_method:
91-
raise Exception("not_payment_method")
61+
if not payload.transaction_status or not payload.payment_method:
62+
raise ValueError("Missing required fields in donation payload.")
9263

9364
if payload.amount > 999999:
94-
raise Exception("amount_gte_999999")
65+
raise ValueError("Amount exceeds allowed limit.")
9566

9667
checkout_data = payload.checkout_data
97-
98-
item = dict()
99-
100-
# Create activist fields
101-
amount = str(payload.amount)
102-
item['name'] = checkout_data.name.title()
103-
item['email'] = checkout_data.email
104-
item['metadata'] = dict(
105-
amount=f"{amount[:len(amount)-2]}.00",
106-
transaction_status=payload.transaction_status,
107-
payment_method=payload.payment_method,
108-
recurring=payload.subscription
109-
)
110-
if payload.subscription:
111-
item['metadata']['recurring_period'] = "Monthly"
112-
11368
address = checkout_data.address
114-
115-
item['address_line'] = \
116-
f"{address.street_number} {address.street}, {address.complementary}" \
117-
if address.complementary \
118-
else f"{address.street_number} {address.street}"
119-
120-
item['locality'] = address.city
121-
item['region'] = address.state
122-
item['postal_code'] = address.zipcode
123-
12469
phone = checkout_data.phone
125-
item['phone'] = f"+55{phone.ddd}{phone.number}"
126-
127-
item['given_name'] = item['name'].split(" ")[0]
128-
item['family_name'] = " ".join(item['name'].split(" ")[1:])
129-
130-
# Clean response
131-
response = dict()
132-
for key, value in item.items():
133-
if value:
134-
response[key] = value
135-
136-
return response
13770

71+
item = {
72+
'name': checkout_data.name.title(),
73+
'email': checkout_data.email,
74+
'metadata': {
75+
'amount': f"{str(payload.amount)[:-2]}.00",
76+
'transaction_status': payload.transaction_status,
77+
'payment_method': payload.payment_method,
78+
'recurring': payload.subscription,
79+
'recurring_period': "Monthly" if payload.subscription else None
80+
},
81+
'address_line': f"{address.street_number} {address.street}, {address.complementary}".strip(', '),
82+
'locality': address.city,
83+
'region': address.state,
84+
'postal_code': address.zipcode,
85+
'phone': f"+55{phone.ddd}{phone.number}" if phone else None
86+
}
87+
88+
item['name'], item['given_name'], item['family_name'] = normalize_name(item['name'], None, None)
89+
return clean_response(item)
13890

13991
def pressure(payload: Pressure):
140-
"""pressure"""
14192
form_data = payload.form_data
142-
item = dict()
143-
144-
item['name'] = form_data.name.title()
145-
item['email'] = form_data.email
146-
item['given_name'] = form_data.name.title()
147-
item['family_name'] = form_data.lastname.title()
148-
if form_data.state:
149-
item['region'] = form_data.state
150-
151-
if form_data.phone:
152-
item['phone'] = form_data.phone
153-
154-
item["phone"] = item["phone"].replace(r'[\(\) -]+', '', regex=True)
155-
item["phone"] = item["phone"].replace(
156-
r'^\d{1}(\d{2})(\d{1})(\d{4})(\d{4})$', r'+55 (\1) \2 \3 \4', regex=True)
157-
item["phone"] = item["phone"].replace(
158-
r'^\d{2}(\d{2})(\d{1})(\d{4})(\d{4})$', r'+55 (\1) \2 \3 \4', regex=True)
159-
item["phone"] = item["phone"].replace(
160-
r'^(\d{2})(\d{1})(\d{4})(\d{4})$', r'+55 (\1) \2 \3 \4', regex=True)
161-
item["phone"] = item["phone"].replace(
162-
r'^\+(\d{2})(\d{2})(\d{1})(\d{4})(\d{4})$', r'+\1 (\2) \3 \4 \5', regex=True)
163-
item["phone"] = item["phone"].replace(
164-
r'^(\d{2})(\d{4})(\d{4})$', r'+55 (\1) 9 \2 \3', regex=True)
165-
item["phone"] = item["phone"].replace(
166-
r'^\{"ddd"=>"(\d{2})","number"=>"(\d{1})(\d{8})"\}$', r'+55 (\1) \2 \3', regex=True)
167-
168-
item['region'] = item['phone'].replace(r'^\+[\d ]+\((\d{2})\)[\d ]+$', r'\1', regex=True) \
169-
if not item['region'] & item['phone'] \
170-
else item['region']
171-
172-
item['region'] = find_by_ddd(item['region'])
173-
174-
# Clean response
175-
response = dict()
176-
for key, value in item.items():
177-
if value:
178-
response[key] = value
179-
180-
return response
181-
93+
item = {
94+
'name': form_data.name.title(),
95+
'email': form_data.email,
96+
'given_name': form_data.name.split(" ")[0].title(),
97+
'family_name': " ".join(form_data.name.split(" ")[1:]).title(),
98+
'region': form_data.state,
99+
'phone': normalize_phone(form_data.phone) if form_data.phone else None
100+
}
101+
if item['phone']:
102+
item['region'] = find_by_ddd(item['phone'])
103+
return clean_response(item)
182104

183105
def plip(payload: Plip):
184-
"""plip"""
185106
form_data = payload.form_data
186-
item = dict()
187-
188-
item['name'] = form_data.name.title()
189-
item['email'] = form_data.email
190-
item['region'] = form_data.state
191-
item['given_name'] = item['name'].split(" ")[0]
192-
item['family_name'] = " ".join(item['name'].split(" ")[1:])
193-
if form_data.color:
194-
item['color'] = form_data.color
195-
196-
if form_data.whatsapp:
197-
item["phone"] = form_data.whatsapp
198-
199-
item['phone'] = only_digits(item['phone'])
200-
item['phone'] = re.sub(
201-
r'^(\d{2})(\d{1})(\d{4})(\d{4})$', r'+55 (\1) \2 \3 \4', item['phone'])
202-
item['phone'] = re.sub(
203-
r'^(\d{1})(\d{4})(\d{4})$', r'+55 (xx) \1 \2 \3', item['phone'])
204-
item['phone'] = re.sub(
205-
r'^(\d{2})(\d{4})(\d{4})$', r'+55 (\1) 9 \2 \3', item['phone'])
206-
item['phone'] = re.sub(
207-
r'^(\d{4})(\d{4})$', r'+55 (xx) 9 \1 \2', item['phone'])
208-
209-
if form_data.gender:
210-
item['gender'] = form_data.gender
211-
212-
item['metadata'] = dict(
213-
expected_signatures=form_data.expected_signatures,
214-
unique_identifier=payload.unique_identifier,
215-
type_form="Ativista"
216-
)
217-
218-
# Clean response
219-
response = dict()
220-
for key, value in item.items():
221-
if value:
222-
response[key] = value
223-
224-
return response
225-
107+
item = {
108+
'name': form_data.name.title(),
109+
'email': form_data.email,
110+
'region': form_data.state,
111+
'color': form_data.color,
112+
'phone': normalize_phone(form_data.whatsapp) if form_data.whatsapp else None,
113+
'metadata': {
114+
'expected_signatures': form_data.expected_signatures,
115+
'unique_identifier': payload.unique_identifier,
116+
'type_form': "Ativista"
117+
}
118+
}
119+
item['name'], item['given_name'], item['family_name'] = normalize_name(item['name'], None, None)
120+
return clean_response(item)
226121

227122
def to_payload(data: Payload):
228123
"""to_payload"""

0 commit comments

Comments
 (0)