source: OpenWorkouts-current/ow/models/user.py @ 2d91474

currentfeature/docs
Last change on this file since 2d91474 was 2d91474, checked in by borja <borja@…>, 5 years ago

(#23) - Show workouts in the dashboard with date filtering

  • Property mode set to 100644
File size: 3.9 KB
Line 
1
2from uuid import uuid1
3from operator import attrgetter
4
5import bcrypt
6from repoze.folder import Folder
7from pyramid.security import Allow
8
9from ow.catalog import get_catalog, reindex_object
10
11
12class User(Folder):
13
14    __parent__ = __name__ = None
15
16    def __acl__(self):
17        permissions = [
18            (Allow, str(self.uid), 'edit'),
19            (Allow, str(self.uid), 'view'),
20        ]
21        return permissions
22
23    def __init__(self, **kw):
24        self.uid = kw.get('uid', uuid1())
25        self.nickname = kw.get('nickname', '')
26        self.firstname = kw.get('firstname', '')
27        self.lastname = kw.get('lastname', '')
28        self.email = kw.get('email', '')
29        self.bio = kw.get('bio', '')
30        self.birth_date = kw.get('birth_date', None)
31        self.height = kw.get('height', None)
32        self.weight = kw.get('weight', None)
33        self.gender = kw.get('gender', 'female')
34        self.picture = kw.get('picture', None)  # blob
35        self.timezone = kw.get('timezone', 'UTC')
36        self.__password = None
37        self.last_workout_id = 0
38        super(User, self).__init__()
39
40    def __str__(self):
41        return u'User: %s (%s)' % (self.email, self.uid)
42
43    @property
44    def password(self):
45        return self.__password
46
47    @password.setter
48    def password(self, password=None):
49        """
50        Sets a password for the user, hashing with bcrypt.
51        """
52        password = password.encode('utf-8')
53        self.__password = bcrypt.hashpw(password, bcrypt.gensalt())
54
55    def check_password(self, password):
56        """
57        Check a plain text password against a hashed one
58        """
59        hashed = bcrypt.hashpw(password.encode('utf-8'), self.__password)
60        return hashed == self.__password
61
62    @property
63    def fullname(self):
64        """
65        Naive implementation of fullname: firstname + lastname
66        """
67        return u'%s %s' % (self.firstname, self.lastname)
68
69    def add_workout(self, workout):
70        # This returns the main catalog at the root folder
71        catalog = get_catalog(self)
72        self.last_workout_id += 1
73        workout_id = str(self.last_workout_id)
74        self[workout_id] = workout
75        reindex_object(catalog, workout)
76
77    def workouts(self, year=None, month=None):
78        """
79        Return this user workouts, sorted by date, from newer to older
80        """
81        workouts = self.values()
82        if year:
83            workouts = [w for w in workouts if w.start.year == year]
84        if month:
85            workouts = [w for w in workouts if w.start.month == month]
86        workouts = sorted(workouts, key=attrgetter('start'))
87        workouts.reverse()
88        return workouts
89
90    def workout_ids(self):
91        return self.keys()
92
93    @property
94    def num_workouts(self):
95        return len(self.workout_ids())
96
97    @property
98    def activity_years(self):
99        return sorted(list(set(w.start.year for w in self.workouts())),
100                      reverse=True)
101
102    def activity_months(self, year):
103        months = set(
104            w.start.month for w in self.workouts() if w.start.year == year)
105        return sorted(list(months))
106
107    @property
108    def activity_dates_tree(self):
109        """
110        Return a dict containing information about the activity for this
111        user.
112
113        Example:
114
115        {
116            2019: {
117                1: {'cycling': 12, 'running': 1}
118            },
119            2018: {
120                1: {'cycling': 10, 'running': 3},
121                2: {'cycling': 14, 'swimming': 5}
122            }
123        }
124        """
125        tree = {}
126        for workout in self.workouts():
127            year = workout.start.year
128            month = workout.start.month
129            sport = workout.sport
130            if year not in tree:
131                tree[year] = {}
132            if month not in tree[year]:
133                tree[year][month] = {}
134            if sport not in tree[year][month]:
135                tree[year][month][sport] = 0
136            tree[year][month][sport] += 1
137        return tree
Note: See TracBrowser for help on using the repository browser.