rp13 rückschau

felix schwenzel,    

es gibt eine konstante seit 7 jahren republica, die mir jedes jahr auffällt. es wird immer wieder versucht den eindruck zu erwecken, dass die leute die zur republica gehen eine homogene masse seien. „die szene“ sei dies, die netzgemeinde wolle das, die community beschäftige sich dieses jahr mit jenem. auch sätze wie „die republca [ist|war|sollte|hätte] …“ konnte ich mir eben in 5 minütiger recherche googelei zu hunderten zusammensuchen.

dabei ist das alles quatsch. die republica ist eigentlich wie twitter. je nachdem welche timeline man sich zusammengeklickt hat, hat jeder sein eigenes, individuelles twitter. die stimmen einiger grosstwitterer werden zwar regelmässig — ob man will oder nicht — in die timeline gespült, aber nirgendwo spielt die gleiche musik. ausser bei der verabschiedung.

[nach dem schreiben gemerkt, dass meine idee oben gar nicht meine ist, sondern ein mem dass sich aus einem tweet von kathrin passig in mein unterbewusstsein gewunden hat.]

* * *

meine republica war ein bisschen wie die von anne wizorek:

Es klingt immer so schlimm wichtigpopichtig wenn man sagt, dass man von der re:publica nicht so viel mitbekommen habe, weil man selbst einen Vortrag halten musste. Aber nun ja, ich habe leider längst nicht so viel von der #rp13 mitnehmen können, wie ich gerne gewollt hätte, weil da eben dieser Talk war. Ich war zumindest am Montag unfassbar neidisch auf alle, die es schon hinter sich hatten […].

am montag war ich nicht nur verzweifelt, weil ich übers ganze wochenende meinen vortrag konzeptionell nicht in den griff bekommen hatte, sondern auch noch von einem tödlichen männerschnupfen angeschlagen. der schnupfen hatte am wochenende meinen kopf mit grossen mengen antimaterie gefüllt. ich hatte anfangs versucht die erkrankung vor mir und der beifahrerin geheimzuhalten, aber am sonntag brachen dann meine nasendämme.

am montag versuchte ich meinem körper dann wieder normalität vorzugaukeln, verzichtete aber — auf empfehlung der beifahrerin — darauf freunden und bekannten die hand zu geben. erfreulicherweise habe ich viele freunde und bekannte, die mir auch gar nicht die hand geben möchten. es ist auch gut möglich, dass ich den einen oder anderen gar nicht grüsste, das aber nicht aus gründen der hygiene, sondern weil ich am montag noch sehr verpeilt war.

der erste tag der republica half dann aber super meine verzweiflung zu überwinden. die (wenigen) sessions die ich mir ansah (dueck, passig, 20 minuten lineham (video mittlerweile gesperrt), lobo) und die paar gespräche die ich führte (unter anderem passig, richel, dentaku, pritlove, krell, winde) halfen mir zumindest meinen kopf wieder in gang zu kriegen.

trotz der permanenten angespanntheit bin ich froh jedesmal auf der republica erst am letzten tag gesprochen zu haben. dadurch konnte ich immer gags anderer klauen mich immer inspirieren lassen und auf sachen, die in den vorherigen tagen gesagt wurden, eingehen. sollte ich nochmal auf der republica sprechen, würde ich das wieder gerne am dritten tag tun. möglicherweise ist die republica ohne eine solche anspannung auch langweilig. obwohl das ist quatsch. dann würde ich wahrscheinlich die ganze zeit ins internet schreiben, statt an meinem vortrag.

* * *

dieses (und letztes) jahr habe ich, entgegen meiner gewohnheit, nicht meinen eigenen rechner für die präsentation benutzt, sondern den des veranstalters. was mich dieses und letztes jahr gewundert hat war, dass vor mir offenbar niemand die moderationsnotizen von keynote benutzt hat. der keynote „moderatormonitor“ des stage-2-rechners war am dritten tag noch jungfräulich auf standardeinstellung, ohne notizen. so sieht die aus:

standard moderatormonitor

ich weiss gar nicht wie man eine präsentation ohne moderatornotizen halten kann. obwohl doch: ich habe leute gesehen (doctorow) die ihre notizen auf papier hatten (doctorow hat entweder ein drittes auge oder nie auf die notizen geblickt) oder auf nem ipad (casasola merkle & lison).

ich schreibe alles in die moderator-notizen, so dass ichs als stichworgeber nutzen kann oder mich zur not vorlesend daran entlanghangeln zu können. seit einem veritablen blackout vor sechs jahren, wirken meine vorträge nur schlecht vorbereitet, sind es aber nicht. so sieht mein moderatormonitor aus:

mein moderatormonitor

was mich auch wunderte, wie viele ihre präsentationen auf den bühnen eins bis drei (oder gar vier?) im 4:3-format ablieferten (statt 16:9).

* * *

tanja haeusler meint hier im gespräch mit philip banse einen neuen trend auf der republica festgestellt zu haben: den talk vor dem talk fertigzustellen. ich glaube der trend ist gar nicht mal so neu.

youtube-video

direkt youtube-link

das interview hab ich schon nach 4 minuten gemocht. tolle tanja, tolles interview. der rant zum gleichen thema war nicht so mein ding, was aber eher an der form, als am inhalt lag.

* * *

ich las in vielen republica-rückblicken, dass sich die republica sehr professionalisiert habe. fand ich auch. es fiel auf, dass das wlan fast durchgängig funktionierte und dass die videos der sessions teilweise schon 30 bis 40 minuten nach der veranstaltung sauber verschlagwortet und beschrieben auf youtube lagen. sehr respektabel. keine ahnung ob es auch ausdruck dieser professionalisierung war, dass die leitfarbe der republica 2013 die der next-konferenz war.

auffällig ist aber auch die professionalisierung der besucher. michael kreil hat beispielsweise eine geniale visualisierung der der session-videos gebaut:
michaelkreil.github.io/republicavideos

johannes mirus hat sich für seine republica rückschau die mühe gemacht jede session die er gesehen hat zu kommentieren und zu videolinken. sehr beispielhaft.

das kotzende einhorn hat beim musikexpress nachlese betrieben, aber dafür eine rückschau auf viele andere rückschauen. ralf graf hat auch sehr fleissig artikel über die rp13 gesammelt.

* * *

ich habe auf der republica keine einziges vine-video gedreht, ungefähr acht oder neun fotos gemacht (davon drei instagramme, 1, 2, 3) und nicht mehr als 10 tweets gefunkt.

blick von stage 2

blick von stage 2

vielen dank übrigens für das ziemlich überwältigende feedback zu meinem vortrag. wenns um lob geht, finde ich pauschalisieren übrigens total töffte. kritik wünsch ix mir immer voll differenziert, aber das ist leider ein frommer wunsch (beweisstück 1).

* * *

sehr beeindruckt hat mich übrigens die gefasstheit von anne wizorek. anders beeindruckt hat mich jan-uwe fitz (der vergrämer). bei kate darlings vortrag fiel mir auf, dass englisch, zumindest wenns muttersprachlich und amerikanisch gefärbt ist, eine angenehmere vortragssprache als deutsch sein könnte. ganz grandios johnny als interviewer von 3 menschen, die auf youtube extrem erfolgreich sachen machen. sehr tolle fotos von teymur madjderey auf dickehipster.de (via). (wird fortgesetzt …)

mein vortrag auf der republica 2013

felix schwenzel,    

youtube-video

direkt youtube-link


10 vorschläge um die welt zu verbessern

reclaim social media

felix schwenzel,    

ich werde in den nächsten zwei tagen wahrscheinlich nicht dazu kommen, mehr über das reclaim-social-media projekt von sascha und mir zu schreiben. ein paar absätze und ein paar downloads habe ich heute mittag zusammengeschrieben. leider ist die einrichtung noch nicht ganz trivial. dazu dann mehr nach der republica.

* * *

links:

heldinnen meiner fernseh-kindheit im dschungel

felix schwenzel,    

kürzlich bin ix im netz darüber gestolpert, dass inger nilsson, die in den 60er jahren pipi langstrumpf spielte, 2009 in der schwedischen version von „Ich bin ein Star – Holt mich hier raus!“ mitgespielt hat („Kändisdjungeln“).

dann eben stefanie powers in der glaserei mit einer katze gesehen und kurz darauf gesehen, dass stefanie powers 2011 in der britischen version des australischen dschungels eine folge lang mitgespielt hat.

ich bin sicher mit einem nachmittag recherche fände ich mindestens 20 fernsehhelden der 80er, die zwischenzeitlich in den dschungel gegangen sind.

quote.fm-RSS mit den empfehlungen aller gefolgten

felix schwenzel,    

seitdem quote.fm RSS-feeds einzelner nutzer anbietet (hier die ode von martin weigert auf die quote.fm-RSS-feeds) habe ich ein paar quote.fm-nutzer in meinem RSS-dings (früher google reader, jetzt auf meiner eigenen fever installation) aboniert. und lieben gerlernt. das liegt zum einen natürlich an den jeweiligen nutzern. abonniert hatte ich bisher:

aber ich habe mich schon immer gefragt, warum bietet mir quote.fm nicht alle leute denen ich auf quote.fm folge als RSS-feed an? warum sollte ich alle 140 leute denen ich folge einzeln abonnieren? kürzlich fiel mir dann beim duschen ein, dass das ja nicht so schwer sein könnte sowas zu scripten.

die quote.fm-API abfragen nach denen denen ich folge (quote.fm/api/user/listFollowings?username=ix), aus dieser liste feed-URLs konstruieren und diese feed-liste SimplePie zum frass vorwerfen und neu rausschreiben. hier ist das ergebnis:

* * *

eben via martin weigert gelesen, dass quote.fm das geld ausgegangen ist und quote.fm an eine agentur vertickt haben:

That means: Philipp, Marcel, Flo and I are saying our good-byes and sometime in the (quite near) future elbdudler will take over and hopefully build this thing here into something that you guys will appreciate.

hoffentlich wird das nicht so schlimm wie es sich anhört, aber noch funktioniert dieses quote.fm-dings ja noch.

* * *

das script hat als abhängigkeit lediglich SimplePie (download) und einen cache-ordner auf der gleichen ebene in der das script liegt:

das script ist nicht elegant gescriptet, funktioniert aber. fehler schliesse ich wie immer ausdrücklich nicht aus.

<?php
$input = '
<form method="get" name="schick it ab" action="http://'.$_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME'].'">
	<fieldset>
		<label for="1">quote.fm benutzername</label>
		<input id ="1" type="text" name="user" />
		<input type="submit" name="senden" />
	</fieldset>
</form>';
	$user_id = $_GET["user"];
	if ($user_id == "") {	
	$user_id = "ix"; 
	echo $input;
	exit;
	}
	$count = 200;
	$apiurl= 'https://quote.fm/api/user/listFollowings?username='.$user_id;
    $timeout = 15;

	$feeds = array();
	$i=0;
while ( $i <= 20 ) // mehr als 20 seiten? eher nicht.
	{
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $apiurl.'&pageSize=100&page='.$i);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );
   	curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout );
	$output = curl_exec($ch);
	curl_close($ch);
	$rawData = trim($output);

	$response = json_decode($rawData, true);
//
//	echo $response;
	if ( ($response['code'] == "404") AND ($i == 0) ) { 

	echo "<p>fehler. <i>".$user_id."</i> kein gültiger quote.fm benutzername.</p>"; 
	echo $input;
?>	

<?php
	exit; }	

	if ( ($response['totalCount'] - (($i+1) * 100)) <= 0 ) { $i=20; }
	foreach($response['entities'] as $entry){
		$feeds[] = 'http://quote.fm/'.$entry['username'].'/feed';
		//echo $entry['username'];
	}
	$i++;
}

//print_r($feeds);

// Include the SimplePie library
// For 1.3+:
require_once('SimplePie/autoloader.php');

// Create a new SimplePie object
$feed = new SimplePie();

// Instead of only passing in one feed url, we'll pass in an array of three
$feed->set_feed_url($feeds);

// We'll use favicon caching here (Optional)
//$feed->set_favicon_handler('handler_image.php');

$feed->set_cache_duration ( 3600 );
$feed->set_timeout ( 10 );
$feed->set_stupidly_fast( true );
//$feed->set_autodiscovery_level(SIMPLEPIE_LOCATOR_NONE);
$feed->force_feed(true);


// Initialize the feed object
$feed->init();

// This will work if all of the feeds accept the same settings.
$feed->handle_content_type();

// Begin our XHTML markup
header("Content-Type: application/rss+xml");
echo '<?xml version="1.0" encoding="UTF-8"?>';
?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">

<channel>
<title>Recent recommendations of all people <?php echo $user_id; ?> is following</title>
<link>https://quote.fm/<?php echo $user_id; ?></link>
<description>Recent recommendations of all people <?php echo $user_id; ?> is following</description>
<lastBuildDate><?php echo date(DATE_ATOM , time()); ?></lastBuildDate>
<language>en</language>
<atom:link href="<?php echo 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME'].'?user='.$user_id; ?>" rel="self" type="application/rss+xml" />
<generator>http://quote.fm</generator>

<?php if ($feed->error): ?>
<?php //echo $feed->error; ?>
<?php print_r( $feed->error); ?>
<?php endif; ?>

<?php $j = 0; ?>
<?php foreach ($feed->get_items() as $item): ?>

<item>
<title><![CDATA[<?php echo $item->get_title(); ?>]]></title>
<link><?php echo $item->get_permalink(); ?></link>
<pubDate><?php echo $item->get_date('D, j M Y H:i:s O'); ?></pubDate>
<dc:creator><?php $author = $item->get_author(0); if ($author != "") {echo $author->get_name(); } ?></dc:creator>
<category><![CDATA[<?php $category = $item->get_category(0); if ($category != "") { echo $category->get_label();} ?>]]></category>
<guid isPermaLink="true"><?php echo $item->get_permalink(); ?></guid>
<description><![CDATA[<p><?php $feed = $item->get_feed(); echo $feed->get_title(); ?></p>
<?php echo $item->get_content(); ?>]]></description>

<content:encoded><![CDATA[<p><?php echo $feed->get_title(); ?></p>
<?php echo $item->get_content(); ?>]]></content:encoded>
</item>
<?php $j++; if ($j >= $count) { break; }?>
<?php endforeach; ?>
</channel>
</rss>

bulgurpilaw nach ottolenghi

felix schwenzel,    

bulgurpilaw nach ottolenghi

eigentlich sollen es 3 kleine zwiebeln sein, ich habe aber 3 mittelgrosse zwiebeln in halbe ringe geschnitten und zusammen mit (leider nur) 2 kleinen in ringe geschnittenen spitzpaprika in 90 millilitern olivenöl 10 minuten an- und weichgebraten.

danach habe ich 2 esslöffel tomatenmark, 2 EL koriandersamen, ein teelöffel sechuan pfeffer (ottolenghi schlägt rosa pfeffer vor), etwas zucker, salz und pfeffer und 100 gramm korinthen nochmal 2 minuten mitgebraten.

400 gramm mittelgroben bulgur habe ich wie beim risotto auch nochmal ein bisschen glasiggebraten und dann mit einem halben liter wasser abgelöscht und aufgekocht. das ganze dann 20 minuten ohne hitze quellen lassen, petersilie (statt schnittlauch), fertig. mit einem klecks jogurt schmeckts besser als ohne.

selbstgehostetes twitter-RSS mit der twitter API 1.1

felix schwenzel,    

vor ein paar tagen veröffentlichte gabe weatherhead einen artikel mit dem titel „TweetFeeder Script: From Twitter to RSS“. gabe weatherhead hat sich ein script gebastelt das ein paar twitter accounts sporadisch nach links die keine bilder sind überprüft und diese links dann in eines seiner pinboard-accounts schreibt. der artikel hätte also genauer „From Twitter to Pinboard“ heissen müssen.

gestern bookmarkte sascha lobo den (neuen?) dienst twitter-rss.com, der genau das tut was er im domainnamen ankündigt: er macht beliebige twitter-konten per RSS abonnierbar.

in den letzten monaten habe ich mich auch immer wieder mit dem thmea twitter und RSS beschäftigt, was daran liegt, dass twitter sich zu meinem bedauern mehr und mehr einigelt und abschottet. im september wurden die möglichkeiten per ifttt daten aus twitter rauszuholen von twitter empfindlich eingeschränkt und seit diesem frühjahr arbeitet twitter daran die relativ offene API der version 1.0 mit der version 1.1 zu ersetzen, die für jede kleinigkeit authentifizierung benötigt und die eh noch versteckt vorhandenen twitter-RSS-feeds beseitigt.

RSS ist und bleibt mein favorisierter weg daten zu verarbeiten, sei es meine rückseite zu bestücken, meine monatlichen twitter-favoriten-listen automatisch zu erzeugen oder per RSS-reader den überblick zu behalten. deshalb habe ich mir meinen eigenen php-basierten twitter-zu-RSS-übersetzer, bzw. proxy gebaut.

ein eigener, selbstgescripteter und selbstgehosteter übersetzer hat ein paar vorteile gegenüber lösungen wie twitter-rss.com:

  • ich mache mich nicht von einem weiteren drittanbieter abhängig
  • ich kann bestimmen wie die ausgabe aussieht oder formatiert ist
  • ich kann alles selbst steuern und erweitern

der beste teil ist natürlich: wenn viele dieses oder andere scripte nutzen um twitter-ströme auszulesen, kann twitter nicht einfach die schotten dicht machen, wie bei ifttt. ifttt ein paar berechtigungen zu entziehen ist einfach, den selbstgehosteten scripten oder webapps von hunderten oder tausenden nutzern rechte zu entziehen ist schon sehr viel schwerer.

* * *

mit meinem script lese ich den twitter-strom meines eigenen accounts aus. technisch passiert nichts aufregendes:

  • ich authentifiziere mich mit meiner eigens definierten twitter-app, bzw. deren schlüsseln
  • twitter liefert mir json-codiert die letzten 20 meiner tweets, exklusive retweets
  • aus der json-antwort baue ich mir meinen RSS-feed zusammen und gebe ihn aus

wenn ich die anfrage etwas anpasse kann ich auf diese art und weise beispielsweise auch meine twitter-favoriten auslesen und als RSS ausgeben:

// favoriten
	$apiurl = 'http://api.twitter.com/1.1/favorites/list.json';
// timeline
	$apiurl = 'http://api.twitter.com/1.1/statuses/user_timeline.json';

mit einer twitter-such-anfrage sollte das ähnlich klappen, das habe ich aber noch nicht ausprobiert.

als grössten vorteil sehe ich, dass ich die RSS-ausgabe selbst steuern und formatieren kann. das script wandelt bespielsweise die verkackten t.co-links die die twitter-api zurückliefert in klartext-adressen um, hashtags in suchlinks und twitter-namen in profillinks. der titel eines RSS-items liefert den rohen volltext eines tweets, die description des RSS-items liefert hingegen das offizielle embed-format eines tweets zurück, also nach diesem schema:

rss ausgabe

das ausgabeformat lässt sich bei bedarf natürlich leicht anpassen. in einem tweet eingebettete bilder bette ich per HTML in die tweet-description ein. das ist nicht besonders schön, aber effektiv (demo):

rss ausgabe mit eingebettetem bild

* * *

für die twitter-kommunikation und die RSS-generierung nutze ich zwei php-klassen. einerseits die OAuth 1.0A library von @themattharris und den Universal Feed Generator von anis uddin ahmad. das ganze paket lässt sich hier runterladen, hier eine demoausgabe meiner tweets.

<?php
/*
// generiert einen rss-feed eines nutzers ohne seine (nativen) retweets
//
*/
	header('Content-Type: text/html; charset=utf-8');
	require 'tmhOAuth/tmhOAuth.php';
	require 'tmhOAuth/tmhUtilities.php';
	include('feed_generator/FeedWriter.php'); // include the feed generator feedwriter file

// app: hier wirres.net
// eigene app keys gibts hier: https://dev.twitter.com/apps/new
	$tmhOAuth = new tmhOAuth(array(
	  'consumer_key'    => 'xxx',
	  'consumer_secret' => 'xxx',
	  'user_token'      => 'xxx',
	  'user_secret'     => 'xxx',
	));

	$lang = 'de';
	$count = 20;
	$user = 'diplix';
	$user_name = 'Felix Schwenzel';
	$userid = ''; //?
//	$apiurl = 'http://api.twitter.com/1.1/favorites/list.json';
	$apiurl = 'http://api.twitter.com/1.1/statuses/user_timeline.json';
	$embedcode = true;

	$tmhOAuth->request(
    'GET',
    $apiurl,
		array(
			'lang'				=> $lang,
			'count'				=> $count,
			'screen_name'		=> $user,
			'include_rts' 		=> 'false',
			'include_entities' 	=> 'true'
		),
	  	true
  	);

//echo $tmhOAuth->response['response'];

if ($tmhOAuth->response['code'] == 200) {
	$data = json_decode($tmhOAuth->response['response'],1);
	$feed = new FeedWriter(RSS2);

//	$feed->setTitle('@'.$user.'s Twitter Favs'); // set your title
	$feed->setTitle('@'.$user.'s Twitter Timeline'); // set your title
	$feed->setLink('http://'.$_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME']); // set the url to the feed page you're generating

//	$feed->setChannelElement('updated', date(DATE_ATOM , time()));
//	$feed->setChannelElement('author', $user_name); // set the author name
	$feed->setChannelElement('description', $user_name.'s tweets'); // set the description

// iterate through the response to add items to the feed
	if ( is_array( $data ) ) {
		foreach($data as $entry){
			$post_date_gmt = strtotime( $entry['created_at'] );
			$post_date_gmt = gmdate( 'Y-m-d H:i:s', $post_date_gmt );
			$post_date     = gmdate( 'd.m.Y H:i', strtotime( $entry['created_at'] ));
			$tweetlink = 'http://twitter.com/'.$user.'/status/'.$entry['id_str'];

			$post_content = $entry['text'];
//			$post_content = ( html_entity_decode( trim( $post_content ) ) );
			$post_content = ( html_entity_decode( $post_content ) ); // ohne trim?

//links einsetzen/auflösen
			if ( count( $entry['entities']['urls'] ) ) {
				foreach ( $entry['entities']['urls'] as $url ) {
					$post_content = str_replace( $url['url'], '<a href="'.$url['expanded_url'].'">'.$url['display_url'].'</a>', $post_content );
				}
			}

// bild attached?			
			$image_url = '';
			$image_html = '';
			if ( count( $entry['entities']['media'] ) ) {
				foreach ( $entry['entities']['media'] as $media ) {
					$post_content = str_replace( $media['url'], '<a href="'.$media['expanded_url'].'">'.$media['display_url'].'</a>', $post_content );
					if ($media['type']=='photo') {
						$image_url = $media['media_url'];
						$image_html = '<div class="twitter-image"><a href="'.$media['expanded_url'].'"><img src="'.$image_url.'" alt=""></a></div>';
					}
				}
			}

		    $post_content = preg_replace( '/\s((http|ftp)+(s)?:\/\/[^<>\s]+)/i', ' <a href=\"\\0\" target=\"_blank\">\\0</a>',$post_content);
		    $post_content = preg_replace('/[@]+([A-Za-z0-9-_]+)/', '<a href="http://twitter.com/\\1" target="_blank">\\0</a>', $post_content );  
		    $post_content = preg_replace('/[#]+([A-Za-z0-9-_]+)/', '<a href="http://twitter.com/search?q=%23\\1" target="_blank">\\0</a>', $post_content );  
			$post_content_original = $post_content;

// embedcode konstruieren
			if ($embedcode) {
				$post_content = '<blockquote class="twitter-tweet imported"><p>'.$post_content.'</p>'.$image_html.'— '.$entry['user']['name'].' (<a href="https://twitter.com/'.$entry['user']['screen_name'].'/">@'.$entry['user']['screen_name'].'</a>) <a href="'.$tweetlink.'">'.$post_date.'</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>';
			}

// tags auflisten
			$tags = array();
			if ( preg_match_all( '/(^|[(\[\s])#(\w+)/', $entry['text'], $tag ) ) {
				$tags = $tag[2];
				echo $tags;
			}

			$in_reply_to_user_id     = !empty( $entry['in_reply_to_user_id_str'] ) ? $entry['in_reply_to_user_id_str'] : '';
			$in_reply_to_screen_name = !empty( $entry['in_reply_to_screen_name'] ) ? $entry['in_reply_to_screen_name'] : '';
			$in_reply_to_status_id   = !empty( $entry['in_reply_to_status_id_str'] ) ? $entry['in_reply_to_status_id_str'] : '';

			$item = $feed->createNewItem();

//            $item->setTitle($post_date);
            $item->setTitle(strip_tags($post_content_original));
            $item->setDate($entry['created_at']);
            $item->setLink($tweetlink);
            $item->setDescription($post_content);
			$item->addElement('guid', $tweetlink, array('isPermaLink'=>'true'));

			//metagedoens
//  			$item->addElement('in_reply_to_user_id', $in_reply_to_user_id);
//  			$item->addElement('in_reply_to_screen_name', $in_reply_to_screen_name);
//  			$item->addElement('in_reply_to_status_id', $in_reply_to_status_id);

// hashtags zu kategorien
//	  			$item->addElement('category', $tags);
				foreach ( $tags as $tag ) {
		  			$item->addElement('category', $tag);
				}

            $feed->addItem($item);
        }

// that's it... don't echo anything else, just call this method
	$feed->genarateFeed();
  	} else {
//    return NULL;
  }
}

* * *

das alles ist natürlich lange nicht perfekt. der universal feed generator generiert derzeit beispielsweise keine mehrfachen RSS-kategorien, so dass bei mehreren hashtags eines tweets immer nur der letzte als RSS-kategorie im RSS-feed landet. ich hoffe das dieser feed-generator das künftig besser erledigt. caching wäre irgendwann auch keine schlechte idee, um die twitter API nicht über gebühr zu strapazieren. eine zentrale konfiguration und eine flexibilisierung, so dass ich mir alle möglichen feeds mit dem script erzeugen kann, nicht nur twitter-favoriten und die eigenen tweets.