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
):
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, {}],
27 stale
= 'update_after',
30 return map(_wrap_num_listened
, r
)
33 def _wrap_num_listened(obj
):
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 """
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',
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 """
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',
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 """
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',
110 stale
= 'update_after',
113 return val
['value'] if val
else 0
117 @cache_result(timeout
=60*60)
118 def suggestions_for_user(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,
128 schema
= Suggestions
,
133 s
.user
= user
.profile
.uuid
.hex
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
:
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
:
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
):
166 raise QueryParameterMissing('user')
171 udb
= get_userdata_database()
172 res
= udb
.view('history/by_user',
174 startkey
= [user
.profile
.uuid
.hex, {}],
175 endkey
= [user
.profile
.uuid
.hex, None],
180 return map(_wrap_historyentry
, res
)
183 @cache_result(timeout
=60)
184 def device_history(user
, device
, start
, length
):
187 raise QueryParameterMissing('user')
190 raise QueryParameterMissing('device')
195 udb
= get_userdata_database()
197 res
= udb
.view('history/by_device',
199 startkey
= [user
.profile
.uuid
.hex, device
.id, {}],
200 endkey
= [user
.profile
.uuid
.hex, device
.id, None],
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()
217 return User
.objects
.get(profile__google_email
=email
)
218 except User
.DoesNotExist
:
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
:
229 user
.google_email
= email
234 def get_user_by_id(user_id
):
235 User
= get_user_model()
237 User
.objects
.get(profile__uuid
=user_id
)
238 except User
.DoesNotExist
:
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
250 @repeat_on_conflict(['user'])
251 def set_device_deleted(user
, device
, is_deleted
):
252 device
.deleted
= is_deleted
253 user
.set_device(device
)
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()
267 @repeat_on_conflict(['user'])
268 def unsync_device(user
, device
):
269 if user
.is_synced(device
):
270 user
.unsync_device(device
)
274 @repeat_on_conflict(['user'])
275 def set_device(user
, device
):
276 user
.set_device(device
)
280 @repeat_on_conflict(['user'])
281 def create_missing_user_tokens(user
):
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
)
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
)))