title = $title; $this->description = $description; $this->url = $url; $this->category = $category; $this->authoremail = $authoremail; $this->authorname = $authorname; $this->pubdate = $pubdate; $this->datemodified = $datemodified; $this->guid = $guid; $this->timestamp = $timestamp; //atom-only $this->relatedlink = $this->relatedlink; $this->relatedlinktitle = $this->relatedlinktitle; $this->via = $this->via; $this->viaurl = $this->viaurl; }//end update } function clean($input, $maxlength) { //makes user input safe for processing $input = substr($input, 0, $maxlength); $input = EscapeShellCmd($input); return ($input); } function ifd02unixdate($timestamp) { // translates a ifd0 timestamp into a unix timestamp // e.g. 2004:12:30 15:41:23 becomes like 1104446760 // replace the space so it can implode into an array $timestamp = str_replace(" ",":",$timestamp); $time = explode(":",$timestamp); $unixtime = mktime($time[3],$time[4],$time[5],$time[1],$time[2],$time[0]); return $unixtime; } function MakeRSSDate($date,$timezone) { /* translates date from unix timestamp to valid rss format "1098861960" becomes like "Wed, 27 Oct 2004 00:26:00 PST" */ //date comes in as unix time stamp $rssdate = date('D, d M Y H:i:s', trim($date)); $rssdate = trim($rssdate . " " . $timezone); return $rssdate; } function MakeAtomDate($date,$timezone) { /* translates date from unix timestamp to valid Atom date format "1098861960" becomes like "2004-05-27T03:48:48-05:00" * * $date is unix timestamp * $timezone is like "-5:00" * output must be like "2002-10-02T10:00:00" or "2002-10-02T10:00:00-05:00" */ //date comes in as unix time stamp $atomdate = date('Y-m-d\TH:i:s',$date); $atomdate = trim($atomdate . strval($timezone)); return $atomdate; } function ResizeImage($file) { // adapted from http://www.jetevents.pl's script // posted to http://us3.php.net/manual/en/function.imagecreatefromjpeg.php // input: // str $file = full system path to file (e.g., /home/username/htdocs/some/subfolder/mypic.jpg) // returns: str path to resized thumbnail pic $maxx=100; // maximum width $maxy=75; // maximum height // name of file - must be jpg $size = getimagesize ($file); // params of image if ($size[0]>$size[1]) {$sizemin[0]=$maxx;$sizemin[1]=$maxy;}; if ($size[1]>$size[0]) {$sizemin[0]=$maxy;$sizemin[1]=$maxx;}; //ADM additions $newpath = $file . ASIF_SUFFIX; // // create the thumbnail, unless it already exists. if (!is_file($newpath)) { $im=@imagecreatefromjpeg($file); // incoming image $small = imagecreatetruecolor($sizemin[0], $sizemin[1]); // new image ImageCopyResampled($small, $im, 0, 0, 0, 0, $sizemin[0], $sizemin[1], $size[0], $size[1]); // below is main function resampling image ImageDestroy($im); // free memory if (ImageJPEG($small,$newpath,100)) // try to save image { //echo "File $newpath has been written
\n"; // success } else { // failed to write file echo "Error ! File has not been written."; }; }//end if tn exists return $newpath; } function PrepareItems($pictures,$thumbnails,$alldata) { /* * arr $pictures: an array of Picture objects * str $alldata: whether to include all available exif data. * str $thumbnails: whether to include links to thumbnail images in output * * Function translates Picture objects into XMLItem objects. * */ foreach ($pictures as $pic) { $item = new XMLItem; $title = $pic->filename; //if "taken" date is available, use it. //otherwise, use file creation date. if ($pic->exif["IFD0"]["DateTime"]) { $timestamp = ifd02unixdate($pic->exif["IFD0"]["DateTime"]); } else { $timestamp = $pic->exif["FILE"]["FileDateTime"]; } $pubdate = MakeRSSDate($timestamp,ASIF_TIMEZONE_ENGLISH); $url = $pic->filepath; //change these two values to suit your needs. $category = "photos"; $authoremail = "spam@" . $_ENV['HTTP_HOST']; $authorname = "Asif, the thousand robots exif processor"; $guid = $pic->filepath . "#" . $timestamp; if ($alldata=="yes") { foreach ($pic->exif as $key => $section) { foreach ($section as $name => $val) { $allexif .= "$name: " . substr($val,0,ASIF_MAX_EXIF_LENGTH) . " \n | "; } } /* * if you have "$alldata" set to yes, you may get * crazily encoded stuff back. this attempts to deal with some of it. * need a better way to escape unknown characters, or maybe one of the * settings at http://tinyurl.com/4ooch would work. */ $description = utf8_encode($allexif); unset($allexif); } //end if all data else { // better way to do this? $description = "Taken: " . $pic->exif["IFD0"]["DateTime"] . " | \n" . "Comment: " . $pic->exif["COMPUTED"]["UserComment"] . " | \n" . "Filesize: " . round(intval($pic->exif["FILE"]["FileSize"])/1024,0) . "kb" . " | \n" . "Height: " . $pic->exif["COMPUTED"]["Height"] . " | \n" . "Width: " . $pic->exif["COMPUTED"]["Width"] . " | \n" . "F-stop: " . $pic->exif["COMPUTED"]["ApertureFNumber"] . " | \n" . "Camera: " . $pic->exif["IFD0"]["Make"] . " " . $pic->exif["IFD0"]["Model"] . " | \n" . "ISO: " . $pic->exif["EXIF"]["ISOSpeedRatings"]. " | \n" . "Flash: " . $pic->exif["EXIF"]["Flash"]. " | \n" . "Focal Length: " . $pic->exif["EXIF"]["FocalLength"]; } //add img tag and link to thumbnail image if necessary if ($thumbnails=="yes") $description = "filepath\">filepath . ASIF_SUFFIX . "\" alt=\"$title\" class=\"asifphoto\" />\n | " . $description; $item->update($title,$description,$url,$category,$authoremail,$authorname,$pubdate,$datemodified,$guid,$timestamp,$relatedlink,$relatedlinktitle,$via,$viaurl); //add to the array of items $items[]=$item; } //end foreach return $items; } function PrepareMetaData($format) { $metadata["commenttext"] = "Produced by Asif, the Thousand Robots EXIF processor. See thousandrobots.com/projects/asif/ for more info. \n This document is rendered in $format and is available in HTML, RSS, or Atom. For info on RSS and Atom, see bloglines.com. \n \n-ADM"; $metadata["feedtitle"] = "Photos and EXIF data from " . $_ENV['HTTP_HOST']; $metadata["feedurl"] = $_SERVER["SCRIPT_URI"]; $metadata["feedtagline"] = "EXIF data (like image size, date, and user comments) can be stored along with digital photos. This document contains that data."; $metadata["feedauthorname"] = "spam@" . $_ENV['SERVER_NAME']; $metadata["feedid"] = "tag:" . $_ENV['HTTP_HOST'] . ",2004-12-29:/exif"; $metadata["timezone_numeric"] = ASIF_TIMEZONE_NUMERIC; $metadata["timezone_english"] = ASIF_TIMEZONE_ENGLISH; return $metadata; } function BuildRSSFeed($commenttext,$channeltitle,$channelurl,$channeldescription,$editor,$timezone,$arrItems) { /* * This function is a generic RSS feed assembler. Pass in the values for the feed * and an array filled with Item objects, and it will return a valid RSS 2.0 feed. * * it sets the channel buildtime to whatever the current time is. timezone is passed * into this function by whatever function calls it. * * note the construction of the element. it adds an author email and name. * Email addresses are necessary for valid RSS 2.0. * * */ // contains the text used in the first part of the rss output $buildtime = MakeRSSDate(time(),$timezone); $header =""; $header .= " \n $channeltitle $channelurl $channeldescription en-us see " . $_ENV['HTTP_HOST'] . " for copyright info http://backend.userland.com/rss thousandrobots.com rss generator $editor $editor $buildtime "; //build the item string if (!empty($arrItems)) { foreach ($arrItems as $item) { $data .= "\n\n" . "$item->title\n" . "description]]>\n" . "$item->url\n" . "$item->authoremail ($item->authorname)\n" . "$item->pubdate\n" . "$item->category\n" . "$item->guid\n" . "\n"; } }//end if not empty $footer = "\n"; $rss = trim($header . $data . $footer); return $rss; } function BuildAtomFeed($commenttext,$feedtitle,$alturl,$feedtagline,$feedid,$feedauthorname,$timezone,$arrEntries) { // Generic Atom feed builder. Re-use for anything. // Just pass it an array full of objects ($arrEntries)to build into the feed. // Feed will validate as long as the stuff you pass into it is valid. $buildtime = MakeAtomDate(time(),$timezone); $header =""; $header .= "" . " $feedtitle $feedtagline $feedid see " . $_ENV['HTTP_HOST'] . " for copyright info $buildtime $feedauthorname "; //build the item string if (!empty($arrEntries)) { foreach ($arrEntries as $entry) { $pubdate = MakeAtomDate($entry->timestamp,$timezone); $data .= "\n\n" . "$entry->title\n" . "url\" />\n" . "$pubdate\n" . //should have a separate modified date, but whatever. "$pubdate\n" . "$entry->guid\n" . "description]]>\n"; if ($entry->relatedlink) $data .= "relatedlink\" title=\"$entry->relatedlinktitle\" />\n"; if ($entry->via) $data .= "viaurl\" title=\"$entry->via\" />\n"; $data .= "\n"; }//end foreach }//end if not empty $footer = ""; $atom = trim($header . $data . $footer); return $atom; } function BuildHTML($commenttext,$feedtitle,$channelurl,$feeddescription,$editor,$timezone,$items,$thumbnails) { //outputs the items as html. //note the link to the stylesheet, and the classes on all the divs, etc. $html = ' ' . "\n\n \n \n $feedtitle\n \n \n
\n

$feedtitle

\n

$feeddescription

\n
"; foreach ($items as $item) { //turn the description back into an array so it can be output on separate lines. $description = explode(" | ",$item->description); $itemlist .= "
\n

$item->title

\n"; $itemlist.= "

url\">view
"; //split the description into separate lines foreach ($description as $field) { $itemlist .= $field . "
\n"; } $itemlist .= "

\n
\n"; }//end foreach $html .= $itemlist . "
\n\n"; return $html; }//end function function ProcessFiles($directory,$thumbnails) { /* * str $directory: the directory to process * bool $thumbnails: whether thumbnails should be generated */ // comment out the next two statements if you want to permit access to // files "above" the directory where the script resides. This is NOT recommended. // You should adjust your openbasedir setting in php.ini instead so you aren't vulnerable. if (strpos($directory,"/")===0) die ("Access to that directory not allowed"); if (strpos($directory,".")===0) die ("Access to that directory not allowed"); //if no dir specified, set to dir where script resides if (!$directory) $directory = "."; $realpath = realpath($directory); //make sure the directory exists if (!is_dir($directory)) die("No directory at $directory."); //the next statement requires PHP5. //See below for PHP4 equivalent. $files = scandir($realpath); /* PHP4 rough equivalent to scandir. (Untested) code from: http://tinyurl.com/5ovps $dh = opendir($realpath); while (false !== ($filename = readdir($dh))) { $files[] = $filename; } */ if (!is_array($files)) { $error = "No files to process in this directory."; die ($error); } foreach ($files as $file) { //check if it's a file and a jpeg $realfile = $realpath . "/" . $file; if (is_file($realfile) && (exif_imagetype($realfile)==2) && (strpos($realfile,ASIF_SUFFIX)===false)) { $exif = exif_read_data($realfile, 0, true); $pic = new Picture(); //edit the path so it renders into a proper url when appended to the domain name. //yuck -- got to be a better way to do this if ($directory===".") { $htmldirectory = "/"; } else { $htmldirectory = "/" . $directory . "/"; } $pic->filename = $file; $pic->filepath = dirname($_SERVER["SCRIPT_URI"]) . $htmldirectory . $file; $pic->exif = $exif; $pictures[] = $pic; //create thumbnails if necessary if ($thumbnails == "yes") ResizeImage($realfile); } //end if jpegs }//end foreach file if (is_array($pictures)) {return $pictures;} else { $error = "No images to process in this directory."; die ($error); } }//end function $photos = ProcessFiles(clean($_GET["directory"],ASIF_PATH_LENGTH_LIMIT),clean($_GET["thumbnails"],3)); switch (clean($_GET["format"],4)) { case "rss": $feeditems = PrepareItems($photos,clean($_GET["thumbnails"],3),clean($_GET["alldata"],3)); $feeddata = PrepareMetaData("RSS"); $output = BuildRSSFeed ( $feeddata["commenttext"], $feeddata["feedtitle"], $feeddata["feedurl"], $feeddata["feedtagline"], $feeddata["feedauthorname"], ASIF_TIMEZONE_ENGLISH, $feeditems ); header('Content-Type: text/xml'); echo $output; break; case "atom": $feeditems = PrepareItems($photos,clean($_GET["thumbnails"],3),clean($_GET["alldata"],3)); $feeddata = PrepareMetaData("Atom"); $output = BuildAtomFeed ( $feeddata["commenttext"], $feeddata["feedtitle"], $feeddata["feedurl"], $feeddata["feedtagline"], $feeddata["feedid"], $feeddata["feedauthorname"], ASIF_TIMEZONE_NUMERIC, $feeditems ); header('Content-Type: text/xml'); echo $output; break; default: //output as HTML $feeditems = PrepareItems($photos,clean($_GET["thumbnails"],3),clean($_GET["alldata"],3)); $feeddata = PrepareMetaData("html"); $output = BuildHTML ( $feeddata["commenttext"], $feeddata["feedtitle"], $feeddata["feedurl"], $feeddata["feedtagline"], $feeddata["feedauthorname"], ASIF_TIMEZONE_ENGLISH, $feeditems, clean($_GET["thumbnails"],3) ); echo $output; } ?>