Use config file instead of multiple options

This commit is contained in:
Cyril Novel 2020-06-11 21:27:15 +02:00
commit 8d5f00a896
3 changed files with 100 additions and 44 deletions

11
src/config_example.ini Normal file
View file

@ -0,0 +1,11 @@
[Data]
mariages = /path/to/mariages.csv
members = /path/to/members.csv
[Mailer]
smtp_server = smtp.example.com
user = admin@example.com
password = password
[Destination]
receiver = diff@example.com

View file

@ -1,3 +1,4 @@
import configparser
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
@ -14,36 +15,68 @@ months = ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'ao
'octobre', 'novembre', 'décembre'] 'octobre', 'novembre', 'décembre']
class EmailSender: class DataPaths:
def __init__(self, smtp_server, user, password): def __init__(self, mariages_path, members_path):
self._smtp_server = smtp_server self._mariages_path = mariages_path
self._user = user self._members_path = members_path
self._pwd = password
print("Setup OK")
def send_paturlettre(self, recipients): def mariages(self):
return self._mariages_path
def members(self):
return self._members_path
class Mailer:
def __init__(self, server, user, password):
self._server = server
self._usr = user
self._pwd = password
def server(self):
return self._server
def user(self):
return self._usr
def password(self):
return self._pwd
class EmailSender:
def __init__(self, mailer: Mailer, paths: DataPaths, receiver: str):
self._mailer = mailer
self._paths = paths
self._receiver = receiver
print("Email Sender is set up")
def send_paturlettre(self):
msg = MIMEMultipart('alternative') msg = MIMEMultipart('alternative')
msg['Subject'] = f'[Paturlettre] Semaine {get_week_number_and_span()[0]}' msg['Subject'] = f'[Paturlettre] Semaine {get_week_number_and_span()[0]}'
msg['From'] = 'Paturlettre <paturlettre@kosmon.fr>' msg['From'] = 'Paturlettre <paturlettre@kosmon.fr>'
msg['To'] = 'Diffusion Paturlettre <no_reply_paturlettre@kosmon.fr>' msg['To'] = 'Diffusion Paturlettre <no_reply_paturlettre@kosmon.fr>'
msg.preamble = f'La Paturlettre de la semaine {get_week_number_and_span()[0]} !' msg.preamble = f'La Paturlettre de la semaine {get_week_number_and_span()[0]} !'
msg.attach(MIMEText(create_plain_email(), 'plain')) print("Msg Header is set up")
msg.attach(MIMEText(create_email_from_template(), 'html'))
print("Msg OK")
conn = SMTP_SSL(self._smtp_server, port=465) events_previous, events_current, events_next = get_events(self._paths)
print("Conn OK") msg.attach(MIMEText(create_plain_email(events_previous, events_current, events_next),
conn.login(self._user, self._pwd) 'plain'))
print("Login OK") msg.attach(MIMEText(create_html_templated(events_previous, events_current, events_next),
'html'))
print("Msg body is generated")
conn = SMTP_SSL(self._mailer.server(), port=465)
print("SMTP Connection OK")
conn.login(self._mailer.user(), self._mailer.password())
print("SMTP Login OK")
try: try:
conn.sendmail(msg['From'], 'diffusion_paturlettre@kosmon.fr', msg.as_string()) conn.sendmail(msg['From'], self._receiver, msg.as_string())
print("Send OK") print("Paturlettre has been sent!")
finally: finally:
conn.quit() conn.quit()
def create_email_from_template(): def create_html_templated(events_previous, events_current, events_next):
events_previous, events_current, events_next = get_events()
with open('../html_template/mail.html', 'r', encoding='utf-8') as tmp: with open('../html_template/mail.html', 'r', encoding='utf-8') as tmp:
mail = tmp.read() mail = tmp.read()
mail = mail.replace('{LogoAddress}', mail = mail.replace('{LogoAddress}',
@ -65,8 +98,7 @@ def create_email_from_template():
return mail return mail
def create_plain_email(): def create_plain_email(events_previous, events_current, events_next):
events_previous, events_current, events_next = get_events()
wk_and_span = get_week_number_and_span() wk_and_span = get_week_number_and_span()
mail_plain = f'Paturlettre - Semaine {wk_and_span[0]}\n' mail_plain = f'Paturlettre - Semaine {wk_and_span[0]}\n'
mail_plain += f'du {wk_and_span[1].day} {months[wk_and_span[1].month - 1]}' \ mail_plain += f'du {wk_and_span[1].day} {months[wk_and_span[1].month - 1]}' \
@ -104,7 +136,9 @@ def create_html_string_for_day(day_name: str, events: list, last_day: bool) -> s
if not last_day and i == len(events) - 1: if not last_day and i == len(events) - 1:
style = "width: 100%; border-bottom: 1px dashed #9ba5ae;" style = "width: 100%; border-bottom: 1px dashed #9ba5ae;"
html_str += f' <tr style="{style}">\n' html_str += f' <tr style="{style}">\n'
html_str += f' <td class="genea_row"><span class="min_info"><b>{e.type_str()}</b> · {e.event_date_as_str()} </span><br />{e.event_description()}</td>\n' html_str += f' <td class="genea_row"><span class="min_info">' \
f'<b>{e.type_str()}</b> · {e.event_date_as_str()} </span>' \
f'<br />{e.event_description()}</td>\n'
html_str += ' </tr>' html_str += ' </tr>'
return html_str return html_str
@ -156,17 +190,23 @@ def create_plain_string_for_week(events: list):
return plain_str return plain_str
def get_events(): def get_events(data_paths: DataPaths):
today = date.today() today = date.today()
monday = today - timedelta(days=today.weekday()) monday = today - timedelta(days=today.weekday())
previous_monday = monday - timedelta(days=7) previous_monday = monday - timedelta(days=7)
next_monday = monday + timedelta(days=7) next_monday = monday + timedelta(days=7)
previous_week_events = create_events_from_span(previous_monday, previous_week_events = create_events_from_span(previous_monday,
previous_monday + timedelta(days=6)) previous_monday + timedelta(days=6),
data_paths.members(),
data_paths.mariages())
this_week_events = create_events_from_span(monday, this_week_events = create_events_from_span(monday,
monday + timedelta(days=6)) monday + timedelta(days=6),
data_paths.members(),
data_paths.mariages())
next_week_events = create_events_from_span(next_monday, next_week_events = create_events_from_span(next_monday,
next_monday + timedelta(days=6)) next_monday + timedelta(days=6),
data_paths.members(),
data_paths.mariages())
return previous_week_events, this_week_events, next_week_events return previous_week_events, this_week_events, next_week_events
@ -176,19 +216,28 @@ def get_week_number_and_span():
return today.isocalendar()[1], monday, monday + timedelta(days=6) return today.isocalendar()[1], monday, monday + timedelta(days=6)
def load_config(config_file) -> (Mailer, DataPaths, str):
config = configparser.ConfigParser()
config.read(config_file, encoding='utf-8')
mailer = Mailer(config['Mailer']['smtp_server'],
config['Mailer']['user'],
config['Mailer']['password'])
data_path = DataPaths(config['Data']['mariages'],
config['Data']['members'])
receiver = config['Destination']['receiver']
return mailer, data_path, receiver
def main(): def main():
parser = ArgumentParser(description='Send mail') parser = ArgumentParser(description='Send Paturlettre mail')
parser.add_argument('-s', '--smtp', dest='smtp_server', parser.add_argument('-c', '--config', dest='config',
help='Json files to process, multiple values accepted') help='Config file to load')
parser.add_argument('-u', '--user', dest='user',
help='Json files to process, multiple values accepted')
parser.add_argument('-p', '--password', dest='password',
help='Json files to process, multiple values accepted')
args = parser.parse_args() args = parser.parse_args()
email_sender = EmailSender(args.smtp_server, args.user, args.password) mailer, paths, receiver = load_config(args.config)
email_sender.send_paturlettre(None) email_sender = EmailSender(mailer, paths, receiver)
print("Done") email_sender.send_paturlettre()
print("Exiting script")
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -1,14 +1,10 @@
from datetime import date from datetime import date
from src.person import Person from src.person import Person
from src.mariage import Mariage from src.mariage import Mariage
from os.path import abspath, join, dirname
event_types = ['N', 'M', 'D'] event_types = ['N', 'M', 'D']
members_file = abspath(join(dirname(__file__), 'data', 'members.csv'))
mariages_file = abspath(join(dirname(__file__), 'data', 'mariages.csv'))
class Event: class Event:
def __init__(self, event_type: str, event_date: date, current_date: date, def __init__(self, event_type: str, event_date: date, current_date: date,
@ -61,7 +57,7 @@ class Event:
return self._type return self._type
def load_persons_to_dict() -> dict: def load_persons_to_dict(members_file: str) -> dict:
id_to_person = {} id_to_person = {}
first_line = True first_line = True
with open(members_file, 'r', encoding='utf-8') as members: with open(members_file, 'r', encoding='utf-8') as members:
@ -85,7 +81,7 @@ def load_persons_to_dict() -> dict:
return id_to_person return id_to_person
def load_mariage_to_dict() -> dict: def load_mariage_to_dict(mariages_file: str) -> dict:
id_to_mariage = {} id_to_mariage = {}
first_line = True first_line = True
with open(mariages_file, 'r', encoding='utf-8') as mariages: with open(mariages_file, 'r', encoding='utf-8') as mariages:
@ -125,9 +121,9 @@ def find_significant_other(id_to_mariage: dict, uid: int) -> int:
return -1 return -1
def create_events_from_span(start: date, end: date) -> list: def create_events_from_span(start: date, end: date, members_file: str, mariages_file: str) -> list:
id_to_person = load_persons_to_dict() id_to_person = load_persons_to_dict(members_file)
id_to_mariage = load_mariage_to_dict() id_to_mariage = load_mariage_to_dict(mariages_file)
cur_year = start.year cur_year = start.year
events = [] events = []