From 344455e4098c125d404e5b68282478d6a23624b2 Mon Sep 17 00:00:00 2001 From: Riccardo Berto Date: Mon, 28 Mar 2022 17:40:43 +0200 Subject: [PATCH] deprecated db.transaction --- main.py | 128 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 77 insertions(+), 51 deletions(-) diff --git a/main.py b/main.py index 1fa1655..edb53b3 100644 --- a/main.py +++ b/main.py @@ -7,31 +7,31 @@ from glob import glob from email.message import Message from sqlalchemy import create_engine, text -from sqlalchemy.engine import Connection import gpxpy -from bs4 import BeautifulSoup config = configparser.ConfigParser() -config.read('config.ini') +config.read("config.ini") -db = create_engine(f"postgresql://{config['db']['username']}:{config['db']['password']}@{config['db']['host']}/{config['db']['database']}").connect() +db = create_engine( + f"postgresql://{config['db']['username']}:{config['db']['password']}@{config['db']['host']}/{config['db']['database']}" +).connect() -mail = IMAP4(host=config['mail']['host']) -fitotrack_msg_filter = 'ALL' +mail = IMAP4(host=config["mail"]["host"]) +fitotrack_msg_filter = "ALL" def init_database(): - with open('init.sql') as f: - db.execute('\n'.join(f.readlines())) + with open("init.sql") as f: + db.execute("\n".join(f.readlines())) def _get_sender(msg: Message) -> str: - sender: str = msg.get('from') - if ' ' in sender: - sender = sender.split(' ') + sender: str = msg.get("from") + if " " in sender: + sender = sender.split(" ") for field in sender: - if '@' in field and '<' in field and '>' in field: + if "@" in field and "<" in field and ">" in field: return field[1:-1] return sender @@ -39,87 +39,113 @@ def _get_sender(msg: Message) -> str: def get_gpx_files_from_mail(): mail.starttls(ssl.create_default_context()) - mail.login(config['mail']['username'], config['mail']['password']) + mail.login(config["mail"]["username"], config["mail"]["password"]) mail.select() _, ids = mail.search(None, fitotrack_msg_filter) ids = ids[0].split() for i in ids: - _, fetched = mail.fetch(i, '(RFC822)') + _, fetched = mail.fetch(i, "(RFC822)") email_message = email.message_from_bytes(fetched[0][1]) sender = _get_sender(email_message) for part in email_message.walk(): - if part.get_content_maintype() == 'multipart' or part.get_content_disposition() is None: + if ( + part.get_content_maintype() == "multipart" + or part.get_content_disposition() is None + ): continue filename = part.get_filename() if filename: - filename = f'{sender}_{filename}' - if not os.path.exists(f'gpx_files/{filename}'): - with open(f'gpx_files/{filename}', 'wb') as f: - print(f'creating {filename}') + filename = f"{sender}_{filename}" + if not os.path.exists(f"gpx_files/{filename}"): + with open(f"gpx_files/{filename}", "wb") as f: + print(f"creating {filename}") f.write(part.get_payload(decode=True)) - mail.store(i, '+FLAGS', '\\Deleted') - + mail.store(i, "+FLAGS", "\\Deleted") + mail.expunge() mail.close() mail.logout() -def process_gpx_files(tx: Connection): - for filepath in glob('gpx_files/*.gpx'): - owner = os.path.split(filepath)[-1].split('_workout-')[0] +def process_gpx_files(): + for filepath in glob("gpx_files/*.gpx"): + owner = os.path.split(filepath)[-1].split("_workout-")[0] filename = f'workout-{os.path.split(filepath)[-1].split("_workout-")[1]}' - print(f'Processing {filename}') - if list(tx.execute(text('select exists(select from training where owner = :owner and filename = :filename)'), - dict(owner=owner, filename=filename,),),)[0][0]: + print(f"Processing {filename}") + if list( + db.execute( + text( + "select exists(select from training where owner = :owner and filename = :filename)" + ), + dict( + owner=owner, + filename=filename, + ), + ), + )[0][0]: os.remove(filepath) continue with open(filepath) as f: gpx_file = gpxpy.parse(f) - if gpx_file.creator != 'FitoTrack': - raise ValueError('gpx file not generated by the FitoTrack app') - training_id = list(tx.execute( - text(""" + if gpx_file.creator != "FitoTrack": + raise ValueError("gpx file not generated by the FitoTrack app") + training_id = list( + db.execute( + text( + """ insert into training(owner, filename, type, description, moving_time, stopped_time, moving_distance, stopped_distance) values (:owner, :filename, :type, :description, :moving_time, :stopped_time, :moving_distance, :stopped_distance) returning id - """), - dict(owner=owner, - filename=filename, - type='cycling', # TODO other training types - description=gpx_file.description, - moving_time=gpx_file.get_moving_data().moving_time, - stopped_time=gpx_file.get_moving_data().stopped_time, - moving_distance=gpx_file.get_moving_data().moving_distance, - stopped_distance=gpx_file.get_moving_data().stopped_distance,), - ))[0][0] + """ + ), + dict( + owner=owner, + filename=filename, + type="cycling", # TODO other training types + description=gpx_file.description, + moving_time=gpx_file.get_moving_data().moving_time, + stopped_time=gpx_file.get_moving_data().stopped_time, + moving_distance=gpx_file.get_moving_data().moving_distance, + stopped_distance=gpx_file.get_moving_data().stopped_distance, + ), + ) + )[0][0] for track in gpx_file.tracks: for segment in track.segments: for point in segment.points: - tx.execute(text(""" + db.execute( + text( + """ insert into training_data(training_id, t, geog, speed, elevation) values (:training_id, :t, :geog, :speed, :elevation) - """), - dict(training_id=training_id, - t=point.time, - geog=f'POINT({point.latitude} {point.longitude})', - speed=point.speed, - elevation=point.elevation,),) + """ + ), + dict( + training_id=training_id, + t=point.time, + geog=f"POINT({point.latitude} {point.longitude})", + speed=point.speed, + elevation=point.elevation, + ), + ) os.remove(filepath) def main(): try: - os.mkdir('gpx_files') + os.mkdir("gpx_files") except FileExistsError: pass init_database() get_gpx_files_from_mail() - db.transaction(process_gpx_files) + + with db.begin(): + process_gpx_files() -if __name__ == '__main__': +if __name__ == "__main__": try: main() except (KeyboardInterrupt, EOFError):