From 81b2b78f7c248de756513ccd440fc0ffebd98b56 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 21 Dec 2024 14:57:31 +0100 Subject: [PATCH] delete functionality --- rowers/integrations/intervals.py | 46 +++++++++++++++++++++-- rowers/models.py | 20 +++++++++- rowers/templates/plannedsessionview.html | 4 +- rowers/tests/mocks.py | 4 ++ rowers/tests/testdata/testdata.tcx.gz | Bin 3999 -> 4000 bytes 5 files changed, 67 insertions(+), 7 deletions(-) diff --git a/rowers/integrations/intervals.py b/rowers/integrations/intervals.py index 8b0828b0..042b5eff 100644 --- a/rowers/integrations/intervals.py +++ b/rowers/integrations/intervals.py @@ -380,16 +380,34 @@ class IntervalsIntegration(SyncIntegration): stepstext = ps.steps_intervals() + category = 'WORKOUT' + startdate = ps.preferreddate.strftime('%Y-%m-%dT%H:%M:%S') + enddate = ps.preferreddate.strftime('%Y-%m-%d') + 'T23:59:59' + if ps.sessiontype == 'cycletarget': + category = 'TARGET' + startdate = ps.startdate.strftime('%Y-%m-%dT%H:%M:%S') + enddate = ps.enddate.strftime('%Y-%m-%d') + 'T23:59:59' + data = { - "start_date_local": ps.preferreddate.strftime('%Y-%m-%dT%H:%M:%S'), + "start_date_local": startdate, "type": mytypes.intervalsmapping[ps.sessionsport], - "category": "WORKOUT", - "end_date_local": ps.preferreddate.strftime('%Y-%m-%d') + 'T23:59:59', + "category": category, + "end_date_local": enddate, "name": ps.name, "description": stepstext, "indoor": ps.sessionsport in mytypes.ergtypes, } + if ps.sessiontype == 'cycletarget': + if ps.sessionmode == 'time': + data['time_target'] = ps.sessionvalue*60 + elif ps.sessionmode == 'distance': + data['distance_target'] = ps.sessionvalue + elif ps.sessionmode == 'rScore': + data['load_target'] = ps.sessionvalue + elif ps.sessionmode == 'Trimp': + data['load_target'] = ps.sessionvalue/2. + url = self.oauth_data['base_url'] + 'athlete/0/events' response = requests.post(url, headers=headers, json=data) @@ -399,8 +417,28 @@ class IntervalsIntegration(SyncIntegration): data = response.json() id = data['id'] - ps.intervalsid = id + ps.intervals_icu_id = id ps.save() return id + def plannedsession_delete(self, ps, *args, **kwargs): + _ = self.open() + r = self.rower + + headers = { + 'Authorization': 'Bearer ' + r.intervals_token, + } + + url = self.oauth_data['base_url'] + 'athlete/0/events/' + str(ps.intervals_icu_id) + + response = requests.delete(url, headers=headers) + + if response.status_code != 200: + dologging('intervals.icu.log', response.text) + return 0 + + ps.intervals_icu_id = None + ps.save() + + return 1 diff --git a/rowers/models.py b/rowers/models.py index f6264f64..20ba4f2e 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -5,7 +5,8 @@ from rowers.courseutils import coordinate_in_path from rowers.utils import ( # workflowleftpanel, workflowmiddlepanel, defaultleft, defaultmiddle, landingpages, landingpages2, - steps_read_fit, steps_write_fit, steps_read_intervals, ps_dict_order, uniqify + steps_read_fit, steps_write_fit, steps_read_intervals, ps_dict_order, uniqify, + dologging ) from rowers.metrics import axlabels from rowers.utils import geo_distance, move_one_meter @@ -1174,6 +1175,7 @@ class Rower(models.Model): c2_auto_import = models.BooleanField(default=False) intervals_auto_export = models.BooleanField(default=False) intervals_auto_import = models.BooleanField(default=False) + intervals_delete_plannedsession = models.BooleanField(default=False, verbose_name="Deleting planned session deletes it on intervals.icu") intervals_resample_to_1s = models.BooleanField(default=False, verbose_name='Resample to 1s on export') sporttrackstoken = models.CharField( default='', max_length=200, blank=True, null=True) @@ -1246,6 +1248,7 @@ class Rower(models.Model): intervals_token = models.CharField( default='', max_length=200, blank=True, null=True) intervals_owner_id = models.CharField(default='', max_length=200,blank=True, null=True) + privacychoices = ( ('visible', 'Visible'), @@ -2952,6 +2955,19 @@ class PlannedSession(models.Model): s = steps_read_intervals(settings.MEDIA_ROOT+'/'+self.fitfile.name) return s + def delete(self, *args, **kwargs): + r = self.manager.rower + if self.intervals_icu_id and r.intervals_delete_plannedsession: + headers = { + 'Authorization': 'Bearer '+ r.intervals_token + } + url = 'https://intervals.icu/api/v1/athlete/0/events/'+str(self.intervals_icu_id) + response = requests.delete(url, headers=headers) + if response.status_code != 200: + dologging('intervals.icu.log', response.text) + + super(PlannedSession, self).delete(*args, **kwargs) + def save(self, *args, **kwargs): if self.sessionvalue <= 0: # pragma: no cover self.sessionvalue = 1 @@ -4628,6 +4644,7 @@ class RowerExportForm(ModelForm): 'rp3_auto_import', 'intervals_auto_import', 'intervals_auto_export', + 'intervals_delete_plannedsession', 'intervals_resample_to_1s', 'imports_are_private' ] @@ -4656,6 +4673,7 @@ class RowerExportFormIntervals(ModelForm): 'intervals_auto_import', 'intervals_auto_export', 'intervals_resample_to_1s', + 'intervals_delete_plannedsession', ] class RowerExportFormGarmin(ModelForm): diff --git a/rowers/templates/plannedsessionview.html b/rowers/templates/plannedsessionview.html index 20156570..78c696e3 100644 --- a/rowers/templates/plannedsessionview.html +++ b/rowers/templates/plannedsessionview.html @@ -23,8 +23,8 @@ {% else %} Export to Garmin {% endif %} - {% if ps.intervalsid != "" %} - Exported to intervals.icu + {% if plannedsession.intervals_icu_id %} + Exported to intervals.icu {% else %} Export to intervals.icu {% endif %} diff --git a/rowers/tests/mocks.py b/rowers/tests/mocks.py index 512b2429..a3a1effc 100644 --- a/rowers/tests/mocks.py +++ b/rowers/tests/mocks.py @@ -1042,6 +1042,10 @@ def mocked_requests(*args, **kwargs): class MockSession: + def __init__(self): + self.status_code = 200 + self.text = "- 20m 200W" + class headers: def __init__(self,*args,**kwargs): # pragma: no cover pass diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index 6a09e1d661564a6ddbe4771b84f966ea86a4aef9..c4a132d71a7f3101211bcd2e491f8f28ea302fce 100644 GIT binary patch delta 258 zcmV+d0sa1;AD|xxABzYGp1@_X2dNH!eDu$`N`ZufR2DxZ!!c<{P^b#`&( zHFmSi+Z(A&*5Q0xx9Fkp2i>P(ua5c2Tk30 Iti*r;0E|nHMF0Q* delta 257 zcmV+c0sj7=AD<+lIJJZMCm_J{BTJ63+ zczBUGo?U#{_gR^Kd%F^qPsbfRc-_A`ySVb2 zJUBl;SsitK`stT1#^t%cI$8Ser`M~KmzO{HxAZ=yL$5rX4_lsg|4En3&Vs9OpTFL1 zwN9J8eA;ij;quXbasGoB>81~VU7jqv%`$PwpFTXgEBAHqq+1_9esuWrv&?4u=WhEi z=`DWt`t*-wx-)=#0K5MW7FWL5J^AfpI=r(*y;`T|@GzlVUOY-q21t+32 H#DD<+q<)DS