Changeset 26220ba in OpenWorkouts-current for ow/models/user.py


Ignore:
Timestamp:
Jan 25, 2019, 12:48:51 AM (5 years ago)
Author:
Borja Lopez <borja@…>
Branches:
current, feature/docs, master
Children:
d0fc76b, ed7e9d7
Parents:
c6219ed (diff), 5bdfbfb (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge patches from darcs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • ow/models/user.py

    rc6219ed r26220ba  
    1 
     1from decimal import Decimal
     2from datetime import datetime, timedelta, timezone
    23from uuid import uuid1
    34from operator import attrgetter
     
    89
    910from ow.catalog import get_catalog, reindex_object
     11from ow.utilities import get_week_days
    1012
    1113
     
    136138            tree[year][month][sport] += 1
    137139        return tree
     140
     141    def stats(self, year=None, month=None):
     142        year = year or datetime.now().year
     143        stats = {
     144            'workouts': 0,
     145            'time': timedelta(seconds=0),
     146            'distance': Decimal(0),
     147            'elevation': Decimal(0),
     148            'sports': {}
     149        }
     150
     151        for workout in self.workouts(year=year, month=month):
     152            stats['workouts'] += 1
     153            stats['time'] += workout.duration or timedelta(seconds=0)
     154            stats['distance'] += workout.distance or Decimal(0)
     155            stats['elevation'] += workout.uphill or Decimal(0)
     156
     157            if workout.sport not in stats['sports']:
     158                stats['sports'][workout.sport] = {
     159                    'workouts': 0,
     160                    'time': timedelta(seconds=0),
     161                    'distance': Decimal(0),
     162                    'elevation': Decimal(0),
     163                }
     164
     165            stats['sports'][workout.sport]['workouts'] += 1
     166            stats['sports'][workout.sport]['time'] += (
     167                workout.duration or timedelta(0))
     168            stats['sports'][workout.sport]['distance'] += (
     169                workout.distance or Decimal(0))
     170            stats['sports'][workout.sport]['elevation'] += (
     171                workout.uphill or Decimal(0))
     172
     173        return stats
     174
     175    def get_week_stats(self, day):
     176        """
     177        Return some stats for the week the given day is in.
     178        """
     179        week = get_week_days(day)
     180
     181        # filter workouts
     182        workouts = []
     183        for workout in self.workouts():
     184            if week[0].date() <= workout.start.date() <= week[-1].date():
     185                workouts.append(workout)
     186
     187        # build stats
     188        stats = {}
     189        for week_day in week:
     190            stats[week_day] = {
     191                'workouts': 0,
     192                'time': timedelta(0),
     193                'distance': Decimal(0),
     194                'elevation': Decimal(0),
     195                'sports': {}
     196            }
     197            for workout in workouts:
     198                if workout.start.date() == week_day.date():
     199                    day = stats[week_day]  # less typing, avoid long lines
     200                    day['workouts'] += 1
     201                    day['time'] += workout.duration or timedelta(seconds=0)
     202                    day['distance'] += workout.distance or Decimal(0)
     203                    day['elevation'] += workout.uphill or Decimal(0)
     204                    if workout.sport not in day['sports']:
     205                        day['sports'][workout.sport] = {
     206                            'workouts': 0,
     207                            'time': timedelta(seconds=0),
     208                            'distance': Decimal(0),
     209                            'elevation': Decimal(0),
     210                        }
     211                    day['sports'][workout.sport]['workouts'] += 1
     212                    day['sports'][workout.sport]['time'] += (
     213                        workout.duration or timedelta(0))
     214                    day['sports'][workout.sport]['distance'] += (
     215                        workout.distance or Decimal(0))
     216                    day['sports'][workout.sport]['elevation'] += (
     217                        workout.uphill or Decimal(0))
     218
     219        return stats
     220
     221    @property
     222    def week_stats(self):
     223        """
     224        Helper that returns the week stats for the current week
     225        """
     226        return self.get_week_stats(datetime.now(timezone.utc))
     227
     228    @property
     229    def week_totals(self):
     230        week_stats = self.week_stats
     231        return {
     232            'distance': sum([week_stats[t]['distance'] for t in week_stats]),
     233            'time': sum([week_stats[t]['time'] for t in week_stats],
     234                        timedelta())
     235        }
Note: See TracChangeset for help on using the changeset viewer.