Über die Feiertage habe ich mich mal rangesetzt und für selfoss eine Android App geschrieben. Die App dient als Frontend und lädt im Hintergrund natürlich die Daten von der eigenen selfoss Installation. Daher muss beim Start der Applikation die URL, sowie die Zugangsdaten (sofern vorhanden) angegeben werden. Im Gegensatz zum WebFrontend, dass ja auch eine mobile Variante bietet, ist die App allerdings für die Bandbreite schonender (es werden lediglich die Daten via JSON übertragen) und in der Bedienung komfortabler.

 

Die App basiert auf phonegap und jQuery Mobile und ist natürlich auch wieder OpenSource unter github zu finden. Wen also die Umsetzung interessiert, der kann einen Blick darauf werden. Nachdem phonegap ja plattformunabhängig ist, könnte man sie auch ohne großen Aufwand für iOS, Windows Phone, usw. kompilieren. Allerdings benötigt man dazu einen iOS Entwickler Zugang und einen Mac. Wer also über beides verfügt, kann sich gerne bei mir melden.

Im Augenblick ist die App allerdings noch beta. Feedback und Fehler also bitte an mich weitergeben. Überhaupt interessiert mich eure Meinung zu selfoss und alles was dazu gehört. Über Rückmeldungen bin ich also sehr dankbar!

Zur Android App im Google Appstore: https://market.android.com/details?id=de.aditu.selfoss

Oder zum direkten Download der .apk Datei: http://selfoss.aditu.de/

In einem Gastbeitrag bei phphatesme schreibe ich über selfoss. Dort stelle ich auch die verschiedenen Bibliotheken vor, die ich für den RSS Reader verwende. Also für Interessierte: schaut einfach rein.

Herzlichen Dank an Nils, dass er mir die Möglichkeit gegeben hat, selfoss in seinem Blog vorzustellen.

Nach dem erfolgreichen Release von selfoss gibts heute auch schon das erste Update. Folgendes hat sich geändert:

  • Passwörter werden jetzt als Hash in der config.ini gespeichert. In der config.ini kann dazu ein salt gesetzt werden. Ein Passwort kann dann unter der URL: http://your_selfoss_url.com/password erzeugt werden. Dieses muss dann in der config.ini abgelegt werden.
  • alle JavaScript Dateien werden jetzt zu einer all.js zusammengefasst und minimiert. Analog für alle CSS Stylesheets.
  • die Apache Konfiguration enthält nun Optionen für ein Caching und für eine Kompression der Dateien.
  • Code wurde nochmal aufgeräumt und ein paar unnütze Dinge entfernt.
Selfoss gibts wie gewohnt hier zum Download: http://selfoss.aditu.de/

So, endlich ist es vollbracht. selfoss 1.0 ist verfügbar. Dazu gibt es jetzt auch eine eigene Webseite, wo natürlich die Werbetrommel ordentlich angeheizt wird und mit Buzzwords nur so um sich geworfen wird.

Neu verfügbar ist nun neben MySQL ein Datenbankbackend für Sqlite und MongoDB (danke Harald). Zudem habe ich noch ein paar Bugs entfernt. Vielen Dank an alle Betatester. Euer Feedback war echt super!

Auf selfoss.aditu.de ist nun auch eine Dokumentation zu finden. Dort ist auch eine kurze Erklärung, wie eigene spouts, also andere Anwendungen und Quellen an Selfoss angeschlossen werden können. Dazu habe ich hier im Blog ja auch schon einmal ein Tutorial geschrieben.

Tja, sonst kann ich nur sagen: schaut euch selfoss einfach einmal an. Ich nutze es ja schon seit einigen Monaten und schätze die schlichte und übersichtliche Art, News zu lesen sehr.

Letzte Woche habe ich ja den neuen RSS Reader selfoss als Beta Version veröffentlicht. Ein Vorteil von dem Reader ist die Erweiterbarkeit hinsichtlich der Quellen. So können nicht nur RSS Feeds verarbeitet, sondern auch beliebige Quellen angezapft werden (z.B. Logfiles, Email Accounts, Webseiten ohne RSS Feed, Facebook OpenGraph).

Manchmal möchte man aber auch nur einzelne Einträge von RSS Feeds um zusätzliche Informationen anreichern. Ich mache das beim RSS Feed von heise, wo der Inhalt des News Beitrages nicht mitgeliefert wird. Diesen lade ich dann einfach in einer speziellen Datenquelle, die sich um diese Funktion von einem gewöhnlichen RSS Feed unterscheidet, nach.

Nun gibt es eine Schritt-für-Schritt Anleitung, wie so eine Datenquelle erstellt werden kann.

Eine Datenquelle, eine Klasse

selfoss stellt ein kleines Framework zur Verfügung, das es erlaubt recht einfach neue Datenquellen hinzuzufügen. Dazu muss nur eine einzelne PHP Datei unter
/spouts/your_spouts/your_spout.php
abgelegt werden (your_spouts und your_spout kann frei durch einen anderen Namen ersetzt werden). Diese PHP Datei muss eine einzelne Klasse enthalten, welche von der abstrakten Klasse \spouts\spout abgeleitet ist (man beachte, dass selfoss PHP 5.3 voraussetzt und \spouts der Namespace für alle Datenquellen ist).

Datenelemente der Klasse

Die eigene Klasse muss drei Datenelemente definieren:

  • name: der Name der Datenquelle
  • description: eine Beschreibung
  • params: hier werden die Optionen der Datenquelle festgelegt. Soll z.B. ein Benutzername eingegeben werden, so kann dies hier vorgegeben werden.

Folgend gleich ein Beispiel für so eine Klasse. Natürlich fehlen hier noch die Methode, auf die ich gleich eingehe. Es wird eine Datenquelle für einen Email Account via IMAP definiert. Der Benutzer muss, wenn er eine solche neue Email IMAP Quelle definiert, die Email Adresse, das Passwort und den Server eintragen. $params beschreibt diese drei Parameter, legt fest, was für ein Typ diese darstellen und wie die Eingabe des Benutzers validiert wird.

<?PHP
namespace spouts\mail;
class imap extends \spouts\spout {
    public $name = 'Email';
    public $description = 'email imap account as source';
    public $params = array(
            "email" => array(
            "title"      => "Email",
            "type"       => "text",
            "default"    => "",
            "required"   => true,
            "validation" => array("email")
        ),
        "password" => array(
            "title"      => "Password",
            "type"       => "password",
            "default"    => "",
            "required"   => true,
            "validation" => array("notempty")
        ),
        "host" => array(
            "title"      => "URL",
            "type"       => "text",
            "default"    => "",
            "required"   => true,
            "validation" => array("notempty")
        )
    );
}

Methoden der Klasse

Durch die abstrakte Elternklasse \spouts\spout muss die Datenquelle einige Funktionen implementieren. Diese werden dann im laufenden Betrieb von selfoss aufgerufen. Folgendes UML Diagramm gibt einen Überblick über die Struktur:

Die Klasse muss drei Dinge implementieren:

  • Sie muss eine Funktion load($params) für das Laden der Informationen zur Verfügung stellen. Diese wird während der Aktualisierung einmal aufgerufen und erhält als Parameter die aktuellen Einstellungen. load($params) muss von der Datenquelle implementiert werden und holt die Daten von der entfernten Quelle (z.B. führt einen IMAP Zugriff aus und lädt aktuelle Emails).
  • Sie muss das Interface Iterable implementieren. selfoss iteriert, nachdem load() ausgeführt wurde, dann über die einzelnen Einträge (mit Hilfe der Funktionen, die das Interface Iterable vorgibt: rewind, current, key, next, valid). Die einzelnen Einträge könnten z.B. neue Emails sein.
  • Während selfoss über die einzelnen Einträge iteriert, werden dann die Informationen dieser einzelnen Einträge abgerufen. Dies geschieht über Funktionen, welche durch die abstrakte Klasse \spouts\spout vorgegeben werden. Informationen sind z.B. Betreff einer Email, Email Body usw.

Der Ablauf ist dann folgender:

  1. Im Beispiel würde load($params) von selfoss mit der vom Benutzer eingegebenen Email, Passwort und Host aufgerufen.
  2. Diese Methode würde dann die Emails vom IMAP Account herunterladen und zwischenspeichern.
  3. selfoss iteriert über die einzelnen Emails (mit rewind, current, key, next, valid).
  4. Bei jedem einzelnen Iterationsschritt (also für jede Email) werden die Email-Informationen abgerufen (Inhalt, Betreff, Datum usw.) und zwar mit Hilfe der Funktionen: getId(), getTitle(), getContent(), getIcon(), getLink(), getDate().
  5. Um den Rest kümmert sich selfoss (prüfen ob es den Eintrag schon gibt, alte Einträge löschen usw.)

Eine Implementierung für diese Funktionen liegt natürlich völlig in der Hand des Entwicklers einer Datenquelle. Daher verweise ich an dieser Stelle auf die vorhandenen Datenquellen. \spouts\spout\feed (\spouts\rss\feed.php) stellt ein gutes Beispiel dar. Wer diese als Vorlage nimmt, kommt recht schnell sehr weit, denn dort werden alle Funktionen genutzt. Soll nur ein Standard RSS Feed um Funktionen erweitert oder angepasst werden, dann verweise ich auch die Klasse \spouts\spout\heise (\spouts\rss\heise.php). Hier wird lediglich die getContent() überschrieben und ansonsten verhält sich die Datenquelle wie ein gewöhnliches RSS Feed.

Thumbnails

Soll anstelle eines Textes ein Vorschaubild angezeigt werden, so muss die Methode getThumbnail() implementiert werden. Diese liefert für einen einzelnen Eintrag das Vorschaubildchen (die URL auf das Bild). \spouts\spout\images (\spouts\rss\images.php) ist ein Beispiel dafür. Diese Datenquelle geht von einem gewöhnlichen RSS Feed aus, durchsucht es nach Bilder (entweder ausgezeichnete Thumbnails im XML des Beitrages, oder das erste Bild im Content des Beitrages) und liefert die URL an selfoss. Das Laden, Verkleinern, Speichern und Aufräumen der Bilder übernimmt selfoss.

Los gehts…

Das war sie, die kurze und knackige Einführung, wie Datenquellen für selfoss entwickelt werden können. Gerne könnt ihr mir dazu Fragen stellen und bei Problemen schreiben (am besten hier im Blog, so dass auch andere von den Antworten profitieren können). Sehr freue ich mich auch über fertige Datenquellen. Gerne nehme ich neue in selfoss auf.

Wie es scheint, sind einige an selfoss interessiert und nachdem der Reader bei mir schon seit einiger Zeit stabil läuft, ist eine Beta durchaus angebracht. Einführend sollte ich aber ein wenig das Prinzip hinter selfoss erklären, denn das unterscheidet sich von rsslounge. Wer sich also eine verbesserte oder umfangreichere Version von rsslounge erhofft, wird wohl an dieser Stelle enttäuscht werden.

Benannt habe ich Selfoss nach dem isländischen Wasserfall. Aus vielen Quellen werden Informationen abgegriffen und landen am Ende in einem immerwährenden Storm an Informationen. Das kommt einem Wasserfall irgendwie nahe.

Features

selfoss sammelt Nachrichten von verschiedenen Quellen und stellt diese in einem einzigen Stream dar. Es gibt keine Kategorien, keine umfangreichen Optionen oder ein Prioritätensystem, wie bei rsslounge. Die Idee ist nicht neu, immerhin bieten twitter, facebook und wie sie alle heißen als zentrale Anlaufstelle eine “Pinnwand” in der aktuelle Meldungen einfach untereinander angezeigt werden. selfoss ist aber darauf ausgelegt, Informationen aus verschiedensten Quellen zu aggregieren. Ein offenes Pluginsystem erlaubt es, einfach neue Datenquellen hinzuzufügen (ein Tutorial dazu werde ich noch verfassen).

Out of the Box unterstützt selfoss folgende Quellen (Wer rsslounge kennt, wird die Liste wiedererkennen):

  • RSS Feeds
  • RSS Feeds mit Bilder
  • deviantArt Benutzer, Favoriten und Daily Deviations
  • Tumblr Blogs
  • Eigene Twitter Timeline
  • Twitter Benutzer
  • Heise Feed mit vollem Text

Unterstützt werden auch wieder Bilder, von denen automatisch Thumbnails erzeugt und angezeigt werden. Interessante Einträge können markiert werden und gefiltert angezeigt werden. Zudem steht eine Suche zur Verfügung.

selfoss als mashup

Darüber hinaus stellt selfoss die aggregierten Beiträge als ein neues RSS Feed zur Verfügung. Wer also selfoss nur zum Sammeln von Informationen verwenden will, um diese dann via RSS weiter zu verarbeiten, wird hier das Tool seiner Wahl finden. Nachdem es möglich ist, auch eigene Plugins für Datenquellen zu schreiben, können beispielsweise Informationen aus RSS Feeds, Emails und Logfiles zusammengefasst werden.

selfoss als lifestream

selfoss lässt sich auch als schreibgeschützte Version konfigurieren, die es nur mit einem angemeldeten Benutzer erlaubt Einstellungen zu ändern. selfoss kann also mit eigenen Inhalten befüllt werden. So könnte man eigene Einträge von Twitter, Facebook, deviantArt und anderen Seiten zusammenfassen und gesammelt in einer Seite anzeigen. Für mich ist das jetzt nicht wirklich ein Feature, aber da es sich angeboten hat auch einen “Public” Modus einzubauen, habe ich das vorgesehen.

Anforderungen

selfoss benötigt folgende Ausstattung:

  • WebServer (Apache, lighttpd usw.)
  • MySQL
  • PHP 5.3 oder höher
  • Browser (Chrome, Firefox, Safari, IE7+)
  • iPad und Android

Clientseitig läuft es auf allen gängigen Browsern und ist insbesondere auch auf dem iPad oder unter Android lauffähig. Zumindest war mir das wichtig, denn ich will auch mal unterwegs oder vom Sofa aus kurz die aktuellsten News checken.

Standardmäßig ist die .htaccess Konfigurationsdatei für den Apache Webserver dabei, aber eine Konfiguration ist auch unter nginx oder lighttpd möglich (siehe dazu das Manual von Fat Free PHP Framework).

Installation

Die Installation ist simpel:

  1. alle Dateien hochladen (auch die versteckten nicht vergessen)
  2. das data Verzeichnis und dessen Unterverzeichnisse schreibbar machen
  3. in die config.ini die Datenbankverbindung eintragen
  4. CronJob http://<yourselfossurl>/update einrichten
  5. selfoss im Browser aufrufen und Quellen eintragen

Download

Herunterladen könnt ihr selfoss hier:

Die Sourcen sind auf github zu finden. An der Stelle will ich natürlich auch auf den Künstler des Logos verweisen.

Feedback

Über Feedback freue ich mich natürlich sehr. Ihr könnt mir Emails schreiben, auf diesen Beitrag kommentieren oder das Ticket System von github verwenden.

Es gibt ja eine ganze Fülle an PHP Frameworks und jedes wartet mit seinen ganz eigenen Vor- und Nachteilen auf. Für rsslounge habe ich das Zend Framework gewählt und bereue diese Entscheidung nicht, denn es bietet eine Vielzahl an sehr nützlichen Funktionen und sorgt für eine saubere und aufgeräumte Struktur. Ein gravierender Nachteil ist allerdings die Größe und die hohe Anzahl an Dateien, die das Framework mit sich bringt. Für ein Webprogramm, das anderen zur Verfügung gestellt werden soll und die dies dann auf einen eigenen Server hochladen sollen, ist das ziemlich lästig. Hinzu kommt doch eine gewisse Komplexität, wie man beispielsweise am Cachingverhalten sieht.

Für mein neuestes Projekt wollte ich etwas einfaches, das eine saubere Struktur ermöglicht, aber nicht mit tausenden Dateien und riesigem Funktionsumfang daher kommt. Da ich schon vor einiger Zeit auf das PHP Fat-Free Framework gestoßen bin, und es einen sehr guten ersten Eindruck hinterlassen hat, habe ich mich entschlossen mir das Framework etwas genauer anzusehen. Sehr schnell war klar, dass es perfekt geeignet ist.

Features

Das PHP Fat-Free Framework verfügt über alle wichtigen Features, die mittlerweile so Standard sind:

  • Routing Mechanismus (sehr einfach auch im MVC Style realisierbar)
  • Datenbankzugriff (sogar mit einem mini ORM und einem MongoDB mapper)
  • Template Engine
  • Schnick Schnack wie: On-the-fly JavaScript/CSS compressor, CAPTCHA generator, OpenID, usw.

Die Template Engine konnte mich nicht ganz überzeugen, hier habe ich selbst Hand angelegt, eine kleine Hilfsklasse geschrieben und auf den in PHP integrierten Syntax zurückgegriffen. Ansonsten konnte das Framework in voller Linie überzeugen. Selbst eine Migration um eine Major Version funktionierte mit sehr geringem Aufwand, was mich doch sehr überrascht hat.

Anforderungen

Das Framework selbst ist sehr klein und wird mit einer einzigen 55KB großen PHP Datei beworben. Ganz richtig ist das aber nicht: Der Datenbankzugriff und weitere Funktionen wurden in Plugins ausgelagert. Nimmt man den gesamten Funktionsumfang, so hat man 27 Dateien mit einer gesamten Größe von 223 KB, was natürlich immernoch sehr schlank ist.

Ein bestimmter Server ist nicht erforderlich und das Manual bietet Anleitungen für das Umschreiben der URLs für den Apache Webserver, lighttpd und nginx. Einziger Wermutstropfen: Es benötigt mindestens PHP 5.3, was für einen simplen RSS Reader, der möglichst überall laufen soll eine doch recht hohe Anforderung ist. Gleichzeitig liefert diese Anforderung auch zahlreiche Vorteile, wie beispielsweise schlankeren Code durch Lambda-Funktionen oder der Einsatz von Namespaces.

F3 in der Praxis

Warum mir das Framework so zusagt, sieht man schnell, wenn man ein paar Zeilen Code sieht. Ein Beispiel ist das Routing:

require __DIR__.'/libs/f3/base.php';
F3::set('AUTOLOAD','libs/f3/|libs/|libs/WideImage/|models/|libs/twitteroauth|libs/FeedWriter');
F3::route('GET /', 'controllers\Index->home');
F3::route('GET /mark/@item', 'controllers\Items->mark');
F3::route('POST /source', 'controllers\Sources->add');
F3::route('PUT /source/@id', 'controllers\Sources->write');

Mit der ersten Zeile wird das Framework eingebunden. Mit der zweiten wird ein Autoloader registriert und die entsprechenden Inlcude-Pfade gesetzt (das Pipe Symbol | dient hier als Trennzeichen. Dann werden die Routen definiert. Das Fat-Free Framework unterstützt hierbei auch den REST Ansatz und einzelne URLs können mehrfach, je nach Art des HTTP Requests belegt werden. In diesem Beispiel wird bei einem GET Aufruf der URL / die Klasse \controllers\Index instaziiert und dort die Methode home aufgerufen.

Ähnlich einfach ist der Datenbankzugriff:

F3::set('DB',
	new DB(
		'mysql:host=localhost;port=3306;dbname=mysqldb',
		'admin',
		'p455w0rD'
	)
);
DB::sql('SELECT brandName FROM wherever');
foreach (F3::get('DB->result') as $row) {
	// whatever you want to do with $row
}

Um SQL Injection vorzubeugen, werden natürlich auch parametrisierte Queries unterstützt.

Ähnlich simpel ist das gesamte Framework gestrickt und meist bietet es verschiedene Wege etwas umzusetzen. Besonders elegant finde ich das Routing mit Lambda Funktionen:

F3::route('GET /about',
	function() {
		echo 'No subliminal messages here...';
	}
);

Lizenz und Downloads

Das Framework steht unter der GPLv3 Lizenz zur Verfügung, es wird aber auch eine kostenpflichtige, kommerzielle Lizenz angeboten. Das finde ich das einzige Manko, hier bietet beispielsweise das Zend Framework unter der MIT Lizenz sehr viel mehr Möglichkeiten.

Zur Projektseite des PHP Fat-Free Frameworks: http://fatfree.sourceforge.net/