<?php if (!defined('PmWiki')) exit(); /* * Fortune - Fortune cookie for PmWiki 2.0 * Copyright 2005-2006 by D.Faure (dfaure@cpan.org) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Adapted to PmWiki from code by Henrik Aasted Sorensen, henrik@aasted.org * Read more at http://www.aasted.org/quote * * See http://www.pmwiki.org/wiki/Cookbook/Fortune for info. */ Markup("fortune", "directives", "/\\(:fortune(\\s+.*)?\\s*:\\)/e", "'<:block>'.Oracle(PSS('$1'))"); function Oracle($opt) { global $FortunesDir; SDV($FortunesDir, dirname(__FILE__) . '/fortunes'); $opt = ParseArgs($opt); $f = new Fortune; $out = ($opt['file']) ? $f->getRandomQuote("$FortunesDir/" . $opt['file'] . ".dat") : $f->quoteFromDir($FortunesDir); $spec = Array("/€/", "/‹/", "/›/", "/Å“/", "/Ÿ/", "/¡/", "/¢/", "/£/", "/¤/", "/Â¥/", "/¦/", "/§/", "/¨/", "/©/", "/ª/", "/«/", "/¬/", "/Â/", "/®/", "/¯/", "/°/", "/±/", "/²/", "/³/", "/´/", "/µ/", "/·/", "/¹/", "/º/", "/»/", "/¿/", "/À/", "/Ã/", "/Â/", "/Ã/", "/Ä/", "/Ã…/", "/Æ/", "/Ç/", "/È/", "/É/", "/Ê/", "/Ë/", "/ÃŒ/", "/Ã/", "/ÃŽ/", "/Ã/", "/Ã/", "/Ñ/", "/Ã’/", "/Ó/", "/Ô/", "/Õ/", "/Ö/", "/×/", "/Ù/", "/Ú/", "/Û/", "/Ü/", "/Ã/", "/à /", "/á/", "/â/", "/ã/", "/ä/", "/Ã¥/", "/æ/", "/ç/", "/è/", "/é/", "/ê/", "/ë/", "/ì/", "/Ã/", "/î/", "/ï/", "/ð/", "/ñ/", "/ò/", "/ó/", "/ô/", "/õ/", "/ö/", "/ø/", "/ù/", "/ú/", "/û/", "/ü/", "/ý/", "/ÿ/", "/</", "/>/"); $rep_pat = Array("€", "<", ">", "œ", "Ÿ", "¡", "¢", "£", "¤", "¥", "¦", "§", "¨", "©", "ª", "«", "¬", "­", "®", "&masr;", "°", "±", "²", "³", "´", "µ", "·", "¹", "º", "»", "¿", "À", "Á", "Â", "Ã", "Ä", "Å", "&Aelig", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î", "Ï", "ð", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö", "×", "Ù", "Ú", "Û", "Ü", "Ý", "à", "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë", "ì", "í", "î", "ï", "ð", "ñ", "ò", "ó", "ô", "õ", "ö", "ø", "ù", "ú", "û", "ü", "ý", "ÿ", "<", ">"); $out = preg_replace($spec, $rep_pat, $out); $out = str_replace("retourligne", "<br>", $out); return Keep("<div id='fortune'>$out</div>"); } class Fortune { /* Main methods to use: quoteFromDir($dir): Quotes from any of the fortune-files in the dir. getRandomQuote($file): Quotes from the specific file. */ function quoteFromDir($dir) { $amount = 0; $index = 0; if ( $handle = opendir($dir) ) { while (false !== ($file = readdir($handle))) { if ( strpos($file, ".dat") != false) { $len = strlen($file); if (substr($file, $len - 4) == ".dat"){ $number = $this->getNumberOfQuotes($dir . "/" . $file); $amount += $number; $quotes[$index] = $amount; $files[$index] = $file; $index++; } } } srand((double)microtime()*1000000); $index = rand(0, $amount); $i = 0; while ($quotes[$i] < $index) { $i++; } return $this->getRandomQuote($dir . "/" . $files[$i]); } return -1; } /* Reads the number of quotes in the file. */ function getNumberOfQuotes($file) { $fd = fopen($file, "rb"); $this->readLong($fd); // Just move over the first long. Might as well be fseek. $len = $this->readLong($fd); fclose($fd); return $len; } /* Picks quote number $index from the dat-file in $file. */ function getExactQuote($file, $index) { if (is_file($file) == FALSE) { echo "Input must be a file!<br/>"; return; } if ( ($fd = fopen($file, "rb")) == FALSE ) { echo "Cannot open $file<br/>"; return; } fseek($fd, 24 + 4 * $index); $phys_index = $this->readLong($fd); fclose($fd); $quotefile = substr($file, 0, strlen($file) - 4); if ( ($fd = fopen($quotefile, "rb")) == FALSE ) { echo "Cannot find file $quotefile!<br/>"; } $res = $this->getQuote($fd, $phys_index); fclose($fd); return $res; } /* Returns a random quote from $file. */ function getRandomQuote($file) { $number = $this->getNumberOfQuotes($file); $index = rand(0, $number - 1); return $this->getExactQuote($file, $index); } /* Reads a quote from the specified index. */ function getQuote($fd, $index) { fseek($fd, $index); $line=""; $res = ""; do { $res = $res . $line; $line = fgets($fd, 1024) . "retourligne"; } while ( ($line[0] != "%") && (!feof($fd)) ); return $res; } /* Gets indexes from the file pointed to by the filedescriptor $fd. */ function getIndices($fd) { fseek($fd, 24, SEEK_SET); $i = 0; while ( feof($fd) == FALSE ) { $res[$i] = readLong($fd); $i++; } return $res; } function readLong($fd) { $res = fread($fd, 4); $l = ord($res[3]); $l += ord($res[2]) << 8; $l += ord($res[1]) << 16; $l += ord($res[0]) << 24; return $l; } function createIndexFile($file) { $fd = @fopen($file, "r"); if ($fd == false) { echo "File error!"; exit; } $i = 1; $length = 0; $longest = 0; $shortest = 100000; $indices[0] = 0; while (!feof($fd)) { $line = fgets($fd); if ($line == "%\n") { $indices[$i] = ftell($fd); $i++; if ($length > $longest) $longest = $length; if ($length < $shortest) $shortest = $length; $length = 0; } else { $length = $length + strlen($line); } } fclose($fd); $fd = @fopen($file . ".dat", "w"); if ($fd == false) { echo "<!-- createIndexFile: Could not write to file....-->"; exit; } // Write header. $this->writeLong($fd, 2); $this->writeLong($fd, count($indices)); $this->writeLong($fd, $longest); $this->writeLong($fd, $shortest); $this->writeLong($fd, 0); $this->writeLong($fd, 37 << 24); for ($i = 0 ; $i < count($indices) ; $i++) { $this->writeLong($fd, $indices[$i]); } fclose($fd); } function writeLong($fd, $l) { fwrite($fd, chr ( ($l >> 24) & 255)); fwrite($fd, chr ( ($l >> 16) & 255)); fwrite($fd, chr ( ($l >> 8) & 255)); fwrite($fd, chr ( $l & 255)); } } // End of class