Private
Public Access
1
0

Merge branch 'develop' into feature/mapcompare

This commit is contained in:
Sander Roosendaal
2020-06-02 21:04:13 +02:00
9 changed files with 246 additions and 20 deletions

View File

@@ -2049,30 +2049,25 @@ def leaflet_chart(lat,lon,name=""):
return script,div return script,div
def leaflet_chart_compare(workoutids,labeldict={},startenddict={}): def leaflet_chart_compare(course,workoutids,labeldict={},startenddict={}):
data = [] data = []
for id in workoutids: for id in workoutids:
w = Workout.objects.get(id=id) w = Workout.objects.get(id=id)
rowdata = rdata(w.csvfilename) rowdata = rdata(w.csvfilename)
df = pd.DataFrame({ df = pd.DataFrame({
'id':id, 'id':id,
'latitude':rowdata.df[' latitude'], 'lat':rowdata.df[' latitude'],
'longitude':rowdata.df[' longitude'] 'lon':rowdata.df[' longitude']
}) })
data.append(f) data.append(df)
df = pd.concat(data,axis=0) df = pd.concat(data,axis=0)
if lat.empty or lon.empty:
return [0,"invalid coordinate data"]
latmean,lonmean,coordinates = course_coord_center(course)
lat_min, lat_max, long_min, long_max = course_coord_maxmin(course)
# Throw out 0,0 # Throw out 0,0
df = pd.DataFrame({
'lat':lat,
'lon':lon
})
df = df.replace(0,np.nan) df = df.replace(0,np.nan)
df = df.loc[(df!=0).any(axis=1)] df = df.loc[(df!=0).any(axis=1)]
df.fillna(method='bfill',axis=0,inplace=True) df.fillna(method='bfill',axis=0,inplace=True)
@@ -2082,8 +2077,6 @@ def leaflet_chart_compare(workoutids,labeldict={},startenddict={}):
if lat.empty or lon.empty: if lat.empty or lon.empty:
return [0,"invalid coordinate data"] return [0,"invalid coordinate data"]
latmean = lat.mean()
lonmean = lon.mean()
latbegin = lat[lat.index[0]] latbegin = lat[lat.index[0]]
longbegin = lon[lon.index[0]] longbegin = lon[lon.index[0]]
latend = lat[lat.index[-1]] latend = lat[lat.index[-1]]
@@ -5210,12 +5203,10 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line',
'workoutid'] 'workoutid']
datadf = dataprep.getsmallrowdata_db(columns,ids=ids,doclean=False,compute=False) datadf = dataprep.getsmallrowdata_db(columns,ids=ids,doclean=False,compute=False)
datadf.dropna(axis=1,how='all',inplace=True) datadf.dropna(axis=1,how='all',inplace=True)
datadf.dropna(axis=0,how='any',inplace=True) datadf.dropna(axis=0,how='any',inplace=True)
nrworkouts = len(ids) nrworkouts = len(ids)
try: try:

View File

@@ -2917,6 +2917,17 @@ def update_duplicates_on_delete(sender, instance, **kwargs):
# conn.close() # conn.close()
# engine.dispose() # engine.dispose()
class VirtualRaceFollower(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE,null=True)
race = models.ForeignKey(VirtualRace,on_delete=models.CASCADE)
emailaddress = models.EmailField(max_length=254,blank=True,null=True,
verbose_name="Email Address")
class FollowerForm(ModelForm):
class Meta:
model = VirtualRaceFollower
fields = ['emailaddress']
# Virtual Race results (for keeping results when workouts are deleted) # Virtual Race results (for keeping results when workouts are deleted)
@python_2_unicode_compatible @python_2_unicode_compatible
class VirtualRaceResult(models.Model): class VirtualRaceResult(models.Model):

View File

@@ -0,0 +1,39 @@
{% extends "newbase.html" %}
{% load staticfiles %}
{% load rowerfilters %}
{% load tz %}
{% block title %}Follow Virtual Challenge{% endblock %}
{% block main %}
<h1>Follow {{ plannedession.name }}</h1>
<ul class="main-content">
<li class="grid_2">
<p>To follow this challenge and receive all news per email, fill out your
email address and submit the form.
</li>
<li class="grid_2">
<form enctype="multipart/form-data" method="post">
<table width=100%>
{{ form.as_table }}
</table>
{% csrf_token %}
<input type="submit" value="Save">
</form>
</li>
</ul>
{% endblock %}
{% block sidebar %}
{% if 'racing' in active %}
{% include 'menu_racing.html' %}
{% else %}
{% include 'menu_plan.html' %}
{% endif %}
{% endblock %}

View File

@@ -160,12 +160,16 @@
<div id="registerbuttons"> <div id="registerbuttons">
{% if request.user.is_anonymous %} {% if request.user.is_anonymous %}
<p> <p>
Registered users of rowsandall.com can participate in this challenge. Participation is free, unless specified differently in the race comment above. Registered users of rowsandall.com can participate in this challenge.
Participation is free, unless specified differently in the race comment above.
{% if race.sessiontype == 'race' %} {% if race.sessiontype == 'race' %}
<a href="/rowers/virtualevent/{{ race.id }}/register"><h3>Register</h3></a> <a href="/rowers/virtualevent/{{ race.id }}/register"><h3>Register</h3></a>
{% else %} {% else %}
<a href="/rowers/virtualevent/{{ race.id }}/registerindoor"><h3>Register</h3></a> <a href="/rowers/virtualevent/{{ race.id }}/registerindoor"><h3>Register</h3></a>
{% endif %} {% endif %}
{% if request.user|isfollower:race.id %}
<a href="/rowers/virtualevent/{{ race.id }}/follow/"><h3>Follow this challenge</h3></a>
{% endif %}
</p> </p>
{% else %} {% else %}
<p> <p>
@@ -184,6 +188,9 @@
{% else %} {% else %}
<a href="/rowers/virtualevent/{{ race.id }}/registerindoor"><h3>Register</h3></a> <a href="/rowers/virtualevent/{{ race.id }}/registerindoor"><h3>Register</h3></a>
{% endif %} {% endif %}
{% if request.user|isfollower:race.id %}
<a href="/rowers/virtualevent/{{ race.id }}/follow/"><h3>Follow this challenge</h3></a>
{% endif %}
</p> </p>
{% endif %} {% endif %}
{% if button == 'submitbutton' %} {% if button == 'submitbutton' %}

View File

@@ -12,7 +12,8 @@ from rowers.utils import calculate_age
from rowers.models import ( from rowers.models import (
course_length,WorkoutComment, course_length,WorkoutComment,
TrainingMacroCycle,TrainingMesoCycle, TrainingMicroCycle, TrainingMacroCycle,TrainingMesoCycle, TrainingMicroCycle,
Rower,Workout,SiteAnnouncement, TeamInvite, TeamRequest, CoachOffer,CoachRequest Rower,Workout,SiteAnnouncement, TeamInvite, TeamRequest, CoachOffer,CoachRequest,
VirtualRaceFollower,VirtualRace,
) )
from rowers.plannedsessions import ( from rowers.plannedsessions import (
race_can_register, race_can_submit,race_rower_status race_can_register, race_can_submit,race_rower_status
@@ -40,6 +41,21 @@ from django.template.defaultfilters import stringfilter
from six import string_types from six import string_types
@register.filter
def isfollower(user,id):
if user.is_anonymous:
return True
try:
race = VirtualRace.objects.get(id=id)
except VirtualRace.DoesNotExist:
return False
followers = VirtualRaceFollower.objects.filter(race=race,user=user)
return followers.count()==0
@register.filter @register.filter
def adaptive(s): def adaptive(s):
u = s u = s

View File

@@ -348,6 +348,8 @@ urlpatterns = [
views.virtualevent_uploadimage_view,name='virtualevent_uploadimage_view'), views.virtualevent_uploadimage_view,name='virtualevent_uploadimage_view'),
re_path(r'^virtualevent/(?P<id>\d+)/setimage/(?P<logoid>\d+)/$', re_path(r'^virtualevent/(?P<id>\d+)/setimage/(?P<logoid>\d+)/$',
views.virtualevent_setlogo_view,name='virtualevent_setlog_view'), views.virtualevent_setlogo_view,name='virtualevent_setlog_view'),
re_path(r'^virtualevent/(?P<id>\d+)/follow/$',
views.addfollower_view,name='addfollower_view'),
re_path(r'^logo/(?P<id>\d+)/delete/$', re_path(r'^logo/(?P<id>\d+)/delete/$',
views.logo_delete_view,name='logo_delete_view'), views.logo_delete_view,name='logo_delete_view'),
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/darkskywind/$',views.workout_downloadwind_view,name='workout_downloadwind_view'), re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/darkskywind/$',views.workout_downloadwind_view,name='workout_downloadwind_view'),

View File

@@ -1625,6 +1625,39 @@ def virtualevent_addboat_view(request,id=0):
"You have successfully registered for this race. Good luck!" "You have successfully registered for this race. Good luck!"
) )
otherrecords = VirtualRaceResult.objects.filter(
race = race).exclude(userid = r.id)
for otherrecord in otherrecords:
otheruser = Rower.objects.get(id=otherrecord.userid)
othername = otheruser.user.first_name+' '+otheruser.user.last_name
registeredname = r.user.first_name+' '+r.user.last_name
if otherrecord.emailnotifications:
job = myqueue(
queue,
handle_sendemail_raceregistration,
otheruser.user.email, othername,
registeredname,
race.name,
race.id
)
followers = VirtualRaceFollower.objects.filter(race = race)
for follower in followers:
othername = ''
if follower.user:
othername = follower.user.first_name+' '+follower.user.last_name
registeredname = r.user.first_name+' '+r.user.last_name
email = follower.emailaddress
job = myqueue(
queue,
handle_sendemail_raceregistration,
email, othername,
registeredname,race.name,race.id,
)
url = reverse('virtualevent_view', url = reverse('virtualevent_view',
kwargs = { kwargs = {
'id':race.id 'id':race.id
@@ -1804,7 +1837,12 @@ def virtualevent_register_view(request,id=0):
add_rower_race(r,race) add_rower_race(r,race)
otherrecords = IndoorVirtualRaceResult.objects.filter( # remove followers
myfollows = VirtualRaceFollower.objects.filter(user=r.user,race=race)
for f in myfollows:
f.delete()
otherrecords = VirtualRaceResult.objects.filter(
race = race).exclude(userid = r.id) race = race).exclude(userid = r.id)
for otherrecord in otherrecords: for otherrecord in otherrecords:
@@ -1821,6 +1859,22 @@ def virtualevent_register_view(request,id=0):
race.id race.id
) )
followers = VirtualRaceFollower.objects.filter(race = race)
for follower in followers:
othername = ''
if follower.user:
othername = follower.user.first_name+' '+follower.user.last_name
registeredname = r.user.first_name+' '+r.user.last_name
email = follower.emailaddress
job = myqueue(
queue,
handle_sendemail_raceregistration,
email, othername,
registeredname,race.name,race.id,
)
messages.info( messages.info(
request, request,
@@ -2039,6 +2093,11 @@ def indoorvirtualevent_register_view(request,id=0):
add_rower_race(r,race) add_rower_race(r,race)
# remove followers
myfollows = VirtualRaceFollower.objects.filter(user=r.user,race=race)
for f in myfollows:
f.delete()
otherrecords = IndoorVirtualRaceResult.objects.filter( otherrecords = IndoorVirtualRaceResult.objects.filter(
race = race).exclude(userid = r.id) race = race).exclude(userid = r.id)
@@ -2056,6 +2115,22 @@ def indoorvirtualevent_register_view(request,id=0):
race.id race.id
) )
followers = VirtualRaceFollower.objects.filter(race = race)
for follower in followers:
othername = ''
if follower.user:
othername = follower.user.first_name+' '+follower.user.last_name
registeredname = r.user.first_name+' '+r.user.last_name
email = follower.emailaddress
job = myqueue(
queue,
handle_sendemail_raceregistration,
email, othername,
registeredname,race.name,race.id,
)
messages.info( messages.info(
request, request,
@@ -2734,6 +2809,7 @@ def virtualevent_submit_result_view(request,id=0,workoutid=0):
if not jobid: if not jobid:
messages.info(request,"Result submitted successfully.") messages.info(request,"Result submitted successfully.")
for otherrecord in otherrecords: for otherrecord in otherrecords:
try: try:
otheruser = Rower.objects.get(id=otherrecord.userid) otheruser = Rower.objects.get(id=otherrecord.userid)
@@ -2751,7 +2827,21 @@ def virtualevent_submit_result_view(request,id=0,workoutid=0):
except Rower.DoesNotExist: except Rower.DoesNotExist:
pass pass
followers = VirtualRaceFollower.objects.filter(race = race)
for follower in followers:
othername = ''
if follower.user:
othername = follower.user.first_name+' '+follower.user.last_name
registeredname = r.user.first_name+' '+r.user.last_name
email = follower.emailaddress
job = myqueue(
queue,
handle_sendemail_racesubmission,
email, othername,
registeredname,race.name,race.id,
)
# redirect to race page # redirect to race page
@@ -2820,3 +2910,71 @@ def virtualevent_submit_result_view(request,id=0,workoutid=0):
'rower':r, 'rower':r,
'w_form':w_form, 'w_form':w_form,
}) })
def addfollower_view(request,id=0):
try:
race = VirtualRace.objects.get(id=id)
except VirtualRace.DoesNotExist:
raise Http404("Virtual Challenge does not exist")
if not request.user.is_anonymous:
follower = VirtualRaceFollower(
user=request.user,
race=race,
emailaddress = request.user.email
)
follower.save()
messages.info(request,"You will receive challenge notifications per email")
url = reverse(virtualevent_view,
kwargs={'id':id})
return HttpResponseRedirect(url)
# Anonymous
if request.method == 'POST':
form = FollowerForm(request.POST)
if form.is_valid():
email = form.cleaned_data['emailaddress']
follower = VirtualRaceFollower(
race=race,
emailaddress = email
)
follower.save()
messages.info(request,"You will receive challenge notifications per email")
url = reverse(virtualevent_view,
kwargs={'id':id})
return HttpResponseRedirect(url)
else:
form = FollowerForm()
breadcrumbs = [
{
'url':reverse('virtualevents_view'),
'name': 'Challenges'
},
{
'url':reverse('virtualevent_view',
kwargs={'id':race.id}
),
'name': race.name
},
{
'url': reverse(addfollower_view,
kwargs = {'id':race.id}
),
'name': 'Follow'
}
]
return render(request,'followerform.html',
{
'form':form,
'active':'nav-racing',
'breadcrumbs':breadcrumbs,
}
)

View File

@@ -116,6 +116,7 @@ from rowers.models import (
PlannedSessionComment,CoachRequest,CoachOffer, PlannedSessionComment,CoachRequest,CoachOffer,
VideoAnalysis,ShareKey, VideoAnalysis,ShareKey,
StandardCollection,CourseStandard, StandardCollection,CourseStandard,
VirtualRaceFollower,
) )
from rowers.models import ( from rowers.models import (
RowerPowerForm,RowerForm,GraphImage,AdvancedWorkoutForm, RowerPowerForm,RowerForm,GraphImage,AdvancedWorkoutForm,
@@ -129,7 +130,8 @@ from rowers.models import (
VirtualRaceForm,VirtualRaceResultForm,RowerImportExportForm, VirtualRaceForm,VirtualRaceResultForm,RowerImportExportForm,
IndoorVirtualRaceResultForm,IndoorVirtualRaceResult, IndoorVirtualRaceResultForm,IndoorVirtualRaceResult,
IndoorVirtualRaceForm,PlannedSessionCommentForm, IndoorVirtualRaceForm,PlannedSessionCommentForm,
Alert, Condition, StaticChartRowerForm Alert, Condition, StaticChartRowerForm,
FollowerForm,
) )
from rowers.models import ( from rowers.models import (
FavoriteForm,BaseFavoriteFormSet,SiteAnnouncement,BasePlannedSessionFormSet, FavoriteForm,BaseFavoriteFormSet,SiteAnnouncement,BasePlannedSessionFormSet,

View File

@@ -1542,7 +1542,7 @@ def virtualevent_mapcompare_view(request,id=0):
int(w.id): w.__str__() for w in workouts int(w.id): w.__str__() for w in workouts
} }
script,div = leaflet_chart_compare(workoutids, script,div = leaflet_chart_compare(race.course,workoutids,
labeldict=labeldict, labeldict=labeldict,
startenddict=startenddict) startenddict=startenddict)