def test_merge_podcasts(self): # Create additional data that will be merged state1 = episode_state_for_user_episode(self.user, self.episode1) state2 = episode_state_for_user_episode(self.user, self.episode2) action1 = EpisodeAction(action='play', timestamp=datetime.utcnow(), upload_timestamp=get_timestamp(datetime.utcnow())) action2 = EpisodeAction(action='download', timestamp=datetime.utcnow(), upload_timestamp=get_timestamp(datetime.utcnow())) add_episode_actions(state1, [action1]) add_episode_actions(state2, [action2]) # copy of the object episode2 = episode_by_id(self.episode2._id) # decide which episodes to merge groups = [(0, [self.episode1, self.episode2])] counter = Counter() pm = PodcastMerger([self.podcast1, self.podcast2], counter, groups) pm.merge() state1 = episode_state_for_user_episode(self.user, self.episode1) state2 = episode_state_for_user_episode(self.user, episode2) self.assertIn(action1, state1.actions) self.assertIn(action2, state1.actions) self.assertEqual(state2._id, None)
def episode_settings(user, url, podcast_url): episode = episode_for_podcast_url(podcast_url, url) if episode is None: raise Http404 episode_state = episode_state_for_user_episode(user, episode) return episode_state, episode_state, udb
def add_user_recursive(self, user, docs): """ adds a user and all the podcast and episodes it references """ # User docs.add(user._id) # Suggestions suggestions = suggestions_for_user(user) docs.add(suggestions._id) progress(0, len(docs), '', stream=sys.stderr) # Podcast States for p_state in podcast_states_for_user(user): self.add_podcast_state(p_state, docs) progress(0, len(docs), p_state, stream=sys.stderr) # Podcast podcast = podcast_by_id(p_state.podcast) self.add_podcast(podcast, docs) progress(0, len(docs), podcast, stream=sys.stderr) # Episodes for episode in episodes_for_podcast(podcast): self.add_episode(episode, docs) progress(0, len(docs), episode, stream=sys.stderr) e_state = episode_state_for_user_episode(user, episode) self.add_episode_state(e_state, docs) progress(0, len(docs), e_state, stream=sys.stderr)
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 (ValueError, AttributeError): timestamp = datetime.utcnow() else: timestamp = datetime.utcnow() action = EpisodeAction() action.timestamp = timestamp action.upload_timestamp = get_timestamp(datetime.utcnow()) action.device = device.id if device else None action.action = action_str state = episode_state_for_user_episode(request.user, episode) add_episode_actions(state, [action]) podcast = podcast_by_id(episode.podcast) return HttpResponseRedirect(get_episode_link_target(episode, podcast))
def test_merge_podcasts(self): podcast1 = podcast_by_id(self.podcast1.get_id()) podcast2 = podcast_by_id(self.podcast2.get_id()) podcast3 = podcast_by_id(self.podcast3.get_id()) # assert that the podcasts are actually grouped self.assertEqual(podcast2._id, podcast3._id) self.assertNotEqual(podcast2.get_id(), podcast2._id) self.assertNotEqual(podcast3.get_id(), podcast3._id) # Create additional data that will be merged state1 = episode_state_for_user_episode(self.user, self.episode1) state2 = episode_state_for_user_episode(self.user, self.episode2) action1 = EpisodeAction(action='play', timestamp=datetime.utcnow(), upload_timestamp=get_timestamp(datetime.utcnow())) action2 = EpisodeAction(action='download', timestamp=datetime.utcnow(), upload_timestamp=get_timestamp(datetime.utcnow())) add_episode_actions(state1, [action1]) add_episode_actions(state2, [action2]) # copy of the object episode2 = episode_by_id(self.episode2._id) # decide which episodes to merge groups = [(0, [self.episode1, self.episode2])] counter = Counter() pm = PodcastMerger([podcast2, podcast1], counter, groups) pm.merge() state1 = episode_state_for_user_episode(self.user, self.episode1) state2 = episode_state_for_user_episode(self.user, episode2) self.assertIn(action1, state1.actions) self.assertIn(action2, state1.actions) self.assertEqual(state2._id, None) episode1 = episode_by_id(self.episode1._id) # episode2 has been merged into episode1, so it must contain its # merged _id self.assertEqual(episode1.merged_ids, [episode2._id])
def toggle_favorite(request, episode): episode_state = episode_state_for_user_episode(request.user, episode) is_fav = episode_state.is_favorite() set_episode_favorite(episode_state, not is_fav) podcast = podcast_by_id(episode.podcast) return HttpResponseRedirect(get_episode_link_target(episode, podcast))
def episode(request, episode): podcast = podcast_by_id(episode.podcast) podcast = check_restrictions(podcast) user = request.user if not podcast: raise Http404 if user.is_authenticated(): episode_state = episode_state_for_user_episode(user, episode) is_fav = episode_state.is_favorite() # pre-populate data for fetch_data podcasts_dict = {podcast.get_id(): podcast} episodes_dict = {episode._id: episode} has_history = bool(list(episode_state.get_history_entries())) played_parts = EpisodeHeatmap(podcast.get_id(), episode._id, user._id, duration=episode.duration) devices = dict( (d.id, d.name) for d in user.devices ) can_flattr = user.get_wksetting(FLATTR_TOKEN) and episode.flattr_url else: has_history = False is_fav = False played_parts = None devices = {} can_flattr = False is_publisher = check_publisher_permission(user, podcast) 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, 'has_history': has_history, 'is_favorite': is_fav, 'played_parts': played_parts, 'actions': EPISODE_ACTION_TYPES, 'devices': devices, 'can_flattr': can_flattr, 'is_publisher': is_publisher, })
def auto_flattr_episode(user, episode_id): """ Task to auto-flattr an episode In addition to the flattring itself, it also records the event """ success, msg = flattr_thing(user, episode_id, None, False, 'Episode') if not success: return False episode = episode_by_id(episode_id) state = episode_state_for_user_episode(user, episode) action = EpisodeAction() action.action = 'flattr' action.upload_timestamp = get_timestamp(datetime.utcnow()) add_episode_actions(state, [action]) return True
def flattr_episode(request, episode): """ Flattrs an episode, records an event and redirects to the episode """ user = request.user site = RequestSite(request) # Flattr via the tasks queue, but wait for the result task = flattr_thing.delay(user, episode._id, site.domain, request.is_secure(), 'Episode') success, msg = task.get() if success: action = EpisodeAction() action.action = 'flattr' action.upload_timestamp = get_timestamp(datetime.utcnow()) state = episode_state_for_user_episode(request.user, episode) add_episode_actions(state, [action]) messages.success(request, _("Flattr\'d")) else: messages.error(request, msg) podcast = podcast_by_id(episode.podcast) return HttpResponseRedirect(get_episode_link_target(episode, podcast))
def history(request, episode): """ shows the history of the episode """ user = request.user podcast = podcast_by_id(episode.podcast) episode_state = episode_state_for_user_episode(user, episode) # 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(user, history, podcasts=podcasts_dict, episodes=episodes_dict) devices = dict( (d.id, d.name) for d in user.devices ) return render(request, 'episode-history.html', { 'episode': episode, 'podcast': podcast, 'history': history, 'actions': EPISODE_ACTION_TYPES, 'devices': devices, })
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 = episode_state_for_user_episode(user, e1) add_episode_actions(s1, [EpisodeAction(action='play', upload_timestamp=get_timestamp(datetime.utcnow()))]) s3 = episode_state_for_user_episode(user, e3) add_episode_actions(s3, [EpisodeAction(action='play', upload_timestamp=get_timestamp(datetime.utcnow()))]) # 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_by_id(e1._id) es1 = episode_state_for_user_episode(user, e1) self.assertEqual(len(es1.actions), 1) # check if merged episode's id can still be accessed e3 = episode_by_id(e3_id) es3 = episode_state_for_user_episode(user, e3) self.assertEqual(len(es3.actions), 1) p1 = podcast_by_id(p1.get_id()) ps1 = podcast_state_for_user_podcast(user, p1) self.assertEqual(len(ps1.get_subscribed_device_ids()), 2) self.assertEqual(len(list(episodes_for_podcast(p1))), 3)