Skip to content
Snippets Groups Projects
Commit 16268205 authored by Nick Lee's avatar Nick Lee
Browse files

Use student's preferred UW email when inviting and auto-retry failed HTTP requests

parent 0c0194e0
No related branches found
No related tags found
No related merge requests found
...@@ -5,6 +5,7 @@ import argparse,getpass,re ...@@ -5,6 +5,7 @@ import argparse,getpass,re
import sys,subprocess,os import sys,subprocess,os
import json,urllib.request import json,urllib.request
import gitlab import gitlab
import ldap
# Parse command-line arguments. # Parse command-line arguments.
parser = argparse.ArgumentParser(description="This script is used to create student repositories.") parser = argparse.ArgumentParser(description="This script is used to create student repositories.")
...@@ -84,11 +85,11 @@ for student in students: ...@@ -84,11 +85,11 @@ for student in students:
master_branch_exists = True master_branch_exists = True
if not master_branch_exists: if not master_branch_exists:
print("> master branch doesn't exist for %s. Creating it." % student) print("> master branch doesn't exist for %s. Creating it." % student)
time.sleep(3)
for assn in ['A0', 'A1', 'A2', 'A3', 'A4']: for assn in ['A0', 'A1', 'A2', 'A3', 'A4']:
print("> Doing work for assignment %s" % assn) print("> Doing work for assignment %s" % assn)
gitlab.request('projects/%d/repository/files' % project_ids[student], gitlab.request('projects/%d/repository/files' % project_ids[student],
post_hash={'file_path':("%s/.gitignore" % assn), 'branch_name':"master", 'content':"*.class\n", 'commit_message':("Creating %s folder" % assn)}) post_hash={'file_path':("%s/.gitignore" % assn), 'branch_name':"master", 'content':"*.class\n", 'commit_message':("Creating %s folder" % assn)})
time.sleep(5)
# Wait for master branch to become protected. Gitlab seems to have a delay on protecting the # Wait for master branch to become protected. Gitlab seems to have a delay on protecting the
# master branch when it's created. # master branch when it's created.
...@@ -129,7 +130,8 @@ for student in students: ...@@ -129,7 +130,8 @@ for student in students:
# Step 2: Make the post request to invite by email # Step 2: Make the post request to invite by email
if authenticity_token: if authenticity_token:
student_email = "%s@uwaterloo.ca" % student #student_email = "%s@uwaterloo.ca" % student
student_email = ldap.get_student_email(student)
print("> Got authenticity token.") print("> Got authenticity token.")
print("> Sending invitation email to %s" % student_email) print("> Sending invitation email to %s" % student_email)
post_data = urllib.parse.urlencode({'authenticity_token':authenticity_token,'user_ids':student_email,'access_level':30}).encode('ascii') post_data = urllib.parse.urlencode({'authenticity_token':authenticity_token,'user_ids':student_email,'access_level':30}).encode('ascii')
...@@ -141,4 +143,4 @@ for student in students: ...@@ -141,4 +143,4 @@ for student in students:
print("> Could not add student %s to repo!" % student) print("> Could not add student %s to repo!" % student)
print("> Done processing %s." % student) print("> Done processing %s." % student)
time.sleep(10) # Put in a bit of a delay so that git.uwaterloo.ca isn't hammered time.sleep(5) # Put in a bit of a delay so that git.uwaterloo.ca isn't hammered
...@@ -12,37 +12,41 @@ private_token = '' ...@@ -12,37 +12,41 @@ private_token = ''
# post_hash: A dictionary of data to send in a POST request # post_hash: A dictionary of data to send in a POST request
# query_headers: Any headers you want to send as part of the request # query_headers: Any headers you want to send as part of the request
# quit_on_error: If True, will quit program on error. If False, will # quit_on_error: If True, will quit program on error. If False, will
# return False on error instead # try 2 more times, and finially return false
# Returns: A python object # Returns: A python object
def request(query, post_hash={}, query_headers={}, http_method=None, quit_on_error=True): def request(query, post_hash={}, query_headers={}, http_method=None, quit_on_error=False, max_attempts=3):
try: max_tries = 3
if 'PRIVATE-TOKEN' not in query_headers: for request_attempt in list(range(1,max_tries+1)):
query_headers['PRIVATE-TOKEN'] = private_token try:
post_data = urllib.parse.urlencode(post_hash).encode('ascii') if post_hash else None if 'PRIVATE-TOKEN' not in query_headers:
req = urllib.request.Request(url="https://git.uwaterloo.ca/api/v3/" + query, query_headers['PRIVATE-TOKEN'] = private_token
data=post_data, post_data = urllib.parse.urlencode(post_hash).encode('ascii') if post_hash else None
headers=query_headers, req = urllib.request.Request(url="https://git.uwaterloo.ca/api/v3/" + query,
method=http_method) data=post_data,
with urllib.request.urlopen(req) as f: headers=query_headers,
json_string = f.read().decode('utf-8') method=http_method)
try: with urllib.request.urlopen(req) as f:
python_object = json.loads(json_string) json_string = f.read().decode('utf-8')
except Exception as e: try:
print(json_string) python_object = json.loads(json_string)
print("Error occurred trying to interpret above data as JSON.") except Exception as e:
print("Error message: %s" % str(e)) print(json_string)
if quit_on_error: print("Error occurred trying to interpret above data as JSON.")
sys.exit(1) print("Error message: %s" % str(e))
else: if quit_on_error:
return False sys.exit(1)
return python_object else:
except Exception as e: return False
print("Error occurred trying to access https://git.uwaterloo.ca/api/v3/" + query) return python_object
print("Error %s message: %s" % (type(e).__name__, str(e))) except Exception as e:
if quit_on_error: print("Error occurred trying to access https://git.uwaterloo.ca/api/v3/" + query)
sys.exit(1) print("Error %s message: %s" % (type(e).__name__, str(e)))
else: if quit_on_error:
return False sys.exit(1)
elif request_attempt < max_tries:
print("Retrying... (re-try number %d)" % request_attempt)
print("Request failed after %d attempts" % max_tries)
return False
# Read private token from token_file. Mutates the global private_token # Read private token from token_file. Mutates the global private_token
# above and returns it too. # above and returns it too.
......
ldap.py 0 → 100644
#!/usr/bin/python3
from ldap3 import Server, Connection, ALL
# Returns the preferred email of the given student
def get_student_email(userid):
userid = userid[0:8]
conn = Connection('uwldap.uwaterloo.ca', auto_bind=True)
conn.search('dc=uwaterloo,dc=ca', '(uid=%s)' % userid, attributes=['mail', 'mailLocalAddress', 'cn'])
if conn.entries:
return conn.entries[0].mail
else:
return "%s@uwaterloo.ca" % userid
# For testing
#print(get_student_email('jsmio'))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment