d82ce2e657c20585230dcaa55ec90c60f4ebbf36
[mygpo.git] / mygpo / db / couchdb / user.py
blobd82ce2e657c20585230dcaa55ec90c60f4ebbf36
1 from collections import Counter
3 from couchdbkit import ResourceNotFound
5 from mygpo.cache import cache_result
6 from mygpo.decorators import repeat_on_conflict
7 from mygpo.db.couchdb import get_main_database
8 from mygpo.users.settings import FLATTR_TOKEN, FLATTR_AUTO, FLATTR_MYGPO, \
9 FLATTR_USERNAME
10 from mygpo.db import QueryParameterMissing
11 from mygpo.db.couchdb.episode import episodes_by_id
14 @cache_result(timeout=60)
15 def get_num_listened_episodes(user):
17 if not user:
18 raise QueryParameterMissing('user')
20 db = get_main_database()
21 r = db.view('listeners/by_user_podcast',
22 startkey = [user._id, None],
23 endkey = [user._id, {}],
24 reduce = True,
25 group_level = 2,
28 return map(_wrap_num_listened, r)
31 def _wrap_num_listened(obj):
32 count = obj['value']
33 podcast = obj['key'][1]
34 return (podcast, count)
37 @cache_result(timeout=60)
38 def get_num_played_episodes(user, since=None, until={}):
39 """ Number of played episodes in interval """
41 if not user:
42 raise QueryParameterMissing('user')
44 since_str = since.strftime('%Y-%m-%d') if since else None
45 until_str = until.strftime('%Y-%m-%d') if until else {}
47 startkey = [user._id, since_str]
48 endkey = [user._id, until_str]
50 db = get_main_database()
51 res = db.view('listeners/by_user',
52 startkey = startkey,
53 endkey = endkey,
54 reduce = True,
57 val = res.one()
58 return val['value'] if val else 0
63 @cache_result(timeout=60)
64 def get_latest_episodes(user, count=10):
65 """ Returns the latest episodes that the user has accessed """
67 if not user:
68 raise QueryParameterMissing('user')
70 startkey = [user._id, {}]
71 endkey = [user._id, None]
73 db = get_main_database()
74 res = db.view('listeners/by_user',
75 startkey = startkey,
76 endkey = endkey,
77 include_docs = True,
78 descending = True,
79 limit = count,
80 reduce = False,
83 keys = [r['value'] for r in res]
84 return episodes_by_id(keys)
88 @cache_result(timeout=60)
89 def get_seconds_played(user, since=None, until={}):
90 """ Returns the number of seconds that the user has listened
92 Can be selected by timespan, podcast and episode """
94 if not user:
95 raise QueryParameterMissing('user')
97 since_str = since.strftime('%Y-%m-%dT%H:%M:%S') if since else None
98 until_str = until.strftime('%Y-%m-%dT%H:%M:%S') if until else {}
100 startkey = [user._id, since_str]
101 endkey = [user._id, until_str]
103 db = get_main_database()
104 res = db.view('listeners/times_played_by_user',
105 startkey = startkey,
106 endkey = endkey,
107 reduce = True,
110 val = res.one()
111 return val['value'] if val else 0
115 @cache_result(timeout=60*60)
116 def suggestions_for_user(user):
118 if not user:
119 raise QueryParameterMissing('user')
121 from mygpo.users.models import Suggestions
122 r = Suggestions.view('suggestions/by_user',
123 key = user._id,
124 include_docs = True,
127 if r:
128 return r.first()
130 else:
131 s = Suggestions()
132 s.user = user._id
133 return s
136 @cache_result(timeout=60*60)
137 def user_agent_stats():
138 from mygpo.users.models import User
139 res = User.view('clients/by_ua_string',
140 wrap_doc = False,
141 group_level = 1,
142 stale = 'update_after',
145 return Counter(dict((r['key'], r['value']) for r in res))
148 def deleted_users():
149 from mygpo.users.models import User
150 users = User.view('users/deleted',
151 include_docs = True,
152 reduce = False,
154 return list(users)
157 def deleted_user_count():
158 from mygpo.users.models import User
159 total = User.view('users/deleted',
160 reduce = True,
162 return list(total)[0]['value'] if total else 0
166 @cache_result(timeout=60)
167 def user_history(user, start, length):
169 if not user:
170 raise QueryParameterMissing('user')
172 if length <= 0:
173 return []
175 db = get_main_database()
176 res = db.view('history/by_user',
177 descending = True,
178 startkey = [user._id, {}],
179 endkey = [user._id, None],
180 limit = length,
181 skip = start,
184 return map(_wrap_historyentry, res)
187 @cache_result(timeout=60)
188 def device_history(user, device, start, length):
190 if not user:
191 raise QueryParameterMissing('user')
193 if not device:
194 raise QueryParameterMissing('device')
196 if length <= 0:
197 return []
199 db = get_main_database()
201 res = db.view('history/by_device',
202 descending = True,
203 startkey = [user._id, device.id, {}],
204 endkey = [user._id, device.id, None],
205 limit = length,
206 skip = start,
209 return map(_wrap_historyentry, res)
212 @repeat_on_conflict(['user'])
213 def update_flattr_settings(user, token, enabled=None, flattr_mygpo=False,
214 username=None):
215 """ Updates the Flattr settings of a user """
217 if enabled is not None:
218 user.settings[FLATTR_AUTO.name] = enabled
220 if token is not None:
221 user.settings[FLATTR_TOKEN.name] = token
223 if flattr_mygpo is not None:
224 user.settings[FLATTR_MYGPO.name] = flattr_mygpo
226 if username is not None:
227 user.settings[FLATTR_USERNAME.name] = username
229 user.save()
232 def _wrap_historyentry(action):
233 from mygpo.users.models import HistoryEntry
234 return HistoryEntry.from_action_dict(action['value'])
237 def user_by_google_email(email):
238 """ Get a user by its connected Google account """
240 from mygpo.users.models import User
241 users = User.view('users/by_google_email',
242 key = email,
243 include_docs = True,
246 if not users:
247 return None
249 return users.one()
252 @repeat_on_conflict(['user'])
253 def set_users_google_email(user, email):
254 """ Update the Google accoutn connected with the user """
256 if user.google_email == email:
257 return user
259 user.google_email = email
260 user.save()
261 return user
264 def get_user_by_id(user_id):
265 from mygpo.users.models import User
266 try:
267 return User.get(user_id)
268 except ResourceNotFound:
269 return None