Merge branch 'feature/duplicates' into develop
This commit is contained in:
+25
-6
@@ -999,13 +999,31 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
|
|||||||
maxhr = np.nan_to_num(maxhr)
|
maxhr = np.nan_to_num(maxhr)
|
||||||
averagehr = np.nan_to_num(averagehr)
|
averagehr = np.nan_to_num(averagehr)
|
||||||
|
|
||||||
|
duplicate = False
|
||||||
|
|
||||||
|
t = datetime.datetime.strptime(duration,"%H:%M:%S.%f")
|
||||||
|
delta = datetime.timedelta(hours=t.hour, minutes=t.minute, seconds=t.second)
|
||||||
|
|
||||||
|
workoutenddatetime = workoutstartdatetime+delta
|
||||||
|
|
||||||
# check for duplicate start times and duration
|
# check for duplicate start times and duration
|
||||||
ws = Workout.objects.filter(startdatetime=workoutstartdatetime,
|
ws = Workout.objects.filter(user=r,date=workoutdate,duplicate=False).exclude(
|
||||||
distance=totaldist,
|
startdatetime__gt=workoutenddatetime
|
||||||
user=r)
|
)
|
||||||
if (len(ws) != 0):
|
|
||||||
message = "Warning: This workout probably already exists in the database"
|
ws2 = []
|
||||||
privacy = 'hidden'
|
|
||||||
|
for ww in ws:
|
||||||
|
t = ww.duration
|
||||||
|
delta = datetime.timedelta(hours=t.hour, minutes=t.minute, seconds=t.second)
|
||||||
|
enddatetime = ww.startdatetime+delta
|
||||||
|
if enddatetime > workoutstartdatetime:
|
||||||
|
ws2.append(ww)
|
||||||
|
|
||||||
|
|
||||||
|
if (len(ws2) != 0):
|
||||||
|
message = "Warning: This workout overlaps with an existing one and was marked as a duplicate"
|
||||||
|
duplicate = True
|
||||||
|
|
||||||
|
|
||||||
w = Workout(user=r, name=title, date=workoutdate,
|
w = Workout(user=r, name=title, date=workoutdate,
|
||||||
@@ -1014,6 +1032,7 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
|
|||||||
duration=duration, distance=totaldist,
|
duration=duration, distance=totaldist,
|
||||||
weightcategory=r.weightcategory,
|
weightcategory=r.weightcategory,
|
||||||
starttime=workoutstarttime,
|
starttime=workoutstarttime,
|
||||||
|
duplicate=duplicate,
|
||||||
workoutsource=workoutsource,
|
workoutsource=workoutsource,
|
||||||
rankingpiece=rankingpiece,
|
rankingpiece=rankingpiece,
|
||||||
forceunit=forceunit,
|
forceunit=forceunit,
|
||||||
|
|||||||
@@ -237,8 +237,6 @@ def interactive_boxchart(datadf,fieldname,extratitle=''):
|
|||||||
|
|
||||||
|
|
||||||
def interactive_activitychart(workouts,startdate,enddate,stack='type'):
|
def interactive_activitychart(workouts,startdate,enddate,stack='type'):
|
||||||
if len(workouts) == 0:
|
|
||||||
return "",""
|
|
||||||
|
|
||||||
dates = []
|
dates = []
|
||||||
dates_sorting = []
|
dates_sorting = []
|
||||||
@@ -316,7 +314,10 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'):
|
|||||||
label = CatAttr(columns=['date'], sort=False),
|
label = CatAttr(columns=['date'], sort=False),
|
||||||
xlabel='Date',
|
xlabel='Date',
|
||||||
ylabel='Time',
|
ylabel='Time',
|
||||||
title='Activity',
|
title='Activity {d1} to {d2}'.format(
|
||||||
|
d1 = startdate.strftime("%Y-%m-%d"),
|
||||||
|
d2 = enddate.strftime("%Y-%m-%d"),
|
||||||
|
),
|
||||||
stack=stack,
|
stack=stack,
|
||||||
plot_width=350,
|
plot_width=350,
|
||||||
plot_height=250,
|
plot_height=250,
|
||||||
|
|||||||
+38
-2
@@ -2134,6 +2134,7 @@ class Workout(models.Model):
|
|||||||
privacy = models.CharField(default='visible',max_length=30,
|
privacy = models.CharField(default='visible',max_length=30,
|
||||||
choices=privacychoices)
|
choices=privacychoices)
|
||||||
rankingpiece = models.BooleanField(default=False,verbose_name='Ranking Piece')
|
rankingpiece = models.BooleanField(default=False,verbose_name='Ranking Piece')
|
||||||
|
duplicate = models.BooleanField(default=False,verbose_name='Duplicate Workout')
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
|
||||||
@@ -2181,7 +2182,42 @@ def auto_delete_file_on_delete(sender, instance, **kwargs):
|
|||||||
if instance.csvfilename+'.gz':
|
if instance.csvfilename+'.gz':
|
||||||
if os.path.isfile(instance.csvfilename+'.gz'):
|
if os.path.isfile(instance.csvfilename+'.gz'):
|
||||||
os.remove(instance.csvfilename+'.gz')
|
os.remove(instance.csvfilename+'.gz')
|
||||||
|
|
||||||
|
@receiver(models.signals.post_delete,sender=Workout)
|
||||||
|
def update_duplicates_on_delete(sender, instance, **kwargs):
|
||||||
|
if instance.id:
|
||||||
|
|
||||||
|
duplicates = Workout.objects.filter(
|
||||||
|
user=instance.user,date=instance.date,
|
||||||
|
duplicate=True)
|
||||||
|
|
||||||
|
for d in duplicates:
|
||||||
|
t = d.duration
|
||||||
|
delta = datetime.timedelta(hours=t.hour, minutes=t.minute, seconds=t.second)
|
||||||
|
workoutenddatetime = d.startdatetime+delta
|
||||||
|
ws = Workout.objects.filter(
|
||||||
|
user=d.user,date=d.date,
|
||||||
|
).exclude(
|
||||||
|
pk__in=[instance.pk,d.pk]
|
||||||
|
).exclude(
|
||||||
|
startdatetime__gt=workoutenddatetime
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
ws2 = []
|
||||||
|
|
||||||
|
for ww in ws:
|
||||||
|
t = ww.duration
|
||||||
|
delta = datetime.timedelta(hours=t.hour, minutes=t.minute, seconds=t.second)
|
||||||
|
enddatetime = ww.startdatetime+delta
|
||||||
|
if enddatetime > d.startdatetime:
|
||||||
|
ws2.append(ww)
|
||||||
|
|
||||||
|
if len(ws2) == 0:
|
||||||
|
d.duplicate=False
|
||||||
|
d.save()
|
||||||
|
|
||||||
|
|
||||||
# Delete stroke data from the database when a workout is deleted
|
# Delete stroke data from the database when a workout is deleted
|
||||||
@receiver(models.signals.post_delete,sender=Workout)
|
@receiver(models.signals.post_delete,sender=Workout)
|
||||||
def auto_delete_strokedata_on_delete(sender, instance, **kwargs):
|
def auto_delete_strokedata_on_delete(sender, instance, **kwargs):
|
||||||
@@ -2404,7 +2440,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','timezone','duration','distance','workouttype','boattype','weightcategory','notes','rankingpiece']
|
fields = ['name','date','starttime','timezone','duration','distance','workouttype','boattype','weightcategory','notes','rankingpiece','duplicate']
|
||||||
widgets = {
|
widgets = {
|
||||||
'date': AdminDateWidget(),
|
'date': AdminDateWidget(),
|
||||||
'notes': forms.Textarea,
|
'notes': forms.Textarea,
|
||||||
|
|||||||
+32
-2
@@ -3380,6 +3380,11 @@ def addmanual_view(request):
|
|||||||
rankingpiece = form.cleaned_data['rankingpiece']
|
rankingpiece = form.cleaned_data['rankingpiece']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
rankingpiece = False
|
rankingpiece = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
duplicate = form.cleaned_data['duplicate']
|
||||||
|
except KeyError:
|
||||||
|
duplicate = False
|
||||||
|
|
||||||
if private:
|
if private:
|
||||||
privacy = 'private'
|
privacy = 'private'
|
||||||
@@ -3403,6 +3408,7 @@ def addmanual_view(request):
|
|||||||
avghr=avghr,
|
avghr=avghr,
|
||||||
rankingpiece=rankingpiece,
|
rankingpiece=rankingpiece,
|
||||||
avgpwr=avgpwr,
|
avgpwr=avgpwr,
|
||||||
|
duplicate=duplicate,
|
||||||
avgspm=avgspm,
|
avgspm=avgspm,
|
||||||
title = name,
|
title = name,
|
||||||
notes=notes,
|
notes=notes,
|
||||||
@@ -6748,6 +6754,7 @@ def workouts_view(request,message='',successmessage='',
|
|||||||
enddate = startdate
|
enddate = startdate
|
||||||
startdate = s
|
startdate = s
|
||||||
|
|
||||||
|
|
||||||
startdatestring = startdate.strftime('%Y-%m-%d')
|
startdatestring = startdate.strftime('%Y-%m-%d')
|
||||||
enddatestring = enddate.strftime('%Y-%m-%d')
|
enddatestring = enddate.strftime('%Y-%m-%d')
|
||||||
|
|
||||||
@@ -6763,6 +6770,10 @@ def workouts_view(request,message='',successmessage='',
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
activity_enddate = enddate
|
activity_enddate = enddate
|
||||||
|
|
||||||
|
g_startdate = activity_startdate
|
||||||
|
g_enddate = activity_enddate
|
||||||
|
|
||||||
|
|
||||||
if teamid:
|
if teamid:
|
||||||
try:
|
try:
|
||||||
theteam = Team.objects.get(id=teamid)
|
theteam = Team.objects.get(id=teamid)
|
||||||
@@ -6779,6 +6790,7 @@ def workouts_view(request,message='',successmessage='',
|
|||||||
team=theteam,
|
team=theteam,
|
||||||
startdatetime__gte=activity_startdate,
|
startdatetime__gte=activity_startdate,
|
||||||
startdatetime__lte=activity_enddate,
|
startdatetime__lte=activity_enddate,
|
||||||
|
duplicate=False,
|
||||||
privacy='visible').order_by("-date", "-starttime")
|
privacy='visible').order_by("-date", "-starttime")
|
||||||
elif theteam.viewing == 'coachonly':
|
elif theteam.viewing == 'coachonly':
|
||||||
workouts = Workout.objects.filter(
|
workouts = Workout.objects.filter(
|
||||||
@@ -6790,6 +6802,7 @@ def workouts_view(request,message='',successmessage='',
|
|||||||
team=theteam,user=r,
|
team=theteam,user=r,
|
||||||
startdatetime__gte=activity_startdate,
|
startdatetime__gte=activity_startdate,
|
||||||
enddatetime__lte=activity_enddate,
|
enddatetime__lte=activity_enddate,
|
||||||
|
duplicate=False,
|
||||||
privacy='visible').order_by("-startdatetime")
|
privacy='visible').order_by("-startdatetime")
|
||||||
|
|
||||||
|
|
||||||
@@ -6805,6 +6818,7 @@ def workouts_view(request,message='',successmessage='',
|
|||||||
user=r,
|
user=r,
|
||||||
startdatetime__gte=activity_startdate,
|
startdatetime__gte=activity_startdate,
|
||||||
startdatetime__lte=activity_enddate,
|
startdatetime__lte=activity_enddate,
|
||||||
|
duplicate=False,
|
||||||
privacy='visible').order_by("-startdatetime")
|
privacy='visible').order_by("-startdatetime")
|
||||||
else:
|
else:
|
||||||
theteam = None
|
theteam = None
|
||||||
@@ -6814,9 +6828,18 @@ def workouts_view(request,message='',successmessage='',
|
|||||||
startdatetime__lte=enddate).order_by("-date", "-starttime")
|
startdatetime__lte=enddate).order_by("-date", "-starttime")
|
||||||
g_workouts = Workout.objects.filter(
|
g_workouts = Workout.objects.filter(
|
||||||
user=r,
|
user=r,
|
||||||
|
duplicate=False,
|
||||||
startdatetime__gte=activity_startdate,
|
startdatetime__gte=activity_startdate,
|
||||||
startdatetime__lte=activity_enddate).order_by("-startdatetime")
|
startdatetime__lte=activity_enddate).order_by("-startdatetime")
|
||||||
|
|
||||||
|
|
||||||
|
if len(g_workouts) == 0:
|
||||||
|
g_workouts = Workout.objects.filter(
|
||||||
|
user=r,
|
||||||
|
startdatetime__gte=timezone.now()-timedelta(days=15)).order_by("-startdatetime")
|
||||||
|
g_enddate = timezone.now()
|
||||||
|
g_startdate = (timezone.now()-timedelta(days=15))
|
||||||
|
|
||||||
if rankingonly:
|
if rankingonly:
|
||||||
workouts = workouts.exclude(rankingpiece=False)
|
workouts = workouts.exclude(rankingpiece=False)
|
||||||
|
|
||||||
@@ -6854,9 +6877,10 @@ def workouts_view(request,message='',successmessage='',
|
|||||||
else:
|
else:
|
||||||
stack='type'
|
stack='type'
|
||||||
|
|
||||||
|
|
||||||
script,div = interactive_activitychart(g_workouts,
|
script,div = interactive_activitychart(g_workouts,
|
||||||
activity_startdate,
|
g_startdate,
|
||||||
activity_enddate,
|
g_enddate,
|
||||||
stack=stack)
|
stack=stack)
|
||||||
|
|
||||||
messages.info(request,successmessage)
|
messages.info(request,successmessage)
|
||||||
@@ -9853,6 +9877,11 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
rankingpiece =- Workout.objects.get(id=id).rankingpiece
|
rankingpiece =- Workout.objects.get(id=id).rankingpiece
|
||||||
|
|
||||||
|
try:
|
||||||
|
duplicate = form.cleaned_data['duplicate']
|
||||||
|
except KeyError:
|
||||||
|
duplicate = Workout.objects.get(id=id).duplicate
|
||||||
|
|
||||||
if private:
|
if private:
|
||||||
privacy = 'private'
|
privacy = 'private'
|
||||||
else:
|
else:
|
||||||
@@ -9892,6 +9921,7 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
|||||||
row.duration = duration
|
row.duration = duration
|
||||||
row.distance = distance
|
row.distance = distance
|
||||||
row.boattype = boattype
|
row.boattype = boattype
|
||||||
|
row.duplicate = duplicate
|
||||||
row.privacy = privacy
|
row.privacy = privacy
|
||||||
row.rankingpiece = rankingpiece
|
row.rankingpiece = rankingpiece
|
||||||
row.timezone = thetimezone
|
row.timezone = thetimezone
|
||||||
|
|||||||
Reference in New Issue
Block a user