[Migration] move update_flattr_settings to view
[mygpo.git] / mygpo / db / couchdb / user.py
blob58b15e647fd52412c2ba82807a25371140cca5c8
1 from collections import Counter
3 from couchdbkit import ResourceNotFound
5 from django.db.models import Count
6 from django.contrib.auth import get_user_model
8 from mygpo.cache import cache_result
9 from mygpo.decorators import repeat_on_conflict
10 from mygpo.db.couchdb import get_userdata_database, \
11 get_single_result, get_suggestions_database
12 from mygpo.db import QueryParameterMissing
15 @cache_result(timeout=60)
16 def get_num_listened_episodes(user):
18 if not user:
19 raise QueryParameterMissing('user')
21 udb = get_userdata_database()
22 r = udb.view('listeners/by_user_podcast',
23 startkey = [user.profile.uuid.hex, None],
24 endkey = [user.profile.uuid.hex, {}],
25 reduce = True,
26 group_level = 2,
27 stale = 'update_after',
30 return map(_wrap_num_listened, r)
33 def _wrap_num_listened(obj):
34 count = obj['value']
35 podcast = obj['key'][1]
36 return (podcast, count)
39 @cache_result(timeout=60)
40 def get_num_played_episodes(user, since=None, until={}):
41 """ Number of played episodes in interval """
43 if not user:
44 raise QueryParameterMissing('user')
46 since_str = since.strftime('%Y-%m-%d') if since else None
47 until_str = until.strftime('%Y-%m-%d') if until else {}
49 startkey = [user.profile.uuid.hex, since_str]
50 endkey = [user.profile.uuid.hex, until_str]
52 udb = get_userdata_database()
53 val = get_single_result(udb, 'listeners/by_user',
54 startkey = startkey,
55 endkey = endkey,
56 reduce = True,
57 stale = 'update_after',
60 return val['value'] if val else 0
65 @cache_result(timeout=60)
66 def get_latest_episode_ids(user, count=10):
67 """ Returns the latest episodes that the user has accessed """
69 if not user:
70 raise QueryParameterMissing('user')
72 startkey = [user.profile.uuid.hex, {}]
73 endkey = [user.profile.uuid.hex, None]
75 udb = get_userdata_database()
76 res = udb.view('listeners/by_user',
77 startkey = startkey,
78 endkey = endkey,
79 include_docs = True,
80 descending = True,
81 limit = count,
82 reduce = False,
83 stale = 'update_after',
86 return [r['value'] for r in res]
90 @cache_result(timeout=60)
91 def get_seconds_played(user, since=None, until={}):
92 """ Returns the number of seconds that the user has listened
94 Can be selected by timespan, podcast and episode """
96 if not user:
97 raise QueryParameterMissing('user')
99 since_str = since.strftime('%Y-%m-%dT%H:%M:%S') if since else None
100 until_str = until.strftime('%Y-%m-%dT%H:%M:%S') if until else {}
102 startkey = [user.profile.uuid.hex, since_str]
103 endkey = [user.profile.uuid.hex, until_str]
105 udb = get_userdata_database()
106 val = get_single_result(udb, 'listeners/times_played_by_user',
107 startkey = startkey,
108 endkey = endkey,
109 reduce = True,
110 stale = 'update_after',
113 return val['value'] if val else 0
117 @cache_result(timeout=60*60)
118 def suggestions_for_user(user):
120 if not user:
121 raise QueryParameterMissing('user')
123 from mygpo.users.models import Suggestions
124 sdb = get_suggestions_database()
125 s = get_single_result(sdb, 'suggestions/by_user',
126 key = user.profile.uuid.hex,
127 include_docs = True,
128 schema = Suggestions,
131 if not s:
132 s = Suggestions()
133 s.user = user.profile.uuid.hex
135 return s
138 @repeat_on_conflict(['suggestions'])
139 def update_suggestions(suggestions, podcast_ids):
140 """ Updates the suggestions object with new suggested podcasts """
142 if suggestions.podcasts == podcast_ids:
143 return
145 sdb = get_suggestions_database()
146 suggestions.podcasts = podcast_ids
147 sdb.save_doc(suggestions)
150 @repeat_on_conflict(['suggestions'])
151 def blacklist_suggested_podcast(suggestions, podcast_id):
152 """ Adds a podcast to the list of unwanted suggestions """
154 if podcast_id in suggestions.blacklist:
155 return
157 sdb = get_suggestions_database()
158 suggestions.blacklist.append(podcast_id)
159 sdb.save_doc(suggestions)
162 @cache_result(timeout=60)
163 def user_history(user, start, length):
165 if not user:
166 raise QueryParameterMissing('user')
168 if length <= 0:
169 return []
171 udb = get_userdata_database()
172 res = udb.view('history/by_user',
173 descending = True,
174 startkey = [user.profile.uuid.hex, {}],
175 endkey = [user.profile.uuid.hex, None],
176 limit = length,
177 skip = start,
180 return map(_wrap_historyentry, res)
183 @cache_result(timeout=60)
184 def device_history(user, device, start, length):
186 if not user:
187 raise QueryParameterMissing('user')
189 if not device:
190 raise QueryParameterMissing('device')
192 if length <= 0:
193 return []
195 udb = get_userdata_database()
197 res = udb.view('history/by_device',
198 descending = True,
199 startkey = [user.profile.uuid.hex, device.id, {}],
200 endkey = [user.profile.uuid.hex, device.id, None],
201 limit = length,
202 skip = start,
205 return map(_wrap_historyentry, res)
208 def _wrap_historyentry(action):
209 from mygpo.users.models import HistoryEntry
210 return HistoryEntry.from_action_dict(action['value'])
213 def user_by_google_email(email):
214 """ Get a user by its connected Google account """
215 User = get_user_model()
216 try:
217 return User.objects.get(profile__google_email=email)
218 except User.DoesNotExist:
219 return None
222 @repeat_on_conflict(['user'])
223 def set_users_google_email(user, email):
224 """ Update the Google accoutn connected with the user """
226 if user.google_email == email:
227 return user
229 user.google_email = email
230 user.save()
231 return user
234 def get_user_by_id(user_id):
235 User = get_user_model()
236 try:
237 User.objects.get(profile__uuid=user_id)
238 except User.DoesNotExist:
239 return None
242 @repeat_on_conflict(['user'])
243 def activate_user(user):
244 """ activates a user so that he is able to login """
245 user.is_active = True
246 user.activation_key = None
247 user.save()
250 @repeat_on_conflict(['user'])
251 def set_device_deleted(user, device, is_deleted):
252 device.deleted = is_deleted
253 user.set_device(device)
254 user.save()
257 @repeat_on_conflict(['state'])
258 def update_device_state(state, devices):
259 old_devs = set(state.disabled_devices)
260 state.set_device_state(devices)
262 if old_devs != set(state.disabled_devices):
263 udb = get_userdata_database()
264 udb.save_doc(state)
267 @repeat_on_conflict(['user'])
268 def unsync_device(user, device):
269 if user.is_synced(device):
270 user.unsync_device(device)
271 user.save()
274 @repeat_on_conflict(['user'])
275 def set_device(user, device):
276 user.set_device(device)
277 user.save()
280 @repeat_on_conflict(['user'])
281 def create_missing_user_tokens(user):
283 generated = False
285 from mygpo.users.models import TOKEN_NAMES
286 for tn in TOKEN_NAMES:
287 if getattr(user, tn) is None:
288 user.create_new_token(tn)
289 generated = True
291 if generated:
292 user.save()
294 @repeat_on_conflict(['user'])
295 def add_published_objs(user, ids):
296 """ Adds published objects to the user """
297 user.published_objects = list(set(user.published_objects + list(ids)))
298 user.save()