Introduction To Computational Media on the Web (ICM-W) : Week 12

Additional Topics

Processing and Processing.js

Processing.org
Learning Processing
ICM
Processing.js

cron

cron is a scheduler for *nix that can run command line applications.

One way to create a cron entry, is to create a text file with a particular syntax:
MAILTO="youremail@yourhost.com"
* * * * * php application.php 1>>output.log 2>>error.log
Of course, you should replace the "youremail@yourhost.com" with your email address and replace "application.php" with the path to your script and replace "output.log" and "error.log" with the path to the files that you want to log to.

The *'s indicate the positions of time increments and * itself means every one.

The first entry is minute, followed by hour, day of month, month of year and day of week

From Wikipedia: http://en.wikipedia.org/wiki/Cron
.---------------- minute (0 - 59) 
|  .------------- hour (0 - 23)
|  |  .---------- day of month (1 - 31)
|  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ... 
|  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)  OR sun,mon,tue,wed,thu,fri,sat 
|  |  |  |  |
*  *  *  *  *  command to be executed


Here is a more functional example:
MAILTO="Shawn.Van.Every@nyu.edu"
0 12 15 * * php /home/sve204/myphpscript.php 1>>/home/sve204/myphpscript_output.log 2>>/home/sve204/myphpscript_error.log
The above example will run at 12 noon on the 15th day of every month.

To install this into your "crontab" you should save it as a plain text file and upload it to the server.

After it is uploaded, you need to log into the server with SSH and issue the following command:
crontab nameoffile.txt

cron with a PHP script

When a PHP script is run with cron as opposed to with a webserver, you need to make sure you do a couple of things.

The first is that you should use a #!/path/to/php on the first line. This tells the server that it is a PHP script as the server doesn't pay attention to the extension the way a webserver does. (It also allows you to do away with the "php application.php" technique of running the script and just put the actual path and script name in your crontab.)

http://en.wikipedia.org/wiki/Shebang_(Unix)

The other thing you need to do is make sure your PHP script is executable. Meaning that the server doesn't treat it like a normal text file but rather as an executable script. The easiest way to do this is "Get information" in Fetch and select the "Execute" permission on the file for your user.

Last, you should probably make it run in "quiet" mode so that it doesn't output HTTP headers that will make your log files messy: #!/usr/bin/php -q

Here is an example which periodically does a Twitter search and logs the data to a file:
		
!#/usr/bin/php -q
entry); $i++)
	{
		$current_entry = $twitterxml->entry[$i];
		$titles[$i] = $current_entry->title;
	}
	
	file_write_contents("/home/sve204/twitter_shebang.txt",$titles,FILE_APPEND);	
?>
To run this via cron, 1 time per hour, I would save it as "hit_twitter.php", upload it to the server, make it executable and then prepare the crontab file like this:
MAILTO="Shawn.Van.Every@nyu.edu"
30 * * * * php /home/sve204/hit_twitter.php 1>>/home/sve204/hit_twitter_log.txt 2>>/home/sve204/hit_twitter_error_log.txt

Media Uploading

Browsers generally allow a file to be uploaded to a server through a special type of form. Below is an example (called file_upload.php):
<html>
	<head>
		<title>Upload</title>
	</head>
	
	<body>
		<h1>File Upload Test</h1>
<?

	ini_set('display_errors', true);
	ini_set('display_startup_errors', true);
	// You could also log them:
	//ini_set('log_errors', true);
	//ini_set('error_log', '/home/netid/php_errors.log');
	error_reporting(E_ALL);

	// Extra Database connect function
	$mySql = null;
	function sqlConnect() {
		# Configuration Variables
		$hostname = "xxxx";
		$dbname = "xxxx";
		$username = "xxxx";
		$password = "xxxx";
		
		$mySql = mysql_connect($hostname, $username, $password) or die (mysql_error());
		mysql_select_db($dbname, $mySql) or die(mysql_error());
		
		return $mySql;
	}

	// Limit what people can upload for security reasons
	$allowed_mime_types = array("video/3gpp"=>"3gp", 
								"audio/x-wav"=>"wav", 
								"video/mp4"=>"mp4",
								"video/3gpp2"=>"3g2",
								"video/mpeg"=>"mpg",
								"video/quicktime"=>"mov",
								"video/x-quicktime"=>"mov",
								"video/x-msvideo"=>"avi",
								"image/jpg"=>"jpg",
								"image/jpeg"=>"jpg",
								"image/pjpeg"=>"jpg",
								"image/png"=>"png",
								"audio/vnd.wave"=>"wav"
								);

	// Make sure form was submitted
	if (isset($_POST['form_submitted']) && $_POST['form_submitted'] == "true")
	{
		// Check the mime type
		$allowed_types = array_keys($allowed_mime_types);
		$allowed = false;
		if (isset($_FILES['bytes']['type']))
		{		
			for ($i = 0; $i < sizeof($allowed_types) && !$allowed; $i++)
			{
				if (strstr($_FILES['bytes']['type'], $allowed_types[$i]))
				{
					$allowed = true;
				}
			}
		
			// If the mime type is good, save it..
			if ($allowed)
			{
				$uploadfilename = time() . "_" . rand(1000,9999) . "_" . basename($_FILES['bytes']['name']);
				// Make sure apache can write to this folder
				$uploaddir = '/home/sve204/public_html/uploads/';
				$uploadfile = $uploaddir . $uploadfilename;
				$uploadrelativefile = 'http://itp.nyu.edu/~sve204/uploads/' . $uploadfilename;
		
				if (move_uploaded_file($_FILES['bytes']['tmp_name'], $uploadfile))
				{
					// Make sure the file isn't executable and you can delete it if you need
					chmod($uploadfile, 0666);
					
					// Put it in the database
					/* Database Table:
						file_uploads
						file_id int(11) auto_increment
						file varchar(255)
						other text
					*/
					
					$other = "";
					if (isset($_POST['subject']))
					{
						$other = $_POST['other'];
					}
										
					// Connect to the database
					$mySql = sqlConnect();
										
					// Insert Data
					$query = "insert into file_uploads (file, other) values ('" . $uploadfilename . "', '" . $other . "')";
					$result = mysql_query($query, $mySql);
					
					// Disconnect from the database
					mysql_close($mySql);					
					
					// Tell the user
					echo "<p>Success <br /> <a href=\"" . $uploadrelativefile  . "\">" . $uploadrelativefile . "</a></p>";
				}
				else
				{
					echo "<p>Error on upload...!  Here is some debugging info:</p>";
					var_dump($_FILES);
				}
			}
			else
			{
				echo "<p>Type not allowed...! Here is some debugging info:</p>";
				var_dump($_FILES);
			}
		}
		else
		{
			echo "<p>Strange, file type not sent by browser...!  Here is some debugging info:</p>";
			var_dump($_FILES);
		}
	}
	else
	{
?>
		<form enctype="multipart/form-data" method="post" action="file_upload.php">
			<p>
				Other: <input type="text" name="other" /><br />
				<input type="file" name="bytes" />
				<input type="hidden" name="form_submitted" value="true" />
				<br />
				<input type="submit" name="submit" value="submit" />
			</p>
		</form>
<?
	}
?>
	</body>
</html>


More information:
PHP - Upload Script Security

Tagging and Rating

Tagging and rating are similar operations that allow users to add additional metadata to individual pieces of information that may exist in a database.

For this example we'll create a system that allows us to tag and rate files that have been uploaded in the file upload example above.

First we'll create a table that holds the tags:
file_upload_tags:
tag_id int(11) primary_key auto_increment
tag text
Then we'll create a table that holds the tag to file mapping:
file_upload_tag_map:
tag_id int(11)
file_id int(11)
We'll do something similar for the ratings:
file_upload_ratings:
rating int(11)
file_id int(11)
ts timestamp current_timestamp
Now we need to create a page which lists the files that have been uploaded and allows them to be rated:
file_upload_list.php:
<?

	ini_set('display_errors', true);
	ini_set('display_startup_errors', true);
	// You could also log them:
	//ini_set('log_errors', true);
	//ini_set('error_log', '/home/netid/php_errors.log');
	error_reporting(E_ALL);

	// Extra Database connect function
	$mySql = null;
	function sqlConnect() {
		# Configuration Variables
		$hostname = "localhost";
		$dbname = "xxxx";
		$username = "xxxx";
		$password = "xxxx";
		
		$mySql = mysql_connect($hostname, $username, $password) or die (mysql_error());
		mysql_select_db($dbname, $mySql) or die(mysql_error());
		
		return $mySql;
	}

	/* Database Table:
		file_uploads
		file_id int(11) auto_increment
		file varchar(255)
		other text
	*/
											
	// Connect to the database
	$mySql = sqlConnect();
						
	$query = "select file_id, file, other from file_uploads";					
	$result = mysql_query($query, $mySql);					
?>
<html>
	<head>
		<title>Upload List</title>
	</head>
	
	<body>
		<h1>File Upload List</h1>
		<?
			while ($row = mysql_fetch_array($result))
			{
				$rating_query = "select avg(rating) from file_upload_ratings where file_id = " . $row['file_id'];					
				$rating_result = mysql_query($rating_query, $mySql);
				if ($rating_row = mysql_fetch_array($rating_result))
				{
					echo("Rating: " . $rating_row['avgrating']);
				}
		?>
				<img src="http://itp.nyu.edu/~sve204/uploads/<?=$row['file']?>" />
				
			<?
				$tag_query = "select tag from file_upload_tags fut, file_upload_tag_map futm where futm.tag_id = fut.tag_id and futm.file_id = " . $row['file_id'];
				$tag_result = mysql_query($tag_query, $mySql);
				while ($tag_row = mysql_fetch_array($tag_result))
				{
			?>
					<?=$tag_row['tag']?> 
			
			<?
				}
			?>
			
				<form action="file_upload_tag_rate.php" method="GET">
					<input type="hidden" name="file_id" value="" />				
					Tag: <input type="text" name="tag" /><br />
					Rating: 1:<input type="radio" name="rating" value="1" />
					2:<input type="radio" name="rating" value="2" />
					3:<input type="radio" name="rating" value="3" /><br />
					<input type="submit" name="submit" value="Submit" />
				</form>
				<br /><br />				
		<?
			}
		?>			
	</body>
</html>
Finally the file_upload_tag_rate.php file:
<html>
	<head>
		<title>File Upload Tag/Rating</title>
	</head>
	
	<body>
		<h1>File Upload Tag/Rating</h1>
<?
	// Extra Database connect function
	$mySql = null;
	function sqlConnect() {
		# Configuration Variables
		$hostname = "localhost";
		$dbname = "xxxx";
		$username = "xxxx";
		$password = "xxxx";
		
		$mySql = mysql_connect($hostname, $username, $password) or die (mysql_error());
		mysql_select_db($dbname, $mySql) or die(mysql_error());
		
		return $mySql;
	}

/*
	<form action="file_upload_tag_rate.php" method="GET">
		<input type="hidden" name="file_id" value="<?=$row['file_id']?>" />
		Tag: <input type="text" name="tag" /><br />
		Rating: 1:<input type="radio" name="rating" value="1" />
		2:<input type="radio" name="rating" value="2" />
		3:<input type="radio" name="rating" value="3" /><br />
		<input type="submit" name="submit" value="Submit" />
	</form>
*/

	if (isset($_GET['file_id']) && isset($_GET['tag']) && isset($_GET['rating']))
	{
		// Connect to the database
		$mySql = sqlConnect();
						
		// Insert Rating Data
		$query = "insert into file_upload_ratings (file_id, rating) values (" . $_GET['file_id'] . ", " . $_GET['rating'] . ")";
		$result = mysql_query($query, $mySql);
		
		// See if tag is already in table
		$query = "select tag_id from file_upload_tags where tag = '" . $_GET['tag'] . "'";
		$result = mysql_query($query, $mySql);
		
		// If so, get the id
		if ($row = mysql_fetch_array($result))
		{
			$tag_id = $row['tag_id'];
		}
		else
		{
			// If not, insert it
			$query = "insert into file_upload_tags (tag) values ('" . $_GET['tag'] . "')";
			$result = mysql_query($query, $mySql);
			// Get the new id
			$tag_id = mysql_insert_id($mySql);
		}

		// Insert the tag id into the map table
		$query = "insert into file_upload_tag_map (file_id, tag_id) values (" . $_GET['file_id'] . ", " . $tag_id . ")";
		$result = mysql_query($query,$mySql);

		echo("Good");
	}
	else
	{
		echo("Problem");
	}
?>
	</body>
</html>

Physical Object to JSSerial to PHP and back

Example