Es tut sich wieder was bei newsbeuter. Und zwar hab ich in den letzten Tagen eine Filtersprache entwickelt, um dynamische Abfragen für theoretisch alles zu ermöglichen, primär aber, um Feeds und Artikel in Feeds zu filtern, nach Kriterien wie Autor, Titel, Inhalt, Veröffentlichungsdatum, Anzahl der ungelesenen Artikel, URL des RSS-Feeds, usw. usf. Derzeit ist es so implementiert, dass man in der Feedübersicht die Taste F drückt, eine Abfrage eingibt, die gefilterte Feedübersicht präsentiert kriegt, und diese Filterung wieder löschen kann. Ein Abfrage sieht etwa so aus:
unread_count > 0 and unread_count <= 20
Mit dieser Abfrage erhält man alle Feeds, die mindestens einen, aber 20 oder weniger ungelesene Artikel enthalten. Bald werden auch solche Abfragen möglich sein:
( author =~ "Frank" or author =~ "John" ) and ( title =~ "Linux" or title =~ "FreeBSD" )
Das würde alle Artikel der Autoren "Frank" oder "John" (als Text innerhalb der Quotes sind übrigens Regular Expressions möglich) mit "Linux" oder "FreeBSD" im Titel. Eine freie Gestaltung der Abfragen ist möglich, "the sky is the limit" wie es im Englischen so schön heisst. Die Abfrage
rssurl =~ "^https:"
filtert übrigens alle Feeds mit HTTPS-URL heraus. Wie man merkt, kommt man mit diesen Mitteln schnell zu vorher ungeahnten Möglichkeiten.
Implementiert habe ich den Parser für diese Abfragesprache übrigens mit
Coco/R für C++, ein Compilergenerator, der an der Uni Linz entwickelt wird. Das ging ziemlich schnell und intuitiv, und mit den verfügbaren Beispielen für z.B. dem Compiler für die Minisprache
Taste war es auch mir Compilerbau-Unerfahrenen möglich, schnell zu einem funktionierenden Parser zu gelangen. Die Code-Templates für die Generierung der Klassen rundherum (die "frame files") musste ich etwas adaptieren, etwa um aus einem std::istream statt aus einem FILE* zu parsen (was den Vorteil hat, über std::ifstream Dateien und über std::istringstream auch Strings anbinden zu können). Die Anbindung an newsbeuter selbst habe ich so gestaltet, dass ich einen Matcher implementiert habe, der einen geparsten Ausdruck gegen jedes beliebige Objekt prüfen kann, solange dieses nur von der Basisklasse
matchable (enthält lediglich zwei pure virtual functions zum überprüfen, ob ein Attribut vorhanden ist, bzw. um dessen Wert abzurufen) abgeleitet ist. Damit erhalte ich die größtmögliche Flexibilität, und kann eben theoretisch jedes Objekt matchen (auch wenn das nicht wirklich bei allen Objekten innerhalb von newsbeuter Sinn macht). Die eigentliche Integration war mit diesen Vorarbeiten dann ein Kinderspiel, und mittlerweile ist die Funktion zum Verstecken der bereits gelesenen Feeds sogar über die Filtersprache implementiert (über exakt den gleichen Mechanismus hängen sich dann auch die anderen Filterabfragen rein). Erstmals präsentieren werde ich dieses neue Feature übrigens übermorgen auf den
Linuxwochen Wien. Kommt zahlreich.