20
20
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
21
# THE SOFTWARE.
22
22
23
+ import argparse
24
+ import datetime
23
25
import requests
24
26
25
27
from adabot import github_requests as github
26
28
from adabot .lib import common_funcs
27
29
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" )
28
34
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
37
35
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 )]
39
41
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.
57
64
"""
58
- labels_assigned = 0
59
65
60
66
params = {
61
67
"state" : "open" ,
@@ -86,17 +92,64 @@ def assign_hacktoberfest(repo):
86
92
87
93
response = requests .get (link , timeout = 30 )
88
94
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
+
89
132
for issue in issues :
133
+ update_issue = False
90
134
label_names = [label ["name" ] for label in issue ["labels" ]]
91
135
has_good_first = "good first issue" in label_names
92
136
has_hacktober = {"Hacktoberfest" , "hacktoberfest" } & set (label_names )
93
137
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 :
100
153
params = {
101
154
"labels" : label_names
102
155
}
@@ -107,27 +160,36 @@ def assign_hacktoberfest(repo):
107
160
json = params )
108
161
109
162
if result .ok :
110
- labels_assigned += 1
163
+ labels_changed += 1
111
164
else :
112
165
# sadly, GitHub will only silently ignore labels that are
113
166
# not added and return a 200. so this will most likely only
114
167
# trigger on endpoint/connection failures.
115
168
print ("Failed to add Hacktoberfest label to: {}" .format (issue ["url" ]))
116
169
117
- return labels_assigned
170
+ return labels_changed
118
171
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 )
121
174
return result
122
175
123
176
124
177
if __name__ == "__main__" :
125
178
labels_assigned = 0
179
+ args = cli_args .parse_args ()
180
+
181
+ remove_labels = args .remove_label
126
182
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..." )
128
187
129
188
repos = common_funcs .list_repos ()
130
189
for repo in repos :
131
- labels_assigned += process_hacktoberfest (repo )
190
+ labels_assigned += process_hacktoberfest (repo , remove_labels )
132
191
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