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
def leaflet_chart_compare(workoutids,labeldict={},startenddict={}):
def leaflet_chart_compare(course,workoutids,labeldict={},startenddict={}):
data = []
for id in workoutids:
w = Workout.objects.get(id=id)
rowdata = rdata(w.csvfilename)
df = pd.DataFrame({
'id':id,
'latitude':rowdata.df[' latitude'],
'longitude':rowdata.df[' longitude']
'lat':rowdata.df[' latitude'],
'lon':rowdata.df[' longitude']
})
data.append(f)
data.append(df)
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
df = pd.DataFrame({
'lat':lat,
'lon':lon
})
df = df.replace(0,np.nan)
df = df.loc[(df!=0).any(axis=1)]
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:
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]]
@@ -5210,12 +5203,10 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line',
'workoutid']
datadf = dataprep.getsmallrowdata_db(columns,ids=ids,doclean=False,compute=False)
datadf.dropna(axis=1,how='all',inplace=True)
datadf.dropna(axis=0,how='any',inplace=True)
nrworkouts = len(ids)
try:

View File

@@ -2917,6 +2917,17 @@ def update_duplicates_on_delete(sender, instance, **kwargs):
# conn.close()
# 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)
@python_2_unicode_compatible
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">
{% if request.user.is_anonymous %}
<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' %}
<a href="/rowers/virtualevent/{{ race.id }}/register"><h3>Register</h3></a>
{% else %}
<a href="/rowers/virtualevent/{{ race.id }}/registerindoor"><h3>Register</h3></a>
{% endif %}
{% if request.user|isfollower:race.id %}
<a href="/rowers/virtualevent/{{ race.id }}/follow/"><h3>Follow this challenge</h3></a>
{% endif %}
</p>
{% else %}
<p>
@@ -184,6 +188,9 @@
{% else %}
<a href="/rowers/virtualevent/{{ race.id }}/registerindoor"><h3>Register</h3></a>
{% endif %}
{% if request.user|isfollower:race.id %}
<a href="/rowers/virtualevent/{{ race.id }}/follow/"><h3>Follow this challenge</h3></a>
{% endif %}
</p>
{% endif %}
{% if button == 'submitbutton' %}

View File

@@ -12,7 +12,8 @@ from rowers.utils import calculate_age
from rowers.models import (
course_length,WorkoutComment,
TrainingMacroCycle,TrainingMesoCycle, TrainingMicroCycle,
Rower,Workout,SiteAnnouncement, TeamInvite, TeamRequest, CoachOffer,CoachRequest
Rower,Workout,SiteAnnouncement, TeamInvite, TeamRequest, CoachOffer,CoachRequest,
VirtualRaceFollower,VirtualRace,
)
from rowers.plannedsessions import (
race_can_register, race_can_submit,race_rower_status
@@ -40,6 +41,21 @@ from django.template.defaultfilters import stringfilter
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
def adaptive(s):
u = s

View File

@@ -348,6 +348,8 @@ urlpatterns = [
views.virtualevent_uploadimage_view,name='virtualevent_uploadimage_view'),
re_path(r'^virtualevent/(?P<id>\d+)/setimage/(?P<logoid>\d+)/$',
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/$',
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'),

View File

@@ -1625,6 +1625,39 @@ def virtualevent_addboat_view(request,id=0):
"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',
kwargs = {
'id':race.id
@@ -1804,7 +1837,12 @@ def virtualevent_register_view(request,id=0):
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)
for otherrecord in otherrecords:
@@ -1821,6 +1859,22 @@ def virtualevent_register_view(request,id=0):
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(
request,
@@ -2039,6 +2093,11 @@ def indoorvirtualevent_register_view(request,id=0):
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(
race = race).exclude(userid = r.id)
@@ -2056,6 +2115,22 @@ def indoorvirtualevent_register_view(request,id=0):
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(
request,
@@ -2734,6 +2809,7 @@ def virtualevent_submit_result_view(request,id=0,workoutid=0):
if not jobid:
messages.info(request,"Result submitted successfully.")
for otherrecord in otherrecords:
try:
otheruser = Rower.objects.get(id=otherrecord.userid)
@@ -2751,7 +2827,21 @@ def virtualevent_submit_result_view(request,id=0,workoutid=0):
except Rower.DoesNotExist:
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
@@ -2820,3 +2910,71 @@ def virtualevent_submit_result_view(request,id=0,workoutid=0):
'rower':r,
'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,
VideoAnalysis,ShareKey,
StandardCollection,CourseStandard,
VirtualRaceFollower,
)
from rowers.models import (
RowerPowerForm,RowerForm,GraphImage,AdvancedWorkoutForm,
@@ -129,7 +130,8 @@ from rowers.models import (
VirtualRaceForm,VirtualRaceResultForm,RowerImportExportForm,
IndoorVirtualRaceResultForm,IndoorVirtualRaceResult,
IndoorVirtualRaceForm,PlannedSessionCommentForm,
Alert, Condition, StaticChartRowerForm
Alert, Condition, StaticChartRowerForm,
FollowerForm,
)
from rowers.models import (
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
}
script,div = leaflet_chart_compare(workoutids,
script,div = leaflet_chart_compare(race.course,workoutids,
labeldict=labeldict,
startenddict=startenddict)