[PubSub] add podcast to pubsub subscription
[mygpo.git] / mygpo / data / podcast.py
blobc9610dc86175b3b4c58872d94c37ec9599137d1f
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 collections import Counter
19 import random
20 import logging
22 from django.conf import settings
24 from mygpo.podcasts.models import Podcast
25 from mygpo.subscriptions.models import Subscription
26 from mygpo import pubsub
28 logger = logging.getLogger(__name__)
31 def calc_similar_podcasts(podcast, num=20, user_sample=100):
32 """ Get a list of podcasts that seem to be similar to the given one.
34 The similarity is based on similar subscriptions; for performance
35 reasons, only a sample of subscribers is considered """
37 logger.info('Calculating podcasts similar to {podcast}'.format(
38 podcast=podcast))
40 # get all users that subscribe to this podcast
41 user_ids = Subscription.objects.filter(podcast=podcast)\
42 .order_by('user')\
43 .distinct('user')\
44 .values_list('user', flat=True)
45 logger.info('Found {num_subscribers} subscribers, taking a sample '
46 'of {sample_size}'.format(num_subscribers=len(user_ids),
47 sample_size=user_sample))
49 # take a random sample of ``user_sample`` subscribers
50 user_ids = list(user_ids) # evaluate ValuesQuerySet
51 random.shuffle(user_ids)
52 user_ids = user_ids[:user_sample]
54 # get other podcasts that the user sample subscribes to
55 podcasts = Counter()
56 for user_id in user_ids:
57 subscriptions = Podcast.objects\
58 .filter(subscription__user__id__in=user_ids)\
59 .distinct('pk')\
60 .exclude(pk=podcast.pk)
61 podcasts.update(Counter(subscriptions))
62 logger.info('Found {num_podcasts}, returning top {num_results}'.format(
63 num_podcasts=len(podcasts), num_results=num))
65 return podcasts.most_common(num)
68 def subscribe_at_hub(podcast):
69 """ Tries to subscribe to the given podcast at its hub """
71 if not podcast.hub:
72 return
74 base_url = settings.DEFAULT_BASE_URL
76 if not base_url:
77 logger.warn('Could not subscribe to podcast {podcast} '
78 'at hub {hub} because DEFAULT_BASE_URL is not '
79 'set.'.format(podcast=podcast, hub=podcast.hub))
80 return
82 logger.info('subscribing to {podcast} at {hub}.'.format(podcast=podcast,
83 hub=podcast.hub))
84 pubsub.subscribe(podcast, podcast.url, podcast.hub, base_url)