The Monash Unit Description Avatar
A.J.Hurst
Version
Table of Contents
<version 1> = 2.8.5
1. Global Constants
<context variables 2> =my $TESTING = 0;
Define whether we are running in test mode
<context variables 3> =my $WEBPAGE = "/u/homes1/ajh";
my $SERVER = "http://www.csse.monash.edu.au";
Define the location of the home web page, and the base server
address
<context variables 4> =#my $TestingVersion = "<B> Test Version! </B>";
my $TestingVersion = "";
my $SUBMISSIONS = "$WEBPAGE/units";
Set this to the name of the unit descriptions directory. There
is one of these directories for each faculty using the
avatar
<context variables 5> =my $CGIPAGE = "$SERVER/cgi-bin/cgiwrap/ajh";
Define the base page for any cgi scripts.
<context variables 6> =my $XMLPAGE = "$WEBPAGE/cgi-bin";
Define where all XML and XSL support scripts and files are
stored.
<context variables 7> =my $APPROVALS = "$XMLPAGE/MonAtar-IT.appr";
<context variables 8> =my $TMP = "$WEBPAGE/tmp";
<context variables 9> =my $GRAPHICS = "$SERVER/~ajh/graphics";
<context variables 10> =# Set this to the name of the CGI on your web server
$SCRIPT = "$CGIPAGE/MonAtar";
<context variables 11> =# Define the xslt processor and options
$XSLTOPTS = "XML_CATALOG_FILES=$XMLPAGE/catalog";
$XSLTPROC = "$XSLTOPTS /usr/local/bin/xsltproc";
$XP = "--param";
2. Overview
This document describes Version 2 of the Infotech Subject
Avatar, now know as MonAtar (MONash AvaTAR).
The purpose of the system is to maintain on-line documentation
associated with course and unit offerings, originally within the
Faculty of Information Technology at Monash, but recently
extended to other faculties (Business and Economics,
Medicine). The system is built using XML technology, while the
actual Common Gateway Interface (CGI) components are written in
Perl. This document details the main Perl component
MonAtar, with links to the other components.
The XML components of the system include document type
definitions (dtds), XML templates, and eXtensible Stylesheet
Language Transformations (XSLT). The latter perform significant
amounts of processing within the system, and are invoked from
within the main Perl cgi script, the MonAtar program
itself. These documents are defined separately, as defining XSLT
documents within an XML document can get a bit bizarre!
2.1 The Manifest
Files used in this system are described below. In general,
XSL files are maintained separately, because of the editing
issues mentioned above.
- a2x.w
- The literate program (old style) to convert text to XML
markup. This is actually uploaded to the cgi web site as the
derived file a2x.pl.
- basic2html.xsl
- XSLT transformer for basic markup items
- maketest.pl
- A hastily cobbled together perl script to generate a
test version for running on the local host.
- monatar.xlp
- The source form of this document. This is a literate
program, translated to the output file MonAtar by a
suite of XSLT scripts. MonAtar is a perl cgi
script.
- UnitDescriptionV2.dtd
- The document type definition for the unit description
itself.
- UnitTemplateV2.xml
- This defines the initial form of a freshly created unit
decription.
- V1toV2.xsl
- XSLT script to convert unit description
documents from Version 1 to Version 2 format
- V2Guidelines.xml
- An XML file that is converted to
V2Guidelines.html and uploaded to the web site. This
file contains helpful instructions on how to edit the
various parts of the unit description file.
- xml2html.xsl
- XSLT script to convert unit description documents from
Version 2 to HTML, presented as a viewable document or
editable document, depending upon the value of the parameter
ViewOrEdit (View or Edit
respectively).
- xml2txt.xsl
- XSLT script to translate XML markup to formatted plain
text, for editing by novice editors.
- xmlextract.xsl
- xslt.dtd
- A link to the document type definition for all the XSLT
scripts that form part of this package.
-
MakeReviewForm.xsl
- mergexml.xsl
- MonAtar-appr.xsl
- Merge approval information with an XML unit
description.
- MonAtar-version.xsl
- Review2html.xsl
- ReviewV1.dtd
- sanitiseV2.xsl
- stylesheet.dtd
2.2 User Issues
- Have separate edit buttons for each section.
- Incorporate a2x.pl into monatar litprog
- Design Version Control interface
- Create a lock file on the no version comment page.
Delete this lock file when edits are saved or submitted.
Good question is what happens if the user doesn't save or
submit. Should the lock be removed say after 24 hours?
(The edits are saved, but not in the archive.)
- add StartPoint mechanism to always display description
at edit point.
- Generate the prohibitions matrix; change wording of
submit statement; include subject description in email;
define interest groups
2.3 Pedagogic Issues
Ainslie Ellis writes:
I have looked at the new format. It looks fine.
Is it possible to provide a sample outline that has a brief
comment under each heading (or a link to an html page if a
longer comment is needed) that indicates what should be
thought of at each stage. I already have a lot of this
information. and am happy to write up a checklist for each
item if you think this would be useful.
Also in the objectives part, I would prefer this to
commence with At the completion of a unit a student should
be able to:
followed by perhaps a comment like
- Write your cognitive domain objectives here
- Write your affective domain objectives here
- Write your psychomotor domain objectives here
- Write your social domain objectives here
with a link to an html document (see attachment for this
email) for more detail.
2.4 Legacy Issues
- Write a conversion xsl script from old format to
new. Complete, called V1toV2.xsl
- Create copy of units directory and archive wherein all
descriptions can be converted. Keep this up-to-date until
change-over. Done.
- The new cgi script will be cookie based, to avoid
reauthentication. Done.
- The new cgi script will be monolithic, to eliminate a
majority security hole in the previous version. Done.
2.5 Directories and files
There are various locations where the files are to be stored,
defined symbolically within this script as:
- XMLPAGE
- The directory containing all xml and xsl files required
for MonAtar use. On shelob this is $WEBPAGE/cgi-bin,
while on ararat it is $WEBPAGE/xml
- basic2html.xsl
- XSL script included by xml2html.xsl
- canonical.pl
- perl script to convert an XML file into canonical
form. I'm not sure this is required any longer, since
sanitise.xsl has been written?
3. The MonAtar Main cgi script and Authentication
"MonAtar" 12 =#!/usr/bin/perl
<initialization 13,14>
<subroutines 22,23,24,25,26,27,28,29,30,33,34,36,40,42,50,53,60,61,65,66,69,74,76,98,103,104,105,106>
<get parameters 15,16,17>
if ($auth->param('UnitCode') && @params==1) {
&doView($auth->param('UnitCode'));
} elsif ($auth->param('compare')) {
&doCompare;
} elsif ($auth->param('authaction') =~ /Authenticate/) {
<perform avatar authentication 20>
} elsif ($auth->param('authenticate') || (!$cookie)) {
<login to avatar 19>
} elsif (!$auth->param && $cookie) {
<re-enter avatar 18>
} elsif ($auth->param('reenter')) {
<re-enter avatar 18>
} elsif ($auth->param('view')) {
&doView($auth->param('UnitCode'));
} elsif ($auth->param('create')) {
&doEdit(1);
} elsif ($auth->param('edit')) {
&doEdit(0);
} elsif ($auth->param('change')) {
&doChange();
} elsif ($auth->param('update')) {
&doUpdate();
} elsif ($auth->param('Save')) {
&doSave();
} elsif ($auth->param('Submit')) {
&doSubmit();
} elsif ($auth->param('compare')) {
&doCompare;
} elsif ($auth->param('show')) {
&doShow;
} elsif ($auth->param('approve')) {
&doApprove;
} elsif ($auth->param('review')) {
&doReview;
} elsif ($auth->param('reviewSubmit')) {
&doReviewSubmit;
} else {
<illegal parameters 21>
}
&printBottom;
close DEBUG;
close LOG;
exit;
The order of tests in here is very important, and controls the
security of the system. Do not reorder these tests without
obeying the following rules! The key issue is that the avatar
can be used without authentication for viewing or comparing unit
descriptions, but for all other purposes, the user must be
authenticated. A cookie is issued once the user has
authenticated, and this avoids having to re-authenticate on
repeat visits to the home avatar page.
Two pages generated by the avatar have special significance.
They are the login page and authenticating page. The login page
requires the user to enter details of their AuthCate userid and
password, while the authenticating page performs the
authentication of these details by looking up the Monash
Directory Pages, and returning information about what is found.
This page also sets a cookie, to avoid the user having to
re-authenticate.
The first test therefore checks to see if the desired display
is to view a unit description. This is prompted by a single
parameter UnitCode=unitcode. Any additional
parameters and this non-authenticated display will fall through
to require authentication.
The next page that can be viewed without authentication
is the authenticating page itself. This is the second test, and
is driven by the parameter authaction=Authenticate,
generated by the login page. It must appear before the login
page itself, since no cookie has yet been issued, and we want
all attempts to visit pages without cookies to trap to the login
page. If authentication is successful, we move to the Unit
Selection Page.
If the avatar is invoked with an explicit request to
authenticate, or no cookie has yet been issued, we generate the
login page.
If the avatar is invoked with no explicit parameters, but a
cookie has been issued, then this is a revisit to the avatar,
and we generate the Welcome (Back) Page.
Subsequent tests branch into other sections of the avatar for
handling.
The final step, if no tests succeed, is to issue a warning
about illegal parameters to the avatar.
3.1 avatar initialization
<initialization 13> =my @additions=("/local/lib/perl5/site_perl/5.6.0");
push(@INC,@additions);
#print join(',',@INC),"\n";
require Net::LDAP;
use Carp;
use CGI qw(:standard :html3);
$auth = new CGI;
<context variables 2,3,4,5,6,7,8,9,10,11>
my $ldap_server = 'directory.monash.edu';
my $ldap_port = 389;
my $ldap_basedn = 'o=Monash University, c=AU';
my $dn;
# set to 1 for various debugging information
my $debug = 1;
# cleared once HTML headers have been printed
my $needHeaders = 1;
# This is the displayed title...
$TITLE = "InfoTech Unit Avatar: Authentication";
Chunk referenced in 12Chunk defined in 13,
14
<initialization 14> =$TimeStamp = `/bin/date "+%Y%m%d:%H%M%S"`; chop $TimeStamp;
$timestamp = $TimeStamp; $timestamp=~s/://;
Chunk referenced in 12Chunk defined in 13,
14
This is my timestamp. I use a contraction of the ISO
standard, where the date and time are in most significant
order, with a colon separating the day of the month from the
hour of the day. The year is 4 digits, all others are 2
digits with a leading zero if required.
<get parameters 15> =@params = $auth->param;
unless(open LOG,">>$SUBMISSIONS/log") {
printError('NoLog',"Cannot open log file $SUBMISSIONS/log");
exit;
}
$School = "(No School)";
$Faculty = "(No Faculty)";
$Staff = "(No Staff Info)";
$rawCookie=$ENV{'HTTP_COOKIE'};
@rawCookies = split(/;/,$rawCookie);
foreach(@rawCookies){
m/([^=]*)=(.*)$/;
my ($key,$val) = ($1,$2);
print LOG $TimeStamp,'
<version 1> (key,val)=',"($key,$val)\n";
$cookies{$key} = $val;
}
if ($cookies{'AVATAR'}) {
$cid = $cookies{'AVATAR'};
$cid=~s/\+/ /g;
$cookie="AVATAR=".$cid;
$cid =~ s/--/=/g;
grabPersonData($cid);
}
my $logindata = 0;
foreach $name (@params) {
if ($name eq 'myuid') {$logindata++;}
if ($name eq 'mypass') {$logindata++;}
my $value = $auth->param($name);
$value =~ s/</</g;
#if ($name ne 'mypass') {
# print LOG $name,"=",$value," ";
#}
}
$UnitCode = $auth->param('UnitCode');
$UnitCode =~ tr/a-z/A-Z/;
Chunk referenced in 12Chunk defined in 15,
16,
17
<get parameters 16> =$EditExpert = $auth->param('EditExpert');
Chunk referenced in 12Chunk defined in 15,
16,
17
Does this editor want to edit the XML markup directly, or
does she prefer to use plain text? Set to 1 (in
doEdit) if the former.
<get parameters 17> =# This is the debugging file
$debugfile = "dummy.dbg";
if ($UnitCode) {$debugfile = "$UnitCode.dbg"};
open DEBUG,">$TMP/$debugfile";
print DEBUG "rawCookie=$rawCookie\n";
print DEBUG "Cookie=$cookie\n";
print DEBUG "cid=$cid\n";
print DEBUG "School=$School\n";
print DEBUG "Faculty=$Faculty\n";
Chunk referenced in 12Chunk defined in 15,
16,
17
3.2 avatar main control branches
3.2.1 re-entering the avatar
<re-enter avatar 18> =$TITLE="Infotech Unit Avatar: Home Page (Version
<version 1>)";
&printHtmlHeaders;
$cid=~s/--/=/g;
&grabPersonData($cid);
print "<P></P><h1 align=\"center\" style=\"color:#339933;".
"background-color:#99ffcc\">Welcome back, $given!</h1>";
&doUnitSelection;
We have cookie data, so the user has already authenticated
and re-entered the avatar. Convert the flattened equals
signs back to equals, and extract the given name as the
first word in the common name or cn field. Print the Welcome
Back heading, and then generate the Unit Selection Page.
3.2.2 Logging in to the Avatar
<login to avatar 19> =&printHtmlHeaders;
print start_form(-action=>"$SCRIPT"),
h2("Please supply your AuthCate username and password"),
"Username: ",textfield('myuid'),p,
"Password: ",password_field('mypass'),p,
submit('authaction','Authenticate me!'),
hidden('UnitCode',$auth->param('UnitCode')),
end_form;
print "<em>It may take a minute or so to process</em>";
print " - <b>PLEASE MAKE SURE YOU HAVE COOKIES ENABLED</b>";
print "<p>(If you have already authenticated, click your browser ";
print "RELOAD/REFRESH button to go to the Unit Selection Page)</p>";
No parameters supplied to avatar, or authentication forced,
so print the login page.
3.2.3 Perform avatar authentication
<perform avatar authentication 20> =&doAuthenticate;
if ($dn) {
unless(open LOG,">>$SUBMISSIONS/log") {
printError('NoLog',"Cannot open log file $SUBMISSIONS/log");
exit;
}
print LOG $TimeStamp,'
<version 1> ',$dn,"\n";
&grabPersonData($dn);
my $cookie = $dn;
$cookie=~s/=/--/g; $cookie=~s/ /\+/g;
print "Set-Cookie: AVATAR=$cookie\n";
print LOG $TimeStamp,'
<version 1> ',"Set-Cookie: AVATAR=$cookie\n";
close LOG;
$TITLE="Welcome to the Infotech Unit Avatar Home Page (V
<version 1>)";
&printHtmlHeaders;
# could put first time information in here?
if ($UnitCode) {
&doEdit(0);
} else {
&doUnitSelection;
}
}
Handle the authentication process. I am very grateful
to Nate Bailey for the original code upon which this
subroutine is based, but as it has been significantly
altered, all responsibility rests with me!
If authentication succeeds, we get back a domain name
dn, which is analyzed to extract the user's given
name, and then encoded to avoid problems with internal equal
signs, before being returned to the client as a cookie for
subsequent authentication purposes.
Finally, we generate the Unit Selection Page.
3.2.4 Handle Illegal Parameters
<illegal parameters 21> =$TITLE="Infotech Unit Avatar: Error Page";
&printHtmlHeaders;
$_=$auth->p."These are the parameters and values:";
$_=$_."<P STYLE=\"margin-left:20pt\">";
foreach $name (@params) {
$_=$_.$name.'='.$auth->param($name).'<BR>';
}
$_=$_.'</P>';
&printError("Illegal Parameters",$_);
Note that we should not normally enter this code. If we
do, it is because the avatar has been called with unknown
parameters, so we print that fact, together with a synopsis
of the parameters in error.
3.3 avatar subroutines
<subroutines 22> =sub doLogOperation {
my($location)=(shift);
print LOG $TimeStamp,'
<version 1> ',"$Editor calls $location\n";
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
<subroutines 23> =sub doAuthenticate {
my($uid,$passwd) = (param('myuid'),param('mypass'));
if (!($uid.$passwd)) {
&printHtmlHeaders();
&printError('Insufficient information',
"You left one or more of the fields blank -- ".
"you must fill out all the fields.");
} elsif ($uid eq 'sjoy' && $passwd eq '*****') {
$dn = "cn=Sally Joy2, ou=Department of Racketeering, ".
"ou=Faculty of Business and Economics, ou=Staff, ".
"o=Monash University, c=au";
} elsif ($uid eq 'ajh' && $passwd eq '*****') {
$dn = "cn=John Hurst2, ou=School of Microsoftware Imagineering, ".
"ou=Faculty of Information Technology, ou=Staff, ".
"o=Monash University, c=au";
} elsif ($uid eq 'luff' && $passwd eq '*****') {
$dn = "cn=Tony Luff2, ou=Department of Immaculate Conception, ".
"ou=Faculty of Medicine, ou=Staff, o=Monash University, c=au";
} elsif ($uid eq 'dnh' && $passwd eq '*****') {
$dn = "cn=David Hurst, ou=Department of Students, ".
"ou=Faculty of Information Technology, ou=Student, o=Monash University, c=au";
} else {
$dn = doLDAP(undef,$uid,$passwd);
}
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
doAuthenticate collects username and password
parameters from the call, checks that they are non-empty, and
calls the LDAP authentication routine.
<subroutines 24> =sub doLDAP {
my ($dn,$uid,$pass) = @_;
my $mesg;
if ($pass eq "") {
$pass = $uid;
$uid = $dn;
$dn = undef;
}
my $ld = Net::LDAP->new($ldap_server, port => $ldap_port);
unless ($ld) {
carp "ldap_open to $ldap_server failed!";
return undef;
}
if ($pass eq '') {
carp "ldap bind for $uid failed: no password!";
return undef;
}
unless ($dn) {
unless (($mesg=$ld->bind) && $mesg->code==LDAP_SUCCESS) {
carp "ldap anon bind to $ldap_server failed";
return undef;
}
my $filter = "(uid=$uid)";
unless ($mesg = $ld->search(base=>$ldap_basedn,
filter=>$filter)) {
carp "ldap search for $uid failed";
return undef;
}
my @entries = $mesg->all_entries;
unless (scalar(@entries) == 1) {
&printError("not exactly one ldap entry for $uid");
return undef;
}
$dn = $entries[0]->dn();
}
######################################################
### WARNING!!! If we don't have '$pass', this will ###
### successfully make an _anonymous_ bind. ###
######################################################
unless (($mesg=$ld->bind($dn, password=>$pass))
&& $mesg->code==LDAP_SUCCESS) {
$ld->unbind;
printError("LDAP bind failed",
"I could not connect to the LDAP server. ".
"It returned an error code of ".$mesg->code.
", which means: ".$mesg->error."");
return undef;
}
unless ($mesg = $ld->search(base=>$dn,
filter=>'(objectclass=*)')) {
$ld->unbind;
carp "Search with $uid 's basedn ($dn) failed";
return undef;
}
return $dn;
}
sub doProcessDescription {
print start_html(),
h1('Calling propose('.$auth->param('propose').',
'.$auth->param('UnitCode').')'),
end_form;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
<subroutines 25> =sub printBottom {
return;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
<subroutines 26> =sub printHtmlHeaders {
#if (!$needheaders) {return;}
print header('text/html');
my $ADT = "$SERVER/~ajh/adt";
print <<"END";
<html>
<head>
<meta content="text/html; charset=ASCII" http-equiv="Content-Type">
<title>
$TITLE
</title>
<link rel="stylesheet"
href="$SERVER/~ajh/styles/monash.css"
type="text/css">
</head>
<body>
<div class="spacer"></div>
<div id="global-header">
<div id="global-images">
<table width="100%" bgcolor="white">
<tr width="100%">
<td align="left">
<table>
<tr>
<td align="left">
<a href="http://www.monash.edu.au">
<span style="font-family:sans-serif;
font-size:+160%;font-weight:bold;
background-color:#ffffff;color:black">
MONASH UNIVERSITY
</span>
</a>
</td>
</tr>
<tr>
<td align="left">
<a href="http://www.infotech.monash.edu.au"
COLOR="black">
<span style="font-family:sans-serif;
font-size:+140%;font-weight:bold;
background-color:#ffffff;
color:black">
INFORMATION TECHNOLOGY</span>
</a>
</td>
</tr>
<tr>
<td align="left">
<a href="http://www.csse.monash.edu.au" COLOR="black">
<span style="font-family:sans-serif;
font-size:+120%;font-weight:bold;
background-color:#ffffff;color:black">
Computer Science and Software Engineering</span>
</a>
</td>
</tr>
</table>
</td>
<td align="right">
<img id="banner-image"
SRC="$SERVER/~ajh/images/banner/4472=R761-11.jpg"
height="79" alt="steam loco">
</td>
</tr>
</table>
</div>
<div class="spacer"></div>
<table id="global-nav" summary="Layout for site-wide navigation"><tr>
<td align="left"><span style="font-size:+140%">
M O N A T A R $TestingVersion
</span>
</td><td>
$TITLE
</td>
</tr></table>
<table id="global-utils" summary="Layout for utility navigation">
<tr><td align="left">
<a HREF="$ADT/../index.html" accesskey="4">John Hurst</a> |
<a HREF="$ADT/index.html" accesskey="4">InfoTech AD(T)</a> |
<a HREF="$ADT/quality/index.html">Quality</a> |
<a HREF="$ADT/quality/V2Guidelines.html">Completing an Avatar Entry</a> |
</td>
</tr>
</table>
</div>
<div class="spacer"></div>
<div style="background-color:#99ffcc">
END
# If the person has authenticated, let them know we know who they are.
if (defined $dn) {
@splitdn = split(/,/,$dn);
$name = $splitdn[0];
$name =~ s/.*=//;
}
$needHeaders = 0;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
<subroutines 27> =sub printLDAPError {
if ($needHeaders) {&printHtmlHeaders();}
$lderr = ldap_get_lderrno($ld,$blah1,$blah2);
$errmsg = ldap_err2string($lderr);
print p,"\nError: $errmsg\n",p,hr;
&printBottom;
return;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
<subroutines 28> =sub printError {
my ($type, $info) = @_;
$TITLE="InfoTech Unit Avatar: Sorry!";
if ($needHeaders) {&printHtmlHeaders();}
print h2("$type");
print "<FONT SIZE=\"+1\">$info<BR>";
print "<P>Click this link to return to the Welcome page: ";
print "<A HREF=\"$SCRIPT\">Infotech Unit Avatar</A></P></FONT>";
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
<subroutines 29> =sub printBadAuth {
if ($needHeaders) {&printHtmlHeaders();}
print p,"The login/password you have supplied is incorrect.",p;
print "Return to <a href=\"$SCRIPT\">authentication screen</a>.";
&printBottom;
exit;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
<subroutines 30> =sub grabPersonData {
my $dn = shift;
#print LOG $TimeStamp,'
<version 1> ',"grabPersonData($dn)\n";
$dn =~ /cn *= *([^,]*),/; $Editor = $1;
$Editor =~ /([\w]*) ([\w]*)/;
$EscEditor = $Editor; $EscEditor =~ s/'/"e;/g;
($given,$surname) = ($1,$2);
if ($dn =~ /ou *= *([\w\s]*School[\w\s]*)/) {$School = $1};
if ($dn =~ /ou *= *([\w\s]*Department[\w\s]*)/) {$School = $1};
if ($dn =~ /ou *= *([\w\s]*Faculty[\w\s]*)/) {$Faculty = $1};
if ($dn =~ /ou *= *((Staff|Student)[\w\s]*)/) {$Staff = $1};
#if ($Staff=~/^Student$/) {$School=""; $Faculty="";}
if ($Faculty=~/Information/) {
<grabPersonData: set submission details for InfoTech 31>
} elsif ($Faculty=~/Business/) {
$SUBMISSIONS="$WEBPAGE/units-buseco";
$APPROVALS = "$XMLPAGE/MonAtar-Bus.appr";
$FECEADR="John.Hurst\@infotech.monash.edu.au";
$FECEOFF="John.Hurst\@infotech.monash.edu.au";
} elsif ($Faculty=~/Medicine/) {
$SUBMISSIONS="$WEBPAGE/units-med";
$APPROVALS = "$XMLPAGE/MonAtar-Med.appr";
$FECEADR="John.Hurst\@infotech.monash.edu.au";
$FECEOFF="John.Hurst\@infotech.monash.edu.au";
} else {
<grabPersonData: set submission details for no Faculty 32>
}
print LOG $TimeStamp,'
<version 1> ',
"editor=$Editor,expert=$EditExpert,unitcode=$UnitCode,".
"given=$given,surname=$surname,school=$School,faculty=$Faculty,".
"staff=$Staff,unitsfile=$SUBMISSIONS\n";
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
(Bug 20031009:115255) When extraction the school, department or
faculty information, we must allow for leading words
before the school/department/faculty key word, so that
places like Peninsula School of Network Computing are not
discriminated against.
<grabPersonData: set submission details for InfoTech 31> =$SUBMISSIONS="$WEBPAGE/units";
$APPROVALS = "$XMLPAGE/MonAtar-IT.appr";
$FECEADR="fecvote\@infotech.monash.edu.au";
$FECEOFF="Ralph.Gillon\@infotech.monash.edu.au".
",Geraldine.DCosta\@infotech.monash.edu.au";
<grabPersonData: set submission details for no Faculty 32> =print LOG "No units database for $Faculty\n";
$SUBMISSIONS="$WEBPAGE/units";
$APPROVALS = "$XMLPAGE/MonAtar-IT.appr";
$FECEADR="fecvote\@infotech.monash.edu.au";
$FECEOFF="Ralph.Gillon\@infotech.monash.edu.au";
If the faculty is not one of those directly handled, print log
message and use InfoTech as default.
3.4 getLatestApproved: subroutine to find most
recent approved version
<subroutines 33> =sub getLatestApproved {
my $unitcode = shift;
my $dir="$SUBMISSIONS/archive";
my @units;
opendir(ARCHIVE,$dir);
my @archfiles=grep(!/^\.\.?$/,readdir(ARCHIVE));
foreach $f (@archfiles) {
if ($f =~ /^$UnitCode-[0-9]+-A/) {
unshift(@units,$f);
}
}
closedir ARCHIVE;
@units=sort(@units);
if ($TESTING) {print join(', ',@units);}
$ApprovedVersion="";
if (@units) {$ApprovedVersion=$units[$#ApprovedVersion];}
if ($TESTING) {print "[",$ApprovedVersion,"]";}
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
4. The Unit Selection Page
<subroutines 34> =sub doUnitSelection {
print $auth->start_html(),
$auth->start_form(-method=>"post",
-action=>"$SCRIPT",
-target=>"_blank");
if (($Staff !~ /^Staff|Student$/)) {
print "Sorry, but you are not authorised to use this form, $given";
} else {
<selection page text 35>
}
print $auth->endform,$auth->hr;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
Collect the domain name from the parameter, and analyse it for
school and faculty data. If the person identified is not staff,
then they cannot use the avatar.
<selection page text 35> =my %hints = (
'review'=>"May be completed by staff or students. ".
"(See the <A HREF=\"$SERVER/~ajh/".
"adt/quality/index.html#Using%20the%20Review".
"%20System\">ADT Quality Page</A> for help)",
'compare'=>'Compare two unit descriptions (under development)',
'show'=>"Show summary of unit descriptions matching the above ".
"prefix. <B>This can also be used to compare changes since ".
"the last approval of a unit.</B>",
'showall'=>"Show a list of <B>all</B> unit descriptions ".
"matching the above prefix",
'showapproval'=>"Show the approval work flow of unit ".
"descriptions matching the above prefix",
'view'=>"Generate a read-only view of the unit description"
);
if ($Staff=~/^Staff$/) {
print $auth->p,
textfield(-name=>'UnitCode',-default=>$UnitCode,-size=>10),
" Enter unit code here, please $given",
$auth->hidden('Editor',$Editor);
print $auth->p,
$auth->table({-cellpadding=>0,-cellspacing=>0},
Tr(td({-'colspan'=>"2"},"<B>USER functions</B>"),td()),
Tr(td({-'bgcolor'=>"#99ffcc",-align=>"center"},
$auth->submit(-name=>'review',
-value=>'REVIEW Unit')),
td($hints{'review'}."\n")),
Tr(td({-'bgcolor'=>"#99ffcc",-align=>"center"},
$auth->submit(-name=>'view',
-value=>'VIEW Description')),
td($hints{'view'}."\n")),
Tr(td({-'bgcolor'=>"#99ffcc",-align=>"center"}),
td(textfield(-name=>'DisplayDate',-size=>10),
"Enter date YYYYMMDDHHMMSS (or prefix) to restrict view\n")),
Tr(td({-'bgcolor'=>"#99ffcc",-align=>"center"},
$auth->submit(-name=>'edit',
-value=>'EDIT Existing Description')),
td("Generate an editable view of the current unit description")),
Tr(td({-'bgcolor'=>"#99ffcc"},
$auth->submit(-name=>'create',
-value=>'CREATE New Description')),
td("Create a new unit description")),
Tr(td(),td()),
Tr(td({-'colspan'=>"2"},"<B>MANAGEMENT functions</B>"),td()),
Tr(td({-'bgcolor'=>"#99ffcc",-align=>"center"},
$auth->submit(-name=>'compare',
-value=>'COMPARE Descriptions')),
td($hints{'compare'}."\n")),
Tr(td({-'bgcolor'=>"#99ffcc",-align=>"center"},
$auth->submit(-name=>'show',
-value=>'SHOW Descriptions')),
td($hints{'show'}."\n")),
Tr(td({-'bgcolor'=>"#99ffcc",-align=>"center"},
$auth->submit(-name=>'show',
-value=>'SHOW ALL Descriptions')),
td($hints{'showall'}."\n")),
Tr(td({-'bgcolor'=>"#99ffcc",-align=>"center"},
$auth->submit(-name=>'show',
-value=>'SHOW APPROVAL Profile')),
td($hints{'showapproval'}."\n")),
Tr(td({-'bgcolor'=>"#99ffcc",-align=>"center"},
$auth->submit(-name=>'approve',
-value=>'APPROVE Description')),
td("(Only available for authorised users)"."\n")),
);
} elsif ($Staff=~/^Student$/) {
print "<P>What unit do you wish to view or review, $given? ",
textfield('UnitCode',$UnitCode),
"</P>",
$auth->hidden('Editor',$Editor);
print $auth->p,
$auth->table(
Tr(td("<B>USER functions</B>"),td()),
Tr(td($auth->submit('review','REVIEW Unit')),td($hints{'review'})),
Tr(td($auth->submit('view','VIEW Description')),
td("View the unit description")),
);
}
print $auth->p,
"Note: If you enter a partial unit code (such as BUS), ",
"the SHOW (ALL) DESCRIPTIONS button will limit its search to just ",
"those units starting with that prefix. The prefix can be ",
"as long or as short as you desire. An empty unit code ",
"will show all units.</P>";
print $auth->p,
"<B>NB: If when using the back button you do not see the page ",
"you expect, click reload/refresh to refresh the actual contents</B>";
print $auth->p,
"<B>Version 2.7.0 has a new work-flow for approvals.</B>",
"<BR/>\n",
"<B>Version 2.6.15 adds date-restricted sub-view.</B>",
"<BR/>\n",
"<B>Version 2.6.12 adds change dates to fields.</B>",
"<BR/>\n",
"<B>Version 2.6.5 restructures the submit and approve processes.</B>";
Generate the main content of the Unit Selection Page. The
purpose of this page is to allow the user to choose between a
range of options for the unit description document. These
options are specified by buttons on the page, and cause
reinvocation of the avatar with appropriate parameters.
5. View a Unit Description
5.1 doView: view a unit description
doView is responsible for collecting the nominated
unit description document, and formatting it using
xsltproc under the stylesheet xml2html.xsl, the
standard html view of a unit description for version 2
descriptions. (If a version 1 description is encountered, use
FECSA-html.xsl instead.) Since this page is intended
for printing, it uses a standard text/html header, and does
not call printHtmlHeaders!
Parms: /---------\
see list ---------->| MonAtar |
below \---------/
|
V
getDocument: result in $TMP/$UnitCode.xml
+--------------------+
| $TMP/$UnitCode.xml |
+--------------------+
|
V
+--------------+ /----------\
| xml2html.xsl |---->| xsltproc | (If V1, use FECSA-html.xsl instead)
+--------------+ \----------/
|
V
/ \
/OK?\ no
\ /------> Error, Translation
\ /
| yes
V
display this file
delete TMP files
The following parameters are passed to MonAtar.
- UnitCode
- The unit code
- Editor
- If present, an authenticated user
- EditExpert
- If present, a boolean indicating
the expert status of the user
<subroutines 36> =sub doView {
doLogOperation("doView");
$UnitCode=~tr/a-z/A-Z/;
&getDocument(1,0);
$DisplayDate = $auth->param('DisplayDate');
if ($DisplayDate) {
$DisplayDate .= "00000000000000";
$DisplayDate = substr($DisplayDate,0,14);
}
print header('text/html'); # plain header!
<doView: set xsltproc parameters 37>
$cmd="$XSLTPROC $parms -o $dest $xsl $src 2>$erf";
`$cmd`;
$err = ""; open ERR,"<$erf"; while (<ERR>) {$err.=$_}; close ERR;
if ($err) {
<doView: handle errors 39>
} else {
# use the resultant HTML file as returned page
open NEW,"<$dest";
while (<NEW>) {print;}
close NEW;
}
unlink $src,$dest,$erf;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
Force the unit code to be upper case. Get the document. Set
xslt processing parameters, and process the description to
html. Gather the error output, and if that is non-empty,
display in an error page, otherwise the output of the
translation is used. Discard all temporary files.
<doView: set xsltproc parameters 37> =$src="$TMP/$UnitCode.xml";
<doView: set stylesheet according to version 38>
$dest="$TMP/$UnitCode$destmod.html";
$erf="$TMP/$UnitCode-edit.stderr";
$datetime=$TimeStamp; #`/bin/date "+%d %b %Y %H:%M"`; chop($datetime);
$datetime="$XP DateAndTime \"'$datetime'\"";
if (defined($Editor)) {$editor="$XP Editor \"'$EscEditor'\""}
else {$editor=""};
$unit="$XP UnitCode \"'$UnitCode'\"";
$expert="$XP EditExpert \"\'$EditExpert\'\"";
$parms="$datetime $editor $unit $expert";
if ($DisplayDate) {
$parms .= " $XP DisplayDate \"\'$DisplayDate\'\"";
}
xsltproc requires 2 parameters, the stylesheet $xsl
defining the translations, and the source xml document
$src. In addition, we specify the destination html
document $dest, an error file for stderr $erf, a
date and time parameter $datetime, an editor parameter
$Editor, and a unit code parameter $UnitCode. The
latter three are used within the xsl stylesheet.
<doView: set stylesheet according to version 38> =open XML,"<$src" or print "Cannot open $src!<BR>";
$xsl = "";
while (<XML>) {
if (/<UnitDescription>/) {
$xsl = "$XMLPAGE/FECSA-html.xsl";
last;
} elsif (/UnitDescriptionV2/) {
$xsl = "xml2html.xsl";
last;
}
}
close XML;
if (!$xsl) {
printError("Document Type","unable to determine document type for $UnitCode");
return;
}
This avatar may be called upon to handle version 1 documents.
Read the first few lines of the document to see what version it
is, and set the xsl stylesheet appropriately.
<doView: handle errors 39> =$err=~s/&/&/g; $err=~s/</</g;
print "<P>doView: There was an error in translating the source file \n";
print "<TT>$TMP/$UnitCode.xml</TT>.\n";
print "Here is the output that was generated.\n";
print "If you cannot interpret this, please contact John Hurst.<P>\n";
print "<P><B>Command:</B></P>\n";
print "<PRE>\n";
print "$EditOrView\n";
print "$cmd\n";
print "<PRE>\n";
print "<P><B>Output:</B></P>\n";
print "</PRE>\n";
print "$err\n";
print "</PRE>\n";
print "\n";
Chunk referenced in 36 106
There were errors. Before we display the error file, we munge
out all ampersands into ampersand entities, and all less than
signs into less than entities.
5.2 getDocument: retrieve a unit description file
<subroutines 40> =sub getDocument {
my $readonly = shift;
my $createOK = shift;
$getDoc="<P>Getting Document $UnitCode\n";
my $erf="$TMP/$UnitCode-new.stderr";
if (-f "$SUBMISSIONS/$UnitCode.xml") {
# previous submission available, copy it into $TMP
$source="$SUBMISSIONS/$UnitCode.xml";
$getDoc .= "<P>previous submission available, copy it into $TMP\n";
} elsif ($readonly &&
-f "$SUBMISSIONS/archive/$UnitCode") {
$source="$SUBMISSIONS/archive/$UnitCode";
$getDoc .= "<P>using $UnitCode, copy it into $TMP\n";
$UnitCode =~ s/-[0-9]+-.$//;
} elsif ($createOK) {
my $cmd;
my $src="$XMLPAGE/UnitTemplateV2.xml";
my $xsl="$XMLPAGE/mergexml.xsl";
my $tmp="$TMP/$UnitCode-new1.xml";
my $p1 = "$XP FieldA \"'UnitCode'\"";
my $p2 = "$XP NewText \"'$UnitCode'\"";
my $parms="$p1 $p2";
$getDoc .= "New $UnitCode document, grabbing $src\n";
$cmd="$XSLTPROC $parms -o $tmp $xsl $src 2>$erf";
$getDoc.="New $UnitCode, merging Unit Code ($cmd)\n";
`$cmd`;
$source="$TMP/$UnitCode-new.xml";
$p1 = "$XP FieldA \"'FacultyInformation'\"";
$p2 = "$XP FieldB \"'FIProposer'\"";
my $p3 = "$XP NewText \"'$EscEditor'\"";
$parms="$p1 $p2 $p3";
$cmd="$XSLTPROC $parms -o $source $xsl $tmp 2>>$erf";
$getDoc .= "New $UnitCode, setting Proposer ($cmd)\n";
`$cmd`;
# must do this to make persistent copy
`cp $source "$SUBMISSIONS/$UnitCode.xml"`;
unlink $tmp;
} else {
printError('Missing Document',
"I couldn't find the Unit Description for $UnitCode. ".
"Do you need to CREATE a new one?");
exit;
}
<getDocument: and sanitise it 41>
unlink $erf;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
The getDocument subroutine retrieves the XML unit
description document for the unit $UnitCode. There are
two parameters to the routine:
- readonly
- A boolean which hen true indicates that the document is
to be accessed read only.
- createOK
- A boolean which when true indicates that the document
can be created if it does not already exist.
If the document is to be created, the template
UnitTemplateV2.xml is retrieved, and the new unit
code merged into it using the XSLT transformation
mergexml.xsl.
<getDocument: and sanitise it 41> =$tmp="$TMP/$UnitCode.xml";
$cmd="$XSLTPROC -o $tmp $XMLPAGE/sanitiseV2.xsl $source 2>$erf";
$getDoc .= "Sanitise $UnitCode ($cmd)";
`$cmd`;
if (! -z $erf) {
open ERRS,$erf;
while (<ERRS>) {$getDoc .= $_;}
close ERRS;
}
$getDoc .= "<P>closed $tmp\n";
print DEBUG $getDoc,"\n";
We used to just copy the document here, with the only
alteration being to force the DOCTYPE line. However, a
transformer sanitiseV2.xsl is now used to render the
current document into a canonical form.
6. Edit a Unit Description
There are three stages to editing the unit description, each of
which is handled by a separate invocation of the avatar.
Before anything else, ensure that we have a Version Comment.
Next, doEdit generates a rendered version of the unit
description, marked up with buttons to change the various
editable fields of the document. Each of these buttons forces a
call on the next stage of the avatar, with parameters indicating
the unit, the field, and the user.
The next stage doChange renders the selected field in an
editable text window. The XML of the selected field is extracted
from the master document, and converted to ascii text according
to the markup. This is done so that naive users are not
required to edit XML text directly.
The final stage doUpdate converts the ascii text back
into XML, and replaces the original field of the master document
with this new text.
6.1 doEdit: Generate an Edit Markup of the Unit Description
<subroutines 42> =sub doEdit {
doLogOperation("doEdit");
my $createOK = shift;
my $StartPoint = $auth->param('StartPoint');
my $VersionComment = $auth->param('VersionComment');
$UnitCode=~tr/a-z/A-Z/;
if ($UnitCode=~/^$/) {
printError('No Unit Code',
"You need to enter a unit code in the form ABC1234. ".
"Please return to the Welcome page and try again");
exit;
}
if ($createOK & !$VersionComment) {
$VersionComment="Initial Draft";
}
getDocument(0,$createOK);
<doEdit: parameter debugging 43>
$TITLE="InfoTech Unit Avatar: Edit $UnitCode";
&printHtmlHeaders;
if ($auth->param('edit')=~/Expert/) {$EditExpert=1;}
if ($auth->param('edit')=~/Novice/) {$EditExpert=0;}
my $myself=$auth->self_url;
if ($StartPoint) {
print $auth->p,
"Go To <A HREF=\"$myself#$StartPoint\">$StartPoint</A>\n";
}
if (! -f "$TMP/$UnitCode.xml") {
print "<P>No $TMP/$UnitCode.xml!\n";
print $getDoc;
return;
}
if (!$Editor) {
if ($cookie =~ /cn--([^,]+),/) {
$Editor = $1;
print "<P>Editor = $Editor</P>\n";
$auth->param('Editor',$Editor);
} else {
print "<P><B>DO NOT HAVE AN EDITOR</B>";
print "<P>Cookie = $cookie\n";
return;
}
}
<doEdit: have a Version Comment 45>
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
doEdit is responsible for collecting the nominated
unit description document, and formatting it using
xsltproc under the stylesheet xml2html.xsl, the
standard html view of a unit description. Gather the error
output, and if that is non-empty, we display that in an error
page, otherwise the output of the translation is used.
Now (v2.6.13) that there are auto version comments, the final
macro call has been reduced from a choice (which depended on a
non-null $VersionComment) between the two <doEdit: do NOT have a Version Comment 44> and <doEdit: have a Version Comment 45> macros.
<doEdit: parameter debugging 43> =if ($debug) {
$_=$TimeStamp." doEdit:These are the parameters and values:\n";
foreach $name (@params) {
$_=$_." ".$name.'='.$auth->param($name)."\n";
}
$_=$_." ".$field.'='.$newtext."\n";
$_=$_."\n";
print DEBUG;
}
<doEdit: do NOT have a Version Comment 44> =print $auth->p,
"Please enter a comment to describe the changes being made.",
"This comment will be recorded in the document version history.",
"Click 'edit' when done";
print $auth->start_form(-action=>"$SCRIPT"),
$auth->hidden('UnitCode',$UnitCode),
$auth->hidden('Editor',$Editor,),
$auth->hidden('StartPoint',$StartPoint),
$auth->hidden('EditExpert',$EditExpert),
$auth->textarea(-name=>'VersionComment',
-default=>$VersionComment,
-override=>1,
-rows=>10,
-columns=>80),
$auth->p,
$auth->submit('edit'),
$auth->end_form;
The routine was invoked with no Version Comment parameter.
This is essential for version control, so we first invoke a
simple textarea screen for the user to enter a version
comment. This will be passed around on all subsequent updates
following this doEdit call, but discarded once out of the
edit-change-update cycle. This allows users to edit multiple
fields on the one version comment.
(20031020:152839) omitted. Now that there is an automatic
version history comment added, this is no longer essential.
The user can still edit the field in the final edit pane.
<doEdit: have a Version Comment 45> =print "<P>Note: Clicking on Headings and SubHeadings below will take ",
"you to the corresponding place in the <A HREF=\"",
"$SERVER/~ajh/adt/quality/V2Guidelines.html",
"\">Guidelines Document</A></P>\n";
$VersionComment=~s/'/'/g;
$VersionComment=~s/"/"/g;
<doEdit: change Editor level 46>
print $auth->p,"<B>Reason for Document Update:</B> $VersionComment";
<doEdit: set xsltproc parameters 48>
$cmd="$XSLTPROC $parms -o $dest $xsl $src 2>$erf";
`$cmd`;
$err = ""; open ERR,"<$erf"; while (<ERR>) {$err.=$_}; close ERR;
if ($err) {
<doEdit: handle errors 49>
} else {
print $auth->hr;
print "<div style=\"background-color:#fff\">";
# use the resultant HTML file as returned page
open NEW,"<$dest";
while (<NEW>) {print;}
close NEW;
print $auth->hr,
$auth->p,
"Is the version comment below still accurate after all your changes?",
" If not, correct it below and click 'edit'",
$auth->p,
$auth->start_form(-action=>"$SCRIPT"),
$auth->hidden('UnitCode',$UnitCode),
$auth->hidden('Editor',$Editor),
$auth->hidden('StartPoint',$StartPoint),
$auth->hidden('EditExpert',$EditExpert),
$auth->textarea(-name=>'VersionComment',
-default=>$VersionComment,
-override=>1,
-rows=>10,
-columns=>80),
$auth->p,
$auth->submit('edit'),
$auth->end_form,
$auth->hr,
$auth->p,
$auth->start_form(-action=>"$SCRIPT"),
$auth->hidden('UnitCode',$UnitCode),
$auth->hidden('Editor',$Editor),
$auth->hidden('StartPoint',$StartPoint),
$auth->hidden('EditExpert',$EditExpert),
$auth->hidden('VersionComment',$VersionComment),
$auth->submit('Save'),
"Click this button to save your edits and return ",
"to the Avatar Home Page. ",
$auth->end_form,
$auth->p,
$auth->start_form(-action=>"$SCRIPT"),
$auth->hidden('UnitCode',$UnitCode),
$auth->hidden('Editor',$Editor),
$auth->hidden('StartPoint',$StartPoint),
$auth->hidden('EditExpert',$EditExpert),
$auth->hidden('VersionComment',$VersionComment),
$auth->submit('Submit'),
"Click this button to submit your unit description for ",
"<B STYLE=\"color:red\">SCHOOL</B> ",
"approval and return to the Avatar Home Page. ",
$auth->p,
"<B STYLE=\"color:red\">NOTE THAT DIRECT SUBMISSION TO FEC IS NO LONGER POSSIBLE</B> ",
$auth->end_form;
print "</div>\n";
}
<doEdit: change Editor level 46> =if ($EditExpert) {
print "<P>You are currently an <B>Expert</B> editor, $Editor!</P>\n";
} else {
print "<P>You are currently a <B>Novice</B> editor, $Editor!</P>\n";
}
print $auth->p,
<doEdit: helpful text 47>
print $auth->start_form(-action=>"$SCRIPT"),
$auth->hidden('UnitCode',$UnitCode),
$auth->hidden('Editor',$Editor,),
$auth->hidden('VersionComment',$VersionComment),
$auth->hidden('StartPoint',$StartPoint),
$auth->p,
$auth->submit('edit','Novice'),
$auth->submit('edit','Expert'),
$auth->hidden('EditExpert',$EditExpert),
$auth->end_form;
print $auth->hr;
The first part of this part asks the user to nominate whether
they wish to edit plain text ('Novice' user) or XML ('Expert'
user). The value of $EditExpert is set on entry to the
doEdit subroutine (see above).
<doEdit: helpful text 47> ="<P>When editing your Unit Description, you can choose to ",
"edit plain text (with some markup), or XML.</P><P>Plain ",
"text is more user friendly, but less powerful; while editing ",
"the XML requires strict discipline in tag closing and nesting. ",
"Also please bear in mind that editing plain text may lose some ",
"document formatting. (If you do not understand this message, ",
"you can safely ignore it and proceed straight to the 'edit' box.)</P>",
"<P>Click the Expert button if you want to edit the XML directly</P>";
We have to sanitise the version comment for passing as a
parameter into xsltproc. The call on xsltproc
renders the XML unit description document into HTML, with
clickable buttons to change the various editable fields.
Question: what should be done with the version comment at
this stage?. One option is to insert it into the XML
document as soon as possible, another is to defer it until the
document is saved and/or archived, yet another is to add it as
an editable field (but not yet part of the XML).
<doEdit: set xsltproc parameters 48> =$xsl = "xml2html.xsl";
$src="$TMP/$UnitCode.xml";
$dest="$TMP/$UnitCode$destmod.html";
$erf="$TMP/$UnitCode-edit.stderr";
$datetime=$TimeStamp; #`/bin/date "+%d %b %Y %H:%M"`; chop($datetime);
$datetime="$XP DateAndTime \"'$datetime'\"";
if (defined($Editor)) {$editor="$XP Editor \"'$EscEditor'\""}
else {$editor=""};
$unit="$XP UnitCode \"'$UnitCode'\"";
$expert="$XP EditExpert \"\'$EditExpert\'\"";
$change="$XP ViewOrEdit \"'Edit'\"";
$version="$XP VersionComment \"'$VersionComment'\"";
$server="$XP Server \"'$SCRIPT'\"";
$parms="$datetime $editor $unit $expert $change $version $server";
xsltproc requires 2 parameters, the stylesheet $xsl
defining the translations, and the source xml document
$src. In addition, we specify the destination html
document $dest, an error file for stderr $erf, a
date and time parameter $datetime, an editor parameter
$Editor, and a unit code parameter $UnitCode. The
latter three are used within the xsl stylesheet.
<doEdit: handle errors 49> =$err=~s/&/&/g; $err=~s/</</g;
print "<P>doEdit: There was an error in translating the source file \n";
print "<TT>$TMP/$UnitCode.xml</TT>.\n";
print "Here is the output that was generated.\n";
print "If you cannot interpret this, please contact John Hurst.<P>\n";
print "<P><B>Command:</B></P>\n";
print "<PRE>\n";
print "$EditOrView\n";
print "$cmd\n";
print "<PRE>\n";
print "<P><B>Output:</B></P>\n";
print "</PRE>\n";
print "$err\n";
print "</PRE>\n";
print "\n";
There were errors. Before we display the error file, we munge
out all ampersands into ampersand entities, and all less than
signs into less than entities.
6.2 doChange: Generate an Editable Text of the specified Field
Parms: /---------\
see list ---------->| MonAtar |
below \---------/
|
V
getDocument: result in $TMP/$UnitCode.xml
+--------------------+
| $TMP/$UnitCode.xml |
+--------------------+
|
V
+-------------+ /----------\
| xml2txt.xsl |---->| xsltproc |<---- Param FieldA "fieldA value"
+-------------+ \----------/ Param FieldB "fieldB value"
| Param EditExpert "Novice|Expert"
V
/ \
/OK?\ no
\ /------> Error, Cannot happen!
\ /
| yes
V
+---------------------------+ text if EditExpert = Novice
| $TMP/$UnitCode$suffix.txt |
+---------------------------+ xml if EditExpert = Expert
use this file to build default value in form
delete TMP files
The following parameters are passed to MonAtar.
- change
- a value passed in from the doEdit generated form, with
the structure Change FieldA/FieldB, where FieldA and
FieldB are hierarchical field tags from the Unit Description
document. These are used to extract the original value from
the document for setting the default editing value.
- UnitCode
- The unit code
- Editor
- an authenticated user
- EditExpert
- a boolean indicating the expert status of the
user
<subroutines 50> =sub doChange {
doLogOperation("doChange");
$change = $auth->param('change');
$VersionComment = $auth->param('VersionComment');
$UnitCode=~tr/a-z/A-Z/;
$change=~s#^Change ([^/]*)(/(.*))?$#\1\2#;
$FieldA=$1; $FieldB=$3;
$suffix=$FieldA.$FieldB;
getDocument(0,0);
$TITLE="Infotech Avatar: Updating $UnitCode";
&printHtmlHeaders;
if ($EditExpert) {
print "<P>You are currently an <B>Expert</B> editor!</P>\n";
} else {
print "<P>You are currently a <B>Novice</B> editor!</P>\n";
}
if ($debug) {
$_=$auth->p."doChange($UnitCode,$Editor,$FieldA,$FieldB)=>$change\n";
$_=$_.$auth->p."These are the parameters and values:\n";
$_=$_."<P STYLE=\"margin-left:20pt\">";
foreach $name (@params) {
$_=$_.$name.'='.$auth->param($name).'<BR>';
}
$_=$_.'</P>';
print DEBUG $_;
}
print $auth->h2("Editing $UnitCode $change field ..."),
$auth->p,
"Edit the following text, then click this 'Update' ",
"button.";
<doChange: print helpful hints 51>
my $xsl = "$XMLPAGE/xml2txt.xsl";
if ($EditExpert) {$xsl = "$XMLPAGE/xmlextract.xsl"};
my $src = "$TMP/$UnitCode.xml";
my $dst = "$TMP/$UnitCode$suffix.txt";
my $prm = "$XP FieldA \"\'$FieldA\'\" $XP FieldB \"\'$FieldB\'\"";
$prm .= " $XP EditExpert \"\'$EditExpert\'\"";
my $ers = "$TMP/$UnitCode-change.ers";
my $cmd = "$XSLTPROC $prm $xsl $src >$dst 2>$ers";
my $res = `$cmd`;
if ($debug) {
print DEBUG "doChange: $cmd\n";
}
my $val = "";
open XML,$dst;
while (<XML>) {$val=$val.$_;}
close XML;
unlink $dst;
print $auth->start_form(-action=>"$SCRIPT"),
$auth->submit('update',"Update the $change");
<doChange: warn about editing ObjText 52>
print $auth->p,
$auth->textarea(-name=>$change,
-default=>$val,
-override=>1,
-rows=>50,
-columns=>80),
$auth->p,
$auth->hidden(-name=>'UnitCode',-default=>$UnitCode),
$auth->hidden(-name=>'Editor',-default=>$Editor),
$auth->hidden('EditExpert',$EditExpert),
$auth->hidden(-name=>'VersionComment',-default=>$VersionComment),
$auth->hidden(-name=>'FieldA',-default=>$FieldA),
$auth->hidden(-name=>'FieldB',-default=>$FieldB),
$auth->hidden(-name=>'value',-default=>$val),
$auth->end_form;
unlink $ers;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
<doChange: print helpful hints 51> =if (!$EditExpert) {
print "Some helpful hints:";
print $auth->p,
"<P>Text in this window should be formatted to reflect its logical ",
"structure, and is used to build the document structure of the ",
"XML fragment.</P>",
"<UL><LI>Blank lines represent paragraph breaks. ",
"<B>DON'T put blank lines between items in an (un)numbered list, ",
"otherwise each item will be a separate list!</B></LI>",
"<LI>(Carriage) returns or enters are ignored if the next line ",
"has the same indentation as the previous line.</LI>",
"<LI>Itemized text should be consistently indented, and flagged ",
"with a leading '+', '-' or 'o' character, followed by at least ",
"one blank.</LI>",
"<LI>Numbered text should be consistently indented, and flagged ",
"with one or more leading digits, followed by a full stop and at ",
"least one blank.</LI>",
"<LI>Nested itemized or numbered paragraphs can be shown by ",
"increasing the indentation.</LI>",
"<LI>{\\b bold}, {\\i italic}, and {\\ul underline} can be used to ",
"markup highlighted text</LI></UL>\n";
}
<doChange: warn about editing ObjText 52> = if ($change=~m^UnitObjectives/ObjText^) {
print $auth->p,'<span style="color:red"><b><blink>'.
'IF YOU CONTINUE TO EDIT THIS FIELD, IT WILL BE DELETED.'.
'</blink> USE YOUR BACK BUTTON NOW TO CANCEL!</b></span>';
}
6.3 doUpdate: Incorporate changes into the Unit Description
<subroutines 53> =sub doUpdate {
doLogOperation("doUpdate");
my $FieldA = $auth->param('FieldA');
my $FieldB = $auth->param('FieldB');
my $VersionComment = $auth->param('VersionComment');
my $field = $FieldA;
if ($FieldB) {$field="$FieldA/$FieldB";}
my $suffix = $FieldA.$FieldB;
my $newtext = $auth->param($field);
$UnitCode=~tr/a-z/A-Z/;
getDocument(0,0);
<doUpdate: parameter debugging 54>
$newtext =~ s/\r/ /g;
if ($auth->param('update')=~/Change Classification/) {
$FieldA = "Classification"; $field=$FieldA;
$Attribute = "BOK";
$newtext = $auth->param("BOK");
$newtext =~ s/.*\((.*)\)/\1/;
} elsif ($auth->param('update')=~m^Update the UnitObjectives/ObjText^) {
$newtext="";
} else {
if (!$EditExpert) {
<doUpdate: convert plain text to XML 55>
}
<doUpdate: sanitise newtext 56>
}
<doUpdate: call the xslt processor 57>
if (-s $ers && $debug) {print DEBUG "doUpdate: failed on merge\n";}
if (-z $ers) {
<doUpdate: check revised document 59>
if (-s $ers && $debug) {print DEBUG "doUpdate: failed on check\n";}
}
if (-s $ers) {
<doUpdate: error reporting 58>
} else {
rename "$TMP/$UnitCode-new.xml","$SUBMISSIONS/$UnitCode.xml";
if ($VersionComment) {$VersionComment.="; ";}
$VersionComment.="modified $field";
$auth->param(-name=>'StartPoint',-values=>[$field]);
$auth->param(-name=>'VersionComment',-values=>[$VersionComment]);
&doEdit(0);
}
unlink $ers;
return;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
doUpdate is called when the user has edited a field of
the description, and clicks the "Update the ...."
button. The avatar is invoked with the following set of
parameters:
- UnitCode
- The unit code
- Editor
- The editor of the document
- field
- The element name of the field being edited.
- tag
- (This parameter varies with the tag of the
field being edited.) The new value of the field.
- value
- The original value of the field (not used)
We grab the new text to replace the field. This is the raw
ascii text, as edited by the user. Write this text into a
file, for conversion by the ascii to xml translator,
a2x. Call the translator, and read the translated text
(now in XML markup) back into $newtext.
<doUpdate: parameter debugging 54> =if ($debug) {
$_=$TimeStamp." doUpdate:These are the parameters and values:\n";
foreach $name (@params) {
$_=$_." ".$name.'='.$auth->param($name)."\n";
}
$_=$_." ".$field.'='.$newtext."\n";
$_=$_."\n";
print DEBUG;
print DEBUG "doUpdate($UnitCode,$Editor,$field,$newtext)=>$suffix\n";
print DEBUG "Opening $TMP/$UnitCode$suffix.txt\n";
}
<doUpdate: convert plain text to XML 55> =my $txt = "$TMP/$UnitCode$suffix.txt";
open FIELD,">$txt";
print FIELD $newtext;
close FIELD;
$newtext="";
$cmd="$XMLPAGE/a2x.pl $txt";
if ($debug) {
print DEBUG "doUpdate: $cmd\n";
}
`$cmd`;
unlink $txt;
my $xml = "$TMP/$UnitCode$suffix.xml";
open FIELD,$xml;
while (<FIELD>) {s#<p></p>##; $newtext=$newtext.$_;}
close FIELD;
unlink $xml;
#print "<P>Finished translation to XML\n";
<doUpdate: sanitise newtext 56> =$newtext=~s/\n/ /g;
$newtext=~s/ +/ /g;
$newtext=~s/"/"/g;
$newtext=~s/'/'/g;
$newtext=~tr/[\x80-\xff]/?/;
if ($debug) {
print DEBUG $newtext;
print DEBUG "<P>End of translated text\n";
}
sanitise the new text to be inserted by
- removing all new lines and replacing them with spaces
- replacing multiple spaces with a single space
- changing double quotes (which foul up the parameter
passing at the command line level) to XML entities
- ditto for single quotes
- ensuring that all characters are 7-bit ASCII
For debugging purposes, print the new sanitised text.
<doUpdate: call the xslt processor 57> =$proc="$XSLTPROC";
$xsl="$XMLPAGE/mergexml.xsl";
$src="$TMP/$UnitCode.xml";
$dst="$TMP/$UnitCode-new.xml";
$ers="$TMP/$UnitCode-new.ers";
$prms="$XP FieldA \"\'$FieldA\'\" $XP FieldB \"\'$FieldB\'\"";
$prms.=" $XP NewText \"\'$newtext\'\" $XP Attribute \"\'$Attribute\'\"";
$prms.=" $XP DateTime \"\'$timestamp\'\"";
$cmd="$proc $prms -o $dst $xsl $src 2>$ers";
if ($debug) {print DEBUG "$cmd\n"};
`$cmd`;
We add the edited field into the unit description with the
aid of the mergexml.xsl XSLT transform.
This script takes an existing XML unit description and merges
the NexText parameter into the field
FieldA/FieldB. This is a two level addressing
operation, since many fields of the unit description are
subfields of top-level fields. See the mergexml.xsl documentation
for further details of this transformation.
<doUpdate: error reporting 58> =$TITLE="Infotech Avatar: Error in Updating $UnitCode";
&printHtmlHeaders;
print "<P>doUpdate: There was an error in adding your edits to \n";
print "<TT>$TMP/$UnitCode.xml</TT>.\n";
print "Here is the output that was generated.\n";
print "If you cannot interpret this, please contact John Hurst.<P>\n";
print "<P><B>Command:</B></P>\n";
print "<PRE>\n";
print "$cmd\n";
print "<PRE>\n";
print "<P><B>Output:</B></P>\n";
print "</PRE>\n";
$err=""; open ERR,"<$ers";while(<ERR>){$err.=$_;} close ERR;
$err=~s/&/&/g; $err=~s/</</g;
print "$err\n";
print "</PRE>\n";
print "\n";
<doUpdate: check revised document 59> =$proc="$XSLTPROC";
$xsl="xml2html.xsl";
$src="$TMP/$UnitCode-new.xml";
$dst="$TMP/$UnitCode-new.html";
$ers="$TMP/$UnitCode-new.ers";
$prms="$XP UnitCode \"\'$UnitCode\'\" ";
$cmd="$proc $prms -o $dst $xsl $src 2>$ers";
print DEBUG "doUpdate: check revised document ($cmd)\n";
`$cmd`;
We have a new document, UnitCode-new.xml, which we should check for well-formedness before proceding further. Do this by running it through the view stylesheet.
6.4 doSave: Incorporate changes into the Unit Description
<subroutines 60> =sub doSave {
doLogOperation("doSave");
my $VersionComment = $auth->param('VersionComment');
my @Classification = $auth->param('BOK');
$UnitCode=~tr/a-z/A-Z/;
getDocument(0,0);
$TITLE="Infotech Unit Avatar: Save Document";
&printHtmlHeaders;
$src="$TMP/$UnitCode.xml";
print $auth->p,"<P>Timestamp=$timestamp</P>\n";
$k="V";
$FullUnitCode="$UnitCode-$timestamp-$k";
$dest="$SUBMISSIONS/archive/$FullUnitCode";
<doUpdate: parameter debugging 54>
$proc="$XSLTPROC";
$xsl="$XMLPAGE/MonAtar-version.xsl";
$src="$TMP/$UnitCode.xml";
$dst="$TMP/$UnitCode-new.xml";
$ers="$TMP/$UnitCode-new.ers";
$prms="$XP Date \"\'$timestamp\'\" ".
"$XP Editor \"\'$EscEditor\'\" ".
"$XP VersionComment \"\'$VersionComment\'\"";
$cmd="$proc $prms -o $dst $xsl $src 2>$ers";
#print "<P>$cmd\n";
`$cmd`;
$err=""; open ERR,"<$ers";while(<ERR>){$err.=$_;} close ERR;
if ($err) {
<doUpdate: error reporting 58>
} else {
`cp "$TMP/$UnitCode-new.xml" "$dest"`;
rename "$TMP/$UnitCode-new.xml","$SUBMISSIONS/$UnitCode.xml";
print $auth->p,"Save successful! Click to reenter avatar, ".
"or view edited description";
print $auth->start_form(-action=>"$SCRIPT"),
$auth->submit('reenter',"Reenter Avatar"),
$auth->submit('view',"View Updated Unit"),
$auth->hidden('UnitCode',$UnitCode),
$auth->end_form;
}
unlink $ers;
return;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
doSave is called when the user clicks the final "Save"
button on the doEdit page.
The avatar is invoked with the following set of
parameters:
- UnitCode
- The unit code
- Editor
- The editor of the document
- VersionComment
- The comment to insert in the version history, along
with Editor, Date and Time information.
6.5 doSubmit: Incorporate changes into the Unit Description
<subroutines 61> =sub doSubmit {
doLogOperation("doSubmit");
my $VersionComment = $auth->param('VersionComment');
$UnitCode=~tr/a-z/A-Z/;
getDocument(0,0);
$TITLE="Infotech Unit Avatar: Submit Document";
&printHtmlHeaders;
$src="$TMP/$UnitCode.xml";
print $auth->p,"<P>Timestamp=$timestamp</P>\n";
$k="M";
$FullUnitCode="$UnitCode-$timestamp-$k";
$dest="$SUBMISSIONS/archive/$FullUnitCode";
<doUpdate: parameter debugging 54>
$proc="$XSLTPROC";
$xsl="$XMLPAGE/MonAtar-version.xsl";
$src="$TMP/$UnitCode.xml";
$dst="$TMP/$UnitCode-new.xml";
$ers="$TMP/$UnitCode-new.ers";
$prms="$XP Date \"\'$timestamp\'\" ".
"$XP Editor \"\'$EscEditor\'\" ".
"$XP VersionComment \"\'$VersionComment\'\"";
$cmd="$proc $prms -o $dst $xsl $src 2>$ers";
#print "<P STYLE=\"margin-left:20pt\">$cmd</P>\n";
`$cmd`;
<doSubmit: get document values 62>
$err=""; open ERR,"<$ers";while(<ERR>){$err.=$_;} close ERR;
if ($err) {
<doUpdate: error reporting 58>
} else {
`cp "$TMP/$UnitCode-new.xml" "$dest"`;
rename "$TMP/$UnitCode-new.xml","$SUBMISSIONS/$UnitCode.xml";
<doSubmit: send mail to SEC members 63>
print $auth->p,"<B>Submit successful!</B>";
print $auth->p,
"Click to reenter avatar, ",
"or simply delete this window and reuse original window.";
print $auth->start_form(-action=>"$SCRIPT"),
$auth->submit('reenter',"Avatar"),
$auth->hidden('UnitCode',$UnitCode),
$auth->end_form;
}
return;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
doSubmit is called when the user clicks the final
"Submit" button on the doEdit page.
The avatar is invoked with the following set of
parameters:
- UnitCode
- The unit code
- Editor
- The editor of the document
- VersionComment
- The comment to insert in the version history, along
with Editor, Date and Time information.
The document is also archived with the extension "M" (for
unit subMission to the school level).
<doSubmit: get document values 62> =open DOCVALS,"<$TMP/$UnitCode.msgs";
while (<DOCVALS>) {$docvals.=$_};
close DOCVALS;
$docvals=~s/UnitName = (.*)\$\n//s; $UnitName = $1;
$docvals=~s/UnitSummary = (.*)\$\n//s; $UnitSummary = $1;
<doSubmit: send mail to SEC members 63> =my $mode = "submitted";
getLatestApproved($UnitCode);
$mailmsg="A unit description (for a new or existing unit)\n";
$mailmsg.=" $UnitCode $UnitName\n";
$mailmsg.="has been $mode at URL:\n\n";
$mailmsg.=" $SCRIPT?UnitCode=$FullUnitCode\n\n";
if ($ApprovedVersion) {
$mailmsg.="You can compare this with the latest (Faculty) approved";
$mailmsg.=" version by clicking\n\n";
$mailmsg.=" $SCRIPT?".
"compare=compare&BaseCode=$ApprovedVersion".
"&UnitCode=$FullUnitCode\n\n";
}
if ($mode=~/saved/) {
$mailmsg.="WARNING: This revision has not been notified to SEC\n";
$mailmsg.="******** You must explicitly SUBMIT the description ";
$mailmsg.="for that to happen!\n\n";
}
$mailmsg.="Author of Revisions: $Editor\n";
$mailmsg.="Unit Synopsis: $UnitSummary\n";
if ($UnitCode) {
$esub="[MonAtar] $UnitCode $UnitName ($mode) ";
<doSubmit: get submission data 64>
# send each of the school SEC members an email
foreach $eadr (@adrs) {
$recipients.=$eadr."\n";
&sendmail($eadr,$esub,$mailmsg);
}
# Send the ADT a copy
$eadr="John.Hurst\@infotech.monash.edu.au";
$recipients.=$eadr."\n";
&sendmail($eadr,$esub,$mailmsg);
# sanitise the ProposerEmail field(s)
$ProposerEMail=~tr/\r\n /,,,/;
$ProposerEMail =~s/,,+/,/g;
@emails = split(',',$ProposerEMail); # chop at commas
foreach $email (@emails) {
$email =~ s/[\s;]//g;
if ($email =~ /^[\w\.-@<>"]+$/) {
$recipients.=$email."\n";
&sendmail($email,$esub,$mailmsg);
} else {
print "<P>$email not emailed as it contains illegal characters</P>\n";
}
}
# sanitise the ContactEmail field(s)
$ContactEMail=~tr/\r\n /,,,/;
$ContactEMail =~s/,,+/,/g;
@emails = split(',',$ContactEMail); # chop at commas
foreach $email (@emails) {
$email =~ s/[\s;]//g;
if ($email =~ /^[\w\.-@<>"]+$/) {
$recipients.=$email."\n";
&sendmail($email,$esub,$mailmsg);
} else {
print "<P>$email not emailed as it contains illegal characters</P>\n";
}
}
print "<P>The following email addresses have been notified of your submission</P>\n";
print "<PRE STYLE=\"margin-left:20pt\">$recipients</PRE>\n";
print "with the following message:\n";
print "<PRE STYLE=\"margin-left:20pt\">$mailmsg</PRE>\n";
if ($debug) {
print DEBUG "Submit: emailed the following recipients:\n$recipients\n";
}
}
<doSubmit: get submission data 64> =my ($fac,$sch);
print DEBUG "doSubmit: Faculty=$Faculty, School=$School\n";
if ($Faculty=~/Information Technology/) {
$fac="IT";
if ($School=~/Gippsland/) {$sch="gscit"}
elsif ($School=~/Business Systems/) {$sch="sbs"}
elsif ($School=~/Computer Science/) {$sch="csse"}
elsif ($School=~/Network/) {$sch="snc"}
elsif ($School=~/Information Management/) {$sch="sims"}
elsif ($School=~/Multimedia/) {$sch="sms"}
elsif ($School=~/Business and Information Technology/) {$sch="mum"}
elsif ($School=~/South Africa/) {$sch="sa"}
else {
printError("No School","No school code $School to receive submission");
}
} elsif ($Faculty=~/Medicine/) {
printError("No Faculty","$Faculty not currently receiving submissions");
} elsif ($Faculty=~/Business/) {
printError("No Faculty","$Faculty not currently receiving submissions");
} else {
printError("No Faculty","$Faculty not currently receiving submissions");
}
my $submitdataname = "MonAtar-$fac-$sch.adr";
open ADRS,$submitdataname or
printError("No Addresses","I couldn't find the addresses $submitdataname to email");
my @adrs;
while (<ADRS>) {
chop;
push(@adrs,$_);
}
close ADRS;
# Here a kludge to check if editor's school is the same
# as the proposing school for the unit. If not, send to both.
my ($propsch) = $UnitCode;
$propsch =~ s/[0-9]+.*$//;
if ($propsch=~/GCO/) {$propsch="gscit"}
elsif ($propsch=~/BUS/) {$propsch="sbs"}
elsif ($propsch=~/CSE/) {$propsch="csse"}
elsif ($propsch=~/CPE/) {$propsch="snc"}
elsif ($propsch=~/IMS/) {$propsch="sims"}
elsif ($propsch=~/MIS/) {$propsch="sims"}
elsif ($propsch=~/MMS/) {$propsch="sms"};
if ($propsch ne $sch) {
# schools differ, do the proposing school as well
my $submitdataname = "MonAtar-$fac-$propsch.adr";
open ADRS,$submitdataname or
printError("No Addresses","I couldn't find the ".
"addresses $submitdataname to email");
while (<ADRS>) {
chop;
push(@adrs,$_);
}
close ADRS;
}
<subroutines 65> =use Socket;
sub sendmail {
my ($adr) = shift;
#my ($repl) = shift;
my ($sub) = shift;
my ($msg) = shift;
my ($remote,$port, $iaddr, $paddr, $proto, $line);
open MSG,">$TMP/msg-Avatar";
print MSG "To: $adr\n";
print MSG "From: MonAtar\@csse.monash.edu.au\n";
my $repl = "$Editor\@infotech.monash.edu.au";
$repl =~ s/ /\./g;
print MSG "Reply-to: $repl\n";
print MSG "Subject: $sub\n\n";
print MSG $msg;
close MSG;
$cmd="/usr/lib/sendmail -t <$TMP/msg-Avatar";
`$cmd`;
return;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
20030228:170657 removed the -ba flag from the sendmail
line. This now seems to stop transmission (reason why is
obscure).
7. Compare Unit Decriptions
<subroutines 66> =sub doCompare {
doLogOperation("doCompare");
my $BaseCode = $auth->param('BaseCode');
<doCompare: set xsltproc parameters 67>
$cmd="$XSLTPROC $parms -o $dest $xsl $src 2>$erf";
`$cmd`;
$err = ""; open ERR,"<$erf"; while (<ERR>) {$err.=$_}; close ERR;
print $auth->header();
print $auth->start_html(-title=>"Compare Unit Descriptions",
-BGCOLOR=>"#ddffdd");
if ($err) {
<doCompare: handle errors 68>
} else {
# use the resultant HTML file as returned page
open NEW,"<$dest";
while (<NEW>) {print;}
close NEW;
}
#unlink $src,$dest,$erf;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
<doCompare: set xsltproc parameters 67> =my $fileA="$SUBMISSIONS/archive/$BaseCode";
my $fileB="$SUBMISSIONS/archive/$UnitCode";
my $dest="$TMP/$UnitCode-compare.html";
my $src="$XMLPAGE/dummy.xml";
my $erf="$TMP/$UnitCode.stderr";
my $parms="$XP UnitA \"'$fileA'\"";
$parms.=" $XP UnitB \"'$fileB'\"";
$xsl = "$XMLPAGE/compare.xsl";
<doCompare: handle errors 68> =$err=~s/&/&/g; $err=~s/</</g;
print "<P>doCompare: There was an error in comparing the files \n";
print "<TT>$fileA</TT>.\n";
print "Here is the output that was generated.\n";
print "If you cannot interpret this, please contact John Hurst.<P>\n";
print "<P><B>Command:</B></P>\n";
print "<PRE>\n";
print "$EditOrView\n";
print "$cmd\n";
print "<PRE>\n";
print "<P><B>Output:</B></P>\n";
print "</PRE>\n";
print "$err\n";
print "</PRE>\n";
print "\n";
There were errors. Before we display the error file, we munge
out all ampersands into ampersand entities, and all less than
signs into less than entities.
8. Show Unit Descriptions
<subroutines 69> =sub doShow {
doLogOperation("doShow");
my $ShowAll = $auth->param('show');
$UnitCode =~ s/( |\n|\r)*//g;
$UnitCode=~tr/a-z/A-Z/;
my (%units);
my (%SaveLateTime,%SaveLateLink);
my (%SubmitLateTime,%SubmitLateLink);
my (%OKLateTime,%OKLateLink);
my (%EndorseLateTime,%EndorseLateLink);
my (%ApproveLateTime,%ApproveLateLink);
my $Since = $auth->param('Since') || '20000101';
my $Until = $auth->param('Until') || '20041231';
$yearrequired='t';
$Since=~/([\d]{4})/; my $syr = $1;
$Until=~/([\d]{4})/; my $uyr = $1;
if ($syr eq $uyr) {$yearrequired=''};
print $auth->header();
print $auth->start_html(-title=>"Summary of All Descriptions",
-BGCOLOR=>"#ddffdd");
<doShow: generate form components 70>
getLatestApproved($UnitCode);
my $dir="$SUBMISSIONS/archive";
if ($TESTING) {print "directory=$dir<P>\n";}
opendir(ARCHIVE,$dir);
@archfiles=grep(!/^\.\.?$/,readdir(ARCHIVE));
closedir ARCHIVE;
@archfiles=sort(@archfiles);
$Until.="240001"; # make last date inclusive, i.e., up till midnight.
<doShow: compute time ranges 71>
<doShow: generate table of units 72>
<doShow: version differences 73>
print $auth->end_html();
exit 0;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
doShow is responsible for collecting the nominated unit
description document, and formatting it using xsltproc
under the stylesheet xml2html.xsl, the standard html
view of a unit description. Gather the error output, and if
that is non-empty, we display that in an error page, otherwise
the output of the translation is used. This output used to be
saved, but there seems little point now.
<doShow: generate form components 70> =print $auth->startform("post","$SCRIPT");
print $auth->h1('Unit Description Summary: '.$ShowAll),
$auth->p,"<P><B>For </B>",
$auth->textfield('UnitCode',$UnitCode,8),
"(Entering a (part) unit code in this field will ",
"limit the search to units matching this prefix)",
$auth->p,"<P><B>Since ",
$auth->textfield('Since',$Since,10)," and Until </B>",
$auth->textfield('Until',$Until,10),
$auth->submit('show',$auth->param('show')),
" (Dates are inclusive)";
print $auth->endform();
<doShow: compute time ranges 71> =foreach $f (@archfiles) {
if ($f =~ /^$UnitCode/) {
if ($f=~/([A-Za-z]+[0-9]+[A-Za-z]?)-([0-9]+)(-[VMSEA])?/) {
my ($s,$t,$m) = ($1,$2,$3);
if ($t gt $Since && $t le $Until) {
$units{$s}++;
if (!$m || $m=~/V/) {
if (!$SaveLateTime{$s}) {
$SaveLateTime{$s} = $t; $SaveLateLink{$s}=$f;
} elsif ($t gt $SaveLateTime{$s}) {
$SaveLateTime{$s} = $t; $SaveLateLink{$s}=$f;
}
} elsif ($m=~/M/) {
if (!$SubmitLateTime{$s}) {
$SubmitLateTime{$s} = $t; $SubmitLateLink{$s}=$f;
} elsif ($t gt $SubmitLateTime{$s}) {
$SubmitLateTime{$s} = $t; $SubmitLateLink{$s}=$f;
}
} elsif ($m=~/S/) {
if (!$OKLateTime{$s}) {
$OKLateTime{$s} = $t; $OKLateLink{$s}=$f;
} elsif ($t gt $OKLateTime{$s}) {
$OKLateTime{$s} = $t; $OKLateLink{$s}=$f;
}
} elsif ($m=~/E/) {
if (!$EndorseLateTime{$s}) {
$EndorseLateTime{$s} = $t; $EndorseLateLink{$s}=$f;
} elsif ($t gt $EndorseLateTime{$s}) {
$EndorseLateTime{$s} = $t; $EndorseLateLink{$s}=$f;
}
} elsif ($m=~/A/) {
if (!$ApproveLateTime{$s}) {
$ApproveLateTime{$s} = $t; $ApproveLateLink{$s}=$f;
} elsif ($t gt $ApproveLateTime{$s}) {
$ApproveLateTime{$s} = $t; $ApproveLateLink{$s}=$f;
}
}
}
}
}
}
<doShow: generate table of units 72> =if ($ShowAll=~/SHOW Descriptions/) {
print "<P><B>Clicking on any link will generate a comparison ".
"for that unit description against the latest (Faculty) ".
"approved version of the unit.</B></P>\n";
print "<P>If there is no previously approved version, only ".
"the unit code-time stamp is shown (no links).</P>\n";
print "<P>Links are arranged most recent first. The current ".
"approved version is highlighted in green. ".
"The suffixes for each link indicate the level of ".
"approval:<BR>".
" V - saved only<BR>".
" M - submitted to SEC<BR>".
" S - OKed by School<BR>".
" E - Endorsed by FEC<BR>".
" A - Approved by Faculty Board</P>\n";
print "<TABLE BGCOLOR=\"white\" BORDER=\"1\">\n";
print "<TR><TH>Unit</TH><TH>Times</TH><TH>".
"Approved</TH>";
foreach $s (sort(keys(%units))) {
print "<TR><TD>$s</TD>","<TD ALIGN=\"center\">",
$units{$s},"</TD>";
print "<TD>",$ApproveLateTime{$s},"</TD>";
my $line="";
my (@links);
foreach $f (@archfiles) {
if ($f =~ /^$s-/) {
if ($f=~/([A-Za-z]+[0-9]+[A-Za-z]?)-([0-9]+)(-[VCM])?/) {
my ($s,$t,$m) = ($1,$2,$3);
if ($t gt $Since && $t le $Until) {
push(@links,$f);
}
}
}
}
@links = sort(@links);
foreach $f (@links) {
my $bg = "";
if ($ApprovedVersion=~/$f/) {$bg=" BGCOLOR=\"lightgreen\"";}
my $linkage="<A HREF=\"$SCRIPT?".
"compare=compare&BaseCode=$ApprovedVersion&".
"UnitCode=".$f."\"><TT>".
$f."</TT></A>";
if (!$ApprovedVersion) {
$linkage="$f";
}
$line="<TD$bg>$linkage</TD>".$line;
}
print $line;
print "</TR>\n";
}
print "\n</TABLE>\n";
} elsif ($ShowAll=~/SHOW ALL Descriptions/) {
print "<TABLE BGCOLOR=\"white\" BORDER=\"1\">\n";
print "<TR><TH>Unit</TH><TH>Times</TH>";
foreach $s (sort(keys(%units))) {
print "<TR><TD>$s</TD>",
"<TD ALIGN=\"center\">",$units{$s};
my $line="";
my (@links);
foreach $f (@archfiles) {
if ($f =~ /^$s/) {
if ($f=~/([A-Za-z]+[0-9]+[A-Za-z]?)-([0-9]+)(-.)?/) {
my ($s,$t,$m) = ($1,$2,$3);
if ($t gt $Since && $t le $Until) {
push(@links,$f);
}
}
}
}
@links = sort(@links);
foreach $f (@links) {
$f=~/([A-Za-z]+[0-9]+[A-Za-z]?)-([0-9]+)(-.)?/;
my ($t) = ($2);
$line="<TD>".dispDate($t,$f,' ')."</TD>".$line;
}
print $line;
print "</TR>";
}
print "\n</TABLE>\n";
} elsif ($ShowAll=~/SHOW APPROVAL Profile/) {
<doShow: print Approval page explanation 75>
print "<TABLE BGCOLOR=\"white\" BORDER=\"1\">\n";
print "<TR><TH>Unit</TH><TH>Times</TH>";
print "<TH>Latest Save</TH><TH>Latest Submit</TH>";
print "<TH>School OK given</TH><TH>FEC Endorsed</TH>\n";
print "<TH>FacBoard Approved</TH></TR>\n";
foreach $s (sort(keys(%units))) {
print "<TR><TD>$s</TD>",
"<TD ALIGN=\"center\">",$units{$s};
my $col = 'lightgreen';
if ($SubmitLateTime{$s} < $SaveLateTime{$s}) {
$col = 'yellow';}
print "</TD><TD ALIGN=\"center\" BGCOLOR=\"".$col."\">",
dispDate($SaveLateTime{$s},$SaveLateLink{$s},'Not Saved');
$col='lightgreen';
if (!$SubmitLateTime{$s}) {$col = 'pink';}
print "</TD><TD ALIGN=\"center\" BGCOLOR=\"".$col."\">",
dispDate($SubmitLateTime{$s},$SubmitLateLink{$s},'Not Submitted');
if ($col=~/lightgreen/ &&
$OKLateTime{$s} < $SubmitLateTime{$s}) {
$col = 'pink';}
print "</TD><TD ALIGN=\"center\" BGCOLOR=\"".$col."\">",
dispDate($OKLateTime{$s},$OKLateLink{$s},'Not OK');
if ($col=~/lightgreen/ &&
$EndorseLateTime{$s} < $OKLateTime{$s}) {
$col = 'pink';}
print "</TD><TD ALIGN=\"center\" BGCOLOR=\"".$col."\">",
dispDate($EndorseLateTime{$s},$EndorseLateLink{$s},'Not Endorsed');
if ($col=~/lightgreen/ &&
$ApproveLateTime{$s} < $EndorseLateTime{$s}) {
$col = 'pink';}
print "</TD><TD ALIGN=\"center\" BGCOLOR=\"".$col."\">",
dispDate($ApproveLateTime{$s},$ApproveLateLink{$s},'Not Approved'),
"</TD></TR>\n";
}
print "\n</TABLE>\n";
}
<doShow: version differences 73> =if ($ShowAll=~/SHOW Descriptions/) {
if (scalar(keys(%units)) eq 1) {
my @sc = keys(%units); my $sc = $sc[0];
print $auth->h2(
"List of Saves and Differences for $sc over this Period");
my $last="$XMLPAGE/UnitTemplate.xml";
foreach $f (@archfiles) {
if ($f=~/^$UnitCode/) {
if ($f=~/([A-Z]+[0-9]+)-([0-9]+)(-[VCM])?/) {
my ($s,$t,$m) = ($1,$2,$3);
if ($t gt $Since && $t le $Until) {
print dispDate($t,$f,"Error"),"<PRE>\n";
$diffs=`/usr/bin/diff -w $last $dir/$f`;
$diffs=~s/\n</\nREMOVE/g; $diffs=~s/\n>/\nINSERT/g;
$diffs=~s/&/&/g; $diffs=~s/</</g;
$diffs=~s#\nREMOVE#\n<B>REMOVE</B>#g;
$diffs=~s#\nINSERT#\n<B>INSERT</B>#g;
print $diffs;
print "\n</PRE><BR>";
$last="$dir/$f";
}
}
}
}
}
}
<subroutines 74> =sub dispDate {
my ($date,$link,$nodate)=(shift,shift,shift);
my ($displaydate,$linkage);
if (!defined($date)) {return $nodate;}
if ($date =~ /([\d]{4})([\d]{2})([\d]{2})([\d]{2})([\d]{2})/) {
my ($yr,$mon,$day,$hr,$min)=($1,$2,$3,$4,$5);
@Month = ('Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Nov','Dec');
if ($yearrequired) {
$displaydate = $day.' '.$Month[$mon-1].' '.$yr.' '.$hr.':'.$min;
} else {
$displaydate = $day.' '.$Month[$mon-1].' '.$hr.':'.$min;
}
if ($link) {
$linkage="<A HREF=\"$SCRIPT?".
"UnitCode=".$link."\"><TT>".
$displaydate."</TT></A>";
return $linkage;
} else {
return $displaydate;
}
} else {
return $nodate;
}
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
<doShow: print Approval page explanation 75> =print <<' FINIS';
<P>The colour code used is as follows:</P>
<DL>
<DT>yellow</DT><DD>Saves are current that have not been approved</DD>
<DT>green</DT><DD>Approval process complete to this stage</DD>
<DT>pink</DT><DD>Approval process not yet completed to this stage</DD>
</DL>
FINIS
Warning! The use of the here document is a kluge. Note
the explicit inclusion of indentation space, which cannot be
elided in this literate program structure.
9. doApprove: Approve a Unit Description
doApprove is responsible for handling the process of
approving unit descriptions. There are a range of different
approvals, and the work flow for these approvals must be
maintained. Firstly we identify which level of approval is
sought, then find which unit description is to be approved, and
finally stamp the unit approval. There are three separate pages
to handle each of these steps, and consequently three entry
points to this routine, corresponding to the approve
parameter on entry.
The workflow is handled by the flag attached to the file. This
is a single letter flag, with the following meanings:
- V
- a saVed file: generated by an arbitrary (authenticated)
user saving the file.
- M
- a subMitted file: when a user submits a file for school
approval.
- S
- a School approved file: when the school SEC approves the
proposal. Schools can only approve a file with the M flag
- E
- an Endorsed file: when the proposal is approved by the
FEC. FEC can only approve files with the S flag.
- A
- an Approved file: finally approved by Faculty Board. FB
can only approve files with the E flag.
<subroutines 76> =
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
On entering doApprove, the approve parameter is
set to either APPROVE Description, indicating first time
entry, or APPROVE parameter, indicating the choice
of approval option, or SELECT parameter,
indicating which unit or units is to be approved. In the latter
two cases, the second part of the parameter is set to one of the
following two groups:
-
ADT,
DAC,
FacMan,
FacultyBoard,
FEC,
FRC,
-
CPE,
CSE,
FIT,
GCO,
IMS,
ITW,
MMS,
SBS
indicating for the first group, the appropriate approval
authority, and for the second group, the appropriate school
approval authority.
9.1 doApprove: What Approvals are Possible
for this User?
<doApprove: show approvals options 77> =print $auth->header(),
$auth->start_html(-title=>'Infotech Unit Approvals',
-BGCOLOR=>'#f0fff0'),
$auth->h1('Infotech Unit Avatar: Approvals Page'),
$auth->startform('post',"$SCRIPT"),
$auth->p;
if (-f "$SUBMISSIONS/$UnitCode.xml") {
<doApprove: collect approvals data 78>
if (%posn || %subj) {
<doApprove: items can be approved 79>
} else {
print "Hello, $Editor. ";
print "There are no items you have authority to approve";
}
} else {
print "There is no description for unit $UnitCode";
}
print $auth->endform,
$auth->end_html;
Generate the stub form that identifies what approvals may be
given by this person (the Editor) for this unit
(UnitCode). The permissions are given by the file
$APPROVALS, specified below.
The two parameters passed to the approval script proper are
the approval capability, and the date. See below for why.
<doApprove: collect approvals data 78> =open APPRO,"<$APPROVALS"
or die "No Approvals file";
my %posn; my %subj;
while (<APPRO>) {
s/(.*)://;
my $person = $1;
if ($person eq $Editor) {
foreach $posn (split(' ',$_)) {
if ($posn=~s/^=//) {$subj{$posn} = 't';}
else {$posn{$posn} = "t";}
}
}
}
if ($TESTING) {print DEBUG %subj,",",%posn,"\n";}
close APPRO;
Read the following file in to determine who has what
approvals capabilities. Build a hash array indexed on
approval capability for just the person identified as the
Editor. The actual value stored in this hash is
irrelevant, it is the keys that are the important data.
If the line in the approvals file contains an entry preceded
by an equals sign, then this person is also able to give
school approval for units prefixed by the value following the
equals sign. For example, the =CSE flag gives authority
to give school approval for all CSE units.
<doApprove: items can be approved 79> =print "$Editor, you are able to approve ",
"the following items for unit ",
$UnitCode,":",$auth->p;
my $SchoolCode = 0;
foreach $posn (keys(%subj)) {
if ($UnitCode=~/$posn/) {
print $auth->submit('approve','SELECT '.$posn.' School');
print $auth->textfield('school','School Information',60);
$SchoolCode = $posn;
print "<P>If giving School approval, ";
print "you must replace `School Information' with the date, ";
print "meeting number or URL of the relevant School approval ";
print "process</P>";
}
}
foreach $posn (keys(%posn)) {
print $auth->p;
print $auth->submit('approve','SELECT '.$posn);
}
$Date=$TimeStamp; #`/bin/date "+%d %b %Y"`;
print $auth->hidden('date',$Date),
$auth->hidden('school',$SchoolCode),
$auth->hidden('Editor',$Editor),
$auth->hidden('UnitCode',$UnitCode);
We have some valid items that can be approved by this person.
Generate welcome message, and list all the approval options.
School approval is the first to be processed. This is
indicated by finding entries in the subj hash array
(The 3 letter school/unit prefix is used as the key.)
Then each non-school approval is listed. These are simpler
in the sense that they do not require any ancillary
information, and hence are just buttons with no text fields.
If school approval was indicated, print some help text.
Finally generated hidden fields to pass over essential data
to the approval script. Invoke the next stage, which is
selection of the unit to approve.
Show the unit descriptions links that can be approved.
"MonAtar-IT.appr" 80 =Annabelle McDougall:FacultyBoard
Christopher Avram:ADT FEC DAC FacultyBoard =CSE =FIT
Christabel Gonsalvez:=IMS =MIS
Geraldine D'Costa:FEC FacultyBoard
Des Casey:=CPE
Don Schauder:FRC
Guojun Lu:=GCO =FIT
John Betts:=BUS
John Hurst:ADT FEC DAC FacultyBoard FRC Resources =CSE =FIT
Kerry Tanner:=IMS =MIS
Kim Styles:=GCO
Leisa McGuinness:=CPE
Lindsay Smith:=MMS
Liz Kendall:FRC =CPE
Madhusudan Chetty:=GCO
Marguerite Jones-Roberts:FRC
Muhamed Bekir:Resources
Pang Hiew:=CSE =BUS =ITW
Ralph Gillon:FEC FacultyBoard FRC
Ronald Pose:=CSE =FIT
Sue Gleeson:FEC FacMan FacultyBoard
Trudi Robinson:=IMS =MIS
Velika Raicevic:FRC
"MonAtar-Bus.appr" 81 =Sally Joy2:ADT FEC DAC FacultyBoard FRC
"MonAtar-Med.appr" 82 =Tony Luff2:ADT FEC DAC FacultyBoard FRC
The name of each person able to give approvals appears first
on each line, separated from the approval level indicators by
a colon. Multiple approval indicators are blank
separated.
"MonAtar-IT-sbs.adr" 83 =John.Betts@infotech.monash.edu.au
Kate.Smith@infotech.monash.edu.au
Anne.Parr@infotech.monash.edu.au
Peter.Lawrence@infotech.monash.edu.au
Dineli.Mather@infotech.monash.edu.au
Caitlin.Slattery@infotech.monash.edu.au
Judy.Backhouse@infotech.monash.edu
Hiew.Pang.Leang@busit.monash.edu.my
Elsa.Phung@busit.monash.edu.my
Grace.Bol@infotech.monash.edu.au
"MonAtar-IT-csse.adr" 84 =education@csse.monash.edu.au
"MonAtar-IT-gscit.adr" 85 =ml-edu@www.gscit.monash.edu.au
"MonAtar-IT-mum.adr" 86 =sec@infotech.monash.edu.my
"MonAtar-IT-sims.adr" 87 =simsedco@sims.monash.edu.au
"MonAtar-IT-sms.adr" 88 =smseduc@infotech.monash.edu.au
"MonAtar-IT-snc.adr" 89 =Des.Casey@infotech.monash.edu.au
Liz.Kendall@infotech.monash.edu.au
Leisa.McGuinness@infotech.monash.edu.au
I haven't worked out how best to handle school level
approvals yet, since these will require some way of working
from unit code to school, and from school to person. The
latter part is more straightforward - I expect to be able to
use a list of FEC voting members to determine that.
9.2 doApprove: Select Unit(s) to Approve
<doApprove: select unit for approval 90> =my $approvaltype = $1; my $flag="V";
print $auth->header(),
$auth->start_html(-title=>'Infotech Unit Approvals',
-BGCOLOR=>'#f0fff0'),
$auth->h1('Infotech Unit Avatar: Approvals Page'),
$auth->startform('post',"$SCRIPT"),
$auth->p;
print $auth->p, "$Editor, you can give $approvaltype ".
"approval to the following units (most recent first)";
print $auth->p;
if ($approvaltype=~/^(.*) School/) {
$flag = "M";
$SchoolCode = $1;
if ($TESTING) {
print $auth->p,"Got SchoolCode of $SchoolCode in select";
}
} elsif ($approvaltype=~/FEC/) {
$flag="S"
} elsif ($approvaltype=~/FacultyBoard/) {
$flag="E"
} else {
$flag="*"
}
print $auth->p;
<doApprove: list valid units 91>
print $auth->hidden('date',$Date),
$auth->hidden('school',$SchoolCode),
$auth->hidden('Editor',$Editor),
$auth->hidden('UnitCode',$UnitCode);
print $auth->p;
print $auth->submit('approve','APPROVE '.$approvaltype);
print $auth->endform,
$auth->end_html;
At this stage, the user has clicked a button indicating what
approval they wish to offer, so now we must find out what unit
or units they wish to give that approval to. Run through all
the units they can approve, marking them all available to
approve. The user can then deselect any not approved, and
then completes the process by clicking the final approve
button.
<doApprove: list valid units 91> =my $dir="$SUBMISSIONS/archive";
my @units;
opendir(ARCHIVE,$dir);
@archfiles=grep(!/^\.\.?$/,readdir(ARCHIVE));
foreach $f (@archfiles) {
if ($f =~ /^$UnitCode-[0-9]+-$flag/) {
unshift(@units,$f);
}
}
closedir ARCHIVE;
print $auth->radio_group(-name=>'whichUnit',
-values=>\@units,
-linebreak=>'true');
print $auth->p,"\n";
9.3 doApprove: Give Approval to Unit
<doApprove: give approval to unit 92> =my $approve=$1;
my $schoolinfo=$auth->param('school');
my $other="";
my $VersionComment="$approve Approval";
my $fullunit = $auth->param('whichUnit');
print $auth->header();
print $auth->start_html('test'),
$auth->h1("Approvals Information for $fullunit");
if ($approve=~/School/) {$approve='School';}
if ($approve=~/FRC/) {
$approve='Other'; $other="FRC Approved/Noted ";
$VersionComment="$other";
}
getDocument(0,0);
Collect the parameters and setup the approval information.
FRC approval is treated as a special case, since it does not
have a separate unit description field. Then get the unit
description document to operate upon. This creates a working
copy in the temporary directory.
<doApprove: give approval to unit 93> =$xsl="$XMLPAGE/MonAtar-appr.xsl";
$src="$SUBMISSIONS/archive/$fullunit";
$dest="$TMP/$UnitCode-appr.xml";
$erf="$TMP/$UnitCode-appr.ers";
$date=$timestamp;
$parms="$XP FIA$approve \"'$other$date ($EscEditor)'\"";
$parms.=" $XP Approve \"'$approve'\"";
$parms.=" $XP VersionComment \"'$VersionComment'\"";
$parms.=" $XP Editor \"'$EscEditor'\"";
#$date=`/bin/date "+%d %b %Y %H:%M"`; chop($date);
$parms.=" $XP Date \"'$date'\"";
$parms.=" $XP School \"'$schoolinfo'\"";
$cmd="$XSLTPROC $parms $xsl $src >$dest 2>$erf";
`$cmd`;
Setup all the xsltproc commands to process the document, and
add the approval information. Then process the document, using
the MonAtar-appr.xsl
XSLT transformer script.
<doApprove: give approval to unit 94> =print DEBUG $cmd,"\n";
open ERRS,"<$erf";
$errs="";
print "<PRE>\n$cmd\n";
while (<ERRS>) {print;$errs.=$_;}
print "</PRE>\n";
close ERRS;
Print any error messages generated.
<doApprove: give approval to unit 95> =if ($approve=~/School/ && $schoolinfo=~/^School Information$/) {
my $msg="<P><B>You haven't entered the school approval information.\n";
$msg.="Please click the back button and complete the ".
"missing information.</B></P>";
print $msg;
$errs.=$msg;
}
Check that school information has been entered, if giving
school approval.
<doApprove: give approval to unit 96> =if (!$errs) {
my %approvalworkflow = ('School','S','FEC','E','FacultyBoard','A');
my $flag = $approvalworkflow{$approve};
if (!$flag) {
$fullunit=~/.*-(.)$/;
$flag=$1;
}
print $auth->p,
"$approve Approval ($flag) given by $Editor on $date ",
$auth->p;
rename $dest,$src;
`cp -p $src $SUBMISSIONS/$UnitCode.xml`;
$FullUnitCode="$UnitCode-$timestamp-$flag";
my $arc = "$SUBMISSIONS/archive/$FullUnitCode";
$xsl = "$XMLPAGE/sanitiseV2.xsl";
$cmd = "$XSLTPROC $xsl $src >$arc 2>$erf";
print DEBUG $cmd,`$cmd`;
print $auth->a({-href=>"$SCRIPT?UnitCode=$FullUnitCode"},
"View the approved unit");
my ($adr,$subj,$msg);
# compute $adr by grabbing ProposerEMail field
$subj = "[MonAtar] $UnitCode InfoTech Unit Submission (Approval)";
$msg = "$UnitCode has been given $approve Approval. View at\n\n";
$msg.= " $SCRIPT?UnitCode=$FullUnitCode\n\n";
if ($approve=~/School/) {
$msg.= "The school comment is: $schoolinfo\n";
}
getLatestApproved($UnitCode);
if ($ApprovedVersion) {
$msg.="You can compare this with the latest (Faculty) approved ";
$msg.="version by clicking\n\n";
$msg.=" $SCRIPT?".
"compare=compare&BaseCode=$ApprovedVersion".
"&UnitCode=$FullUnitCode\n\n";
}
print $auth->p;
$adr = "ajh\@csse.monash.edu.au";
&sendmail($adr,$subj,$msg);
print "Emailed $adr approval status\n";
my @adrs = split(',',$FECEOFF);
foreach $adr (@adrs) {
&sendmail($adr,$subj,$msg);
print "Emailed $adr approval status
\n";
}
}
Stamp approved by copying approved document to base
directory, and archiving a sanitised version.
<doApprove: give approval to unit 97> =unlink $ers;
print $auth->endform,
$auth->end_html;
And clean up.
The interface to this script is through the two parameters
approve and date, supplied by the
description-approval form described in the previous
subsection.
9.4 The Approval XML Translation Rules
To add approvals to the master unit XML file, we run an
XSLT translation over it, translating from XML to XML. Hence
many of the templates in this ruleset are effectively
idempotent, and the (currently) seven approval capabilities
each have a CLI parameter to pass in any updated values.
The final template is a "catch-all" template. It
copies through unchanged any other elements and their tags.
(File has been moved to a separate file.)
10. Review a Unit Description
10.1 doReview: start a review template
<subroutines 98> =
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
doReview is responsible for collecting the nominated
unit description document, and processing it using
xsltproc under the stylesheet
MakeReviewForm.xsl.
This generates an html page that the
user can edit and submit, using ReviewSubmit.
<doReview: no unit description file 99> =$TITLE="Infotech Unit Avatar: Unit Review Failure";
printError('Missing Document',
"<P>There is no Unit Description for \"<B>$UnitCode</B>\".</P>".
"<P>You need to write one of these before you can complete ".
"the review. Go to the avatar home page and click EDIT ".
"Description and follow the instructions there.</P>");
<doReview: process unit description file 100> =$xsl = "$XMLPAGE/MakeReviewForm.xsl";
$dest="$TMP/$UnitCode-rev.xml";
$erf="$TMP/$UnitCode-rev.stderr";
$datetime=$TimeStamp;
$datetime="$XP DateAndTime \"'$datetime'\"";
$Editor="$given $surname";
$editor="$XP Editor \"'$EscEditor'\"";
$unit="$XP UnitCode \"'$UnitCode'\"";
$staff="$XP Staff \"'$Staff'\"";
$school="$XP School \"'$School'\"";
$parms="$datetime $editor $unit $staff $school";
$cmd="$XSLTPROC $parms -o $dest $xsl $src 2>$erf";
`$cmd`;
print DEBUG $cmd;
$err = ""; open ERR,"<$erf"; while (<ERR>) {$err.=$_}; close ERR;
if ($err) {
$TITLE="Infotech Unit Avatar: Unit Review Failure";
&printHtmlHeaders;
<doReview: handle errors 102>
} else {
<doReview: make review edit page 101>
}
<doReview: make review edit page 101> =$xsl = "$XMLPAGE/Review2html.xsl";
$src="$TMP/$UnitCode-rev.xml";
$dest="$TMP/$UnitCode-rev.html";
$change="$XP ViewOrEdit \"'Edit'\"";
$server="$XP Server \"'$SCRIPT'\"";
$parms="$datetime $editor $unit $change $server";
$cmd="$XSLTPROC $parms -o $dest $xsl $src 2>$erf";
`$cmd`;
print DEBUG $cmd;
$err = ""; open ERR,"<$erf"; while (<ERR>) {$err.=$_}; close ERR;
if ($err) {
$TITLE="Infotech Unit Avatar: Unit Review Failure";
&printHtmlHeaders;
<doReview: handle errors 102>
} else {
$TITLE="Infotech Unit Avatar: Unit Review Page";
&printHtmlHeaders;
print "$Editor,$School,$Staff,$Faculty<P>\n";
# use the resultant HTML file as returned page
open NEW,"<$dest";
while (<NEW>) {print;}
close NEW;
}
#unlink $src,$dest,$erf;
<doReview: handle errors 102> =$err=~s/&/&/g; $err=~s/</</g;
print "<P>doReview: There was an error in translating the source file \n";
print "<TT>$TMP/$UnitCode.xml</TT>.\n";
print "Here is the output that was generated.\n";
print "If you cannot interpret this, please contact John Hurst.<P>\n";
print "<P><B>Command:</B></P>\n";
print "<PRE>\n";
print "$EditOrView\n";
print "$cmd\n";
print "<PRE>\n";
print "<P><B>Output:</B></P>\n";
print "</PRE>\n";
print "$err\n";
print "</PRE>\n";
print "\n";
There were errors. Before we display the error file, we munge
out all ampersands into ampersand entities, and all less than
signs into less than entities.
10.2 doReviewSubmit: submit a unit review
Parms: /---------\
see list ---------->| MonAtar |
below \---------/
|
V
+-----------------------------------+
| $TMP/$UnitCode-$timestamp-rev.xml |
+-----------------------------------+
|
V
+-----------------+ /----------\
| Review2html.xsl |---->| xsltproc |
+-----------------+ \----------/
|
V
/ \
/OK?\ no
\ /------> Error, Translation
\ /
| yes
V
+------------------------------------+
| $TMP/$UnitCode-$timestamp-rev.html |
+------------------------------------+
|
V
display this file
copy $TMP/review.xml to
|
V
+------------------------------+
| reviews/$UnitCode-$timestamp |
+------------------------------+
delete TMP files
The following parameters are passed to MonAtar via the
UnitCode-rev.html script generated in
doReview. These are used to generate the temporary file
$UnitCode-$timestamp-rev.xml. NOTE: We must avoid conflict with concurrent
review instantiations. We try to do this by timestamping each
review, but the conflict is still possible.
AssAccurate |
DelURL |
OutFeedbackData |
AssAlign |
Editor |
OutIssues |
AssFeedbackData |
GeneralCommentsData |
OutIssuesData |
AssFeedback |
ObjCorrect |
OutMonitor |
AssMarks |
ObjFit |
OutMonitorData |
AssObjectives |
ObjGAAware |
ReviewFeedbackData |
AssReliable |
ObjGAIdentified |
ReviewerRelation |
AssSchemes |
ObjSpread |
School |
AssValid |
ObjWkWeight |
Staff |
DelInTime |
OutAddressed |
UnitCode |
DelInTimeData |
OutAddressedData |
UnitCoordinator |
DelTimeTable |
OutFeedback |
UnitName |
<subroutines 103> =sub revEntry1 {
my ($ind,$el,$val)=(shift,shift,shift);
my ($parm)=($auth->param($val));
$parm=~s/&/&/g;
print XML " ",'<',$el,'>';
print XML $parm;
print XML " ",'</',$el,'>',"\n";
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
revEntry1 handles elements of the form:
Note the subtlety in the substitions into parm. The
match is against raw ampersands, which must be replaced by
escaped ampersands. But the code itself is in an ampersand
sensitive environment, so the raw code must also escape
ampersands! (This is not necessarily apparent in the document,
due to the different escaping mechanisms for HTML and TeX.)
<subroutines 104> =sub revEntry2 {
my ($ind,$el,$val)=(shift,shift,shift);
my ($parm)=($auth->param($val));
$parm=~s/&/&/g;
print XML " ",'<',$el," yesno=\"";
print XML $parm;
print XML "\"/>\n";
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
revEntry2 handles elements of the form:
<subroutines 105> =sub revEntry3 {
my ($ind,$el,$val,$data)=(shift,shift,shift,shift);
my ($parm1)=($auth->param($val));
$parm1=~s/&/&/g;
my ($parm2)=($auth->param($data));
$parm2=~s/&/&/g;
print XML " ",'<',$el," yesno=\"";
print XML $parm1;
print XML "\">";
print XML $parm2;
print XML '</',$el,">\n";
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
revEntry3 handles elements of the form:
<$el yesno="$val">$data<$el/>
<subroutines 106> =sub doReviewSubmit {
doLogOperation("doReviewSubmit");
my $revsrc="$TMP/$UnitCode-$timestamp-rev.xml";
open XML,">$revsrc" or die "Cannot open review document";
print XML "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
print XML "<!DOCTYPE ReviewV1 PUBLIC \"-//MONASH-CSSE//DTD ".
"ReviewV1 1.0//EN\" \"/ReviewV1.dtd\">\n";
print XML "<ReviewV1 xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n";
print XML " <DateAndTime>",$TimeStamp,"</DateAndTime>\n";
print XML " <ReviewerName relation=\"",
$auth->param('ReviewerRelation'),"\">",
$auth->param('Editor'),"</ReviewerName>\n";
revEntry1(2,'ReviewerStaff','Staff');
revEntry1(2,'ReviewerSchool','School');
revEntry1(2,'UnitCode','UnitCode');
revEntry1(2,'UnitName','UnitName');
print XML " <UnitCoordinator>",$auth->param('UnitCoordinator'),
"</UnitCoordinator>\n";
print XML " <UnitCoordEMail/>\n";
print XML " <UnitObjectives>\n";
revEntry2(4,'ObjCorrect','ObjCorrect');
revEntry2(4,'ObjContent','ObjContent');
print XML " <ObjWorkload>\n";
revEntry2(6,'ObjWkWeight','ObjWkWeight');
revEntry2(6,'ObjSpread','ObjSpread');
revEntry2(6,'ObjFit','ObjFit');
print XML " </ObjWorkload>\n";
print XML " <ObjGradAttrs>\n";
print XML " <ObjGAIdentified yesno=\"",
$auth->param('ObjGAIdentified'), "\"/>\n";
print XML " <ObjGAAware yesno=\"",$auth->param('ObjGAAware'),"\"/>\n";
print XML " </ObjGradAttrs>\n";
print XML " </UnitObjectives>\n";
print XML " <UnitOutcomes>\n";
revEntry3(2,'OutMonitor','OutMonitor','OutMonitorData');
revEntry3(2,'OutIssues','OutIssues','OutIssuesData');
revEntry3(2,'OutFeedback','OutFeedback','OutFeedbackData');
print XML " <OutFBAware yesno=\"",
$auth->param('OutFBAware'),"\"/>\n";
revEntry3(2,'OutAddressed','OutAddressed','OutAddressedData');
print XML " </UnitOutcomes>\n";
print XML " <Delivery>\n";
print XML " <DelTeachMethods yesno=\"",$auth->param('DelTeachMethods'),
"\"/>\n";
print XML " <DelContentExp yesno=\"",$auth->param('DelContentExp'),
"\"/>\n";
print XML " <DelAssessExp yesno=\"",$auth->param('DelAssessExp'),
"\"/>\n";
print XML " <DelTeachMethods yesno=\"",$auth->param('DelTeachMethods'),
"\"/>\n";
print XML " <DelTimeTable yesno=\"",$auth->param('DelTimeTable'),
"\"/>\n";
revEntry1(4,'DelURL','DelURL');
revEntry3(2,'DelInTime','DelInTime','DelInTimeData');
print XML " </Delivery>\n";
print XML " <Assessment>\n";
revEntry3(4,'AssFeedback','AssFeedback','AssFeedbackData');
print XML " <AssFeedUseful yesno=\"",
$auth->param('AssFeedUseful'),"\"/>\n";
print XML " <AssObjectives yesno=\"",$auth->param('AssObjectives'),
"\"/>\n";
print XML " <AssAlign yesno=\"",$auth->param('AssAlign'),"\"/>\n";
print XML " <AssValid yesno=\"",$auth->param('AssValid'),"\"/>\n";
print XML " <AssReliable yesno=\"",$auth->param('AssReliable'),"\"/>\n";
print XML " <AssSchemes yesno=\"",$auth->param('AssSchemes'),"\"/>\n";
print XML " <AssMarks yesno=\"",$auth->param('AssMarks'),"\"/>\n";
print XML " <AssAccurate yesno=\"",
$auth->param('AssAccurate'),"\"/>\n";
print XML " <Satisfaction yesno=\"",
$auth->param('Satisfaction'),"\"/>\n";
print XML " </Assessment>\n";
print XML " <General>\n";
revEntry1(4,'Comments','GeneralCommentsData');
revEntry1(4,'ReviewFeedback','ReviewFeedbackData');
print XML " </General>\n";
print XML " <ResourceReqs/>\n";
print XML "</ReviewV1>\n";
close XML;
print header('text/html');
$xsl="$XMLPAGE/Review2html.xsl";
$dest="$TMP/$UnitCode-$timestamp-rev.html";
$erf="$TMP/$UnitCode-$timestamp-rev.stderr";
$datetime=$TimeStamp;
$datetime="$XP DateAndTime \"'$datetime'\"";
if (defined($Editor)) {$editor="$XP Editor \"'$EscEditor'\""}
else {$editor=""};
$unit="$XP UnitCode \"'$UnitCode'\"";
$view="$XP ViewOrEdit \"'View'\"";
$parms="$datetime $editor $unit $view";
$cmd="$XSLTPROC $parms -o $dest $xsl $revsrc 2>$erf";
`$cmd`;
$err = ""; open ERR,"<$erf"; while (<ERR>) {$err.=$_}; close ERR;
if ($err) {
<doView: handle errors 39>
} else {
print "<P>Your review has been succesfully submitted. ".
"Here is what you have entered:</P>\n";
my $reviewpage="reviews";
if ($Staff=~/Student/) {$reviewpage="reviews/students";}
$cmd="cp $revsrc $SUBMISSIONS/$reviewpage/$UnitCode-$timestamp";
`$cmd`;
# use the resultant HTML file as returned page
open NEW,"<$dest";
while (<NEW>) {print;}
close NEW;
}
#unlink $revsrc,$dest,$erf;
}
Chunk referenced in 12Chunk defined in 22,
23,
24,
25,
26,
27,
28,
29,
30,
33,
34,
36,
40,
42,
50,
53,
60,
61,
65,
66,
69,
74,
76,
98,
103,
104,
105,
106
doReviewSubmit is responsible for building a completed
review from data supplied through parameters to this avatar
call. This is done by building the xml document from scratch.
11. XSL Stylesheets and Transformers
11.1 MakeReviewForm.xsl An XSL
script to Generate a Review Form
The script creates an XML review form from the data supplied
in a unit description document.
The MakeReviewForm.xsl
documentation is maintained separately.
11.2 mergexml.xsl Merge Updates with Description
Combine edited field and Old XML to make new a XML
Description file.
The mergexml.xsl
documentation is maintained separately.
11.3 MonAtar-appr.xsl Merge Approval Information
with Description
Combine edited field and Old XML to make new a XML
Description file.
The MonAtar-appr.xsl
documentation is maintained separately.
11.4 V1toV2.xsl Converter Script
This XSLT transformer script converts unit descriptions from
version 1 format to version 2. It has been renamed from
old2new.xsl to V1toV2.xsl.
The V1toV2.xsl
documentation is maintained separately.
11.5 xml2html.xsl Convert XML Description to HTML
Converts an XML description file to HTML. There are two main
forms: view and edit. View gives plain HTML,
suitable for printing; Edit gives buttons to click to update
the various editable fields. The choice is set by a parameter.
This has been moved to a
separate file.
11.6 xml2txt.xsl Convert XML Description to Plain Text
This has been moved to a separate file.
12. TODO
- 20041119:103111
- Add a disestablishment field with date
- 20041112:110259
- Add a "Date to Take Effect" popup when submitting for
approval.
- 20040730:145937
- When an edit is made to a description that is part way
through the approval process, there needs to be some sort of
warning. Such edits should only be made by the approving
authority to update the latest version.
- 20040519:143534
- Add item to unit review about addition of Inclusive
Practices awareness in unit contexts.
- 20040512:081040
- (Chris Gonsalvez) Some way of defining the 700 character
limit for unit summaries. Also a section called Resources or
Notes (not subject to the approval process), which the School
could use for more detailed information about the unit. This
would help with trying to keep all the information about a
unit in one central source. Email reply to Chris, 20040512:
The second one is easy, and I'll add it asap. The monatar is
currently undergoing testing for the new approval process, so
it will need to wait until that is finished (no promises on
ETA, I'm afraid).
The first will require a little more thought, and possibly
input from other users. I'm reluctant to add another field to
do this, because it then becomes a source of potential
inconsistency, if edited without due regard to the open length
field. Possibilities that occur to me include:
- separate field (potential inconsistencies)
- limit current field (transition issues)
- warn user when field is longer than 700 chars (my
pref)
- XML markup in current field to show what is omitted
in short version (ideal, but needs user training)
- other suggestions?
- 20040503:135320
- Auto inform library whenever a reading list is changed.
- 20030616:223549
- Need better change mechanism: check out sanitising that
highlights differences
- 20030616:223244
- Mode for single section edit, which does auto version
history
- 20030605:170128
- Move the version history stuff on home page to end of home
page
- 20030326:112216
- Follow through on the six areas identified in
CHEQ Unit Review Guidelines. In broad terms, Units
will be evaluated in relation to 6 key areas
- Content
-
Content
and objectives
- Teaching
-
Teaching
methods
- Assessment
-
Assessment
procedures
- Workloads
-
Student
workload and study behaviour
- Evaluation
-
Routine
evaluation
- Expertise
-
Expertise
of teaching staff
- 20020124:083406
- Design Version Control interface
- 20020124:083539
- add StartPoint mechanism to always display description at
edit point.
- 20020322:125308
- Generate the prohibitions matrix; change wording of submit
statement; include subject description in email; define
interest groups
- 20020516:155005
- Add Telecommunications and Networks to classification
- 20020522:094705
- Fix home page so that code,enter does a view rather than
give an error
13. DONE
- Write converter for all archived xml descriptions
- Incorporate a2x.pl into monatar litprog
14. Indices
14.1 Files
File Name |
Defined in |
MonAtar |
12 |
MonAtar-Bus.appr |
81 |
MonAtar-IT-csse.adr |
84 |
MonAtar-IT-gscit.adr |
85 |
MonAtar-IT-mum.adr |
86 |
MonAtar-IT-sbs.adr |
83 |
MonAtar-IT-sims.adr |
87 |
MonAtar-IT-sms.adr |
88 |
MonAtar-IT-snc.adr |
89 |
MonAtar-IT.appr |
80 |
MonAtar-Med.appr |
82 |
14.2 Chunks
Chunk Name |
Defined in |
Used in |
context variables |
2, 3, 4, 5, 6, 7, 8, 9, 10, 11
|
13 |
doApprove: collect approvals data |
78 |
77 |
doApprove: give approval to unit |
92, 93, 94, 95, 96, 97
|
76 |
doApprove: items can be approved |
79 |
77 |
doApprove: list valid units |
91 |
90 |
doApprove: select unit for approval |
90 |
76 |
doApprove: show approvals options |
77 |
76 |
doChange: print helpful hints |
51 |
50 |
doChange: warn about editing ObjText |
52 |
50 |
doCompare: handle errors |
68 |
66 |
doCompare: set xsltproc parameters |
67 |
66 |
doEdit: change Editor level |
46 |
45 |
doEdit: do NOT have a Version Comment |
44 |
|
doEdit: handle errors |
49 |
45 |
doEdit: have a Version Comment |
45 |
42 |
doEdit: helpful text |
47 |
46 |
doEdit: parameter debugging |
43 |
42 |
doEdit: set xsltproc parameters |
48 |
45 |
doReview: handle errors |
102 |
100, 101
|
doReview: make review edit page |
101 |
100 |
doReview: no unit description file |
99 |
98 |
doReview: process unit description file |
100 |
98 |
doShow: compute time ranges |
71 |
69 |
doShow: generate form components |
70 |
69 |
doShow: generate table of units |
72 |
69 |
doShow: print Approval page explanation |
75 |
72 |
doShow: version differences |
73 |
69 |
doSubmit: get document values |
62 |
61 |
doSubmit: get submission data |
64 |
63 |
doSubmit: send mail to SEC members |
63 |
61 |
doUpdate: call the xslt processor |
57 |
53 |
doUpdate: check revised document |
59 |
53 |
doUpdate: convert plain text to XML |
55 |
53 |
doUpdate: error reporting |
58 |
53, 60, 61
|
doUpdate: parameter debugging |
54 |
53, 60, 61
|
doUpdate: sanitise newtext |
56 |
53 |
doView: handle errors |
39 |
36, 106
|
doView: set stylesheet according to version |
38 |
37 |
doView: set xsltproc parameters |
37 |
36 |
get parameters |
15, 16, 17
|
12 |
getDocument: and sanitise it |
41 |
40 |
grabPersonData: set submission details for InfoTech |
31 |
30 |
grabPersonData: set submission details for no Faculty |
32 |
30 |
illegal parameters |
21 |
12 |
initialization |
13, 14
|
12 |
login to avatar |
19 |
12 |
perform avatar authentication |
20 |
12 |
re-enter avatar |
18 |
12, 12
|
selection page text |
35 |
34 |
subroutines |
22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 36, 40, 42, 50, 53, 60, 61, 65, 66, 69, 74, 76, 98, 103, 104, 105, 106
|
12 |
subroutines |
22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 36, 40, 42, 50, 53, 60, 61, 65, 66, 69, 74, 76, 98, 103, 104, 105, 106
|
12 |
subroutines |
22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 36, 40, 42, 50, 53, 60, 61, 65, 66, 69, 74, 76, 98, 103, 104, 105, 106
|
12 |
subroutines |
22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 36, 40, 42, 50, 53, 60, 61, 65, 66, 69, 74, 76, 98, 103, 104, 105, 106
|
12 |
subroutines |
22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 36, 40, 42, 50, 53, 60, 61, 65, 66, 69, 74, 76, 98, 103, 104, 105, 106
|
12 |
subroutines |
22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 36, 40, 42, 50, 53, 60, 61, 65, 66, 69, 74, 76, 98, 103, 104, 105, 106
|
12 |
subroutines |
22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 36, 40, 42, 50, 53, 60, 61, 65, 66, 69, 74, 76, 98, 103, 104, 105, 106
|
12 |
subroutines |
22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 36, 40, 42, 50, 53, 60, 61, 65, 66, 69, 74, 76, 98, 103, 104, 105, 106
|
12 |
subroutines |
22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 36, 40, 42, 50, 53, 60, 61, 65, 66, 69, 74, 76, 98, 103, 104, 105, 106
|
12 |
subroutines |
22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 36, 40, 42, 50, 53, 60, 61, 65, 66, 69, 74, 76, 98, 103, 104, 105, 106
|
12 |
subroutines |
22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 36, 40, 42, 50, 53, 60, 61, 65, 66, 69, 74, 76, 98, 103, 104, 105, 106
|
12 |
14.3 Identifiers
Identifier |
Defined in |
Used in |
Document History
20020208:074656 |
ajh |
2.0 |
First documented version: basic (edit, change, update)
profile working |
20020322:125406 |
ajh |
2.1 |
many updates; add prohibitions matrix (et al) TODOs |
20020322:171540 |
ajh |
2.1.1 |
Added button to bottom of view page to enter avatar |
20020325:152654 |
ajh |
2.2.0 |
Dual editing mode installed |
20020327:221227 |
ajh |
2.2.1 |
added Classification in View and Edit modes |
20020331:214023 |
ajh |
2.2.2 |
updated MonAtar-version.xsl (not in this litprog) to
handle save of attributes |
20020403:170511 |
ajh |
2.2.3 |
first on-line version 2 |
20020416:175300 |
ajh |
2.2.4 |
fix mergexml.xsl: not copying attributes |
20020506:124920 |
ajh |
2.3.0 |
fix xml2txt.xsl to use new markup rules (rtf based) |
20020531:090141 |
ajh |
2.3.1 |
fix Proposer insertion, and chopping last char bug |
20020612:090340 |
ajh |
2.3.2 |
remove xml2html.xsl file from this document |
20020613:095104 |
ajh |
2.3.3 |
remove mergexml.xsl file from this document |
20020624:115207 |
ajh |
2.3.4 |
reformat date in Version History |
20020805:122352 |
ajh |
2.3.5 |
add non-ASCII exclusion |
20020805:150916 |
ajh |
2.3.6 |
remove ajh from submission emailing |
20020815:095048 |
ajh |
2.3.7 |
Change Objective titles |
20020816:154511 |
ajh |
2.3.8 |
Add direct jump link on edit page |
20020905:160429 |
ajh |
2.3.9 |
Add check in doUpdate to ensure xml errors not saved |
20020925:163831 |
ajh |
2.3.10 |
Add sanitise stage in getDocument |
20021011:103207 |
ajh |
2.3.11 |
Add check in approve that Unit Description exists,
and Add ability for all approvers to approve FIT units (done by
adding fields to MonAtar-appr.txt) |
20021016:161838 |
ajh |
2.4.0 |
Adds the unit review capability |
20021021:171541 |
ajh |
2.4.1 |
Adds general cooments and review comments sections |
20021022:094714 |
ajh |
2.4.2 |
Add separate create description button |
20021022:120546 |
ajh |
2.4.3 |
Add student authentication and functions |
20021024:151538 |
ajh |
2.4.4 |
Remove multiple update conflict in routine
doReviewSubmit, and document |
20021028:103902 |
ajh |
2.4.5 |
Add link to Review explanations |
20021030:110244 |
ajh |
2.4.6 |
Add field about effect of unit change upon credit
assessments |
20030228:170810 |
ajh |
2.4.7 |
remove -ba flag from sendmail |
20030311:151932 |
ajh |
2.4.8 |
add XMLPAGE to ReviewV1.dtd address |
20030315:170519 |
ajh |
2.5.0 |
Add image buttons to home page, and obsolete Objective
Text field (which gets deleted if it is edited). |
20030324:172248 |
ajh |
2.5.1 |
Restructured editing page to separate version comment
from expert/novice selection. |
20030417:143818 |
ajh |
2.5.2 |
fix bug in email extraction of UnitName and UnitSummary
|
20030430:093852 |
ajh |
2.5.3 |
remove temporary files where possible (mainly in
doUpdate) |
20030430:151559 |
ajh |
2.5.4 |
Added IS classifications to xml2html.xsl (no change to
this file) |
20030515:105345 |
ajh |
2.5.5 |
fixed bug with saving cookie for reentry (must trim
blanks) |
20030515:114212 |
ajh |
2.5.6 |
added Don't Know buttons to review page (not in this
file) |
20030525:163936 |
ajh |
2.6.0 |
First version under xlp, start to add multi-faculty
mechanisms |
20030605:163847 |
ajh |
2.6.1 |
basic multi-faculty mechanisms working |
20030805:092750 |
ajh |
2.6.2 |
add FEC review WP recommendations |
20030806:090112 |
ajh |
2.6.3 |
clean up new format; fix bugs in sanitiseV2
and xml2html |
20030807:095606 |
ajh |
2.6.4 |
add reasons for change |
20030807:161730 |
ajh |
2.6.5 |
revise submission process |
20030811:094615 |
ajh |
2.6.6 |
change approval time stamp to exclude colon |
20030815:141937 |
ajh |
2.6.7 |
updated school approvals and circulation data |
20030826:113513 |
ajh |
2.6.8 |
updated school approvals and circulation data |
20030916:124251 |
ajh |
2.6.9 |
replaced Monash Identity under instruction from Brand
Police |
20030924:134126 |
ajh |
2.6.10 |
allow multiple FEC EOs, separated by commas |
20031009:115201 |
ajh |
2.6.11 |
Fix bug with School information extraction in
grabPersonData |
20031017:083126 |
ajh |
2.6.12 |
Change xsl access through catalog, add changedate,
start altering xml2html.xsl to use streamlined call templates
and add change dates |
20031020:152619 |
ajh |
2.6.13 |
automatically add version history comment about fields
modified |
20031021:170158 |
ajh |
2.6.14 |
fix bug where approved descriptions not getting -A
timestamp |
20031023:113838 |
ajh |
2.6.15 |
Add view date restriction |
20031024:121538 |
ajh |
2.6.16 |
Add approval unit list |
20031125:101329 |
ajh |
2.6.17 |
reply-to field in sent email now points to editor (but
note: it will not work yet for non-infotech users) |
20040319:085013 |
ajh |
2.6.18 |
update date fields in show all descriptions |
20040322:092152 |
ajh |
2.7.0 |
revise approval work flow, add new SHOW APROVALS |
20040516:145812 |
ajh |
2.7.1 |
add button on successful save to view edited unit
(thanks to Shane Moore for this suggestion) |
20040517:114008 |
ajh |
2.7.2 |
Changed SHOW APPROVAL latest save colour to yellow |
20040524:203146 |
ajh |
2.7.3 |
Add compare link to submit mailouts |
20040525:155453 |
ajh |
2.7.4 |
Add student reviews |
20040526:101132 |
ajh |
2.7.5 |
Fix double question mark bug in email message for
doSubmit |
20040526:160202 |
ajh |
2.7.6 |
sort compare list |
20040526:160240 |
ajh |
2.7.7 |
doCompare does not require authentication |
20040531:162734 |
ajh |
2.7.8 |
First working version with student reviews |
20040602:142027 |
ajh |
2.7.9 |
Fix bug with sorted lists of units |
20040611:082134 |
ajh |
2.7.10 |
remove Denise Martin from mailing list, minor edits,
including IT.appr list to remove obsolete school
codes |
20040728:132457 |
ajh |
2.7.11 |
Add MIS to school codes, and change link display in
SHOW descriptions when no previously approved unit. |
20040730:084412 |
ajh |
2.7.12 |
Change Roger Silberberg to Judy Backhouse in SBS list |
20040812:151420 |
ajh |
2.7.13 |
make email subject line consistent with approval |
20040814:172839 |
ajh |
2.7.14 |
add logging of operations |
20040823:095412 |
ajh |
2.8.0 |
add processing of recommended reading field |
20040920:125031 |
ajh |
2.8.1 |
add Geraldine D'Costa to mailing list |
20041015:114520 |
ajh |
2.8.2 |
fix bug that did not escape quotes in Editor name |
20041019:125409 |
ajh |
2.8.3 |
make sure data entered in reviews has ampersands
escaped |
20041026:171548 |
ajh |
2.8.4 |
fixed bug in SHOW descriptions that appended line info from previous line |
20041201:114325 |
ajh |
2.8.5 |
minor changes for migration to faculty server |