def form_valid(self, form): name = self.repo_full_name = form.cleaned_data['name'] # create the waiting subscription if not exists subscription, created = WaitingSubscription.objects.get_or_create( user=self.request.user, repository_name=name ) if not created: # the subscription already exists, force the state and updated_at subscription.state = WAITING_SUBSCRIPTION_STATES.WAITING subscription.save() message = 'Your subscription to <strong>%s</strong> will be added shortly' # if the repository exists (and fetched), convert into a real subscription try: repository = subscription.repository if not repository.first_fetch_done: raise Repository.DoesNotExist() except Repository.DoesNotExist: # add a job to fetch the repository FirstFetch.add_job(name, gh=self.request.user.get_connection()) else: # If a FirstFetch is still running, do nothing more, but else... if repository.first_fetch_done: message = 'Your subscription to <strong>%s</strong> was just added' subscription.convert(form.can_use) # start fetching events (it'll be ignored if there is already a queued job) CheckRepositoryEvents.add_job(repository.id) messages.success(self.request, message % name) return super(AddRepositoryView, self).form_valid(form)
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) # 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 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