def update_subscriptions(self, user, device, add, remove): conflicts = intersect(add, remove) if conflicts: msg = "can not add and remove '{}' at the same time".format(str(conflicts)) logger.warning(msg) raise RequestException(msg) add_s = list(map(normalize_feed_url, add)) rem_s = list(map(normalize_feed_url, remove)) assert len(add) == len(add_s) and len(remove) == len(rem_s) pairs = zip(add + remove, add_s + rem_s) updated_urls = list(filter(lambda pair: pair[0] != pair[1], pairs)) add_s = filter(None, add_s) rem_s = filter(None, rem_s) # If two different URLs (in add and remove) have # been sanitized to the same, we ignore the removal rem_s = filter(lambda x: x not in add_s, rem_s) for add_url in add_s: podcast = Podcast.objects.get_or_create_for_url(add_url).object subscribe(podcast.pk, user.pk, device.uid, add_url) remove_podcasts = Podcast.objects.filter(urls__url__in=rem_s) for podcast in remove_podcasts: unsubscribe(podcast.pk, user.pk, device.uid) return updated_urls
def test_merge_podcasts(self): subscribe(self.podcast2, self.user, self.device) # merge podcast2 into podcast1 pm = PodcastMerger([self.podcast1, self.podcast2], Counter(), []) pm.merge() # get podcast for URL of podcast2 and unsubscribe from it p = Podcast.objects.get(urls__url=self.P2_URL) unsubscribe(p, self.user, self.device) subscriptions = Podcast.objects.filter(subscription__user=self.user) self.assertEqual(0, len(subscriptions))
def upload(request): try: emailaddr = request.POST['username'] password = request.POST['password'] action = request.POST['action'] protocol = request.POST['protocol'] opml = request.FILES['opml'].read() except MultiValueDictKeyError: return HttpResponse("@PROTOERROR", content_type='text/plain') user = auth(emailaddr, password) if not user: return HttpResponse('@AUTHFAIL', content_type='text/plain') dev = get_device(user, LEGACY_DEVICE_UID, request.META.get('HTTP_USER_AGENT', '')) existing_urls = [x.url for x in dev.get_subscribed_podcasts()] i = Importer(opml) podcast_urls = [p['url'] for p in i.items] podcast_urls = map(normalize_feed_url, podcast_urls) podcast_urls = list(filter(None, podcast_urls)) new = [u for u in podcast_urls if u not in existing_urls] rem = [u for u in existing_urls if u not in podcast_urls] # remove duplicates new = list(set(new)) rem = list(set(rem)) for n in new: p = Podcast.objects.get_or_create_for_url(n).object subscribe(p.pk, user.pk, dev.uid) for r in rem: p = Podcast.objects.get_or_create_for_url(r).object unsubscribe(p.pk, user.pk, dev.uid) return HttpResponse('@SUCCESS', content_type='text/plain')
def set_subscriptions(urls, user, device_uid, user_agent): # remove empty urls urls = list(filter(None, (u.strip() for u in urls))) device = get_device(user, device_uid, user_agent, undelete=True) subscriptions = dict((p.url, p) for p in device.get_subscribed_podcasts()) new = [p for p in urls if p not in subscriptions.keys()] rem = [p for p in subscriptions.keys() if p not in urls] remove_podcasts = Podcast.objects.filter(urls__url__in=rem) for podcast in remove_podcasts: unsubscribe(podcast.pk, user.pk, device.uid) for url in new: podcast = Podcast.objects.get_or_create_for_url(url).object subscribe(podcast.pk, user.pk, device.uid, url) # Only an empty response is a successful response return HttpResponse("", content_type="text/plain")
def test_merge(self): p1 = Podcast.objects.get_or_create_for_url( "http://example.com/podcast1.rss" ).object p2 = Podcast.objects.get_or_create_for_url( "http://example.com/podcast2.rss" ).object e1 = Episode.objects.get_or_create_for_url( p1, "http://example.com/podcast1/e1.mp3" ).object e1.title = "Episode 1" e1.save() e2 = Episode.objects.get_or_create_for_url( p2, "http://example.com/podcast1/e2.mp3" ).object e2.title = "Episode 2" e2.save() e3 = Episode.objects.get_or_create_for_url( p2, "http://example.com/podcast2/e2.mp3" ).object e3.title = "Episode 3" e3.save() e4 = Episode.objects.get_or_create_for_url( p2, "http://example.com/podcast2/e3.mp3" ).object e4.title = "Episode 4" e4.save() User = get_user_model() user = User() user.username = "******" user.email = "*****@*****.**" user.set_password("secret") user.save() device1 = Client.objects.create(user=user, uid="dev1", id=uuid.uuid1()) device2 = Client.objects.create(user=user, uid="dev2", id=uuid.uuid1()) subscribe(p1.pk, user.pk, device1.uid) unsubscribe(p1.pk, user.pk, device1.uid) subscribe(p1.pk, user.pk, device1.uid) subscribe(p2.pk, user.pk, device2.uid) action1 = EpisodeHistoryEntry.create_entry(user, e1, EpisodeHistoryEntry.PLAY) action3 = EpisodeHistoryEntry.create_entry(user, e3, EpisodeHistoryEntry.PLAY) # we need that for later e3_id = e3.pk actions = Counter() # decide which episodes to merge groups = [(0, [e1.id]), (1, [e2.id, e3.id]), (2, [e4.id])] # carry out the merge pm = PodcastMerger([p1, p2], actions, groups) pm.merge() e1 = Episode.objects.get(pk=e1.pk) history1 = EpisodeHistoryEntry.objects.filter(episode=e1, user=user) self.assertEqual(len(history1), 1) # check if merged episode's id can still be accessed e3 = Episode.objects.filter(podcast=p1).get_by_any_id(e3_id) history3 = EpisodeHistoryEntry.objects.filter(episode=e3, user=user) self.assertEqual(len(history3), 1) p1 = Podcast.objects.get(pk=p1.get_id()) subscribed_clients = Client.objects.filter(subscription__podcast=p1) self.assertEqual(len(subscribed_clients), 2) episodes = p1.episode_set.all() self.assertEqual(len(episodes), 3)