Ejemplo n.º 1
0
    def handle(self, *args, **options):

        skip = options.get('skip')
        total = EpisodeUserState.view('episode_states/by_user_episode',
                limit=0,
            ).total_rows
        db = get_main_database()

        actions = Counter()
        actions['merged'] = 0


        for n in count(skip):

            first = EpisodeUserState.view('episode_states/by_user_episode',
                    skip         = n,
                    include_docs = True,
                    limit        = 1,
                )
            first = list(first)
            if not first:
                break

            first = first[0]


            states = EpisodeUserState.view('episode_states/by_user_episode',
                    key          = [first.user, first.episode],
                    include_docs = True,
                )
            states = list(states)

            l1 = len(states)
            # we don't want to delete this one
            states.remove(first)

            assert len(states) == l1-1

            if states:
                updater = get_updater(states)

                obj_funs = [(first, updater)] + [(state, do_delete) for state in states]

                bulk_save_retry(db, obj_funs)

                merged = len(states)-1
                actions['merged'] += merged
                total -= merged

            status_str = ', '.join('%s: %d' % x for x in actions.items())
            progress(n+1, total, status_str)
Ejemplo n.º 2
0
 def get_all_states(self):
     from mygpo.users.models import EpisodeUserState
     r =  EpisodeUserState.view('episode_states/by_podcast_episode',
         startkey = [self.podcast, self._id, None],
         endkey   = [self.podcast, self._id, {}],
         include_docs=True)
     return iter(r)
Ejemplo n.º 3
0
 def get_episode_states(podcast):
     r =  EpisodeUserState.view('users/episode_states_by_podcast_episode',
             startkey     = [podcast.get_id(), None, None],
             endkey       = [podcast.get_id(), {},   {}],
             include_docs = True
         )
     return r
Ejemplo n.º 4
0
def update_episodes(user, actions, now, ua_string):
    update_urls = []

    grouped_actions = defaultdict(list)

    # group all actions by their episode
    for action in actions:

        podcast_url = action['podcast']
        podcast_url = sanitize_append(podcast_url, 'podcast', update_urls)
        if podcast_url == '': continue

        episode_url = action['episode']
        episode_url = sanitize_append(episode_url, 'episode', update_urls)
        if episode_url == '': continue

        act = parse_episode_action(action, user, update_urls, now, ua_string)
        grouped_actions[ (podcast_url, episode_url) ].append(act)

    # Prepare the updates for each episode state
    obj_funs = []

    for (p_url, e_url), action_list in grouped_actions.iteritems():
        episode_state = EpisodeUserState.for_ref_urls(user, p_url, e_url)

        fun = partial(update_episode_actions, action_list=action_list)
        obj_funs.append( (episode_state, fun) )

    db = get_main_database()
    bulk_save_retry(db, obj_funs)

    return update_urls
Ejemplo n.º 5
0
    def handle_obj(self, seq, doc, actions):
        state = EpisodeUserState.wrap(doc)

        episode = episode_by_id(state.episode)

        if not episode:
            actions['missing'] += 1
            return

        listeners = episode_listener_count(episode)
        updated = set_episode_listeners(episode, listeners)
        actions['updated'] += int(updated)
Ejemplo n.º 6
0
    def listener_count(self):
        """ returns the number of users that have listened to this podcast """

        from mygpo.users.models import EpisodeUserState
        r = EpisodeUserState.view('listeners/by_podcast',
                startkey    = [self.get_id(), None],
                endkey      = [self.get_id(), {}],
                group       = True,
                group_level = 1,
                reduce      = True,
            )
        return r.first()['value'] if r else 0
Ejemplo n.º 7
0
    def listener_count(self, start=None, end={}):
        """ returns the number of users that have listened to this episode """

        from mygpo.users.models import EpisodeUserState
        r = EpisodeUserState.view('listeners/by_episode',
                startkey    = [self._id, start],
                endkey      = [self._id, end],
                reduce      = True,
                group       = True,
                group_level = 1
            )
        return r.first()['value'] if r else 0
Ejemplo n.º 8
0
    def handle_obj(self, seq, doc, actions):
        state = EpisodeUserState.wrap(doc)

        try:
            episode = Episode.get(state.episode)

        except ResourceNotFound:
            episode = None

        if episode:
            listeners = episode.listener_count()
            updated = self.update(episode=episode, listeners=listeners)
            actions['updated'] += updated

        else:
            actions['missing'] += 1
Ejemplo n.º 9
0
    def episode_listener_counts(self):
        """ (Episode-Id, listener-count) tuples for episodes w/ listeners """

        from mygpo.users.models import EpisodeUserState
        r = EpisodeUserState.view('listeners/by_podcast_episode',
                startkey    = [self.get_id(), None, None],
                endkey      = [self.get_id(), {},   {}],
                group       = True,
                group_level = 2,
                reduce      = True,
            )

        for res in r:
            episode   = res['key'][1]
            listeners = res['value']
            yield (episode, listeners)
Ejemplo n.º 10
0
    def listener_count_timespan(self, start=None, end={}):
        """ returns (date, listener-count) tuples for all days w/ listeners """

        if isinstance(start, datetime):
            start = start.isoformat()

        if isinstance(end, datetime):
            end = end.isoformat()

        from mygpo.users.models import EpisodeUserState
        r = EpisodeUserState.view('listeners/by_podcast',
                startkey    = [self.get_id(), start],
                endkey      = [self.get_id(), end],
                group       = True,
                group_level = 2,
                reduce      = True,
            )

        for res in r:
            date = parser.parse(res['key'][1]).date()
            listeners = res['value']
            yield (date, listeners)
Ejemplo n.º 11
0
def episode_state_for_user_episode(user, episode):

    if not user:
        raise QueryParameterMissing('user')

    if not episode:
        raise QueryParameterMissing('episode')


    key = 'episode-state-userid-%s-episodeid-%s' % (sha1(user._id).hexdigest(),
            sha1(episode._id).hexdigest())

#   Disabled as cache invalidation does not work properly
#   state = cache.get(key)
#   if state:
#       return state

    udb = get_userdata_database()
    state = get_single_result(udb, 'episode_states/by_user_episode',
            key          = [user._id, episode._id],
            include_docs = True,
            limit        = 1,
            schema       = EpisodeUserState,
        )

    if state:
        cache.set(key, state)
        return state

    else:
        podcast = podcast_by_id(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
        # don't cache here, because the state is saved by the calling function

        return state
Ejemplo n.º 12
0
 def get_user_state(self, user):
     from mygpo.users.models import EpisodeUserState
     return EpisodeUserState.for_user_episode(user, self)