Ejemplo n.º 1
0
def print_issue_overview(*insights):
    closed_issues = sum([x["closed_issues"] for x in insights])
    issue_closers = set().union(*[x["issue_closers"] for x in insights])
    new_issues = sum([x["new_issues"] for x in insights])
    issue_authors = set().union(*[x["issue_authors"] for x in insights])
    output_handler(
        "* {} closed issues by {} people, {} opened by {} people".format(
            closed_issues, len(issue_closers), new_issues, len(issue_authors)))

    # print Hacktoberfest labels changes if its Hacktober
    in_season, season_action = hacktober.is_hacktober_season()
    if in_season:
        hacktober_changes = ""
        if season_action == "add":
            hacktober_changes = "* Assigned Hacktoberfest label to {} issues.".format(
                sum([x["hacktober_assigned"] for x in insights]))
        elif season_action == "remove":
            hacktober_changes += "* Removed Hacktoberfest label from {} issues.".format(
                sum([x["hacktober_removed"] for x in insights]))
        output_handler(hacktober_changes)
    def gather_insights(self, repo, insights, since, show_closed_metric=False):
        """Gather analytics about a repository like open and merged pull requests.
        This expects a dictionary with GitHub API repository state (like from the
        list_repos function) and will fill in the provided insights dictionary
        with analytics it computes for the repository.
        """

        if repo["owner"]["login"] != "adafruit":
            return []
        params = {"sort": "updated",
                  "state": "all",
                  "since": since.strftime("%Y-%m-%dT%H:%M:%SZ")}
        response = github.get("/repos/" + repo["full_name"] + "/issues", params=params)
        if not response.ok:
            # replace 'output_handler' with ERROR_OUTPUT_HANDLER
            self.output_file_data.append("Insights request failed: {}".format(repo["full_name"]))
            return [ERROR_OUTPUT_HANDLER]

        issues = response.json()
        for issue in issues:
            created = datetime.datetime.strptime(issue["created_at"], "%Y-%m-%dT%H:%M:%SZ")
            if "pull_request" in issue:
                pr_info = github.get(issue["pull_request"]["url"])
                pr_info = pr_info.json()
                if issue["state"] == "open":
                    if created > since:
                        insights["new_prs"] += 1
                        insights["pr_authors"].add(pr_info["user"]["login"])
                    insights["active_prs"] += 1
                else:
                    if pr_info["merged"]:
                        merged_info = ""
                        if show_closed_metric:
                            created = datetime.datetime.strptime(
                                issue["created_at"],
                                "%Y-%m-%dT%H:%M:%SZ"
                            )
                            merged = datetime.datetime.strptime(
                                issue["closed_at"],
                                "%Y-%m-%dT%H:%M:%SZ"
                            )

                            days_open = merged - created
                            if days_open.days < 0: # opened earlier today
                                days_open += datetime.timedelta(
                                    days=(days_open.days * -1)
                                )
                            elif days_open.days == 0:
                                days_open += datetime.timedelta(
                                    days=(1)
                                )
                            merged_info = " (Days open: {})".format(days_open.days)

                        pr_link = "{0}{1}".format(
                            issue["pull_request"]["html_url"],
                            merged_info
                        )
                        insights["merged_prs"].append(pr_link)

                        pr_author = pr_info["user"]["login"]
                        if pr_author == "weblate":
                            pr_commits = github.get(str(pr_info["url"]) + "/commits")
                            if pr_commits.ok:
                                for commit in pr_commits.json():
                                    author = commit.get("author")
                                    if author:
                                        insights["pr_merged_authors"].add(author["login"])
                        else:
                            insights["pr_merged_authors"].add(pr_info["user"]["login"])

                        insights["pr_reviewers"].add(pr_info["merged_by"]["login"])
                        pr_reviews = github.get(str(pr_info["url"]) + "/reviews")
                        if pr_reviews.ok:
                            for review in pr_reviews.json():
                                if review["state"].lower() == "approved":
                                    insights["pr_reviewers"].add(review["user"]["login"])
                    else:
                        insights["closed_prs"] += 1
            else:
                issue_info = github.get(issue["url"])
                issue_info = issue_info.json()
                if issue["state"] == "open":
                    if created > since:
                        insights["new_issues"] += 1
                        insights["issue_authors"].add(issue_info["user"]["login"])
                    insights["active_issues"] += 1

                else:
                    insights["closed_issues"] += 1
                    insights["issue_closers"].add(issue_info["closed_by"]["login"])

        issues = []
        params = {"state": "open", "per_page": 100}
        response = github.get("/repos/" + repo["full_name"] + "/issues", params=params)
        if not response.ok:
            # replace 'output_handler' with ERROR_OUTPUT_HANDLER
            self.output_file_data.append("Issues request failed: {}".format(repo["full_name"]))
            return [ERROR_OUTPUT_HANDLER]

        while response.ok:
            issues.extend(response.json())
            try:
                links = response.headers["Link"]
            except KeyError:
                break

            if links:
                next_url = None
                for link in links.split(","):
                    link, rel = link.split(";")
                    link = link.strip(" <>")
                    rel = rel.strip()
                    if rel == "rel=\"next\"":
                        next_url = link
                        break
                if not next_url:
                    break
                response = requests.get(link, timeout=30)

        for issue in issues:
            created = datetime.datetime.strptime(issue["created_at"], "%Y-%m-%dT%H:%M:%SZ")
            days_open = datetime.datetime.today() - created
            if days_open.days < 0: # opened earlier today
                days_open += datetime.timedelta(days=(days_open.days * -1))
            if "pull_request" in issue:
                pr_link = "{0} (Open {1} days)".format(issue["pull_request"]["html_url"],
                                                       days_open.days)
                insights["open_prs"].append(pr_link)
            else:
                issue_link = "{0} (Open {1} days)".format(issue["html_url"],
                                                          days_open.days)
                insights["open_issues"].append(issue_link)
                if "labels" in issue:
                    for i in issue["labels"]:
                        if i["name"] == 'good first issue':
                            insights["good_first_issues"] += 1

        # process Hacktoberfest labels if it is Hacktoberfest season
        in_season, season_action = hacktober.is_hacktober_season()
        if in_season:
            hacktober_issues = [
                issue for issue in issues if "pull_request" not in issue
            ]
            if season_action == "add":
                insights["hacktober_assigned"] += (
                    hacktober.assign_hacktoberfest(repo,
                                                   issues=hacktober_issues)
                )
            elif season_action == "remove":
                insights["hacktober_removed"] += (
                    hacktober.assign_hacktoberfest(repo,
                                                   issues=hacktober_issues,
                                                   remove_labels=True)
                )

        # get milestones for core repo
        if repo["name"] == "circuitpython":
            params = {"state": "open"}
            response = github.get("/repos/adafruit/circuitpython/milestones", params=params)
            if not response.ok:
                # replace 'output_handler' with ERROR_OUTPUT_HANDLER
                self.output_file_data.append("Failed to get core milestone insights.")
                return [ERROR_OUTPUT_HANDLER]
            else:
                milestones = response.json()
                for milestone in milestones:
                    #print(milestone)
                    insights["milestones"][milestone["title"]] = milestone["open_issues"]
        return []