Private
Public Access
1
0

Merge branch 'develop' into feature/idoklad

This commit is contained in:
2024-12-22 16:51:14 +01:00
18 changed files with 520 additions and 60 deletions

View File

@@ -7,6 +7,7 @@ from rowers.views.statements import *
from rowers.plannedsessions import get_dates_timeperiod
from rowers.tasks import fetch_strava_workout
from rowers.utils import NoTokenError
from rowers.models import PlannedSession
import rowers.integrations.strava as strava
from rowers.integrations import importsources
@@ -681,8 +682,73 @@ def rower_process_testcallback(request): # pragma: no cover
return HttpResponse(text)
# view to list planned sessions from intervals.icu
@login_required()
@user_passes_test(isplanmember, login_url="/rowers/paidplans/",
message="This functionality requires a Self-coach plan or higher",
redirect_field_name=None)
def plannedsession_intervalsimport_view(request, message="", userid=0):
r = getrequestrower(request, userid=userid)
if r.user != request.user:
messages.error(
request, 'You can only access your own workouts on Intervals.icu, not those of your athletes')
url = reverse('plannedsession_intervalsimport_view',
kwargs={'userid': request.user.id})
return HttpResponseRedirect(url)
integration = importsources['intervals'](request.user)
sessions_list = integration.get_plannedsessions_list()
if request.method == 'POST': # pragma: no cover
tdict = dict(request.POST.lists())
sessionids = [id for id in tdict['session']]
for sessionid in sessionids:
sessiondata = integration.get_plannedsession(sessionid)
if sessiondata['description'] is None:
sessiondata['description'] = ''
if sessiondata:
timetarget = sessiondata['time_target']
if timetarget is None:
timetarget = sessiondata['moving_time']
if timetarget is None:
timetarget = 3600
timetarget = int(timetarget)/60.
ps = PlannedSession(
name=sessiondata['name'],
comment=sessiondata['description'],
sessionmode='time',
sessionvalue=timetarget,
startdate=arrow.get(sessiondata['start_date_local']).datetime,
enddate=arrow.get(sessiondata['end_date_local']).datetime,
preferreddate=arrow.get(sessiondata['start_date_local']).datetime,
sessionsport=mytypes.intervalsmappinginv[sessiondata['type']],
sessiontype='session',
intervals_icu_id=sessiondata['id'],
manager=request.user,
)
ps.save()
ps.rower.add(r)
if sessiondata['category'].lower() == 'workout':
ps.fitfile = sessiondata['fitfile']
ps.save()
ps.update_steps()
if sessiondata['category'].lower() == 'target':
ps.sessiontype = 'cycletarget'
ps.sessionvalue = int(sessiondata['time_target'])/60.
ps.enddate = ps.startdate + datetime.timedelta(days=6)
ps.save()
url = reverse('plannedsessions_view')
return HttpResponseRedirect(url)
return render(request, 'intervals_list_import.html',
{
'sessions': sessions_list,
'rower': r,
'active': 'nav-plans',
})
# The page where you select which Strava workout to import
@login_required()
@user_passes_test(isplanmember, login_url="/rowers/paidplans/",
message="This functionality requires a Self-coach plan or higher",

View File

@@ -2052,6 +2052,41 @@ def plannedsession_templateedit_view(request, id=0):
'steps': steps,
})
@permission_required('plannedsession.change_session', fn=get_session_by_pk, raise_exception=True)
@user_passes_test(can_plan, login_url="/rowers/paidplans/",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def plannedsession_tointervals_view(request, id=0):
r = getrequestplanrower(request)
startdate, enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
ps = get_object_or_404(PlannedSession, pk=id)
intervals = IntervalsIntegration(request.user)
result = intervals.plannedsession_create(ps)
if not result: # pragma: no cover
messages.error(
request, 'You failed to export your session to Intervals')
else:
messages.info(
request, 'Session is now on Intervals.')
url = reverse(plannedsession_view, kwargs={'userid': r.user.id,
'id': ps.id, })
startdatestring = startdate.strftime('%Y-%m-%d')
enddatestring = enddate.strftime('%Y-%m-%d')
url += '?when='+startdatestring+'/'+enddatestring
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
@permission_required('plannedsession.change_session', fn=get_session_by_pk, raise_exception=True)
@user_passes_test(can_plan, login_url="/rowers/paidplans/",
@@ -2483,9 +2518,11 @@ def plannedsession_view(request, id=0, userid=0):
plannedsession=ps).order_by("created")
steps = ''
steps_intervals = ''
if ps.steps: # pragma: no cover
d = ps.steps
steps = ps_dict_get_description_html(d, short=False)
steps_intervals = ps.steps_intervals()
return render(request, 'plannedsessionview.html',
{
@@ -2516,6 +2553,7 @@ def plannedsession_view(request, id=0, userid=0):
'coursediv': coursediv,
'comments': comments,
'steps': steps,
'steps_intervals': steps_intervals,
}
)
@@ -2707,6 +2745,7 @@ def rower_view_instantplan(request, id='', userid=0):
startdate = form.cleaned_data['startdate']
notes = form.cleaned_data['notes']
datechoice = form.cleaned_data['datechoice']
plan_past_days = form.cleaned_data['plan_past_days']
status = True
if target and datechoice == 'target': # pragma: no cover
@@ -2726,10 +2765,14 @@ def rower_view_instantplan(request, id='', userid=0):
notes=notes,
)
if not plan_past_days:
p.startdate = timezone.now().date()
p.save()
p.rowers.add(r)
create_sessions_from_json(plansteps, r, startdate, r.user, planbyrscore=byrscore)
create_sessions_from_json(plansteps, r, startdate, r.user, planbyrscore=byrscore,
plan=p, plan_past_days = plan_past_days, asynchronous=True)
messages.info(request, 'Your Sessions have been added')
@@ -3335,6 +3378,13 @@ class TrainingPlanDelete(DeleteView):
template_name = 'trainingplan_delete.html'
success_url = reverse_lazy(rower_create_trainingplan)
def post(self, request, *args, **kwargs):
delete_sessions = request.POST.get('delete_sessions',0)
delete_all_sessions = request.POST.get('delete_all_sessions',0)
self.object = self.get_object()
self.object.delete(delete_sessions=delete_sessions, delete_all_sessions=delete_all_sessions)
return HttpResponseRedirect(self.get_success_url())
def get_object(self, *args, **kwargs):
obj = super(TrainingPlanDelete, self).get_object(*args, **kwargs)
if not can_delete_plan(self.request.user, obj): # pragma: no cover

View File

@@ -4976,6 +4976,7 @@ def workout_upload_api(request):
# sync related IDs
sporttracksid = post_data.get('sporttracksid','')
intervalsid = post_data.get('intervalsid','')
c2id = post_data.get('c2id', '')
garminid = post_data.get('garminid','')
workoutid = post_data.get('id','')