assign publisher permissions via web interface
[mygpo.git] / mygpo / db / couchdb / user.py
blobc88feb63d2d0802caf2d277a155a5b9d9304aa9d
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
9 from mygpo.users.settings import FLATTR_TOKEN, FLATTR_AUTO, FLATTR_MYGPO, \
10 FLATTR_USERNAME
11 from mygpo.db import QueryParameterMissing
12 from mygpo.db.couchdb.episode import episodes_by_id
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._id, None],
24 endkey = [user._id, {}],
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._id, since_str]
50 endkey = [user._id, 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_episodes(user, count=10):
67 """ Returns the latest episodes that the user has accessed """
69 if not user:
70 raise QueryParameterMissing('user')
72 startkey = [user._id, {}]
73 endkey = [user._id, 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 keys = [r['value'] for r in res]
87 return episodes_by_id(keys)
91 @cache_result(timeout=60)
92 def get_seconds_played(user, since=None, until={}):
93 """ Returns the number of seconds that the user has listened
95 Can be selected by timespan, podcast and episode """
97 if not user:
98 raise QueryParameterMissing('user')
100 since_str = since.strftime('%Y-%m-%dT%H:%M:%S') if since else None
101 until_str = until.strftime('%Y-%m-%dT%H:%M:%S') if until else {}
103 startkey = [user._id, since_str]
104 endkey = [user._id, until_str]
106 udb = get_userdata_database()
107 val = get_single_result(udb, 'listeners/times_played_by_user',
108 startkey = startkey,
109 endkey = endkey,
110 reduce = True,
111 stale = 'update_after',
114 return val['value'] if val else 0
118 @cache_result(timeout=60*60)
119 def suggestions_for_user(user):
121 if not user:
122 raise QueryParameterMissing('user')
124 from mygpo.users.models import Suggestions
125 db = get_main_database()
126 s = get_single_result(db, 'suggestions/by_user',
127 key = user._id,
128 include_docs = True,
129 schema = Suggestions,
132 if not s:
133 s = Suggestions()
134 s.user = user._id
136 return s
139 @cache_result(timeout=60*60)
140 def user_agent_stats():
141 from mygpo.users.models import User
142 res = User.view('clients/by_ua_string',
143 wrap_doc = False,
144 group_level = 1,
145 stale = 'update_after',
148 return Counter(dict((r['key'], r['value']) for r in res))
151 def deleted_users():
152 from mygpo.users.models import User
153 users = User.view('users/deleted',
154 include_docs = True,
155 reduce = False,
157 return list(users)
160 def deleted_user_count():
161 from mygpo.users.models import User
162 total = User.view('users/deleted',
163 reduce = True,
165 return list(total)[0]['value'] if total else 0
169 @cache_result(timeout=60)
170 def user_history(user, start, length):
172 if not user:
173 raise QueryParameterMissing('user')
175 if length <= 0:
176 return []
178 udb = get_userdata_database()
179 res = udb.view('history/by_user',
180 descending = True,
181 startkey = [user._id, {}],
182 endkey = [user._id, None],
183 limit = length,
184 skip = start,
187 return map(_wrap_historyentry, res)
190 @cache_result(timeout=60)
191 def device_history(user, device, start, length):
193 if not user:
194 raise QueryParameterMissing('user')
196 if not device:
197 raise QueryParameterMissing('device')
199 if length <= 0:
200 return []
202 udb = get_userdata_database()
204 res = udb.view('history/by_device',
205 descending = True,
206 startkey = [user._id, device.id, {}],
207 endkey = [user._id, device.id, None],
208 limit = length,
209 skip = start,
212 return map(_wrap_historyentry, res)
215 @repeat_on_conflict(['user'])
216 def update_flattr_settings(user, token, enabled=None, flattr_mygpo=False,
217 username=None):
218 """ Updates the Flattr settings of a user """
220 if enabled is not None:
221 user.settings[FLATTR_AUTO.name] = enabled
223 if token is not None:
224 user.settings[FLATTR_TOKEN.name] = token
226 if flattr_mygpo is not None:
227 user.settings[FLATTR_MYGPO.name] = flattr_mygpo
229 if username is not None:
230 user.settings[FLATTR_USERNAME.name] = username
232 user.save()
235 def _wrap_historyentry(action):
236 from mygpo.users.models import HistoryEntry
237 return HistoryEntry.from_action_dict(action['value'])
240 def user_by_google_email(email):
241 """ Get a user by its connected Google account """
243 from mygpo.users.models import User
244 users = User.view('users/by_google_email',
245 key = email,
246 include_docs = True,
249 if not users:
250 return None
252 return users.one()
255 @repeat_on_conflict(['user'])
256 def set_users_google_email(user, email):
257 """ Update the Google accoutn connected with the user """
259 if user.google_email == email:
260 return user
262 user.google_email = email
263 user.save()
264 return user
267 def get_user_by_id(user_id):
268 from mygpo.users.models import User
269 try:
270 return User.get(user_id)
271 except ResourceNotFound:
272 return None
275 @repeat_on_conflict(['user'])
276 def activate_user(user):
277 """ activates a user so that he is able to login """
278 user.is_active = True
279 user.activation_key = None
280 user.save()
283 @repeat_on_conflict(['user'])
284 def set_device_deleted(user, device, is_deleted):
285 device.deleted = is_deleted
286 user.set_device(device)
287 user.save()
290 @repeat_on_conflict(['state'])
291 def update_device_state(state, devices):
292 old_devs = set(state.disabled_devices)
293 state.set_device_state(devices)
295 if old_devs != set(state.disabled_devices):
296 udb = get_userdata_database()
297 udb.save_doc(state)
300 @repeat_on_conflict(['user'])
301 def unsync_device(user, device):
302 if user.is_synced(device):
303 user.unsync_device(device)
304 user.save()
307 @repeat_on_conflict(['user'])
308 def set_device(user, device):
309 user.set_device(device)
310 user.save()
313 @repeat_on_conflict(['user'])
314 def create_missing_user_tokens(user):
316 generated = False
318 from mygpo.users.models import TOKEN_NAMES
319 for tn in TOKEN_NAMES:
320 if getattr(user, tn) is None:
321 user.create_new_token(tn)
322 generated = True
324 if generated:
325 user.save()
327 @repeat_on_conflict(['user'])
328 def add_published_objs(user, ids):
329 """ Adds published objects to the user """
330 user.published_objects = list(set(user.published_objects + list(ids)))
331 user.save()