2 # This file is part of my.gpodder.org.
4 # my.gpodder.org is free software: you can redistribute it and/or modify it
5 # under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or (at your
7 # option) any later version.
9 # my.gpodder.org is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
12 # License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with my.gpodder.org. If not, see <http://www.gnu.org/licenses/>.
18 from datetime
import timedelta
19 from collections
import defaultdict
20 from itertools
import cycle
23 from django
.core
.cache
import cache
25 from mygpo
.data
.mimetype
import get_type
, CONTENT_TYPES
26 from mygpo
.core
.models
import Podcast
, Episode
27 from mygpo
.users
.models
import EpisodeUserState
, Device
, DeviceDoesNotExist
28 from mygpo
.decorators
import repeat_on_conflict
29 from mygpo
.json
import json
32 def get_random_picks(languages
=None):
33 """ Returns random podcasts for the given language """
36 for podcast
in Podcast
.random():
39 counts
= cache
.get('podcast-language-counts')
41 counts
= get_podcast_count_for_language()
42 cache
.set('podcast-language-counts', counts
, 60*60)
45 # extract positive counts of all languages in language param
46 counts
= filter(lambda (l
, c
): l
in languages
and c
> 0, counts
.items())
48 for lang
, count
in cycle(counts
):
49 skip
= random
.randint(0, count
-1)
51 for podcast
in Podcast
.for_language(lang
, skip
=skip
, limit
=1):
56 def get_podcast_count_for_language():
57 """ Returns a the number of podcasts for each language """
59 counts
= defaultdict(int)
62 r
= db
.view('core/podcasts_by_language',
65 stale
= 'update_after',
68 counts
.update( dict( (x
['key'][0], x
['value']) for x
in r
) )
73 def get_device(user
, uid
, user_agent
, undelete
=True):
75 Loads or creates the device indicated by user, uid.
77 If the device has been deleted and undelete=True, it is undeleted.
80 store_ua
= user
.settings
.get('store_user_agent', True)
82 @repeat_on_conflict(['user'])
83 def _get(user
, uid
, undelete
):
88 device
= user
.get_device_by_uid(uid
, only_active
=False)
90 except DeviceDoesNotExist
:
91 device
= Device(uid
=uid
)
92 user
.devices
.append(device
)
95 if device
.deleted
and undelete
:
96 device
.deleted
= False
97 user
.set_device(device
)
100 if store_ua
and user_agent
and \
101 getattr(device
, 'user_agent', None) != user_agent
:
102 device
.user_agent
= user_agent
103 user
.set_device(device
)
111 return _get(user
=user
, uid
=uid
, undelete
=undelete
)
114 def get_favorites(user
):
115 favorites
= Episode
.view('users/favorite_episodes_by_user',