diff --git a/rowers/dataprepnodjango.py b/rowers/dataprepnodjango.py
index 8872d4e7..af17d87a 100644
--- a/rowers/dataprepnodjango.py
+++ b/rowers/dataprepnodjango.py
@@ -18,6 +18,7 @@ from rowsandall_app.settings import DATABASES
from utils import lbstoN
+
user = DATABASES['default']['USER']
password = DATABASES['default']['PASSWORD']
database_name = DATABASES['default']['NAME']
@@ -335,6 +336,7 @@ def handle_nonpainsled(f2,fileformat,summary=''):
return (f2,summary,oarlength,inboard)
+
# Create new workout from file and store it in the database
# This routine should be used everywhere in views.py and mailprocessing.py
# Currently there is code duplication
diff --git a/rowers/templates/c2_list_import2.html b/rowers/templates/c2_list_import2.html
index 03f2d8e7..886542be 100644
--- a/rowers/templates/c2_list_import2.html
+++ b/rowers/templates/c2_list_import2.html
@@ -6,36 +6,50 @@
{% block content %}
Available on C2 Logbook
- {% if workouts %}
-
-
-
- | Import |
- Date/Time |
- Duration |
- Total Distance |
- Type |
- Source |
- Comment |
-
-
-
- {% for workout in workouts %}
-
- |
-Import |
- {{ workout|lookup:'starttime' }} |
- {{ workout|lookup:'duration' }} |
- {{ workout|lookup:'distance' }} |
- {{ workout|lookup:'rowtype' }} |
- {{ workout|lookup:'source' }} |
- {{ workout|lookup:'comment' }} |
-
-
- {% endfor %}
-
-
- {% else %}
- No workouts found
- {% endif %}
+
+{% if workouts %}
+
+
+
This imports all workouts that have not been imported to rowsandall.com.
+ The action may take a longer time to process, so please be patient. Click on Import in the list below to import an individual workout.
+
+
+
+
+
+
+
+ | Import |
+ Date/Time |
+ Duration |
+ Total Distance |
+ Type |
+ Source |
+ Comment |
+ New |
+
+
+
+ {% for workout in workouts %}
+
+ |
+ Import |
+ {{ workout|lookup:'starttime' }} |
+ {{ workout|lookup:'duration' }} |
+ {{ workout|lookup:'distance' }} |
+ {{ workout|lookup:'rowtype' }} |
+ {{ workout|lookup:'source' }} |
+ {{ workout|lookup:'comment' }} |
+ {{ workout|lookup:'new' }} |
+
+
+ {% endfor %}
+
+
+
+{% else %}
+ No workouts found
+{% endif %}
{% endblock %}
diff --git a/rowers/templates/sporttracks_list_import.html b/rowers/templates/sporttracks_list_import.html
index 96a2aa2d..b547efc8 100644
--- a/rowers/templates/sporttracks_list_import.html
+++ b/rowers/templates/sporttracks_list_import.html
@@ -6,34 +6,47 @@
{% block content %}
Available on SportTracks
- {% if workouts %}
-
-
-
- | Import |
- Name |
- Date/Time |
- Duration |
- Total Distance |
- Type |
-
-
-
- {% for workout in workouts %}
-
- |
-Import |
- {{ workout|lookup:'name' }} |
- {{ workout|lookup:'starttime' }} |
- {{ workout|lookup:'duration' }} |
- {{ workout|lookup:'distance' }} m |
- {{ workout|lookup:'type' }} |
-
-
- {% endfor %}
-
-
- {% else %}
- No workouts found
- {% endif %}
+{% if workouts %}
+
+
+
This imports all workouts that have not been imported to rowsandall.com.
+ The action may take a longer time to process, so please be patient. Click on Import in the list below to import an individual workout.
+
+
+
+
+
+
+
+ | Import |
+ Name |
+ Date/Time |
+ Duration |
+ Total Distance |
+ Type |
+ New |
+
+
+
+ {% for workout in workouts %}
+
+ |
+ Import |
+ {{ workout|lookup:'name' }} |
+ {{ workout|lookup:'starttime' }} |
+ {{ workout|lookup:'duration' }} |
+ {{ workout|lookup:'distance' }} m |
+ {{ workout|lookup:'type' }} |
+ {{ workout|lookup:'new' }} |
+
+
+ {% endfor %}
+
+
+
+{% else %}
+ No workouts found
+{% endif %}
{% endblock %}
diff --git a/rowers/urls.py b/rowers/urls.py
index dbb5fcd9..ec5d73a4 100644
--- a/rowers/urls.py
+++ b/rowers/urls.py
@@ -211,9 +211,11 @@ urlpatterns = [
url(r'^workout/c2import/$',views.workout_c2import_view),
url(r'^workout/stravaimport/$',views.workout_stravaimport_view),
url(r'^workout/c2import/(?P\d+)/$',views.workout_getc2workout_view),
+ url(r'^workout/c2import/all/$',views.workout_getc2workout_all),
url(r'^workout/stravaimport/(?P\d+)/$',views.workout_getstravaworkout_view),
url(r'^workout/sporttracksimport/$',views.workout_sporttracksimport_view),
url(r'^workout/sporttracksimport/(?P\d+)/$',views.workout_getsporttracksworkout_view),
+ url(r'^workout/sporttracksimport/all/$',views.workout_getsporttracksworkout_all),
url(r'^workout/runkeeperimport/$',views.workout_runkeeperimport_view),
url(r'^workout/runkeeperimport/(?P\d+)/$',views.workout_getrunkeeperworkout_view),
url(r'^workout/underarmourimport/$',views.workout_underarmourimport_view),
diff --git a/rowers/utils.py b/rowers/utils.py
index b700cba3..b78310cd 100644
--- a/rowers/utils.py
+++ b/rowers/utils.py
@@ -4,6 +4,21 @@ import numpy as np
lbstoN = 4.44822
+def uniqify(seq, idfun=None):
+ # order preserving
+ if idfun is None:
+ def idfun(x): return x
+ seen = {}
+ result = []
+ for item in seq:
+ marker = idfun(item)
+ # in old Python versions:
+ # if seen.has_key(marker)
+ # but in new ones:
+ if marker in seen: continue
+ seen[marker] = 1
+ result.append(item)
+ return result
def serialize_list(value,token=','):
assert(isinstance(value, list) or isinstance(value, tuple) or isinstance(value,np.ndarray))
diff --git a/rowers/views.py b/rowers/views.py
index 376fa0d1..460ef645 100644
--- a/rowers/views.py
+++ b/rowers/views.py
@@ -267,7 +267,7 @@ def splitstdata(lijst):
return [np.array(t),np.array(latlong)]
-from utils import geo_distance,serialize_list,deserialize_list
+from utils import geo_distance,serialize_list,deserialize_list,uniqify
from rowers.models import checkworkoutuser
# Check if a user is a Coach member
@@ -5764,15 +5764,25 @@ def workout_sporttracksimport_view(request,message=""):
return HttpResponseRedirect(url)
else:
workouts = []
+ r = Rower.objects.get(user=request.user)
+ stids = [int(getidfromsturi(item['uri'])) for item in res.json()['items']]
+ knownstids = uniqify([
+ w.uploadedtosporttracks for w in Workout.objects.filter(user=r)
+ ])
+ newids = [stid for stid in stids if not stid in knownstids]
for item in res.json()['items']:
d = int(float(item['total_distance']))
- i = getidfromsturi(item['uri'])
+ i = int(getidfromsturi(item['uri']))
+ if i in knownstids:
+ nnn = ''
+ else:
+ nnn = 'NEW'
n = item['name']
ttot = str(datetime.timedelta(seconds=int(float(item['duration']))))
s = item['start_time']
r = item['type']
- keys = ['id','distance','duration','starttime','type','name']
- values = [i,d,ttot,s,r,n]
+ keys = ['id','distance','duration','starttime','type','name','new']
+ values = [i,d,ttot,s,r,n,nnn]
res = dict(zip(keys,values))
workouts.append(res)
return render(request,'sporttracks_list_import.html',
@@ -5823,7 +5833,58 @@ def c2listdebug_view(request,message=""):
{'workouts':workouts,
'teams':get_my_teams(request.user),
})
-
+
+# Import all unknown workouts available on Concept2 logbook
+@login_required()
+def workout_getc2workout_all(request,message=""):
+ try:
+ thetoken = c2_open(request.user)
+ except C2NoTokenError:
+ return HttpResponseRedirect("/rowers/me/c2authorize/")
+
+ res = c2stuff.get_c2_workout_list(request.user)
+
+ if (res.status_code != 200):
+ message = "Something went wrong in workout_c2import_view (C2 token refresh)"
+ messages.error(request,message)
+ else:
+ r = Rower.objects.get(user=request.user)
+ c2ids = [item['id'] for item in res.json()['data']]
+ knownc2ids = uniqify([
+ w.uploadedtoc2 for w in Workout.objects.filter(user=r)
+ ])
+ newids = [c2id for c2id in c2ids if not c2id in knownc2ids]
+ for c2id in newids:
+ res = c2stuff.get_c2_workout(request.user,c2id)
+ if (res.status_code == 200):
+ data = res.json()['data']
+ splitdata = None
+ if 'workout' in data:
+ if 'splits' in data['workout']:
+ splitdata = data['workout']['splits']
+ if 'intervals' in data['workout']:
+ splitdata = data['workout']['intervals']
+
+ # Check if workout has stroke data, and get the stroke data
+ if data['stroke_data']:
+ res2 = c2stuff.get_c2_workout_strokes(request.user,c2id)
+ # We have stroke data
+ if res2.status_code == 200:
+ strokedata = pd.DataFrame.from_dict(res2.json()['data'])
+ # create the workout
+ id,message = add_workout_from_strokedata(
+ request.user,c2id,data,strokedata,
+ source='c2')
+ w = Workout.objects.get(id=id)
+ w.uploadedtoc2=c2id
+ w.save()
+ if message:
+ messages.error(request,message)
+
+ url = reverse(workouts_view)
+ return HttpResponseRedirect(url)
+
+
# List of workouts available on Concept2 logbook - for import
@login_required()
def workout_c2import_view(request,message=""):
@@ -5844,6 +5905,12 @@ def workout_c2import_view(request,message=""):
return HttpResponseRedirect(url)
else:
workouts = []
+ r = Rower.objects.get(user=request.user)
+ c2ids = [item['id'] for item in res.json()['data']]
+ knownc2ids = uniqify([
+ w.uploadedtoc2 for w in Workout.objects.filter(user=r)
+ ])
+ newids = [c2id for c2id in c2ids if not c2id in knownc2ids]
for item in res.json()['data']:
d = item['distance']
i = item['id']
@@ -5852,8 +5919,12 @@ def workout_c2import_view(request,message=""):
r = item['type']
s2 = item['source']
c = item['comments']
- keys = ['id','distance','duration','starttime','rowtype','source','comment']
- values = [i,d,ttot,s,r,s2,c]
+ if i in knownc2ids:
+ nnn = ''
+ else:
+ nnn = 'NEW'
+ keys = ['id','distance','duration','starttime','rowtype','source','comment','new']
+ values = [i,d,ttot,s,r,s2,c,nnn]
res = dict(zip(keys,values))
workouts.append(res)
@@ -5959,6 +6030,38 @@ def workout_getsporttracksworkout_view(request,sporttracksid):
})
return HttpResponseRedirect(url)
+# Imports all new workouts from SportTracks
+@login_required()
+def workout_getsporttracksworkout_all(request):
+ res = sporttracksstuff.get_sporttracks_workout_list(request.user)
+ if (res.status_code == 200):
+ r = Rower.objects.get(user=request.user)
+ stids = [int(getidfromsturi(item['uri'])) for item in res.json()['items']]
+ knownstids = uniqify([
+ w.uploadedtosporttracks for w in Workout.objects.filter(user=r)
+ ])
+ newids = [stid for stid in stids if not stid in knownstids]
+ for sporttracksid in newids:
+ res = sporttracksstuff.get_sporttracks_workout(
+ request.user,sporttracksid)
+ data = res.json()
+
+ id,message = add_workout_from_stdata(request.user,sporttracksid,data)
+ print sporttracksid,id
+ if id==0:
+ messages.error(request,message)
+
+ else:
+ w = Workout.objects.get(id=id)
+ w.uploadedtosporttracks=sporttracksid
+ print 'saved'
+ w.save()
+
+ url = reverse(workouts_view)
+ return HttpResponseRedirect(url)
+
+
+
# Imports a workout from Concept2
@login_required()
def workout_getc2workout_view(request,c2id):