Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: PHP: RSS-syöte Ohjelmointiputkan viesteistä

Sivun loppuun

Metabolix [15.09.2009 22:43:24]

#

RSS on yksinkertainen XML-formaatti, joka on tarkoitettu usein päivittyvien tietojen kuten uutisten välittämiseen. Monissa selaimissa on tuki tai lisäosa RSS-syötteiden lukemista varten, tai siihen voi käyttää jotakin erillistä ohjelmaa.

RSS-syöte sisältää yleensä ainakin sivuston nimen, linkin sivustolle sekä uutisten otsikot ja linkit pidempiin teksteihin. Monia muitakin tietoja voi antaa; esimerkiksi seuraavassa syötteessä uutisilla on lisäksi kategoria.

<?xml version='1.0' encoding='ISO-8859-1'?>
<rss version='2.0' xmlns:atom='http://www.w3.org/2005/Atom'>
<channel>
	<atom:link href='http://oma.sivu.fi/uutiset.rss' rel='self' type='application/rss+xml' />
	<title>Oman Sivun uutiset</title>
	<link>http://oma.sivu.fi/</link>
	<description>Oman sivun uusimmat uutiset.</description>
	<language>fi</language>
	<ttl>5</ttl>
	<item>
		<title>Oma sivu uudistuu!</title>
		<category>Sivuston kehitys</category>
		<link>http://oma.sivu.fi/uutiset.php?id=2</link>
		<guid>http://oma.sivu.fi/uutiset.php?id=2</guid>
	</item>
	<item>
		<title>Oma sivu avattu!</title>
		<category>Sivuston kehitys</category>
		<link>http://oma.sivu.fi/uutiset.php?id=1</link>
		<guid>http://oma.sivu.fi/uutiset.php?id=1</guid>
	</item>
</channel>
</rss>

Yleensä syöte tehdään oman sivuston sisällöstä, mutta koska Ohjelmointiputkassa ei ainakaan vielä ole RSS-syötettä, seuraava PHP-skripti hakee Ohjelmointiputkan keskustelun uusimmat viestit ja luo niistä RSS-syötteen. Koodi yksinkertaistuu huomattavasti, jos tietoja ei tarvitse hakea toiselta palvelimelta.

<?php
// Ilmoitetaan, että kyseessä on RSS-data.
// Merkistö on sama kuin Ohjelmointiputkassa, jottei dataa tarvitse skriptissä muuttaa.
header("Content-Type: application/rss+xml; charset=UTF-8");

// Tallennetaan data väliaikaistiedostoon, päivitetään enintään 5 minuutin välein.
$datafile = "keskustelu.rss.tmp";
$ttl_min = 5;

// Jos tiedosto on riittävän tuore, luetaan data suoraan sieltä.
if (file_exists($datafile) && filemtime($datafile) >= time() - $ttl_min * 60) {
	readfile($datafile);
	die();
}

// Haetaan uudet viestit Ohjelmointiputkasta.
$data = file_get_contents("https://www.ohjelmointiputka.net/keskustelu/uudet.php");

// Jos meni pieleen, tulostetaan vanha tiedosto.
if (!$data || !strpos($data, 'Uudet viestit')) {
	readfile($datafile);
	die();
}

// Puskuroidaan tuloste, jotta saadaan se lopuksi koottua tiedostoon.
ob_start();

// Ensin tulostetaan RSS-tiedoston vakio-osa.
// XML-prologi:
echo "<?xml version='1.0' encoding='UTF-8'?>\n";
// RSS-elementti versiotietoineen:
echo "<rss version='2.0' xmlns:atom='http://www.w3.org/2005/Atom'>\n";
// Syötekanava: viittaus kanavaan itseensä, kanavan nimi, kuvaus, kieli ja linkki.
$url = htmlspecialchars("http://{$_SERVER["HTTP_HOST"]}{$_SERVER["SCRIPT_NAME"]}");
echo "<channel>\n";
echo "\t<atom:link href='{$url}' rel='self' type='application/rss+xml' />\n";
echo "\t<title>Ohjelmointiputka: Keskustelu</title>\n";
echo "\t<description>Ohjelmointiputkan keskustelun uusimmat viestit.</description>\n";
echo "\t<language>fi</language>\n";
echo "\t<link>https://www.ohjelmointiputka.net/keskustelu/</link>\n";

// Tulostetaan ttl-arvo eli se, kuinka usein selaimen pitäisi päivittää.
echo "\t<ttl>", $ttl_min, "</ttl>\n";

// Haetaan sivulta taulukon rivit.
$data = substr($data, strrpos($data, '<div id="sisalto">'));
$data = substr($data, 0, strrpos($data, '</div>'));
$data = substr($data, strpos($data, '</tr>'));

// Poimitaan sisällöstä taulukon solut.
preg_match_all('#\\<td\\>(.*?)\\</td\\>#', $data, $m);
unset($data);

// Jaetaan solut kolmen ryhmiin, ohitetaan ensimmäiset kolme.
$td_arr = array_chunk($m[1], 3);
unset($m);

// Käydään rivit läpi.
foreach ($td_arr as $tr) {
	// Peräkkäiset solut ovat linkki aiheeseen, alueen nimi ja viestin aika.
	list($linkki, $alue, $aika) = $tr;

	// Linkistä saadaan vielä aiheen id, viestin id sekä aiheen otsikko.
	preg_match('#\\<a.*?\\?.*?id=([0-9]*).*?v=([0-9]*).*?".*?\\>(.*)\\</a\\>#', $linkki, $m);
	list($linkki, $aid, $vid, $aihe) = $m;

	// Kootaan näistä uusi linkki, joka vie suoraan oikeaan viestiin.
	$linkki = htmlspecialchars("https://www.ohjelmointiputka.net/keskustelu/aihe.php?id=". $aid. "&v=". $vid. "#". $vid);

	// Aika pitää pyörittää oikeaan muotoon.
	$aika = preg_replace('#.*?(\\d+)\\.(\\d+)\\.(\\d+) (\\d+:\\d+:\\d+).*#', '$3-$2-$1 $4', $aika);
	$aika = gmdate("D, d M Y H:i:s T", strtotime($aika));

	// Tulostetaan tiedot: kohteen nimi (aihe), kategoria (alue), linkki, tunniste (linkki sopii hyvin), aika.
	// Muista htmlspecialchars! Nyt kaikki data on kuitenkin valmiiksi HTML-enkoodattu.
	echo "\t<item>\n";
	echo "\t\t<title>", $aihe, "</title>\n";
	echo "\t\t<category>", strip_tags($alue), "</category>\n";
	echo "\t\t<link>", $linkki, "</link>\n";
	echo "\t\t<guid>", $linkki, "</guid>\n";
	echo "\t\t<pubDate>", $aika, "</pubDate>\n";
	echo "\t</item>\n";
}
// Tulostetaan pari RSS:n lopetusriviä.
echo "</channel>\n";
echo "</rss>\n";

// Laitetaan tiedot datatiedostoon ja tulostetaan.
file_put_contents($datafile, ob_get_contents());
ob_end_flush();

(Muokkaus elokuussa 2011: Ohjelmointiputkassa on nykyään omakin RSS-syöte, joten koodista ei ole enää hyötyä.)

peg [20.09.2009 21:58:45]

#

Tosi hyvä, herätys Antti. Hyvä idea myös hakea vain lähdekoodi.
Aikaleima olisi hyvä hakea.
EDIT:
kyllähän sä haet sen, mutta tulostus puuttui.
echo "\t\t<pubDate>", $aika, "</pubDate>\n";

Olli [23.09.2009 18:10:51]

#

Joo itse olen tehnyt tästä vain minun serverille version, jossa oli vähän sotkuisampaa tämä koodi :P Löytyy kun keskustelua kaivelee.

Metabolix [23.09.2009 18:54:35]

#

Olli kirjoitti:

Joo itse olen tehnyt tästä vain minun serverille version.

Käytin sitä ennen, mutta ääkköset bugasivat. Se olikin syy tämän tekemiseen. :)

peg kirjoitti:

Aikaleima olisi hyvä hakea.

Saat ihan vapaasti lisätä omaan versioosi. Pitäisikö sen kuitenkin olla jossain tietyssä muodossa, esim. Y-m-d H:i:s?

tesmu [29.09.2009 16:05:40]

#

Keskustelussa voisi olla suoraan linkit -> "Lukemattomat viestit" -> "Vastaamattomat viestit" jne jne


Itse ainakin omilla foorumeilla käytän niitä (phpBB) ja ominaisuus on mielestäni kätevä.

peg [04.10.2009 20:48:35]

#

Siis tarkoitin tuota loppu tulostelua, muutin sen näin

echo "\t\t<guid>", $linkki, "</guid>\n";
echo "\t\t<pubDate>", $aika, "</pubDate>\n";
echo "\t</item>\n";

peg [19.11.2010 17:10:09]

#

Nyt kun ohjelmointiputkan title muutettiin ei tämä enää toimi.
Olisi kiva tietää muutetaanko vielä vai jätetäänkö ohjelmointiputkan otsikot nykymuotoon.???

Metabolix [19.11.2010 17:32:02]

#

peg: Kiitos ilmoituksesta, päivitin skriptin. Lisäsin myös pubDaten – oikeassa formaatissa, toisin kuin sinun ehdotuksissasi.

Metabolix [15.12.2011 23:59:59]

#

Sivustolla on nykyään oikea RSS-syöte, joten tämä koodi on vanhentunut ja jäänee sivuston kehittymisen vuoksi muutenkin vanhaksi aikanaan.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta