Files
polar-flow-analysis/flow.py
2015-12-27 15:24:40 +01:00

127 lines
4.6 KiB
Python

import logging
import requests
import pickle
import os.path
import json
import re
import sys
import subprocess
from io import StringIO
from datetime import timedelta
class Flow:
format = '%d.%m.%Y'
zip = False # zipped downloads not yet implemented
def __init__(self, logger = None, period = 2, file = 'flow-session.dat', jsondir = 'json', datadir = 'data', persist = True, restart = False):
self.logger = logger or logging.getLogger(__name__)
self.jsondir = jsondir
self.datadir = datadir
if not os.path.exists(jsondir):
os.makedirs(jsondir)
if not os.path.exists(datadir):
os.makedirs(datadir)
self.period = 2 # weeks
self.file = file
self.persist = persist
self.restart = restart
if not restart and persist and os.path.exists(file):
self.logger.info('Reading session from file')
file = open(self.file, 'rb')
session_dump = file.read()
self.session = pickle.loads(session_dump)
file.close()
else:
self.session = requests.Session()
pass
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
if self.persist:
self.logger.info('Writing session to file')
session_dump = pickle.dumps(self.session)
file = open(self.file, 'wb')
file.write(session_dump)
file.close()
def isLoggedIn(self):
self.logger.info('Checking login status')
result = self.session.get('https://flow.polar.com/training/')
return result.status_code is 200
def login(self, email, password):
if not self.restart and self.isLoggedIn():
self.logger.info('Skip login')
return True
self.logger.info('Logging in')
result = self.session.post(
'https://flow.polar.com/login',
data = {
'email' : email,
'password' : password
},
verify = True
)
return result.status_code is 200
def generateRanges(self, start, end, period = None, format = None):
period = period or self.period
format = format or self.format
end_tmp = start
while end_tmp < end:
start = end_tmp + timedelta(days = 1)
end_tmp = start + timedelta(days = 7 * period)
start_f = start.strftime(format)
end_f = min(end, end_tmp).strftime(format)
yield (start_f, end_f)
def getEventsInRange(self, start, end):
ranges = self.generateRanges(start, end)
for range in ranges:
url = 'https://flow.polar.com/training/getCalendarEvents?start=%s&end=%s' % range
result = self.session.get(url)
if result.status_code is 200:
filename = '{}/{} - {}.json'.format(self.jsondir, range[0], range[1])
self.logger.info('Writing event json to %s' % filename)
file = open(filename, 'wb')
file.write(result.text.encode('latin-1'))
file.close()
def downloadTraining(self, id):
types = ('tcx', 'csv', 'gpx')
for type in types:
url = 'https://flow.polar.com/training/analysis/%d/export/%s/%s' % (id, type, str(self.zip).lower())
result = self.session.get(url)
if result.status_code is 200:
content_disposition = result.headers['Content-Disposition']
match = re.search('filename="([^"]+)";', content_disposition)
if match is not None:
filename = '{}/{}'.format(self.datadir, match.group(1))
self.logger.info('Writing training to {}'.format(filename))
file = open(filename, 'wb')
file.write(result.text.encode('latin-1'))
file.close()
def parseCalenderEvents(self):
for root, dirs, filenames in os.walk(self.jsondir):
for filename in filenames:
self.logger.info('Parsing file %s' % filename)
file = open('{}/{}'.format(root, filename), 'r')
contents = json.load(StringIO(file.read()))
file.close()
for item in contents:
self.downloadTraining(item['listItemId'])
def processTraining(self, session):
proc = subprocess.Popen(['RScript','test.R', session], stdout = subprocess.PIPE, universal_newlines = True)
while True:
line = proc.stdout.readline()
if line != '':
print("test:", line.rstrip())
else:
break