324 Tage zuvor: Restore erfolgreich

Heute ist es 303 Tage her, dass diese Webseite offline ging. Eine ziemlich lange Zeit, selbst für mich. Allerdings habe ich nur bedingt zu dieser beachtlichen Wiederherstellungszeit beigetragen. Gut einen Tag habe ich für die eigentliche Wiederherstellung auf einem anderen Webserver gebraucht. Allerdings hat es gut zehn Monate gedauert, bis ich wieder auf meine Daten zugreifen konnte.

Am 5. November waren meine Webseiten nicht mehr erreichbar. Ein Zugriff auf den Server war nicht mehr möglich, und auch ein Fern-Reboot brachte leider keine Abhilfe. Ein freundliches Nachfragen beim Hoster hat allerdings auch keine Lösung gebracht – bis zur Antwort waren bereits einige Wochen verstrichen. Da es sich bei dem Server um einen RaspberryPi in einem gratis-Hosting Programm handelte, kann man sich auch nur bedingt ueber Antwortzeiten beschweren. Jedenfalls wurden mir zwei Optionen angeboten:

  1. Die SD-Karte zum booten neu aufsetzen lassen, was eine Neukonfiguration erfordert.
  2. Den RasPi zurück schicken lassen, womit der Platz im Rechenzentrum wegfallen würde.

Das Hosting-Programm wurde in der Zwischenzeit eingestellt. Option 2 hieß daher auch, dass ein Umzug auf einen neuen Server anstehen würde. Da ich jedoch zu diesem Zeitpunkt (Dezember) bereits einige Zeit mit warten verbracht hatte, entschloss ich mich für Option 2. In Vorbereitung auf den Umzug der Webseiten erstellte ich schon einmal einen neuen Server, diesmal in der Amazon-Cloud.

Nach einigen Tagen lieft der Server in der Cloud, samt verteilter Ressourcen und Nutzung von etlichen AWS Diensten. Die Performance-Unterschiede sind gewaltig – und nebenbei habe ich noch das Know-How für Cloud-basierte Webseiten aufgebaut. Alles in allem eine sehr positive Erfahrung! Jedenfalls bis die erste Rechnung kam und das Aufräumen und das Zusammenstreichen der Dienste auf das wirklich Notwendige anfing. Am Ende kostete mich der Server samt aller Ressourcen knapp $5.50 pro Monat. Ein akzeptabler Preis.

Was nun noch fehlte, waren meine Daten. Einige Webseiten konnte ich von Backups wiederherstellen. Das Blog jedoch basiert auf einer Datenbank – und für die hatte ich kein Offsite-Backup eingerichtet. Es hieß also warten bis der RasPi eintrifft. Und das war, nach etlichen Tickets, Emails und Tweets, gestern dann endlich der Fall. 303 Tage nachdem die Webseite offline ging.

Nun also ist das Blog wieder verfügbar. Wenn ich mir anschaue wie viele Artikel ich in den letzten Jahren über diesen Zeitraum geschrieben habe, hat das Internet sie sicherlich nicht vermisst. Allerdings hatte ich durchaus ab und an das Bedürfnis einige Tricks nieder zu schreiben. Wollen wir hoffen, dass derlei auch in nächster Zukunft weiterhin der Fall sein wird.

644 Tage zuvor: Twitter-Home als Feed mit Javascript

Vor gut zwei Jahren hat Twitter einen wichtigen Schritt zur Datensicherheit gemacht. Mit Einführung ihrer API 1.1 wurde zum Ausführen vieler Funktionen eine OAuth Authentifizierung nötig. Und bei der Implementierung in (Web-) Applikationen ist dies auch meistens kein Problem. Anders sieht es da schon mit JavaScript aus.

Generell ist von einer Implementierung von OAuth in JavaScript auch deutlich abzuraten! Da die privaten Schlüssel zur einer eindeutigen Identifizierung im Klartext dem Client vorliegen müssen, gibt es keine Möglichkeit diese ausreichend vor Fremdzugriff zu schützen. Für mein letzte Projekt, eine personalisierte Browser-Startseite, war jedoch eine Server-seitige Implementation nicht zielführend.

kbo Startpage

Beim Herausarbeiten der Funktionalität stieß ich immer wieder auf Aussagen das dies generell nicht möglich sei (sogar von Twitter-Mitarbeitern). Selbstredend ist dies nicht korrekt; wenn auch die Implementation, vor allem dank des faszinierenden Signatur-Prozesses, durchaus herausfordernd ist. Um meinen Teil zum aufräumen mit diesem Gerücht beizutragen, hier jedenfalls die Früchte meiner Arbeit.

Um das Skript auszuführen benötigt man:

  1. Eine Twitter-App (zu erstellen)
  2. Authentifizierten Zugriff der App auf das eigene Profil
  3. Die CryptoJS library (hmac-sha1.js reicht)
  4. jQuery (zumindest in dem Beispiel)

Füllt man die Variablen für Consumer und Access Token aus, sollte der Aufruf von loadTwitter() das Array tweets[] mit den letzten Tweets der Twitter Home-Timeline befüllen. Und die kann man dann, zum Beispiel, in einer personalisierten Startseite verwenden.

/*
 * Retrieve Tweets from your personal Twitter home via REST.
 * (c)2015 by Kai Boenke [code@boenke.info]
 * Requires CryptoJS (hmac-sha1.js): https://code.google.com/p/crypto-js/
 * Requires jQUery: https://jquery.com/
 */
var tweets = [];
function loadTwitter(){
	twitterURL =			"https://api.twitter.com/1.1/statuses/home_timeline.json";
	twitterURLmethod =		"GET",
	twitterKey =			"xxxxxxxxxxxxxxxxxxxxxxxxx"; //Consumer Key (User)
	twitterSecret =			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; //Consumer Secret (User)
	twitterToken =			"99999999-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; //Access Token (App)
	twitterTokenSecret =	"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; //Access Token Secret (App)
	twitterNonce =			getNonce(32);
	twitterTimestamp =		Math.round(Date.now()/1000);
	
	// Generate oAuth Signature (https://dev.twitter.com/oauth/overview/creating-signatures)
	twitterParameter = [
		encodeURI('oauth_consumer_key='+twitterKey),
		encodeURI('oauth_nonce='+twitterNonce),
		encodeURI('oauth_signature_method='+"HMAC-SHA1"),
		encodeURI('oauth_timestamp='+twitterTimestamp),
		encodeURI('oauth_token='+twitterToken),
		encodeURI('oauth_version='+"1.0")
	];
	twitterParameter.sort();
	twitterSignatureBase =	twitterURLmethod +"&"+ encodeURIComponent(twitterURL) +"&"+ encodeURIComponent(twitterParameter.join("&"));
	twitterSignatureKey =	encodeURIComponent(twitterSecret) +"&"+ encodeURIComponent(twitterTokenSecret);
	twitterSignature =		encodeURIComponent(CryptoJS.HmacSHA1(twitterSignatureBase, twitterSignatureKey).toString(CryptoJS.enc.Base64));
	
	// Get tweets
	$.ajax({
		type:		twitterURLmethod,
		url:		twitterURL,
		headers:	{
			'Authorization': 'OAuth '+
				'oauth_consumer_key="'+ twitterKey +'", '+
				'oauth_nonce="'+ twitterNonce +'", '+
				'oauth_signature="'+ twitterSignature +'", '+
				'oauth_signature_method="HMAC-SHA1", '+
				'oauth_timestamp="'+ twitterTimestamp +'", '+
				'oauth_token="'+ twitterToken +'", '+
				'oauth_version="1.0"'
		}
	}).done(function(twitterData){
		// Retrieve tweets
		$.each(twitterData, function(i, tweet){
			tweets.push({
				timestamp: (new Date(tweet.created_at)).getTime(),
				link: "https://twitter.com/"+ tweet.user.screen_name +"/status/"+ tweet.id_str,
				value: tweet.text
			});
		});
	});
}

839 Tage zuvor: Intelligenz für das Intelligente Wohnen

So ein Smart-Home ist schon etwas feines: Lichter gehen von alleine aus, wenn die werten Familienmitglieder es mal wieder vergessen, der freundliche Hausgeist erinnert einen daran rechtzeitig die Mülltonnen an die Strasse zu stellen und wenn mal niemand zu Hause ist kann das Haus von ganz allein so tun als ob es doch so wäre. Um das zu bewerkstelligen muss man zum einen selbstredend die entsprechende Hardware haben. Zum anderen braucht man auch noch eine Zentrale, die alles miteinander verbindet – und letztendlich steuert.

Soweit, so einfach. Doch es bringt auch eine Reihe neuer Herausforderungen mit sich. Zum Beispiel die neuartige Frage warum eine Lampe sich morgens partout nicht einschalten lassen will. Oder weshalb das Wohnzimmer auf einmal rot leuchtet. Oder warum morgens das Radio läuft. Oder warum allabendlich die Beleuchtung im Garten angeht. Oder, oder, oder…

Was dafür bislang fehlte war ein Schaltplan für das Smarthome; denn zumindest meine Schaltzentrale bietet keine adäquate Lösung um derlei Zusammenhänge klar darzustellen. Aber dafür gibt es eine API samt XML Export der Konfiguration. Was fehlt ist lediglich ein Konverter in eine anschaulichere Darstellungsweise, zum Beispiel ein UML Diagramm (mein persönlicher Favorit für derlei ist yUML). Und das sieht dann in etwa so aus:

Schaltbild eines Smarthome

Das Bild muss sich in seiner Komplexität nicht unbedingt hinter klassischen Schaltplänen verstecken, hilft aber ebenso gut um die Fehlerursache einzugrenzen.

Das Script zum konvertieren der XML Datei in ein PHP-Array gibt es in meinem github Repository. Viel Spaß beim visualisieren!

949 Tage zuvor: Update mit noch mehr Updates

Scheinbar schreibe ich dieses Blog nur noch, um es mit Updates zu bestücken. Jedenfalls ist das in der Tat (schon wieder) der Grund aus dem ich einen Artikel schreibe. Aber man weiß ja nie wie es weiter geht…

Dem geneigten Leser mag es vielleicht aufgefallen sein, dass dieses Blog eine Weile lang nicht erreichbar war. Grund ist, dass es in der Zwischenzeit von einem Professionellen Webhoster auf eine Self-Hosting Plattform umgezogen ist. Die netten Menschen bei edis.at bieten nämlich ein tolles Gratis-Hosting für Raspberry-PI Module an. Nachdem ich mir dort vor etliche Monaten einen Slot sichern konnte, wurden nach und nach Webseiten umgezogen.

Leider hat sich dabei heraus gestellt, dass dieses Blog nicht so ohne weiteres auf der neuen Plattform (lighttpd und MySQL unter Debian) lauffähig ist. Und mit der Zeit war es auch nicht so üppig bestellt, als das ich mich direkt dahinter hängen konnte. Im Endeffekt lag es dann an ein paar fehlenden PHP-Modulen. Kleiner Tip fuer alle, die Textpattern unter lighttpd laufen lassen wollen: Mit einem 404-Handler kann man saubere URL’s realisieren!

server.error-handler-404 = "/textpattern/index.php"

Wie dem auch sei, mittlerweile scheint wieder alles zu funktionieren – wenngleich auch weniger performant als zuvor. Und wo ich schonmal dabei war, wurde auch gleich eine aktuelle Version eingespielt.

Jetzt fehlen nur noch neue Artikel…

1397 Tage zuvor: Update mit Updates

Scheinbar habe ich mir weit über ein halbes Jahr Zeit gelassen um das Update auf Textpattern 4.5.4 (dem CMS für dieses Blog) durchzuführen. Nicht, weil es so viel Arbeit ist; um genau zu sein hat es keine zehn Minuten gedauert. Eher weil es immer andere Dinge zu tun gab. Zeit raubend sind eher die Arbeiten an der Seite selbst, die im Laufe der Zeit liegen geblieben sind – aber auch die sind nunmehr abgearbeitet. Eine kleine Übersicht der Änderungen:

  • Kommentare erfordern keine Email-Adresse mehr
  • Die Suchfunktion liefert nun Ergebnisse
  • Tag-Suchen zeigen jetzt die gesamten Artikel an, nicht nur eine Ergebnisliste
  • Die Artikelnavigation am Ende der Seite wird wieder angezeigt
  • Sowohl Anderswo als auch Andere wurden repariert und aktualisiert (soweit möglich)

Außerdem wurden diverse Anpassungen am Design durchgeführt.

Wie immer gilt: Wer Fehler findet bitte melden! Ich werde dazu die kommenden Wochen die Anzeige von Fehlermeldungen aktiviert lassen. Als kleinen Ansporn habe ich insgesamt fünf Artikel freigeschaltet, die seit einiger Zeit auf Veröffentlichung gewartet haben.

Weiterlesen?

1397 Tage zuvor: Sticky-Navigation in Prototype

Sticky-Navigationen sind ja irgendwie ein Trend: Die Navigationsleiste einer Webseite bleibt dabei am oberen Fensterrand kleben, wenn man nach unten scrollt. Ist ja auch eine praktische Sache, manchmal jedenfalls.

Die gängigen Implementierungen greifen jedoch auf jQuery zurück. Soweit nichts verwerfliches, ist es doch eine weit verbreitete Standard-Bibliothek. Für die Implementierung auf diesem Blog wollte ich jedoch die ohnehin bereits verwendete Bibliothek Prototype nutzen. Doch leider gab es dazu keine Lösung. Oder zumindest konnte ich keine finden. Für die nachfolgenden Leidensgenossen hier ein passende Lösung:


1407 Tage zuvor: Zigeuner-Soße

Dem geneigten Leser mag bekannt sein, dass mich hauptsächlich der Heißhunger auf geliebte, heimische Gerichte zum Kochen gebracht hat. Kochen soll in diesem Zusammenhang, so traurig es auch sein mag darauf hinzuweisen, auf das Zubereiten von Gerichten von Grund auf heißen. Keine Tüten-Soßen, keine Dosen-Ravioli und ganz sicher auch keine Mikrowellen-Currywurst.

Eine letzte Bastion, die es zu erklimmen galt, war die Zigeuner-Soße. Einige erste Versuche sind leider nicht sehr erfolgreich geendet (zumindest was meine geschmackliche Erinnerung betraf), daher hatte ich mich zuletzt nicht mehr sehr häufig daran versucht. Heute jedoch wurden die Bemühungen von Erfolg gekrönt. Damit es beim nächsten Mal nicht wieder im Desaster endet, hier das (ziemlich einfache) Rezept:

  • Zwei Zwiebeln, in Halbkreise geschnitten
  • Eine Knoblauch-Zehe
  • Zwei Paprika (rot & grün), in kleine Streifen geschnitten
  • Circa fünf pürierte Tomaten

Die Zwiebeln scharf anbraten. Sobald die Kanten der Zwiebeln braun werden Knoblauch und Paprika dazugeben und ebenfalls mit scharf anbraten. Mit dem Tomaten-Püree ablöschen und alles kurz aufkochen. Mit Salz, Pfeffer, Paprika, ein wenig Chilli und süßem Curry nach Belieben abschmecken. Anschließend circa 30 Minuten köcheln lassen.

Dazu passt natürlich nur eines: Schnitzel mit Pommes! Obwohl es auf einem Hotdog bestimmt auch ganz vorzüglich schmecken dürfte. Zigeuner-Hotdog?

1410 Tage zuvor: Bubble-Sort in PHP

Da bin ich die Tage doch glatt dazu gekommen einige (Er-)Kenntnisse meines Algorithmus-Kurses vom letzten Jahr anzuwenden. Grund war die fehlende Funktion zur Sortierung eines Mehrdimensionalen Arrays basierend auf einem Sub-Key. Aber gut, so konnte ich mir wenigstens beweisen das ich das Konzept noch verstanden habe:

// (Bubble)Sort
do{
	$swapped = false;
	for($i=0; $i<(count($calendar)-1); $i++){
		if($calendar[$i]["stamp"] > $calendar[$i+1]["stamp"]){
			$swap = $calendar[$i];
			$calendar[$i] = $calendar[$i+1];
			$calendar[$i+1] = $swap;
			$swapped = true;
		}
	}
}while($swapped != false);

Mal schauen wann mir dann eine Anwendung für die Algorithmen zu Graphen in den Schoss fällt.

PS: Wieso gibt es in PHP eigentlich kein array_swap()?

1412 Tage zuvor: The Gathering

Ich bin jetzt schon seit zwei Tagen auf der Suche nach einem ganz bestimmtes Lied. Gothic war es wohl. Circa im Jahre 2001 – gehört wohlgemerkt. Trotz mannigfaltigen Anfragen konnte ich es bis dato nicht entdecken.

Aber immerhin habe ich dabei viel Musik zu hören bekommen. Ein wirklicher Fund, wie ich finde, ist The Gathering’s if_then_else:

1524 Tage zuvor: Stadt des Winds

Nun also Chicago. Ganze fünf Jahre hat es gedauert. Zumindest wurde eine Geschäftsreise mit freiem Wochenende daraus. Und das Frühstücksbuffet im Hotel erinnerte doch arg an alte Zeiten. Nicht des Essens wegen (grausam). Vielmehr kennt man fast jeden, der im Esssaal sitzt – alles Kollegen. Zuletzt passierte mir dies in einem ähnlich günstig (was das berufliche betrifft) gelegenen Hotel im Stuttgarter Raum.

Aber zurück zu Chicago, den sub-urbanen Teil in dem mein Hotel gelegen ist. Es erinnert einen doch arg Wohnsiedlungen die aussehen wie im Film: Lang-gezogene, grüne Vorgärten mit Auffahrten für die diversen Autos. Weiße Briefkästen am Straßenrand soweit die Strasse reicht. Chicago selbst hingegen ist anders. Anders als so vieles in diesem Land: Eine spürbar alte Stadt. Das wird einem nicht nur durch die tatsächlich nennenswert alte Geschichte auf, sondern man spürt es auch. Die überall vorhandenen Industriegebäude erinnern an die Zeiten der Industrialisierung, allerdings weniger dreckig als der Ruhrpott.

CHicago

Doch auch die klassischen Touristen-Attraktionen sind durchaus sehenswert: The Art Institute of Chicago (Zeit mitbringen! Auch wenn Google einem hier die Gemälde erklären kann), Grant Park , eine Boots-Tour über den Chicago-River oder auch einfach nur durch die Stadt zu spazieren. Chicago ist definitiv eine Reise wert! Und es gibt immer noch so viel zu sehen… Einzig mit der typischen Chicago-style Pizza konnte ich mich nicht so recht anfreunden. Sei’s drum.