26C3 & das erste mal Berlin
vom 28. December 2009
Zusammen mit Florian, Martin Sigloch und Bea bin ich dieses Jahr zum CCC Kongress (26c3, heise, tagesthemen) nach Berlin gefahren. Zum Glück waren Michael und Jason schon am Abend davor da und haben uns Bändchen gekauft, denn schon am ersten Tag gegen Mittag war alles ausverkauft. Ohne sie hätten wir wieder heimfahren können. Nochmals vielen Dank dafür!
Und auch tolle Plätze hatten wir. In Sofas im ersten Stock mit Blick auf den Fernsehturm Richtung Alexanderplatz. Vor unseren Füßen habs jeden Abend ne Tesla Show die jeden Tag spektakulärer wurde. Anfangs waren es nur ein paar Blitze, ein Tag später spielte die Teslaspule schon Musik (YouTube). Das WLan war am ersten Tag erwartungsgemäß schlecht, nachdem sich aber Jason und Florian mit Switchen ausgestattet hatten, konnten wir entspannt über Kabel ins Netz. An dieser Stelle nochmal ein Danke an Florian, der auf seinem Server einen VPN-Tunnel eingerichtet hat, um nicht ungeschützt ins Netz zu müssen :-)

Es gab viel zu sehen und zu lernen. In den ersten beiden Tagen waren wir in einigen Vorträgen, die restlichen Tage haben wir die Streams gemütlich auf dem Sofa verfolgt. Dies war auch besser so, denn bei den beliebteren Vorträgen und Veranstaltungen musste man sich schon eine halbe Stunde zuvor anstellen um einen Stehplatz zu bekommen. Die Streams waren dieses mal wieder sehr professionell gemacht, auch wenn sie zu Spitzenzeiten ein paar mal ruckelten.

Interessant fand ich auch, dass man auf dem Kongress viele bekannte Gesichter gesehen hat, die man normalerweise nur von berühmten Blogs, Podcasts oder dem Fernsehn kennt.
Geschlafen haben wir in einer ziemlich billigen Absteige im Osten von Berlin, doch das war uns egal, denn alles war besser als in einer Turnhalle oder auf einem Stuhl zu schlafen. Berlin an sich ist eine echt tolle Stadt! Leider haben wir nicht all zu viel davon angeschaut, da wir die meiste Zeit auf dem Kongress waren.

Vom Alexanderplatz war ich etwas enttäuscht, den hab ich mich etwas spektakulärer vorgestellt. Aber allgemein würde ich fast behaupten, dass die Menschen in Berlin einen Tick menschlicher, sozialer, hilfsbereiter und freundlicher sind als bei uns im Schwabenländle. Ich werde auf jeden Fall bei der nächsten Gelegenheit wieder nach Berlin gehen!
RSS Feed update
vom 17. December 2009Falls sich jemand wundert, warum sein Feedreader alte Posts nun plötzlich als brandneue Posts markiert: Das liegt daran, dass ich einen kleinen Fehler im RSS Feed repariert habe (das Preface der Artikel werden jetzt auch angezeigt, danke an Bea und Benjamin für den Bug-Report!) und sich die Titel aller Posts geändert haben. Also keine Panik, der einzige neue Artikel ist dieser hier :)
Kommentar schreiben,
del.icio.us
Adventskalender 2009
vom 2. December 2009Dieses Jahr haben Florian und ich uns einen besonderen Adventskalender ausgedacht. Wir werden uns jeden Tag abwechseln, wobei Florian jeden zweiten Tag ein Kommandozeilentool vorstellen wird und ich euch im gleichen Rhythmus mit einem kleinen 2D-Spiel in die Open Source Scene einführen werde.
Wir freuen uns natürlich auf regelmäßige Besuche und auch rege Teilnahme. Florians Teile werden jeweils in sich abgeschlossen sein, mein Teil dagegen ist zusammenhängend und bezieht jeden der mitmachen will mit ein.
Viel Spaß und eine schöne Vorweihnachtszeit!
Kommentar schreiben,
del.icio.us
Schandfleck
vom 19. November 2009Ok, jetzt ist es offiziell: Meine Wohnung ist ein Schandfleck der Gesellschaft und muss schleunigst entfernt werden. Bürger von Heilbronn werden zur Mithilfe aufgefordert.
Donald Knuth, der Meister der Lyrik
vom 3. August 2009Donald E. Knuth ist die lebende Legende im Softwareumfeld. Er widmet schon über Jahrzehnte hinweg sein Leben der Forschung und der formalen Beschreibung von Algorithmen. Sein "still in progress" Band Art of Computer Programming ist wahrlich ein Meisterwerk. Interessant ist aber, dass sich die wenigsten Informatiker an dieses monströse Werk wagen. Er ist auch der Auffassung, dass Programmcode mit der selben Sorgfalt verfasst werden sollten wie literarische Texte. Dokumentation und Code sollten vereint sein.
"Let us change our traditional attitude to the construction of programs. Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do." - Donald E. Knuth
Da ich auch einen gewissen Standard an Dokumentation und Programmcode habe und meinen Code ästhetisch ansprechend formatiere und schreibe (bzw. den Code so gestalte, dass er mich anspricht :)), bin ich natürlich immer wieder auf der Suche nach Vorbildern.
Deshalb dachte ich mir, wieso nicht mal den Quellcode von TeX (einem Textsatzsystem von Herrn Ph. D. Knuth persönlich) anschauen. Und tatsächlich: Im ersten Moment dachte ich, der Code sei nur die Dokumentation zu TeX. Er liest sich wie eine Definition oder ein Informatikbuch. Hier mal ein kleiner Auszug:
@ Now comes the harder part: At this point in the program, |cur_val| is a
nonnegative integer and $f/2^{16}$ is a nonnegative fraction less than 1;
we want to multiply the sum of these two quantities by the appropriate
factor, based on the specified units, in order to produce a |scaled|
result, and we want to do the calculation with fixed point arithmetic that
does not overflow.
@<Scan units and set |cur_val| to $x\cdot(|cur_val|+f/2^{16})$...@>=
if inf then @<Scan for \(f)\.{fil} units; |goto attach_fraction| if found@>;
@<Scan for \(u)units that are internal dimensions;
|goto attach_sign| with |cur_val| set if found@>;
if mu then @<Scan for \(m)\.{mu} units and |goto attach_fraction|@>;
if scan_keyword("true") then @<Adjust \(f)for the magnification ratio@>;
@.true@>
if scan_keyword("pt") then goto attach_fraction; {the easy case}
@.pt@>
@<Scan for \(a)all other units and adjust |cur_val| and |f| accordingly;
|goto done| in the case of scaled points@>;
attach_fraction: if cur_val>=@'40000 then arith_error:=true
else cur_val:=cur_val*unity+f;
done:
Abgesehen von der gewöhnungsbedürftigen Syntax ist das fast schon lyrik, was er da an den Tag legt. Leider sind nicht alle Programmiersprachen so biegsam, aber Ruby geht hier schon sehr in die richtige Richtung. Also hier ein Aufruf an alle: Doku + Code = Awesome! :)
Load Balancing für Ruby
vom 28. July 2009Web-Anwendungen werden immer anspruchsvoller und komplexer. Sobald der erste Server in die Knie geht, muss man sich Gedanken über Performance und Lastverteilung machen. Gerade bei Anwendungen, die mit Ruby oder Python geschrieben wurden, stößt man häufig schneller an die Grenzen als mit anderen Skriptsprachen wie PHP oder Perl.
Für Ruby gibt es mehrere Ansätze, wie man die Last auf mehrere Server verteilen kann. Ich möchte hier nun eine der vielen Möglichkeit vorstellen. Für dieses Beispiel verwende ich Lighttpd als Webserver, Thin als Dispatcher, Ramaze als Web-Framework und MySQL zur Datenhaltung.

Fangen wir von vorn an: Wenn ein Request eintritt, wird zuerst entschieden, ob das anzufragende Objekt erst noch generiert werden muss. Wird ein Bild, eine CSS-Datei oder eine andere statische Datei angefragt, kann diese direkt zurückgeliefert werden. Anders sieht es bei Webseiten aus, die zuerst durch Ruby gerendert werden müssen. Hier kommt die Lastverteilung mit ins Spiel. Wir konfigurieren Lighttpd so, dass er die Last auf zwei andere Webserver umleitet. Hier die nötige Konfiguration:
$HTTP["host"] =~ "example\.com" {
server.document-root = "/var/www/"
$HTTP["url"] !~ "^/(css|images|js|libs)" {
proxy.balance = "fair"
proxy.server = ( "/" => (
("host" => "192.168.0.50", "port" => 7000),
("host" => "192.168.0.51", "port" => 7000)
))
}
}
Thin selbst muss natürlich auf den beiden Hosts 192.168.0.50 und 192.168.0.51 gestartet und konfiguriert werden. Das nimmt uns Ramaze ab, in dem wir in der app.rb (der "Startdatei") folgendes hinterlegen:
Ramaze.start( :adapter => :thin, :port => 7000, :file => __FILE__ )
Mit dieser Konfiguration starten wir die Anwendung auf beiden Hosts. Thin kann auch von Hand gestartet werden, der Befehl dazu ist, wer hätte es anders erwartet: "thin". Wenn die Performance in die Knie geht, kann man so einfach eine neue Thin-Instanz auf einem separaten Server starten und einbinden.
Natürlich lässt sich jetzt noch die Datenbank auf mehrere Server verteilen. Hier sollte man allerdings darauf achten, dass der Server mit dem Anwendungscode und der Datenbankserver physikalisch im selben LAN bzw. im selben Rechenzentrum untergebracht sind, denn sonst ist zwar die Last verteilt, aber die Performance geht in den Keller, da mehr Zeit zum Übertragen der Datensätze verbraten wird als das eigentliche berechnen.
Active Browsing, Teil 2
vom 23. July 2009Im letzten Beitrag habe ich über Active Browsing geschrieben und der Mächtigkeit, die jeder User im Grunde hat, diese aber nicht nutzt. Wir wollen uns nun das Leben mit ein paar Zeilen Code vereinfachen.
Installation der Komponenten
Um ruby-libnotify und mechanize nutzen zu können, müssen sie zuerst installiert werden. Bei Mechanize ist das kein Problem, da es schon als rubygem vorliegt. Ein simples gem install mechanize installiert das Paket, inklusive nokogiri für das Parsen der Webseiten. Bei ruby-libnotify muss man selbst Hand anlegen und mit dem Dreischritt ruby extconf.rb && make && make install das Paket zusammenbauen und installieren. Wer das Paket libopenssl-ruby noch nicht installiert hat, sollte das zuvor erledigen.
Login und Parsing
Der Erste Schritt ist nun, sich auf der Webseite anzumelden und die Titel aller Jobaufträge aus der HTML Datei herauszusuchen. Wir binden zuerst die Pakete mechanize und nokogiri ein, um damit arbeiten zu können.
require 'mechanize' require 'nokogiri'
Als nächstes kümmern wir uns um den Login. Hier kommt uns mechanize sehr entgegen, denn es bietet ein simples Interface zur HTML-Seite. Machen wir zuerst Gebrauch von den Methoden get und submit:
class TextBroker
def initialize(mail, pass)
@agent = WWW::Mechanize.new
@mail, @pass = mail, pass
login
end
private
def login
page = @agent.get('http://www.textbroker.de/')
loginForm = page.form('login-autoren')
loginForm.author_mail = @mail
loginForm.pass = @pass
@agent.submit(loginForm, loginForm.buttons.first)
end
end
Unter @agent ist die mechanize-Instanz abgelegt, die wir im Konstruktor initialisieren. Die private Methode login läd zuerst die Startseite mit get herunter und greift sich das Login Formular der Autoren anhand der ID. Die Attribute author_mail und pass sind Formularfelder, die sich so befüllen und auslesen lassen. mit submit wird das Login-Formular abgeschickt. In der mechanize Instanz wird nun der Cookie gesetzt, um dauerhaft eingeloggt zu sein. Ab jetzt können wir GET/POST-Anfragen innerhalb des passwortgeschützten Bereichs starten ohne sich erneut einzuloggen.
Sammeln wir nun die Jobs ein, die auf der Seite verfügbar sind. Ich habe die Methode fetch genannt, und in die TextBroker Klasse integriert. (In Ruby sind alle Klassen offen und können so erweitert werden, hier wird also keine neue Klasse angelegt, sondern die bestehende erweitert)
class TextBroker
def fetch
page = @agent.get('http://www.textbroker.de/a/search.php')
links = page.links.select {|l| !l.href.nil? and l.href.include?("search.php?hdl_id=") }
links.map {|l| l.text }
end
end
Wir stellen einen neuen GET-Request, um uns die HTML-Seite mit den Jobangeboten zu besorgen. über das Attribut links erhalten wir ein Array von allen Links, die auf der Seite verfügbar sind. Daraus selektieren wir uns alle, die im href Attribut den String "search.php?hdl_id=" enthalten haben. Da wir nur am Linktext interessiert sind, erstellen wir mit map ein Array der Linktexte und geben diese zurück.
Damit sind wir schon mit dem ersten Teil fertig und können uns eine Liste der Aufträge holen.
wwwAccess = TextBroker.new('mail@aaron-mueller.de', 'xxx')
pp wwwAccess.fetch #=> ["...", "...", ...]
Im nächsten Schritt werden wir diese Information auswerten und grafisch aufbereiten, so dass der User nur das sieht, was er wirklich sehen will: Die neu hinzugekommenen Jobaufträge.
Darstellung
Da ich unter GNOME arbeite, habe ich mich für das GTK Binding entschieden. Zusammen mit ruby-libnotify ist das Zusammenstecken einer GUI ganz einfach. Zuerst einmal binden wir wieder die benötigten Bibliotheken ein:
require 'gtk2' require 'RNotify'
Da wir unser Programm in der Notification Area positionieren wollen, brauchen wir grundlegend nur ein Gtk::StatusIcon und die Notification selbst.
statusIcon = Gtk::StatusIcon.new
statusIcon.stock = Gtk::Stock::DND_MULTIPLE
statusIcon.tooltip = "Textbroker.de Benachrichtigung"
notify = Notify::Notification.new("Header", "Content", nil, statusIcon)
notify.timeout = 5000
Um nun in regelmäßigen Abständen nach neuen Aufträgen zu suchen, und um diesen Vorgang starten und stoppen zu können, verbinden wir das Signal "activate" (was für einen Linksklick steht) mit einem Stück Code:
wwwAccess = TextBroker.new('mail@aaron-mueller.de', 'xxx')
fetchThread = nil
statusIcon.signal_connect("activate") {|widget, event|
if fetchThread.instance_of? Thread
fetchThread.terminate
fetchThread = nil
statusIcon.stock = Gtk::Stock::DND_MULTIPLE
else
statusIcon.stock = Gtk::Stock::JUMP_TO
fetchThread = Thread.new do
oldJobs = []
loop do
newJobs = (jobs = wwwAccess.fetch) - oldJobs
oldJobs = jobs
if !newJobs.empty?
content = "\n\n"
newJobs.each {|job| content += job + "\n" }
notify.update("Neue Schreibaufträge vorhanden", content, nil)
notify.show
end
sleep 60
end
end
end
}
Dies bedarf einer Erklärung: Jedes mal, wenn das Icon gedrückt wird, soll es entweder den fetchThread starten und in regelmäßigen Abständen nach neuen Jobs suchen, oder den aktuellen Thread beenden. Um dies zu visualisieren, ändern wir das Icon bei jeden Klick. Wird der Thread gestartet, läuft er in eine Endlosschleife, die alle 60 Sekunden unsere fetch Methode aus der TextBroker Klasse aufruft und dann mit dem letzten Stand überprüft. Gibt es Veränderungen (ist also das newJobs Array nicht leer), rufen wir die Methode update vom Notification Objekt auf und zeigen diese an.
Damit man das Programm auch anständig beenden kann, geben wir dem Icon noch ein Kontextmenü mit einem Beenden Eintrag.
menu = Gtk::Menu.new
menuQuit = Gtk::ImageMenuItem.new(Gtk::Stock::QUIT)
menuQuit.signal_connect("activate") {|widget, event| Gtk.main_quit }
menu.append(menuQuit)
statusIcon.signal_connect("popup-menu") {|widget, button, time|
if button == 3
menu.show_all
menu.popup(nil, nil, button, time)
end
}
Am Ende müssen wir nur noch die Notification initialisieren und in den Event-Loop von GTK hineinspringen. Danach übernimmt GTK die Ablaufkontrolle.
Notify.init("textbroker-notification")
Gtk.main
Zusammengezählt sind das nun ca. 80 Zeilen Code, nicht viel für eine solche Aufgabe. Dieses Vorgehen lässt sich auf beliebige Resourcen anwenden und erleichtert den Alltag ungemein. Allerdings kann man nicht oft genug darauf hinweisen, dass man hier Funktionalität erstellt, die vom Autor der Webseite (oder einer anderen Resource) so nicht vorgesehen wurden, entweder aus Faulheit oder aber aus gutem Grund.
Habt ihr Ideen, wo man eine solche Technik einsetzen kann? Oder habt ihr selbst schon das ein oder andere Tool geschrieben? Soll ich öfters solche "Beispielprojekte" vorstellen? Lasst es mich in den Kommentaren wissen. :)
Active Browsing, Teil 1
vom 23. July 2009Wer bei meinem Vortrag mit dem Titel "Fix the web with Greasemonkey" dabei war, weiß was gemeint ist. Für alle anderen ein kleiner Abriss: Das Web liefert uns aufbereitete Daten in einer Form, die der Ersteller festlegt. Oft ist es aber so, dass man nur an einer bestimmten Information interessiert ist und alles andere am Liebsten ausblenden würde oder auf eine andere Art und Weise dargestellt bekommen möchte. Mechanismen, die dazu beitragen, die Informationen so darzustellen, wie es einem selbst am besten gefällt, nennt man Active Browsing. Mittlerweile gibt es einige Tools, um sich das Surfen etwas zu personalisieren und nach den eigenen Wünschen zu formen.
Mit dem schon erwähnten Greasemonkey - einem Firefox-Addon - kann man durch einfache Javascript-Dateien die Darstellung umgestalten, in dem man in den DOM-Baum eingreift. Ein anderes Beispiel ist Readability, welches durch ein Bookmarklet nur den eigentlichen Content einer Seite anzeigt.
Diese Tools vereinfachen das Surfen ungemein, aber es gibt oft genug Situationen, wo man regelmäßig eine bestimmte Information auf einer Webseite abfragen will, bspw. den Flottenstatus bei einem Onlinespiel oder ob jemand neue Artikel bei eBay eingestellt hat. Für gewöhnlich geht man hier alle paar Stunden auf die Seite, loggt sich ein, hangelt sich durch ein paar Menüs und sucht die Information, die meistens nur aus einer Zahl oder einer Liste bestehen, heraus. Wie praktisch wäre es doch, wenn solche Seiten einen RSS-Feed oder eine andere API anbieten würden, damit man immer zur richtigen Zeit mit den entsprechenden Informationen versorgt werden würde. Dies ist allerdings in den seltensten Fällen so. Eine bessere Möglichkeit muss also her!
Hinweis: Da ich nach der Springerlink Aktion (eingeweihte wissen Bescheid) etwas vorsichtig geworden bin was "Web-Automatismus" angeht, soll das folgende Beispiel nur das Konzept verdeutlichen und dient NICHT zur eins zu eins Nachahmung. Deshalb stelle ich auch nicht den kompletten Code online, sondern nur die einzelnen Stücke separat. Zudem wird das Verfahren oft missbräuchlich verwendet. Grundsätzlich ist jeder selbst für sein Handeln verantwortlich und sollte mit gesundem Menschenverstand und Rücksicht auf den Webseitenbetreiber vorgehen, denn dieser stellt schließlich den Service bereit und trägt den Traffic.
Um mit dem Nachfolgenden etwas anfangen zu können, muss man kein Ruby können und auch kein Linux verwenden, es soll nur das Konzept beschrieben werden. Ähnliche Tools und Bibliotheken gibt es in fast jeder Sprache.
So, nun also zum Thema! Weiter oben habe ich die Problematik mit den immer wiederkehrenden Schritten, um an eine bestimmte Information zu kommen, schon angesprochen. Diesen Umstand wollen wir vereinfachen. Als Beispiel nehme ich das Portal textbroker.com, auf dem Autoren Texte für Geld schreiben können und Kunden Anfragen für Texte stellen können. Leider gibt es mehr Autoren als Kunden, so sind die meisten Aufträge schon nach ein paar Minuten nach der Einstellung vergeben. Sprich, man muss entweder Glück haben und im richtigen Moment die Stellenbeschreibung anschauen oder eben alle paar Minuten das folgende Szenario abspulen:
Auf die Startseite gehen und sich anmelden. Zum Glück speichert Firefox nach dem ersten Mal ein Cookie und dieser Schritt muss nur einmal am Tag gemacht werden. Dann auf "Aufträge Zeigen" und anschließend auf den Button "Suche starten" klicken. Nun bekommt man alle verfügbaren Aufträge angezeigt. Da man meist nur an bestimmten Aufträgen interessiert ist, und die Liste alle verfügbaren Aufträge anzeigt, muss man diese nach Änderungen durchsuchen und kann sich dann entscheiden, ob man den Auftrag annehmen will oder nicht.
Diesen Vorgang wollen wir automatisieren, aber nicht im Browser, sondern mit einem externen Programm. Die Idee ist, dass sich das Programm selbständig in regelmäßigen Abständen auf der Webseite einloggt, die Liste der verfügbaren Aufträge holt und diese dem User über die Notification Area der Schnellstartleiste (unter Windows wird das meines Wissens SysTray genannt), als Notification (Sprechblase) anzeigt. Das Ergebniss soll so aussehen:

Um dies ohne händisches Parsen von XML Dateien oder umständliche wget/curl Aufrufe zu lösen, gibt es im Ruby Umfeld einige interessante Projekte. Eines davon nennt sich mechanize, das die Interaktion mit Webseiten um einiges vereinfacht. So wird dem Programmierer beispielsweise das Cookie-Handling komplett abgenommen und auch das Parsen der HTML-Seiten ist erschreckend simpel. Ein weiteres tolles Projekt ist ruby-libnotify, welches ein Wrapper für libnotify implementiert, um Betriebssystem Notifications darzustellen.
Mit diesen beiden Helfern wollen wir ein Programm zusammennageln, das uns immer die neusten Jobangebote anzeigt. Wie dies funktioniert, erfahrt ihr im nächsten Blogeintrag :)
Kommentar schreiben,
del.icio.us
Mit GIT und Ramaze zum Ziel
vom 11. June 2009Wer mich kennt, weiß dass Ruby seit ein paar Jahren meine Lieblingsprogrammiersprache ist. Da ich zur Zeit durch das Praxissemester bei IBM täglich mit PHP und dem Zend-Framework arbeiten muss, tut es richtig gut, privat mit Ruby zu programmieren. Im Webbereich ist RubyOnRails ja mittlerweile zu einem quasi-Industriestandard geworden. Mir ist das Framework aber zu groß, zu aufgebläht, zu schwerfällig und komplex. Deshalb hab ich mich - mal wieder - auf die Suche nach einem für mich besseren Web-Framework gemacht und bin auf Ramaze gestoßen. Ideal für mein aktuelles Projekt (von dem ich bald berichten werde).
Ramaze ist wirklich nur ein Framework zur Entwicklung, nichts anderes. Es steht jedem Entwickler frei, welchen Server, welche DB-Schnittstelle und welche Template Engine man verwenden möchte. Der SourceCode ist super dokumentiert und durchgetestet. Aber das Beste an diesem Framework ist die Community und die Entwickler selbst. Ich hatte zu Beginn ein paar Anlaufschwierigkeiten, die ich im IRC innerhalb von ein paar Minuten gelöst bekam.
Beim Programmieren habe ich einen kleinen Bug gefunden, der eigentlich schnell behoben war. Auf der Seite fand ich leider kein Bug-Tracker o.ä., also beschloss ich mit der Anleitung ein Patchfile zu generieren. Nachdem ich den Patch an manveru im IRC geschickt hatte, war er 10 Minuten später im trunk eingeflochten. So macht das Spaß!
Bisher bin ich mit Subversion als Versionsverwaltung immer gut gefahren, auch wenn viele nicht damit zurechtkommen oder darüber fluchen. Doch GIT wird mir von Tag zu Tag sympathischer.
Kommentar schreiben,
del.icio.us
Geocaching
vom 11. June 2009Allein in Baden-Württemberg sind über 14 Tausend Schätze versteckt, von denen die meisten gar nichts wissen, und die, die von den Schätze wissen, geben alles daran, dass sie nicht beim Finden erwischt werden. Ich hab schon des Öfteren von Geocaching gehört, aber mich nie richtig damit beschäftigt, da ich kein tragbares GPS-Gerät habe. Heute haben Bea und ich uns auf den Weg gemacht und gleich mal den ersten Cache direkt vor meiner Wohnung gehoben. Zur Navigation haben wir einen BlackBerry Bold 9000 mit der Black Star Software verwendet.
Weil wir beim ersten schnell fündig wurden, haben wir uns natürlich danach was komplexeres herausgesucht. Der dreiteilige Multi-Cache SIDK war schon ziemlich herausfordernd für den Anfang. Beim ersten GPS-Punkt angekommen, fanden wir nach 5 Minuten suchen weitere GPS-Koordinaten, die uns mitten in die Stadt führten. Als wir dann da ganz unauffällig nach dem nächsten Hinweis suchten, fragte uns plötzlich einer "Habt ihr auch euren Schlüssel verloren?" und grinste :) Es stellte sich dann heraus, dass er auch auf der Suche war. Gemeinsam haben wir es dann gefunden.
Den dritten Teil mit Nacht-Cache Finale haben wir nicht hinbekommen, aber das wird noch!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16