working parsing of message, finding conflicts
This commit is contained in:
parent
34be02ccc7
commit
224ffbe65c
138
email_client.py
138
email_client.py
@ -13,22 +13,28 @@ import imaplib
|
||||
import getpass
|
||||
import email
|
||||
import email.header
|
||||
import datetime
|
||||
from IPython import embed
|
||||
import re
|
||||
import datetime as dt
|
||||
|
||||
EMAIL_ACCOUNT = "bzigr02"
|
||||
EMAIL_FOLDER = "INBOX"
|
||||
|
||||
fields = ["Fist name", "Last name", "e-Mail", "Institution", "Phone", "Country", "City", "ZIP code", "Street",
|
||||
"Fees", "Farewell event (Thu 20 Feb)", "Gwinner Award",
|
||||
"Food preferences", "LabTour (Fri 21 Feb)", "Messages"]
|
||||
|
||||
reg_fees = {'early': {"proMember": 95, "proNonMember":115, "studentMember": 55, "studentNonMember": 65},
|
||||
'late': {"proMember": 115, "proNonMember":135, "studentMember": 65, "studentNonMember": 75}}
|
||||
farewell_fee = {"senior": 45, "student": 25}
|
||||
early_bird = dt.datetime.fromisoformat('2020-01-16T00:00:00')
|
||||
|
||||
|
||||
class Participation(object):
|
||||
field_mapping = [("First name", "_first_name"), ("Last name", "_last_name"),
|
||||
("Institution", "_institution", True), ("Street", "_address_street"),
|
||||
("City", "_address_city"), ("ZIP code", "_address_zip"),
|
||||
("Phone", "_phone"), ("e-Mail", "_email"),
|
||||
("Country", "_address_country"), ("Fee", "_role"),
|
||||
("Messages", "_message"), ("Food preferences", "_food_preference"),
|
||||
("Farewell event", "_farewell"), ("Gwinner", "_gwinner"),
|
||||
("Lab Tour (Fri 21 Feb)", "_lab_tour", True)]
|
||||
|
||||
def __init__(self, email_message):
|
||||
self._registration_date = ""
|
||||
@ -36,9 +42,10 @@ class Participation(object):
|
||||
self._last_name = ""
|
||||
self._phone = ""
|
||||
self._email = ""
|
||||
self._student = False
|
||||
self._member = False
|
||||
self._farewell = False
|
||||
self._farewell = ""
|
||||
self._gwinner = ""
|
||||
self._lab_tour = ""
|
||||
self._food_preference = ""
|
||||
self._food_vegi = False
|
||||
self._food_vegan = False
|
||||
self._food_gluten = False
|
||||
@ -46,41 +53,62 @@ class Participation(object):
|
||||
self._address_street = ""
|
||||
self._address_city = ""
|
||||
self._address_zip = ""
|
||||
self._country = ""
|
||||
self._address_country = ""
|
||||
self._institution = ""
|
||||
self._role = ""
|
||||
self._message = ""
|
||||
self._fee = 0.0
|
||||
|
||||
self._conflicts = []
|
||||
self.__parse_message(email_message)
|
||||
|
||||
def __parse_message(self, message):
|
||||
self._registration_date = message["Date"]
|
||||
date_tuple = email.utils.parsedate_tz(message['Date'])
|
||||
if date_tuple:
|
||||
local_date = dt.datetime.fromtimestamp(
|
||||
email.utils.mktime_tz(date_tuple))
|
||||
self._registration_date = local_date
|
||||
|
||||
msg_body = message.get_payload()[0].as_string()
|
||||
msg_body = re.sub(r'=20', ' ', msg_body)
|
||||
msg_body = re.sub(r'=\n', '', msg_body)
|
||||
msg_body = re.sub(r'=E2=82=AC', 'EUR', msg_body)
|
||||
msg_body = re.sub(r'&', 'and', msg_body)
|
||||
|
||||
lines = msg_body.split('\n')
|
||||
self.__parse_food(lines)
|
||||
self.__parse_address(lines)
|
||||
embed()
|
||||
pass
|
||||
|
||||
def __parse_address(self, lines):
|
||||
street = [s for s in lines if s.lower().startswith("street")]
|
||||
self._address_street = street[0]
|
||||
city = [s for s in lines if s.lower().startswith("city")]
|
||||
self._address_city = city[0]
|
||||
plz = [s for s in lines if s.lower().startswith("zip")]
|
||||
self._address_zip = plz[0]
|
||||
inst = [s for s in lines if s.lower().startswith("institution")]
|
||||
self._institution = ', '.join(inst)
|
||||
|
||||
def __parse_food(self, lines):
|
||||
food = [l for l in lines if "Food preference" in l]
|
||||
if len(food) > 0:
|
||||
prefs = food[0].lower()
|
||||
|
||||
for fm in Participation.field_mapping:
|
||||
self.__parse_lines(lines, fm)
|
||||
self.__process_food(lines)
|
||||
self.__check()
|
||||
|
||||
def __check(self):
|
||||
if "student" not in self._role and self.gwinner_award:
|
||||
self._conflicts.append("Gwinner award selected but not student!")
|
||||
if (self._food_vegan or self._food_gluten or self.vegetarian) and self._food_normal:
|
||||
self._conflicts.append("Conflict in food preferences!")
|
||||
|
||||
def __calc_fee(self):
|
||||
fee = .0
|
||||
early_or_late = "early" if self.registration_date < early_bird else "late"
|
||||
pro_or_stud = "senior" if "pro" in self._role else "student"
|
||||
fee += reg_fees[early_or_late][self._role]
|
||||
fee += farewell_fee[pro_or_stud] if self.farewell_event else 0.0
|
||||
return fee
|
||||
|
||||
def __parse_lines(self, lines, field_map):
|
||||
assert(len(field_map) >= 2)
|
||||
|
||||
ls = [l for l in lines if l.lower().startswith(field_map[0].lower())]
|
||||
if len(ls) < 1:
|
||||
print("%s not found: " % field_map[0])
|
||||
return
|
||||
if len(field_map) == 2:
|
||||
setattr(self, field_map[1], ls[0].split(field_map[0])[-1].strip())
|
||||
else:
|
||||
setattr(self, field_map[1], ', '.join(map(lambda x:x.split(field_map[0])[-1].strip(), ls)))
|
||||
|
||||
def __process_food(self, lines):
|
||||
if len(self._food_preference) > 0:
|
||||
prefs = self._food_preference.lower()
|
||||
self._food_normal = "no special" in prefs
|
||||
self._food_vegan = "vegan" in prefs
|
||||
self._food_vegi = "vegetarian" in prefs
|
||||
@ -90,6 +118,48 @@ class Participation(object):
|
||||
def registration_date(self):
|
||||
return self._registration_date
|
||||
|
||||
@property
|
||||
def fee(self):
|
||||
return self.__calc_fee()
|
||||
|
||||
@property
|
||||
def farewell_event(self):
|
||||
return len(self._farewell) > 0
|
||||
|
||||
@property
|
||||
def gwinner_award(self):
|
||||
return len(self._gwinner) > 0
|
||||
|
||||
@property
|
||||
def labtour(self):
|
||||
return self._lab_tour.split(",")
|
||||
|
||||
@property
|
||||
def valid(self):
|
||||
return len(self._conflicts) == 0
|
||||
|
||||
def __str__(self):
|
||||
str = ""
|
||||
str += "Name: %s %s\n" % (self._first_name, self._last_name)
|
||||
str += "Institution: %s\n" % self._institution
|
||||
str += "Phone: %s\n" % self._phone
|
||||
str += "e-Mail: %s\n" % self._email
|
||||
str += "%s %s\n" % ("senior" if "pro" in self._role else "student",
|
||||
"non-member" if "NonMember" in self._role else "member")
|
||||
str += "Farewell event: %s\n" % "Yes" if self.farewell_event else "No"
|
||||
str += "Fee: %f Eur\n" % self.fee
|
||||
str += "Lab tour: %s\n" % ( "No" if len(self.labtour) == 0 else "Yes, " + ", ".join(self.labtour))
|
||||
str += "Gwinner award: %s\n" % "Yes" if self.gwinner_award else "No"
|
||||
str += "Food preferences: %s, %s, %s, %s\n" % ("no prefs" if self._food_normal else "",
|
||||
"vegetarian" if self._food_vegi else "",
|
||||
"vegan" if self._food_vegan else "",
|
||||
"gluten free" if self._food_gluten else "")
|
||||
str += "Registration date: %s\n" % self.registration_date.isoformat()
|
||||
str += "Message:%s\n" % self._message
|
||||
if not self.valid:
|
||||
str += "Inconsistencies: %s\n" % ", ".join(self._conflicts)
|
||||
return str
|
||||
|
||||
|
||||
def process_mailbox(M):
|
||||
"""
|
||||
@ -116,7 +186,7 @@ def process_mailbox(M):
|
||||
# Now convert to local date-time
|
||||
date_tuple = email.utils.parsedate_tz(msg['Date'])
|
||||
if date_tuple:
|
||||
local_date = datetime.datetime.fromtimestamp(
|
||||
local_date = dt.datetime.fromtimestamp(
|
||||
email.utils.mktime_tz(date_tuple))
|
||||
print ("Local Date:", \
|
||||
local_date.strftime("%a, %d %b %Y %H:%M:%S"))
|
||||
@ -168,6 +238,8 @@ if __name__ == "__main__":
|
||||
print("ERROR: Unable to open mailbox folder ", rv)
|
||||
|
||||
new_participations = process_registrations(M)
|
||||
embed()
|
||||
for p in new_participations:
|
||||
print(p)
|
||||
|
||||
M.close()
|
||||
M.logout()
|
||||
|
Loading…
Reference in New Issue
Block a user