Archive for the ‘Codeschnipsel’ Category
[Proof of Concept] SharpConnect
Nachdem ich in den letzten Tagen an einem Konzept getüftelt habe, wie man verschiedene webbasierte APIs einfach zugänglich machen könnte, möchte ich nun eine beispielhafte Implementierung vorführen: SharpConnect. (Download DLL) Und das Ziel meiner Wahl ist natürlich Last.FM, was auch sonst. Wohlgemerkt gehe ich hier nicht auf die Umsetzung ein, nur auf die Verwendung.
Es stellt sich zuerst die Frage: Was wollen wir? Ich für meinen Teil würde z.B. gerne wissen, wo und wann Kasabian demnächst Konzerte geben (Nicht, dass die Chance bestünde, das München auf der Liste wäre, aber dennoch…), und somit böte sich der API-Aufruf artist.getEvents zur näheren Betrachtung an: Welche Parameter hat er, wie muss er ausgeführt werden und wie sieht die Antwort aus?
Wir sehen, dass es zwei Parameter gibt (“artist” und “api_key”, beide benötigt) und dass die Antwort ein XML-Dokument ist, dass die Wurzel “lfm” hat, anschließend den Knoten “events” und viele Kindknoten “event”, die die einzelnen Konzerte enthalten. Diese wiederum besitzen Werte für die auftretenden Künstler, den Ort, die Zeit, Ticketverkäufe, etc… Das Beispiel von der API-Seite:
<events artist="Cher" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" total="4">
<event>
<id>599858</id>
<title>Cher</title>
<artists>
<artist>Cher</artist>
<headliner>Cher</headliner>
</artists>
<venue>
<name>The Colosseum at Caesars Palace</name>
<location>
<city>Las Vegas</city>
<country>United States</country>
<street></street>
<postalcode></postalcode>
<geo:point>
<geo:lat>36.2265501474709</geo:lat>
<geo:long>-115.0048828125</geo:long>
</geo:point>
<timezone>PST</timezone>
</location>
<url>http://www.last.fm/venue/8841108</url>
</venue>
<startDate>Sat, 16 Aug 2008</startDate>
<startTime>19:30</startTime>
<description></description>
<image size="small">...</image>
<image size="medium">...</image>
<image size="large">...</image>
<attendance>42</attendance>
<reviews>0</reviews>
<tag>lastfm:event=669027</tag>
<url>http://www.last.fm/event/599858</url>
<website>http://...</website>
<tickets>
<ticket supplier="...">http://...</ticket>
...
</tickets>
</event>
...
</events>
Scripe. Oder: Warum eine Scriptsprache auch nur eine Suppe ist.
Es ist wohl aufgefallen, ich erwähne es trotzdem: Seit einiger Zeit arbeite ich an einem Prinzip, dass es jedem Interessierten ermöglichen soll, eine eigene Script- oder Programmiersprache zu entwerfen. Meine theoretischen Überlegungen, so langweilig sie auch manches Mal seien mögen, habe ich in einer Reihe von Artikeln festgehalten; damit ich diese Texte aber auch schreiben konnte, musste ich immer ein kleines Stückchen vorausdenken und einiges an implementierungstechnischer Vorarbeit leisten.
Und heute war ich dann soweit, dass ich eine gar nicht so üble Version vor mir hatte, die ich nun (nicht detailliert, eher angeberischerweise
) präsentieren will. Vorhang auf für Scripe!
Wie entwickle ich meine eigene Scriptsprache? (Teil 3: Syntax)
Nun, wie weit sind wir bisher? Wir haben einen Lexer, der unsere Eingabe in Einzelteile spaltet, und wir können einfache Ausdrücke in eine verwertbare Form bringen. Was wir bisher noch nicht (bewusst) gemacht haben, ist, einen Ausdruck zu analysieren und zu prüfen, ob er sinnvoll ist oder nur unzusammenhängend aneinandergereihte Token enthält.
Zur Erinnerung: sowohl “1+2+3″ als auch “1+(” wären Zeichenfolgen, die der Lexer akzeptieren und ohne zu meckern zerkleinern würde. Das ist auch in Ordnung so, da die syntaktische Prüfung ohnehin eher Aufgabe des Parsers ist. Aber was genau gilt es denn dabei zu beachten?
“Syntaxfragen”
- Sind genau so viele öffnende wie schließende Klammern vorhanden und passen diese zusammen?
- Stimmt die Zahl der Parameter, mit der eine Funktion aufgerufen wird?
- Stimmen die Parametertypen, mit denen eine Funktion aufgerufen wird? (“+” arbeitet normalerweise nur auf Zahlen, der Punkt z.B. in PHP auf Strings, etc…)
- Befinden sich Operatoren an den richtigen Positionen? (Die Fakultät einer Zahl wird z.B. durch Anhängen eines Ausrufezeichens gekennzeichnet: “3!”)
- Darf eine Funktion geschachtelt vorkommen? (z.B. wäre “echo(echo(1))” eher sinnlos, wenn “echo” die Ausgabefunktion ist)
- Darf eine Funktion/ein Konstrukt in einer untergeordneten Umgebung vorkommen? (Das wäre z.B. der Fall, wenn man Funktionsdefinitionen innerhalb von Funktionsdefinitionen zulässt.)
Neben der Syntax gibt es noch weitere Punkte, die eine Programmier-/Scriptsprache ausmachen. Eine Auflistung findet man z.B. hier.
Wie entwickle ich meine eigene Scriptsprache? (Teil 2: Grundlagen des Parsens)
Einen wichtigen Schritt haben wir an dieser Stelle bereits hinter uns: Der hier beschriebene Lexer verwandelt eine Eingabesequenz wie “1+3*(4-2)” in eine Liste von Tokens mit Typ und Wert:
zahl : 1 operator : + zahl : 3 operator : * open : ( zahl : 4 operator : - zahl : 2 close : )
Damit haben wir eine maschinenlesbare Repräsentation des gewünschten Ausdrucks – allerdings keine Garantie dafür, dass dieser syntaktisch korrekt ist. Ebensowenig kann eine Maschine, die diese Liste nun vorgelegt bekommt, “einfach mal so” den Wert des Ausdrucks berechnen, da ihr Informationen zur Auswertungsreihenfolge fehlen. (Wenn 1+3 zuerst berechnet wird, lautet das Ergebnis 8, wenn 3*(4-2) zuerst berechnet wird, lautet es 7.)
Wir brauchen also eine Darstellung unseres Ausdrucks, die bezüglich der Reihenfolge der Auswertung eindeutig ist und eine Maschine, die diese erstellt – und wie könnte es anders sein: auch dieses Problem wurde bereits einmal gelöst.
Wandeln wir also auf den Spuren von Edsger W. Dijkstra.
Wie entwickle ich meine eigene Scriptsprache? (Teil 1: Der Lexer)
Die Aufgabe, die ich mir hier gestellt habe, eine eigene Script- oder Programmiersprache zu entwickeln, bringt so ihre Probleme mit sich. Wie und wo fange ich an? Ist das nicht zu viel für mich? Und sollte ich nicht auf bereits vorhandene Bibliotheken zurückgreifen, anstatt alles von Grund auf neu zu entwickeln?
Vor allem die letzte Frage kann einem zu schaffen machen. Warum etwas möglicherweise nicht gut funktionierendes entwickeln, wenn es doch überall schon tausendfach durchdachte Lösungen gibt? Immerhin lautet doch eine der obersten Regeln in der Softwareentwicklung:
Don’t reinvent the wheel!
Nun, ich bin Informatikstudent. Ich will wissen, wie die Dinge “unter der Haube” aussehen, ich will lernen. Und wenn alle nur noch auf vorgefertige Bibliotheken zurückgreifen, weiß doch bald keiner mehr, was dem Zauber eigentlich zugrunde liegt… Dementsprechend:
Don’t reinvent the wheel, unless you plan on learning more about wheels!
Diese Anleitung soll jedem helfen, der interessiert daran ist, was im Inneren eines Interpreters oder Compilers eigentlich (ungefähr so) abläuft. Ich selbst habe gerade erst das zweite Semester hinter mir, d.h. allzu theoretisch wird es hier nicht und jeder mit ein wenig logischem Denken und genug Engagement sollte es hinbekommen, meinen Ausführungen zu folgen.
Lasset uns beginnen.
Wie entwickle ich meine eigene Scriptsprache? Ein Abenteuer in Teilen.
In diesem Artikel, dem ersten von vielen, geht es um die Entwicklung einer eigenen Script- oder Programmiersprache. Das sei nur für die erwähnt, die sich Angesichts des Vorgeplänkels der nächsten zwei Absätze fragen: “Was wird das denn jetzt?” und dann wieder verschwinden wollen…
Vorspiel
Neben LastSharp und LeSharp, den beiden Tools, die für eine breite Masse gedacht und deshalb auch zumindest ein bisschen nützlich sind, arbeite ich noch an zwei eher theoretischen Projekten: UVD (das im Moment ruht) und Lapicon (Loose API Connection Language).
Letzteres ist eine Scriptsprache zum Senden und Verarbeiten von REST-Requests, also zum Verwenden verschiedenster APIs, z.b. dem von Last.FM. Kein großer Leckerbissen für den Otto-Normal-Benutzer also und auch für Entwickler, die sich mit dem Thema beschäftigen, ist die Sprache nicht der Inbegriff von Eleganz. Deshalb mein Entschluss: Lapicon muss von Grund auf neu entwickelt werden. Das bedeutet: neue Funktionen, mehr Komfort, bessere Performance, usw… Alles in allem keine triviale Aufgabe.
Und dann kam mir die Idee, meinen Versuch zu protokollieren und somit allen, die daran interessiert sind, eine eigene Programmier- oder Scriptsprache zu entwickeln, ein Stückchen weiterzuhelfen. Eine kleine Reise, ein kleines Abenteuer also.
Read the rest of this entry »
Inside Last.FM: Silent Authentication für API 2.0
Update (17.07.2009): Das hier ist (abgesehen von den “Skills”, die ich dabei gebraucht hab) wohl ziemlich überflüssig, wenn man die API-Methode auth.getMobileSession mal genauer betrachtet. Wieder was gelernt: RTFM!
Da im Moment anscheinend wieder Änderungen am Last.FM-Webservice gemacht werden, die dazu geführt haben, dass LastSharp höchstens noch mithilfe der “Modifizierten Verbindung” (unter “Erweiterte Einstellungen” >> “Verschiedenes”) funktioniert, habe ich mir mal das Radio-API angesehen, das ja anscheinend die Zukunft des Radiostreamings bei Last.FM ist. Was mich daran allerdings stört, ist die umständliche Anmeldeprozedur: Token holen, Browser öffnen, auf Authentifizierung warten, Session holen.
Der Umweg über den Browser ist einfach unschön, weshalb ich nach einer Lösung gesucht habe, die den Login sowie die anschließende Bestätigung eines Users im Hintergrund simuliert, sodass er das eigentliche Programm nicht verlassen muss.
Zwischenstand: Universal Version Description (UVD) / Entwickler gesucht
Ich möchte an dieser Stelle einmal auf den aktuellen Stand des hier begonnenen Projekts verweisen, der sich wie folgt darstellt: Ich habe das UVD-Format weiter ausgearbeitet und angepasst und damit begonnen, eine C#-Bibliothek zu schreiben, die dessen Verarbeitung dient.
Als Beispiel sei die UVD von LastSharp gegeben, die wir im folgenden Codebeispiel mithilfe einer XSL-Transformation (DescriptionPage.xsl) in eine HTML-Datei verwandeln. Das soll illustrieren, wie einfach die Verwendung von UVD sein kann, wenn entsprechende Bibliotheken vorhanden sind:
UVD lastsharp = UVD.Create("http://dev.xscheme.de/uvd/lastsharp.uvd.xml");
lastsharp.Save("c:/lastsharp.htm", "http://dev.xscheme.de/uvd/DescriptionPage.xsl");
Nun haben wir eine Datei “lastsharp.htm”, die hier eingesehen werden kann und Beschreibungen in verschiedenen Sprachen und Längen bietet, Downloadlinks, etc… Außerdem sind (wie man bei der Ansicht des Quelltextes feststellen kann) auch die META-Tags zu Schlüsselwörtern und Beschreibungen bereits gesetzt, sodass die Seite auch für Suchmaschinen verwendbar ist.
Vom Gedankenspiel zum Versuch: Universal Version Description (UVD)
Das Problem der Updates
Ich bin in meinem vorletzten Artikel zum Thema Update-Check bereits darauf eingegangen: Versionsänderungen sind nicht immer leicht zu verfolgen und die Überprüfung auf Updates erfordert meist einen nicht zu unterschätzenden Programmier- und Verwaltungsaufwand. Weiterhin bedeutet es für den Entwickler selbst auch, dass er auf mehreren Hochzeiten tanzen muss: er stellt meist eine eigene Downloadseite bereit, die Links zu verschiedenen Versionen enthält, er aktualisiert gleichzeitig die Dateien, die für die Versionsüberprüfung zuständig sind, er kümmert sich um die Daten, die in irgendwelchen Softwareverzeichnissen (heise, chip.de, etc…) stehen, usw., usw… Als verantwortungsvoller Entwickler mit der Ambition, sein Programm unter die Leute zu bringen, hat man richtiggehend die Pflicht, diese Schritte durchzuführen – und das regelmäßig und mit äußerster Genauigkeit.
Hier nun also das (absolut logische und vernünftige) Konzept, das die meisten Beispiele, die man im Web zu dem Thema “Update-Check” findet, implementieren:

Augenscheinliche Probleme hierbei:
- Die Verwaltung der Programmdaten läuft (beim Otto-Normal-Programmierer) meist von Hand ab, d.h. man bearbeitet die Update-Datei (die nicht, wie im Beispiel, im XML-Format vorliegen kann), lädt sie von Hand auf den eigenen Webserver und ist aus Kompatibilitätsgründen meist an ein (demnach schwer erweiterbares) Format und an einen bestimmten Dateinamen gebunden.
- Je nachdem, wie detailliert die Update-Informationen sind (nur Versionsnummer vs. Versionsnummer, Änderungsdatum, Changelog, …), kann das Bearbeiten der Versionsdatei eine Heidenarbeit bedeuten.
- Der Entwickler muss das Programm erst einmal dazu bringen, einen funktionierenden Versions-Check durchzuführen.
- Und was passiert bei Programmen, die mehrsprachig funktionieren und beworben werden?
Die Idee im erwähnten Artikel war es also, den “Update Notification Server” nicht mehr als Eigentum des Entwicklers zu sehen, sondern als über ein API zugängliche Plattform im Internet, die Verwaltungsfunktionen komfortabel bereitstellt. Gleichzeitig wären verschiedene Bibliotheken für das API nötig, um dem Programmierer die Implementierung der Versionsprüfung fast gänzlich abzunehmen.
Was folgte, war ein Einspruch.
Wie verwende ich Lapicon in meinem eigenen Programm? (.NET)
Lapicon (Loose API Connection Language) kann (ab Version 1.0.10) auf einfache Art und Weise im eigenen Programm verwendet werden.
Um zu lernen, wie das geht, entwickeln wir hier (mit C#, aber eine Übertragung auf andere .NET-Sprachen dürfte jeder einigermaßen versierte Programmierer hinbekommen) ein Mini-Programm, das in einem Fenster zwei Eingabefelder für “Interpret” und “Titel” bereitstellt und das zugehörige Album findet. Ich gebe zu, keine bahnbrechende Idee, aber zur Demonstration reicht’s. Read the rest of this entry »