Compare commits
No commits in common. "6c103d512c47b22de160bc95487f7ba717d3fe94" and "184e13b698cb174f5429834881b9f1d671ff5c26" have entirely different histories.
6c103d512c
...
184e13b698
23
init.sql
23
init.sql
@ -1,25 +1,12 @@
|
|||||||
create table if not exists training(
|
create table if not exists training(
|
||||||
id uuid primary key default gen_random_uuid(),
|
id integer primary key,
|
||||||
owner varchar(255) not null,
|
|
||||||
filename text not null,
|
|
||||||
medium varchar(255) not null,
|
medium varchar(255) not null,
|
||||||
description text not null,
|
uuid uuid 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,
|
t timestamp with time zone not null,
|
||||||
lat float not null,
|
lat float not null,
|
||||||
lon float not null,
|
lon float not null,
|
||||||
speed float not null,
|
speed float not null,
|
||||||
elevation float not null,
|
altitude float not null,
|
||||||
distance 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
63
main.py
@ -1,15 +1,8 @@
|
|||||||
import configparser
|
import configparser
|
||||||
from imaplib import IMAP4
|
from imaplib import IMAP4
|
||||||
import ssl
|
import ssl
|
||||||
import email
|
|
||||||
import os
|
|
||||||
from glob import glob
|
|
||||||
import sys
|
|
||||||
from gpxpy import gpx
|
|
||||||
|
|
||||||
from sqlalchemy import create_engine, text
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy.engine import Connection
|
|
||||||
import gpxpy
|
|
||||||
|
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
@ -18,7 +11,6 @@ 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'])
|
mail = IMAP4(host=config['mail']['host'])
|
||||||
fitotrack_msg_filter = '(OR SUBJECT "fitotrack" SUBJECT "Fitotrack" SUBJECT "FITOTRACK" SUBJECT "FitoTrack")'
|
|
||||||
|
|
||||||
|
|
||||||
def init_database():
|
def init_database():
|
||||||
@ -27,66 +19,19 @@ def init_database():
|
|||||||
|
|
||||||
|
|
||||||
def get_gpx_files_from_mail():
|
def get_gpx_files_from_mail():
|
||||||
try:
|
|
||||||
os.mkdir('gpx_files')
|
|
||||||
except FileExistsError:
|
|
||||||
pass
|
|
||||||
mail.starttls(ssl.create_default_context())
|
mail.starttls(ssl.create_default_context())
|
||||||
mail.login(config['mail']['username'], config['mail']['password'])
|
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()
|
mail.logout()
|
||||||
|
|
||||||
|
|
||||||
def process_gpx_files(tx: Connection, owner: str):
|
def main():
|
||||||
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()
|
init_database()
|
||||||
get_gpx_files_from_mail()
|
get_gpx_files_from_mail()
|
||||||
db.transaction(process_gpx_files, owner)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
try:
|
||||||
main(sys.argv[1])
|
main()
|
||||||
except IndexError:
|
|
||||||
print('Run the script with "python main.py OWNER_NAME"')
|
|
||||||
except (KeyboardInterrupt, EOFError):
|
except (KeyboardInterrupt, EOFError):
|
||||||
pass
|
pass
|
Loading…
x
Reference in New Issue
Block a user