Skip to content

Commit

Permalink
Merge pull request #111 from sommersoft/hacktober_schedule
Browse files Browse the repository at this point in the history
Schedule Hacktoberfest Labeling
  • Loading branch information
kattni authored Oct 7, 2019
2 parents 462006f + e6f0485 commit b2f6591
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 40 deletions.
17 changes: 17 additions & 0 deletions adabot/circuitpython_libraries.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from adabot import pypi_requests as pypi
from adabot.lib import circuitpython_library_validators as cirpy_lib_vals
from adabot.lib import common_funcs
from adabot.lib import assign_hacktober_label as hacktober

# Setup ArgumentParser
cmd_line_parser = argparse.ArgumentParser(
Expand Down Expand Up @@ -132,6 +133,8 @@ def run_library_checks(validators, bundle_submodules, latest_pylint, kw_args):
"open_issues": [],
"issue_authors": set(),
"issue_closers": set(),
"hacktober_assigned": 0,
"hacktober_removed": 0,
}
core_insights = copy.deepcopy(lib_insights)
for k in core_insights:
Expand Down Expand Up @@ -426,6 +429,20 @@ def print_issue_overview(*insights):
.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)

if __name__ == "__main__":
validator_kwarg_list = {}
startup_message = [
Expand Down
142 changes: 102 additions & 40 deletions adabot/lib/assign_hacktober_label.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,42 +20,48 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import argparse
import datetime
import requests

from adabot import github_requests as github
from adabot.lib import common_funcs

cli_args = argparse.ArgumentParser(description="Hacktoberfest Label Assigner")
cli_args.add_argument("-r", "--remove-label", action="store_true",
help="Option to remove Hacktoberfest labels, instead of adding them.",
dest="remove_label")

def ensure_hacktober_label_exists(repo):
""" Checks if the 'Hacktoberfest' label exists on the repo.
If not, creates the label.
"""
response = github.get("/repos/" + repo["full_name"] + "/labels")
if not response.ok:
print("Failed to retrieve labels for '{}'".format(repo["name"]))
return False

repo_labels = [label["name"] for label in response.json()]
# Hacktoberfest Season
# - lists are in [start, stop] format.
# - tuples are in (month, day) format.
_ADD_SEASON = [(9, 29), (10, 30)]
_REMOVE_SEASON = [(11, 1), (11, 10)]

hacktober_exists = {"Hacktoberfest", "hacktoberfest"} & set(repo_labels)
if not hacktober_exists:
params = {
"name": "Hacktoberfest",
"color": "f2b36f",
"description": "DigitalOcean's Hacktoberfest"
}
result = github.post("/repos/" + repo["full_name"] + "/labels", json=params)
if not result.status_code == 201:
print("Failed to create new Hacktoberfest label for: {}".format(repo["name"]))
return False

return True

def assign_hacktoberfest(repo):
""" Gathers open issues on a repo, and assigns the 'Hacktoberfest' label
to each issue if its not already assigned.
def is_hacktober_season():
""" Checks if the current day falls within either the add range (_ADD_SEASON)
or the remove range (_REMOVE_SEASON). Returns boolean if within
Hacktoberfest season, and which action to take.
"""
today = datetime.date.today()
add_range = [
datetime.date(today.year, *month_day) for month_day in _ADD_SEASON
]
remove_range = [
datetime.date(today.year, *month_day) for month_day in _REMOVE_SEASON
]
if add_range[0] <= today <= add_range[1]:
return True, "add"
elif remove_range[0] <= today <= remove_range[1]:
return True, "remove"

return False, None


def get_open_issues(repo):
""" Retrieve all open issues for given repo.
"""
labels_assigned = 0

params = {
"state": "open",
Expand Down Expand Up @@ -86,17 +92,64 @@ def assign_hacktoberfest(repo):

response = requests.get(link, timeout=30)

return issues


def ensure_hacktober_label_exists(repo):
""" Checks if the 'Hacktoberfest' label exists on the repo.
If not, creates the label.
"""
response = github.get("/repos/" + repo["full_name"] + "/labels")
if not response.ok:
print("Failed to retrieve labels for '{}'".format(repo["name"]))
return False

repo_labels = [label["name"] for label in response.json()]

hacktober_exists = {"Hacktoberfest", "hacktoberfest"} & set(repo_labels)
if not hacktober_exists:
params = {
"name": "Hacktoberfest",
"color": "f2b36f",
"description": "DigitalOcean's Hacktoberfest"
}
result = github.post("/repos/" + repo["full_name"] + "/labels", json=params)
if not result.status_code == 201:
print("Failed to create new Hacktoberfest label for: {}".format(repo["name"]))
return False

return True

def assign_hacktoberfest(repo, issues=None, remove_labels=False):
""" Gathers open issues on a repo, and assigns the 'Hacktoberfest' label
to each issue if its not already assigned.
"""
labels_changed = 0

if not issues:
issues = get_open_issues(repo)

for issue in issues:
update_issue = False
label_names = [label["name"] for label in issue["labels"]]
has_good_first = "good first issue" in label_names
has_hacktober = {"Hacktoberfest", "hacktoberfest"} & set(label_names)

if has_good_first and not has_hacktober:
label_exists = ensure_hacktober_label_exists(repo)
if not label_exists:
continue

label_names.append("Hacktoberfest")
if remove_labels:
if has_hacktober:
label_names = [
label for label in lable_names
if label not in has_hacktober
]
update_issue = True
else:
if has_good_first and not has_hacktober:
label_exists = ensure_hacktober_label_exists(repo)
if not label_exists:
continue
update_issue = True

if update_issue:
params = {
"labels": label_names
}
Expand All @@ -107,27 +160,36 @@ def assign_hacktoberfest(repo):
json=params)

if result.ok:
labels_assigned += 1
labels_changed += 1
else:
# sadly, GitHub will only silently ignore labels that are
# not added and return a 200. so this will most likely only
# trigger on endpoint/connection failures.
print("Failed to add Hacktoberfest label to: {}".format(issue["url"]))

return labels_assigned
return labels_changed

def process_hacktoberfest(repo):
result = assign_hacktoberfest(repo)
def process_hacktoberfest(repo, issues=None, remove_labels=False):
result = assign_hacktoberfest(repo, issues, remove_labels)
return result


if __name__ == "__main__":
labels_assigned = 0
args = cli_args.parse_args()

remove_labels = args.remove_label

print("Checking for open issues to assign the Hacktoberfest label to...")
if not remove_labels:
print("Checking for open issues to assign the Hacktoberfest label to...")
else:
print("Checking for open issues to remove the Hacktoberfest label from...")

repos = common_funcs.list_repos()
for repo in repos:
labels_assigned += process_hacktoberfest(repo)
labels_assigned += process_hacktoberfest(repo, remove_labels)

print("Added the Hacktoberfest label to {} issues.".format(labels_assigned))
if not remove_labels:
print("Added the Hacktoberfest label to {} issues.".format(labels_assigned))
else:
print("Removed the Hacktoberfest label from {} issues.".format(labels_assigned))
19 changes: 19 additions & 0 deletions adabot/lib/circuitpython_library_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from adabot import travis_requests as travis
from adabot import pypi_requests as pypi
from adabot.lib import common_funcs
from adabot.lib import assign_hacktober_label as hacktober


# Define constants for error strings to make checking against them more robust:
Expand Down Expand Up @@ -867,6 +868,24 @@ def gather_insights(self, repo, insights, since):
days_open.days)
insights["open_issues"].append(issue_link)

# 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"}
Expand Down

0 comments on commit b2f6591

Please sign in to comment.