[Migration] fix typo
[mygpo.git] / mygpo / db / couchdb / user.py
blob17326d3d9f779302537c4a8aa7e950946b2c06c8
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, get_userdata_database, \
8 get_single_result, get_suggestions_database
9 from mygpo.users.settings import FLATTR_TOKEN, FLATTR_AUTO, FLATTR_MYGPO, \
10 FLATTR_USERNAME
11 from mygpo.db import QueryParameterMissing
14 @cache_result(timeout=60)
15 def get_num_listened_episodes(user):
17 if not user:
18 raise QueryParameterMissing('user')
20 udb = get_userdata_database()
21 r = udb.view('listeners/by_user_podcast',
22 startkey = [user._id, None],
23 endkey = [user._id, {}],
24 reduce = True,
25 group_level = 2,
26 stale = 'update_after',
29 return map(_wrap_num_listened, r)
32 def _wrap_num_listened(obj):
33 count = obj['value']
34 podcast = obj['key'][1]
35 return (podcast, count)
38 @cache_result(timeout=60)
39 def get_num_played_episodes(user, since=None, until={}):
40 """ Number of played episodes in interval """
42 if not user:
43 raise QueryParameterMissing('user')
45 since_str = since.strftime('%Y-%m-%d') if since else None
46 until_str = until.strftime('%Y-%m-%d') if until else {}
48 startkey = [user._id, since_str]
49 endkey = [user._id, until_str]
51 udb = get_userdata_database()
52 val = get_single_result(udb, 'listeners/by_user',
53 startkey = startkey,
54 endkey = endkey,
55 reduce = True,
56 stale = 'update_after',
59 return val['value'] if val else 0
64 @cache_result(timeout=60)
65 def get_latest_episode_ids(user, count=10):
66 """ Returns the latest episodes that the user has accessed """
68 if not user:
69 raise QueryParameterMissing('user')
71 startkey = [user._id, {}]
72 endkey = [user._id, None]
74 udb = get_userdata_database()
75 res = udb.view('listeners/by_user',
76 startkey = startkey,
77 endkey = endkey,
78 include_docs = True,
79 descending = True,
80 limit = count,
81 reduce = False,
82 stale = 'update_after',
85 return [r['value'] for r in res]
89 @cache_result(timeout=60)
90 def get_seconds_played(user, since=None, until={}):
91 """ Returns the number of seconds that the user has listened
93 Can be selected by timespan, podcast and episode """
95 if not user:
96 raise QueryParameterMissing('user')
98 since_str = since.strftime('%Y-%m-%dT%H:%M:%S') if since else None
99 until_str = until.strftime('%Y-%m-%dT%H:%M:%S') if until else {}
101 startkey = [user._id, since_str]
102 endkey = [user._id, until_str]
104 udb = get_userdata_database()
105 val = get_single_result(udb, 'listeners/times_played_by_user',
106 startkey = startkey,
107 endkey = endkey,
108 reduce = True,
109 stale = 'update_after',
112 return val['value'] if val else 0
116 @cache_result(timeout=60*60)
117 def suggestions_for_user(user):
119 if not user:
120 raise QueryParameterMissing('user')
122 from mygpo.users.models import Suggestions
123 sdb = get_suggestions_database()
124 s = get_single_result(sdb, 'suggestions/by_user',
125 key = user._id,
126 include_docs = True,
127 schema = Suggestions,
130 if not s:
131 s = Suggestions()
132 s.user = user._id
134 return s
137 @repeat_on_conflict(['suggestions'])
138 def update_suggestions(suggestions, podcast_ids):
139 """ Updates the suggestions object with new suggested podcasts """
141 if suggestions.podcasts == podcast_ids:
142 return
144 sdb = get_suggestions_database()
145 suggestions.podcasts = podcast_ids
146 sdb.save_doc(suggestions)
149 @repeat_on_conflict(['suggestions'])
150 def blacklist_suggested_podcast(suggestions, podcast_id):
151 """ Adds a podcast to the list of unwanted suggestions """
153 if podcast_id in suggestions.blacklist:
154 return
156 sdb = get_suggestions_database()
157 suggestions.blacklist.append(podcast_id)
158 sdb.save_doc(suggestions)
161 @cache_result(timeout=60*60)
162 def user_agent_stats():
163 from mygpo.users.models import User
164 res = User.view('clients/by_ua_string',
165 wrap_doc = False,
166 group_level = 1,
167 stale = 'update_after',
170 return Counter(dict((r['key'], r['value']) for r in res))
173 def deleted_users():
174 from mygpo.users.models import User
175 users = User.view('users/deleted',
176 include_docs = True,
177 reduce = False,
179 return list(users)
182 def deleted_user_count():
183 from mygpo.users.models import User
184 total = User.view('users/deleted',
185 reduce = True,
187 return list(total)[0]['value'] if total else 0
191 @cache_result(timeout=60)
192 def user_history(user, start, length):
194 if not user:
195 raise QueryParameterMissing('user')
197 if length <= 0:
198 return []
200 udb = get_userdata_database()
201 res = udb.view('history/by_user',
202 descending = True,
203 startkey = [user._id, {}],
204 endkey = [user._id, None],
205 limit = length,
206 skip = start,
209 return map(_wrap_historyentry, res)
212 @cache_result(timeout=60)
213 def device_history(user, device, start, length):
215 if not user:
216 raise QueryParameterMissing('user')
218 if not device:
219 raise QueryParameterMissing('device')
221 if length <= 0:
222 return []
224 udb = get_userdata_database()
226 res = udb.view('history/by_device',
227 descending = True,
228 startkey = [user._id, device.id, {}],
229 endkey = [user._id, device.id, None],
230 limit = length,
231 skip = start,
234 return map(_wrap_historyentry, res)
237 @repeat_on_conflict(['user'])
238 def update_flattr_settings(user, token, enabled=None, flattr_mygpo=False,
239 username=None):
240 """ Updates the Flattr settings of a user """
242 if enabled is not None:
243 user.settings[FLATTR_AUTO.name] = enabled
245 if token is not None:
246 user.settings[FLATTR_TOKEN.name] = token
248 if flattr_mygpo is not None:
249 user.settings[FLATTR_MYGPO.name] = flattr_mygpo
251 if username is not None:
252 user.settings[FLATTR_USERNAME.name] = username
254 user.save()
257 def _wrap_historyentry(action):
258 from mygpo.users.models import HistoryEntry
259 return HistoryEntry.from_action_dict(action['value'])
262 def user_by_google_email(email):
263 """ Get a user by its connected Google account """
265 from mygpo.users.models import User
266 users = User.view('users/by_google_email',
267 key = email,
268 include_docs = True,
271 if not users:
272 return None
274 return users.one()
277 @repeat_on_conflict(['user'])
278 def set_users_google_email(user, email):
279 """ Update the Google accoutn connected with the user """
281 if user.google_email == email:
282 return user
284 user.google_email = email
285 user.save()
286 return user
289 def get_user_by_id(user_id):
290 from mygpo.users.models import User
291 try:
292 return User.get(user_id)
293 except ResourceNotFound:
294 return None
297 @repeat_on_conflict(['user'])
298 def activate_user(user):
299 """ activates a user so that he is able to login """
300 user.is_active = True
301 user.activation_key = None
302 user.save()
305 @repeat_on_conflict(['user'])
306 def set_device_deleted(user, device, is_deleted):
307 device.deleted = is_deleted
308 user.set_device(device)
309 user.save()
312 @repeat_on_conflict(['state'])
313 def update_device_state(state, devices):
314 old_devs = set(state.disabled_devices)
315 state.set_device_state(devices)
317 if old_devs != set(state.disabled_devices):
318 udb = get_userdata_database()
319 udb.save_doc(state)
322 @repeat_on_conflict(['user'])
323 def unsync_device(user, device):
324 if user.is_synced(device):
325 user.unsync_device(device)
326 user.save()
329 @repeat_on_conflict(['user'])
330 def set_device(user, device):
331 user.set_device(device)
332 user.save()
335 @repeat_on_conflict(['user'])
336 def create_missing_user_tokens(user):
338 generated = False
340 from mygpo.users.models import TOKEN_NAMES
341 for tn in TOKEN_NAMES:
342 if getattr(user, tn) is None:
343 user.create_new_token(tn)
344 generated = True
346 if generated:
347 user.save()
349 @repeat_on_conflict(['user'])
350 def add_published_objs(user, ids):
351 """ Adds published objects to the user """
352 user.published_objects = list(set(user.published_objects + list(ids)))
353 user.save()