Index: ow/models/user.py
===================================================================
--- ow/models/user.py	(revision 8c2b0949ae91540ee5c8101b9d5ff39003773da3)
+++ ow/models/user.py	(revision 5ec3a0b5cf5640304a0953320daef2a28bbca9a5)
@@ -1,4 +1,3 @@
-from decimal import Decimal
-from datetime import datetime, timedelta, timezone
+
 from uuid import uuid1
 from operator import attrgetter
@@ -6,8 +5,7 @@
 import bcrypt
 from repoze.folder import Folder
-from pyramid.security import Allow, Deny, Everyone, ALL_PERMISSIONS
+from pyramid.security import Allow
 
 from ow.catalog import get_catalog, reindex_object
-from ow.utilities import get_week_days, get_month_week_number
 
 
@@ -18,7 +16,6 @@
     def __acl__(self):
         permissions = [
+            (Allow, str(self.uid), 'edit'),
             (Allow, str(self.uid), 'view'),
-            (Allow, str(self.uid), 'edit'),
-            (Deny, Everyone, ALL_PERMISSIONS),
         ]
         return permissions
@@ -26,5 +23,4 @@
     def __init__(self, **kw):
         self.uid = kw.get('uid', uuid1())
-        self.nickname = kw.get('nickname', '')
         self.firstname = kw.get('firstname', '')
         self.lastname = kw.get('lastname', '')
@@ -34,25 +30,12 @@
         self.height = kw.get('height', None)
         self.weight = kw.get('weight', None)
-        self.gender = kw.get('gender', 'robot')
+        self.gender = kw.get('gender', 'female')
         self.picture = kw.get('picture', None)  # blob
-        self.timezone = kw.get('timezone', 'UTC')
-        self.locale = kw.get('locale', 'en')
         self.__password = None
         self.last_workout_id = 0
-        # has this user verified his account?
-        self.verified = False
-        self.verification_token = None
-        self.verification_tokens_sent = 0
         super(User, self).__init__()
 
     def __str__(self):
-        return u'User: %s (%s)' % (self.uid, self.email)
-
-    def __repr__(self):
-        return u'<%s.%s: %s (%s)>' % (
-            self.__class__.__module__,
-            self.__class__.__name__,
-            self.uid, self.email
-        )
+        return u'User: %s (%s)' % (self.email, self.uid)
 
     @property
@@ -90,18 +73,9 @@
         reindex_object(catalog, workout)
 
-    def workouts(self, year=None, month=None, week=None):
+    def workouts(self):
         """
         Return this user workouts, sorted by date, from newer to older
         """
-        workouts = self.values()
-        if year:
-            workouts = [w for w in workouts if w.start.year == year]
-            if month:
-                workouts = [w for w in workouts if w.start.month == month]
-            if week:
-                week = int(week)
-                workouts = [
-                    w for w in workouts if w.start.isocalendar()[1] == week]
-        workouts = sorted(workouts, key=attrgetter('start'))
+        workouts = sorted(self.values(), key=attrgetter('start'))
         workouts.reverse()
         return workouts
@@ -113,326 +87,2 @@
     def num_workouts(self):
         return len(self.workout_ids())
-
-    @property
-    def favorite_sport(self):
-        """
-        Return which sport is the one with most workouts for this user.
-        In case of more than one sport with the maximum number of workouts,
-        return the first in reversed alphabetical ordering
-        """
-        sports = {}
-        for w in self.workouts():
-            if w.sport not in sports.keys():
-                sports[w.sport] = 0
-            sports[w.sport] += 1
-        _sports = sorted(sports.items(), reverse=True,
-                         key=lambda x: (x[1], x[0]))
-        if _sports:
-            return _sports[0][0]
-        return None
-
-    @property
-    def activity_sports(self):
-        return sorted(list(set(w.sport for w in self.workouts())))
-
-    @property
-    def activity_years(self):
-        return sorted(list(set(w.start.year for w in self.workouts())),
-                      reverse=True)
-
-    def activity_months(self, year):
-        months = set(
-            w.start.month for w in self.workouts() if w.start.year == year)
-        return sorted(list(months))
-
-    @property
-    def activity_dates_tree(self):
-        """
-        Return a dict containing information about the activity for this
-        user.
-
-        Example:
-
-        {
-            2019: {
-                1: {'cycling': 12, 'running': 1}
-            },
-            2018: {
-                1: {'cycling': 10, 'running': 3},
-                2: {'cycling': 14, 'swimming': 5}
-            }
-        }
-        """
-        tree = {}
-        for workout in self.workouts():
-            year = workout.start.year
-            month = workout.start.month
-            sport = workout.sport
-            if year not in tree:
-                tree[year] = {}
-            if month not in tree[year]:
-                tree[year][month] = {}
-            if sport not in tree[year][month]:
-                tree[year][month][sport] = 0
-            tree[year][month][sport] += 1
-        return tree
-
-    def stats(self, year=None, month=None):
-        year = year or datetime.now().year
-        stats = {
-            'workouts': 0,
-            'time': timedelta(seconds=0),
-            'distance': Decimal(0),
-            'elevation': Decimal(0),
-            'sports': {}
-        }
-
-        for workout in self.workouts(year=year, month=month):
-            stats['workouts'] += 1
-            stats['time'] += workout.duration or timedelta(seconds=0)
-            stats['distance'] += workout.distance or Decimal(0)
-            stats['elevation'] += workout.uphill or Decimal(0)
-
-            if workout.sport not in stats['sports']:
-                stats['sports'][workout.sport] = {
-                    'workouts': 0,
-                    'time': timedelta(seconds=0),
-                    'distance': Decimal(0),
-                    'elevation': Decimal(0),
-                }
-
-            stats['sports'][workout.sport]['workouts'] += 1
-            stats['sports'][workout.sport]['time'] += (
-                workout.duration or timedelta(0))
-            stats['sports'][workout.sport]['distance'] += (
-                workout.distance or Decimal(0))
-            stats['sports'][workout.sport]['elevation'] += (
-                workout.uphill or Decimal(0))
-
-        return stats
-
-    def get_week_stats(self, day):
-        """
-        Return some stats for the week the given day is in.
-        """
-        week = get_week_days(day)
-
-        # filter workouts
-        workouts = []
-        for workout in self.workouts():
-            if week[0].date() <= workout.start.date() <= week[-1].date():
-                workouts.append(workout)
-
-        # build stats
-        stats = {}
-        for week_day in week:
-            stats[week_day] = {
-                'workouts': 0,
-                'time': timedelta(0),
-                'distance': Decimal(0),
-                'elevation': Decimal(0),
-                'sports': {}
-            }
-            for workout in workouts:
-                if workout.start.date() == week_day.date():
-                    day = stats[week_day]  # less typing, avoid long lines
-                    day['workouts'] += 1
-                    day['time'] += workout.duration or timedelta(seconds=0)
-                    day['distance'] += workout.distance or Decimal(0)
-                    day['elevation'] += workout.uphill or Decimal(0)
-                    if workout.sport not in day['sports']:
-                        day['sports'][workout.sport] = {
-                            'workouts': 0,
-                            'time': timedelta(seconds=0),
-                            'distance': Decimal(0),
-                            'elevation': Decimal(0),
-                        }
-                    day['sports'][workout.sport]['workouts'] += 1
-                    day['sports'][workout.sport]['time'] += (
-                        workout.duration or timedelta(0))
-                    day['sports'][workout.sport]['distance'] += (
-                        workout.distance or Decimal(0))
-                    day['sports'][workout.sport]['elevation'] += (
-                        workout.uphill or Decimal(0))
-
-        return stats
-
-    @property
-    def week_stats(self):
-        """
-        Helper that returns the week stats for the current week
-        """
-        return self.get_week_stats(datetime.now(timezone.utc))
-
-    @property
-    def week_totals(self):
-        week_stats = self.week_stats
-        return {
-            'distance': sum([week_stats[t]['distance'] for t in week_stats]),
-            'time': sum([week_stats[t]['time'] for t in week_stats],
-                        timedelta())
-        }
-
-    @property
-    def yearly_stats(self):
-        """
-        Return per-month stats for the last 12 months
-        """
-        # set the boundaries for looking for workouts afterwards,
-        # we need the current date as the "end date" and one year
-        # ago from that date. Then we set the start at the first
-        # day of that month.
-        end = datetime.now(timezone.utc)
-        start = (end - timedelta(days=365)).replace(day=1)
-
-        # build the stats, populating first the dict with empty values
-        # for each month.
-        stats = {}
-        for days in range((end - start).days):
-            day = (start + timedelta(days=days)).date()
-            if (day.year, day.month) not in stats.keys():
-                stats[(day.year, day.month)] = {
-                    'workouts': 0,
-                    'time': timedelta(0),
-                    'distance': Decimal(0),
-                    'elevation': Decimal(0),
-                    'sports': {}
-                }
-
-        # now loop over workouts, filtering and then adding stats to the
-        # proper place
-        for workout in self.workouts():
-            if start.date() <= workout.start.date() <= end.date():
-                # less typing, avoid long lines
-                month = stats[
-                    (workout.start.date().year, workout.start.date().month)]
-                month['workouts'] += 1
-                month['time'] += workout.duration or timedelta(seconds=0)
-                month['distance'] += workout.distance or Decimal(0)
-                month['elevation'] += workout.uphill or Decimal(0)
-                if workout.sport not in month['sports']:
-                    month['sports'][workout.sport] = {
-                        'workouts': 0,
-                        'time': timedelta(seconds=0),
-                        'distance': Decimal(0),
-                        'elevation': Decimal(0),
-                    }
-                month['sports'][workout.sport]['workouts'] += 1
-                month['sports'][workout.sport]['time'] += (
-                    workout.duration or timedelta(0))
-                month['sports'][workout.sport]['distance'] += (
-                    workout.distance or Decimal(0))
-                month['sports'][workout.sport]['elevation'] += (
-                    workout.uphill or Decimal(0))
-
-        return stats
-
-    @property
-    def weekly_year_stats(self):
-        """
-        Return per-week stats for the last 12 months
-        """
-        # set the boundaries for looking for workouts afterwards,
-        # we need the current date as the "end date" and one year
-        # ago from that date. Then we set the start at the first
-        # day of that month.
-        end = datetime.now(timezone.utc)
-        start = (end - timedelta(days=365)).replace(day=1)
-
-        stats = {}
-
-        # first initialize the stats dict
-        for days in range((end - start).days):
-            day = (start + timedelta(days=days)).date()
-            week = day.isocalendar()[1]
-            month_week = get_month_week_number(day)
-            key = (day.year, day.month, week, month_week)
-            if key not in stats.keys():
-                stats[key] = {
-                    'workouts': 0,
-                    'time': timedelta(0),
-                    'distance': Decimal(0),
-                    'elevation': Decimal(0),
-                    'sports': {}
-                }
-
-        # now loop over the workouts, filtering and then adding stats
-        # to the proper place
-        for workout in self.workouts():
-            if start.date() <= workout.start.date() <= end.date():
-                # less typing, avoid long lines
-                start_date = workout.start.date()
-                week = start_date.isocalendar()[1]
-                month_week = get_month_week_number(start_date)
-                week = stats[(start_date.year,
-                              start_date.month,
-                              week,
-                              month_week)]
-
-                week['workouts'] += 1
-                week['time'] += workout.duration or timedelta(seconds=0)
-                week['distance'] += workout.distance or Decimal(0)
-                week['elevation'] += workout.uphill or Decimal(0)
-                if workout.sport not in week['sports']:
-                    week['sports'][workout.sport] = {
-                        'workouts': 0,
-                        'time': timedelta(seconds=0),
-                        'distance': Decimal(0),
-                        'elevation': Decimal(0),
-                    }
-                week['sports'][workout.sport]['workouts'] += 1
-                week['sports'][workout.sport]['time'] += (
-                    workout.duration or timedelta(0))
-                week['sports'][workout.sport]['distance'] += (
-                    workout.distance or Decimal(0))
-                week['sports'][workout.sport]['elevation'] += (
-                    workout.uphill or Decimal(0))
-
-        return stats
-
-    def sport_totals(self, sport=None, year=None):
-        """
-        Return totals for this user, filtered by sport.
-
-        If no sport is passed, the favorite sport is picked up
-
-        If the additional parameter year is passed, show stats only
-        for that year
-        """
-        totals = {
-            'workouts': 0,
-            'time': timedelta(0),
-            'distance': Decimal(0),
-            'elevation': Decimal(0),
-            'max_time': timedelta(0),
-            'max_time_wid': None,
-            'max_distance': Decimal(0),
-            'max_distance_wid': None,
-            'max_elevation': Decimal(0),
-            'max_elevation_wid': None
-        }
-
-        if self.activity_sports:
-            sport = sport or self.favorite_sport
-            for workout in self.workouts():
-                if workout.sport == sport:
-                    if year is None or workout.start.year == year:
-                        wid = str(workout.workout_id)
-                        time = workout.duration or timedelta(0)
-                        distance = workout.distance or Decimal(0)
-                        elevation = workout.uphill or Decimal(0)
-                        totals['workouts'] += 1
-                        totals['time'] += time
-                        totals['distance'] += distance
-                        totals['elevation'] += elevation
-                        if time > totals['max_time']:
-                            totals['max_time'] = time
-                            totals['max_time_wid'] = wid
-                        if distance > totals['max_distance']:
-                            totals['max_distance'] = distance
-                            totals['max_distance_wid'] = wid
-                        if elevation > totals['max_elevation']:
-                            totals['max_elevation'] = elevation
-                            totals['max_elevation_wid'] = wid
-
-        return totals
