コード例 #1
0
def view_user(request, username):
    """
    Render the user page based on username
    Input:
        request[django.http.HttpRequest]
        username[str]: Name of the user
    """
    users = models.GitUser.objects.filter(name=username)
    if users.count() == 0:
        raise Http404('Bad username')

    repos = RepositoryStatus.get_user_repos_with_open_prs_status(username)
    pr_ids = []
    for r in repos:
        for pr in r["prs"]:
            pr_ids.append(pr["id"])
    event_list = EventsStatus.get_single_event_for_open_prs(pr_ids)
    evs_info = EventsStatus.multiline_events_info(event_list)
    data = {
        'username': username,
        'repos': repos,
        'events': evs_info,
        "update_interval": settings.EVENT_PAGE_UPDATE_INTERVAL,
    }
    return render(request, 'ci/user.html', data)
コード例 #2
0
def recipe_crons(request, recipe_id):
    recipe = get_object_or_404(models.Recipe, pk=recipe_id)
    event_list = (EventsStatus.get_default_events_query().filter(
        jobs__recipe__filename=recipe.filename,
        jobs__recipe__cause=recipe.cause,
        jobs__recipe__scheduler__isnull=False).exclude(
            jobs__recipe__scheduler=''))
    total = 0
    count = 0
    qs = models.Job.objects.filter(recipe__filename=recipe.filename)
    for job in qs.all():
        total += job.seconds.total_seconds(
        ) if job.status == models.JobStatus.SUCCESS else 0
        count += 1 if job.status == models.JobStatus.SUCCESS else 0
    if count:
        total /= count
    events = get_paginated(request, event_list)
    evs_info = EventsStatus.multiline_events_info(events)
    avg = timedelta(seconds=total)
    data = {
        'recipe': recipe,
        'events': evs_info,
        'average_time': avg,
        'pages': events,
    }
    return render(request, 'ci/recipe_events.html', data)
コード例 #3
0
def do_branch_page(request, branch):
    """
    Render the branch page given a branch object
    Input:
        request[django.http.HttpRequest]
        branch[models.Branch]
    """
    if request.method != "GET":
        return HttpResponseNotAllowed(['GET'])

    causes = []
    if request.GET.get("do_filter", "0") == "0":
        causes = [models.Event.PUSH, models.Event.MANUAL, models.Event.RELEASE]
        form = forms.BranchEventsForm(initial={"filter_events": causes})
    else:
        form = forms.BranchEventsForm(request.GET)
        if form.is_valid():
            causes = [int(c) for c in form.cleaned_data["filter_events"]]

    event_list = EventsStatus.get_default_events_query().filter(
        base__branch=branch, cause__in=causes)
    events = get_paginated(request, event_list)
    evs_info = EventsStatus.multiline_events_info(events)
    return render(request, 'ci/branch.html', {
        "form": form,
        'branch': branch,
        'events': evs_info,
        'pages': events
    })
コード例 #4
0
    def test_get_single_event_for_open_prs(self):
        self.create_events()

        pr = models.PullRequest.objects.latest()
        latest_event = pr.events.latest()
        # 1. main PullRequest query
        # 2. latest() for each PullRequest
        # 3. jobs query below
        with self.assertNumQueries(3):
            info = EventsStatus.get_single_event_for_open_prs([pr.pk])
            self.assertEqual(len(info), 1) # should only have the latest event
            self.assertEqual(info[0].pk, latest_event.pk)
            # pre, test, test1, merge
            self.assertEqual(info[0].jobs.count(), 4)

        last_modified = latest_event.last_modified + datetime.timedelta(0,10)

        with self.assertNumQueries(2):
            info = EventsStatus.get_single_event_for_open_prs([pr.pk], last_modified)
            self.assertEqual(len(info), 0)

        last_modified = latest_event.last_modified - datetime.timedelta(0,10)
        with self.assertNumQueries(2):
            info = EventsStatus.get_single_event_for_open_prs([pr.pk], last_modified)
            self.assertEqual(len(info), 1)
            self.assertEqual(info[0].pk, latest_event.pk)
コード例 #5
0
def repo_update(request):
    """
    Get the updates for the repo page.
    """
    if 'last_request' not in request.GET or 'limit' not in request.GET or 'repo_id' not in request.GET:
        return HttpResponseBadRequest('Missing parameters')

    this_request = TimeUtils.get_local_timestamp()
    repo_id = int(request.GET['repo_id'])
    limit = int(request.GET['limit'])
    last_request = int(float(request.GET['last_request'])) # in case it has decimals
    dt = timezone.localtime(timezone.make_aware(datetime.datetime.utcfromtimestamp(last_request)))
    repo = get_object_or_404(models.Repository, pk=repo_id)
    repos_status = RepositoryStatus.filter_repos_status([repo.pk], last_modified=dt)
    event_q = EventsStatus.get_default_events_query()
    event_q = event_q.filter(base__branch__repository=repo)[:limit]
    events_info = EventsStatus.multiline_events_info(event_q, last_modified=dt)
    # we also need to check if a PR closed recently
    closed = []
    for pr in models.PullRequest.objects.filter(repository=repo, closed=True, last_modified__gte=dt).values('id').all():
        closed.append({'id': pr['id']})

    return JsonResponse({'repo_status': repos_status,
        'closed': closed,
        'last_request': this_request,
        'events': events_info,
        'limit': limit,
        })
コード例 #6
0
def cronjobs(request):
    # TODO: make this check for permission to view cron stuff instead
    allowed = Permissions.is_allowed_to_see_clients(request.session)
    if not allowed:
        return render(request, 'ci/cronjobs.html', {
            'recipes': None,
            'allowed': False
        })

    recipe_list = models.Recipe.objects.filter(
        active=True,
        current=True,
        scheduler__isnull=False,
        branch__isnull=False).exclude(scheduler="")
    local_tz = pytz.timezone('US/Mountain')
    for r in recipe_list:
        event_list = (EventsStatus.get_default_events_query().filter(
            jobs__recipe__filename=r.filename, jobs__recipe__cause=r.cause))
        events = get_paginated(request, event_list)
        evs_info = EventsStatus.multiline_events_info(events)
        r.most_recent_event = evs_info[0]['id'] if len(evs_info) > 0 else None

        c = croniter(r.scheduler,
                     start_time=r.last_scheduled.astimezone(local_tz))
        r.next_run_time = c.get_next(datetime)

    # TODO: augment recipes objects with fields that html template will need.
    data = {
        'recipes': recipe_list,
        'allowed': True,
        'update_interval': settings.HOME_PAGE_UPDATE_INTERVAL,
    }
    return render(request, 'ci/cronjobs.html', data)
コード例 #7
0
def event_list(request):
    event_list = EventsStatus.get_default_events_query()
    events = get_paginated(request, event_list)
    evs_info = EventsStatus.multiline_events_info(events)
    return render(request, 'ci/events.html', {
        'events': evs_info,
        'pages': events
    })
コード例 #8
0
ファイル: views.py プロジェクト: joshua-cogliati-inl/civet
def sha_events(request, owner, repo, sha):
    repo = get_object_or_404(models.Repository.objects, name=repo, user__name=owner)
    event_q = models.Event.objects.filter(head__branch__repository=repo, head__sha__startswith=sha)
    event_list = EventsStatus.get_default_events_query(event_q)
    events = get_paginated(request, event_list)
    evs_info = EventsStatus.multiline_events_info(events)
    return render(request, 'ci/events.html',
            {'events': evs_info, 'pages': events, 'sha': sha, 'repo': repo})
コード例 #9
0
ファイル: views.py プロジェクト: joshua-cogliati-inl/civet
def scheduled_events(request):
    """
    List schedule events
    """
    event_list = EventsStatus.get_default_events_query().filter(cause=models.Event.MANUAL)
    events = get_paginated(request, event_list)
    evs_info = EventsStatus.multiline_events_info(events)
    return render(request, 'ci/scheduled.html', {'events': evs_info, 'pages': events})
コード例 #10
0
    def test_events_info(self):
        self.create_events()

        ev = models.Event.objects.first()
        info = EventsStatus.events_info([ev])
        self.assertEqual(len(info), 1)

        ev = models.Event.objects.all()
        info = EventsStatus.events_info(ev)
        self.assertEqual(len(info), 3)
コード例 #11
0
    def test_multi_line(self):
        self.create_events()
        e = utils.create_event(user=self.owner, commit1='456', branch1=self.branch, branch2=self.branch, cause=models.Event.PUSH)
        e.description = "some description"
        e.save()
        event_q = EventsStatus.get_default_events_query()[:30]
        info = EventsStatus.multiline_events_info(event_q, max_jobs_per_line=100)
        self.assertEqual(len(info), 3)
        self.assertEqual(len(info[0]["jobs"]), 6)

        info = EventsStatus.multiline_events_info(event_q, max_jobs_per_line=1)
        self.assertEqual(len(info), 18)
コード例 #12
0
ファイル: views.py プロジェクト: joshua-cogliati-inl/civet
def view_event(request, event_id):
    """
    Show the details of an Event
    """
    ev = get_object_or_404(EventsStatus.events_with_head(), pk=event_id)
    evs_info = EventsStatus.multiline_events_info([ev])
    allowed = Permissions.is_collaborator(request.session, ev.build_user, ev.base.repo())
    has_unactivated = ev.jobs.filter(active=False).count() != 0
    context = {'event': ev,
        'events': evs_info,
        'allowed_to_cancel': allowed,
        "update_interval": settings.EVENT_PAGE_UPDATE_INTERVAL,
        "has_unactivated": has_unactivated,
        }
    return render(request, 'ci/event.html', context)
コード例 #13
0
    def test_get_default_events_query(self):
        self.create_events()

        q = EventsStatus.get_default_events_query()
        with self.assertNumQueries(1):
            self.assertEqual(q.count(), 3)

        event_q = models.Event.objects.filter(head__sha="1234")
        q = EventsStatus.get_default_events_query(event_q=event_q)
        with self.assertNumQueries(1):
            self.assertEqual(q.count(), 1)

        event_q = models.Event.objects.filter(head__sha="invalid")
        q = EventsStatus.get_default_events_query(event_q=event_q)
        with self.assertNumQueries(1):
            self.assertEqual(q.count(), 0)
コード例 #14
0
def get_user_repos_info(request, limit=30, last_modified=None):
    """
    Get the information for the main view.
    This checks to see if the user has preferred repositories set, and if
    so then just shows those.
    You can also set the "default" parameter to show all the repositories.
    Input:
      request: django.http.HttpRequest
      limit: int: How many events to show
      last_modified: datetime: If not None, then only get information that has occured after this time.
    Return:
      (repo_info, evs_info, default):
        repo_info: list of dicts of repository status
        evs_info: list of dicts of event information
        default: Whether the default view was enforced
    """
    pks = []
    default = request.GET.get('default')
    if default is None:
        default = False
        for server in settings.INSTALLED_GITSERVERS:
            try:
                gitserver = models.GitServer.objects.get(
                    host_type=server["type"], name=server["hostname"])
            except models.GitServer.DoesNotExist:
                # Probably shouldn't happen in production but it does seem to
                # happen during selenium testing
                continue
            user = gitserver.signed_in_user(request.session)
            if user != None:
                for repo in user.preferred_repos.filter(
                        user__server=gitserver).all():
                    pks.append(repo.pk)
    else:
        default = True
    if pks:
        repos = RepositoryStatus.filter_repos_status(
            pks, last_modified=last_modified)
        evs_info = EventsStatus.events_filter_by_repo(
            pks, limit=limit, last_modified=last_modified)
    else:
        repos = RepositoryStatus.main_repos_status(last_modified=last_modified)
        evs_info = EventsStatus.all_events_info(limit=limit,
                                                last_modified=last_modified)
    return repos, evs_info, default
コード例 #15
0
def event_update(request, event_id):
    ev = get_object_or_404(models.Event, pk=event_id)
    ev_data = {'id': ev.pk,
        'complete': ev.complete,
        'last_modified': TimeUtils.display_time_str(ev.last_modified),
        'created': TimeUtils.display_time_str(ev.created),
        'status': ev.status_slug(),
      }
    ev_data['events'] = EventsStatus.multiline_events_info([ev])
    return JsonResponse(ev_data)
コード例 #16
0
    def test_all_events_info(self):
        self.create_events()

        with self.assertNumQueries(4):
            info = EventsStatus.all_events_info()
            self.assertEqual(len(info), 3)
            # pre, blank, test, test1, blank, merge
            self.assertEqual(len(info[0]["jobs"]), 6)

        # make sure limit works
        with self.assertNumQueries(4):
            info = EventsStatus.all_events_info(limit=1)
            self.assertEqual(len(info), 1)
            self.assertEqual(len(info[0]["jobs"]), 6)

        last_modified = models.Event.objects.last().last_modified
        last_modified = last_modified + datetime.timedelta(0,10)

        # make sure last_modified works
        with self.assertNumQueries(4):
            info = EventsStatus.all_events_info(last_modified=last_modified)
            self.assertEqual(len(info), 0)
コード例 #17
0
def user_open_prs(request, username):
    """
    Get the updates for the main page.
    """
    users = models.GitUser.objects.filter(name=username)
    if users.count() == 0:
        return HttpResponseBadRequest('Bad username')

    if 'last_request' not in request.GET:
        return HttpResponseBadRequest('Missing parameters')

    this_request = TimeUtils.get_local_timestamp()
    last_request = int(float(request.GET['last_request'])) # in case it has decimals
    dt = timezone.localtime(timezone.make_aware(datetime.datetime.utcfromtimestamp(last_request)))
    repos = RepositoryStatus.get_user_repos_with_open_prs_status(username)
    repo_ids = []
    pr_ids = []
    for r in repos:
        repo_ids.append(r["id"])
        for pr in r["prs"]:
            pr_ids.append(pr["id"])
    event_list = EventsStatus.get_single_event_for_open_prs(pr_ids)
    evs_info = EventsStatus.multiline_events_info(event_list)
    ev_ids = []
    for e in evs_info:
        ev_ids.append(e["id"])
    # Now get the changed ones
    repos = RepositoryStatus.get_user_repos_with_open_prs_status(username, dt)
    evs_info = EventsStatus.multiline_events_info(event_list, dt)

    data = {'repos': repo_ids,
        'prs': pr_ids,
        'events': ev_ids,
        'repo_status': repos,
        'closed': [],
        'last_request': this_request,
        'changed_events': evs_info,
        }
    return JsonResponse(data)
コード例 #18
0
def pr_update(request, pr_id):
    pr = get_object_or_404(models.PullRequest, pk=pr_id)
    closed = 'Open'
    if pr.closed:
        closed = 'Closed'
    pr_data = {'id': pr.pk,
        'closed': closed,
        'last_modified': TimeUtils.display_time_str(pr.last_modified),
        'created': TimeUtils.display_time_str(pr.created),
        'status': pr.status_slug(),
      }
    pr_data['events'] = EventsStatus.multiline_events_info(pr.events.all(), events_url=True)
    return JsonResponse(pr_data)
コード例 #19
0
ファイル: views.py プロジェクト: joshua-cogliati-inl/civet
def do_repo_page(request, repo):
    """
    Render the repo page. This has the same layout as the main page but only for single repository.
    Input:
        request[django.http.HttpRequest]
        repo[models.Repository]
    """
    limit = 30
    repos_status = RepositoryStatus.filter_repos_status([repo.pk])
    events_info = EventsStatus.events_filter_by_repo([repo.pk], limit=limit)

    params = {
        'repo': repo,
        'repos_status': repos_status,
        'events_info': events_info,
        'event_limit': limit,
        'last_request': TimeUtils.get_local_timestamp(),
        'update_interval': settings.HOME_PAGE_UPDATE_INTERVAL
        }
    return render(request, 'ci/repo.html', params)
コード例 #20
0
ファイル: views.py プロジェクト: joshua-cogliati-inl/civet
def view_pr(request, pr_id):
    """
    Show the details of a PR
    Input:
      request: django.http.HttpRequest
      pr_id: pk of models.PullRequest
    Return:
      django.http.HttpResponse based object
    """
    pr = get_object_or_404(models.PullRequest.objects.select_related('repository__user'), pk=pr_id)
    ev = pr.events.select_related('build_user', 'base__branch__repository__user__server').latest()
    allowed = Permissions.is_collaborator(request.session, ev.build_user, ev.base.repo())
    current_alt = []
    alt_choices = []
    default_choices = []
    if allowed:
        alt_recipes = (models.Recipe.objects
                .filter(repository=pr.repository,
                    build_user=ev.build_user,
                    current=True,
                    active=True,
                    cause=models.Recipe.CAUSE_PULL_REQUEST_ALT,)
                .order_by("display_name"))

        default_recipes = (models.Recipe.objects
                .filter(repository=pr.repository,
                    build_user=ev.build_user,
                    current=True,
                    active=True,
                    cause=models.Recipe.CAUSE_PULL_REQUEST,)
                .order_by("display_name"))

        push_recipes = (models.Recipe.objects
                .filter(repository=pr.repository,
                    build_user=ev.build_user,
                    current=True,
                    active=True,
                    cause=models.Recipe.CAUSE_PUSH,)
                .order_by("display_name"))

        default_recipes = [r for r in default_recipes.all()]
        current_alt = [ r.pk for r in pr.alternate_recipes.all() ]
        current_default = [j.recipe.filename for j in pr.events.latest("created").jobs.all() ]
        push_map = {r.filename: r.branch for r in push_recipes.all()}
        alt_choices = []
        for r in alt_recipes:
            alt_choices.append({"recipe": r,
                "selected": r.pk in current_alt,
                "push_branch": push_map.get(r.filename),
                })

        default_choices = []
        for r in default_recipes:
            default_choices.append({"recipe": r,
                "pk": r.pk,
                "disabled": r.filename in current_default,
                "push_branch": push_map.get(r.filename),
                })

        if alt_choices and request.method == "POST":
            form_choices = [ (r.pk, r.display_name) for r in alt_recipes ]
            form = forms.AlternateRecipesForm(request.POST)
            form.fields["recipes"].choices = form_choices
            form_default_choices = []
            for r in default_choices:
                if not r["disabled"]:
                    form_default_choices.append((r["pk"], r["recipe"].display_name))
            form.fields["default_recipes"].choices = form_default_choices
            if form.is_valid():
                pr.alternate_recipes.clear()
                for pk in form.cleaned_data["recipes"]:
                    alt = models.Recipe.objects.get(pk=pk)
                    pr.alternate_recipes.add(alt)
                # do some saves to update the timestamp so that the javascript updater gets activated
                pr.save()
                pr.events.latest('created').save()
                messages.info(request, "Success")
                pr_event = PullRequestEvent.PullRequestEvent()
                selected_default_recipes = []
                if form.cleaned_data["default_recipes"]:
                    q = models.Recipe.objects.filter(pk__in=form.cleaned_data["default_recipes"])
                    selected_default_recipes = [r for r in q]
                pr_event.create_pr_alternates(pr, default_recipes=selected_default_recipes)
                # update the choices so the new form is correct
                current_alt = [ r.pk for r in pr.alternate_recipes.all() ]
                alt_choices = [ {"recipe": r, "selected": r.pk in current_alt} for r in alt_recipes ]
            else:
                messages.warning(request, "Invalid form")
                logger.warning("Invalid form")
                for field, errors in form.errors.items():
                    logger.warning("Form error in field: %s: %s" % (field, errors))

    events = EventsStatus.events_with_head(pr.events)
    evs_info = EventsStatus.multiline_events_info(events, events_url=True)
    context = { "pr": pr,
        "events": evs_info,
        "allowed": allowed,
        "update_interval": settings.EVENT_PAGE_UPDATE_INTERVAL,
        "alt_choices": alt_choices,
        "default_choices": default_choices,
        }
    return render(request, 'ci/pr.html', context)