def test_group(self): self.podcast1 = Podcast(urls=['http://example1.com']) self.podcast1.save() self.podcast2 = Podcast(urls=['http://example2.com']) self.podcast2.save() group = self.podcast1.group_with(self.podcast2, 'My Group', 'p1', 'p2') self.assertIn(self.podcast1, group.podcasts) self.assertIn(self.podcast2, group.podcasts) self.assertEquals(len(group.podcasts), 2) self.assertEquals(group.title, 'My Group') self.assertEquals(self.podcast1.group_member_name, 'p1') self.assertEquals(self.podcast2.group_member_name, 'p2') # add to group self.podcast3 = Podcast(urls=['http://example3.com']) self.podcast3.save() group = self.podcast1.group_with(self.podcast3, 'My Group', 'p1', 'p3') self.assertIn(self.podcast3, group.podcasts) self.assertEquals(self.podcast3.group_member_name, 'p3') # add group to podcast self.podcast4 = Podcast(urls=['http://example4.com']) self.podcast4.save() group = self.podcast4.group_with(self.podcast1, 'My Group', 'p4', 'p1') self.assertIn(self.podcast4, group.podcasts) self.assertEquals(self.podcast4.group_member_name, 'p4')
def test_group(self): self.podcast1 = Podcast(urls=["http://example1.com"]) self.podcast1.save() self.podcast2 = Podcast(urls=["http://example2.com"]) self.podcast2.save() group = self.podcast1.group_with(self.podcast2, "My Group", "p1", "p2") self.assertIn(self.podcast1, group.podcasts) self.assertIn(self.podcast2, group.podcasts) self.assertEquals(len(group.podcasts), 2) self.assertEquals(group.title, "My Group") self.assertEquals(self.podcast1.group_member_name, "p1") self.assertEquals(self.podcast2.group_member_name, "p2") # add to group self.podcast3 = Podcast(urls=["http://example3.com"]) self.podcast3.save() group = self.podcast1.group_with(self.podcast3, "My Group", "p1", "p3") self.assertIn(self.podcast3, group.podcasts) self.assertEquals(self.podcast3.group_member_name, "p3") # add group to podcast self.podcast4 = Podcast(urls=["http://example4.com"]) self.podcast4.save() group = self.podcast4.group_with(self.podcast1, "My Group", "p4", "p1") self.assertIn(self.podcast4, group.podcasts) self.assertEquals(self.podcast4.group_member_name, "p4")
def for_podcast(cls, podcast): """ all tags for the podcast, in decreasing order of importance """ res = Podcast.view('tags/by_podcast', startkey = [podcast.get_id(), None], endkey = [podcast.get_id(), {}], reduce = True, group = True, group_level = 2, stale = 'update_after', ) tags = Counter(dict((x['key'][1], x['value']) for x in res)) res = Podcast.view('usertags/by_podcast', startkey = [podcast.get_id(), None], endkey = [podcast.get_id(), {}], reduce = True, group = True, group_level = 2, ) tags.update(Counter(dict( (x['key'][1], x['value']) for x in res))) get_tag = itemgetter(0) return map(get_tag, tags.most_common())
def setUp(self): self.podcast1 = Podcast(urls=['http://example.com/feed.rss']) self.podcast2 = Podcast(urls=['http://test.org/podcast/']) self.podcast3 = Podcast(urls=['http://test.org/feed/']) self.podcast1.save() self.podcast2.save() self.podcast3.save() self.episode1 = Episode(podcast=self.podcast1.get_id(), urls = ['http://example.com/episode1.mp3']) self.episode2 = Episode(podcast=self.podcast2.get_id(), urls = ['http://example.com/episode1.mp3']) self.episode3 = Episode(podcast=self.podcast3.get_id(), urls = ['http://example.com/media.mp3']) self.episode1.save() self.episode2.save() self.episode3.save() self.podcast2.group_with(self.podcast3, 'My Group', 'Feed1', 'Feed2') self.user = User(username='******') self.user.email = '*****@*****.**' self.user.set_password('secret!') self.user.save()
def search_podcasts(q, limit=20, skip=0): if is_url(q): url = sanitize_url(q) podcast = Podcast.for_url(url, create=True) if not podcast.title: update_podcasts([podcast]) podcast = Podcast.for_url(url) return [podcast], 1 db = get_main_database() #FIXME current couchdbkit can't parse responses for multi-query searches q = q.replace(',', '') res = db.search('podcasts/search', wrapper=search_wrapper, include_docs=True, limit=limit, skip=skip, q=q, sort='\\subscribers<int>') #FIXME: return empty results in case of search backend error try: return list(res), res.total_rows except: return [], 0
class MergeTests(TestCase): def setUp(self): self.podcast1 = Podcast(urls=['http://example.com/feed.rss']) self.podcast2 = Podcast(urls=['http://test.org/podcast/']) self.podcast1.save() self.podcast2.save() self.episode1 = Episode(podcast=self.podcast1.get_id(), urls = ['http://example.com/episode1.mp3']) self.episode2 = Episode(podcast=self.podcast2.get_id(), urls = ['http://example.com/episode1.mp3']) self.episode1.save() self.episode2.save() self.user = User(username='******') self.user.email = '*****@*****.**' self.user.set_password('secret!') self.user.save() def test_merge_podcasts(self): state1 = self.episode1.get_user_state(self.user) state2 = self.episode2.get_user_state(self.user) action1 = EpisodeAction(action='play', timestamp=datetime.utcnow()) action2 = EpisodeAction(action='download', timestamp=datetime.utcnow()) state1.add_actions([action1]) state2.add_actions([action2]) state1.save() state2.save() pm = PodcastMerger([self.podcast1, self.podcast2]) pm.merge() state1 = self.episode1.get_user_state(self.user) state2 = self.episode2.get_user_state(self.user) self.assertIn(action1, state1.actions) self.assertIn(action2, state1.actions) def tearDown(self): self.podcast1.delete() self.episode1.delete() try: self.podcast2.delete() self.episode2.delete() except: pass self.user.delete()
def setUp(self): self.podcast1 = Podcast(urls=['http://example.com/feed.rss']) self.podcast2 = Podcast(urls=[self.P2_URL]) self.podcast1.save() self.podcast2.save() self.user = User(username='******') self.user.email = '*****@*****.**' self.user.set_password('secret!') self.user.save() self.device = get_device(self.user, 'dev', '')
def handle(self, *args, **options): if len(args) != 5: print 'Usage: ./manage.py group-podcasts <url1> <url2> <group-name> <name1> <name2>' return p1_url = args[0] p2_url = args[1] group_title = args[2] myname = args[3] othername = args[4] p1 = Podcast.for_url(p1_url) p2 = Podcast.for_url(p2_url) p1.group_with(p2, group_title, myname, othername)
def add_action(request, episode): device = request.user.get_device(request.POST.get('device')) action_str = request.POST.get('action') timestamp = request.POST.get('timestamp', '') if timestamp: try: timestamp = dateutil.parser.parse(timestamp) except: timestamp = datetime.utcnow() else: timestamp = datetime.utcnow() action = EpisodeAction() action.timestamp = timestamp action.device = device.id if device else None action.action = action_str state = episode.get_user_state(request.user) @repeat_on_conflict(['action']) def _add_action(action): state.add_actions([action]) state.save() _add_action(action=action) podcast = Podcast.get(episode.podcast) return HttpResponseRedirect(get_episode_link_target(episode, podcast))
def list_favorites(request): site = RequestSite(request) episodes = backend.get_favorites(request.user) podcast_ids = [episode.podcast for episode in episodes] podcasts = get_to_dict(Podcast, podcast_ids, Podcast.get_id) def set_podcast(episode): episode = proxy_object(episode) episode.podcast = podcasts.get(episode.podcast, None) return episode episodes = map(set_podcast, episodes) feed_url = 'http://%s/%s' % (site.domain, reverse('favorites-feed', args=[request.user.username])) podcast = Podcast.for_url(feed_url) if 'public_feed' in request.GET: request.user.favorite_feeds_token = '' request.user.save() elif 'private_feed' in request.GET: request.user.create_new_token('favorite_feeds_token', 8) request.user.save() token = request.user.favorite_feeds_token return render(request, 'favorites.html', { 'episodes': episodes, 'feed_token': token, 'site': site, 'podcast': podcast, })
def add_chapter(request, episode): e_state = episode.get_user_state(request.user) podcast = Podcast.get(episode.podcast) try: start = parse_time(request.POST.get('start', '0')) if request.POST.get('end', '0'): end = parse_time(request.POST.get('end', '0')) else: end = start adv = 'advertisement' in request.POST label = request.POST.get('label') except Exception as e: # FIXME: when using Django's messaging system, set error message return HttpResponseRedirect(get_episode_link_target(episode, podcast)) chapter = Chapter() chapter.start = start chapter.end = end chapter.advertisement = adv chapter.label = label e_state.update_chapters(add=[chapter]) return HttpResponseRedirect(get_episode_link_target(episode, podcast))
def example_podcasts(request, format): podcasts = cache.get('example-podcasts', None) try: scale = int(request.GET.get('scale_logo', 64)) except (TypeError, ValueError): return HttpResponseBadRequest('scale_logo has to be a numeric value') if scale not in range(1, 257): return HttpResponseBadRequest('scale_logo has to be a number from 1 to 256') if not podcasts: try: examples = ExamplePodcasts.get('example_podcasts') ids = examples.podcast_ids podcasts = list(Podcast.get_multi(ids)) cache.set('example-podcasts', podcasts) except ResourceNotFound: podcasts = [] title = 'gPodder Podcast Directory' domain = RequestSite(request).domain p_data = lambda p: podcast_data(p, domain, scale) return format_podcast_list( podcasts, format, title, json_map=p_data, xml_template='podcasts.xml', request=request, )
def _decorator(request, slug_id, *args, **kwargs): podcast = Podcast.for_slug_id(slug_id) if podcast is None: raise Http404 return f(request, podcast, *args, **kwargs)
def get_episode_link_target(episode, podcast, view_name='episode', add_args=[]): """ Returns the link-target for an Episode, preferring slugs over Ids automatically distringuishes between relational Episode objects and CouchDB-based Episodes """ from mygpo.core.models import Podcast # prefer slugs if episode.slug: args = [podcast.slug or podcast.get_id(), episode.slug] view_name = '%s-slug-id' % view_name # for short URLs, prefer oldids over CouchDB-IDs elif episode.oldid: args = [episode.oldid] # fallback: CouchDB-IDs else: if not podcast: if isinstance(episode.podcast, Podcast): podcast = episode.podcast elif isinstance(episode.podcast, basestring): podcast = Podcast.get(episode.podcast) args = [podcast.slug or podcast.get_id(), episode._id] view_name = '%s-slug-id' % view_name return strip_tags(reverse(view_name, args=args + add_args))
def podcast_slugs(base_slug): res = Podcast.view('podcasts/by_slug', startkey = [base_slug, None], endkey = [base_slug + 'ZZZZZ', None], wrap_doc = False, ) return [r['key'][0] for r in res]
def handle(self, *args, **options): silent = options.get('silent') # couchdbkit doesn't preserve microseconds started = datetime.utcnow().replace(microsecond=0) podcasts = Podcast.all_podcasts() total = Podcast.view('podcasts/by_oldid', limit=0).total_rows for n, podcast in enumerate(podcasts): subscriber_count = self.get_subscriber_count(podcast) self.update(podcast=podcast, started=started, subscriber_count=subscriber_count) if not silent: progress(n, total)
def _wrap_podcast_group(res): if res['doc']['doc_type'] == 'Podcast': return Podcast.wrap(res['doc']) else: pg = PodcastGroup.wrap(res['doc']) id = res['key'] return pg.get_podcast_by_id(id)
def create(request, username, format): """ Creates a new podcast list and links to it in the Location header """ title = request.GET.get('title', None) if not title: return HttpResponseBadRequest('Title missing') slug = slugify(title) if not slug: return HttpResponseBadRequest('Invalid title') plist = PodcastList.for_user_slug(request.user._id, slug) if plist: return HttpResponse('List already exists', status=409) urls = parse_subscription(request.raw_post_data, format) podcasts = [Podcast.for_url(url, create=True) for url in urls] podcast_ids = map(Podcast.get_id, podcasts) plist = PodcastList() plist.title = title plist.slug = slug plist.user = request.user._id plist.podcasts = podcast_ids plist.save() response = HttpResponse(status=201) list_url = reverse('api-get-list', args=[request.user.username, slug, format]) response['Location'] = list_url return response
def _get_existing_slugs(self): from mygpo.core.models import Podcast res = Podcast.view( "podcasts/by_slug", startkey=[self.base_slug, None], endkey=[self.base_slug + "ZZZZZ", None], wrap_doc=False ) return [r["key"][0] for r in res]
def episode(request, episode): podcast = Podcast.get(episode.podcast) if not check_publisher_permission(request.user, podcast): return HttpResponseForbidden() if request.method == 'POST': form = None #EpisodeForm(request.POST, instance=e) #if form.is_valid(): # form.save() elif request.method == 'GET': form = None #EpisodeForm(instance=e) timeline_data = list(episode_listener_data(episode)) heatmap = EpisodeHeatmap(episode.podcast, episode._id, duration=episode.duration) return render(request, 'publisher/episode.html', { 'episode': episode, 'podcast': podcast, 'form': form, 'timeline_data': timeline_data, 'heatmap': heatmap, })
def handle(self, *args, **options): # couchdbkit doesn't preserve microseconds start_time = datetime.utcnow().replace(microsecond=0) excluded_tags = settings.DIRECTORY_EXCLUDED_TAGS tags = args or Tag.all() for n, tag in enumerate(tags): if not isinstance(tag, basestring): tag = str(tag) label = utils.remove_control_chars(tag.strip()) if not label: continue tag_obj = Tag(tag) podcast_ids, weights = utils.unzip(list(tag_obj.get_podcasts())) podcast_objs = Podcast.get_multi(podcast_ids) podcasts = [] for podcast, weight in zip(podcast_objs, weights): e = CategoryEntry() e.podcast = podcast.get_id() e.weight = float(weight * podcast.subscriber_count()) podcasts.append(e) category = Category.for_tag(label) if not category: if not label or label in excluded_tags: continue category = Category() category.label = label category.spellings = [] # delete if it has been excluded after it has been created if label in excluded_tags: category.delete() continue # we overwrite previous data if category.updated != start_time: category.podcasts = [] category.merge_podcasts(podcasts) category.updated = start_time if 'weight' in category: del category['weight'] category.save() try: utils.progress(n % 1000, 1000, category.label.encode('utf-8')) except: pass
def get_podcasts(self, count=None): user = User.get(self.user) subscriptions = user.get_subscribed_podcast_ids() ids = filter(lambda x: not x in self.blacklist + subscriptions, self.podcasts) if count: ids = ids[:count] return filter(lambda x: x and x.title, Podcast.get_multi(ids))
def _prepare_list(self, l): podcasts = Podcast.get_multi(l.podcasts[:self.podcasts_per_topic]) user = User.get(l.user) l = proxy_object(l) l.podcasts = podcasts l.username = user.username l.cls = "PodcastList" return l
def show_slug(request, slug): podcast = Podcast.for_slug(slug) if slug != podcast.slug: target = reverse('podcast_slug', args=[podcast.slug]) return HttpResponseRedirect(target) return show(request, podcast.oldid)
def _get_podcasts(self, *args, **options): if options.get('toplist'): yield self.get_toplist() if options.get('new'): yield self.get_podcast_with_new_episodes() if options.get('random'): yield Podcast.random() get_podcast = lambda url: Podcast.for_url(url, create=True) yield map(get_podcast, args) if not args and not options.get('toplist') and not options.get('new') \ and not options.get('random'): yield Podcast.by_last_update()
def search_wrapper(result): doc = result['doc'] if doc['doc_type'] == 'Podcast': p = Podcast.wrap(doc) elif doc['doc_type'] == 'PodcastGroup': p = PodcastGroup.wrap(doc) p._id = result['id'] return p
def podcast_info(request): url = sanitize_url(request.GET.get('url', '')) podcast = Podcast.for_url(url) if not podcast: raise Http404 domain = RequestSite(request).domain resp = podcast_data(podcast, domain) return JsonResponse(resp)
def setUp(self): self.podcast1 = Podcast(urls=['http://example.com/feed.rss']) self.podcast2 = Podcast(urls=['http://test.org/podcast/']) self.podcast1.save() self.podcast2.save() self.episode1 = Episode(podcast=self.podcast1.get_id(), urls = ['http://example.com/episode1.mp3']) self.episode2 = Episode(podcast=self.podcast2.get_id(), urls = ['http://example.com/episode1.mp3']) self.episode1.save() self.episode2.save() self.user = User(username='******') self.user.email = '*****@*****.**' self.user.set_password('secret!') self.user.save()
def handle(self, *args, **options): total = Podcast.count() podcasts = Podcast.all_podcasts() actions = Counter() for n, podcast in enumerate(podcasts): psubscriber = PodcastSubscriberData.for_podcast(podcast.get_id()) res = self.update_subscriber_data(podcast, data=psubscriber) self.update_podcast(podcast=podcast) action = 'updated' if res else 'skipped' actions[action] += 1 status_str = ', '.join('%s: %d' % x for x in actions.items()) progress(n+1, total, status_str)
def update_published_podcasts(request, username): user = User.get_user(username) if not user: raise Http404 published_podcasts = Podcast.get_multi(user.published_objects) update_podcasts(published_podcasts) return HttpResponse('Updated:\n' + '\n'.join([p.url for p in published_podcasts]), mimetype='text/plain')