#!/usr/bin/python

import os,sys,subprocess,time



#########################################################################
# This Python script is called CheckoutAndCommit.py
# This script can checkout the student's code, and also add + commit.
# Last edited by Nick Lee on December 20, 2011
#
#
#
# For each assignment, you should set these four variables:
#
# csv_file_location: In MarkUs, under Groups tab, you can download a CSV file that contains
#                    each student's Quest ID and group_XXXX ID. You should save that CSV file
#                    somewhere on the course account. This variable is the path to that CSV 
#                    file.
csv_file_location = '/u/cs115/marking/a09/a09groups.csv'
#
# assn: This is whatever you typed for "Repository Folder"
#       in the assignment properties page in MarkUs.
assn = 'a09'
#
# checkout_folder: This is the folder where you want to checkout the students' 
#                  code to.
checkout_folder = '/u/cs115/handin/a09_autotest'
#
# due_date: The due date of the assignment. You may want to give the students
#           an extra 10 min or so. Format is yyyy-mm-dd hh:mm:ss
due_date = '2011-12-31 16:10:00'
#
#
#
# At the start of the term, enter the MarkUs URL used by your course here.
# Valid formats:
#     "https://markus002.student.cs.uwaterloo.ca/markus_cs115_f"
#     "markus002.student.cs.uwaterloo.ca/markus_cs115_f"
#     "https://markus002.student.cs.uwaterloo.ca/markus_cs136_f/en/main"
markus_url = "markus002.student.cs.uwaterloo.ca/markus_cs115_f/en/main"
#
#
#########################################################################



# Read the group/quest id CSV file, and produces a list.
# Example of possible output: 
#    [['dlundqui','group_0014'], ['scen','group_0112'], ['vmiskovi','group_0094']]
# Each item in the produced list is a two-item list, where:
#     first item is a student's Quest ID
#     second item is that student's group_XXXX ID.
def ReadGroupMap(location):
	try:
		ans = []
		s = file(location,"r")
		contents = s.readlines()
		s.close()
		for line in contents:
			l = line.split(',')
			ans.append([l[2][:-1],l[1]])
		return ans
	except:
		print "Error occured while reading " + location
		return None
		
# Produces a Quest ID, given a group_XXXX ID. The second argument
# can be the ouput of ReadGroupMap.
def GetQuestID(group_code, CODES):
	for student in CODES:
		if group_code == student[1]:
			return student[0]
	return None
	
# Produces a group_XXXX, given a Quest ID. The second argument
# can be the ouput of ReadGroupMap.
def GetGroupID(quest_id, CODES):
	for student in CODES:
		if quest_id == student[0]:
			return student[1]
	return None
	
# Prints help message
def PrintHelp():
	print "This script expects two arguments."
	print 
	print "The first argument can be either checkout or commit."
	print "If you use checkout, this script will checkout the students' code to:"
	print checkout_folder
	print "If you use commit, this script will add and commit GRADED_ASSIGNMENT.*"
	print
	print "The second argument can be either viewcmds or runcmds."
	print "If you use viewcmds, this script will display some terminal"
	print "commands, but it won't execute any of them. If the second"
	print "argument is runcmds instead, then this script will execute"
	print "the commands."
	print
	

CODES = ReadGroupMap(csv_file_location)

# determine the start of the SVN repository URL
markus_url_root = markus_url.find('markus002.student.cs')
markus_name = markus_url[markus_url_root:].split('/')[1]
svn_url_root = "svn+ssh://markus@markus002.student.cs.uwaterloo.ca/u/markus/%s/svn-repos-root" % markus_name

###
### START
###

runcmds = False
nbr_of_students = len(CODES)
curr_student = 1
checkout_error = []
commit_error = []

if len(sys.argv) != 3:
	PrintHelp()
	sys.exit()


if sys.argv[2] == "runcmds":
	runcmds = True


if sys.argv[1] == 'checkout':
	for stud in CODES:
		print "--- Checking out assignment for " + stud[0] + " --- " + str(curr_student) + "/" + str(nbr_of_students)
		print "Checkout command: ",
		cmd = 'svn checkout -r "{%s}" %s/%s/%s %s/%s/' % (due_date, svn_url_root, stud[1], assn, checkout_folder, stud[0])
		print cmd
		if os.path.isdir(checkout_folder + '/' + stud[0]):
			print "Directory " + checkout_folder + '/' + stud[0] + " already exists. Skipping..."
			curr_student = curr_student + 1
			continue
		if runcmds:
			result = subprocess.call(cmd, shell=True)
			print "Command exited with code: " + str(result)
			if result != 0:
				checkout_error.append(stud);
		curr_student = curr_student + 1
elif sys.argv[1] == 'commit':
	for stud in CODES:
		print "--- Performing add and commit for " + stud[0] + " --- " + str(curr_student) + "/" + str(nbr_of_students)
		# add
		print "Add command:    ",
		cmd = 'svn add ' + checkout_folder + '/' + stud[0] + '/GRADED_ASSIGNMENT.*'
		print cmd
		if runcmds:
			print "Command exited with code: " + str(subprocess.call(cmd, shell=True))
		# commit
		print "Commit command: ",
		cmd = 'svn commit ' + checkout_folder + '/' + stud[0] + '/GRADED_ASSIGNMENT.* -m "Commiting GRADED_ASSIGNMENT.* for ' + stud[0] + '"' 
		print cmd
		if runcmds:
			result = subprocess.call(cmd, shell=True);
			print "Command exited with code: " + str(result)
			if result != 0:
				commit_error.append(stud);
		curr_student = curr_student + 1
else:
	PrintHelp()

print
print

if len(checkout_error) > 0:
	print "These students had checkout errors:" 
	print checkout_error
	print

if len(commit_error) > 0:
	print "These students had commit errors:" 
	print commit_error
	print

print
print "-----------------------------------"	
print time.strftime("Completed %A %B %d, %Y at %H:%M:%S %Z %z")