diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 7cd30d33..1337e3a6 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -5,7 +5,7 @@ from rowingdata import rowingdata as rrdata from rowers.tasks import handle_sendemail_unrecognized from rowers.tasks import handle_zip_file - +import pytz from rowingdata import rower as rrower from rowingdata import main as rmain @@ -49,6 +49,8 @@ import datautils from utils import lbstoN from scipy.interpolate import griddata +from timezonefinder import TimezoneFinder + import django_rq queue = django_rq.get_queue('default') queuelow = django_rq.get_queue('low') @@ -566,14 +568,45 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower', #summary += '\n' #summary += row.intervalstats() - workoutdate = row.rowdatetime.strftime('%Y-%m-%d') - workoutstarttime = row.rowdatetime.strftime('%H:%M:%S') #workoutstartdatetime = row.rowdatetime + timezone_str = 'UTC' try: - workoutstartdatetime = thetimezone.localize(row.rowdatetime).astimezone(utc) + workoutstartdatetime = timezone.make_aware(row.rowdatetime) except ValueError: workoutstartdatetime = row.rowdatetime + + + try: + latavg = row.df[' latitude'].mean() + lonavg = row.df[' longitude'].mean() + tf = TimezoneFinder() + timezone_str = tf.timezone_at(lng=lonavg,lat=latavg) + if timezone_str == None: + timezone_str = tf.closest_timezone_at(lng=lonavg, + lat=latavg) + if timezone_str == None: + timezone_str = 'UTC' + try: + workoutstartdatetime = pytz.timezone(timezone_str).localize( + row.rowdatetime + ) + except ValueError: + workoutstartdatetime = workoutstartdatetime.astimezone( + pytz.timezone(timezone_str) + ) + except KeyError: + timezone_str = 'UTC' + + + + workoutdate = workoutstartdatetime.astimezone( + pytz.timezone(timezone_str) + ).strftime('%Y-%m-%d') + workoutstarttime = workoutstartdatetime.astimezone( + pytz.timezone(timezone_str) + ).strftime('%H:%M:%S') + if makeprivate: privacy = 'hidden' else: @@ -604,6 +637,7 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower', maxhr=maxhr,averagehr=averagehr, startdatetime=workoutstartdatetime, inboard=inboard,oarlength=oarlength, + timezone=timezone_str, privacy=privacy) diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 408f6ab2..71674fbb 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -729,6 +729,8 @@ def leaflet_chart(lat,lon,name=""): id: 'mapbox.outdoors' }}); + + var mymap = L.map('map_canvas', {{ center: [{latmean}, {lonmean}], zoom: 13, @@ -777,6 +779,111 @@ def leaflet_chart(lat,lon,name=""): + return script,div + +def leaflet_chart2(lat,lon,name=""): + if lat.empty or lon.empty: + return [0,"invalid coordinate data"] + + latmean = lat.mean() + lonmean = lon.mean() + latbegin = lat[lat.index[0]] + longbegin = lon[lon.index[0]] + latend = lat[lat.index[-1]] + longend = lon[lon.index[-1]] + + coordinates = zip(lat,lon) + + scoordinates = "[" + + for x,y in coordinates: + scoordinates += """[{x},{y}], + """.format( + x=x, + y=y + ) + + scoordinates += "]" + + script = """ + + """.format( + latmean=latmean, + lonmean=lonmean, + latbegin = latbegin, + latend=latend, + longbegin=longbegin, + longend=longend, + scoordinates=scoordinates, + ) + + div = """ +

 

+ """ + + + return script,div def googlemap_chart(lat,lon,name=""): diff --git a/rowers/templates/basebase.html b/rowers/templates/basebase.html index 1e3cdb3a..9b2d9e79 100644 --- a/rowers/templates/basebase.html +++ b/rowers/templates/basebase.html @@ -17,6 +17,9 @@ + + + diff --git a/rowers/urls.py b/rowers/urls.py index 3f6f005d..0bc81cb6 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -187,6 +187,7 @@ urlpatterns = [ url(r'^workout/compare2/(?P\d+)/(?P\d+)/(?P\w+.*)/(?P\w+.*)/$',views.workout_comparison_view), url(r'^workout/compare/(?P\d+)/(?P\d+-\d+-\d+)/(?P\w+.*)$',views.workout_comparison_list), url(r'^workout/(?P\d+)/edit$',views.workout_edit_view), + url(r'^workout/(?P\d+)/navionics$',views.workout_edit_view_navionics), url(r'^workout/(?P\d+)/setprivate$',views.workout_setprivate_view), url(r'^workout/(?P\d+)/updatecp$',views.workout_update_cp_view), url(r'^workout/(?P\d+)/makepublic$',views.workout_makepublic_view), diff --git a/rowers/views.py b/rowers/views.py index 84fd47b2..fe3635c0 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -3,6 +3,7 @@ import colorsys import timestring import zipfile import bleach +import arrow import pytz import operator import warnings @@ -464,7 +465,7 @@ def add_workout_from_strokedata(user,importid,data,strokedata, except: title = 'Imported' - starttimeunix = mktime(rowdatetime.utctimetuple()) + starttimeunix = arrow.get(rowdatetime).timestamp res = make_cumvalues(0.1*strokedata['t']) cum_time = res[0] @@ -618,9 +619,10 @@ def add_workout_from_runkeeperdata(user,importid,data): except: rowdatetime = datetime.datetime.strptime(data['date'],"%Y-%m-%d %H:%M:%S") rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc) - starttimeunix = mktime(rowdatetime.utctimetuple()) + starttimeunix = arrow.get(rowdatetime).timestamp + #starttimeunix = mktime(rowdatetime.utctimetuple()) starttimeunix += utcoffset*3600 - + try: title = data['name'] @@ -670,9 +672,17 @@ def add_workout_from_runkeeperdata(user,importid,data): distseries = pd.Series(distance,index=times_distance) distseries = distseries.groupby(distseries.index).first() latseries = pd.Series(latcoord,index=times_location) - latseries = latseries.groupby(latseries.index).first() + try: + latseries = latseries.groupby(latseries.index).first() + except TypeError: + latseries = 0.0*distseries + lonseries = pd.Series(loncoord,index=times_location) - lonseries = lonseries.groupby(lonseries.index).first() + try: + lonseries = lonseries.groupby(lonseries.index).first() + except TypeError: + lonseries = 0.0*distseries + spmseries = pd.Series(spm,index=times_spm) spmseries = spmseries.groupby(spmseries.index).first() hrseries = pd.Series(hr,index=times_hr) @@ -761,12 +771,8 @@ def add_workout_from_stdata(user,importid,data): comments = data['comments'] except: comments = '' - - try: - thetimezone = tz(data['timezone']) - except: - thetimezone = 'UTC' + r = getrower(user) try: rowdatetime = iso8601.parse_date(data['start_time']) @@ -781,9 +787,8 @@ def add_workout_from_stdata(user,importid,data): except: rowdatetime = datetime.datetime.strptime(data['date'],"%Y-%m-%d %H:%M:%S") rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc) - starttimeunix = mktime(rowdatetime.utctimetuple()) - - + starttimeunix = arrow.get(rowdatetime).timestamp + try: title = data['name'] except: @@ -944,7 +949,8 @@ def add_workout_from_underarmourdata(user,importid,data): except: rowdatetime = datetime.datetime.strptime(data['date'],"%Y-%m-%d %H:%M:%S") rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc) - starttimeunix = mktime(rowdatetime.utctimetuple()) + starttimeunix = arrow.get(rowdatetime).timestamp + #starttimeunix = mktime(rowdatetime.utctimetuple()) try: @@ -4782,8 +4788,9 @@ def workout_downloadwind_view(request,id=0, avgtime = int(rowdata.df['TimeStamp (sec)'].mean()-rowdata.df.ix[0,'TimeStamp (sec)']) startdatetime = dateutil.parser.parse("{}, {}".format(row.date, row.starttime)) - - starttimeunix = int(mktime(startdatetime.utctimetuple())) + + starttimeunix = int(arrow.get(startdatetime).timestamp) + #starttimeunix = int(mktime(startdatetime.utctimetuple())) avgtime = starttimeunix+avgtime winddata = get_wind_data(avglat,avglon,avgtime) windspeed = winddata[0] @@ -4852,7 +4859,8 @@ def workout_downloadmetar_view(request,id=0, startdatetime = dateutil.parser.parse("{}, {}".format(row.date, row.starttime)) - starttimeunix = int(mktime(startdatetime.utctimetuple())) + starttimeunix = arrow.get(startdatetime).timestamp + #starttimeunix = int(mktime(startdatetime.utctimetuple())) avgtime = starttimeunix+avgtime winddata = get_metar_data(airportcode,avgtime) windspeed = winddata[0] @@ -6275,7 +6283,7 @@ def workout_edit_view(request,id=0,message="",successmessage=""): "%Y-%m-%d %H:%M:%S") startdatetime = timezone.make_aware(startdatetime) startdatetime = startdatetime.astimezone(pytz.timezone(thetimezone)) - print startdatetime + # check if user is owner of this workout if checkworkoutuser(request.user,row): @@ -6397,6 +6405,175 @@ def workout_edit_view(request,id=0,message="",successmessage=""): return HttpResponseRedirect(url) +# The basic edit page +@login_required() +def workout_edit_view_navionics(request,id=0,message="",successmessage=""): + request.session[translation.LANGUAGE_SESSION_KEY] = USER_LANGUAGE + request.session['referer'] = absolute(request)['PATH'] + + + try: + # check if valid ID exists (workout exists) + row = Workout.objects.get(id=id) + form = WorkoutForm(instance=row) + except Workout.DoesNotExist: + raise Http404("Workout doesn't exist") + + if request.method == 'POST': + # Form was submitted + form = WorkoutForm(request.POST) + if form.is_valid(): + # Get values from form + name = form.cleaned_data['name'] + date = form.cleaned_data['date'] + starttime = form.cleaned_data['starttime'] + workouttype = form.cleaned_data['workouttype'] + duration = form.cleaned_data['duration'] + distance = form.cleaned_data['distance'] + notes = form.cleaned_data['notes'] + thetimezone = form.cleaned_data['timezone'] + try: + boattype = request.POST['boattype'] + except KeyError: + boattype = Workout.objects.get(id=id).boattype + try: + privacy = request.POST['privacy'] + except KeyError: + privacy = Workout.objects.get(id=id).privacy + try: + rankingpiece = form.cleaned_data['rankingpiece'] + except KeyError: + rankingpiece =- Workout.objects.get(id=id).rankingpiece + + startdatetime = (str(date) + ' ' + str(starttime)) + startdatetime = datetime.datetime.strptime(startdatetime, + "%Y-%m-%d %H:%M:%S") + startdatetime = timezone.make_aware(startdatetime) + startdatetime = startdatetime.astimezone(pytz.timezone(thetimezone)) + + + # 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.rankingpiece = rankingpiece + row.timezone = thetimezone + try: + row.save() + except IntegrityError: + pass + # 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" + messages.info(request,successmessage) + url = reverse(workout_edit_view, + kwargs = { + 'id':str(row.id), + }) + response = HttpResponseRedirect(url) + else: + message = "You are not allowed to change this workout" + messages.error(request,message) + url = reverse(workouts_view) + + 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 + + comments = WorkoutComment.objects.filter(workout=row) + + aantalcomments = len(comments) + + if (checkworkoutuser(request.user,row)==False): + raise Http404("You are not allowed to edit this workout") + + # create interactive plot + f1 = row.csvfilename + u = row.user.user + r = getrower(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: + mapscript,mapdiv = leaflet_chart2(rowdata.df[' latitude'], + rowdata.df[' longitude'], + row.name) + + #res = googlemap_chart(rowdata.df[' latitude'], + # rowdata.df[' longitude'], + # row.name) + #gmscript = res[0] + #gmdiv = res[1] + + else: + mapscript = "" + mapdiv = "" + + + # render page + if (len(g)<=3): + return render(request, 'workout_form.html', + {'form':form, + 'workout':row, + 'teams':get_my_teams(request.user), + 'graphs1':g[0:3], + 'mapscript':mapscript, + 'aantalcomments':aantalcomments, + 'mapdiv':mapdiv, + }) + + else: + return render(request, 'workout_form.html', + {'form':form, + 'teams':get_my_teams(request.user), + 'workout':row, + 'graphs1':g[0:3], + 'graphs2':g[3:6], + 'mapscript':mapscript, + 'aantalcomments':aantalcomments, + 'mapdiv':mapdiv, + }) + + + return HttpResponseRedirect(url) + + + # Create the chart image with wind corrected pace (OTW) @user_passes_test(ispromember,login_url="/",redirect_field_name=None) def workout_add_otw_powerplot_view(request,id): diff --git a/templates/basebase.html b/templates/basebase.html index 65d611f9..a627ad15 100644 --- a/templates/basebase.html +++ b/templates/basebase.html @@ -32,9 +32,11 @@ {% block meta %} {% endblock %} {% leaflet_js %} {% leaflet_css %} + + {% analytical_head_bottom %} - + {% analytical_body_top %} {% block body_top %}{% endblock %}