Projects
MOSS - Sakai Submission Script

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)