The Fortune Service

Dec 20, 2011 Published by Tony Primerano

I wanted to build a simple module for the AOL AIM Pages site and I wanted to start with something really simple so why not turn the classic Unix fortune program into a service.


At first I figured I would just use an existing service but the only one I could find was written in SOAP and for me to parse that in javascript would take longer than writing a REST service from scratch.

So I dug around some PHP sites (not a language I normally use) and before long I had a simple service..

version 0.1

  • This version supports 4 types of output
    • XML
    • javascript output via document.write
    • javascript with fortune returned in a variable
    • plain HTML output
  • I read the unix.txt (or funny.txt) file and make some changes to support the javascript and XML output. (much of this is probably unnecessary since I am using CDATA)
  • To keep load on the machine low and response time good, I used Richard Heyes' cache code to keep the formatted data in memory.
  • Everytime someone hits the service they get a new fortune.
  • To prevent quotes in the fortunes from messing up my javascript output I urlencoded all the data then had the resulting javascript unencode it when it was finished. There is probably an easier way to do this but I don't really know javascript.

$fileName = "unix.txt";

$category = "";
if (isset($_GET["category"])) 
	$category = $_GET["category"];
switch ($category) {
case "unix":
   $fileName = "unix.txt";
case "funny":
   $fileName = "funny.txt";
case "default":
   $fileName = "unix.txt";

if (!$result = DataCache::Get("test123", $fileName)) {
	$result = array();
	$lines = file($fileName);
	$current = "";

	foreach ($lines as $line_num => $line) {
		if (strcmp(substr($line,0,1),'%') ==0) {
			$result[] = $current;
			$current = "";
		} else {
			// escape &
			$tmp = str_replace("&", " &", substr($line,0, strlen($line)));
			// Preserve spaces 
			$tmp = str_replace("  ", "  ", substr($tmp,0, strlen($tmp)));
			// escape < 
			$tmp = str_replace("<", " <", substr($tmp,0, strlen($tmp)));
			// escape > and replace line feed with br tag
			$tmp = str_replace(">", " >", substr($tmp,0, strlen($tmp)-1)). "<br />";
			// add to current fortune
			$current .= $tmp;
	if (strlen($current) > 0 )
		$result[] = $current;

	DataCache::Put("test123", $fileName, 6, $result);

// Do something useful with $result
srand ((double) microtime() * 1000000);
$randomquote = rand(0,count($result)-1);

$format = "";
if (isset($_GET["format"])) 
   $format = $_GET["format"];

 // prevent caching
header("Cache-Control: no-store");
header("Pragma: no-cache");
header("Expires: Thursday, 05-May-05 05:05:05 GMT");

   switch ($format) {
	   case "js":
 	     header("Content-type: text/plain");
         echo "function fortune() {";
	     echo "document.write(\"<p>\");";
   	     echo "document.write(unescape(\"" . rawurlencode($result[$randomquote]) . "\"));";
	     echo "document.write(\"</p>\");";
	     echo "}";
	   case "jsVar":
 	     header("Content-type: text/plain");
         echo "var fortune=\"" . rawurlencode($result[$randomquote]) . "\";";

	   case "xml":
		   header("Content-type: application/xml; charset=utf-8");
		   echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>";
		   echo "<fortune>";
   		   echo "<![CDATA[" . $result[$randomquote] ."]]>";
		   echo "</fortune>";	

		   header("Content-type: text/html");
		   echo   $result[$randomquote] ;


Output types..

To use the javascript you would src in in your javascript block and then call the fortune function.

On my module manifest uses the jsVar format and looks like this..

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns="" xml:lang="en" lang="en"  >
<head profile="">
 <link href="Fortune.css" id="Fortune-css" rel="stylesheet" type="text/css"/>
<script language="JavaScript1.1" src="" type="text/javascript" ></script>

<!-- defines initFortune() -->
<script language="JavaScript1.1" type="text/javascript" src="Fortune.js">


<body id="Fortune" onload="initFortune()" >
		<h1>Fortune: Version <span>1.0</span></h1>

		<h2>View Interface</h2>
				<div><h3>Random Quotes</h3></div>

<div id="fortuneDiv"> fortune goes here </div>

<p> Fortune/version 0.1 <a href="">
suggestions? </a></p>


		<p>An implementation of Unix fortune</p>
		<p>A simple module to display a fortune</p>
		<p><a href="" rel="license">GNU Lesser </a>.</p>

		<h3>Author Information</h3>
			 <a href="">Tony Primerano</a> - 
			 <a href="">Homepage</a></li>

		<h3>Module Properties</h3>
			<dt>Liquid width module?</dt>
			<dt>Allow multiple module instances on a single page?</dt>

			<dt>Module's default width (in pixels):</dt>
			<dt>Module's minimum width (in pixels, please, see I asked nicely that time):</dt>
			<dd><img alt="fortune cookie" src="Fortune.jpg"/></dd>


initFortune is defined in the Fortune.js file that is delivered with the module. All it does is inject the fortune into the div with the fortuneDiv id.

function initFortune() {

See this module and others on my page

I need to work on the module edit mode so users can select the fortune type. And I also need to look into a way to have different fortunes display on the same page. Just in case 1 fortune isn't enough.  :-)