Freitag, 30. Dezember 2005, 11:13 Uhr

eMeidi.com goes AJAX

Gestern Abend lieferte ich mir einen Wettstreit mit Kollege Burgdorfer – wer springt als erstes auf den AJAX-Zug (oder doch eher: -Hype?) auf und baut die erste AJAX-Anwendung? Nun, ich habe gewonnen – jedenfalls mit Blick auf die Geschwindigkeit der Umsetzung. Er habe aber eine Idee in Petto, die ihn zum Millionär machen werde. Deren Umsetzung ist für diese Wochenende geplant. Mal schauen, ob er bald in die Liga von Larry Page und Sergey Brin aufsteigen wird. Ich wünsche ihm jedenfalls viel Erfolg auf dem Weg zur ersten (mit AJAX generierten) Million.

Anwendung

Doch wo findet sich nun AJAX auf eMeidi.com? Es ist die Jukebox. Diese updated sich nun alle 15’000 Millisekunden und zeigt somit immer relativ akkurat auf, welche Musik bei mir in iTunes gerade läuft. Die Information gelangt mittels einem AppleScript auf meinen Server: Das AppleScript liest den aktuellen Track aus iTunes aus und übermittelt dessen Angaben via GET an ein PHP-Script auf meinem Server. Das PHP-Script generiert aus den GET-Variablen eine simple Text-Datei, die HTML-Code enthält. AJAX macht schliesslich nichts anderes, als diese Text-Datei zu inkludieren. Wieso AJAX? Weil die Benutzer dann meine Homepage nicht jede Minute manuell nachladen müssen, um einen Songwechsel zu bemerken. Ab sofort geht das nämlich vollautomatisch.

Zugegeben: Nichts bahnbrechendes. Aber es geht ja primär darum, mit neuen Techniken in Kontakt zu kommen. Man lehrt ja gerade in unserem Business nie aus …

Umsetzung

AppleScript

Als Erstes mal den AppleScript-Code:

on idle
 set strServer to "http://www.domain.com/tracker.php"
 
 set strTitle to ""
 set strArtist to ""
 set strAlbum to ""
 
 set intIsRunning to 0
 set intIsPlaying to 0
 
 try
  tell application "System Events" --no more using the finder
   if (get name of every process) contains "iTunes" then
    set intIsRunning to 1
   end if
  end tell
  
  if intIsRunning = 1 then
   tell application "iTunes" --start talking to iTunes
    try
     if player state is playing then --now we want to see if iTunes is even playing   
      set intIsPlaying to 1
      if exists (address of current track) then
       --it's an internet stream
      else
       set strTitle to the name of the current track
       set strArtist to the artist of the current track
       set strAlbum to the album of the current track
      end if
     end if
    end try
    
   end tell
  end if
  
 end try
 
 set strURL to strServer & "?playing=" & intIsPlaying & "&artist=" & urlencode(strArtist, true, true) & "&album=" & urlencode(strAlbum, true, true) & "&title=" & urlencode(strTitle, true, true)
 
 set shellCommand to "/usr/bin/curl \"" & strURL & "\""
 do shell script shellCommand
 
 return 15
end idle

on urlencode(this_text, encode_URL_A, encode_URL_B)
 set the standard_characters to ¬
  "abcdefghijklmnopqrstuvwxyz0123456789"
 set the URL_A_chars to "$+!'/?;&@=#%><{}[]\"~`^\\|*"
 set the URL_B_chars to ".-_:"
 set the acceptable_characters to the standard_characters
 if encode_URL_A is false then ¬
  set the acceptable_characters to ¬
   the acceptable_characters & the URL_A_chars
 if encode_URL_B is false then ¬
  set the acceptable_characters to ¬
   the acceptable_characters & the URL_B_chars
 set the encoded_text to ""
 repeat with this_char in this_text
  if this_char is in the acceptable_characters then
   set the encoded_text to ¬
    (the encoded_text & this_char)
  else
   set the encoded_text to ¬
    (the encoded_text & encode_char(this_char)) as string
  end if
 end repeat
 return the encoded_text
end urlencode

on encode_char(this_char)
 set the ASCII_num to (the ASCII number this_char)
 set the hex_list to ¬
  {"0", "1", "2", "3", "4", "5", "6", "7", "8", ¬
   "9", "A", "B", "C", "D", "E", "F"}
 set x to item ((ASCII_num div 16) + 1) of the hex_list
 set y to item ((ASCII_num mod 16) + 1) of the hex_list
 return ("%" & x & y) as string
end encode_char

Download: getsonginfo-clean.scpt

ACHTUNG: Einzelne Bausteine habe ich aus dem Netz zusammengeklaubt. Dank gebührt all denen, die etwas an das Scriptlein beigesteuert haben.

Wichtig ist zum einen strServer (PHP-Script auf dem Server) und return 15 (Wartedauer in Sekunden, bis die Infos erneut abgefragt und übermittelt werden).

Prototype

Natürlich hätte ich die JavaScript-Library von Grund auf neu programmieren können, die AJAX und andere nützliche Hilfsmittel zur Verfügung stellt, um Web 2.0-Anwendungen zu realisieren. Ich habe dann der Einfachheit halber doch auf das JavaScript-Framework Prototype zurückgegriffen - insbesondere die Cross-Browser-Kompatibilität ist hier exzellent umgesetzt, weshalb man sich darüber kaum mehr Gedanken machen muss.

HTML/JavaScript

Prototype wird normal in index.html eingebunden:

<script language="javascript" src="/inc/prototype.js" type="text/javascript"></script>

Der Übersichtlichkeit halber habe ich dann meinen eigenen Code in ein separates JavaScript-Include ausgelagert. Dank Prototype reicht ein Sechszeiler aus, um die Rotation zum Laufen zu bringen:

function updatePlaylist() {
 var strElement = 'playlist';
 
 new Ajax.Updater(
  {success: strElement},
  'subdomains/dev/itunes.txt',
  {asynchronous: true}
 );
 
 window.setTimeout("updatePlaylist()",15000);
 
 return true;
}

Es gäbe auch ein Objekt Ajax.PeriodicalUpdater, aber leider fand ich im Netz gerade nirgends eine aufschlussreiche Beschreibung, weshalb ich auf das gute, alte setTimeout zurückgegriffen habe. Klappt auch damit wunderbar.

Fallstricke

Obwohl das Endresultat mit sechs Zeilen simpel daherkommt, habe ich mir daran doch etwa eine Stunde die Zähne ausgebissen. Leider verfügt Prototype über keine sehr guten Debugging-Features (oder ich habe diese schlicht nicht entdeckt). Rückblickend vermute ich eine falsch formulierte URL (http://...). Als ich die URL relativ angegeben habe, funktionierte alles plötzlich wie geschmiert.

Nachtrag: Ich habe jetzt herausgefunden, wieso es mit der URL nicht geklappt hat - ich habe mit einer Seite auf www.eMeidi.com auf dev.eMeidi.com zugreifen wollen. Das geht anscheinend nicht:

Can't access domains other than the calling domain

Quelle: AJAX Presentation Outline.

Als Nachschlagewerk empfehle ich script.aculo.us sowie AJAX Tutorial with Prototype - .cfm lebt noch? Egal, Pete hat eine sehr simple, aber bemerkenswert handliche PLZ-Nachschlagefunktion mit AJAX generiert.

Tags:
Labels: Uncategorized

Kommentar erfassen