Merge branch 'release/v3.69'
This commit is contained in:
+40
-4
@@ -5,7 +5,7 @@ from rowingdata import rowingdata as rrdata
|
|||||||
|
|
||||||
from rowers.tasks import handle_sendemail_unrecognized
|
from rowers.tasks import handle_sendemail_unrecognized
|
||||||
from rowers.tasks import handle_zip_file
|
from rowers.tasks import handle_zip_file
|
||||||
|
import pytz
|
||||||
from rowingdata import rower as rrower
|
from rowingdata import rower as rrower
|
||||||
from rowingdata import main as rmain
|
from rowingdata import main as rmain
|
||||||
|
|
||||||
@@ -49,6 +49,8 @@ import datautils
|
|||||||
from utils import lbstoN
|
from utils import lbstoN
|
||||||
from scipy.interpolate import griddata
|
from scipy.interpolate import griddata
|
||||||
|
|
||||||
|
from timezonefinder import TimezoneFinder
|
||||||
|
|
||||||
import django_rq
|
import django_rq
|
||||||
queue = django_rq.get_queue('default')
|
queue = django_rq.get_queue('default')
|
||||||
queuelow = django_rq.get_queue('low')
|
queuelow = django_rq.get_queue('low')
|
||||||
@@ -566,13 +568,46 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower',
|
|||||||
#summary += '\n'
|
#summary += '\n'
|
||||||
#summary += row.intervalstats()
|
#summary += row.intervalstats()
|
||||||
|
|
||||||
workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
|
|
||||||
workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
|
#workoutstartdatetime = row.rowdatetime
|
||||||
|
timezone_str = 'UTC'
|
||||||
try:
|
try:
|
||||||
workoutstartdatetime = thetimezone.localize(row.rowdatetime).astimezone(utc)
|
workoutstartdatetime = timezone.make_aware(row.rowdatetime)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
workoutstartdatetime = row.rowdatetime
|
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:
|
if makeprivate:
|
||||||
privacy = 'hidden'
|
privacy = 'hidden'
|
||||||
else:
|
else:
|
||||||
@@ -603,6 +638,7 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower',
|
|||||||
maxhr=maxhr,averagehr=averagehr,
|
maxhr=maxhr,averagehr=averagehr,
|
||||||
startdatetime=workoutstartdatetime,
|
startdatetime=workoutstartdatetime,
|
||||||
inboard=inboard,oarlength=oarlength,
|
inboard=inboard,oarlength=oarlength,
|
||||||
|
timezone=timezone_str,
|
||||||
privacy=privacy)
|
privacy=privacy)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -729,6 +729,8 @@ def leaflet_chart(lat,lon,name=""):
|
|||||||
id: 'mapbox.outdoors'
|
id: 'mapbox.outdoors'
|
||||||
}});
|
}});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var mymap = L.map('map_canvas', {{
|
var mymap = L.map('map_canvas', {{
|
||||||
center: [{latmean}, {lonmean}],
|
center: [{latmean}, {lonmean}],
|
||||||
zoom: 13,
|
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 = """
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
var streets = L.tileLayer('https://api.tiles.mapbox.com/v4/{{id}}/{{z}}/{{x}}/{{y}}.png?access_token=pk.eyJ1Ijoic2FuZGVycm9vc2VuZGFhbCIsImEiOiJjajY3aTRkeWQwNmx6MzJvMTN3andlcnBlIn0.MFG8Xt0kDeSA9j7puZQ9hA', {{
|
||||||
|
maxZoom: 18,
|
||||||
|
id: 'mapbox.streets'
|
||||||
|
}}),
|
||||||
|
|
||||||
|
satellite = L.tileLayer('https://api.tiles.mapbox.com/v4/{{id}}/{{z}}/{{x}}/{{y}}.png?access_token=pk.eyJ1Ijoic2FuZGVycm9vc2VuZGFhbCIsImEiOiJjajY3aTRkeWQwNmx6MzJvMTN3andlcnBlIn0.MFG8Xt0kDeSA9j7puZQ9hA', {{
|
||||||
|
maxZoom: 18,
|
||||||
|
id: 'mapbox.satellite'
|
||||||
|
}}),
|
||||||
|
|
||||||
|
outdoors = L.tileLayer('https://api.tiles.mapbox.com/v4/{{id}}/{{z}}/{{x}}/{{y}}.png?access_token=pk.eyJ1Ijoic2FuZGVycm9vc2VuZGFhbCIsImEiOiJjajY3aTRkeWQwNmx6MzJvMTN3andlcnBlIn0.MFG8Xt0kDeSA9j7puZQ9hA', {{
|
||||||
|
maxZoom: 18,
|
||||||
|
id: 'mapbox.outdoors'
|
||||||
|
}});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var mymap = L.map('map_canvas', {{
|
||||||
|
center: [{latmean}, {lonmean}],
|
||||||
|
zoom: 13,
|
||||||
|
layers: [streets, satellite]
|
||||||
|
}}).setView([{latmean},{lonmean}], 13);
|
||||||
|
|
||||||
|
var navionics = new JNC.Leaflet.NavionicsOverlay({{
|
||||||
|
navKey: 'Navionics_webapi_03205',
|
||||||
|
chartType: JNC.NAVIONICS_CHARTS.NAUTICAL,
|
||||||
|
isTransparent: true,
|
||||||
|
zIndex: 1
|
||||||
|
}});
|
||||||
|
|
||||||
|
|
||||||
|
var osmUrl2='http://tiles.openseamap.org/seamark/{{z}}/{{x}}/{{y}}.png';
|
||||||
|
var osmUrl='http://{{s}}.tile.openstreetmap.org/{{z}}/{{x}}/{{y}}.png';
|
||||||
|
|
||||||
|
|
||||||
|
//create two TileLayer
|
||||||
|
var nautical=new L.TileLayer(osmUrl,{{
|
||||||
|
maxZoom:18}});
|
||||||
|
|
||||||
|
|
||||||
|
L.control.layers({{
|
||||||
|
"Streets": streets,
|
||||||
|
"Satellite": satellite,
|
||||||
|
"Outdoors": outdoors,
|
||||||
|
"Nautical": nautical,
|
||||||
|
}},{{
|
||||||
|
"Navionics":navionics,
|
||||||
|
}}).addTo(mymap);
|
||||||
|
|
||||||
|
var marker = L.marker([{latbegin}, {longbegin}]).addTo(mymap);
|
||||||
|
marker.bindPopup("<b>Start</b>");
|
||||||
|
var emarker = new L.marker([{latend}, {longend}]).addTo(mymap);
|
||||||
|
emarker.bindPopup("<b>End</b>");
|
||||||
|
|
||||||
|
var latlongs = {scoordinates}
|
||||||
|
var polyline = L.polyline(latlongs, {{color:'red'}}).addTo(mymap)
|
||||||
|
mymap.fitBounds(polyline.getBounds())
|
||||||
|
|
||||||
|
</script>
|
||||||
|
""".format(
|
||||||
|
latmean=latmean,
|
||||||
|
lonmean=lonmean,
|
||||||
|
latbegin = latbegin,
|
||||||
|
latend=latend,
|
||||||
|
longbegin=longbegin,
|
||||||
|
longend=longend,
|
||||||
|
scoordinates=scoordinates,
|
||||||
|
)
|
||||||
|
|
||||||
|
div = """
|
||||||
|
<div id="map_canvas" style="width: 100%; height: 400px;"><p> </p></div>
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return script,div
|
return script,div
|
||||||
|
|
||||||
def googlemap_chart(lat,lon,name=""):
|
def googlemap_chart(lat,lon,name=""):
|
||||||
|
|||||||
+38
-2
@@ -12,7 +12,7 @@ from django.core.validators import validate_email
|
|||||||
import os
|
import os
|
||||||
import twitter
|
import twitter
|
||||||
import re
|
import re
|
||||||
|
import pytz
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
@@ -21,6 +21,7 @@ from django.utils import timezone
|
|||||||
import datetime
|
import datetime
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from rowers.rows import validate_file_extension
|
from rowers.rows import validate_file_extension
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
import types
|
import types
|
||||||
|
|
||||||
@@ -389,6 +390,10 @@ def checkworkoutuser(user,workout):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
timezones = (
|
||||||
|
(x,x) for x in pytz.common_timezones
|
||||||
|
)
|
||||||
|
|
||||||
# Workout
|
# Workout
|
||||||
class Workout(models.Model):
|
class Workout(models.Model):
|
||||||
workouttypes = types.workouttypes
|
workouttypes = types.workouttypes
|
||||||
@@ -408,6 +413,9 @@ class Workout(models.Model):
|
|||||||
verbose_name = 'Boat Type')
|
verbose_name = 'Boat Type')
|
||||||
starttime = models.TimeField(blank=True,null=True)
|
starttime = models.TimeField(blank=True,null=True)
|
||||||
startdatetime = models.DateTimeField(blank=True,null=True)
|
startdatetime = models.DateTimeField(blank=True,null=True)
|
||||||
|
timezone = models.CharField(default='UTC',
|
||||||
|
choices=timezones,
|
||||||
|
max_length=100)
|
||||||
distance = models.IntegerField(default=0,blank=True)
|
distance = models.IntegerField(default=0,blank=True)
|
||||||
duration = models.TimeField(default=1,blank=True)
|
duration = models.TimeField(default=1,blank=True)
|
||||||
weightcategory = models.CharField(default="hwt",max_length=10)
|
weightcategory = models.CharField(default="hwt",max_length=10)
|
||||||
@@ -574,7 +582,7 @@ class WorkoutForm(ModelForm):
|
|||||||
duration = forms.TimeInput(format='%H:%M:%S.%f')
|
duration = forms.TimeInput(format='%H:%M:%S.%f')
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Workout
|
model = Workout
|
||||||
fields = ['name','date','starttime','duration','distance','workouttype','notes','privacy','rankingpiece','boattype']
|
fields = ['name','date','starttime','timezone','duration','distance','workouttype','notes','privacy','rankingpiece','boattype']
|
||||||
widgets = {
|
widgets = {
|
||||||
'date': DateInput(),
|
'date': DateInput(),
|
||||||
'notes': forms.Textarea,
|
'notes': forms.Textarea,
|
||||||
@@ -585,10 +593,38 @@ class WorkoutForm(ModelForm):
|
|||||||
super(WorkoutForm, self).__init__(*args, **kwargs)
|
super(WorkoutForm, self).__init__(*args, **kwargs)
|
||||||
# this line to be removed
|
# this line to be removed
|
||||||
del self.fields['privacy']
|
del self.fields['privacy']
|
||||||
|
# self.fields['timezone'] = forms.ChoiceField(choices=[
|
||||||
|
# (x,x) for x in pytz.common_timezones
|
||||||
|
# ],
|
||||||
|
# initial='UTC',
|
||||||
|
# label='Time Zone')
|
||||||
|
|
||||||
if self.instance.workouttype != 'water':
|
if self.instance.workouttype != 'water':
|
||||||
del self.fields['boattype']
|
del self.fields['boattype']
|
||||||
|
|
||||||
|
fieldorder = (
|
||||||
|
'name',
|
||||||
|
'date',
|
||||||
|
'starttime',
|
||||||
|
'timezone',
|
||||||
|
'duration',
|
||||||
|
'distance',
|
||||||
|
'workouttype',
|
||||||
|
'notes',
|
||||||
|
'rankingpiece',
|
||||||
|
'boattype'
|
||||||
|
)
|
||||||
|
|
||||||
|
fields = OrderedDict()
|
||||||
|
for key in fieldorder:
|
||||||
|
try:
|
||||||
|
fields[key] = self.fields.pop(key)
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
for key, valye in self.fields.items():
|
||||||
|
fields[key] = value
|
||||||
|
self.fields = fields
|
||||||
|
|
||||||
# Used for the rowing physics calculations
|
# Used for the rowing physics calculations
|
||||||
class AdvancedWorkoutForm(ModelForm):
|
class AdvancedWorkoutForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
{% load cookielaw_tags %}
|
{% load cookielaw_tags %}
|
||||||
{% load leaflet_tags %}
|
{% load leaflet_tags %}
|
||||||
|
{% load tz_detect %}
|
||||||
|
{% tz_detect %}
|
||||||
{% load analytical %}
|
{% load analytical %}
|
||||||
{% block filters %}
|
{% block filters %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -15,6 +17,9 @@
|
|||||||
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" />
|
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" />
|
||||||
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" />
|
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://webapiv2.navionics.com/dist/webapi/webapi.min.css" >
|
||||||
|
<script type="text/javascript" src="https://webapiv2.navionics.com/dist/webapi/webapi.min.no-dep.js"></script>
|
||||||
|
|
||||||
<link rel="shortcut icon" href="/static/img/favicon.ico" type="image/x-icon" />
|
<link rel="shortcut icon" href="/static/img/favicon.ico" type="image/x-icon" />
|
||||||
<link rel="icon" sizes="32x32" href="/static/img/favicon-32x32.png" type="image/png"/>
|
<link rel="icon" sizes="32x32" href="/static/img/favicon-32x32.png" type="image/png"/>
|
||||||
<link rel="icon" sizes="64x64" href="/static/img/favicon-64x64.png" type="image/png"/>
|
<link rel="icon" sizes="64x64" href="/static/img/favicon-64x64.png" type="image/png"/>
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="grid_12">
|
<div class="grid_12">
|
||||||
|
<p class="midden">
|
||||||
|
Local Time: {% now "jS F Y H:i" %}
|
||||||
|
</p>
|
||||||
<p class="midden">
|
<p class="midden">
|
||||||
Compatible with:
|
Compatible with:
|
||||||
<img src="/static/img/stravasquare.png" alt="Strava icon" width="30" height="30">
|
<img src="/static/img/stravasquare.png" alt="Strava icon" width="30" height="30">
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
{% load rowerfilters %}
|
{% load rowerfilters %}
|
||||||
{% load tz %}
|
{% load tz %}
|
||||||
|
{% get_current_timezone as TIME_ZONE %}
|
||||||
|
|
||||||
{% block title %}Change Workout {% endblock %}
|
{% block title %}Change Workout {% endblock %}
|
||||||
|
|
||||||
@@ -42,11 +43,11 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% localtime on %}
|
|
||||||
<table width=100%>
|
<table width=100%>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Date/Time:</th><td>{{ workout.startdatetime }}</td>
|
{% localtime on %}
|
||||||
|
<th>Date/Time:</th><td>{{ workout.startdatetime|localtime}}</td>
|
||||||
|
{% endlocaltime %}
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<th>Distance:</th><td>{{ workout.distance }}m</td>
|
<th>Distance:</th><td>{{ workout.distance }}m</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
@@ -69,7 +70,6 @@
|
|||||||
<td>
|
<td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
{% endlocaltime %}
|
|
||||||
<form enctype="multipart/form-data" action="" method="post">
|
<form enctype="multipart/form-data" action="" method="post">
|
||||||
<table width=100%>
|
<table width=100%>
|
||||||
{{ form.as_table }}
|
{{ form.as_table }}
|
||||||
|
|||||||
@@ -371,6 +371,7 @@ class DataTest(TestCase):
|
|||||||
'name':'test',
|
'name':'test',
|
||||||
'date':'2016-05-01',
|
'date':'2016-05-01',
|
||||||
'starttime':'07:53:00',
|
'starttime':'07:53:00',
|
||||||
|
'timezone':'UTC',
|
||||||
'duration':'0:55:00.1',
|
'duration':'0:55:00.1',
|
||||||
'distance':8000,
|
'distance':8000,
|
||||||
'notes':'Aap noot \n mies',
|
'notes':'Aap noot \n mies',
|
||||||
@@ -595,6 +596,7 @@ class ViewTest(TestCase):
|
|||||||
'name':'aap',
|
'name':'aap',
|
||||||
'date':'2016-11-05',
|
'date':'2016-11-05',
|
||||||
'starttime':'09:07:14',
|
'starttime':'09:07:14',
|
||||||
|
'timezone':'Europe/Berlin',
|
||||||
'duration':'1:00:00.5',
|
'duration':'1:00:00.5',
|
||||||
'distance':'15000',
|
'distance':'15000',
|
||||||
'workouttype':'rower',
|
'workouttype':'rower',
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ urlpatterns = [
|
|||||||
url(r'^workout/compare2/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>\w+.*)/$',views.workout_comparison_view),
|
url(r'^workout/compare2/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>\w+.*)/$',views.workout_comparison_view),
|
||||||
url(r'^workout/compare/(?P<id>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\w+.*)$',views.workout_comparison_list),
|
url(r'^workout/compare/(?P<id>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\w+.*)$',views.workout_comparison_list),
|
||||||
url(r'^workout/(?P<id>\d+)/edit$',views.workout_edit_view),
|
url(r'^workout/(?P<id>\d+)/edit$',views.workout_edit_view),
|
||||||
|
url(r'^workout/(?P<id>\d+)/navionics$',views.workout_edit_view_navionics),
|
||||||
url(r'^workout/(?P<id>\d+)/setprivate$',views.workout_setprivate_view),
|
url(r'^workout/(?P<id>\d+)/setprivate$',views.workout_setprivate_view),
|
||||||
url(r'^workout/(?P<id>\d+)/updatecp$',views.workout_update_cp_view),
|
url(r'^workout/(?P<id>\d+)/updatecp$',views.workout_update_cp_view),
|
||||||
url(r'^workout/(?P<id>\d+)/makepublic$',views.workout_makepublic_view),
|
url(r'^workout/(?P<id>\d+)/makepublic$',views.workout_makepublic_view),
|
||||||
|
|||||||
+197
-14
@@ -3,6 +3,8 @@ import colorsys
|
|||||||
import timestring
|
import timestring
|
||||||
import zipfile
|
import zipfile
|
||||||
import bleach
|
import bleach
|
||||||
|
import arrow
|
||||||
|
import pytz
|
||||||
import operator
|
import operator
|
||||||
import warnings
|
import warnings
|
||||||
import urllib
|
import urllib
|
||||||
@@ -143,7 +145,7 @@ from dataprep import timedeltaconv
|
|||||||
|
|
||||||
from scipy.interpolate import griddata
|
from scipy.interpolate import griddata
|
||||||
|
|
||||||
LOCALTIMEZONE = tz('Etc/UTC')
|
#LOCALTIMEZONE = tz('Etc/UTC')
|
||||||
USER_LANGUAGE = 'en-US'
|
USER_LANGUAGE = 'en-US'
|
||||||
|
|
||||||
from interactiveplots import *
|
from interactiveplots import *
|
||||||
@@ -463,7 +465,7 @@ def add_workout_from_strokedata(user,importid,data,strokedata,
|
|||||||
except:
|
except:
|
||||||
title = 'Imported'
|
title = 'Imported'
|
||||||
|
|
||||||
starttimeunix = mktime(rowdatetime.utctimetuple())
|
starttimeunix = arrow.get(rowdatetime).timestamp
|
||||||
|
|
||||||
res = make_cumvalues(0.1*strokedata['t'])
|
res = make_cumvalues(0.1*strokedata['t'])
|
||||||
cum_time = res[0]
|
cum_time = res[0]
|
||||||
@@ -617,7 +619,8 @@ def add_workout_from_runkeeperdata(user,importid,data):
|
|||||||
except:
|
except:
|
||||||
rowdatetime = datetime.datetime.strptime(data['date'],"%Y-%m-%d %H:%M:%S")
|
rowdatetime = datetime.datetime.strptime(data['date'],"%Y-%m-%d %H:%M:%S")
|
||||||
rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
|
rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
|
||||||
starttimeunix = mktime(rowdatetime.utctimetuple())
|
starttimeunix = arrow.get(rowdatetime).timestamp
|
||||||
|
#starttimeunix = mktime(rowdatetime.utctimetuple())
|
||||||
starttimeunix += utcoffset*3600
|
starttimeunix += utcoffset*3600
|
||||||
|
|
||||||
|
|
||||||
@@ -669,9 +672,17 @@ def add_workout_from_runkeeperdata(user,importid,data):
|
|||||||
distseries = pd.Series(distance,index=times_distance)
|
distseries = pd.Series(distance,index=times_distance)
|
||||||
distseries = distseries.groupby(distseries.index).first()
|
distseries = distseries.groupby(distseries.index).first()
|
||||||
latseries = pd.Series(latcoord,index=times_location)
|
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 = 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 = pd.Series(spm,index=times_spm)
|
||||||
spmseries = spmseries.groupby(spmseries.index).first()
|
spmseries = spmseries.groupby(spmseries.index).first()
|
||||||
hrseries = pd.Series(hr,index=times_hr)
|
hrseries = pd.Series(hr,index=times_hr)
|
||||||
@@ -761,10 +772,6 @@ def add_workout_from_stdata(user,importid,data):
|
|||||||
except:
|
except:
|
||||||
comments = ''
|
comments = ''
|
||||||
|
|
||||||
try:
|
|
||||||
thetimezone = tz(data['timezone'])
|
|
||||||
except:
|
|
||||||
thetimezone = 'UTC'
|
|
||||||
|
|
||||||
r = getrower(user)
|
r = getrower(user)
|
||||||
try:
|
try:
|
||||||
@@ -780,8 +787,7 @@ def add_workout_from_stdata(user,importid,data):
|
|||||||
except:
|
except:
|
||||||
rowdatetime = datetime.datetime.strptime(data['date'],"%Y-%m-%d %H:%M:%S")
|
rowdatetime = datetime.datetime.strptime(data['date'],"%Y-%m-%d %H:%M:%S")
|
||||||
rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
|
rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
|
||||||
starttimeunix = mktime(rowdatetime.utctimetuple())
|
starttimeunix = arrow.get(rowdatetime).timestamp
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
title = data['name']
|
title = data['name']
|
||||||
@@ -943,7 +949,8 @@ def add_workout_from_underarmourdata(user,importid,data):
|
|||||||
except:
|
except:
|
||||||
rowdatetime = datetime.datetime.strptime(data['date'],"%Y-%m-%d %H:%M:%S")
|
rowdatetime = datetime.datetime.strptime(data['date'],"%Y-%m-%d %H:%M:%S")
|
||||||
rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
|
rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
|
||||||
starttimeunix = mktime(rowdatetime.utctimetuple())
|
starttimeunix = arrow.get(rowdatetime).timestamp
|
||||||
|
#starttimeunix = mktime(rowdatetime.utctimetuple())
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -4782,7 +4789,8 @@ def workout_downloadwind_view(request,id=0,
|
|||||||
startdatetime = dateutil.parser.parse("{}, {}".format(row.date,
|
startdatetime = dateutil.parser.parse("{}, {}".format(row.date,
|
||||||
row.starttime))
|
row.starttime))
|
||||||
|
|
||||||
starttimeunix = int(mktime(startdatetime.utctimetuple()))
|
starttimeunix = int(arrow.get(startdatetime).timestamp)
|
||||||
|
#starttimeunix = int(mktime(startdatetime.utctimetuple()))
|
||||||
avgtime = starttimeunix+avgtime
|
avgtime = starttimeunix+avgtime
|
||||||
winddata = get_wind_data(avglat,avglon,avgtime)
|
winddata = get_wind_data(avglat,avglon,avgtime)
|
||||||
windspeed = winddata[0]
|
windspeed = winddata[0]
|
||||||
@@ -4851,7 +4859,8 @@ def workout_downloadmetar_view(request,id=0,
|
|||||||
startdatetime = dateutil.parser.parse("{}, {}".format(row.date,
|
startdatetime = dateutil.parser.parse("{}, {}".format(row.date,
|
||||||
row.starttime))
|
row.starttime))
|
||||||
|
|
||||||
starttimeunix = int(mktime(startdatetime.utctimetuple()))
|
starttimeunix = arrow.get(startdatetime).timestamp
|
||||||
|
#starttimeunix = int(mktime(startdatetime.utctimetuple()))
|
||||||
avgtime = starttimeunix+avgtime
|
avgtime = starttimeunix+avgtime
|
||||||
winddata = get_metar_data(airportcode,avgtime)
|
winddata = get_metar_data(airportcode,avgtime)
|
||||||
windspeed = winddata[0]
|
windspeed = winddata[0]
|
||||||
@@ -6255,6 +6264,7 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
|||||||
duration = form.cleaned_data['duration']
|
duration = form.cleaned_data['duration']
|
||||||
distance = form.cleaned_data['distance']
|
distance = form.cleaned_data['distance']
|
||||||
notes = form.cleaned_data['notes']
|
notes = form.cleaned_data['notes']
|
||||||
|
thetimezone = form.cleaned_data['timezone']
|
||||||
try:
|
try:
|
||||||
boattype = request.POST['boattype']
|
boattype = request.POST['boattype']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@@ -6272,6 +6282,9 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
|||||||
startdatetime = datetime.datetime.strptime(startdatetime,
|
startdatetime = datetime.datetime.strptime(startdatetime,
|
||||||
"%Y-%m-%d %H:%M:%S")
|
"%Y-%m-%d %H:%M:%S")
|
||||||
startdatetime = timezone.make_aware(startdatetime)
|
startdatetime = timezone.make_aware(startdatetime)
|
||||||
|
startdatetime = startdatetime.astimezone(pytz.timezone(thetimezone))
|
||||||
|
|
||||||
|
|
||||||
# check if user is owner of this workout
|
# check if user is owner of this workout
|
||||||
if checkworkoutuser(request.user,row):
|
if checkworkoutuser(request.user,row):
|
||||||
row.name = name
|
row.name = name
|
||||||
@@ -6285,6 +6298,7 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
|||||||
row.boattype = boattype
|
row.boattype = boattype
|
||||||
row.privacy = privacy
|
row.privacy = privacy
|
||||||
row.rankingpiece = rankingpiece
|
row.rankingpiece = rankingpiece
|
||||||
|
row.timezone = thetimezone
|
||||||
try:
|
try:
|
||||||
row.save()
|
row.save()
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
@@ -6391,6 +6405,175 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
|||||||
|
|
||||||
return HttpResponseRedirect(url)
|
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)
|
# Create the chart image with wind corrected pace (OTW)
|
||||||
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
|
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
|
||||||
def workout_add_otw_powerplot_view(request,id):
|
def workout_add_otw_powerplot_view(request,id):
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ INSTALLED_APPS = [
|
|||||||
'corsheaders',
|
'corsheaders',
|
||||||
'analytical',
|
'analytical',
|
||||||
'cookielaw',
|
'cookielaw',
|
||||||
'django_extensions'
|
'django_extensions',
|
||||||
|
'tz_detect'
|
||||||
]
|
]
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = (
|
AUTHENTICATION_BACKENDS = (
|
||||||
@@ -90,6 +91,7 @@ MIDDLEWARE_CLASSES = [
|
|||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'async_messages.middleware.AsyncMiddleware',
|
'async_messages.middleware.AsyncMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
'tz_detect.middleware.TimezoneMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'rowsandall_app.urls'
|
ROOT_URLCONF = 'rowsandall_app.urls'
|
||||||
@@ -174,7 +176,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/1.9/topics/i18n/
|
# https://docs.djangoproject.com/en/1.9/topics/i18n/
|
||||||
|
|
||||||
TIME_ZONE = 'UTC'
|
#TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
|
|
||||||
@@ -182,6 +184,8 @@ USE_L10N = True
|
|||||||
|
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
|
TZ_DETECT_COUNTRIES = ('US','DE','GB','CZ','FR','IT')
|
||||||
|
|
||||||
LOCALE_PATHS = (
|
LOCALE_PATHS = (
|
||||||
os.path.join(BASE_DIR, 'locale'),
|
os.path.join(BASE_DIR, 'locale'),
|
||||||
os.path.join(BASE_DIR, 'cvkbrno/locale'),
|
os.path.join(BASE_DIR, 'cvkbrno/locale'),
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ urlpatterns += [
|
|||||||
url(r'^tp\_callback',rowersviews.rower_process_tpcallback),
|
url(r'^tp\_callback',rowersviews.rower_process_tpcallback),
|
||||||
url(r'^twitter\_callback',rowersviews.rower_process_twittercallback),
|
url(r'^twitter\_callback',rowersviews.rower_process_twittercallback),
|
||||||
url(r'^i18n/', include('django.conf.urls.i18n')),
|
url(r'^i18n/', include('django.conf.urls.i18n')),
|
||||||
|
url(r'^tz_detect/', include('tz_detect.urls')),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
{% load leaflet_tags %}
|
{% load leaflet_tags %}
|
||||||
{% load cookielaw_tags %}
|
{% load cookielaw_tags %}
|
||||||
|
{% load tz_detect %}
|
||||||
|
{% tz_detect %}
|
||||||
{% load analytical %}
|
{% load analytical %}
|
||||||
{% block filters %}
|
{% block filters %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -30,9 +32,11 @@
|
|||||||
{% block meta %} {% endblock %}
|
{% block meta %} {% endblock %}
|
||||||
{% leaflet_js %}
|
{% leaflet_js %}
|
||||||
{% leaflet_css %}
|
{% leaflet_css %}
|
||||||
|
<link rel="stylesheet" href="https://webapiv2.navionics.com/dist/webapi/webapi.min.css" >
|
||||||
|
<script type="text/javascript" src="https://webapiv2.navionics.com/dist/webapi/webapi.min.no-dep.js"></script>
|
||||||
{% analytical_head_bottom %}
|
{% analytical_head_bottom %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body data-root="http://webapiv2.navionics.com/dist/webapi/images">
|
||||||
{% analytical_body_top %}
|
{% analytical_body_top %}
|
||||||
{% block body_top %}{% endblock %}
|
{% block body_top %}{% endblock %}
|
||||||
<div class="container_12">
|
<div class="container_12">
|
||||||
|
|||||||
Reference in New Issue
Block a user