Autograde Script 2.0

As with the earlier versions, this script is designed to check my students’ typing assignments against a key. I had to download all submitted assignments in moodle, placing them in a folder on my linux box, placing the key in .txt format, and running the script. This would output a fairly long filename that had the grade in it. I would then have to go ahead and manually enter in students’ grades in moodle and manually upload each response file. It was a big improvement, but still a tedious process. This new script automates the entire process.

The usage for the script is simply

./autograde lesson#

After that, it downloads all assignments, grades them, posts the grades to moodle, and uploads a response file.

There were some challenges for me in this one, most of which involved learning the intricacies of moodle. If you’re interested in adapting this for your own purposes, you should know that each assignment has a different number. One is related to the submissions.php file which displays the assignments in the browser, the other is related to the moodledata folder where the submissions for each student are actually stored.

In order to make this work, I had to be able to query the mysql database to find the userid number for each student. Each submission file begins with the student’s username, so I had to find a way to truncate the file so that it would return the username only and then use that to query the mysql database to return the userid. I found a great php script here and ended up using it twice in my setup – once to obtain the username in order to find the userid, and again later to obtain a consistent, and simpler filename. The second instance probably could have been done in bash instead of php, but I was already taking up too much time to write this script as it was. At some point, I may tinker with it and see if I can make it more efficient, but since it works, I’m not really inclined to fix it.

If you have any comments or suggestions on how to improve it in any way, I welcome your comments.

Dependencies:
docx2txt
dwdiff
curl
Chirp Internet’s php text truncation script
ftp access to your moodledata directory

First, here’s the main script. If you’re going to use it, be sure to change the URL’s and replace the username and password with your correct information. Also, you’ll need to do a search and replace to replace the &lt and &gt with the proper angle brackets.

#!/bin/bash

# first check if there is one argument1:
if [ "$#" -ne 1 ]; then
    echo "usage: $0 &ltlesson#&gt"
    exit
fi

WORKDIR=$HOME/autograde/$1
KEYFILE=$HOME/autograde/keys/$1key.txt


if [ "$1" == lesson1 ]; then
ASSIGNMENT=125
UPLOADDIR=93
else if [ "$1" == lesson2 ]; then
ASSIGNMENT=126
UPLOADDIR=94
else if [ "$1" == lesson3 ]; then
ASSIGNMENT=127
UPLOADDIR=95
else if [ "$1" == lesson4 ]; then
ASSIGNMENT=17
UPLOADDIR=11
else if [ "$1" == lesson5 ]; then
ASSIGNMENT=15
UPLOADDIR=10
else if [ "$1" == lesson6 ]; then
ASSIGNMENT=33
UPLOADDIR=22
else if [ "$1" == lesson7 ]; then
ASSIGNMENT=54
UPLOADDIR=35
else if [ "$1" == lesson8 ]; then
ASSIGNMENT=74
UPLOADDIR=50
else if [ "$1" == lesson9 ]; then
ASSIGNMENT=94
UPLOADDIR=67
else if [ "$1" == lesson10 ]; then
ASSIGNMENT=128
UPLOADDIR=96
else if [ "$1" == lesson11 ]; then
ASSIGNMENT=129
UPLOADDIR=97
else if [ "$1" == lesson12 ]; then
ASSIGNMENT=98
UPLOADDIR=71
else if [ "$1" == lesson13 ]; then
ASSIGNMENT=130
UPLOADDIR=98
else if [ "$1" == lesson14 ] ; then
ASSIGNMENT=131
UPLOADDIR=99
else if [ "$1" == lesson15 ] ; then
ASSIGNMENT=132
UPLOADDIR=100
else if [ "$1" == lesson16 ] ; then
ASSIGNMENT=133
UPLOADDIR=101
else echo "Please input the lesson you which to grade as \"lesson#\", using only lower case, no spaces, and of course, no quotes."
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi

echo "Moodle assignment number is" $ASSIGNMENT
echo "Working directory is" $WORKDIR
echo "The key for this exercise is" $KEYFILE

#visit the home page to get current session cookie
echo "Visiting the home page to get current session cookie"
wget --spider --save-cookies cookies.txt --keep-session-cookies https://yourwebsite.com/moodle/login/index.php

#log in to moodle
echo "logging into moodle"
wget --load-cookies cookies.txt --save-cookies cookies.txt --keep-session-cookies --post-data "username=username&password=password&testcookie=1" -O- https://yourwebsite.com/moodle/login/index.php

#download all files for assignment
echo "downloading zip file containing assignments for" $1
wget --load-cookies cookies.txt --save-cookies cookies.txt --keep-session-cookies --post-data "download=zip" -O "$WORKDIR/assignments.zip" https://yourwebsite.com/moodle/mod/assignment/submissions.php?id=$ASSIGNMENT


#unzip assignments to appropriate location
unzip $WORKDIR/assignments.zip -d $WORKDIR

#delete previously uploaded feedback files
rm $WORKDIR/*response*

GRADEDDIR=$WORKDIR/graded

#checks to see if $GRADEDDIR exists and creates it if it does not
if [ ! -d "$GRADEDDIR" ]; then
mkdir -p "$GRADEDDIR"
fi

#converts MS Word format to plain text
for UNGRADED in $WORKDIR/*.docx; do
docx2txt.sh $UNGRADED;
done

#compares text files against key and outputs to .GRADED.txt file
for GRADED in $WORKDIR/*.txt; do
/usr/bin/dwdiff -s $KEYFILE $GRADED &gt "$WORKDIR/$(basename $GRADED .txt).GRADED"
done

#renames .GRADED file with information dwdiff writes to end of file
for RENAMED in $WORKDIR/*.GRADED; do
mv $RENAMED "$WORKDIR/$(basename $RENAMED .GRADED).$(grep "old:" $RENAMED).RENAMED"
done

#moves graded files to graded directory
for MOVED in $WORKDIR/*.RENAMED; do
mv "$MOVED" $GRADEDDIR/
done

#begin converting .RENAMED to .html
for COLORIZED in $GRADEDDIR/*.RENAMED; do
cat "$COLORIZED" | sed -e 's/\[-/&ltspan style=\"background-color:red\"&gt/g' -e 's/-\]/&lt\/span&gt/g' -e 's/{+/&ltspan style=\"background-color:yellow\"&gt/g' -e 's/+}/&lt\/span&gt/g' -e '1i&lthtml&gt\n&ltbody&gt\n&ltpre&gt' -e 's/old:/Answer Key:/' -e 's/new:/Your Document:/' &gt "$COLORIZED.html"
done

#finish converting .txt to .html
for HTMLEND in $GRADEDDIR/*.html; do
echo "&lt/pre&gt
&lt/body&gt
&lt/html&gt" &gt&gt '$HTMLEND'
done

#clean up the filenames a bit
rename 's/.old: /\-/' $GRADEDDIR/*.html
rename 's/.RENAMED././' $GRADEDDIR/*.html

#removes .txt files from $WORKDIR
rm $WORKDIR/*.txt
#remove last line of .RENAMED file and rename to .TRUNCATED
for TRUNCATED in $GRADEDDIR/*.RENAMED; do
sed -e '$d' "$TRUNCATED" &gt "$TRUNCATED".TRUNCATED
done

#remove spaces from .TRUNCATED filenames
rename 's/ /_/g' $GRADEDDIR/*.TRUNCATED

#remove spaces from .html filenames
rename 's/ /_/g' $GRADEDDIR/*.html

#remove % sign and replace with word 'percent' in html filenames
rename 's/%/percent/g' $GRADEDDIR/*.html

#remove all .RENAMED files from $GRADEDDIR to clean up a bit
rm $GRADEDDIR/*.RENAMED

#define userid and grade variables and post the grades and a generic comment to moodle
for POSTED in $GRADEDDIR/*.TRUNCATED; do
USERID=$(curl -s -d "filename=$(basename $POSTED)" http://yourwebsite.com/getuserid.php)
POSTEDGRADE=$(grep -o '[[:digit:]]*% common' $POSTED | grep -o '[[:digit:]]*')
wget --load-cookies cookies.txt --save-cookies cookies.txt --keep-session-cookies --post-data "offset=1&userid=$USERID&id=$ASSIGNMENT&mode=grade&menuindex=10&saveuserid=-1&grade=$POSTEDGRADE&submissioncomment=Please+ask+me+if+you+have+any+questions.+&format=1&mailinfo=0&submit=Save+changes" -O- https://yourwebsite.com/moodle/mod/assignment/submissions.php
done

echo "Now renaming files into an easier to read format. This may take a while."

for RESPONSEFILES in $GRADEDDIR/*.html; do
GETUSERID=$(curl -s -d "filename=$(basename $RESPONSEFILES)" http://yourwebsite.com/getuserid.php | sed 's/ //g')
GETSHORTNAME=$(curl -s -d "filename=$(basename $RESPONSEFILES)" "http://yourwebsite.com/getusername.php" | sed 's/ //g')
mv $RESPONSEFILES $GRADEDDIR/$GETSHORTNAME
done

rename 's/Chapter/_Chapter/' $GRADEDDIR/*.html

for SHORTNAMERESPONSE in $GRADEDDIR/*.html ; do
GETUSERID=$(curl -s -d "filename=$(basename $SHORTNAMERESPONSE)" http://yourwebsite.com/getuserid.php | sed 's/ //g')
curl -T $SHORTNAMERESPONSE ftp://yourwebsite.com/moodledata/2/moddata/assignment/$UPLOADDIR/$GETUSERID/responses/ --user username:password --ftp-create-dirs
done

#clean up a bit more
rm $WORKDIR/assignments.zip
rm $GRADEDDIR/*.TRUNCATED
rm $WORKDIR/*.docx
rm $GRADEDDIR/*.html

Next is the getuserid.php script:

&lt?php
// Original PHP code by Chirp Internet: www.chirp.com.au 
// Please acknowledge use of this code by including this header. 
function myTruncate($string, $limit, $break=".", $pad="...") 
{  
  // return with no change if string is shorter than $limit  
  if(strlen($string) &lt= $limit) return $string;  
  // is $break present between $limit and the end of the string?  
   if(false !== ($breakpoint = strpos($string, $break, $limit))) {  
     if($breakpoint &lt strlen($string) - 1) {  
  $string = substr($string, 0, $breakpoint);  
  }
  } 
  
  return $string; 
  }

$con = mysql_connect("localhost",databasename","password");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }

mysql_select_db("databasename", $con);

$testpost = $_POST['filename'];
$testtruncate = myTruncate($testpost, 1, "_");
$result = mysql_query("SELECT id FROM mdl_user WHERE username LIKE '$testtruncate'") or die(mysql_error());
while($row = mysql_fetch_array($result))
  {
  echo $row["id"];
  }

mysql_close($con);
?&gt 

Last is the getusername.php script, which really probably could be done entirely in bash, I just haven’t put my head to it yet:

&lt?php
$filename = $_POST['filename'];
$pieces = explode("_", $filename);
echo $pieces[0] . $pieces[1] . $pieces[2] . "feedback.html";
?&gt 

And that’s it. Again, any comments or suggestions you have are most welcome.

Leave a Reply

Your email address will not be published. Required fields are marked *