Stanford's Measure of Software Similarity (MOSS) allows you to quickly and intelligently check students' software submissions for signs of plagiarism. More detailed instructions regarding general use of MOSS can be found here.
To automate the MOSS submission process using the file hierarchy exported by Sakai when downloading student submissions, I've written the python script below which traverses those folders, pulls out the student's files, appends their netIDs to each file, and then submits them all to the MOSS server. Note that this code has only been tested on a Linux machine. For more detailed instructions, please email me.
# Craig LaBoda # Duke University # February 2015 # # This script traverses the standard Sakai file tree of students' submissions, renaming and copying the files to a temporary location. Afterwards, it submits those files to moss to check for plagiarism. # # Instructions: # 1. Make a top directory that contains this file, your version of the moss.pl script, and the the Sakai folders from the bulk download option in Sakai. Each of these Sakai folders should contain many subfolders, each corresponding to a student in the class. # 2. Adjust the settings for this script to reflect the names of those folders and any changes to the general moss settings. # 3. Run this python script from the top directory described in Step 1. import os import shutil import datetime # --------------------------------- Settings ---------------------------------- # Names of Sakai folders sakaiDirs = ["2015submissions","2014submissions"]; # The unique label for each of these directories dirLabel = '2015','2014'; # Keep the temporary directory with renamed files for debugging purposes? keepTempDir = 0; # The extensions of the files you are submitting extension = ".v"; # Some general moss settings mossLang = "verilog"; mossMVal = "40"; mossTitle = "Duke ECE###, Homework 1, Spring 2015 and 2015"; mossFilter = '*'; # use this to filter certain submissions by name (e.g. m* for all files starting with m) - useful for multi file assignments # -------------------------------- Main Script ---------------------------------- # Generate a temporary directory tempDir = "temp_"+str(datetime.datetime.now()) tempDir = tempDir.replace(" ","_"); tempDir = tempDir.replace("-","_"); tempDir = tempDir.replace(":","_"); tempDir = tempDir.replace(".","_"); if not os.path.exists(tempDir): os.makedirs(tempDir) # Start by looping through all specified Sakai directories for k in xrange(0,len(sakaiDirs)): # Iterate through all of the students in the current directory cursakaiDirs = sakaiDirs[k] for item in os.listdir(cursakaiDirs): # Get the student's netid netIDstart = item.index('(')+1 netIDstop = item.index('@') netid = item[netIDstart:netIDstop] # Go into the student's submission folder loopDir = os.getcwd()+'/'+cursakaiDirs+'/'+item+'/'+'Submission attachment(s)' # Loop through all files and focus only on those with the correct extension for filename in os.listdir(loopDir): if filename.endswith(extension): filenameEndInd = filename.index('.') # Move a copy of the file to the temporary folder # While moving, append the unique label and netid newfilename = filename[0:filenameEndInd]+'_'+str(dirLabel[k])+'_'+netid+extension newfilename = newfilename.replace(" ","") newfilename = newfilename.lower() shutil.copy(loopDir+'/'+filename, os.getcwd()+'/'+tempDir+'/'+newfilename) # Now that all of the files are in the moveDir, submit them to the moss server mossCall = 'perl moss.pl -l '+mossLang+' -m '+mossMVal+' -c "'+mossTitle+'" '+tempDir+'/'+mossFilter+extension os.system(mossCall) # Remove the temporary directory for renamed files if the user wants if (keepTempDir==0): shutil.rmtree(tempDir)