Robert Rivera October 25, 2006 Section 001 IT 210 Lab 5 - Perl ****Note: This lab write-up is from an old IT 210 lab! It is only here as an example! Purpose: To become familiar with how Perl interacts with different web pages, and to know how its syntax runs. Learn how to upload and store files using more than one programming language, and be able to use Perl to create your buttons. Learn how to mix different programming languages together to accomplish an overall goal. It is important to learn how and where they are executed, either on the server, or on the client, and how permissions need to be set to be able to read or write to a file. Procedures: 1. The Submit document: a. For this lab, it is required that you have a form that submits a first name, last name, email, picture and sound. There also needs to be field checking on the fields, so you won’t put in a blank for the first or last name, and the email. 2. Making the upload .cgi file: a. The file needs to be located on the server, because that is where it is going to loaded from. This file must be placed in the /var/www/html/cgi-bin folder. b. Because the upload file is a perl file, you’ll need to use the #! character to denote that a perl script is about to come. Then after that, you put where your perl code is at, so the server knows where to get it. You also need to declare that you’re going to write to an HTML page, too. c. Now begins the actual coding, telling the server what to do with the information passed in from the query string: i. Using variable names, such as $first, $last, etc., the parameters were accessed from the query string using the command $q->param($firstname);. This code, repeated for the other parameters passed in from the submit form, were retrieve in this way. ii. Then, the first and last name variables had their first letters made into uppercase using the command $first = “\ufirst”; and $last = “\u$last”;. iii. Learning how to open a file from the reference from http://search.cpan.org/src/LDS/CGI.pm-3.17/cgi_docs.html, under the subheading “Creating a new CGI query object,” a section1.txt file was created using the open (FILEHANDLE, “file”) command. It was used in the following way: open(STUDENTS, ">>$dir/$mytext"). The $dir variable has the path to where the file will be written to, and $mytext is the new file name variable. iv. After the file had been opened in append mode (denoted by the two “greater than” signs (“>>”) in the file name), it was ready to receive a new name. The print command was used to print to the file handle, where all of the file data manipulation occurs. In this command, the $first, $last, and the $email variables were passed into the file, along with a \n for a new line at the end. v. Then we close the file using the command close (FILEHANDLE), in this case, it was close (STUDENTS);. d. After this block of code, the pring qq{} command was used to print HTML to the page. The HTML code was placed between the brackets. This denotes to Perl not to execute it as Perl code. However, when you call a variable that was declared in Perl, you can use it to print its data simply by placing it in the HTML section of your code. 3. Making the student.pl file: a. For this file, you have to use the same opening syntax as the upload.pl file. This includes the “she-bang”, perl directory, and the use CGI; command. b. Then a print <<EOF; command was placed in the file. After this command, you can place regular HTML code and it will be executed as HTML. The ending tag for this command is EOF . Javascript from Lab 4 (where it loads the picture and sound) was placed here for a reference for the Perl that will call it later on. Results: Dummy UML – This UML does NOT belong to this lab. It is here only to show you where it should go. This UML Diagram shows how testAjax.htm interacts with time.asp. Within testAjax.htm there is a function that calls time.asp when something is entered in the Name field. It is dynamic, so it updates the time as soon as something is entered right on the spot. 1. Submission page This picture depicts the submission page, with its fields and Submit button. The Student’s name is being enter along with a picture and sound file, as is being shown by the “Choose File” window. The first 3 entries must have at least one character. 2. Input Information Page This page displays the information that was submitted and how it will be used. This page was referenced by the submit button, and executed on the web server. The information was then taken and saved on the web server for future use. 3. Current Student Page This page displays the buttons for each student entered into the text file. Pressing the button will display the student’s picture and sound file there. Each button was generated in Perl, and was loaded with Javascript. Analysis: This lab was more difficult that it would appear to be. Learning how to program in Perl can be challenging, especially if you can only test your code from the server. There were three main methods for debugging the code that you’ve written that I’ve found very useful: a. Use the “perl” command on the virtual server. This allows you to see any compiling errors that you may have in your code. Great for when you’re missing a dumb semicolon. b. Use the Java Script console in Mozilla Firefox. This helps you see what errors are in your code for Java Script. Finding commas and quotes can be hard, so this aides in fixing those little errors. c. Mozilla’s View Source can also help you as far as HTML goes. It displays exactly what the browser sees. So if you see something isn’t right, you can go back and fix it in the code. Learning the syntax wasn’t too difficult, and there were plenty of topics online that helped out on how to program in it. Learning how to set permissions also taught us that only certain people can see certain files, and that most files are set at a high default level. But overall, because Perl is relatively simple to program in, that is, not much code is required for a lot of performance, it is a very useful web programming tool. Conclusion: This lab showed me a lot of how to secure your files on your own server, and how it ran in the background where the user can’t reach it. Permission’s also help secure the file, but can cause unexpected problems if the server needs to access it, and it doesn’t have permission to do so. You can also use a combination of Java Script and Perl to accomplish quite a bit. Perl is a good choice to use if you want to keep your processes on the server side. References: Human Resources: Scott, Michael Moore, Dr. Bailey, Brandon. Additional Resources: Text and/or web tutorials on Perl/CGI.pm http://www.pageresource.com http://www.sitepoint.com/article/uploading-files-cgi-perl/2 (for uploading files) http://search.cpan.org/src/LDS/CGI.pm-3.17/cgi_docs.html (for opening files method) http://proquest.safaribooksonline.com/ (for basic Perl syntax) Equipment and Programs: 1. PC and virtual server 2. Previous lab code (Java Script) 3. Pictures and sounds (of every kind) 4. PHP Designer PE 2007 5. VIM Editor 6. Mozilla Firefox’s Java Console and View Source Editor 7. Perl, installed on the virtual server Appendix: style2.css: #titleContent { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 24px; line-height: 14px; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; color: #cccccc; position:relative; } #contentBlock { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; line-height: 14px; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; color: #cccccc; position:relative; } .labs { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; line-height: 14px; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; color: #cccccc; position:relative; } a { text-decoration: none; color: #cccccc; } index.htm: <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <LINK REL=stylesheet HREF="style.css" TYPE="text/css"> <html> <head> <title> Lab 5 </title> </head> <body> <BODY background="background2.jpg"> <div id="titleContent"> <center>Lab 5</center> <hr /><br /> </div> <div id="contentBlock"> <center> Please select one of the following: </center> <br /> <center> <a href="dataedit.htm">Add a student</a> </center> <center> <a href="index2.htm">Current list of students</a> </center> <br /> <hr> <center> <a href = "../index.htm">Master Page</a> </center> </div> </html> dataedit.htm: <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <LINK REL=stylesheet HREF="style.css" TYPE="text/css"> <html> <head> <title> Lab 5 - Data Edit Form</title> <script language="JavaScript" type="text/javascript"> <!-function checkfield(form) { if (form.firstname.value == "") { alert("Please enter a first name."); form.firstname.focus(); return false; } if (form.lastname.value == "") { alert("Please enter a last name."); form.lastname.focus(); return false; } if (form.email.value == "") { alert("Please enter an email for the student."); form.email.focus(); return false; } return true; } // --> </script> </head> <body> <BODY background="background2.jpg"> <div id="titleContent"> <center>Lab 5</center> <hr /><br /> </div> <!-- first name, last name, email, picture and sound --> <form action = "/cgi-bin/upload.pl" method = "post" enctype = "multipart/form-data" onSubmit = "return checkfield(this);"> <div id="contentBlock"> Please enter the following information. This information will be saved into your student's database. <br /> <br /> <table border="0"> <TR> <TD>Enter Student's First name: </TD> <TD> <input type = "text" name = "firstname" size = "50" /> </TD> </TR> <TR> <TD>Enter Student's Last name: </TD> <TD> <input type = "text" name = "lastname" size = "50" /> </TD> </TR> <TR> <TD>Enter Student's email address:</TD> <TD> <input type = "text" name = "email" size = "50" /> </TD> </TR> <TR> <TD>Student's Picture file:</TD> <TD> <input type = "file" name = "picture" size = "50" /> </TD> </TR> <TR> <TD>Student's Sound file:</TD> <TD> <input type = "file" name="soundfile" size = "50" /> </TD> <tr> <td><input type = "submit" name="Submit" value = "Submit"></TD> </TR> </table> <hr> <a href = "index.htm">Lab 5 Home page</a> </html> Index2.htm: <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html> <head> <LINK REL=stylesheet HREF="style.css" TYPE="text/css"> <title> My first attempt at JavaScript </title> </head> <!--Ok, first create the frames we need to put the information in--> <!--<FRAMESET rows="30%,85%" border="0" framespacing="0" frameborder="0">--> <frameset cols="25%,75%" border="0" framespacing="0" frameborder="0"> <frame src="/cgi-bin/student.pl" name="left" scrolling="auto"> <!--Left side--> <frame src="rightframe.htm" name="right" scrolling="auto"><!--Right side--> </frameset> </html> rightframe.htm: <html> <head> <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <LINK REL=stylesheet HREF="style2.css" TYPE="text/css"> </script> </head> <body> <BODY background="background2.jpg"> <img src="danger.jpg"> <div id="sound"><embed id="sounds" src="lion_roar.wav" autostart="true" loop="false" height="28px"></embed></div> </body> </html> upload.pl: #! /usr/bin/perl -w use warnings; use CGI; #the my operator makes your variables private to your source file. my $q = CGI->new(); print $q->header ("text/html"); #These are the names my $first = $q->param("firstname"); my $last = $q->param("lastname"); my $email = $q->param("email"); my $dir = "/var/www/html/lab5"; my $uploaddir = "/var/www/html/lab5/media"; my $mytext = "section1.txt"; #This will put them to upper case $first = "\u$first"; $last = "\u$last"; #Now to append the new student to the file. open(STUDENTS, ">>$dir/$mytext") || die("The file could not be opened."); print STUDENTS "$last,$first,$email\n"; close(STUDENTS); #Now for the files... #WARNING! When uploading files, you have to use at least 2 variables for one #file: One with the path name striped, and one with the full path. Use the #one with the path named stripped to store an empty file with just the name, #and the other for the actually upload. It needs the full path to know where #the file is at on the client. my $picture = ("$first" . "_" . "$last" . ".jpg"); my $sound = ("$first" . "_" ."$last" . ".wav"); my $upload_picture = $q->param("picture"); my $upload_sound = $q->param("soundfile"); $picture=~ s/.*[\/\\](.*)/$1/; # strip the remote path and keep the filename $sound=~ s/.*[\/\\](.*)/$1/; # strip the remote path and keep the filename #Then we store the files in our lab 5 directory #First, the picture... open(LOCAL, ">$uploaddir/$picture") or die $!; binmode LOCAL; while(<$upload_picture>) { print LOCAL; } close(LOCAL); #And now the sound... open(LOCAL2, ">$uploaddir/$sound") or die $!; binmode LOCAL2; while(<$upload_sound>) { print LOCAL2; } close(LOCAL2); print qq{ <center>Lab 5 Input Form</center> <hr /><br /> The student has been added successfully:<br /> <blockquote> First Name: $first<br /> Last Name: $last<br /> Email: $email.<br /><br /> </blockquote> The files have been uploaded successfully.<br /> <blockquote> Picture file path and name: $upload_picture<br /> Sound file path and name: $upload_sound<br /><br /> Picture saved as: $picture<br /> Sound saved as: $sound<br /> </blockquote> <hr /><br /> <a href = "/lab5/dataedit.htm" target = "_top">Add another student</a> | <a href = "/lab5/index2.htm">Current list of Students</a> }; student.pl: #! /usr/bin/perl -w use warnings; use CGI; #the my operator makes your variables private to your source file. my $q = CGI->new(); print $q->header ("text/html"); print <<EOF; <head> <LINK REL=stylesheet HREF="/lab5/style.css" TYPE="text/css"> <script language="JavaScript"> <!-// Declare my variables var student = null; var img = new Image(); document.close(); function loadpicture(lastname, firstname) { img.onerror = function() { // --if there is no match for it, perform this function top.right.document.images[0].src = "/lab5/" + "danger.jpg"; // --replay default picture wavesource = "/lab5/" + "lion_roar.wav"; // --replay default sound var newwave = top.right.document.getElementById('sound'); // --retreieve the sound id and store in newwave-wavesource = "<embed id='sounds' src='" + wavesource + "' autostart='true' loop='false' height='28px'></embed>"; // --(code above) place the new wave in wavesource with html coding so it can be played-newwave.innerHTML = wavesource; } src = "/lab5/media/" + firstname + "_" + lastname + ".jpg"; // --this code transposes the first and last names wavesource = "/lab5/media/" + firstname + "_" + lastname + ".wav"; // for both pictures and waves-src = src.replace(' ','_'); // --This code places an underscore between the names to match their files-img.onload = function(){ top.right.document.images[0].src = src; var newwave = top.right.document.getElementById('sound'); wavesource = wavesource.replace(' ','_'); wavesource = "<embed id='sounds' src='" + wavesource + "' autostart='true' loop='false' height='28px'></embed>"; newwave.innerHTML = wavesource; } img.src = src; } // --> </script> </head> <body background="/lab5/background2.jpg"> <div id="titleContent"> <center>Lab 5</center> <hr /><br /> </div> EOF my $dir = "/var/www/html/lab5"; my $mytext = "section1.txt"; #Now to read from the file to store the contents in an array. open(STUDENTS, "<$dir/$mytext"); @mySTUDENTS = <STUDENTS>; close(STUDENTS); @mySTUDENTS = sort(@mySTUDENTS); for $ele (@mySTUDENTS){ my @students = split(",", $ele); my $buttons = '<input type="button" value="'. $students[1] . ' ' . $students[0].'" Onclick="loadpicture(\''. $students[0] . '\',\'' . $students[1].'\')">'; print "$buttons<br>\n"; } print qq{ <hr /> <div class="contentBlock"> <a href = "/lab5/index.htm" target = "_top">Lab 5 Home Page</a> </div> </body> </html> };