Seit Jahren habe ich in meinem Zimmer eine Kompaktanlage (= Kassettenrekorder, CD-Player, Radio und AUX). Dooferweise ist das Kassettenfach kaputt, mit der Antenne ist auch irgendwas nicht in Ordnung und CDs habe ich kaum und höre ich wenn dann über mein MacBook bzw. importiere sie in iTunes und lege sie dann weg. Das heißt von den vier angebotenen Funktionen nutze ich ... hmm... 3-1... genau eine! Und eben diese ist nur einmal vertreten. Also nur ein AUX-Eingang, für mein Laptop, meinen Fernseher und meine NAS. Das funktioniert zur Zeit soweit, da ich einen günstiges Splitterding davor angeschlossen habe, welches man manuell - mit einem Schraubrad - auf einen der Eingänge umschalten darf.

Sinnvollste Lösung: Aufrüsten auf einen Receiver (ein Receiver ist ein Verstärker + Radio, wie ich dank Leo jetzt weiß), mit 3 - 4 AUX-Eingängen. Dieser würde dann einfach meine Anlage + Splitterding ersetzen. Perfekt. Außerdem böte sich mir dann die Möglichkeit bessere Lautsprecher anzuschließen. Lautsprecher mit einem vollerem Klang, einem stärkeren Bass und höheren Höhen. Platz genug - in meinem Zimmer - ist vorhanden.

Nagut, ich gebe zu, ich bin kein ausgebildeter Lautsprecherakkustik-Experte. Wahrscheinlich könnte ich klanglich nicht mal die 20€1 Aldi-Boxen von 400€ Bose-Boxen unterscheiden. Trotzdem werden es wahrscheinlich weder die einen noch die anderen, da ich großen Boxen für 20€ nicht vertraue und generell keine 400€ für Boxen ausgeben will. Preislich wird es von daher wahrscheinlich der goldene Mittelweg werden. Marke noch unklar.

Aber wenn ich ehrlich bin ist der Klang alleine nicht der einzige Kauffaktor. Der andere Faktor ist die Gegenwehr. Die Gegenwehr gegen meine Nachbarn, die mich jedes Wochenende liebevoll um 9 Uhr morgens mit einem unglaublich nervtötenden Klaviergeklimper aus dem Schlaf reißen. Dafür an dieser Stelle ein großes Dankeschön. Ich freue mich jedes Wochenende wieder. ♥
Was genau mein Plan ist? Ganz einfach. Meine Nachbarn sind nicht die einzigen, die laute Töne zu einer unmenschlichen Uhrzeit erzeugen können. Wir, meine baldigen Riesenboxen mit Monsterbass und ich können das auch. Und falls es beim ersten Mal nicht ausreichen sollte lauten Dubstep/Hip-Hop/Irgendwas anderes mit viel Bass abzuspielen, erwarten uns noch viele Wochenenden, an welchen wir unser Zusammenspiel perfektionieren und unsere Trackliste ausarbeiten können.

Und nach einigen Monaten werde ich dann endlich in Ruhe ausschlafen können. Alleine für diesen Traum lohnt es sich in neue Boxen zu investieren.

  1. Ich habe nicht überprüft, ob wirklich so ein Angebot bei Aldi vorliegt. [back]
6 Reaktionen Musik, Wochenende, Nachbarn +11 t1 f1

Das Offscreen-Magazin ist ein Magazin für Designer und Entwickler und handelt im wesentlichen von den "Menschen hinter Bits und Pixeln". Das zumindest steht - auf englisch - hinten drauf. Kaufen kann man es direkt über die Webseite (etwa $21 inklusive Versand) oder in "ausgewählten Buchhandlungen".

Ich wollte natürlich gerne das Porto sparen und dachte, dass wenn es eh in Berlin gedruckt wird ja auch hier verkauft werden müsste, was sich als teilweise richtig herausstellte. Denn man kann es zwar in Berlin kaufen, aber eben nur in zwei auserwählten ausgewählten Läden ("Do you read me?!" und "Pro qm"). Da mir "do you read me?!" noch aus meiner Praktikumszeit bei DOJO bekannt vorkam und ich auch schon häufiger Menschen mit den markanten "Do you read me?!"-Jutebeuteln habe rumlaufen sehen, entschied ich mich für eben diese Buchhandlung.

Dank Google Maps fand ich heraus, dass es nicht allzu schwer sein sollte von meiner Schule aus direkt zur Buchhandlung zu fahren. Eigentlich. Also machte ich mich an einem schönen Sommertag - gestern - nach der Schule auf den Weg, der mich erstmal, an der Siegessäule vorbei, zum Brandenburgertor führte.

Dort angekommen springt die Ampel natürlich grade auf rot. Ich schaffe es grade noch auf dem Fahrradweg zu bremsen. Plötzlich schnauzt mich ein Mann in freundlicher Berliner-Art von hinten an. "Erst nicht anhalten und jetzt nich' fahren können oder was?!". Ich wurde ein bisschen perplex und wusste nicht ganz genau was ich darauf jetzt antworten sollte. Aber glücklicherweise warren wir nicht alleine an der Ampel. Ein paar andere "echte Berliner" machten es sich anscheinend zur Aufgabe mich zu verteidigten und brüllten zurück, dass er doch bitte den "jungen Mann" in Ruhe lassen solle, der ihm nichts getan habe, worauf der andere "wahre Berliner" aus seinen Fingern eine Pistole bildete und sich symbolisch erschoss, was von den anderen Männern natürlich nicht unerwidert blieb. "Ja, genau, erschießen Sie sich einfach!" Ich hatte keine Lust mehr das weiter zu verfolgen und ließ mich zurückfallen.

Nachdem ich die Museumsinsel überquert hatte, wusste ich aus meiner vorherigen Kartenstudie noch, dass ich mich irgendwie links halten müsste um die Kaiserin-Augusta-Allee zu finden. Leider war dort keine Kaiserin-Augusta-Allee. Deshalb kurvte ich erstmal planlos zwischen Straßen, die "irgendwie links" waren, hin und her. Ohne Erfolg, weshalb ich begann Passanten auf der Straße zu fragen. Diese waren aber alle mysteriöserweise der Meinung, dass die Kaiserin-Augusta-Allee irgendwo anders sein müsste. In Tempelhof. Oder Mitte. Oder so. Aber auf jeden Fall nicht hier. Die letzten Passenten, die ich fragte waren zwei Männer, die vor einem Café saßen. Genau wussten sie es auch nicht. Aber sie hatten ein iPhone vor sich auf dem Tisch liegen und boten mir an, dass sie kurz nachgucken könnten. Es stellte sich heraus, dass ich etwa 6 Kilometer von der Kaiserin-Augusta-Allee entfernt war. Mein Ausgangspunkt war näher dran gewesen, als der Punkt, an dem ich mich gerade befand.

Ich war mir aber sicher, dass der Buchladen irgendwo in der Nähe sein müsse. Also suchten sie diesmal direkt nach dem Buchladen. Und Tatsache, der Buchladen war nur zwei Parallelstraßen entfernt. In der Auguststraße 28. Irgendwas muss ich mir wohl falsch gemerkt haben. Nichtsdestotrotz war ich nun endlich bei der Buchhandlung angekommen und kaufte mir das Offscreen-Magazin. 15€. Porto gespart.

Als ich den Buchladen verließ fiel mir auf, dass ich leider komplett orientierungslos war. Und dann passierte ein Zufall, der so unwahrscheinlich war, dass er eigentlich nicht echt gewesen sein konnte. Ich guckte auf die andere Straßenseite und sah plötzlich den Vater eines Bekannten, der auch auf dem Heimweg war, wie sich später herausstellte, und nur wenige Straßen von mir entfernt wohnt, an mir vorbei fahren. Also schloss ich mein Fahrrad auf und folgte ihm einfach. Bis zu einer Kreuzung ein paar Straßen weiter. Dann erkannte er mich und ich fragte ihn, wie ich denn nach hause käme. Er sagte mir, dass ich nur der Straße folgen müsse und dann am Hauptbahnhof rauskommen würde. Und so war es dann auch. Und so kam ich dann etwa eine Stunde später als geplant Zuhause an.

Aber es hat sich gelohnt, denn das Offscreen-Magazin sieht nicht nur wunderschön aus, sondern besteht auch noch aus großartigen Interviews. Und Bildern. Und kurzen Artikeln. Und mehr.

3 Reaktionen Offscreen, Berlin, Mission +11 t1 f1

Vor wenigen Tagen hat Google bekanntgegeben, dass sie an einem Projekt "Glass" arbeiten. Dahinter verbirgt sich eine Brille, die es ermöglicht, die Welt in "Augmented Reality" zu betrachten. Direkt durch die Brillengläser. Zwar sehen die Konzept-Brillen noch nicht sonderlich gut aus, aber wenn sie erstmal auf den Markt kommen sollten, wäre es sicherlich eine technische Revolution. Etwa der gleichen Meinung ist auch Dustin Curtis:

The current Glass prototypes look kind of ridiculous, but the vision for this market is massive. Wearable/embedded computing is, obviously, the post-post-PC world. It's just going to take a very long time to get there.

Wenn ihr auch eingebundene Recommendation auf eurem Blog wollt, könnt ihr euch hier das Skript runterladen. Einbinden tut ihr es dann so:

<iframe src="http://euredomain.de/quotefm.php?id=die-id-eures-artikels&color=die-gewünschte-farbe" width="600" height="178" frameborder="0" scrolling="no"></iframe>

(Das Skript basiert auf dem von Martin und Marcel).

4 Reaktionen Google, Argumented Reality, Brille +11 t1 f1

Aller Anfang ist schwer. Auch dann, wenn man sich an einem Tutorial langhangelt - zum Beispiel dem xCode-Tutorial aus dem Hause Apple - um eine neue Programmiersprache (Cocoa) zu lernen. Und toll ist auch, wenn man dann, obwohl man jeden Schritt befolgt hat, der im Tutorial beschrieben wurde, das Endprodukt ein anderes ist. Bei Apple kam ein fertiges Programm raus, bei mir eine Fehlermeldung:

Threat 1: program received SIGABRT

Leider hatte ich keine Ahnung, was diese kryptische Meldung bedeuten sollte. Auch das restliche Internet1 konnte mir nicht wirklich helfen. Aber nach einigem Ausprobieren habe ich dann doch herausgefunden, dass das mit der definierten Schriftart zu tun hat. Denn nachdem ich diese auf "Arial" geändert hatte ging es dann auch bei mir. Deshalb kann ich jetzt voller Stolz von mir behaupten: Ich bin Mac-Entwickler.

Zeit meine App im Appstore zu veröffentlichen.

  1. Ich habe den Fehler gegooglt. [back]
4 Reaktionen Mac, Cocoa, xCode +11 t1 f1

Das Ziel eines Shortlink-Services sollte es sein kurze Links zu produzieren. Das heißt, dass möglichst wenige Zeichen hinter dem Slash ("/") sein sollten, aber trotzdem eine Verknüpfung zu der Ursprungs-URL vorhanden seien muss und sich die Zeichenkombinationen nicht bei verschiedenen Links doppeln dürfen. Das klingt schwerer als es ist, wie mir dank Jonathan Snook bewusst wurde. Jonathan stellt in seinem Artikel zwei PHP-Fetzen vor, welche Zahlen zu möglichst kurzen Zeichenketten kodieren und von diesen wieder zurück in die Ursprungszahl enkodieren können.

Die Ursprungszahl ist in unserem Beispiel eine ID, die zusammen mit ihrer kombinierten Variante und der URL in eine Datenbank gespeichert werden. Das heißt unsere Datenbankstruktur sieht so aus, dass jede Zeile eine ID ("id"), die kodierte Version der ID ("converted"), die URL ("url") und, damit wir die Links auch auswerten können, eine klickezählende Zahl ("stats") beinhaltet.

CREATE TABLE IF NOT EXISTS `shortlink` (
  `id` int(100) NOT NULL AUTO_INCREMENT,
  `url` text NOT NULL,
  `converted` varchar(100) NOT NULL,
  `stats` int(25) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Dank der PHP-Funktionen, die aus den Code-Fetzen von Jonathan entstanden sind, ist es nun möglich die IDs zu kodieren. Da hier 62 mögliche, verschiedene Zeichen ("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") kombiniert werden können (ACHTUNG: MATHE) gibt es für ein Zeichen hinter dem Slash 62 (62^1), für zwei Zeichen hinter dem Slash 3.844 (62^2) und für drei Zeichen hinter dem Slash 238.328 (62^3) verschiedene, mögliche Kombinationen, etc.

Der Code

Die En- und Dekodier-Funktionen (und eine Link-Überprüfung) - geschrieben in PHP - sehen bei mir so aus:

function is_url($url) {
	if(!preg_match("#^http(s)?://[a-z0-9-_.]+\.[a-z]{2,4}#i", $url)) {
    	return false;
    } else {
    	return true;
    }
}

function url_encrypt($id) {
	$codeset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	$base = strlen($codeset);
	$converted = "";

	while ($id > 0) {
	  $converted = substr($codeset, ($id % $base), 1) . $converted;
	  $id = floor($id/$base);
	}

	return $converted;
}

function url_decrypt($converted) {
	$codeset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	$base = strlen($codeset);
	$c = 0;

	for ($i = strlen($converted); $i; $i--) {
	  $c += strpos($codeset, substr($converted, (-1 * ( $i - strlen($converted) )),1))
	  * pow($base,$i-1);
	}

	return $c;
}

Aber die Funktionen alleine reichen natürlich noch nicht aus - die Links müssen ja auch noch generiert, gespeichert und verarbeitet werden. Dafür brauchen wir erstmal Datenbank-Zugriff. Dafür benutze ich in diesem Beispiel meine PHP-Datenbankklasse (database.class.php), die ihr euch hier abspeichern könnt.

Die Initialisierung der Datenbank und ein paar Grundeinstellungen erfolgen dann wie folgt:

require_once('database.class.php');
$db = new database('hostname', 'benutzername', 'passwort', 'datenbankname');
$pass = 'passwort';   // Irgendein Passwort, dass ihr später zum Speichern und Löschen von Links braucht
$base_url = 'http://stadtpir.at/';    // Der Slash am Ende ist wichtig!

Der nächste Teil ermöglicht das Speichern und Löschen von Links, sowie das Ansehen der Statistiken für den Link und die Automatische Weiterleitung. Ist alles im Code nochmal gesondert gekennzeichnet.

if($_GET['do'] != '' && isset($_GET['url']) && $_GET['pass'] == $pass) {
	$url = rawurldecode($_GET['url']);

	if($_GET['do'] == 'remove') {      // Löschen von gespeicherten URLs
		if($db->delete('urls', '`url`=\''.$url.'\'')) {
			$note = 'true';
		} else {
			$note = 'false';
		}
	} elseif($_GET['do'] == 'stats') {        // Statistiken ansehen
		$note = (($db->get_element('urls', 'stats', '`url`=\''.$url.'\'')) ? $db->get_element('urls', 'stats', '`url`=\''.$url.'\'') : '0');
	} elseif($_GET['do'] == 'add') {        // Link hinzufügen
		if(!$db->get_element('urls', 'converted', '`url`=\''.$url.'\'')) {
			$id = $db->get_next_id('urls');

			if($db->insert('urls', array('id' => $id, 'url' => $url, 'converted' => $converted, 'stats' => 0))) {
				$note = $base_url.url_encrypt($id);
			} else {
				$note = 'false';
			}
		} else {
			$note = $base_url.$db->get_element('urls', 'converted', '`url`=\''.$url.'\'');
		}
	}
} elseif(isset($_GET['converted'])) {         // Weiterleiten
	$id = url_decrypt($_GET['converted']);
	$url = $db->get_element('urls', 'url', '`id`=\''.$id.'\'');    // URL abrufen
	if($url) {
		$db->update('urls', array('stats' => ((int)$db->get_element('urls', 'stats', '`id`=\''.$id.'\'') + 1)), '`id`=\''.$id.'\'');	// Statistiken aktualisieren
		header('HTTP/1.1 301 Moved Permanently');   // Weiterleiten
		header('Location: '.$url);
		exit;
	} else {
		$note = 'false';
	}
}

if($note != '') {
	echo $note;
}

Erklärung

Jetzt das wichtigste: Wie benutze ich das Ganze? Ganz einfach:

URL benutzen:
http://deineurl.ly/zeichenkette-die-beim-hinzufügen-angezeigt-wird

URL hinzufügen:
http://deineurl.ly?do=add&pass=deinpasswort&url=deineurl

URL entfernen:
http://deineurl.ly?do=remove&pass=deinpasswort&url=deineurl

Statistiken abrufen:
http://deineurl.ly?do=stats&pass=deinpasswort&url=deineurl

---

Der komplette Code nochmal hier. Für Fragen steht euch wie immer der Kommentarbereich offen.

---

UPDATE: Johannes hat mich gerade richtig darauf hingewiesen, dass das dekodieren im Endeffekt unnötig ist, da die enkodierte Version ja auch in der Datenbank gespeichert ist.