예제 #1
0
 def set_gid_shorten_urls(self, gid, shorten):
     if shorten:
         self.set_destination_param(gid, 'cache', '',
                                    S1.cache_shorten_urls(), shorten)
     else:
         self.del_destination_param(gid, 'cache', '',
                                    S1.cache_shorten_urls())
예제 #2
0
 def set_provider_session(self, gid, session_id, provider, data):
     """
     Use to store arbitrary session data specific to a provider. All session for all providers is cleared when user logs off
     """
     self.rc.hset(S1.gid_key(gid),
                  S1.destination_session_id_fmt(provider, session_id),
                  json.dumps(data))
예제 #3
0
 def flush_updates(self, gid):
     """ flushes any updates stuck in the update queue """
     destinations = self.get_destinations(gid)
     self.logger.info('Notifying destinations: {0}'.format(destinations))
     for destination in destinations:
         self.pubsub.broadcast_command(
             S1.publisher_channel_name(destination), S1.msg_publish(), gid)
예제 #4
0
    def purge_gid_links(self, destination, user):
        """
        cleans abandoned account links
        """
        # find all parents' [p]->destination:user
        # find all gids that feed the [p]->[destination:user] <- [gid]
        # if the gid is not in gids -- break the link parent -> gid
        # iterate over list of owners/parents of this destination:user account
        parents = self.get_linked_parents(S1.provider_root_key(
            destination, user),
                                          bag='dst')
        for parent in parents:
            # purge gid 2 gid links
            # this is now a manual process -- users can remove gid-gid links from the UI
            # self._purge_gid_gid(parent, gid)

            # check if destination:user is being fed by any of the parent's children
            # Note: parent will be listed as child of self
            children = self.get_linked_children(parent)
            child_links = set(self.get_bindings(destination, user))
            if not len(child_links.intersection(children)):
                self.logger.info(
                    'Removing account linking: [{0}] --> [{1}]'.format(
                        parent, S1.provider_root_key(destination, user)))
                self.remove_linked_account(parent,
                                           S1.provider_root_key(
                                               destination, user),
                                           bag='dst')
예제 #5
0
 def del_provider_session(self, gid, provider):
     keys = self.rc.hkeys(S1.gid_key(gid))
     to_clear = [
         key for key in keys
         if key.startswith(S1.destination_session_fmt(provider))
     ]
     if len(to_clear):
         self.rc.hdel(S1.gid_key(gid), *to_clear)
예제 #6
0
    def add_linked_account(self, parent_gid, gid, bag=None):
        parent_key = S1.provider_root_key('parents', bag) if bag else 'parents'
        child_key = S1.provider_root_key('children',
                                         bag) if bag else 'children'

        self._append_hfield(S1.destination_key_fmt(parent_key), gid,
                            parent_gid)
        self._append_hfield(S1.destination_key_fmt(child_key), parent_gid, gid)
예제 #7
0
 def bind_destination(self, gid, destination, user):
     # bind source and destination
     self._append_hfield(S1.destination_key_fmt(destination), gid, user)
     # bind destination to source
     self._append_hfield(S1.destination_source_key_fmt(destination), user,
                         gid)
     # append destination list for the source
     self._append_hfield(S1.destination_key_fmt(S1.destinations_key()), gid,
                         destination)
예제 #8
0
    def remove_linked_account(self, parent_gid, gid, bag=None):
        parent_key = S1.provider_root_key('parents', bag) if bag else 'parents'
        child_key = S1.provider_root_key('children',
                                         bag) if bag else 'children'

        self._delete_hfield_item(S1.destination_key_fmt(parent_key), gid,
                                 parent_gid)
        self._delete_hfield_item(S1.destination_key_fmt(child_key), parent_gid,
                                 gid)
예제 #9
0
    def remove_from_poller(self, gid):
        # remove from master set
        self.rc.zrem(S1.gid_set('all'), gid)

        # clear cache
        self.rc.delete(S1.cache_key(gid))
        self.del_destination_param(gid, 'cache', gid, S1.updated_key())
        self.del_destination_param(gid, 'cache', gid, S1.etag_key())
        self.purge_temp_accounts(gid)
예제 #10
0
 def purge_temp_accounts(self, gid):
     # remove all accounts
     links_t = self.rc.smembers(S1.links_temp_key(gid))
     links = links_t.difference(self.rc.smembers(S1.links_key(gid)))
     for link in links:
         # second check for usage in another account
         if self.rc.hexists(S1.destination_key_fmt('parents:dst'), link):
             continue
         self.rc.hdel(link, S1.ACCOUNT_KEY)
     self.rc.delete(S1.links_temp_key(gid))
예제 #11
0
 def add_log(self, gid, message):
     # log to log file
     self.logger.error('User Log [{0}]: {1}'.format(gid, message))
     # log to gid's log if key does not exist
     if self.rc.zscore(S1.gid_log_key(gid), message):
         return
     # add new record
     self.rc.zadd(S1.gid_log_key(gid), message, time.time())
     # trim log to latest 99 messages
     self.rc.zremrangebyrank(S1.gid_log_key(gid), 0, -100)
예제 #12
0
 def get_destination_first_use(self, gid, destination, user):
     """ returns first use timestamp for destination """
     result = self.get_destination_param(gid, destination, user,
                                         S1.bound_key())
     if not result:
         return 0
     return float(result)
예제 #13
0
    def bind_user(self, master_gid, gid, destination, user):
        # bind to destination poller
        self.logger.info('Binding: [{0}] --> [{1}]:[{2}]'.format(
            gid, destination, user))
        # store gid to gid relation
        self.add_linked_account(master_gid, gid)
        # store gid to destination user relation
        self.add_linked_account(master_gid,
                                S1.provider_root_key(destination, user),
                                bag='dst')

        # reset timestamps and errors
        self.reset_destination(gid, destination, user)
        # bind source and destination
        self.bind_destination(gid, destination, user)

        # carpet-notify GID destinations of updates
        self.flush_updates(gid)

        # append GID log
        self.add_log(
            master_gid, 'Success: Linked Google+ [{0}] --> [{1}:{2}]'.format(
                gid, destination, user))
        self.logger.info('Success: Linked Google+ [{0}] --> [{1}:{2}]'.format(
            gid, destination, user))
예제 #14
0
 def get_destination_update(self, gid, destination, user):
     """ returns last update timestamp for destination """
     result = self.get_destination_param(gid, destination, user,
                                         S1.updated_key())
     if not result:
         return 0
     return float(result)
예제 #15
0
    def remove_binding(self, gid, destination, user, clean=False):
        """ clears binding created by bind_user() """
        self.logger.info('Unbinding GID: [{0}] -/-> [{1}:{2}]'.format(
            gid, destination, user))
        self.add_log(
            gid, 'Unbinding Google+ [{0}] -/-> [{1}:{2}]'.format(
                gid, destination, user))

        # remove binding update option
        self.rc.hdel(S1.destination_option_key_fmt(destination),
                     S1.destination_pair_fmt(gid, user, S1.updated_key()))

        # remove destination user id from list of destinations for this gid
        self._delete_hfield_item(S1.destination_key_fmt(destination), gid,
                                 user)

        # remove gid from list of sources for this destination user
        self._delete_hfield_item(S1.destination_source_key_fmt(destination),
                                 user, gid)

        # clean linked accounts
        # find the owner(s) of the destination:user pair
        self.purge_gid_links(destination, user)

        # the gid->destination:user link is broken
        # clear this relationship
        self.remove_linked_account(gid,
                                   S1.provider_root_key(destination, user),
                                   bag='dst')

        # remove destination binding if no bindings to this destination left
        bound_users = self.get_destination_users(gid, destination)
        if not (bound_users and len(bound_users)):
            self.logger.info('No links remain for [{0} --> {1}]'.format(
                gid, destination))
            # remove destination from gid destination list
            self._delete_hfield_item(
                S1.destination_key_fmt(S1.destinations_key()), gid,
                destination)

        # keep message map for the destination:user -- user may re-bind later with new token
        # unless forced to clean all
        # keep filters unless forced to clean!
        if clean:
            self.filter.del_filter(destination, gid, user)
            self.filter.del_message_id_map(destination, user)

        # clear bound timestamp
        self.del_destination_param(gid, destination, user, S1.bound_key())

        # check_orphan() will stop polling the gid if nothing is bound to it
        self.check_orphan(gid, 0)
예제 #16
0
    def end_service_query(self, gid, query):
        # get all in list
        results = self.rc.lrange(S1.query_list_out(query), 0, -1)
        if not results:
            return None

        received = []
        # check all results for the specified gid
        mask = '{0}:'.format(gid)
        for result in results:
            if result.startswith(mask):
                self.rc.lrem(S1.query_list_out(query), result)

                # filter out empty results
                received.append(result[len(mask):])

        return [r for r in received if r] if len(received) else None
예제 #17
0
    def get_log(self, gid):
        # get child account logs too
        children = set(self.get_destination_users(gid, 'children'))
        children.add(gid)
        log = {
            k: self.rc.zrange(S1.gid_log_key(k), 0, -1, withscores=True)
            for k in children
        }

        return log
예제 #18
0
 def get_linked_users(self, gid, destination, user):
     """
     yields a list of user gids who own gid->destination:user binding
     @param gid: gid of the source, not user gid
     @param destination: name of the destination i.e. "facebook"
     @param user: destination user id
     @return: yeilds gids of users who own gid->destination:user binding
     """
     parents = self.get_linked_parents(gid)
     for parent in parents:
         children = self.get_linked_children(parent, bag='dst')
         if S1.provider_root_key(destination, user) in children:
             yield parent
예제 #19
0
    def forget_source(self, master_gid, gid):
        """
        Removes source gid, unlinks all bindings associated with the source
        @param master_gid: master gid
        @param gid: source gid
        @return:
        """
        self.logger.info('Removing source [{0}:{1}]...'.format(
            master_gid, gid))
        destinations = self.get_destinations(gid)
        for destination in destinations:
            users = self.get_destination_users(gid, destination)
            for user in users:
                # source gid can be bound to destination that does not belong to this master gid
                # forget_destination will only remove bindings that belong to this master gid
                DataApi.forget_destination(self, self.logger, gid, destination,
                                           user)

        # remove the gid from the list of child accounts
        self.remove_linked_account(master_gid, gid)

        # clear gid data if no destinations left
        destinations = self.get_destinations(gid)
        if not destinations:
            self.logger.info(
                'Source [{0}:{1}] is orphaned, cleaning...'.format(
                    master_gid, gid))
            # remove user keys
            self.rc.delete(S1.gid_key(gid))
            self.rc.delete(S1.gid_log_key(gid))
            self.rc.delete(S1.links_key(gid))
            self.rc.delete(S1.cache_key(gid))
            self.del_destination_param(gid, 'cache', '',
                                       S1.cache_shorten_urls())
            # clear chache and remove gid from poller list
            self.remove_from_poller(gid)
            # remove tnc
            self.rc.hdel(S1.TERMS_OK_KEY, gid)
예제 #20
0
 def is_valid_gid(self, gid):
     return self.rc.zscore(S1.gid_set('all'), gid) or self.rc.exists(
         S1.gid_key(gid))
예제 #21
0
 def get_provider_session(self, gid, session_id, provider):
     value = self.rc.hget(
         S1.gid_key(gid),
         S1.destination_session_id_fmt(provider, session_id))
     return json.loads(value) if value else None
예제 #22
0
 def get_gid_shorten_urls(self, gid):
     return self.get_destination_param(gid, 'cache', '',
                                       S1.cache_shorten_urls())
예제 #23
0
 def refresh_user_token(self, gid, provider, pid):
     self.pubsub.broadcast_command(S1.publisher_channel_name(provider),
                                   S1.msg_register(), pid)
예제 #24
0
 def set_limits(self, gid, limit_tag):
     if limit_tag:
         self.rc.hset(S1.gid_key(gid), S1.LIMITS_KEY, limit_tag)
     else:
         self.rc.hdel(S1.gid_key(gid), S1.LIMITS_KEY)
예제 #25
0
 def add_temp_account(self, gid, provider, user, data):
     self.rc.sadd(S1.links_temp_key(gid),
                  S1.provider_root_key(provider, user))
     self.rc.hset(S1.provider_root_key(provider, user), S1.ACCOUNT_KEY,
                  data)
예제 #26
0
 def get_limits(self, gid):
     return self.rc.hget(S1.gid_key(gid), S1.LIMITS_KEY)
예제 #27
0
 def del_log(self, gid):
     self.rc.delete(S1.gid_log_key(gid))
예제 #28
0
 def is_linked_account(self, gid, provider, user):
     return self.rc.sismember(S1.links_key(gid),
                              S1.provider_root_key(provider, user))
예제 #29
0
 def set_provider_error_count(self, provider, user, count):
     self.rc.hset(S1.provider_root_key(provider, user),
                  S1.error_count_key(), count)
예제 #30
0
 def get_provider_error_count(self, provider, user):
     count_str = self.rc.hget(S1.provider_root_key(provider, user),
                              S1.error_count_key())
     return int(count_str) if count_str else 0