skweez.net

Heise News Feed Fix 0.4

by elm
19.12.2010

[Update 02.06.2012] Es gibt eine neue Version, ab sofort gibt es das Skript auf Github: https://github.com/elm/heise-rss-fix [/Update]

So, nach langer langer Zeit kommt mal wieder ein Update für mein Heise News Feed Fix Script. Das Script weißt jetzt jedem Artikel eine eindeutige ID zu und aktualisiert Artikel, die ein Update erhalten. Außerdem kann man mit dem Script jetzt mit dem Parameter url verschiedene Feeds der Heiseseite auswerten. Um z.B. den Feed von Heise Open mit Inhalt zu füllen, ruft man http://example.com/feed.php?url=http://www.heise.de/open/news/news-atom.xml auf. Gibt man keine URL an, wird der Hauptfeed von Heise benutzt.

Die Datumskorrektur habe ich wieder ausgebaut, da es nicht mehr so aussieht als ob Heise das Datum der Artikel ändert. Vielleicht liegt dass jetzt auch an der ID, dass das richtig erkannt wird.

Danke auch an Mark, der mich auf einen Bug hingewiesen hat.

<?php
// Heise Feed Version 0.4
header("Content-type: text/xml; charset=UTF-8");
define('CACHEFOLDER','feed');
define('FEEDINTERVAL',600);
define('MAXARTIKELS',100);

$feedUrl = urlencode('http://www.heise.de/newsticker/heise-atom.xml');

if( $_GET["url"] ) {
        $feedUrl = urlencode($_GET["url"]);
}

if( $_GET["do"]=="reload" ) $do_reload = true;
if( $_GET["do"]=="sync" ) $do_sync = true;

# Do not diplay xml errors
libxml_use_internal_errors(true);

function getID($url) {
        preg_match('/-([0-9]+)\.html/', $url, $id);
        return $id[1];
}

function getArtikel($url, $id, $date, $forceReload) {
        if(!$forceReload and file_exists(CACHEFOLDER."/".$date."-".$id.".txt")) {
                $artikelFertig = file_get_contents(CACHEFOLDER."/".$date."-".$id.".txt");
        } else {
                $doc = new DOMDocument();
                $artikel = mb_convert_encoding(file_get_contents($url), 'HTML-ENTITIES', "UTF-8");
                $doc->loadHTML($artikel);
                $divs = $doc->getElementsByTagName('div');

                $artikelFertig = 'Konnte Artikelinhalt nicht finden.';

                $newDoc = new DOMDocument();

                foreach ( $divs as $div ) {
                        if( $div->hasAttribute('class') && $div->getAttribute('class') == 'meldung_wrapper' ) {
                                $newDoc->appendChild($newDoc->importNode($div,true));
                        }
                }
                $artikelFertig = $newDoc->saveHTML();
                $artikelFertig = strip_tags($artikelFertig, '<span><a><pre><b><br><em><ul><li><hr><p><img><strong><table><tbod<><td><tr>');
                $artikelFertig = str_replace("\"/","\"http://www.heise.de/",$artikelFertig);
                $artikelFertig = htmlspecialchars($artikelFertig);

                if(!file_put_contents(CACHEFOLDER."/".$date."-".$id.".txt",$artikelFertig)) die();
        }
        $files = glob(CACHEFOLDER."/*.txt");
        while(count($files) > MAXARTIKELS) {
                unlink($files[2]);
                $files = glob(CACHEFOLDER."/*.txt");
        }
        return $artikelFertig;
}

$cacheFile = CACHEFOLDER."/".$feedUrl.".txt";

if($do_reload or $do_sync or !file_exists($cacheFile) or time() - filemtime($cacheFile) > FEEDINTERVAL) {
        $xml = DOMDocument::load(urldecode($feedUrl));
        $entrys = $xml->getElementsByTagName('entry');

        $xml->getElementsByTagName('link')->item(1)->attributes->item(1)->nodeValue="http://example.com/feed.php";

        for ($i=0; $i < $entrys->length; $i++) {
                $entry = $entrys->item($i);
                $url = str_replace('/from/atom10', '', $entry->getElementsByTagName('id')->item(0)->nodeValue);
                $id = getID($url);
                $date = $entry->getElementsByTagName('updated')->item(0)->nodeValue;

                # Set unique id.
                $entry->getElementsByTagName('id')->item(0)->nodeValue = 'http://www.heise.de/'.$id;

                # Create content element and fill it with content
                $content = $xml->createElement('content');
                $entry->appendChild($content);

                $entry->getElementsByTagName('content')->item(0)->setAttribute('type','html');

                $forceReload = false;
                if($do_reload or preg_match("/update/i",$entry->getElementsByTagName('title')->item(0)->nodeValue)) {
                        $forceReload = true;
                }

                $artikelInhalt = getArtikel($url, $id, $date, $forceReload);
                $entrys->item($i)->getElementsByTagName('content')->item(0)->nodeValue = $artikelInhalt;
        }
        $feed = $xml->saveXML();
        file_put_contents($cacheFile, $feed);
        echo $feed;
} else {
        echo file_get_contents($cacheFile);
}

# Clear xml errors
libxml_clear_errors();
?>