Compare commits

...

14 Commits

2 changed files with 77 additions and 9 deletions

View File

@ -1,12 +1,25 @@
create table if not exists training(
id integer primary key,
id uuid primary key default gen_random_uuid(),
owner varchar(255) not null,
filename text not null,
medium varchar(255) not null,
uuid uuid not null,
description text not null,
moving_time float not null,
stopped_time float not null,
moving_distance float not null,
stopped_distance float not null,
data jsonb not null default '{}'
);
create table if not exists training_data(
training_id uuid not null,
t timestamp with time zone not null,
lat float not null,
lon float not null,
speed float not null,
altitude float not null,
elevation float not null,
distance float not null,
kcal int not null
);
kcal int not null,
constraint fk_training_id foreign key(training_id) references training(id) on delete cascade
);
create index if not exists idx_training_data_training_id on training_data(training_id);

63
main.py
View File

@ -1,8 +1,15 @@
import configparser
from imaplib import IMAP4
import ssl
import email
import os
from glob import glob
import sys
from gpxpy import gpx
from sqlalchemy import create_engine
from sqlalchemy import create_engine, text
from sqlalchemy.engine import Connection
import gpxpy
config = configparser.ConfigParser()
@ -11,6 +18,7 @@ config.read('config.ini')
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 = '(OR SUBJECT "fitotrack" SUBJECT "Fitotrack" SUBJECT "FITOTRACK" SUBJECT "FitoTrack")'
def init_database():
@ -19,19 +27,66 @@ def init_database():
def get_gpx_files_from_mail():
try:
os.mkdir('gpx_files')
except FileExistsError:
pass
mail.starttls(ssl.create_default_context())
mail.login(config['mail']['username'], config['mail']['password'])
mail.create(config['mail']['mailbox_dir'])
mail.select()
_, ids = mail.search(None, fitotrack_msg_filter)
ids = ids[0].split()
for i in ids:
_, fetched = mail.fetch(i, '(RFC822)')
email_message = email.message_from_bytes(fetched[0][1])
for part in email_message.walk():
if part.get_content_maintype() == 'multipart' or part.get_content_disposition() is None:
continue
filename = part.get_filename()
if filename and not os.path.exists(f'gpx_files/{filename}'):
with open(os.path.join('gpx_files', filename), 'wb') as f:
f.write(part.get_payload(decode=True))
mail.logout()
def main():
def process_gpx_files(tx: Connection, owner: str):
for filepath in glob('gpx_files/*.gpx'):
filename = os.path.split(filepath)[-1]
if list(db.execute(text('select exists(select from training where filename = :filename)'), dict(filename=filename)))[0][0]:
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(db.execute(
"""insert into training (owner, filename, medium, description, moving_time, stopped_time, moving_distance, stopped_distance) values
(?, ?, ?, ?, ?, ?, ?, ?) returning id""",
(owner,
filename,
"",
gpx_file.description,
gpx_file.get_moving_data().moving_time,
gpx_file.get_moving_data().stopped_time,
gpx_file.get_moving_data().moving_distance,
gpx_file.get_moving_data().stopped_distance,)
))[0][0]
def main(owner: str):
init_database()
get_gpx_files_from_mail()
db.transaction(process_gpx_files, owner)
if __name__ == '__main__':
try:
main()
main(sys.argv[1])
except IndexError:
print('Run the script with "python main.py OWNER_NAME"')
except (KeyboardInterrupt, EOFError):
pass
pass