def token_obj(self):
     if not hasattr(self, '_token_obj'):
         self._token_obj, _ = Token.get_or_connect(token=self.identifier.hget())
     return self._token_obj
 def manage_token(self, *args, **kwargs):
     from core.limpyd_models import Token
     Token.update_token_from_gh(self, *args, **kwargs)
示例#3
0
    def _get_gh(self):
        """
        Return a Connection object based on arguments saved in the job, or by
        type of permission, to get one from the Token model
        """
        from core.limpyd_models import Token

        args = self.gh_args.hgetall()
        if 'access_token' not in args:
            args = None

        permission = getattr(self, 'permission', 'read')

        token = None

        # we have connection args: get the token if available
        if args:
            try:
                token_kwargs = {'token': args['access_token']}
                # ignore the available flag for "self"
                if permission != 'self':
                    token_kwargs['available'] = 1
                try:
                    token = Token.get(**token_kwargs)
                except IndexError:
                    # changed during the "get"... retry once
                    # explanation: the get first check the length of the result
                    # and if it's 1, then it retrieves the first, but in the
                    # meantime, the data may have changed and there is result
                    # anymore...
                    token = Token.get(**token_kwargs)
                except:
                    raise
            except (Token.DoesNotExist, KeyError):
                pass
            else:
                # final check on remaining api calls
                if int(token.rate_limit_remaining.get() or 0):
                    return token.gh

        # no token, try to get one...
        repository = None

        if permission == 'self':
            # forced to use the current one, but not available...
            pass
        else:

            # if we have a repository, get one following permission
            repository = getattr(self, 'repository')
            if repository:
                if repository.private and permission not in ('admin', 'push'):
                    # force correct permission if repository is private
                    permission = 'push'
                token = Token.get_one_for_repository(repository.pk, permission)

            # no repository, not "self", but want one ? don't know why but ok...
            else:
                token = Token.get_one()

        # if we don't have token it's that there is no one available: we delay
        # the job
        if not token:
            self.status.hset(STATUSES.DELAYED)

            if hasattr(self, 'delay_for_gh'):
                # use the "delay_for_gh" attribute if any to delay the job for X seconds
                self.delayed_until.hset(compute_delayed_until(delayed_for=self.delay_for_gh))

            else:
                # check the first available gh
                if permission == 'self':
                    if args:
                        token = Token.get(token=args['access_token'])
                elif repository:
                    token = Token.get_one_for_repository(repository.pk, permission, available=False, sort_by='rate_limit_reset')
                else:
                    token = Token.get_one(available=False, sort_by='rate_limit_reset')

                # if we have a token, get it's delay before availability, and
                # set it on the job for future use
                if token:

                    remaining = token.get_remaining_seconds()
                    if remaining is not None and remaining >= 0:
                        self.delayed_until.hset(compute_delayed_until(remaining))
                    else:
                        self.delayed_until.delete()

                    self.gh = token.gh

                else:
                    # no token at all ? we may have no one for this permission !
                    # so retry in 15mn
                    self.delayed_until.hset(compute_delayed_until(delayed_for=60 * 15))

            return None

        # save it in the job, useful when cloning to avoid searching for a new
        # gh (will only happen if it is not available anymore)
        self.gh = token.gh

        # and ok, return it
        return token.gh