Exemple #1
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
Exemple #2
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.
    """

    # FIXME: this performs one query PER author and could be rewritten to be a LOT more intelligent.

    (repos, authors) = scope.standardize_repos_and_authors()
    interval = 'DY'
    stats = Statistic.queryset_for_range(repos=repos,
                                         authors=authors,
                                         start=scope.start,
                                         end=scope.end,
                                         interval=interval)
    data = None
    if not scope.author:
        stats = Statistic.annotate(
            stats.values('author__email')).order_by('author__email')
        data = _annotations_to_table(stats, 'author', 'author__email')
    else:
        stats = Statistic.annotate(
            stats.values('repo__name')).order_by('repo__name')
        data = _annotations_to_table(stats, 'repo', 'repo__name')
    return data
Exemple #3
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.
    """

    results = []
    for repo in scope.repos:
        stats = Statistic.queryset_for_range(repo,
                                             author=None,
                                             interval='DY',
                                             start=scope.start,
                                             end=scope.end)
        stat2 = Statistic.compute_interval_statistic(stats,
                                                     interval='DY',
                                                     repo=repo,
                                                     author=None,
                                                     start=scope.start,
                                                     end=scope.end)
        stat2 = stat2.to_dict()
        stat2['name'] = repo.name
        # providing pk's for link columns in the repo chart
        for x in ['details1', 'details2', 'details3']:
            stat2[x] = repo.pk
        results.append(stat2)
    results = sorted(results, key=lambda x: x['name'])
    return json.dumps(results)
Exemple #4
0
    def compute_interval_rollup(cls, repo=None, author=None, interval=None, start_day=None, total_instances=None):
        """
        Use the daily team stats to generate weekly or monthly rollup stats.
        start_day is the beginning of that period
        """

        # FIXME: all this code should be cleaned up.

        # IF in weekly mode, and start_day is this week, we need to delete the current stat
        # IF in monthly mode, and start_day is this month, we need to delete the current stat

        assert repo is not None
        assert interval in [ 'WK', 'MN', 'LF']

        (start_day, end_date) = cls.start_and_end_dates_for_interval(repo=repo, author=author, start=start_day, interval=interval)
        if start_day is None and interval != 'LF':
            print("**** GLITCH: Author has no commits? ", author)
            return

        days = cls._queryset_for_interval_rollup(repo=repo, author=author, interval=interval, start_day=start_day, end_date=end_date)

        if days.count() == 0:
            # probably just a merge commit today, be cool about it and skip this one.
            return

        stat = Statistic.compute_interval_statistic(days, repo=repo, interval=interval, author=author, start=start_day, end=end_date, for_update=True)

        cls.smart_bulk_update(repo=repo, start_day=start_day, author=author, interval=interval, stat=stat, total_instances=total_instances)
Exemple #5
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)
Exemple #6
0
 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)
Exemple #7
0
    def compute_interval_rollup(cls,
                                repo=None,
                                author=None,
                                interval=None,
                                start_day=None,
                                total_instances=None):
        """
        Use the daily team stats to generate weekly or monthly rollup stats.
        start_day is the beginning of that period
        """

        # IF in weekly mode, and start_day is this week, we need to delete the current stat
        # IF in monthly mode, and start_day is this month, we need to delete the current stat

        end_date = cls.get_end_day(start_day, interval)

        days = None
        if not author:
            days = Statistic.objects.filter(
                author__isnull=True,
                interval=DAY,
                repo=repo,
                start_date__range=(cls.aware(start_day), cls.aware(end_date)))
        else:
            days = Statistic.objects.filter(
                author=author,
                interval=DAY,
                repo=repo,
                start_date__range=(cls.aware(start_day), cls.aware(end_date)))

        # aggregates total stats for the interval
        data = days.aggregate(lines_added=Sum("lines_added"),
                              lines_removed=Sum("lines_removed"),
                              lines_changed=Sum("lines_changed"),
                              commit_total=Sum("commit_total"),
                              files_changed=Sum("files_changed"),
                              author_total=Max("author_total"))

        stat = Statistic(start_date=cls.aware(start_day),
                         interval=interval,
                         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=data['author_total'])

        cls.smart_bulk_update(repo=repo,
                              start_day=start_day,
                              author=author,
                              interval=interval,
                              stat=stat,
                              total_instances=total_instances)
Exemple #8
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
        """
        file_changes = None
        if not author:
            file_changes = FileChange.objects.select_related(
                'commit', 'author').filter(
                    commit__commit_date__year=start_day.year,
                    commit__commit_date__month=start_day.month,
                    commit__commit_date__day=start_day.day,
                )
        else:
            file_changes = FileChange.objects.select_related(
                'commit',
                'author').filter(commit__commit_date__year=start_day.year,
                                 commit__commit_date__month=start_day.month,
                                 commit__commit_date__day=start_day.day,
                                 commit__author=author)

        if file_changes.count() == 0:
            return

        # FIXME: probably not the most efficient way to do this
        commits = file_changes.values_list('commit',
                                           flat=True).distinct().all()
        files = file_changes.values_list('file', flat=True).distinct().all()
        authors = Commit.objects.filter(pk__in=commits).values_list(
            'author', flat=True).distinct().all()
        authors_count = len(authors)

        # Aggregate values from query set for rollup
        data = file_changes.aggregate(lines_added=Sum("lines_added"),
                                      lines_removed=Sum("lines_removed"))
        commits_total = len(commits)
        files_changed = len(files)
        lines_added = data['lines_added']
        lines_removed = data['lines_removed']
        lines_changed = lines_added + lines_removed

        # FIXME: if start_day is today, we need to delete the current stat

        # Create total rollup row for the day
        stat = Statistic(start_date=cls.aware(start_day),
                         interval=DAY,
                         repo=repo,
                         author=author,
                         lines_added=lines_added,
                         lines_removed=lines_removed,
                         lines_changed=lines_changed,
                         commit_total=commits_total,
                         files_changed=files_changed,
                         author_total=authors_count)

        cls.smart_bulk_update(repo=repo,
                              start_day=start_day,
                              author=author,
                              interval=DAY,
                              stat=stat,
                              total_instances=total_instances)