Inhaltsverzeichnis |
In einem Wiki ist es etwas sehr Feines, dass man PHP-Code auch direkt ausführen lassen kann. Damit wird es möglich eine Wiki-Seite dynamisch mit Inhalt zu füllen. Das Ganze setzt die MediaWiki-Erweiterung runphp voraus. In diesem Code wird die deutsche Seite "Was geschah am XX.Monat" von Wikipedia aufgerufen, eingelesen, bearbeitet und dargestellt. Da ich die Requests an Wikipedia minimieren wollte, ohne den Cache vom Wiki wieder zu aktivieren, habe ich einen eigenen Cache gebastelt. Basiert auf zwei Text-Dateien (time.txt und wikiCache.txt). Die eine speichert die Zeit des letzten Ladens von Wikipedia und die andere den Inhalt der Datei. Solange noch nicht Mitternacht war wird der Inhalt aus dem Cache gelesen und beim ersten Request nach Mitternacht wird die Datei neu von Wikipedia eingelesen und gespeichert.
Natürlich geht das auch über die Wikipedia API nur wollte ich selber etwas basteln. Damit ist man nicht von Änderungen an der API abhängig und lernt gleich noch was über HTTP und dessen Requests ;-)
Alle Codes unterstehen der GNU GPL
Nachdem ihr runphp installiert habt öffnet ihr eine beliebige Seite Eures Wikis, wo ihr den Inhalt angezeigt haben wollt. Klickt als Administrator (SysOp) auf Seite schützen und legt die Rechte zum Bearbeiten auf den Admin fest (nur so läuft runphp, damit besteht zumindest ein minimaler Schutz). Bearbeitet dann die Seite und legt die beiden Tags <runphp> und </runphp> an. Kopiert den untenstehenden Quellcode rein. Viel Spass...
//Setzen der korrekten Zeitzone und Formatierungen setlocale(LC_TIME, "de_DE.ISO8859-1"); date_default_timezone_set('Europe/Zurich'); /* * Einlesen der Text Datei mit dem Zeitstempel der letzten Aktualisierung. * Der Fall, dass die Datei nicht existiert ist nicht tragisch, da dann * die Datei eh neu von Wikipedia geladen wird. Dann wird diese Datei * angelegt. Der Fehler tritt also nur beim ersten Aufruf statt */ $zeit = @file_get_contents($_SERVER['DOCUMENT_ROOT'].'/time.txt'); //Wenn die Seite heute bereits geladen wurde dann aus dem Cache laden if(date('z',$zeit) == date('z',time())){ $dat = file_get_contents($_SERVER['DOCUMENT_ROOT'].'/wikiCache.txt'); //Daten aus dem Cache ausgeben echo $dat; }else{ //String für die Rückgabe von Wikipedia $dat = ''; //Ein paar User-Agents Strings für die Server von Wikipedia ;-) $agents = array( 'Mozilla/5.0 (compatible; Konqueror/3.2; Linux 2.6.2) (KHTML, like Gecko)', 'Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 5.1) Opera 7.04 [de]', 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/523.12.2 (KHTML, like Gecko) Version/3.0.4 Safari/523.12.2', 'Opera/9.10 (Windows NT 5.0; U; de)', 'Mozilla/5.0 (Windows; U; Windows NT 5.0; de-DE; rv:1.6) Gecko/20040206 Firefox/1.0.1', 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506)', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)', 'Lynx/2.8.4rel.1 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/0.9.6c', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; de-AT; rv:1.8.1.2) Gecko/20070222 SeaMonkey/1.1.1', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3', 'Mozilla/5.0 (OS/2; U; Warp 4.5; de; rv:1.8.1.11) Gecko/20071129 PmWFx/2.0.0.11', 'Mozilla/5.0 (OS/2; U; Warp 4.5; de; rv:1.9b3pre) Gecko/2007121420 Firefox/3.0b3pre' ); //Umrühren shuffle($agents); //Socket Verbindung zu Wikipedia öffnen $fp = fsockopen("wikipedia.org", 80, $errno, $errstr, 30); //Variable wo festgehalten wird ob wir uns bereits im interessanten Bereich der Seite befinden $body = false; if (!$fp) { echo "$errstr ($errno)<br />\n"; } else { //Datum für Request formatieren $datum = strftime('%e._%B',time()); //Request zusammensetzen $out = "GET /wiki/".trim($datum)." HTTP/1.1\r\n"; $out .= "Host: de.wikipedia.org\r\n"; //den zufälligen UA einfügen $out .= "User-Agent: {$agents[0]}\r\n"; $out .= "Connection: Close\r\n\r\n"; //Request ausführen fwrite($fp, $out); //Antwort des Servers lesen while (!feof($fp)) { $re = fgets($fp); //ersten Haupttitel suchen if(strpos($re,'<a name="Ereignisse"') !== false){ //Ab jetzt brauchen wir die Daten $body = true; /* * nötig falls man den GANZEN Body auslesen will * dann prüft man oben auf \r\n ,weil gemäss RFC * der Header mit doppelten Zeilenschlag vom * Body abgetrennt sein muss. Das bedeutet, dass * $re == \r\n sein muss und mit der nächsten Zeile * der Body beginnt. continue ist drin damit die Zeile * mit \r\n NICHT angehängt wird */ //continue; } //Wenn im Body dann anhängen if($body === true){ $dat .= $re; } } //Socketverbindung schliessen fclose($fp); } /* * hier wird der Body gesäubert und angepasst: * Doppelte Zeilenenden oder Leerzeichen werden reduziert. * Nicht erwünschte Links und Titel werden entfernt * Relative Links innerhalb von Wikipedia werden zu absoluten inkl Domain ergänzt. * Diverse HTML werden entfernt * Der Haupttitel der Seite wird mit dem Datum ergänzt */ $dat = preg_replace(array( '/\r\n{2,}|\n{2,}|\r{2,}/','/\s{2,}/', '/\[<a.*<\/a>\]/iUs', '/<a name=".*"><\/a>/iUs', '/<h5>Ansichten<\/h5>.*/is' ), array("",' ','',''), $dat ); $dat = str_replace(array( 'href="/', "<p><br /></p>" ), array('href="http://de.wikipedia.org/',''), $dat ); $dat = strip_tags($dat,'<a>,<ul>,<li>,<img>,<h1>,<h2>,<h3>,<h4>,<h5>,<h6>,<h7>,<br>,<br />,<p>'); $dat = str_replace('Ereignisse</h2>','Ereignisse am '.str_replace('_',' ',$datum).'</h2>',$dat); //Datei für Cache öffnen resp anlegen und Daten reinschreiben $fp = fopen($_SERVER['DOCUMENT_ROOT'].'/wikiCache.txt','w'); fwrite($fp,$dat); fclose($fp); //Datei für Zeitstempel öffnen resp anlegen und mit aktuellem Zeitstempel speichern $fp = fopen($_SERVER['DOCUMENT_ROOT'].'/time.txt','w'); fwrite($fp,time()); fclose($fp); //Alles ausgeben echo $dat; } ?>