Exemplo n.º 1
0
    def standardize_repos_and_authors(self):
        """"
        Doesn't modify a scope, but returns some plural forms that let callers not know' \
        if the scope specified plural or singular objects
        """
        repos = None
        authors = None

        if self.author:

            if isinstance(self.author, str):
                email = self.author.replace(" ", "+")
                authors = Author.objects.filter(email=email)
            else:
                authors = Author.objects.filter(pk=self.author.pk).values_list(
                    'pk', flat=True)
        elif self.repo:
            authors = self.repo.author_ids(self.start, self.end)
        else:
            authors = None

        if not self.repo and self.author:
            repos = Author.repos(repos, self.start,
                                 self.end).values_list('pk', flat=True)
        elif self.repo:
            repos = Repository.objects.filter(pk=self.repo.pk).values_list(
                'pk', flat=True)
        else:
            assert self.org is not None
            repos = [
                x.pk for x in Repository.objects.filter(
                    organization=self.org).all()
            ]

        return (repos, authors)
Exemplo n.º 2
0
def repo_table(scope):  # repos, start, end):

    #this drives the list of all repos within an organization, showing the statistics for them within the selected
    #time range, along with navigation links.

    (repos, authors) = scope.standardize_repos_and_authors()
    interval = 'DY'
    # FIXME: explain
    repos = [x.pk for x in scope.available_repos.all()]
    stats = Statistic.queryset_for_range(repos=repos,
                                         authors=authors,
                                         start=scope.start,
                                         end=scope.end,
                                         interval=interval)
    stats = Statistic.annotate(
        stats.values('repo__name')).order_by('repo__name')
    data = _annotations_to_table(stats, 'repo', 'repo__name')

    # FIXME: insert in author count, which is ... complicated ... this can be optimized later
    # we should be able to grab every repo and annotate it with the author count in one extra query tops
    # but it might require manually writing it.
    for d in data:
        repo = d['repo']
        author_count = Author.author_count(repo,
                                           start=scope.start,
                                           end=scope.end)
        d['author_count'] = author_count

    # some repos won't have been scanned, and this requires a second query to fill them into the table
    repos = Repository.objects.filter(last_scanned=None,
                                      organization=scope.org)
    for unscanned in repos:
        data.append(dict(repo=unscanned.name))
    return data
Exemplo n.º 3
0
def author_stats_table(scope, limit=None):
    """
    this drives the author tables, both ranged and non-ranged, accessed off the main repo list.
    the interval 'LF' shows lifetime stats, but elsewhere we just do daily roundups, so this parameter
    should really be a boolean.  The limit parameter is not yet used.
    """

    results = []

    interval = scope.interval
    if interval != 'LF':
        interval = 'DY'

    authors = None
    if scope.repo:
        authors = Author.authors(scope.repo, scope.start, scope.end)

    def add_stat(author, repo):
        stat1 = Statistic.queryset_for_range(repo,
                                             author=author,
                                             start=scope.start,
                                             end=scope.end,
                                             interval=scope.interval)
        stat2 = Statistic.compute_interval_statistic(stat1,
                                                     interval=scope.interval,
                                                     repo=repo,
                                                     author=author,
                                                     start=scope.start,
                                                     end=scope.end)
        stat2 = stat2.to_dict()
        stat2['author'] = author.email
        stat2['repo'] = repo.name
        if stat2['lines_changed']:
            # skip authors with no contribution in the time range
            results.append(stat2)

    if not scope.author and scope.repo:
        for author in authors:
            add_stat(author, scope.repo)
    elif scope.author and not scope.repo:
        for repo in scope.author.repos():
            add_stat(scope.author, repo)
    elif scope.author and scope.repo:
        add_stat(scope.author, scope.repo)

    return results
Exemplo n.º 4
0
    def compute_daily_rollup(cls, repo=None, author=None, start_day=None, total_instances=None):

        """
        Generate rollup stats for everything the team did on a given day
        """

        end_date = cls.get_end_day(start_day, DAY)

        file_change_count = FileChange.change_count(repo, author=author, start=start_day, end=end_date)

        if file_change_count == 0:
            # this looks like a merge commit, FIXME: it would be a good idea to validate that this is 100% true.
            # print("-- skipping potential merge commit --")
            return

        if not author:
            authors_count = Author.author_count(repo, start=start_day, end=end_date)
        else:
            authors_count = 1

        # Aggregate values from query set for rollup

        data = FileChange.aggregate_stats(repo, author=author, start=start_day, end=end_date)

        # FIXME: if start_day is today, we need to UPDATE the current stat? - verify if the bulk_update code deals with this?
        # FIXME: model code method below is rather inefficient, does this matter?

        # Create total rollup row for the day
        stat = Statistic(
            start_date=start_day,
            interval=DAY,
            repo=repo,
            author=author,
            lines_added=data['lines_added'],
            lines_removed=data['lines_removed'],
            lines_changed=data['lines_changed'],
            commit_total= data['commit_total'],
            files_changed=data['files_changed'],
            author_total=authors_count,
            days_active=1,
        )

        stat.compute_derived_values()


        cls.smart_bulk_update(repo=repo, start_day=start_day, author=author, interval=DAY, stat=stat, total_instances=total_instances)
Exemplo n.º 5
0
 def get_authors_for_repo(cls, repo):
     """
     Return the authors involved in the repo
     """
     return Author.authors(repo)