Example #1
0
def requeue_all_repositories():
    """
    Add (ignore if already present) Hook and Event check jobs for all activated
    repositories
    """
    for repository in Repository.objects.filter(first_fetch_done=True):
        CheckRepositoryEvents.add_job(repository.id)
        CheckRepositoryHook.add_job(repository.id, delayed_for=30)
        FetchForUpdate.add_job(repository.id)
    def run(self, queue):
        """
        Fetch the repository and once done, convert waiting subscriptions into
        real ones, and save the cout of converted subscriptions in the job.
        """
        super(FirstFetch, self).run(queue)

        gh = self.gh
        if not gh:
            return  # it's delayed !

        # the identifier of this job is not the repository's id, but its full name
        repository_name = self.identifier.hget()

        # mark waiting subscriptions as in fetching status
        WaitingSubscription.objects.filter(repository_name=repository_name)\
            .update(state=WAITING_SUBSCRIPTION_STATES.FETCHING)

        # get the user who asked to add this repo, and check its rights
        user = GithubUser.objects.get(username=self.gh_args.hget('username'))
        rights = user.can_use_repository(repository_name)

        # TODO: in these two case, we must not retry the job without getting
        #       an other user with fetch rights
        if rights is None:
            raise Exception('An error occured while fetching rights for the user')
        elif rights is False:
            raise Exception('The user has not rights to fetch this repository')

        # try to get a GithubUser which is the owner of the repository
        user_part, repo_name_part = repository_name.split('/')

        if user_part == user.username:
            owner = user
        else:
            try:
                owner = GithubUser.objects.get(username=user_part)
            except GithubUser.DoesNotExist:
                # no user, we will create it during the fetch
                owner = GithubUser(username=user_part)

        # Check if the repository already exists in the DB
        repository = None
        if owner.id:
            try:
                repository = owner.owned_repositories.get(name=repo_name_part)
            except Repository.DoesNotExist:
                pass

        if not repository:
            # create a temporary repository to fetch if none exists
            repository = Repository(name=repo_name_part, owner=owner)

        # fetch the repository if never fetched
        if not repository.first_fetch_done:
            repository.fetch_all(gh=self.gh, force_fetch=True, two_steps=True)
            FetchCollaborators.add_job(repository.id)

        # and convert waiting subscriptions to real ones
        count = 0
        for subscription in WaitingSubscription.objects.filter(repository_name=repository_name):
            try:
                rights = subscription.user.can_use_repository(repository)
            except Exception:
                continue
            if rights:
                count += 1
                subscription.convert(rights)
                message = u'Your subscription to <strong>%s</strong> is now ready' % repository.full_name
                messages.success(subscription.user, message)
            else:
                subscription.state = WAITING_SUBSCRIPTION_STATES.FAILED
                subscription.save(update_fields=('state', ))

        # save count in the job
        self.converted_subscriptions.hset(count)

        # add check-hook/events jobs
        # TODO: should not be in core but for now...
        from gim.hooks.tasks import CheckRepositoryHook, CheckRepositoryEvents
        CheckRepositoryEvents.add_job(repository.id)
        CheckRepositoryHook.add_job(repository.id, delayed_for=30)

        # return the number of converted subscriptions
        return count