247 lines
6.8 KiB
Python
247 lines
6.8 KiB
Python
# for actions related to uploads
|
|
from django.conf import settings
|
|
from django.utils import timezone,translation
|
|
from rowers.tasks import (
|
|
handle_sendemail_unrecognized,handle_sendemailnewcomment,
|
|
handle_sendemailnewresponse, handle_updatedps,
|
|
handle_makeplot,handle_otwsetpower,handle_sendemailtcx,
|
|
handle_sendemailcsv
|
|
)
|
|
|
|
from rowers.models import GraphImage
|
|
|
|
import numpy as np
|
|
import yaml
|
|
import argparse
|
|
import yamllint
|
|
from subprocess import call
|
|
import re
|
|
|
|
try:
|
|
from cStringIO import StringIO
|
|
except:
|
|
from StringIO import StringIO
|
|
|
|
from rowers.utils import (
|
|
geo_distance,serialize_list,deserialize_list,uniqify,
|
|
str2bool,range_to_color_hex,absolute
|
|
)
|
|
|
|
def cleanbody(body):
|
|
p = re.compile('.*---\n([\s\S]*)...')
|
|
m = p.match(body)
|
|
if m != None:
|
|
body = m.group(1)
|
|
|
|
return body
|
|
|
|
def getsyncoptions(uploadoptions,values):
|
|
try:
|
|
value = values.lower()
|
|
values = [values]
|
|
except AttributeError:
|
|
pass
|
|
|
|
for v in values:
|
|
try:
|
|
v = v.lower()
|
|
|
|
if v in ['c2','concept2','logbook']:
|
|
uploadoptions['upload_to_C2'] = True
|
|
if v in ['tp','trainingpeaks']:
|
|
uploadoptions['upload_totp'] = True
|
|
if v in ['strava']:
|
|
uploadoptions['upload_to_Strava'] = True
|
|
if v in ['st','sporttracks']:
|
|
uploadoptions['upload_to_SportTracks'] = True
|
|
if v in ['rk','runkeeper']:
|
|
uploadoptions['upload_to_RunKeeper'] = True
|
|
if v in ['ua','underarmour','mapmyfitness']:
|
|
uploadoptions['upload_to_MapMyFitness'] = True
|
|
except AttributeError:
|
|
pass
|
|
|
|
return uploadoptions
|
|
|
|
def getplotoptions(uploadoptions,value):
|
|
try:
|
|
v = value.lower()
|
|
if v in ['pieplot','timeplot','distanceplot']:
|
|
uploadoptions['make_plot'] = True
|
|
uploadoptions['plottype'] = v
|
|
elif 'pie' in v:
|
|
uploadoptions['make_plot'] = True
|
|
uploadoptions['plottype'] = 'pieplot'
|
|
elif 'distance' in v:
|
|
uploadoptions['make_plot'] = True
|
|
uploadoptions['plottype'] = 'distanceplot'
|
|
elif 'time' in v:
|
|
uploadoptions['make_plot'] = True
|
|
uploadoptions['plottype'] = 'timeplot'
|
|
except TypeError:
|
|
pass
|
|
|
|
return uploadoptions
|
|
|
|
def getboolean(uploadoptions,value,key):
|
|
b = True
|
|
if not value:
|
|
b = False
|
|
if value in [False,'false','False',None,'no']:
|
|
b = False
|
|
|
|
uploadoptions[key] = b
|
|
|
|
return uploadoptions
|
|
|
|
def upload_options(body):
|
|
uploadoptions = {}
|
|
body = cleanbody(body)
|
|
try:
|
|
yml = (yaml.load(body))
|
|
try:
|
|
for key, value in yml.iteritems():
|
|
if key == 'sync' or key == 'synchronization':
|
|
uploadoptions = getsyncoptions(uploadoptions,value)
|
|
if key == 'chart' or key == 'static' or key == 'plot':
|
|
uploadoptions = getplotoptions(uploadoptions,value)
|
|
if 'priva' in key:
|
|
uploadoptions = getboolean(uploadoptions,value,'makeprivate')
|
|
except AttributeError:
|
|
pass
|
|
except yaml.YAMLError as exc:
|
|
pm = exc.problem_mark
|
|
strpm = str(pm)
|
|
pbm = "Your email has an issue on line {} at position {}. The error is: ".format(
|
|
pm.line+1,
|
|
pm.column+1,
|
|
)+strpm
|
|
return {'error':pbm}
|
|
|
|
return uploadoptions
|
|
|
|
def make_plot(r,w,f1,f2,plottype,title,imagename='',plotnr=0):
|
|
if imagename == '':
|
|
imagename = f1[:-4]+'.png'
|
|
fullpathimagename = 'static/plots/'+imagename
|
|
|
|
powerperc = 100*np.array([r.pw_ut2,
|
|
r.pw_ut1,
|
|
r.pw_at,
|
|
r.pw_tr,r.pw_an])/r.ftp
|
|
|
|
ftp = float(r.ftp)
|
|
if w.workouttype in ('water','coastal'):
|
|
ftp = ftp*(100.-r.otwslack)/100.
|
|
|
|
hrpwrdata = {
|
|
'hrmax':r.max,
|
|
'hrut2':r.ut2,
|
|
'hrut1':r.ut1,
|
|
'hrat':r.at,
|
|
'hrtr':r.tr,
|
|
'hran':r.an,
|
|
'ftp':ftp,
|
|
'powerperc':serialize_list(powerperc),
|
|
'powerzones':serialize_list(r.powerzones),
|
|
}
|
|
|
|
# make plot - asynchronous task
|
|
plotnrs = {
|
|
'timeplot':1,
|
|
'distanceplot':2,
|
|
'pieplot':3,
|
|
}
|
|
|
|
if plotnr == 0:
|
|
plotnr = plotnrs[plottype]
|
|
|
|
if w.workouttype in ('water','coastal'):
|
|
plotnr = plotnr+3
|
|
|
|
|
|
if settings.DEBUG:
|
|
res = handle_makeplot.delay(f1,f2,title,
|
|
hrpwrdata,plotnr,
|
|
imagename)
|
|
else:
|
|
res = queue.enqueue(handle_makeplot,f1,f2,
|
|
title,hrpwrdata,
|
|
plotnr,imagename)
|
|
|
|
|
|
i = GraphImage(workout=w,
|
|
creationdatetime=timezone.now(),
|
|
filename=fullpathimagename)
|
|
i.save()
|
|
|
|
return i.id
|
|
|
|
import c2stuff,stravastuff,sporttracksstuff,runkeeperstuff
|
|
import underarmourstuff,tpstuff
|
|
|
|
def make_private(w,options):
|
|
if 'makeprivate' in options and options['makeprivate']:
|
|
w.privacy = 'hidden'
|
|
w.save()
|
|
|
|
return 1
|
|
|
|
def do_sync(w,options):
|
|
if 'upload_to_C2' in options and options['upload_to_C2']:
|
|
try:
|
|
message,id = c2stuff.workout_c2_upload(w.user.user,w)
|
|
except C2NoTokenError:
|
|
id = 0
|
|
message = "Something went wrong with the Concept2 sync"
|
|
|
|
if 'upload_to_Strava' in options and options['upload_to_Strava']:
|
|
try:
|
|
message,id = stravastuff.workout_strava_upload(
|
|
w.user.user,w
|
|
)
|
|
except StravaNoTokenError:
|
|
id = 0
|
|
message = "Please connect to Strava first"
|
|
|
|
|
|
if 'upload_to_SportTracks' in options and options['upload_to_SportTracks']:
|
|
try:
|
|
message,id = sporttracksstuff.workout_sporttracks_upload(
|
|
w.user.user,w
|
|
)
|
|
except SportTracksNoTokenError:
|
|
message = "Please connect to SportTracks first"
|
|
id = 0
|
|
|
|
|
|
if 'upload_to_RunKeeper' in options and options['upload_to_RunKeeper']:
|
|
try:
|
|
message,id = runkeeperstuff.workout_runkeeper_upload(
|
|
w.user.user,w
|
|
)
|
|
except RunKeeperNoTokenError:
|
|
message = "Please connect to Runkeeper first"
|
|
id = 0
|
|
|
|
if 'upload_to_MapMyFitness' in options and options['upload_to_MapMyFitness']:
|
|
try:
|
|
message,id = underarmourstuff.workout_ua_upload(
|
|
w.user.user,w
|
|
)
|
|
except UnderArmourNoTokenError:
|
|
message = "Please connect to MapMyFitness first"
|
|
id = 0
|
|
|
|
|
|
if 'upload_to_TrainingPeaks' in options and options['upload_to_TrainingPeaks']:
|
|
try:
|
|
message,id = tpstuff.workout_tp_upload(
|
|
w.user.user,w
|
|
)
|
|
except TPNoTokenError:
|
|
message = "Please connect to TrainingPeaks first"
|
|
id = 0
|
|
|
|
return 1
|