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 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 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 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 remove_chapter(request, episode, start, end): e_state = episode.get_user_state(request.user) remove = (int(start), int(end)) e_state.update_chapters(rem=[remove]) podcast = Podcast.get(episode.podcast) return HttpResponseRedirect(get_episode_link_target(episode, podcast))
def toggle_favorite(request, episode): episode_state = episode.get_user_state(request.user) is_fav = episode_state.is_favorite() episode_state.set_favorite(not is_fav) episode_state.save() podcast = Podcast.get(episode.podcast) return HttpResponseRedirect(get_episode_link_target(episode, podcast))
def episode(request, episode): podcast = Podcast.get(episode.podcast) if not podcast: raise Http404 if request.user.is_authenticated(): episode_state = episode.get_user_state(request.user) is_fav = episode_state.is_favorite() # pre-populate data for fetch_data podcasts_dict = {podcast.get_id(): podcast} episodes_dict = {episode._id: episode} history = list(episode_state.get_history_entries()) HistoryEntry.fetch_data(request.user, history, podcasts=podcasts_dict, episodes=episodes_dict) played_parts = EpisodeHeatmap(podcast.get_id(), episode._id, request.user._id, duration=episode.duration) devices = dict( (d.id, d.name) for d in request.user.devices ) else: history = [] is_fav = False played_parts = None devices = {} chapters = [] for user, chapter in Chapter.for_episode(episode._id): chapter.is_own = request.user.is_authenticated() and \ user == request.user._id chapters.append(chapter) prev = podcast.get_episode_before(episode) next = podcast.get_episode_after(episode) return render(request, 'episode.html', { 'episode': episode, 'podcast': podcast, 'prev': prev, 'next': next, 'history': history, 'chapters': chapters, 'is_favorite': is_fav, 'played_parts': played_parts, 'actions': EPISODE_ACTION_TYPES, 'devices': devices, })
def handle(self, *args, **options): db = get_main_database() status = self.get_cmd_status() since = self.get_since(status, options) objects = self.get_objects(db, since) actions = Counter() # create unfinished command run status run_status = CommandRunStatus() run_status.timestamp_started = datetime.utcnow() run_status.start_seq = since # add it to existing one (if any) status.runs.append(run_status) status.save() total = db.info()['update_seq'] has_slug = lambda x: bool(x.slug) for seq, obj in objects: total = db.info()['update_seq'] if isinstance(obj, PodcastGroup): podcasts = filter(has_slug, obj.podcasts) if isinstance(obj, Podcast): podcasts = filter(has_slug, [obj]) elif isinstance(obj, Episode): if has_slug(obj): continue podcast = Podcast.get(obj.podcast) if not podcast: continue podcasts = filter(has_slug, [podcast]) updated = self.handle_podcasts(podcasts) actions['updated'] += updated if not options['silent']: status_str = ', '.join('%s: %d' % x for x in actions.items()) progress(seq, total, status_str) # finish command run status run_status.timestamp_finished = datetime.utcnow() run_status.end_seq = total run_status.status_counter = dict(actions) # and overwrite existing one (we could keep a longer log here) status.runs = [run_status] status.save()
def get_podcast_with_new_episodes(self): db = get_main_database() res = db.view('episodes/need_update', group_level = 1, reduce = True, ) for r in res: podcast_id = r['key'] podcast = Podcast.get(podcast_id) if podcast: yield podcast
def privacy(request): site = RequestSite(request) @repeat_on_conflict(['state']) def set_privacy_settings(state, is_public): state.settings['public_subscription'] = is_public state.save() if 'private_subscriptions' in request.GET: set_privacy_settings(state=request.user, is_public=False) elif 'public_subscriptions' in request.GET: set_privacy_settings(state=request.user, is_public=True) if 'exclude' in request.GET: id = request.GET['exclude'] podcast = Podcast.get(id) state = podcast.get_user_state(request.user) set_privacy_settings(state=state, is_public=False) if 'include' in request.GET: id = request.GET['include'] podcast = Podcast.get(id) state = podcast.get_user_state(request.user) set_privacy_settings(state=state, is_public=True) subscriptions = request.user.get_subscriptions() podcasts = get_to_dict(Podcast, [x[1] for x in subscriptions], get_id=Podcast.get_id) included_subscriptions = set(filter(None, [podcasts.get(x[1], None) for x in subscriptions if x[0] == True])) excluded_subscriptions = set(filter(None, [podcasts.get(x[1], None) for x in subscriptions if x[0] == False])) return render(request, 'privacy.html', { 'public_subscriptions': request.user.settings.get('public_subscriptions', True), 'included_subscriptions': included_subscriptions, 'excluded_subscriptions': excluded_subscriptions, 'domain': site.domain, })
def mytags(request): tags_podcast = {} tags_tag = defaultdict(list) for podcast_id, taglist in Tag.for_user(request.user).items(): podcast = Podcast.get(podcast_id) tags_podcast[podcast] = taglist for tag in taglist: tags_tag[ tag ].append(podcast) return render(request, 'mytags.html', { 'tags_podcast': tags_podcast, 'tags_tag': dict(tags_tag.items()), })
def handle(self, *args, **options): docs = set() for username in options.get('users', []): user = User.get_user(username) # User docs.add(user._id) # Suggestions suggestions = Suggestions.for_user(user) docs.add(suggestions._id) # Podcast States for p_state in PodcastUserState.for_user(user): docs.add(p_state._id) # Categories for tag in p_state.tags: c = Category.for_tag(tag) if c: docs.add(c._id) # Podcast podcast = Podcast.get(p_state.podcast) docs.add(podcast._id) # Categories for s in podcast.tags: for tag in podcast.tags[s]: c = Category.for_tag(tag) if c: docs.add(c._id) # Episodes for episode in podcast.get_episodes(): docs.add(episode._id) # Episode States e_state = episode.get_user_state(user) if e_state._id: docs.add(e_state._id) db = get_main_database() docs = sorted(docs) self.dump(docs, db)
def episode_data(episode, domain, podcast=None): podcast = podcast or Podcast.get(episode.podcast) data = { "title": episode.title, "url": episode.url, "podcast_title": podcast.title if podcast else '', "podcast_url": podcast.url if podcast else '', "description": episode.description, "website": episode.link, "mygpo_link": 'http://%(domain)s%(res)s' % dict(domain=domain, res=get_episode_link_target(episode, podcast)) if podcast else '' } if episode.released: data['released'] = episode.released.strftime('%Y-%m-%dT%H:%M:%S') return data
def for_user_episode(cls, user, episode): r = cls.view('episode_states/by_user_episode', key = [user._id, episode._id], include_docs = True, limit = 1, ) if r: return r.first() else: podcast = Podcast.get(episode.podcast) state = EpisodeUserState() state.episode = episode._id state.podcast = episode.podcast state.user = user._id state.ref_url = episode.url state.podcast_ref_url = podcast.url return state
def test_merge(self): p1 = Podcast() p1.urls = ['http://example.com/podcast1.rss'] p1.save() p2 = Podcast() p2.urls = ['http://example.com/podcast2.rss'] p2.save() e1 = Episode() e1.title = 'Episode 1' e1.podcast = p1.get_id() e1.urls = ['http://example.com/podcast1/e1.mp3'] e1.save() e2 = Episode() e2.title = 'Episode 2' e2.podcast = p1.get_id() e2.urls = ['http://example.com/podcast1/e2.mp3'] e2.save() e3 = Episode() e3.title = 'Episode 3' e3.podcast = p2.get_id() e3.urls = ['http://example.com/podcast2/e2.mp3'] e3.save() e4 = Episode() e4.title = 'Episode 4' e4.podcast = p2.get_id() e4.urls = ['http://example.com/podcast2/e3.mp3'] e4.save() user = User() user.username = '******' user.email = '*****@*****.**' user.set_password('secret') device1 = Device() device1.uid = 'dev1' device2 = Device() device2.uid = 'dev2' user.devices.append(device1) user.devices.append(device2) user.save() p1.subscribe(user, device1) time.sleep(1) p1.unsubscribe(user, device1) time.sleep(1) p1.subscribe(user, device1) p2.subscribe(user, device2) s1 = e1.get_user_state(user) s1.add_actions([EpisodeAction(action='play')]) s1.save() s3 = e3.get_user_state(user) s3.add_actions([EpisodeAction(action='play')]) s3.save() # we need that for later e3_id = e3._id actions = Counter() # decide which episodes to merge groups = [(0, [e1]), (1, [e2, e3]), (2, [e4])] # carry out the merge pm = PodcastMerger([p1, p2], actions, groups) pm.merge() e1 = Episode.get(e1._id) es1 = e1.get_user_state(user) self.assertEqual(len(es1.actions), 1) # check if merged episode's id can still be accessed e3 = Episode.get(e3_id) es3 = e3.get_user_state(user) self.assertEqual(len(es3.actions), 1) p1 = Podcast.get(p1.get_id()) ps1 = p1.get_user_state(user) self.assertEqual(len(ps1.get_subscribed_device_ids()), 2) self.assertEqual(len(list(p1.get_episodes())), 3)