Unblock-Us Auto-Update Skript auf Python portiert

Kurz vor Weihnachten noch eine kurze Nachricht:

Ich habe mein Unblock-Us Auto-Update Skript auf Python portiert. Der ein oder andere hat vielleicht eine Abneigung gegen Shell-Skripte, deshalb gibt es jetzt eine Alternative.

Zu finden ist das Ganze nach wie vor auf GitHub und steht nach wie vor unter MIT-Lizenz.

Junecloud Delivery Status per PHP auslesen

Ich habe mich mal wieder hin gesetzt und einen sehr unsauberen, unschönen und schlecht dokumentierten Scraper in PHP geschrieben. Diesmal geht es um die Delivery Status Sendungsverfolgung von den Jungs und Mädels von Junecloud. Delivery Status Touch ist eine meiner „First-Homescreen“-Apps auf iPhone und iPad. Es gibt auch ein Dashboard-Widget für OS X (aber wer benutzt schon noch das Dashboard?).

Ich hatte jetzt das Problem, dass ich gerne alle Informationen zu Sendungsverfolgungen unterschiedlicher Versandunternehmen, die ich sowieso alle bei Delivery Status pflege, in auswertbarer Form auslesen wollte. Leider gibt es von Junecloud selbst dafür keine API, also musste ich, wie schon bei Runtastic, selbst Hand anlegen.

Das Ergebnis nennt sich „php-deliverystatus“ und steht ab sofort unter MIT Lizenz auf GitHub zum Download bereit.

Und so funktioniert es:

<?php         
include('class.deliverystatus.php');         
$ds = New Deliverystatus();         
$ds->setUsername('USERNAME');
$ds->setPassword('PASSWORD');
$ds->setTimeout(20);
 
$ds->login();
$myDeliveries = $ds->getDeliveries();
$ds->logout();
 
var_dump($myDeliveries);
?>

Als Ergebnis bekommt wird ein Array aus Objekten zurückgeliefert. Jedes Array-Element spiegelt eine gespeicherte Lieferung wieder. Alle Infos, die auf der Delivery Status Website angezeigt werden können, können anschließend auch weiterverarbeitet werden.

Hier mal ein Beispiel meiner aktuellen Delivery Status Lieferungen:

array(3) {
  [0]=>
  object(stdClass)#9 (4) {
    ["title"]=>
    string(11) "iPad Air 2 "
    ["tracking_url"]=>
    string(56) "https://tracking.hermesworld.com/?TrackID=71295223100561"
    ["tracking_number"]=>
    string(14) "71295223100561"
    ["information"]=>
    string(10) "www.hlg.de"
  }
  [1]=>
  object(stdClass)#18 (4) {
    ["title"]=>
    string(17) "Bench Jacke eBay "
    ["tracking_url"]=>
    string(83) "http://nolp.dhl.de/nextt-online-public/set_identcodes.do?idc=966939672912&amp;zip=95028"
    ["tracking_number"]=>
    string(12) "966939672912"
    ["information"]=>
    string(18) "nolp.dhl.de, 95028"
  }
  [2]=>
  object(stdClass)#17 (4) {
    ["title"]=>
    string(15) "TNF Jacke eBay "
    ["tracking_url"]=>
    string(83) "http://nolp.dhl.de/nextt-online-public/set_identcodes.do?idc=966939632104&amp;zip=80469"
    ["tracking_number"]=>
    string(12) "966939632104"
    ["information"]=>
    string(18) "nolp.dhl.de, 80469"
  }
}

Wie immer gilt: Viel Spaß!

Die andere Seite

Wenn man die andere Seite sehen will, kann man vielleicht auch mal die andere Seite sehen.“ (Thomas Doll)

Wir sind uns doch alle einig: Atomkraft ist schlecht, oder? Atomkraft, Atommüll und alles was mit dieser Technologie zusammen hängt wird für den Untergang der Menschheit sorgen. Deswegen steigt Deutschland aus der Atomenergie aus. Fukushima hat es doch gezeigt: Atomkraft bringt nichts als Probleme.

So oder so ähnlich klingen Aussagen, die man so ziemlich jedem Menschen, ob man denjenigen kennt oder nicht, vortragen kann, um ein zustimmendes Nicken zu bekommen. Ich kenne kaum jemanden, der dieser Aussage widersprechen würde. Aber warum ist das so? Warum gibt es eigentlich so viele Menschen, die eine so festgezurrte Meinung zu einem solchen Thema haben? Niemand von uns ist Experte für Atomenergie. Niemand von uns weiß, was „Strahlung“ überhaupt ist. Woraus eigentlich dieser schreckliche Atommüll besteht, den wir hier bei uns nicht haben wollen, weiß noch dazu auch niemand.
Die Antwort ist natürlich klar: Jeder von uns hat sich bereits bei Spiegel TV, stern TV oder in beliebigen anderen Medien darüber informieren lassen, wie schlecht die Atomenergie ist. Doch hat sich mal jemand eine Pro-Atomenergie Dokumentation angesehen?

Ich hatte letztens das Vergnügen, mir die Dokumentation „Pandora’s Promise“ anzusehen. Darin geht es um eben genau diese andere Seite der Atomenergie. Die Dokumentation ist vollständig auf Pro-Atomenergie Statements getrimmt. Es wird kein Geheimnis darum gemacht, dass der Atomenergie der Schrecken genommen werden soll. Mit Geigerzählern bewaffnet sieht man Menschen durch Fukushima, Tschernobyl und brasilianische Strände gehen. Erstaunlicher Weise ist in dieser Aufzählung der Strand in Brasilien der Ort, an dem die höchste Strahlenbelastung gemessen wird.
Die Dokumentation ist sicher nicht fehlerfrei. Es wird sehr einseitig berichtet, vieles wird etwas zu reißerisch inszeniert. Doch eines hat mir die Dokumentation mal wieder in das Bewusstsein geholt: Alles hat zwei Seiten.

Sich immer nur der allgemeinen Meinung anzuschließen ist einfach. Man stößt niemandem vor den Kopf, kann immer mitreden und findet überall gleichgesinnte. Doch ab und zu lohnt es sich, mal die andere Seite zu sehen. Ich bin auch nach „Pandora’s Promise“ kein Pro-Atomkraft-Aktivist geworden. Ich werde auch nach „Earthlings“ nicht vegan leben. Aber ich lerne dazu. Nicht weil ich hinterher weiß, wie Atomkraft funktioniert, sondern weil ich beide Seiten der Medaille, zumindest oberflächlich, gesehen habe. Nur so kann man sich mit solchen Themen überhaupt ernsthaft auseinander setzen.

Dieser Beitrag geht an die vielen Stammtisch-Philosophen die ich in letzter Zeit treffen durfte.

80 Kilogramm

Ich habe mit diesem Beitrag extra bis zu dem Tag gewartet, an dem ich mit voller Überzeugung sagen kann: Ich habe die 80 Kilogramm-Marke erreicht. Vor einigen Wochen war dieser Tag. Deshalb hier ein paar Gedanken zum Thema Gewicht, Fitness, Lebensqualität und Wohlgefühl.

Ich war nie schlank. Als Kind war ich immer einer der dickeren, Sport war mein Hass-Schulfach und einen Sportverein kannte ich nur aus Erzählungen. Ich wurde nie gemobbt, hatte viele Freunde und generell eine Kindheit wie aus dem Bilderbuch (an dieser Stelle auch einen schönen Gruß an meine Eltern, denn meine Mutter folgt mir auf Twitter). Ich hatte das Glück, mir um mein Gewicht nie Gedanken machen zu müssen. Natürlich hätte es auch anders laufen können, für mich war das aber nie ein Problem.

Als so um die 15 Jahre alt war und sich meine Realschul-Zeit dem Ende entgegen neigte, hatte ich dann mal für ca. 2 Jahre ein für meine Größe relativ normales Gewicht. Großartige Erinnerungen habe ich an die Zeit zwar nicht mehr, aber wie ich anhand alter Fotos sehen kann, muss es wohl so gewesen sein. In den Jahren von 2006 bis 2008 pendelte mein Gewicht immer zwischen 100 und 110 kg herum. Ein Problem war das damals auch nicht. Meine Ausbildung lief wie am Schnürchen, meine damalige Beziehung auch. Auch in dieser Zeit spielte für mich mein Gewicht überhaupt keine Rolle.

120 kgAb 2008 ging es dann stark bergab, oder besser gesagt: Bergauf. Nach der Ausbildung habe ich Zivildienst in einem Jugendheim gemacht. Dort gab es sozusagen eine nie versiegende Quelle an Nahrungsmitteln – vor allem Süßigkeiten. Innerhalb von 6 Monaten habe ich es geschafft mein Gewichtsminimum auf ca. 115 kg zu setzen. Kurz vor dem Studium im Sommer 2009 hatte ich dann 117 kg auf den Rippen. Die Messung habe ich in einer alten Handy-Notiz gefunden. Ganz schön beachtlich. Nachdem das Studium an meinen Nerven gezerrt hat (ein Thema für sich), ich ziemlich unzufrieden mit allem war und meine damalige Beziehung auch alles andere als rund lief, habe ich direkt noch ein paar Kilo drauf gepackt. Ich wog im Januar 2010 stolze 126 kg. Ich weiß nicht, ob es unterbewusst der Frust war oder einfach die Langeweile, aber damals war der absolute Höhepunkt erreicht.

Nachdem ich das Studium nach einem Semester an den Nagel gehangen hab (sei gegrüßt, Ausdauer) und einen Job angefangen habe, konnte ich mein Gewicht immerhin halten. Wenn man erstmal sowieso alle Klamotten neu gekauft hat und sich um sein Gewicht nach wie vor keine Gedanken macht, kommt man sogar ziemlich gut damit zurecht. Es spielt einfach keine Rolle. Der Job lief, die Beziehung rollte so vor sich hin. Eigentlich war alles im Lot. Ich war zufrieden.

Ich wäre vermutlich für den Rest meines Lebens zwischen 110 und 130 kg hin- und hergependelt, wenn meine damalige Freundin nicht den Stecker aus der Beziehungs-Steckdose gezogen hätte.
Nachdem das Licht dann aus war, konnte ich ca. vier Wochen lang stressbedingt nicht richtig Essen. Das hat dafür gesorgt, dass ich innerhalb weniger Wochen mein Gewicht von 2009 (117 kg) wieder erreicht hatte. Nachdem die stressigste Phase dann vorbei war, kam mir der Gedanke, dass „Momentum“ zu nutzen und weiter abzunehmen. Das war am 22.11.2010.

Seit diesem Tag habe ich jeden Tag mein Gewicht gemessen und aufgeschrieben. Auch heute mache ich das noch, zur Selbstkontrolle. Am 28.04.2011, also knapp 5 Monate nach dem Start war die 100 kg-Marke durchbrochen. Ich habe ca. 3,5 kg pro Monat abgenommen, was angesichts der Tatsache, dass ich überhaupt keinen Sport gemacht, sondern nur anders gegessen habe, eine ziemlich gesunde Rate ist. Zwischen dem 28.04.2011 und dem 01.07.2013 lag mein Durchschnittsgewicht bei ca. 96 kg. Ich kann sagen, dass ich in dieser Zeit eigentlich recht zufrieden mit allem war. Mein Job lief großartig, neues Auto und neue Wohnung waren da, mein neues Umfeld hatte sich etabliert. Ich hätte auch einfach aufhören können. Immerhin habe ich es geschafft, mehr als zwei Jahre lang mein Gewicht zu halten.

2013 stand aber ein Mallorca-Urlaub an. Angeheizt durch die Idee, am Strand vielleicht nicht unbedingt mit einem Wal verwechselt werden zu wollen, habe ich mich konsequent jeden Tag auf meinen Ergometer geschwungen, hauptsächlich fettarm gegessen und auf Süßigkeiten verzichtet. Innerhalb von einem Monat hatte ich, pünktlich zum Tag des Abluges mit 89 kg das bis dato geringste Gewicht erreicht, an das ich mich je erinnern konnte. Ich musste mal wieder neue Klamotten kaufen, da Hosengröße 36 an mir aussah wie aus einem schlechten Hip-Hop-Musikvideo der 90er Jahre.

Nachdem der Urlaub dann aber vorbei war und auch der Sommer sich dem Ende entgegen neigte, habe ich wieder ein paar Kilo drauf gepackt und über den Winter hinweg wieder mein Durchschnittsgewicht von 96 kg erreicht. Aber auch das war völlig in Ordnung: Meine alten Klamotten, die mir schon die vorherigen zwei Jahre treue Dienste erwiesen hatten, hatte ich ohnehin noch im Schrank. Meine Gemütslage war großartig, alles lief wie am Schnürchen. Ich konnte mich echt nicht beklagen. Und wohl gefühlt habe ich mich, wie die vorherigen zwei Jahre, sowieso.

Der wirklich spannende Part kommt allerdings jetzt. Wir sind im Januar 2014 angekommen. Es ist Silvester, jeder macht sich Vorsätze, die nicht eingehalten werden. Mein Vorsatz: Ein mal im Leben 80 Kilogram wiegen. Nicht, weil ich unzufrieden war. Auch nicht, weil ich mich selbst zu dick gefühlt hab, sondern einfach nur aus Prinzip.
Einfach um sagen zu können: „Ich war mal fett, ich war mal dick und ich war auch mal dünn.“

Foto 2-1Ich habe exzessiv damit begonnen Sport zu treiben. Anfangs mindestens 15, später 30 und gegen Ende 45 Minuten täglich. Meine Ernährung habe ich auch komplett umgestellt. Hauptsächlich Salat, kein Fastfood mehr, keine Lieferdienste mehr. Zwischendurch habe ich noch mit Juicing experimentiert. Nachdem ich das Ganze ca. 6 Monate lang durchgezogen habe, kam mit dem 07.06.2014 der Tag, an dem ich zum ersten Mal in meinem Leben die 80 kg-Marke durchbrochen hatte. Ich wog noch 79,7 kg. Mit diesem Gewicht gingen auch andere Klamottengrößen einher: Hosenweite 32, Hemden in Größe S (Regular fit) und M (Slim fit). Ein völlig neuer Kleiderschrank, sozusagen. Das Ganze hat zeitlich perfekt gepasst, denn auch in diesem Jahr sind wir wieder nach Mallorca geflogen. Die „Wal-Problematik“ spielte also in diesem Jahr keine Rolle mehr.

Neben dem geringeren Gewicht und der Kleidergröße war ich auch ziemlich fit. Radfahren konnte ich nahezu endlos, Treppenhäuser waren auch kein Hindernis mehr. Man kann also sagen, dass ich alle Vorzüge eines „schlanken“ Lebensstils mitgenommen habe.

Und das bringt uns zu heute, Ende Juli 2014. Ich wiege 79 kg, trage noch immer Hosen in Größe 32, bin noch immer schlank. Manch einer meiner Freunde nennt mich sogar „dürre“, „Gerippe“ oder gibt mir den Superhelden-Spitznamen „Lauchboy“.
Es wird also Zeit für ein Fazit und zwei für mich entscheidende Fragen:

„Hat es sich gelohnt?“ und „Geht es mir jetzt besser?“

Foto 1-1Auf beide Fragen gibt es die gleiche Antwort: Nein. Es hat sich nicht gelohnt. Verglichen mit 2010, als ich noch 47 kg schwerer war, geht es mir kein Stück besser. Mir geht es mal gut, mal schlecht, mal super. Mal lacht man, mal nicht. Mal macht der Job spaß, mal nicht. Mal ist man deprimiert, mal euphorisiert. So wie das im Leben nunmal ist. Wurde einer dieser Punkte in den letzten zwei Jahren negativ oder positiv beeinflusst, weil ich mehr oder weniger gewogen habe? Für mich nicht mal im Ansatz. Ich hatte geile Tage, Wochen und Monate als ich fett war, als ich dick war und als ich dünn war. Ich hatte gute Freunde als ich fett war, als ich dick war und auch als ich dünn war. Ich hatte einen super Job als ich fett war, als ich dick war und als ich dünn war.
Diese wesentliche Punkte waren immer gegeben. Völlig egal was sich auf meiner Waage abgespielt hat.

„Aber es ist doch toll, dass du jetzt so fit bist, oder?“ – Nein. Man muss der Realität mal ins Auge sehen: Ich habe einen Job, in dem ich 8 Stunden am Tag im Büro sitze. Mein Auto steht direkt vor dem Bürogebäude, ein Fahrstuhl fährt mich bis wenige Meter vor meinen Arbeitsplatz. Meine Wohnung liegt zwar im Dachgeschoss, aber da muss ich eigentlich auch nur 1x am Tag hoch. Meine Hobbies sind Filme, Serien und das Programmieren. Meine Wochenendaktivitäten setzen sich aus Feiern, Grillen, Filme gucken oder Radtouren zusammen. Und jetzt denkt mal drüber nach: Was bringt mir bei einem solchen Leben die Fitness? Rein gar nichts. Fit zu sein bietet in meinem Leben, womit ich vollkommen zufrieden bin, keinerlei Mehrwert. Ich gucke nicht besser Serien, weil ich jetzt 30 Liegestütze schaffe. Ich bin auch nicht besser im Programmieren, weil ich 70 km am Stück Radfahren kann. Es bringt mir unterm Strich absolut nichts. Ich brauche auch kein „Ventil“ um Frust abzubauen – ich bin ohnehin selten gefrustet.

Wer als dicker Mensch meint, abzunehmen ist die Lösung aller Probleme, der irrt gewaltig. Das Leben passiert um einen herum, völlig unabhängig vom Gewicht, der Kleidergröße oder der Fitness. Wer heute dick und unzufrieden ist, der ist morgen dünn und unzufrieden. Wer heute dünn und glücklich ist, der ist morgen auch als dicker Mensch noch glücklich.
Ich schere vieles, wie es so meine Art ist, hier mal wieder über einen Kamm. Aber als jemand der fett war, dick war und dünn war und somit alle Konstellationen durchgemacht hat, kann ich jeden dicken Menschen verstehen der von sich behauptet, dass er glücklich und zufrieden mit seinem Leben ist. Das war ich schließlich auch.

Jetzt bin ich dünn und glücklich. Dünn zu bleiben erfordert eine Menge Arbeit, glücklich zu sein nicht. Für mich ist klar, wo die Reise hin geht. Wenn ich mein Gewicht halten kann, ohne dass Sport, den ich nach wie vor hasse, mein Leben bestimmt, ist es gut. Wenn ich das nicht schaffe, ist es auch völlig in Ordnung.

Ob fett, dick oder dünn: Es spielt für mich keine Rolle.
Es geht mir als dünner Mensch nicht besser – denn auch als dicker Mensch ging es mir gut.

Wer Graphen genau so sehr mag wie ich, findet hier meinen genauen Gewichtsverlauf seit 22.11.2010:

Bildschirmfoto 2014-07-27 um 20.04.04

Runtastic-Aktivitäten per PHP auslesen

Wenn ich mich in meinem Leben dann doch mal sportlich betätige, dokumentiere ich sämtliche Aktivitäten mit Runtastic. Runtastic ist ein ziemlich umfangreiches Portal um seine Aktivitäten und Fitness zu erfassen und eine gute Übersicht zu bekommen.

Was mich schon länger stört: Runtastic bietet keine Entwickler-API an. Ich habe bislang vergeblich versucht, irgendwie an die Daten zu kommen. Selbst ein Gold-Mitgliedschaft bringt einem hier nichts: Was auf Runtastic steht, bleibt auf Runtastic. Um dieses Problem zu umgehen habe ich spontan eine PHP-Klasse geschrieben, die sich bei Runtastic einloggt und sämtliche Aktivitäten als Objekt zurück gibt. Diese Daten kann man dann natürlich auch in Datenbanken importieren oder sich eine schnelle Excel-Export Funktion basteln.

Die Klasse steht seit heute unter dem Namen „php-runtastic“ auf GitHub zum Download bereit und steht unter MIT-Lizenz.

Hier mal ein kleines Beispiel:

<?php
	include("class.runtastic.php");
 
	$runtastic = New Runtastic();
	$runtastic->setUsername("user@example.com");
	$runtastic->setPassword("verysecurepassword");
	$runtastic->setTimeout(20);
 
	if ($runtastic->login()) {
		echo "Username: " . $runtastic->getUsername();
		echo "<br />";
		echo "UID: " . $runtastic->getUid();
		echo "<br />";
		echo "<br />";
 
		$myRuntasticActivities = $runtastic->getActivities();
		echo "My latest <b>" . $myRuntasticActivities[0]->type . "</b> activity was <b>" . $myRuntasticActivities[0]->feeling . "</b>!";
	}
 
?>

Viel Spaß!

Das Spiel aller Spiele: DARK SOULS

Ich weiß überhaupt nicht wo ich anfangen soll. Von DARK SOULS habe ich über die Jahre hinweg eine ganze Menge gehört. Immer mal wieder tauchte der Name auf YouTube, Blogs oder Top-Ten-Listen auf. So richtig damit beschäftigt habe ich mit damit allerdings nie. Ich habe dann im Sommer aus purer Langeweile angefangen, das „Knallhart Durchgenommen: Dark Souls“ von GameOne zu gucken. Am Anfang habe ich überhaupt nicht verstanden, wieso Etienne Gardé und Dennis Richtarski so einen Wind um das Spiel gemacht haben. Auch nach den ersten 2-3 Folgen habe ich es immer noch nicht begriffen. Die Beiden sind verhältnismäßig oft gestorben, mussten ganze Level-Areale von vorne beginnen oder haben nach einer Stunde Spielzeit unterm Strich überhaupt keinen Fortschritt gemacht.

Die Frage die sich mir gestellt hat: Warum sollte man ein Spiel spielen, was einen als Spieler so fertig macht? Es gibt kein Netz, keinen doppelten Boden, keine echten Checkpoints. Wenn du stirbst, fängst du von vorne an. Es gibt keine Map, keinen definierten Weg. Das Spiel gibt einem rein gar nichts. Ich habe es nicht verstanden.

dark_souls_1

Aber irgendetwas muss dieses Spiel doch haben? Wenn Gaming-Veteranen das Spiel feiern und es das „Beste Spiel aller Zeiten“ nennen, dann muss doch etwas dran sein, oder nicht?
Um mich selbst davon zu überzeugen, habe ich mir DARK SOULS, was bereits im Jahr 2011 für die Xbox 360 erschienen ist, letztlich doch einfach mal besorgt. Irgendwann vor zwei Wochen war Michael bei mir um die letzte Episode von „The Walking Dead: Season 1“ zu Ende zu zocken. Als wir damit durch waren, haben wir dann aus Spaß DARK SOULS in die Xbox gelegt da er, genau wie ich, auch nicht so ganz begriffen hat, was der ganze Hype um dieses Spiel soll.

asylum_daemon

Wir legen das Spiel also in die Konsole. Es gibt kein Tutorial, keine Anleitung, keine wirkliche Passage zum einspielen. Es gibt lediglich ein oder zwei unbewaffnete Untote, an denen man kurz testen kann, ob die Batterien im Controller noch funktionieren. Die ersten Gegner sind relativ leicht. Man kommt hier mit „Button mashing“ noch durch und es stellt sich das Gefühl ein, als wäre DARK SOULS ein ganz normales Hack’n’Slay Rollenspiel. Doch weit gefehlt: Noch bevor man überhaupt den ersten echten Abschnitt des Spiels erreicht, wird man mit einem Boss konfrontiert. Der so genannte „Asylum Demon“ haut einen mit zwei Schlägen kaputt und es passiert das unausweichliche: Man stirbt. Schnell erkennt man aber, dass dies im Grunde zum Intro des Spiels gehört. Mit einem Lachen und einem leichten „I see what you did there“-Gefühl startet man wieder am Anfang des Spiels. Im nächsten Aufeinandertreffen mit dem „Asylum Demon“ ist man also schlauer und rennt an ihm vorbei in Sicherheit. Nach ein paar Minuten der Stille findet man sogar noch ein Schild, welches man nun neben dem Schwert tragen kann.

Nachdem man durch ein, zwei Gänge gelatscht ist und die doch ganz ansehnliche Grafik bestaunt hat, trifft man dann auf den ersten Gegner. „Na dann wollen wir mal!“, klingt es im Kopf, ohne überhaupt die Steuerung des Spiels begriffen zu haben. Ich weiß es noch, als wäre es gestern gewesen: Auf den Gegner zu rennend versuche ich, ihn mit ein paar Schlägen in guter alter Diablo-Manier zu killen. Doch weit gefehlt: Noch während ich schlage, holt der Gegner, wohlgemerkt der erste „richtige“ Gegner im Spiel, aus und zieht mir die Hälfte der Lebenspunkte ab. Beim Versuch auszuweichen vergesse ich, das Schild hochzunehmen und kassiere auf der Fluch den nächsten Schlag. Noch bevor ich mich versehe bin ich tot. Alles was bleibt ist der große, rote Schriftzug „YOU DIED“.

Nach einem kurzen Ladebildschirm startet man wieder am Anfang des Spiels. Richtig gelesen: Am Anfang. Nicht etwa an seiner Leiche, oder an einem Checkpoint kurz vor dem Gegner. Nein, am Anfang. Und das Beste: Man hat nichts. Man hat keine Seelen (die Währung für Waffen und Skillpoints im Spiel) und keine Erfahrung. Jedes normale Spiel würde einem nach dem Tod zumindest die Erfahrungspunkte lassen. Nicht mit DARK SOULS. Wer hier stirbt, hat es nicht verdient im Spiel weiter zu kommen. Und so fühlt es sich auch an. Nach ein, zwei Versuchen sind Michael und ich dann am ersten Bonfire (quasi der „Homebase“) angekommen, dem „Firelink Shrine“. Dort kann man sich seine „Ethos Flasks“, mit denen man sich heilen kann, wieder aufladen und dafür sorgen, dass man nach dem nächsten unausweichlichen Tod an eben diesem Bonfire wieder starten darf.

Aus dem „Knallhart Durchgenommen“ von GameOne kannte ich noch in etwa den Weg vom „Firelink Shrine“ zum nächsten Gebiet. Doch nachdem wir auf diesem Weg ca. 10 Mal in Folge gestorben sind, kam langsam der Frust durch. Wenig begeistert haben wir dann beschlossen, das Spiel aus zu machen, da uns einfach der Spaß an dem Ganze gefehlt hat. Wo bleibt der Spaß, wenn man spielt, und spielt, und spielt nur um letztlich dann doch wieder zu sterben und den selben Abschnitt wieder und wieder zu spielen? Ehrlich gesagt war ich durch mit dem Spiel. Für mich war das Experiment DARK SOULS abgehakt und auch Michael sah das ähnlich. Wir haben es an dem Abend nicht wieder an gemacht.

you_died

Am nächsten Morgen bin ich dann mit einem Gefühl aufgewacht, was mir seit langem kein Spiel mehr beschert hat: Ehrgeiz. Ich wollte dieses beknackte Spiel schlagen. Es konnte doch nicht sein, dass ich mich diesem Schrottspiel geschlagen gebe. Und wenn ich „Schrottspiel“ schreibe, dann weil ich das Spiel an diesem Morgen noch immer gehasst habe. Ich habe also den Controller genommen und angefangen zu spielen. Natürlich bin ich wieder am laufenden Band gestorben und habe keinerlei Fortschritt gemacht. Aber nach und nach habe ich gemerkt, wie ich besser wurde. Schläge parieren, Gegnern durch Rollen ausweichen oder auch das „Backstabbing“ schien ich langsam raus zu haben. Irgendwann bin ich dann auf den nächsten Boss, den „Taurus Demon„, gestoßen. Es war ein Kampf, wie ich ihn in einem Spiel lange nicht erlebt habe. Ach was: Wie ich ihn in einem Spiel noch nie erlebt habe! Ich kann mich nicht erinnern, wann ein Spiel bei mir zuletzt derartig Adrenalin freigesetzt hat. Nach bestimmt drei Versuchen habe ich das Vieh dann endlich geschafft und wurde durch eine Flut von Glücksgefühlen durchströmt. Ein Gefühl, was ich in Videospielen seit langer, langer Zeit nicht mehr gehabt habe. Und da war er dann: Der Zeitpunkt, an dem ich DARK SOULS verstanden habe.

DARK SOULS ist ein Arschloch. DARK SOULS ist kein Spiel, was man in wenigen Stunden am Wochenende durch spielt. Es ist auch kein Spiel, wo es darum geht, Erfolge frei zu schalten oder Quests abzuschließen. Es geht um den puren Kampf. Du alleine gegen den Rest der Welt. Kein Netz, kein doppelter Boden. Wenn du stirbst, fängst du neu an. Du speicherst in DARK SOULS nicht einfach ab, um am nächsten Morgen weiter zu machen. Es gibt nicht einmal die Möglichkeit, das Spiel zu pausieren. Entweder du spielst und kämpfst, oder du lässt das Spiel aus.

Aus gelassen habe ich das Spiel schon lange nicht mehr. Ich habe jetzt ca. 7 Stunden Spielzeit und bin noch immer nicht über den zweiten Abschnitt hinaus. Ich sterbe pro „Session“ mindestens 10 mal, verliere meine gesamten Seelen (und damit den gesamten Spielfortschritt) und starte am nächsten Morgen oftmals von der exakt gleichen Stelle wie am Vortag. Warum ich das mache? Um die nächste Welle der Glücksgefühle zu erreichen. Den nächsten Boss zu killen oder das nächste Bonfire zu erreichen löst solch krasse Emotionen aus, dass ich jedes Mal fast schon schockiert darüber bin, wie sehr ich mich doch innerlich über einen virtuellen Erfolg freuen kann. Doch genau das macht DARK SOULS meiner Meinung nach aus: Das Spielerlebnis selbst beschert einem echte Emotionen. Keine Erfolge, die auf dem Bildschirm auftauchen und dann in der Statistik gut aussehen. Echte Emotionen. Wut, Hass, Erleichterung, Freude. Und das alles in einer Kombination, die absolut süchtig macht.

Dieser Text mag übertrieben klingen und wer diesen Blog hier schon länger liest weiß, dass ich dazu neige, zu übertreiben. Doch der Hype gibt dem ganzen Recht. Wer DARK SOULS nicht zumindest mal ausprobiert hat, verpasst eines der geilsten Spiele aller Zeiten. Nicht wegen der guten Grafik, der tollen Story oder den einfachen Achievements, sondern wegen den puren Emotionen.

Prepare to die.

Notifications von Icinga oder Nagios per WhatsApp verschicken

Ich habe in einem anderen Post bereits erklärt, wie man WhatsApp-Nachrichten per Kommandozeile verschicken kann. Wenn die Voraussetzungen erfüllt sind, sind der Fantasie quasi keine Grenzen mehr gesetzt. Was ich als erstes mit den neuen Möglichkeiten gemacht habe ist, sämtliche Host- und Service-Notification meines Icinga-Servers von SMS auf WhatsApp umzustellen.

Das Ganze lässt sich ziemlich leicht umsetzen, wenn man erst einmal die Einrichtung von Yowsup, dem Python-Skript zum Verschicken von Nachrichten, abgeschlossen hat.

Ich erkläre hier kurz, wie man sich also in Zukunft seine Host- und Service-Notifications per WhatsApp zuschicken lassen kann.
In diesem Beispiel gehe ich davon aus, das sämtliche Yowsup-Komponenten Nagios/Icinga Plugin-Verzeichnis liegen. In diesem Fall ist es das Verzeichnis „/usr/lib/nagios/plugins/“ und wurde in der Nagios/Icinga-Konfiguration auf die „$USER1“ Variable gesetzt.

Contact-Definition erweitern

Bereits bestehende Contact-Definitionen, über die bisher Notifications an Nutzer des Nagios/Icinga ausgelöst werden, müssen um ein weiteres Attribut erweitert werden: Die Handynummer. Anfangs habe ich in meinem Fall das bereits vorhanden Attribut „pager“ genutzt, um die Handynummer für WhatsApp dem Kontakt/Nutzer zuzuweisen. Sauberer ist es allerdings, wenn dazu eine benutzerdefinierte Variable benutzt wird. Diese so genannten „Custom-Variables“ zeichnen sich durch den am Anfang stehenden Unterstrich (_) aus und können in beliebiger Anzahl angelegt werden.

Eine Contact-Definiton (/etc/icinga/objects/contacts.cfg) könnte wie folgt aussehen:

define contact{
        contact_name                    timo
	use				generic-contact
        alias                           Timo Schlueter
        email                           me@timo.in
	_whatsapp			4915777818466
	}

Um diese Benutzerdefinierte Variable (_whatsapp) nun in anderen Objekt-Definitionen von Nagios/Icinga zu nutzen, muss fortan die Variable $_CONTACTSWHATSAPP$ verwendet werden.

Command-Definition anlegen

Nach der Anpassung der Contact-Definition muss eine neue Command-Definition angelegt werden, über die der Versand der Nachrichten ausgelöst wird. An sich unterscheidet sich diese Definition kaum von der bereits im Umfang von Nagios/Icinga enthaltenen E-Mail-Notification.

Eine Command-Definition (/etc/icinga/objects/commands.cfg) könnte wie folgt aussehen:

define command {
        command_name    notify-host-by-whatsapp
        command_line    /usr/bin/python $USER1$/yowsup/yowsup-cli -c $USER1$/yowsup/config -s $_CONTACTWHATSAPP$ '$NOTIFICATIONTYPE$ Host : $HOSTNAME$ is $HOSTSTATE$ @ $LONGDATETIME$'
}
 
define command {
        command_name    notify-service-by-whatsapp
        command_line    /usr/bin/python $USER1$/yowsup/yowsup-cli -c $USER1$/yowsup/config -s $_CONTACTWHATSAPP$ '$NOTIFICATIONTYPE$ Host : $HOSTNAME$ - Service : $SERVICEDESC$ is $SERVICESTATE$ @ $LONGDATETIME$'
}

Host- und Service-Commands können selbstverständlich auch zusammengefasst werden. Da in diesem Beispiel allerdings unterschiedliche Ausgaben erfolgen sollen, bietet sich die Trennung zwischen „notify-host-by-whatsapp“ und „notify-service-by-whatsapp“ an.

Command-Definition zuordnen

Sind Contact-Definition erweitert und die Command-Definition angelegt, muss anschließend noch die Command-Definition einem Contact zugeordnet werden. In meinem Fall nutze ich Templates für die Zuordnung von Optionen zu Kontakten. Die Zuordnung kann allerdings auch direkt am einzelnen Kontakt erfolgen. Zur Vereinfachung hier die Contact-Definition von oben, welche um die Command-Definiton erweitert wurde:

        contact_name                    timo
	use				generic-contact
        alias                           Timo Schlueter
        email                           me@timo.in
	_whatsapp			4915777818466
	service_notification_commands   notify-service-by-email notify-service-by-whatsapp
	host_notification_commands      notify-host-by-email notify-host-by-whatsapp

Durch diese Definition wird dem Benutzer „timo“ ab sofort im Falle einer Status-Änderung eines Hosts oder Services nicht nur eine Mail, sondern auch eine Nachricht per WhatsApp zugeschickt.

Noch einige Hinweise:

  • Es sollten immer zwei Wege des Versands von Notifications geben. Gerade WhatsApp hat in letzter Zeit häufiger mit Serverproblemen zu kämpfen, weshalb es sich anbietet, neben WhatsApp auch noch eine Mail oder SMS zu versenden.
  • Aus Sicht des Datenschutzes ist der Versand von Nachrichten über WhatsApp gesondert zu betrachten. WhatsApp wird im Ausland betrieben und hält sich daher mit hoher Wahrscheinlichkeit nicht an die Datenschutzrichtlinien Deutschlands. Ich würde daher nicht empfehlen, sensible Daten (Server-IPs, Hostnamen etc.) über WhatsApp zu verschicken. Ich verwende Nagios/Icinga hauptsächlich zur Überwachung von Web-Anwendungen und Websites und einigen Web-Servern. In diesem Fall versende ich also ohnehin nur öffentlich zugängliche Informationen. Dies sollte im Vorfeld auf jeden Fall abgewogen werden.

Fragen oder Feedback zu der Anleitung bitte jederzeit gerne als Kommentar, Tweet oder Mail hinterlassen.

WhatsApp-Nachrichten über Kommandozeile verschicken

Es gibt mittlerweile eine ziemlich einfache Möglichkeit, per Kommandozeile Nachrichten per WhatsApp zu verschicken. Möglich ist das Ganze über die ein kleines Python-Tool namens „Yowsup„. Mit diesem Tool ist es möglich, die WhatsApp-Registrierung durchzuführen und anschließend Nachrichten zu versenden und zu empfangen. Da ich dem Empfang noch nicht getestet habe, beschreibe ich hier erst einmal, wie der Versand von Nachrichten funktioniert.

Voraussetzungen

  • eine gültige Handynummer
  • Python
    • python-dateutil
    • argparse for python < 2.7
    • libxml2
  • Yowsup

Yowsup downloaden und entpacken

Zuerst einfach das git Repository von Yowsup auf den lokalen Rechner/Server klonen. Das erledigt man über folgenden Befehl:

git clone https://github.com/tgalal/yowsup

Anschließend in den Unterordner „src“ von „yoswum“ wechseln, da dort die Kommandozeilen-Tools (yowsup-cli) liegen, die nun benötigt werden:

cd yowsup/src/

Registrierung

Bevor man Nachrichten versenden kann, muss die eigene Handynummer bei WhatsApp registriert werden. Als erstes muss die Handynummer, die zum versenden von Nachrichten genutzt werden soll, in der Config-Datei angegeben werde. Ich habe dazu einfach, weil Nerds wie ich ja tendenziell eher faul sind, einfach die Beispiel-Datei (config.example) geöffnet und angepasst:

vi config.example
cc=49 #if not specified it will be autodetected
phone=491751234321
id=
password=

Wichtig sind hier im ersten Schritt nur die Parameter „cc“ und „phone“. Unter „cc“ muss die Landeskennung angegeben werden. Für Deutschland wäre dies die „49“. Unter „phone“ muss die Handynummer angegeben werden, die für WhatsApp registriert werden soll. Das Format lautet in meinem Fall: 491751234321.

Anschließend die Datei speichern und folgenden Befehl ausführen (wir befinden uns immer noch im Ordner yowsup/src/):

python yowsup-cli -c config.example -r sms

Die Antwort könnte wie folgt aussehen:

status: sent
retry_after: 25205
length: 6
method: sms

Auf dem angegeben Handy sollte nun eine SMS mit einem Freischaltcode für WhatsApp angekommen sein. Als Beispiel dient hier mal der Code „123-987“.
Abgeschlossen wird die Registrierung mit dem Befehl:

python yowsup-cli -c config.example -R 123-987

Das Ergebnis sollte wie folgt aussehen:

Detected cc: 49
status: ok
kind: free
pw: 74beaae5d1af0c04c57c37ff0045573603ff34dd=
price: 0,89 €
price_expiration: 1389688778
currency: EUR
cost: 0.89
expiration: 1418553624
login: 491751234321
type: existing

Wichtig ist nun das Attribut „pw“. Dort steht das Passwort, mit dem der Login auf den WhatsApp-Servern durchgeführt wird. Dieses Passwort muss nun in der Config-Datei angegeben werden. Also wieder die Datei öffnen und anpassen:

vi config.example
cc=49 #if not specified it will be autodetected
phone=491751234321
id=
password=74beaae5d1af0c04c57c37ff0045573603ff34dd=

Die Registrierung und Konfiguration ist abgeschlossen. Jetzt kommt der lustige Teil.

Nachricht versenden

Nachdem die Konfiguration abgeschlossen ist, kann nun eine Nachricht versendet werden. Hierzu gibt es zwei Möglichkeiten: Zum einen kann man eine Nachricht stumpf versenden, ohne auf Antworten zu warten („Fire-and-forget“) und zum anderen kann man den interaktiven Modus starten, über welchen man im klassischen Chat-Stil Nachrichten empfangen und versenden kann.

Der Befehl für ein einfaches verschicken lautet:

python yowsup-cli -c config.example -s 4915777818466 'Hallo Welt'

Das Ergebnis dürfte in etwa so aussehen:

Detected cc: 49
Authed 491751234321
Sent message

Es wurde somit eine Nachricht vom Absender 491751234321 (der registrierten Nummer) mit dem Inhalt „Hallo Welt“ an die Nummer 4915777818466 geschickt.

Wenn der interaktive „Chat-Modus“ gestartet werden soll, genügt der Befehl:

python yowsup-cli -c config.example -i 4915777818466

Jetzt wird ein Chat-ähnlicher Dialog gestartet, über den nicht nur Nachrichten abgeschickt, sondern auch empfangen werden können.

Diese Spielerei kann nun für alle möglichen Schweinereien genutzt werden. Der Fantasie sind keine Grenzen gesetzt. Ich selbst spiele gerade mit dem Gedanken, Nagios/Icinga Notifications aus meinem Monitoring-System über WhatsApp zu verschicken.

Fragen oder Feedback zu der Anleitung bitte jederzeit gerne als Kommentar, Tweet oder Mail hinterlassen.

Unblock-Us Auto-Update Skript

Ich bin seit ca. einem Jahr absoluter Fan von Netflix. Leider gibt es in Deutschland noch immer keine vernünftige Möglichkeit, ein Abo abzuschließen und Netflix ohne Umwege zu empfangen. Man benötigt nach wie vor einen VPN- oder DNS-Anbieter der Netflix vorgaukelt, man befinde sich in den USA oder Kanada.
Es gibt sicherlich viele dieser Dienste, allerdings habe ich mich ziemlich schnell für Unblock-Us entschieden. Der Dienst stellt alternative DNS-Server ein, die man in seinem Gerät (in meinem Fall Apple TV) einstellt und somit sofort die entsprechenden Angebote von Netflix nutzen kann. Das Ganze hat gegenüber den meisten VPN-Providern den Vorteil, dass man mit nahezu voller Geschwindigkeit auf die Inhalte zugreifen kann.

Einen Nachteil hat das Ganze jedoch: Unblock-Us nutzt zur Authentifizierung die eigene IP-Adresse. Sprich: Ändert sich die IP-Adresse des eigenen Internetanschluss, so muss man diese im Unblock-Us Webinterface erst seinem Account zuteilen. Da mir das allerdings zu stressig war, habe ich mich hin gesetzt und ein kurze Shell-Skript geschrieben. Das Skript läuft nun per Cronjob auf meiner Synology DS212j NAS um 03:00 Uhr morgens und schickt meine aktuelle IP-Adresse an Unblock-Us. Somit brauche ich mich um die Aktualisierungen der Adresse nicht mehr zu kümmern.

Das hat doch was, oder? Wer Interesse an dem Skript hat, kann sich gerne bedienen. Zu ändern sind lediglich die Variablen „userlogin“ und „userpassword“. Dort gehören eure Unblock-Us Zugangsdaten rein.

Viel Spaß.

Unblock-Us Auto-Update Skript auf GitHub

#!/bin/sh                                                                                                                                                                                                   
#                                                                                                                                                                                                           
# Unblock-Us Update-Script  
#                                                                                                                                                                                
# This script automatically sends your current IP address to the Unblock-Us api.                                                                                                                             
# It can be used to update your IP adress via cron.                                                                                                                                                         
#                                                                                                                                                                                                           
# Author:       Timo Schlueter                                                                                                                                                                              
# Mail:         me@timo.in   
# Web:          www.timo.in                                                                                                                                                                                 
# Twitter:      twitter.com/tmuuh                                                                                                                                                                           
#                                                                                                                                                                                                           
# Version:      0.2                                                                                                                                                                                         
# Date:         20-12-2013                                                                                                                                                                                  
#                                                                                                                                                                                                           
# Notes:        I am not affiliated directly or indirectly with Unblock-Us                                                                                                                                  
#                                                                                                                                                                                                           
 
# Variables (user specific)                                                                                                                                                                                 
userlogin="email@example.com"                                                                                                                                                                                   
userpassword="password"                                                                                                                                                                                    
 
# Environment                                                                                                                                                                                              
apiurl="https://api.unblock-us.com/login?$userlogin:$userpassword"                                                                                                                                          
wgetcmd=$(which wget)                                                                                                                                                                                       
 
# Check if username and password are set.                                                                                                                                                                   
if [ -z $userlogin ]                                                                                                                                                                                        
        then                                                                                                                                                                                                
                echo "No password set."                                                                                                                                                                     
                exit 1                                                                                                                                                                                      
elif [ -z $userpassword ]                                                                                                                                                                                   
        then                                                                                                                                                                                                
                echo "No password set."                                                                                                                                                                     
                exit 1                                                                                                                                                                                      
else                                                                                                                                                                                                        
        # Call the api                                                                                                                                                                                      
        response=$($wgetcmd --no-check-certificate -qO- $apiurl)                                                                                                                                            
 
        # Check response from api                                                                                                                                                                           
        if [ $response == "active" ]                                                                                                                                                                        
                then                                                                                                                                                                                        
                        echo "IP address is active. You are good to go!"                                                                                                                                     
                        exit 0                                                                                                                                                                              
        elif [ $response == "bad_password" ]                                                                                                                                                                
                then                                                                                                                                                                                        
                        echo "Wrong username or password."                                                                                                                                                  
                        exit 1                                                                                                                                                                              
        elif [ $response == "not_found" ]                                                                                                                                                                   
                then                                                                                                                                                                                        
                        echo "Username not found."                                                                                                                                                          
                        exit 1                                                                                                                                                                              
        else                                                                                                                                                                                                
                echo "Unknown error. Check api url or documentantion."                                                                                                                                      
                exit 1                                                                                                                                                                                      
        fi                                                                                                                                                                                                  
fi