2020# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2121# THE SOFTWARE.
2222
23+ import argparse
24+ import datetime
2325import requests
2426
2527from adabot import github_requests as github
2628from adabot .lib import common_funcs
2729
30+ cli_args = argparse .ArgumentParser (description = "Hacktoberfest Label Assigner" )
31+ cli_args .add_argument ("-r" , "--remove-label" , action = "store_true" ,
32+ help = "Option to remove Hacktoberfest labels, instead of adding them." ,
33+ dest = "remove_label" )
2834
29- def ensure_hacktober_label_exists (repo ):
30- """ Checks if the 'Hacktoberfest' label exists on the repo.
31- If not, creates the label.
32- """
33- response = github .get ("/repos/" + repo ["full_name" ] + "/labels" )
34- if not response .ok :
35- print ("Failed to retrieve labels for '{}'" .format (repo ["name" ]))
36- return False
3735
38- repo_labels = [label ["name" ] for label in response .json ()]
36+ # Hacktoberfest Season
37+ # - lists are in [start, stop] format.
38+ # - tuples are in (month, day) format.
39+ _ADD_SEASON = [(9 , 29 ), (10 , 30 )]
40+ _REMOVE_SEASON = [(11 , 1 ), (11 , 10 )]
3941
40- hacktober_exists = {"Hacktoberfest" , "hacktoberfest" } & set (repo_labels )
41- if not hacktober_exists :
42- params = {
43- "name" : "Hacktoberfest" ,
44- "color" : "f2b36f" ,
45- "description" : "DigitalOcean's Hacktoberfest"
46- }
47- result = github .post ("/repos/" + repo ["full_name" ] + "/labels" , json = params )
48- if not result .status_code == 201 :
49- print ("Failed to create new Hacktoberfest label for: {}" .format (repo ["name" ]))
50- return False
51-
52- return True
53-
54- def assign_hacktoberfest (repo ):
55- """ Gathers open issues on a repo, and assigns the 'Hacktoberfest' label
56- to each issue if its not already assigned.
42+ def is_hacktober_season ():
43+ """ Checks if the current day falls within either the add range (_ADD_SEASON)
44+ or the remove range (_REMOVE_SEASON). Returns boolean if within
45+ Hacktoberfest season, and which action to take.
46+ """
47+ today = datetime .date .today ()
48+ add_range = [
49+ datetime .date (today .year , * month_day ) for month_day in _ADD_SEASON
50+ ]
51+ remove_range = [
52+ datetime .date (today .year , * month_day ) for month_day in _REMOVE_SEASON
53+ ]
54+ if add_range [0 ] <= today <= add_range [1 ]:
55+ return True , "add"
56+ elif remove_range [0 ] <= today <= remove_range [1 ]:
57+ return True , "remove"
58+
59+ return False , None
60+
61+
62+ def get_open_issues (repo ):
63+ """ Retrieve all open issues for given repo.
5764 """
58- labels_assigned = 0
5965
6066 params = {
6167 "state" : "open" ,
@@ -86,17 +92,64 @@ def assign_hacktoberfest(repo):
8692
8793 response = requests .get (link , timeout = 30 )
8894
95+ return issues
96+
97+
98+ def ensure_hacktober_label_exists (repo ):
99+ """ Checks if the 'Hacktoberfest' label exists on the repo.
100+ If not, creates the label.
101+ """
102+ response = github .get ("/repos/" + repo ["full_name" ] + "/labels" )
103+ if not response .ok :
104+ print ("Failed to retrieve labels for '{}'" .format (repo ["name" ]))
105+ return False
106+
107+ repo_labels = [label ["name" ] for label in response .json ()]
108+
109+ hacktober_exists = {"Hacktoberfest" , "hacktoberfest" } & set (repo_labels )
110+ if not hacktober_exists :
111+ params = {
112+ "name" : "Hacktoberfest" ,
113+ "color" : "f2b36f" ,
114+ "description" : "DigitalOcean's Hacktoberfest"
115+ }
116+ result = github .post ("/repos/" + repo ["full_name" ] + "/labels" , json = params )
117+ if not result .status_code == 201 :
118+ print ("Failed to create new Hacktoberfest label for: {}" .format (repo ["name" ]))
119+ return False
120+
121+ return True
122+
123+ def assign_hacktoberfest (repo , issues = None , remove_labels = False ):
124+ """ Gathers open issues on a repo, and assigns the 'Hacktoberfest' label
125+ to each issue if its not already assigned.
126+ """
127+ labels_changed = 0
128+
129+ if not issues :
130+ issues = get_open_issues (repo )
131+
89132 for issue in issues :
133+ update_issue = False
90134 label_names = [label ["name" ] for label in issue ["labels" ]]
91135 has_good_first = "good first issue" in label_names
92136 has_hacktober = {"Hacktoberfest" , "hacktoberfest" } & set (label_names )
93137
94- if has_good_first and not has_hacktober :
95- label_exists = ensure_hacktober_label_exists (repo )
96- if not label_exists :
97- continue
98-
99- label_names .append ("Hacktoberfest" )
138+ if remove_labels :
139+ if has_hacktober :
140+ label_names = [
141+ label for label in lable_names
142+ if label not in has_hacktober
143+ ]
144+ update_issue = True
145+ else :
146+ if has_good_first and not has_hacktober :
147+ label_exists = ensure_hacktober_label_exists (repo )
148+ if not label_exists :
149+ continue
150+ update_issue = True
151+
152+ if update_issue :
100153 params = {
101154 "labels" : label_names
102155 }
@@ -107,27 +160,36 @@ def assign_hacktoberfest(repo):
107160 json = params )
108161
109162 if result .ok :
110- labels_assigned += 1
163+ labels_changed += 1
111164 else :
112165 # sadly, GitHub will only silently ignore labels that are
113166 # not added and return a 200. so this will most likely only
114167 # trigger on endpoint/connection failures.
115168 print ("Failed to add Hacktoberfest label to: {}" .format (issue ["url" ]))
116169
117- return labels_assigned
170+ return labels_changed
118171
119- def process_hacktoberfest (repo ):
120- result = assign_hacktoberfest (repo )
172+ def process_hacktoberfest (repo , issues = None , remove_labels = False ):
173+ result = assign_hacktoberfest (repo , issues , remove_labels )
121174 return result
122175
123176
124177if __name__ == "__main__" :
125178 labels_assigned = 0
179+ args = cli_args .parse_args ()
180+
181+ remove_labels = args .remove_label
126182
127- print ("Checking for open issues to assign the Hacktoberfest label to..." )
183+ if not remove_labels :
184+ print ("Checking for open issues to assign the Hacktoberfest label to..." )
185+ else :
186+ print ("Checking for open issues to remove the Hacktoberfest label from..." )
128187
129188 repos = common_funcs .list_repos ()
130189 for repo in repos :
131- labels_assigned += process_hacktoberfest (repo )
190+ labels_assigned += process_hacktoberfest (repo , remove_labels )
132191
133- print ("Added the Hacktoberfest label to {} issues." .format (labels_assigned ))
192+ if not remove_labels :
193+ print ("Added the Hacktoberfest label to {} issues." .format (labels_assigned ))
194+ else :
195+ print ("Removed the Hacktoberfest label from {} issues." .format (labels_assigned ))
0 commit comments