Merge pull request #793 from gpodder/remove-advertise
[mygpo.git] / mygpo / subscriptions / __init__.py
blob5c754097afe416ccaf1e1ffedd6972dcf260a67e
1 import collections
4 import logging
6 logger = logging.getLogger(__name__)
8 # we cannot import models in __init__.py, because it gets loaded while all
9 # apps are loaded; ideally all these methods would be moved into a different
10 # (non-__init__) module
13 def get_subscribe_targets(podcast, user):
14 """Clients / SyncGroup on which the podcast can be subscribed
16 This excludes all devices/syncgroups on which the podcast is already
17 subscribed"""
19 # django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
20 from mygpo.users.models import Client
22 clients = (
23 Client.objects.filter(user=user)
24 .exclude(subscription__podcast=podcast, subscription__user=user)
25 .select_related("sync_group")
28 targets = set()
29 for client in clients:
30 if client.sync_group:
31 targets.add(client.sync_group)
32 else:
33 targets.add(client)
35 return targets
38 def get_subscribed_podcasts(user, only_public=False):
39 """Returns all subscribed podcasts for the user
41 The attribute "url" contains the URL that was used when subscribing to
42 the podcast"""
44 # django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
45 from mygpo.subscriptions.models import Subscription, SubscribedPodcast
47 subscriptions = (
48 Subscription.objects.filter(user=user)
49 .order_by("podcast")
50 .distinct("podcast")
51 .select_related("podcast")
54 # django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
55 from mygpo.usersettings.models import UserSettings
57 private = UserSettings.objects.get_private_podcasts(user)
59 podcasts = []
60 for subscription in subscriptions:
61 podcast = subscription.podcast
62 public = subscription.podcast not in private
64 # check if we want to include this podcast
65 if only_public and not public:
66 continue
68 subpodcast = SubscribedPodcast(podcast, public, subscription.ref_url)
69 podcasts.append(subpodcast)
71 return podcasts
74 def get_subscription_history(
75 user, client=None, since=None, until=None, public_only=False
77 """Returns chronologically ordered subscription history entries
79 Setting device_id restricts the actions to a certain device
80 """
82 # django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
83 from mygpo.history.models import SUBSCRIPTION_ACTIONS, HistoryEntry
85 logger.info("Subscription History for {user}".format(user=user.username))
86 history = (
87 HistoryEntry.objects.filter(user=user)
88 .filter(action__in=SUBSCRIPTION_ACTIONS)
89 .order_by("timestamp")
92 if client:
93 logger.info("... client {client_uid}".format(client_uid=client.uid))
94 history = history.filter(client=client)
96 if since:
97 logger.info("... since {since}".format(since=since))
98 history = history.filter(timestamp__gt=since)
100 if until:
101 logger.info("... until {until}".format(until=until))
102 history = history.filter(timestamp__lte=until)
104 if public_only:
105 # django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
106 from mygpo.usersettings.models import UserSettings
108 logger.info("... only public")
109 private = UserSettings.objects.get_private_podcasts(user)
110 history = history.exclude(podcast__in=private)
112 return history
115 def get_subscription_change_history(history):
116 """Actions that added/removed podcasts from the subscription list
118 Returns an iterator of all subscription actions that either
119 * added subscribed a podcast that hasn't been subscribed directly
120 before the action (but could have been subscribed) earlier
121 * removed a subscription of the podcast is not longer subscribed
122 after the action
124 This method assumes, that no subscriptions exist at the beginning of
125 ``history``.
128 # django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
129 from mygpo.history.models import HistoryEntry
131 subscriptions = collections.defaultdict(int)
133 for entry in history:
134 if entry.action == HistoryEntry.SUBSCRIBE:
135 subscriptions[entry.podcast] += 1
137 # a new subscription has been added
138 if subscriptions[entry.podcast] == 1:
139 yield entry
141 elif entry.action == HistoryEntry.UNSUBSCRIBE:
142 subscriptions[entry.podcast] -= 1
144 # the last subscription has been removed
145 if subscriptions[entry.podcast] == 0:
146 yield entry
149 def subscription_diff(history):
150 """Calculates a diff of subscriptions based on a history (sub/unsub)"""
152 # django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
153 from mygpo.history.models import HistoryEntry
155 subscriptions = collections.defaultdict(int)
157 for entry in history:
158 if entry.action == HistoryEntry.SUBSCRIBE:
159 subscriptions[entry.podcast] += 1
161 elif entry.action == HistoryEntry.UNSUBSCRIBE:
162 subscriptions[entry.podcast] -= 1
164 subscribe = [podcast for (podcast, value) in subscriptions.items() if value > 0]
165 unsubscribe = [podcast for (podcast, value) in subscriptions.items() if value < 0]
167 return subscribe, unsubscribe