diff --git a/rowers/integrations/__init__.py b/rowers/integrations/__init__.py index 96bb9221..4e34497e 100644 --- a/rowers/integrations/__init__.py +++ b/rowers/integrations/__init__.py @@ -5,12 +5,14 @@ from .sporttracks import SportTracksIntegration from .rp3 import RP3Integration from .trainingpeaks import TPIntegration + importsources = { 'c2': C2Integration, 'strava': StravaIntegration, 'sporttracks': SportTracksIntegration, 'trainingpeaks': TPIntegration, 'nk': NKIntegration, + 'tp':TPIntegration, 'rp3':RP3Integration, } diff --git a/rowers/templates/list_import.html b/rowers/templates/list_import.html index 1a0f21c2..643bd6db 100644 --- a/rowers/templates/list_import.html +++ b/rowers/templates/list_import.html @@ -8,6 +8,15 @@

Available on {{ integration }}

    +
  • +
    + + {{ dateform.as_table }} +
    + {% csrf_token %} + +
    +
  • {% if workouts %} {% if integration == 'C2 Logbook' %}
  • @@ -30,7 +39,7 @@

  • - {% endif %} + {% endif %}
  • {% csrf_token %} diff --git a/rowers/templates/menu_workouts.html b/rowers/templates/menu_workouts.html index e7bc91c7..b85f728f 100644 --- a/rowers/templates/menu_workouts.html +++ b/rowers/templates/menu_workouts.html @@ -51,7 +51,7 @@
      -
    • Concept2
    • +
    • Concept2
    • NK Logbook
    • Strava
    • SportTracks
    • diff --git a/rowers/tests/test_imports.py b/rowers/tests/test_imports.py index 8ff6ab46..e84c7404 100644 --- a/rowers/tests/test_imports.py +++ b/rowers/tests/test_imports.py @@ -359,8 +359,8 @@ class C2Objects(DjangoTestCase): @patch('rowers.integrations.c2.requests.post', side_effect=mocked_requests) @patch('rowers.integrations.c2.requests.get', side_effect=mocked_requests) def test_c2_upload(self, mock_get, mock_post): - response = self.c.get('/rowers/workout/'+encoded1+'/c2uploadw/') - + url = '/rowers/workout/'+encoded1+'/c2uploadw/' + response = self.c.get(url) self.assertRedirects(response, expected_url = '/rowers/workout/'+encoded1+'/edit/', status_code=302,target_status_code=200) @@ -371,7 +371,7 @@ class C2Objects(DjangoTestCase): @patch('rowers.integrations.c2.requests.post', side_effect=mocked_requests) @patch('rowers.integrations.c2.requests.get', side_effect=mocked_requests) def test_c2_list(self, mock_get, mock_post): - response = self.c.get('/rowers/workout/c2list',follow=True) + response = self.c.get('/rowers/workout/c2import',follow=True) self.assertEqual(response.status_code,200) @@ -381,7 +381,7 @@ class C2Objects(DjangoTestCase): response = self.c.get('/rowers/workout/c2import/12/',follow=True) - expected_url = reverse('workout_c2import_view') + expected_url = reverse('workout_import_view',kwargs={'source':'c2'}) self.assertRedirects(response, expected_url=expected_url, @@ -513,7 +513,7 @@ class C2Objects(DjangoTestCase): def test_c2_import_tz(self, mock_get, mocked_sqlalchemy, mock_session): response = self.c.get('/rowers/workout/c2import/22/',follow=True) - expected_url = '/rowers/workout/c2list/' + expected_url = '/rowers/workout/c2import/' self.assertRedirects(response, expected_url=expected_url, @@ -532,7 +532,7 @@ class C2Objects(DjangoTestCase): def test_c2_import_tz3(self, mock_get, mocked_sqlalchemy): response = self.c.get('/rowers/workout/c2import/32/',follow=True) - expected_url = '/rowers/workout/c2list/' + expected_url = '/rowers/workout/c2import/' self.assertRedirects(response, expected_url=expected_url, @@ -552,7 +552,7 @@ class C2Objects(DjangoTestCase): def test_c2_import_tz2(self, mock_get, mocked_sqlalchemy, MockSession): response = self.c.get('/rowers/workout/c2import/31/',follow=True) - expected_url = '/rowers/workout/c2list/' + expected_url = '/rowers/workout/c2import/' result = tasks.handle_c2_getworkout(self.r.user.id,self.r.c2token,31,self.r.defaulttimezone) @@ -648,7 +648,7 @@ class C2ObjectsTokenExpired(DjangoTestCase): @patch('rowers.integrations.c2.requests.get', side_effect=mocked_requests) @patch('rowers.integrations.c2.Session',side_effect=mocked_requests) def test_c2_list(self, mock_get, mock_post, mock_Session): - response = self.c.get('/rowers/workout/c2list',follow=True) + response = self.c.get('/rowers/workout/c2import/',follow=True) self.assertEqual(response.status_code,200) @@ -757,14 +757,10 @@ class NKObjects(DjangoTestCase): result = integration.open() self.assertEqual(result,"TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq") - response = self.c.get('/rowers/workout/nkimport/all/',follow=True) + response = self.c.get('/rowers/workout/nkimport/?selectallnew=true',follow=True) expected = reverse('workouts_view') - self.assertRedirects(response, - expected_url=expected, - status_code=302,target_status_code=200) - self.assertEqual(response.status_code, 200) @patch('rowers.integrations.nk.requests.get', side_effect=mocked_requests) @@ -780,7 +776,7 @@ class NKObjects(DjangoTestCase): response = self.c.get('/rowers/workout/nkimport/469',follow=True) - expected_url = reverse('workout_nkimport_view') + expected_url = reverse('workout_import_view',kwargs={'source':'nk'}) self.assertRedirects(response, expected_url=expected_url, @@ -804,7 +800,7 @@ class NKObjects(DjangoTestCase): result = integration.token_refresh() response = self.c.get('/rowers/workout/nkimport/404',follow=True) - expected_url = reverse('workout_nkimport_view') + expected_url = reverse('workout_import_view',kwargs={'source':'nk'}) self.assertRedirects(response, expected_url=expected_url, @@ -979,7 +975,7 @@ class RP3Objects(DjangoTestCase): response = self.c.get('/rowers/workout/rp3import/591621',follow=True) - expected_url = reverse('workout_rp3import_view') + expected_url = reverse('workout_import_view',kwargs={'source':'rp3'}) self.assertRedirects(response, expected_url=expected_url, @@ -1163,7 +1159,7 @@ class StravaObjects(DjangoTestCase): mocked_getsmallrowdata_db): response = self.c.get('/rowers/workout/stravaimport/12',follow=True) - expected_url = reverse('workout_stravaimport_view') + expected_url = reverse('workout_import_view',kwargs={'source':'strava'}) self.assertRedirects(response, expected_url=expected_url, @@ -1296,13 +1292,7 @@ class STObjects(DjangoTestCase): @patch('rowers.imports.requests.get', side_effect=mocked_requests) def test_sporttracks_import_all(self, mock_get): - response = self.c.get('/rowers/workout/sporttracksimport/all/',follow=True) - - expected_url = reverse('workouts_view') - - self.assertRedirects(response, - expected_url=expected_url, - status_code=302,target_status_code=200) + response = self.c.get('/rowers/workout/sporttracksimport/?selectallnew=true') self.assertEqual(response.status_code, 200) diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index 2dd6e244..7322a59a 100644 Binary files a/rowers/tests/testdata/testdata.tcx.gz and b/rowers/tests/testdata/testdata.tcx.gz differ diff --git a/rowers/traverselinktest.py b/rowers/traverselinktest.py index 44fbd53a..503b4fbd 100644 --- a/rowers/traverselinktest.py +++ b/rowers/traverselinktest.py @@ -95,7 +95,6 @@ class TraverseLinksTest(TestCase): '.*authorize.*', '.*youtu.*', '.*earth.*', - '.*c2list.*', '.*stravaimport.*', '.*performancephones.*', '.*sporttracks.*', diff --git a/rowers/urls.py b/rowers/urls.py index 40810641..d448a193 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -618,61 +618,17 @@ urlpatterns = [ views.workout_smoothenpace_view, name='workout_smoothenpace_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/undosmoothenpace/$', views.workout_undo_smoothenpace_view, name='workout_undo_smoothenpace_view'), - re_path(r'^workout/c2import/$', views.workout_c2import_view, - name='workout_c2import_view'), - re_path(r'^workout/c2list/$', views.workout_c2import_view, - name='workout_c2import_view'), - re_path(r'^workout/c2list/(?P\d+)/$', - views.workout_c2import_view, name='workout_c2import_view'), - re_path(r'^workout/c2list/user/(?P\d+)/$', - views.workout_c2import_view, name='workout_c2import_view'), - re_path(r'^workout/c2list/(?P\d+)/user/(?P\d+)/$', - views.workout_c2import_view, name='workout_c2import_view'), - re_path(r'^workout/rp3import/$', views.workout_rp3import_view, - name='workout_rp3import_view'), - re_path(r'^workout/rp3import/user/(?P\d+)/$', - views.workout_rp3import_view, name='workout_rp3import_view'), - re_path(r'^workout/stravaimport/$', views.workout_stravaimport_view, - name='workout_stravaimport_view'), re_path(r'^session/rojaboimport/$', views.workout_rojaboimport_view, name='workout_rojaboimport_view'), - re_path(r'^workout/stravaimport/user/(?P\d+)/$', - views.workout_stravaimport_view, name='workout_stravaimport_view'), - re_path(r'^workout/c2import/all/$', views.workout_getc2workout_all, - name='workout_getc2workout_all'), - re_path(r'^workout/c2import/all/(?P\d+)/$', - views.workout_getc2workout_all, name='workout_getc2workout_all'), - re_path(r'^workout/nkimport/$', views.workout_nkimport_view, - name='workout_nkimport_view'), - re_path(r'^workout/nkimport/(?P\d+)/(?P\d+)/$', - views.workout_nkimport_view, name='workout_nkimport_view'), - re_path(r'^workout/nkimport/user/(?P\d+)/$', - views.workout_nkimport_view, name='workout_nkimport_view'), - re_path(r'^workout/nkimport/all/$', views.workout_getnkworkout_all, - name='workout_getnkworkout_all'), - re_path(r'^workout/nkimport/all/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$', - views.workout_getnkworkout_all, - name='workout_getnkworkout_all'), - re_path(r'^workout/rp3import/user/(?P\d+)/$', - views.workout_rp3import_view, name='workout_rp3import_view'), - re_path(r'^workout/rp3import/all/$', views.workout_getrp3workout_all, - name='workout_getrp3workout_all'), + re_path(r'^workout/(?P\w+.*)import/$', + views.workout_import_view, name='workout_import_view'), re_path(r'^workout/(?P\w+.*)import/(?P\d+)/$', views.workout_getimportview, name='workout_getimportview'), - re_path(r'^workout/(?P\w+.*)import/(?P\d+)/async/$', - views.workout_getimportview, {'do_async': True}, name='workout_getimportview'), - # re_path(r'^workout/stravaimport/all/$',views.workout_getstravaworkout_all,name='workout_getstravaworkout_all'), - re_path(r'^workout/sporttracksimport/$', views.workout_sporttracksimport_view, - name='workout_sporttracksimport_view'), - re_path(r'^workout/sporttracksimport/user/(?P\d+)/$', - views.workout_sporttracksimport_view, name='workout_sporttracksimport_view'), - re_path(r'^workout/sporttracksimport/all/$', views.workout_getsporttracksworkout_all, - name='workout_getsporttracksworkout_all'), re_path(r'^workout/polarimport/$', views.workout_polarimport_view, name='workout_polarimport_view'), re_path(r'^workout/polarimport/user/(?P\d+)/', views.workout_polarimport_view, name='workout_polarimport_view'), - re_path('r^workout/(?P\b[0-9A-Fa-f]+\b)/(?P\w+.*)uploadw/$', + re_path(r'^workout/(?P[0-9A-Fa-f]+)/(?P[0-9A-za-z]+)uploadw/$', views.workout_export_view, name='workout_export_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/recalcsummary/$', views.workout_recalcsummary_view, name='workout_recalcsummary_view'), diff --git a/rowers/views/importviews.py b/rowers/views/importviews.py index 9e102150..99dae081 100644 --- a/rowers/views/importviews.py +++ b/rowers/views/importviews.py @@ -10,6 +10,7 @@ from rowers.tasks import fetch_strava_workout import rowers.integrations.strava as strava from rowers.integrations import importsources +from rowers.utils import NoTokenError import numpy @@ -94,7 +95,11 @@ def rower_polar_authorize(request): # pragma: no cover @login_required() def rower_integration_token_refresh(request, source='c2'): - integration = importsource[source](request.user) + try: + integration = importsources[source](request.user) + except KeyError: + url = reverse('workouts_view') + return HttpResponseRedirect(url) try: token = integration.token_refresh() messages.info(request, "Tokens refreshed. Good to go") @@ -320,58 +325,57 @@ def rower_process_nkcallback(request): # pragma: no cover return HttpResponseRedirect(url) + @login_required() -def workout_getnkworkout_all(request, startdatestring='', enddatestring=''): +@permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True) +@permission_required('rower.is_not_freecoach', fn=get_user_by_userid, raise_exception=True) +def workout_import_view(request, source='c2'): startdate, enddate = get_dates_timeperiod( - request, startdatestring=startdatestring, enddatestring=enddatestring) + request, defaulttimeperiod='last30') startdate = startdate.date() enddate = enddate.date() + r = getrequestrower(request) + integration = importsources[source](request.user) + + try: + _ = integration.open() + except NoTokenError: # pragma: no cover + return HttpResponseRedirect("/rowers/me/nkauthorize/") + + + + + if request.method == 'POST': # pragma: no cover + dateform = DateRangeForm(request.POST) + if dateform.is_valid(): + startdate = dateform.cleaned_data['startdate'] + enddate = dateform.cleaned_data['enddate'] + \ + datetime.timedelta(days=1) + else: + dateform = DateRangeForm(initial={ + 'startdate': startdate, + 'enddate': enddate, + }) + + if enddate < startdate: # pragma: no cover + s = enddate + enddate = startdate + startdate = s + + startdatestring = startdate.strftime('%Y-%m-%d') + enddatestring = enddate.strftime('%Y-%m-%d') + + request.session['startdate'] = startdatestring + request.session['enddate'] = enddatestring + before = arrow.get(enddate) before = str(int(before.timestamp()*1000)) after = arrow.get(startdate) after = str(int(after.timestamp()*1000)) - nk_integration = importsources['nk'](request.user) - try: - _ = nk_integration.open() - except NoTokenError: # pragma: no cover - return HttpResponseRedirect("rower_nk_authorize") - - r = getrequestrower(request) - - result = nk_integration.get_workouts(before=before, after=after) - - if result: - messages.info( - request, "Your NK workouts will be imported in the coming few minutes") - else: # pragma: no cover - messages.error(request, "Your NK workouts import failed") - - url = reverse('workouts_view') - return HttpResponseRedirect(url) - - -@login_required() -@permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True) -@permission_required('rower.is_not_freecoach', fn=get_user_by_userid, raise_exception=True) -def workout_nkimport_view(request, userid=0, after=0, before=0): - startdate, enddate = get_dates_timeperiod( - request, defaulttimeperiod='last30') - startdate = startdate.date() - enddate = enddate.date() - r = getrequestrower(request, userid=userid) - nk_integration = importsources['nk'](request.user) - - try: - _ = nk_integration.open() - except NoTokenError: # pragma: no cover - return HttpResponseRedirect("/rowers/me/nkauthorize/") - - - - workouts = nk_integration.get_workout_list(before=0, after=0) + workouts = integration.get_workout_list(before=before, after=after, startdate=startdate, enddate=enddate) if request.method == 'POST': # pragma: no cover @@ -380,11 +384,11 @@ def workout_nkimport_view(request, userid=0, after=0, before=0): ids = tdict['workoutid'] nkids = [int(id) for id in ids] for nkid in nkids: - _ = nk_integration.get_workout(nkid) + _ = integration.get_workout(nkid) messages.info( request, - 'Your NK logbook workouts will be imported in the background.' - ' It may take a few minutes before they appear.') + 'Your {source} workouts will be imported in the background.' + ' It may take a few minutes before they appear.'.format(source=integration.get_name())) url = reverse('workouts_view') return HttpResponseRedirect(url) except KeyError: @@ -396,27 +400,29 @@ def workout_nkimport_view(request, userid=0, after=0, before=0): 'name': 'Workouts' }, { - 'url': reverse('workout_nkimport_view'), - 'name': 'NK Logbook' + 'url': reverse('workout_import_view',kwargs={'source':source}), + 'name': integration.get_name() }, ] checknew = request.GET.get('selectallnew', False) + return render(request, 'list_import.html', { 'workouts': workouts, 'rower': r, - 'startdate': startdate, - 'enddate': enddate, + 'dateform':dateform, 'active': 'nav-workouts', 'breadcrumbs': breadcrumbs, 'teams': get_my_teams(request.user), 'checknew': checknew, - 'integration': 'NK Logbook' + 'startdate':startdate, + 'enddate': enddate, + 'integration': integration.get_name() }) + -# Process Strava Callback @login_required() @@ -568,67 +574,6 @@ def rower_process_testcallback(request): # pragma: no cover return HttpResponse(text) -@login_required() -@permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True) -def workout_rp3import_view(request, userid=0): - r = getrequestrower(request, userid=userid) - rp3_integration = importsources['rp3'](request.user) - - try: - _ = rp3_integration.open() - except NoTokenError: # pragma: no cover - url = reverse('rower_rp3_authorize') - return HttpResponseRedirect(url) - - workouts = rp3_integration.get_workout_list() - datedict = {} - for workout in workouts: - datedict[workout['id']] = workout['starttime'] - - - if request.method == "POST": - try: # pragma: no cover - tdict = dict(request.POST.lists()) - ids = tdict['workoutid'] - rp3ids = [int(id) for id in ids] - - for rp3id in rp3ids: - rp3_integration.get_workout(rp3id,startdatetime=datedict[rp3id]) - # done, redirect to workouts list - messages.info( - request, - 'Your RP3 workouts will be imported in the background.' - ' It may take a few minutes before they appear.') - url = reverse('workouts_view') - return HttpResponseRedirect(url) - except KeyError: # pragma: no cover - pass - - - breadcrumbs = [ - { - 'url': '/rowers/list-workouts/', - 'name': 'Workouts' - }, - { - 'url': reverse('workout_rp3import_view'), - 'name': 'RP3' - }, - ] - - checknew = request.GET.get('selectallnew', False) - - - return render(request, 'list_import.html', - { - 'workouts': workouts, - 'rower': r, - 'active': 'nav-workouts', - 'breadcrumbs': breadcrumbs, - 'teams': get_my_teams(request.user), - 'integration': 'RP3', - 'checknew': checknew, - }) # The page where you select which Strava workout to import @login_required() @@ -791,72 +736,6 @@ def workout_rojaboimport_view(request, message="", userid=0): 'checknew': checknew, }) -# The page where you select which Strava workout to import -@login_required() -@permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True) -@permission_required('rower.is_not_freecoach', fn=get_user_by_userid, raise_exception=True) -def workout_stravaimport_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 the NK Logbook, not those of your athletes') - url = reverse('workout_stravaimport_view', - kwargs={'userid': request.user.id}) - return HttpResponseRedirect(url) - - strava_integration = importsources['strava'](request.user) - try: - _ = strava_integration.open() - except NoTokenError: # pragma: no cover - return HttpResponseRedirect("/rowers/me/stravaauthorize/") - - workouts = strava_integration.get_workout_list() - - if request.method == "POST": - try: # pragma: no cover - tdict = dict(request.POST.lists()) - ids = tdict['workoutid'] - stravaids = [int(id) for id in ids] - alldata = {} - - for stravaid in stravaids: - res = strava_integration.get_workout(id) - - # done, redirect to workouts list - messages.info(request, - 'Your Strava workouts will be imported in the background.' - ' It may take a few minutes before they appear.') - url = reverse('workouts_view') - return HttpResponseRedirect(url) - except KeyError: # pragma: no cover - pass - - breadcrumbs = [ - { - 'url': '/rowers/list-workouts/', - 'name': 'Workouts' - }, - { - 'url': reverse('workout_stravaimport_view'), - 'name': 'Strava' - }, - ] - - checknew = request.GET.get('selectallnew', False) - - # 2022-10-24 sorting the results - workouts = sorted(workouts, key = lambda d:d['starttime'], reverse=True) - - return render(request, 'list_import.html', - {'workouts': workouts, - 'rower': r, - 'active': 'nav-workouts', - 'breadcrumbs': breadcrumbs, - 'teams': get_my_teams(request.user), - 'checknew': checknew, - 'integration': 'Strava' - }) # for Strava webhook request validation @@ -1122,261 +1001,24 @@ def workout_polarimport_view(request, userid=0): # pragma: no cover 'teams': get_my_teams(request.user), }) - -# The page where you select which SportTracks workout to import -@login_required() -@permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True) -@permission_required('rower.is_not_freecoach', fn=get_user_by_userid, raise_exception=True) -def workout_sporttracksimport_view(request, message="", userid=0): - st_integration = importsources['sporttracks'](request.user) - try: - _ = st_integration.open() - except NoTokenError: - return HttpResponseRedirect("/rowers/me/sporttracksauthorize/") - - workouts = st_integration.get_workout_list() - - r = getrower(request.user) - - if request.method == "POST": - try: # pragma: no cover - tdict = dict(request.POST.lists()) - ids = tdict['workoutid'] - stids = [int(id) for id in ids] - alldata = {} - - for id in stids: - res = st_integration.get_workout(id) - - # done, redirect to workouts list - messages.info(request, - 'Your SportTracks workouts will be imported in the background.' - ' It may take a few minutes before they appear.') - url = reverse('workouts_view') - return HttpResponseRedirect(url) - except KeyError: # pragma: no cover - pass - - breadcrumbs = [ - { - 'url': '/rowers/list-workouts/', - 'name': 'Workouts' - }, - { - 'url': reverse('workout_sporttracksimport_view'), - 'name': 'SportTracks' - }, - ] - - checknew = request.GET.get('selectallnew', False) - - - return render(request, 'list_import.html', - {'workouts': workouts, - 'breadcrumbs': breadcrumbs, - 'active': 'nav-workouts', - 'rower': r, - 'teams': get_my_teams(request.user), - 'integration':'SportTracks', - 'checknew': checknew, - }) - - return HttpResponse(res) # pragma: no cover - -# List of workouts on Concept2 logbook. This view only used for debugging - - - -# Import all unknown workouts available on Concept2 logbook -@login_required() -def workout_getc2workout_all(request, page=1, message=""): # pragma: no cover - r = getrequestrower(request) - c2_integration = importsources['c2'](request.user) - try: - _ = c2_integration.open() - except NoTokenError: # pragma: no cover - return HttpResponseRedirect("/rowers/me/c2authorize/") - - result = c2_integration.get_workouts(page=page) - - if result: - messages.info( - request, 'Your C2 workouts will be imported in the coming few minutes') - else: - messages.error(request, 'Your C2 workouts import failed') - - url = reverse('workouts_view') - return HttpResponseRedirect(url) - - -@login_required() -def workout_getrp3workout_all(request): # pragma: no cover - try: - _ = rp3_open(request.user) - except NoTokenError: # pragma: no cover - return HttpResponseRedirect("/rowers/me/rp3authorize/") - - r = getrequestrower(request) - - rp3_integration = importsources['rp3'](request.user) - result = rp3_integration.get_workouts() - - if result: - messages.info( - request, 'Your RP3 workouts will be imported in the coming few minutes') - else: - messages.error(request, 'Your RP3 workouts import failed') - - url = reverse('workouts_view') - return HttpResponseRedirect(url) - -# List of workouts available on Concept2 logbook - for import -@login_required() -@permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True) -@permission_required('rower.is_not_freecoach', fn=get_user_by_userid, raise_exception=True) -def workout_c2import_view(request, page=1, userid=0, message=""): - - rower = getrequestrower(request, userid=userid) - if rower.user != request.user: - messages.error( - request, 'You can only access your own workouts on the Concept2 Logbook, not those of your athletes') - url = reverse('workout_c2import_view', kwargs={ - 'userid': request.user.id}) - return HttpResponseRedirect(url) - - c2_integration = importsources['c2'](request.user) - try: - _ = c2_integration.open() - except NoTokenError: # pragma: no cover - return HttpResponseRedirect("/rowers/me/c2authorize/") - - workouts = c2_integration.get_workout_list(page=1) - - - if request.method == "POST": - try: # pragma: no cover - tdict = dict(request.POST.lists()) - ids = tdict['workoutid'] - c2ids = [int(id) for id in ids] - - for c2id in c2ids: - c2_integration.get_workout(c2id) - # done, redirect to workouts list - messages.info( - request, - 'Your Concept2 workouts will be imported in the background.' - ' It may take a few minutes before they appear.') - url = reverse('workouts_view') - return HttpResponseRedirect(url) - except KeyError: # pragma: no cover - pass - - breadcrumbs = [ - { - 'url': '/rowers/list-workouts/', - 'name': 'Workouts' - }, - { - 'url': reverse('workout_c2import_view'), - 'name': 'Concept2' - }, - { - 'url': reverse('workout_c2import_view', kwargs={'page': page}), - 'name': 'Page '+str(page) - } - ] - - rower = getrower(request.user) - - checknew = request.GET.get('selectallnew', False) - - return render(request, - 'list_import.html', - {'workouts': workouts, - 'rower': rower, - 'active': 'nav-workouts', - 'breadcrumbs': breadcrumbs, - 'teams': get_my_teams(request.user), - 'page': page, - 'checknew': checknew, - 'integration': 'C2 Logbook' - }) - - -importlistviews = { - 'c2': 'workout_c2import_view', - 'strava': 'workout_stravaimport_view', - 'polar': 'workout_polarimport_view', - 'ownapi': 'workout_view', - 'sporttracks': 'workout_sporttracksimport_view', - 'trainingpeaks': 'workout_view', - 'nk': 'workout_nkimport_view', - 'rp3': 'workout_rp3import_view', -} - importauthorizeviews = { - 'c2': 'rower_c2_authorize', - 'strava': 'rower_strava_authorize', + 'c2': 'rower_integration_authorize', + 'strava': 'rower_integration_authorize', 'polar': 'rower_polar_authorize', 'ownapi': 'workout_view', - 'sporttracks': 'rower_sporttracks_authorize', - 'trainingpeaks': 'rower_tp_authorize', - 'nk': 'rower_nk_authorize', - 'rp3': 'rower_rp3_authorize', + 'sporttracks': 'rower_integration_authorize', + 'trainingpeaks': 'rower_integration_authorize', + 'nk': 'rower_integration_authorize', + 'rp3': 'rower_integration_authorize', } - - -@login_required() -def workout_getimportview_old(request, externalid, source='c2', do_async=True): - if 'startdate' in request.session and source == 'nk': # pragma: no cover - startdate = request.session.get('startdate') - enddate = request.session.get('enddate') - - try: - result = importsources[source].get_workout(request.user, externalid, do_async=do_async, - startdate=startdate, enddate=enddate) - except NoTokenError: - return HttpResponseRedirect(reverse(importauthorizeviews[source])) - - url = reverse(importlistviews[source]) - return HttpResponseRedirect(url) - try: - result = importsources[source].get_workout(request.user, externalid, - do_async=do_async) - except NoTokenError: - - return HttpResponseRedirect(reverse(importauthorizeviews[source])) - - if result: # pragma: no cover - messages.info( - request, "Your workout will be imported in the background") - # this should return to the respective import list page - else: # pragma: no cover - messages.error(request, 'Error getting the workout') - - url = reverse(importlistviews[source]) - return HttpResponseRedirect(url) - - -# Imports all new workouts from SportTracks -@login_required() -def workout_getsporttracksworkout_all(request): - st_integration = importsources['sporttracks'](request.user) - st_integration.get_workouts() - messages.info(request,"Your SportTracks workouts will be imported in the background") - - url = reverse('workouts_view') - return HttpResponseRedirect(url) - - @login_required() def workout_getimportview(request, externalid, source='c2', do_async=True): try: integration = importsources[source](request.user) except (TypeError, NotImplementedError, KeyError): - return workout_getimportview_old(request, externalid, source=source, do_async=True) + return reverse("workouts_view") if 'startdate' in request.session and source == 'nk': # pragma: no cover startdate = request.session.get('startdate') enddate = request.session.get('enddate') @@ -1385,14 +1027,14 @@ def workout_getimportview(request, externalid, source='c2', do_async=True): try: result = integration.get_workout(externalid, startdate=startdate, enddate=enddate) except NoTokenError: - return HttpResponseRedirect(reverse(importauthorizeviews[source])) + return HttpResponseRedirect(reverse(importauthorizeviews[source],kwargs={'source':source})) url = reverse(importlistviews[source]) return HttpResponseRedirect(url) try: result = integration.get_workout(externalid) except NoTokenError: - return HttpResponseRedirect(reverse(importauthorizeviews[source])) + return HttpResponseRedirect(reverse(importauthorizeviews[source],kwargs={'source':source})) if result: # pragma: no cover messages.info( @@ -1401,7 +1043,7 @@ def workout_getimportview(request, externalid, source='c2', do_async=True): else: # pragma: no cover messages.error(request, 'Error getting the workout') - url = reverse(importlistviews[source]) + url = reverse("workout_import_view", kwargs={'source':source}) return HttpResponseRedirect(url)