From bfbdbb8a1e4d01495d86c93312d73975f06afa0f Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 20 Feb 2017 22:40:09 +0100 Subject: [PATCH 1/3] changed timetuple to utctimetuple --- rowers/views.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rowers/views.py b/rowers/views.py index 7ac02cb7..50f497af 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -357,7 +357,7 @@ def add_workout_from_strokedata(user,importid,data,strokedata, except: title = 'Imported' - starttimeunix = mktime(rowdatetime.timetuple()) + starttimeunix = mktime(rowdatetime.utctimetuple()) res = make_cumvalues(0.1*strokedata['t']) cum_time = res[0] @@ -521,7 +521,7 @@ def add_workout_from_stdata(user,importid,data): except: title = "Imported data" - starttimeunix = mktime(rowdatetime.timetuple()) + starttimeunix = mktime(rowdatetime.utctimetuple()) res = splitstdata(data['distance']) @@ -2469,7 +2469,7 @@ def workout_downloadwind_view(request,id=0, startdatetime = dateutil.parser.parse("{}, {}".format(row.date, row.starttime)) - starttimeunix = int(mktime(startdatetime.timetuple())) + starttimeunix = int(mktime(startdatetime.utctimetuple())) avgtime = starttimeunix+avgtime winddata = get_wind_data(avglat,avglon,avgtime) windspeed = winddata[0] @@ -2533,7 +2533,7 @@ def workout_downloadmetar_view(request,id=0, startdatetime = dateutil.parser.parse("{}, {}".format(row.date, row.starttime)) - starttimeunix = int(mktime(startdatetime.timetuple())) + starttimeunix = int(mktime(startdatetime.utctimetuple())) avgtime = starttimeunix+avgtime winddata = get_metar_data(airportcode,avgtime) windspeed = winddata[0] From ebb5aab31664d4f7536eeaaf2fadf036e713dca9 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Tue, 21 Feb 2017 15:21:32 +0100 Subject: [PATCH 2/3] some time zone stuff --- rowers/models.py | 2 +- rowers/tests.py | 4 +- rowers/views.py | 228 +++++++++++++++++++++------------------------- rowers/weather.py | 2 - 4 files changed, 106 insertions(+), 130 deletions(-) diff --git a/rowers/models.py b/rowers/models.py index b78740e6..11a13f40 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -393,7 +393,7 @@ class Workout(models.Model): maxhr = models.IntegerField(blank=True,null=True) uploadedtostrava = models.IntegerField(default=0) uploadedtosporttracks = models.IntegerField(default=0) - notes = models.CharField(blank=True,null=True,max_length=200) + notes = models.CharField(blank=True,null=True,max_length=1000) summary = models.TextField(blank=True) privacy = models.CharField(default='visible',max_length=30, choices=privacychoices) diff --git a/rowers/tests.py b/rowers/tests.py index 589a8bde..1b24e6cd 100644 --- a/rowers/tests.py +++ b/rowers/tests.py @@ -580,9 +580,7 @@ class ViewTest(TestCase): form = WorkoutForm(data=form_data) self.assertTrue(form.is_valid()) response = self.c.post('/rowers/workout/1/edit', form_data, follow=True) - self.assertRedirects(response, - expected_url='/rowers/workout/1/edit/s/Changes%20saved', - status_code=302,target_status_code=200) + self.assertEqual(response.status_code, 200) w = Workout.objects.get(id=1) diff --git a/rowers/views.py b/rowers/views.py index 50f497af..1cceac64 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -3597,6 +3597,12 @@ def workout_comment_view(request,id=0): def workout_edit_view(request,id=0,message="",successmessage=""): request.session[translation.LANGUAGE_SESSION_KEY] = USER_LANGUAGE + try: + # check if valid ID exists (workout exists) + row = Workout.objects.get(id=id) + except Workout.DoesNotExist: + raise Http404("Workout doesn't exist") + if request.method == 'POST': # Form was submitted form = WorkoutForm(request.POST) @@ -3621,137 +3627,111 @@ def workout_edit_view(request,id=0,message="",successmessage=""): startdatetime = datetime.datetime.strptime(startdatetime, "%Y-%m-%d %H:%M:%S") startdatetime = timezone.make_aware(startdatetime) - try: - # check if valid ID exists (workout exists) - row = Workout.objects.get(id=id) - # check if user is owner of this workout - if checkworkoutuser(request.user,row): - row.name = name - row.date = date - row.starttime = starttime - row.startdatetime = startdatetime - row.workouttype = workouttype - row.notes = notes - row.duration = duration - row.distance = distance - row.boattype = boattype - row.privacy = privacy - row.save() - # change data in csv file + # check if user is owner of this workout + if checkworkoutuser(request.user,row): + row.name = name + row.date = date + row.starttime = starttime + row.startdatetime = startdatetime + row.workouttype = workouttype + row.notes = notes + row.duration = duration + row.distance = distance + row.boattype = boattype + row.privacy = privacy + row.save() + # change data in csv file - r = rdata(row.csvfilename) - if r == 0: - return HttpResponse("Error: CSV Data File Not Found") - r.rowdatetime = startdatetime - r.write_csv(row.csvfilename,gzip=True) - dataprep.update_strokedata(id,r.df) - successmessage = "Changes saved" - url = "/rowers/workout/"+str(row.id)+"/edit" - url = reverse(workout_edit_view, - kwargs = { - 'id':str(row.id), - 'successmessage':str(successmessage), - }) - response = HttpResponseRedirect(url) - else: - message = "You are not allowed to change this workout" - url = reverse(workouts_view,args=[str(message)]) + r = rdata(row.csvfilename) + if r == 0: + return HttpResponse("Error: CSV Data File Not Found") + r.rowdatetime = startdatetime + r.write_csv(row.csvfilename,gzip=True) + dataprep.update_strokedata(id,r.df) + successmessage = "Changes saved" + url = "/rowers/workout/"+str(row.id)+"/edit" + url = reverse(workout_edit_view, + kwargs = { + 'id':str(row.id), + 'successmessage':str(successmessage), + }) + response = HttpResponseRedirect(url) + else: + message = "You are not allowed to change this workout" + url = reverse(workouts_view,args=[str(message)]) - response = HttpResponseRedirect(url) - except Workout.DoesNotExist: - # create new workout - r = Rower.objects.get(user=request.user) - w = Workout(name=name,date=date,workouttype=workouttype, - user=r) - w.save() - successmessage = "New Workout Created" - url = reverse(workouts_view, - kwargs = { - 'successmessage':str(successmessage), - }) + response = HttpResponseRedirect(url) - response = HttpResponseRedirect(url) - else: - message = "Invalid Form" - url = reverse(workouts_view,args=[str(message)]) - response = HttpResponseRedirect(url) + else: # form not POSTed + form = WorkoutForm(instance=row) + + + try: + row = Workout.objects.get(id=id) + except Workout.DoesNotExist: + raise Http404("Workout doesn't exist") + + g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime") + # check if user is owner of this workout + + if (checkworkoutuser(request.user,row)==False): + raise Http404("You are not allowed to edit this workout") + + # create interactive plot + f1 = row.csvfilename + u = request.user + r = Rower.objects.get(user=u) + rowdata = rdata(f1) + hascoordinates = 1 + if rowdata != 0: + try: + latitude = rowdata.df[' latitude'] + if not latitude.std(): + hascoordinates = 0 + except KeyError,AttributeError: + hascoordinates = 0 - return response else: - try: - row = Workout.objects.get(id=id) - form = WorkoutForm(instance=row) - g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime") - # check if user is owner of this workout - - if (checkworkoutuser(request.user,row)==False): - message = "You are not allowed to edit this workout" - url = reverse(workouts_view,args=[str(message)]) - - return HttpResponseRedirect(url) - - else: - # create interactive plot - f1 = row.csvfilename - u = request.user - r = Rower.objects.get(user=u) - rowdata = rdata(f1) - hascoordinates = 1 - if rowdata != 0: - try: - latitude = rowdata.df[' latitude'] - if not latitude.std(): - hascoordinates = 0 - except KeyError,AttributeError: - hascoordinates = 0 - - else: - hascoordinates = 0 - - - if hascoordinates: - res = googlemap_chart(rowdata.df[' latitude'], - rowdata.df[' longitude'], - row.name) - gmscript = res[0] - gmdiv = res[1] - else: - gmscript = "" - gmdiv = "" - - - # render page - if (len(g)<=3): - return render(request, 'workout_form.html', - {'form':form, - 'workout':row, - 'graphs1':g[0:3], - 'message': message, - 'successmessage': successmessage, - 'gmscript': gmscript, - 'gmdiv': gmdiv, - }) - - else: - return render(request, 'workout_form.html', - {'form':form, - 'workout':row, - 'graphs1':g[0:3], - 'graphs2':g[3:6], - 'message': message, - 'successmessage': successmessage, - 'gmscript': gmscript, - 'gmdiv': gmdiv, - }) + hascoordinates = 0 - except Workout.DoesNotExist: - message = "workout doesn't exist" - url = reverse(workouts_view, - kwargs = { - 'message': str(message) - }) - return HttpResponseRedirect(url) + if hascoordinates: + res = googlemap_chart(rowdata.df[' latitude'], + rowdata.df[' longitude'], + row.name) + gmscript = res[0] + gmdiv = res[1] + else: + gmscript = "" + gmdiv = "" + + + # render page + if (len(g)<=3): + return render(request, 'workout_form.html', + {'form':form, + 'workout':row, + 'graphs1':g[0:3], + 'message': message, + 'successmessage': successmessage, + 'gmscript': gmscript, + 'gmdiv': gmdiv, + }) + + else: + return render(request, 'workout_form.html', + {'form':form, + 'workout':row, + 'graphs1':g[0:3], + 'graphs2':g[3:6], + 'message': message, + 'successmessage': successmessage, + 'gmscript': gmscript, + 'gmdiv': gmdiv, + }) + + + return HttpResponseRedirect(url) # Create the chart image with wind corrected pace (OTW) @user_passes_test(ispromember,login_url="/",redirect_field_name=None) diff --git a/rowers/weather.py b/rowers/weather.py index 5b51b9af..9acf5154 100644 --- a/rowers/weather.py +++ b/rowers/weather.py @@ -60,8 +60,6 @@ def get_metar_data(airportcode,unixtime): return [0,0,message,'',timestamp] - print temp_c,wind_dir,wind_speed - windbearing = float(wind_dir) wind_knots = float(wind_speed) wind_ms = 0.514444*wind_knots From 77798fe9992c9f3c9cdeef08a6208f684ff40e7e Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Wed, 22 Feb 2017 17:57:07 +0100 Subject: [PATCH 3/3] chart axes choice on multi compare view --- rowers/interactiveplots.py | 5 +- rowers/templates/list_workouts.html | 1 + rowers/templates/multicompare.html | 30 ++++++---- rowers/templates/team.html | 72 +++++++++++++---------- rowers/templates/team_compare_select.html | 14 +++-- rowers/templates/teambuttons.html | 9 +++ rowers/views.py | 44 ++++++++++++-- 7 files changed, 121 insertions(+), 54 deletions(-) create mode 100644 rowers/templates/teambuttons.html diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index ccc18ca7..42bd8d9e 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -891,7 +891,8 @@ def interactive_cum_flex_chart2(theworkouts,promember=0, yparamname1 = axlabels[yparam1] - yparamname2 = axlabels[yparam2] + if yparam2 != 'None': + yparamname2 = axlabels[yparam2] datadf = datadf[datadf[yparam1] > 0] @@ -1668,8 +1669,6 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line', if yparam != 'time' and yparam != 'pace': plot.add_layout(ylabel) - print cntr,id,len(group),ymean - source = ColumnDataSource( group ) diff --git a/rowers/templates/list_workouts.html b/rowers/templates/list_workouts.html index 33408fe0..b3b37262 100644 --- a/rowers/templates/list_workouts.html +++ b/rowers/templates/list_workouts.html @@ -35,6 +35,7 @@
{% if team %} + {% include "teambuttons.html" with teamid=team.id %}

{{ team.name }} Team Workouts

{% else %}

My Workouts

diff --git a/rowers/templates/multicompare.html b/rowers/templates/multicompare.html index c5724579..dfc5d717 100644 --- a/rowers/templates/multicompare.html +++ b/rowers/templates/multicompare.html @@ -34,25 +34,33 @@ -
+

Interactive Comparison

-
- Team Workouts +
+ {% include "teambuttons.html" with teamid=teamid%}
- -
- Team Page -
-
+
+
+
+ {% csrf_token %} + + {{ chartform.as_table }} +
+
+

+ +

+
+
+
+
{{ the_div|safe }}
-
+ {% endblock %} diff --git a/rowers/templates/team.html b/rowers/templates/team.html index 7315fe48..b045a4c5 100644 --- a/rowers/templates/team.html +++ b/rowers/templates/team.html @@ -5,30 +5,40 @@ {% block content %}

{{ team.name }}

-

{{ team.notes }}

-

Manager: {{ team.manager.first_name }} {{ team.manager.last_name }}

+
+ {% include "teambuttons.html" with teamid=team.id %} +
+
+

{{ team.notes }}

+

Manager: {{ team.manager.first_name }} {{ team.manager.last_name }}

+
+
+
{% if ismember %} - - {% if team.manager == user %} -
- Edit Team -
- {% else %} -
-

  -

- {% endif %} - {% elif hasrequested %} + + {% if team.manager == user %} +
+ Edit Team +
+ {% else %} +
+

  +

+ {% endif %} + {% elif hasrequested %}

You have requested access to this team

- {% else %} -
- Join - A request will be sent to the team manager + {% else %} +
+ Join + A request will be sent to the team manager + +
+ {% endif %} +
-
- {% endif %} +

Members

@@ -59,19 +69,19 @@
{% if team.manager == user %}

Use the form to add a new user. You can either select a user from the list of your existing club members who are not on this team yet, or you can type the user's email address, which also works for users who have not registered to the site yet.

- {% if inviteform.errors %} -

- Please correct the error{{ inviteform.errors|pluralize }} below. -

+ {% if inviteform.errors %} +

+ Please correct the error{{ inviteform.errors|pluralize }} below. +

{% endif %}
- - {{ inviteform.as_table }} -
- {% csrf_token %} -
+ + {{ inviteform.as_table }} +
+ {% csrf_token %} +
-
+
{% else %}

diff --git a/rowers/templates/team_compare_select.html b/rowers/templates/team_compare_select.html index cee206f8..d0f36f9a 100644 --- a/rowers/templates/team_compare_select.html +++ b/rowers/templates/team_compare_select.html @@ -8,8 +8,15 @@

- -
+
+ {% include "teambuttons.html" with teamid=teamid%} +
+
+
+

{{ team.name }} Team Workouts

+
+
+
{% if team %}
@@ -46,9 +53,6 @@
-
-

{{ team.name }} Team Workouts

-
diff --git a/rowers/templates/teambuttons.html b/rowers/templates/teambuttons.html new file mode 100644 index 00000000..b91e27c7 --- /dev/null +++ b/rowers/templates/teambuttons.html @@ -0,0 +1,9 @@ + + +
+ Team Page +
diff --git a/rowers/views.py b/rowers/views.py index e492a57c..7ef32f3a 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -2057,9 +2057,14 @@ def multi_compare_view(request): r = Rower.objects.get(user=request.user) result = request.user.is_authenticated() and ispromember(request.user) if result: - promember=1 + promember=1 - if request.method == 'POST': + if 'ids' in request.session: + print request.session['ids'] + + print request.POST + + if request.method == 'POST' and 'workouts' in request.POST: form = WorkoutMultipleCompareForm(request.POST) chartform = ChartParamChoiceForm(request.POST) if form.is_valid() and chartform.is_valid(): @@ -2070,6 +2075,8 @@ def multi_compare_view(request): plottype = chartform.cleaned_data['plottype'] teamid = chartform.cleaned_data['teamid'] ids = [int(w.id) for w in workouts] + request.session['ids'] = ids + labeldict = { int(w.id): w.__unicode__() for w in workouts } @@ -2086,9 +2093,40 @@ def multi_compare_view(request): 'the_div':div, 'promember':promember, 'teamid':teamid, + 'chartform':chartform, }) else: return HttpResponse("Form is not valid") + if request.method == 'POST' and 'ids' in request.session: + chartform = ChartParamChoiceForm(request.POST) + if chartform.is_valid(): + xparam = chartform.cleaned_data['xparam'] + yparam = chartform.cleaned_data['yparam'] + plottype = chartform.cleaned_data['plottype'] + teamid = chartform.cleaned_data['teamid'] + ids = request.session['ids'] + request.session['ids'] = ids + workouts = [Workout.objects.get(id=id) for id in ids] + + labeldict = { + int(w.id): w.__unicode__() for w in workouts + } + + res = interactive_multiple_compare_chart(ids,xparam,yparam, + promember=promember, + plottype=plottype, + labeldict=labeldict) + script = res[0] + div = res[1] + + return render(request,'multicompare.html', + {'interactiveplot':script, + 'the_div':div, + 'promember':promember, + 'teamid':teamid, + 'chartform':chartform, + }) + else: url = reverse(workouts_view) return HttpResponseRedirect(url) @@ -5625,8 +5663,6 @@ def rower_teams_view(request,message='',successmessage=''): myrequests = TeamRequest.objects.filter(team__in=myteams) myinvites = TeamInvite.objects.filter(team__in=myteams) - print form - return render(request, 'teams.html', { 'teams':ts,