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
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(
40 # get all users that subscribe to this podcast
41 user_ids
= Subscription
.objects
.filter(podcast
=podcast
)\
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
56 for user_id
in user_ids
:
57 subscriptions
= Podcast
.objects\
58 .filter(subscription__user__id__in
=user_ids
)\
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 """
74 base_url
= settings
.DEFAULT_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
))
82 logger
.info('subscribing to {podcast} at {hub}.'.format(podcast
=podcast
,
84 pubsub
.subscribe(podcast
, podcast
.url
, podcast
.hub
, base_url
)