Changeset 53bb3e5 in OpenWorkouts-current for ow/models/workout.py
- Timestamp:
- Jan 9, 2019, 12:31:33 PM (5 years ago)
- Branches:
- current, feature/docs, master
- Children:
- 119412d
- Parents:
- e3d7b13
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
ow/models/workout.py
re3d7b13 r53bb3e5 7 7 from repoze.folder import Folder 8 8 from pyramid.security import Allow, Everyone 9 from ow.utilities import GPXMinidomParser 9 10 from ow.utilities import ( 11 GPXMinidomParser, 12 copy_blob, 13 create_blob, 14 ) 15 16 from ow.fit import Fit 10 17 11 18 … … 56 63 self.tracking_file = kw.get('tracking_file', None) # Blob 57 64 self.tracking_filetype = '' # unicode string 65 # attr to store ANT fit files. For now this file is used to 66 # generate a gpx-encoded tracking file we then use through 67 # the whole app 68 self.fit_file = kw.get('fit_file', None) # Blob 58 69 59 70 @property … … 188 199 return None 189 200 201 @property 202 def tracking_file_path(self): 203 """ 204 Get the path to the blob file attached as a tracking file. 205 206 First check if the file was not committed to the db yet (new workout 207 not saved yet) and use the path to the temporary file on the fs. 208 If none is found there, go for the real blob file in the blobs 209 directory 210 """ 211 path = None 212 if self.tracking_file: 213 path = self.tracking_file._p_blob_uncommitted 214 if path is None: 215 path = self.tracking_file._p_blob_committed 216 return path 217 218 @property 219 def fit_file_path(self): 220 """ 221 Get the path to the blob file attached as a fit file. 222 223 First check if the file was not committed to the db yet (new workout 224 not saved yet) and use the path to the temporary file on the fs. 225 If none is found there, go for the real blob file in the blobs 226 directory 227 """ 228 path = None 229 if self.fit_file: 230 path = self.fit_file._p_blob_uncommitted 231 if path is None: 232 path = self.fit_file._p_blob_committed 233 return path 234 190 235 def load_from_file(self): 191 236 """ … … 195 240 if self.tracking_filetype == 'gpx': 196 241 self.load_from_gpx() 242 elif self.tracking_filetype == 'fit': 243 self.load_from_fit() 197 244 198 245 def load_from_gpx(self): … … 283 330 return parser.tracks 284 331 332 def load_from_fit(self): 333 """ 334 Try to load data from an ANT-compatible .fit file (if any has been 335 added to this workout). 336 337 "Load data" means: 338 339 1. Copy over the uploaded fit file to self.fit_file, so we can keep 340 that copy around for future use 341 342 2. generate a gpx object from the fit file 343 344 3. save the gpx object as the tracking_file, which then will be used 345 by the current code to display and gather data to be displayed/shown 346 to the user. 347 348 4. Grab some basic info from the fit file and store it in the Workout 349 """ 350 # backup the fit file 351 self.fit_file = copy_blob(self.tracking_file) 352 353 # create an instance of our Fit class 354 fit = Fit(self.fit_file_path) 355 fit.load() 356 357 # fit -> gpx and store that as the main tracking file 358 self.tracking_file = create_blob(fit.gpx, 'gpx') 359 self.tracking_filetype = 'gpx' 360 361 # grab the needed data from the fit file, update the workout 362 self.start = fit.data['start'] 363 # ensure this datetime start object is timezone-aware 364 self.start = self.start.replace(tzinfo=timezone.utc) 365 # duration comes in seconds, store a timedelta 366 self.duration = timedelta(seconds=fit.data['duration']) 367 # distance comes in meters 368 self.distance = Decimal(fit.data['distance']) / Decimal(1000.00) 369 self.uphill = Decimal(fit.data['uphill']) 370 self.downhill = Decimal(fit.data['downhill']) 371 # If the user did not provide us with a title, build one from the 372 # info in the fit file 373 if not self.title: 374 self.title = fit.name 375 376 if fit.data['avg_hr']: 377 self.hr_avg = Decimal(fit.data['avg_hr']) 378 self.hr_min = Decimal(fit.data['min_hr']) 379 self.hr_max = Decimal(fit.data['max_hr']) 380 381 if fit.data['avg_cad']: 382 self.cad_avg = Decimal(fit.data['avg_cad']) 383 self.cad_min = Decimal(fit.data['min_cad']) 384 self.cad_max = Decimal(fit.data['max_cad']) 385 386 if fit.data['avg_atemp']: 387 self.atemp_avg = Decimal(fit.data['avg_atemp']) 388 self.atemp_min = Decimal(fit.data['min_atemp']) 389 self.atemp_max = Decimal(fit.data['max_atemp']) 390 391 return True 392 285 393 @property 286 394 def has_tracking_file(self): … … 290 398 def has_gpx(self): 291 399 return self.has_tracking_file and self.tracking_filetype == 'gpx' 400 401 @property 402 def has_fit(self): 403 return self.fit_file is not None
Note: See TracChangeset
for help on using the changeset viewer.