Archiv des Autors: dasaweb

Über dasaweb

Blog von einem dieser Daniels: Volgelstraußartiger Friedolin, der auf die Backen braucht. (Props to Felix Blume.)

Soll ich mich überholen lassen?

Du kennst das sicher: Du fährst in einer einspurigen Einbahnstraße, Tempo 30, viel Platz ist nicht, links ist ein Gehweg, rechts parken an der Straße entlang Autos, und vor dir tümpelt ein Radfahrer vor sich hin. Du siehst schon, dass sich weiter vorne eine Lücke ergibt, ein paar Parkplätze in Folge sind frei, vielleicht so drei Stück. Du rückst dem Radfahrer ein bisschen auf die Pelle, denn selbstverständlich wird er gleich die Parklücke rechts nutzen, um dir Platz zu machen. Immerhin hält er dich ganz schön auf.

Andere Perspektive: Du merkst auf deinem Fahrrad, dass das Auto hinter dir in der Einbahnstraße vorbei will, offenbar hältst du den Fahrer auf. Obwohl hier ja Tempo 30 ist und du mit 25 km/h nicht gerade langsam unterwegs bist. 10 km/h Unterschied, das Auto fährt ja nicht nur 30, da könntest du es eigentlich vorbei lassen. Solltest es sogar. Da vorne in dem langen Stück mit den freien Parkplätzen ist eine gute Gelegenheit.

Ist es eine gute Gelegenheit? Die Situation kenne ich gut, alle paar Tage als Fahrradfahrer, ab und zu auch als Autofahrer. Schon oft dachte ich, man müsste das mal kurz durchrechen: Soll ich mich überholen lassen?

Weiterlesen

Reise mit dem Licht (Ergänzung)

Vor einer Woche hab ich ein Video empfohlen, in dem man mit Lichtgeschwindigkeit von der Sonne weg durch unser Sonnensystem “fliegt”. Dazu will ich kurz zwei Sachen ergänzen:

1) If the moon were only 1 pixel

Michael hat mich auf diese Seite aufmerksam gemacht: http://joshworth.com/dev/pixelspace/pixelspace_solarsystem.html Gleiche Idee, nur nicht als Video, sondern als scrollbare Webseite. Längere Reisen sind nur zu empfehlen mit einer Maus mit “Hyper-fast scrolling” oder ähnlichem. Oder man fliegt (wie im Video) “nur” mit Lichtgeschwindigkeit durch die Leere :

pixelspace_solarsystem

2) To Scale: The Solar System

Ein paar Jungs bauen – weil sie sonst nichts zu tun haben – unser Sonnensystem in der Wüste von Nevada maßstabsgetreu nach. Mit kleinen leuchtenden Murmeln, einem Auto, wenig Zeit, dafür viel Raum:

CSS-Puns

Wenn du weißt, was CSS ist, dann hast du vermutlich schon einmal etwas mit der Gestaltung von Webseiten zu tun gehabt. Denn CSS ist der Teil einer Webseite, der die reinen Informationen für den Betrachter (hoffentlich hübsch) aufbereitet. CSS definiert Abstände, Farben, Übergänge, Textstile, Rahmen usw.

Aber auch Spaß kann man mit CSS haben, seit einiger Zeit geistern sog. CSS-Puns durchs Netz. Kurze Codeschnipsel im CSS-Stil, die vielleicht in CSS gar keinen richtigen Sinn machen würden, aber etwas gut auf den Punkt bringen. Einfaches Beispiel:

#titanic {
    float: none;
}

Oder etwas aus meinem Urlaub:

#tower-of-pisa {
    font-style: italic;
}

Und ein Beispiel aus aktuellem Anlass:

#europe .country {
    border: none;
}

Die in meinen Augen schönste Sammlung von CSS-Puns ist diese hier von Saijo George. Durchklicken!

Reise mit dem Licht

Eigentlich habe ich mit Astronomie nicht so viel am Hut. Ist ja alles relativ, auch diese Aussage, denn vermutlich habe ich damit deutlich mehr am Hut als der Durchschnittsbürger, immerhin hatte ich Astro als Nebenfach im Studium. Meine mit Abstand peinlichste Veranstaltung im Studium war ein Referat über Braune Zwerge. Mein einziges Ziel: Mir nicht anmerken zu lassen, dass ich sowas von keine Ahnung hatte. Scheint mir geglückt zu sein. Wenn ich schon fachlich nichts konnte hatte ich wenigstens das Blenden irgendwie drauf…

Zur Sache: Seit einiger Zeit interessiere ich mich (zum ersten Mal in meinem Leben wirklich) für Astronomie. Angefangen hat das mit einem Blogpost von Ralf über einen Vortrag von Florian Freistetter, den Wikipedia als “Astronom, Blogger, Buchautor und Podcaster” vorstellt. Und in seiner Funktion als Podcaster hat er mir tatsächlich die Astronomie näher gebracht. “Sternengeschichten” nennt er seinen Podcast leicht verklärt. Kleine Episoden über Themen der Astronomie, gut und oft einfach erklärt, eher leichte Kost. Hörenswert.

Und dann hab ich – frisch Astro-begeistert – heute dieses Video gesehen. Du wirst dir vermutlich kaum die Zeit nehmen, es komplett anzusehen, aber lohnen würde es sich. Die Idee ist schlicht: Die (natürlich virtuelle) Kamera bewegt sich mit Lichtgeschwindigkeit von der Sonne weg durch unser Planetensystem. Eingeblendet ist immer der Abstand zur Sonne, die schon verstrichene Zeit, und wie lange es noch dauert, bis man den nächsten Planeten oder Asteroiden passiert. Diese Angabe eignet sich auch gut zum Vorspulen, will man etwas Zeit sparen. Die ersten gut acht Minuten bis zum Erreichen der Erde solltest du dir aber schon in Echtzeit geben. Beim Ansehen bekommt man ein sehr gutes Gefühl dafür, wie unfassbar die Distanzen im All sind, wie lange Licht unterwegs ist, viel groß der Raum und wie klein die (aus unserer täglichen Perspektive riesigen) Strukturen wie Planten etc. sind, warum eine Fahrt zum Mars so dermaßen viel schwieriger ist als eine zum Mond, warum Astronomie so schwierig ist, wie wahnsinnig hell und heiß die Sonne sein muss, um uns aus dieser Distanz noch die Haut zu verbrutzeln usw. Hut Film ab!

Eine Kreuzung aus Papier

Eine ganz gewöhnliche Kreuzung in Shibuya, einem Stadtbezirk von Tokio.  Nicht ganz gewöhnlich, es ist wohl die am stärksten frequentierte Kreuzung Japans. Wenn ich das richtig gelesen habe überqueren abends bis zu 15.000 Menschen die Ampel. Pro Ampelphase.

Und dann macht sich jemand die Mühe und baut diese Kreuzung mit “nur” 1.000 Papierfiguren nach. Mopeds, Busse, Autos, und viele unterschiedliche Menschen. Bescheuert, und bescheuert schön:

Natürlich chemisch!

Wenn mir jemand ein Lebensmittel oder irgend etwas anderes mithilfe des Etiketts “natürlich” andrehen will kotze ich statt zu kaufen. Denn bei dem Dualismus natürlich vs. chemisch fühle ich mich schlicht verarscht. Natürlich = gut, chemisch = böse. Klar, so einfach ist das nicht, aber die Richtung stimmt schon, oder? Nein, sie stimmt nicht. Das folgende Filmchen spricht mir da aus dem Herzen:

Was natürlich schon stimmt ist, dass z.B. mit Essen zu oft zu viel gepanscht wird. Aber das ist eine andere Geschichte.

Die Straße aus Sicht des Autos

Jeden Tag stürzt in den USA einen 737 ab und reißt 100 Menschen mit in den Tod. Stimmt so natürlich so nicht. Was aber stimmt ist, dass jeden Tag ca. 100 Menschen auf den Straßen Amerikas ums Leben kommen. Das ist schon eine gewaltige Zahl und unter anderem ein Grund für immer neue Assistenzsysteme und (einen Schritt darüber hinaus) eine starke Motivation für die Umsetzung des autonomen Fahrens. Autonomes Fahren ist nicht nur entspannter, sondern eben auch sicherer, auch wenn wir das nicht gerne hören wollen. Zum einen ist selbstbestimmtes Fahren immer noch ein Ausdruck für Freiheit, zum anderen wollen wir einfach nicht glauben, dass eine Maschine eine so komplexe Aufgabe wie das Fahren besser bewerkstelligen können soll als wir es selbst können. Und richtig, das Problem ist komplex. Wahnsinnig komplex. Was ein Auto alles sehen, einschätzen, berechnen und entscheiden muss wird schön im folgenden Video erklärt:

Faszinierend, wie diese System mittlerweile sogar Enten jagenden Rollstühle auf den Fahrbahnen erkennen und entsprechend reagieren kann. Und wenn wir ehrlich sind ist Autofahren gerade auch deshalb so komplex, weil die anderen Verkehrsteilnehmer unberechenbare Wesen sind wie wir selbst eben auch. Je mehr Fahrzeuge autonom unterwegs sein werden, desto berechenbarer und überschaubarer wird das System auch für das eigene autonome Fahrzeug. Und nicht nur das: Das System Straße  besteht ja aus sehr vielen Individuen, für die man versucht hat, simple Regeln so definieren, dass sich bis zu einem gewissen Grad eine Schwarmintelligenz ausbilden kann. Wie gut das funktioniert kann man auf jeder Autobahn beobachten. Nicht besonders gut nämlich. Auch hier wird sich eine Einschränkung des Individuums durch eine stärkere Kopplung positiv auf das Kollektiv auswirken, da bin ich mir sicher.

Ich fahre gerne Auto, sehr gerne sogar. Trotzdem freue ich mich auf’s gefahren werden.

Kontinuierlichere Ampel, alt, analog, echt

Ist ja nichts Neues, dass ich ein Freund kontinuierlicher Ampeln bin. Zwar geht bei einem solchen Konzept die digitale Simplizität verloren (“Bei Rot bleibe stehn, bei Grün kannst du gehn” oder “Bei Rot musst du warten, bei Grün darfst du starten”), dafür sollte die Transparenz des Systems Stress aus der Wartesituation nehmen. Glaube ich jedenfalls.

Dass ein solche analogen kontinuierlichen Ampeln bis in die 70er gab wusste ich gar nicht. Sogar Deutschland hatte bis 1972 die sog. Heuer-Ampel. Das definitiv schönste Modell hatten aber die Australier mit ihrer Marshalite, die sogar mit einer Gelbphase aufwarten konnte:

 

 

OAuth 2.0 – Lord, have mercy!

OAuth 2.0

Es gelingt mir nicht immer, auf dem Laufenden zu bleiben, was technische Entwicklungen im Web angeht. Vorsichtig ausgedrückt. Obwohl ich mich durchaus bemühe. Aber da draußen ist einfach zu viel los. So ging es auch an mir vorbei, dass Google angekündigt hatte, seinen Client-Login im April 2015 abschalten zu wollen. Oder ich habe einfach nicht verstanden, dass mich das betrifft. Hat es mich aber, und das gleich an verschiedenen Stellen.

Zum einen nutze ich an verschiedenen Stellen im Netz die Möglichkeit, Daten aus Google Tabellen auszulesen und diese weiter zu verarbeiten. Dieser Weg hat im Gegensatz zur Nutzung einer Datenbank den Charme, dass auch eine technisch nicht so versierte Gruppe von Usern sehr leicht Daten editieren kann, die dann direkt auf irgendwelchen Webseiten dargestellt oder für andere Dienste verarbeitet werden können.

Zum anderen brauchte ich diese Art der Authentifizierung für das Backup meiner Google Kontakte auf dem Raspberry Pi. Ich hatte darüber mal ausführlich geschrieben.

Die Nutzung des Client-Logins sah (vereinfacht) so aus, dass man sich bei Google-APIs mit seinen Google-Zugangsdaten authentifizieren konnte. Einen Schritt besser war es schon, dazu eine sog. “anwendungsspezifisches Passwort” zu verwenden. D.h. man generierte sich bei Google ein weiteres Passwort, welches dann nur eine einzige Anwendung verwenden durfte. Vorteil: Durch Löschen des vergebenen Passworts war auch der Anwendung der Zugriff auf die Daten entzogen, außerdem musste man nicht sein richtiges Google-Passwort in irgendwelchen Skripten hinterlegen. Umgesetzt hatte ich das alles mit Hilfe des Zend Frameworks.

Diese Möglichkeit gibt es jetzt nicht mehr. OAUth 2.0 ist angesagt. OAuth ist an sich nichts neues, aber das Ding ist einfach deutlich komplexer als die herkömmliche Authentifizierung. Wie OAuth 2.0 funktioniert genau funktioniert erkläre ich hier nicht weiter, man kann das z.B. hier schön nachlesen. Ein Artikel in 5 Teilen, das sagt schon alles. Die Grundidee ist die, dass eine Anwendung einen z.B. auf eine Google-Seite weiterleitet, man sich dort authentifiziert und somit seiner Anwendung bestimmte Rechte zuweist, ohne dass die Anwendung Details der Zugangsberechtigung erhält. Das typische “Loggen Sie sich einfach mit Facebook ein”-Ding. Der große Vorteil ist hier, dass keine Passwörter weitergegeben werden, sondern lediglich sog. Access-Tokens generiert werden, die in der Regel auch eine Verfallsdatum haben. Alles crispy, alles funky, aber eben auch alles etwas komplizierter.

Wie gesagt war der Anlass, mich wieder mal mit dem Thema zu befassen, die Reaktivierung des Backups meiner Google Kontakte mit dem Raspberry Pi. Deshalb werde ich hier mal kurz umreißen, wie das Prozedere jetzt aussieht.

Der PHP-Code

Mir ist klar, dass sich meine PHP-Künste im Rahmen halten. Der Code hier ist also nur zum Hausgebrauch und als Arbeitsgrundlage für weitere Optimierungen geeignet. Außerdem enthält er eine Reihe an Kommentaren, die eher den Stil eines Selbstgesprächs als einer sinnvollen Code-Kommentierung haben. Egal.


<?

		// Backup der Google Kontakte per Cronjob funktioniert nur noch mit OAuth2

		// Es gäbe jetzt 2 Wege:

		// 1) User authentifiziert sich per Web

		// 	Problem:
		// 	- Die Authentifizierung läuft schnell ab.
		// 	- Daher ist das per Skript nicht praktikabel.

		// 2) Authentifizierung über ein "Dienskonto" ("service account") mit einem P12-Schlüssel

		// 	Problem:
		// 	- Das Dienstkonto mit seiner speziell generierten Mailadresse kann sich zwar dauerhaft authentifizieren,
		// 	  hat aber keinen Zugriff auf die Kontakte des Users, der das Dienstkonto erstellt hat...

		// Hinweise:

		// - Erstellen eines Projekts bei Google und erzeugen der Schlüssel:		https://console.developers.google.com/project
		// - API Client Library for PHP:											https://developers.google.com/api-client-library/php/start/get_started
		// - Google Contacts API version 3.0:										https://developers.google.com/google-apps/contacts/v3/index#retrieving_all_contacts
		// - google-api-php-client:													https://github.com/google/google-api-php-client
		// - Beispielcode für Ahthentifizierung per Web:							https://github.com/google/google-api-php-client/issues/462
		// - Warum es nicht geht, sondern nur mit einer "Google managed domain":	http://stackoverflow.com/questions/14407415/accessing-google-contacts-api-via-oauth-2-0-and-private-key-aka-service-account
		// - Vielleicht geht es doch per Web-Authentifizierung???					http://stackoverflow.com/questions/13851157/oauth2-and-google-api-access-token-expiration-time

		//  >>> However, after a successful completion of the OAuth2 installed application flow,
		// 		you will get back a refresh token.
		// 		This refresh token never expires, and you can use it to exchange it for an access token as needed.
		// 		Save the refresh tokens, and use them to get access tokens on-demand
		// 		(which should then immediately be used to get access to user data).

# Debug-Modus. Wenn der TRUE ist werden nur Debug-Infos rausgeschickt:
define("DEBUGMODUS", FALSE);

# # # # VERSION MIT DER WEB-AUTHENTIFIZIERUNG

	# Diese Daten hier erhält man nach der Registrierung eines Projekts in der Developers Console (https://console.developers.google.com/):
	# Client-ID:
	$client_id 		= 'HIER KOMMT DEINE CLIENT-ID REIN';
	# Clientschlüssel:
	$client_secret 	= 'HIER KOMMT DEIN CLIENT-SCHLÜSSEL REIN';

	# Nach dem ersten Aufruf des Skripts per Webbrowser bekommt man einen RefreshToken,
	# den man hier einträgt. Mit diesem kann dann bei jedem weiteren Aufruf
	# ein neuer AccessToken geholt werden, mit dem dann wiederrum die Daten geholt werden:
	$refresh_token = 'HIER KOMMT DEIN REFRESH-TOKEN REIN';

	/*
	 * Copyright 2011 Google Inc.
	 *
	 * Licensed under the Apache License, Version 2.0 (the "License");
	 * you may not use this file except in compliance with the License.
	 * You may obtain a copy of the License at
	 *
	 *     http://www.apache.org/licenses/LICENSE-2.0
	 *
	 * Unless required by applicable law or agreed to in writing, software
	 * distributed under the License is distributed on an "AS IS" BASIS,
	 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	 * See the License for the specific language governing permissions and
	 * limitations under the License.
	 */

	# Falls das Skript per Kommandozeile ausgeführt werden soll sollen die Fehler unterdrückt werden (z.B. die Warnings wg. der Session):
	if ($refresh_token)	error_reporting(0);

	session_start();

	// # Session manuell killen, und damit neue Token erzwingen:
	// unset($_SESSION['access_token']);

	# Diese Library muss eingebunden werden: https://github.com/google/google-api-php-client
	require_once __DIR__ . '/google-api-php-client-master/examples/templates/base.php';
	require_once __DIR__ . '/google-api-php-client-master/src/Google/autoload.php';

	$scriptUri 		= "http://".$_SERVER["HTTP_HOST"].$_SERVER['PHP_SELF'];
	$redirect_uri 	= $scriptUri;

	/************************************************
	  Make an API request on behalf of a user. In
	  this case we need to have a valid OAuth 2.0
	  token for the user, so we need to send them
	  through a login flow. To do this we need some
	  information from our API console project.
	 ************************************************/
	$client = new Google_Client();
	$client->setClientId($client_id);
	$client->setClientSecret($client_secret);
	$client->setRedirectUri($redirect_uri);
	//$client->addScope("https://www.googleapis.com/auth/contacts.readonly");
	$client->addScope("https://www.google.com/m8/feeds");

	# HIER KOMMT DER ENTSCHEIDENDE PUNKT!
	# Der AccessToken soll OFFLINE sein, d.h. ich bekomme auch einen 'refresh_token',
	# mit dem ich mir dann immer wieder neu einen 'access_token' holen kann,
	# ohne die Web-Authentifizierung neu machen zu müssen.
	# Siehe https://developers.google.com/identity/protocols/OAuth2WebServer#refresh
	# PHP-Demo: http://stackoverflow.com/questions/9241213/how-to-refresh-token-with-google-api-client
	# Außerdem muss dazu noch approval_prompt=force gesetzt werden.
	# Siehe https://github.com/google/google-api-php-client/issues/263
	$client->setAccessType('offline');
	$client->setApprovalPrompt('force');

	/************************************************
	  Boilerplate auth management - see
	  user-example.php for details.
	 ************************************************/
	if (isset($_REQUEST['logout'])) {
		unset($_SESSION['access_token']);
	}
	if (isset($_GET['code'])) {
		$client->authenticate($_GET['code']);
		$_SESSION['access_token'] = $client->getAccessToken();
		$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
		header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
	}

	if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
		$client->setAccessToken($_SESSION['access_token']);
	} else {
		$authUrl = $client->createAuthUrl();
	}

	# Falls schon ein RefreshToken gesetzt ist kann das Skript per Kommandozeile ausgeführt werden:
	if ($refresh_token) {

		# Damit hole ich mir bei JEDEM Aufruf einfach einen neuen Access-Token ;-)
		$client->refreshToken($refresh_token);

		# Außerdem die Variable $authUrl löschen, sonst wird weiter unten nur die URL zum Login angezeigt:
		unset($authUrl);
	}

	/************************************************
	  If we're signed in, retrieve contacts
	 ************************************************/
	if ($client->getAccessToken()) {

		if (DEBUGMODUS) echo "<hr><h1>Session-Variablen:</h1><pre>".print_r($_SESSION, true)."</pre>";

		$_SESSION['access_token'] = $client->getAccessToken();

		$access_token = json_decode($client->getAccessToken())->access_token;
		if (DEBUGMODUS) echo "<hr><h1>Client:</h1><pre>".print_r($client, true)."</pre>";
		if (DEBUGMODUS) echo "<hr><h1>Access-Token:</h1><pre>".print_r(json_decode($client->getAccessToken()), true)."</pre>";
		if (DEBUGMODUS) echo "<hr><h1>Weitere Infos zum Access-Token:</h1><pre>".print_r(json_decode(file_get_contents('https://www.googleapis.com/oauth2/v3/tokeninfo?access_token='.$access_token)), true)."</pre>";

		# Beim ersten Aufruf soll einfach nur der Refresh-Token zurückgegeben werden, der muss dann hier ins Skript eingetragen werden:
		if (!$refresh_token) {
			echo "Bitte den Code unterhalb der Linie in das Skript in die Variable $refresh_token eintragen:<hr>";
			echo "<pre>".json_decode($client->getAccessToken())->refresh_token."</pre>";
			exit();
		}

		//$url = 'https://www.google.com/m8/feeds/contacts/default/full?max-results=3&alt=json&v=3.0&oauth_token='.$access_token;
		$url = 'https://www.google.com/m8/feeds/contacts/default/full?max-results=3000&alt=json&v=3.0&oauth_token='.$access_token;

		$response =  file_get_contents($url);

	}
	if (isset($authUrl)) {
		echo "<a class='login' href='" . $authUrl . "'>Zugriff auf Google Contacts autorisieren > KLICK!</a>";
	} else {
		if (DEBUGMODUS) echo "<hr><h1>Kontakte:</h1><pre>".print_r(json_decode($response), true)."</pre>";
		else echo $response;

	}

Dieses Skript muss auf den Raspberry Pi kopiert und so eingerichtet werden, dass es (vorübergehend) aus dem Netz erreichbar ist. Man sollte also irgend einen Webserver auf dem Pi laufen haben.

Außerdem braucht man den Google API PHP-Client, den man herunterladen und in sein Projekt einbinden muss. Könnte man auch per Composer machen, ist in diesem Fall aber vielleicht ein bisschen zu viel des Guten. Immerhin gibt es keine Abhängigkeiten von anderen Paketen.

Die Authentifizierung

Um dem Skript nun Zugriff auf die eigenen Daten zu gewähren, muss in der Google Developers Console ein neues Projekt angelegt werden: https://console.developers.google.com/ Das Projekt braucht einen beliebigen Namen. Außerdem muss man folgende APIs aktivieren:

  • Contacts API
  • Google Contacts CardDAV API
  • Google Partners API

Bin mir nicht wirklich sicher, ob man die “Google Contacts CardDAV API” hier auch braucht, aber sie schadet nicht…

Anschließend brauchen wir Zugangsdaten, die wir (tataaa!) unter “Zugangsdaten” generieren. Und zwar wählen wir “Client-ID für Webanwendung erstellen”. Wichtig ist an dieser Stelle, dass eine Weiterleitungs-URI gesetzt wird, die auf genau die URL zeigt, unter der unser PHP-Skript gerade im Netz erreichbar ist. Wenn wir die Client-ID erstellt haben bekommen wir unter anderem folgende Parameter: Eine “Client-ID” und einen sog. “Clientschlüssel”. Diese beiden Werte müssen wir jetzt in unser PHP-Skript eintragen:

# Diese Daten hier erhält man nach der Registrierung eines Projekts in der Developers Console (https://console.developers.google.com/):
 # Client-ID:
 $client_id = 'HIER KOMMT DEINE CLIENT-ID REIN';
 # Clientschlüssel:
 $client_secret = 'HIER KOMMT DEIN CLIENT-SCHLÜSSEL REIN';

Wenn wir jetzt das PHP-Skript vom Web aus aufrufen, können wir den bekannten Authentifizierungsprozess starten: Das Skript leitet weiter zu einer Google-Authentifizierungsseite, dort sollte man dann alles gut finden und brav bestätigen, und am Ende wird man zurück zu unserem Skript geleitet. Das Skript ist jetzt authentifiziert, die Kontakte bei Google abzuholen. Allerdings verfällt der dazu vergeben Access Token schon innerhalb einer Stunde. Unpraktisch, wenn das Skript die Kontakte z.B. täglich ohne Zutun des Nutzers sichern soll. Daher wird von Google gleichzeitig ein sog. “Refresh Token” angefordert. Mit Hilfe dieses Refresh Tokens kann das Skript bei jedem Aufruf einen neuen Access Token anfordern und anschließend mit diesem die Kontakte anfordern. Dazu muss man den Refresh Token irgendwo hinterlegen. Üblicherweise macht man das in einer Datenbank, der Einfachheit halber speichern wir ihn aber direkt im Skript. Das Skript zeigt den Refresh Token nach erfolgreicher Authentifizierung im Browser an, von dort kopieren wir ihn jetzt in unser Skript:

# Nach dem ersten Aufruf des Skripts per Webbrowser bekommt man einen RefreshToken,
# den man hier einträgt. Mit diesem kann dann bei jedem weiteren Aufruf
# ein neuer AccessToken geholt werden, mit dem dann wiederrum die Daten geholt werden:
$refresh_token = 'HIER KOMMT DEIN REFRESH-TOKEN REIN';

Die Ausführung

Ein Zugriff auf das Skript über das Internet ist nun nicht mehr nötig und sollte auch unterbunden werden. Denn ab jetzt soll das Skript nur noch per Kommandozeile oder Crontab ausgeführt werden, z.B. so:

php ~/skripte/backup-google-contacts.php | gzip > ~/backup/Google\ Kontakte/backup-google-contacts-`date +\%Y-\%m-\%d`.json.gz

Geschafft! Ich hoffe, der eine oder andere kann etwas mit dem Code-Chaos hier anfangen. Der Code sollte auf jeden Fall ein paar Anhaltspunkte für jemanden enthalten, der vor ähnlichen Problemen steht. Ich glaube, mir hätte das eine oder andere Code-Schnipsel weitergeholfen und mir die eine oder andere Nachtschicht erspart. Wobei, wäre vielleicht sogar schade gewesen, so ein Erfolgserlebnis ist ja auch was wert 😉

Too schön to fail

Den Zustand der Physik kann man getrost als desolat bezeichnen. Nicht, dass in den letzten Jahrzehnten nichts geleistet worden wäre, es ist einiges passiert, und auch die großen Theorien wie z.B. die Stringtheorie sind nicht einfach so vom Himmel gefallen. In dem Video, welches ich euch hier zeigen will, diskutieren die beiden Physiker Harald Lesch und Josef M. Gaßner über eben diese Stringtheorie und haben dabei so richtig Spaß zusammen. Also Josef Gaßner hat viel Spaß, während Harald Lesch das alles nicht mehr witzig finden kann. Als Zuschauer kann man aber auf jeden Fall viel Spaß haben, sogar dann, wenn man in der Schule in Physik nicht immer ganz bei der Sache gewesen sein sollte. Und wer gar keinen Zugang zu dem Thema findet, der kann sich einfach an der schlechten Bluescreen-Technik z.B. am Kopfflaum der beiden Diskutanten erfreuen.

Wie gesagt, das Thema der Diskussion ist die Stringtheorie. Harald Lesch mag sie nicht besonders, und das hat seinen Grund:

Im Fußball sagt man, er war ein großes Talent, aber er hat’s eben doch nicht gebracht. Und so scheint’s mir mit der Stringtheorie auch zu sein. Große Versprechungen und nix gehalten, nix, nicht ein Tor geschossen, nicht mal ne Ecke, nix, überhaupt nix.

Seiner Meinung nach ist die Stringtheorie zwar eine faszinierende Theorie, die aber bisher keinerlei experimentell falsifizierbaren Aussagen machen konnte. Er geht noch weiter und hinterfragt de Ansatz, mit immer neuen Theorien die Probleme vorhergehender lösen zu wollen:

Mit anderen Worten: Ich habe eine Theorie, die ein Problem hat. Dafür muss ich eine andere Theorie entwickeln, die genau die Probleme, die die erste Theorie hatte, jetzt wegnehmen kann. (…) Und dann brauch ich noch eine dritte Theorie, die die Probleme der zweiten Theorie, die aber günstigerweise die Probleme der ersten Theorie schon weggebügelt hat, auch noch wegbügelt, was natürlich zu einer vierten, n-ten und x-ten Theorie führt, die dann irgendwie alle Probleme wegmittelt, bis auf die Probleme, die sie selber produziert, was zu einer weiteren Theorie führt, die (n+1)-te Theorie, …

Dem widerspricht der Physiker und Mathematiker Josef Gaßner nicht wirklich, aber ist einfach so dermaßen fasziniert von der Schönheit dieser Theorien, wirkt fast ein bisschen verliebt. Und Liebe macht eben blind:

Die Theorie ist zu schön, too schön to fail. (…) Das Ganze hat schon einen gewissen Schick, das spricht den Mathematiker in mir schon ein wenig an.

Ich kann das nachvollziehen. Ich habe im Studium einige Theorievorlesungen gehört, bei denen ich zwar mitnichten alles verstanden haben und trotzdem sehr fasziniert von den Formulierungen der Theorien war (Bsp. Supersymmetrie). Aber Schönheit ist nicht alles. Irgendwann muss eine Theorie auch liefern, und  Lesch fragt die Community zurecht:

Ab wann wären wir bereit zu sagen, die Theorie ist tot?

Auch Gaßner fürchtet wohl, dass wir in diese Richtung unterwegs sind und formuliert in seinem Schlusswort frei nach Thomas Henry Huxley:

Das Schlimmste Drama, die größte Tragödie besteht in der Erschlagung einer schönen Theorie durch eine hässliche Tatsache.

Wie gesagt, die Unterhaltung der beiden ist äußerst unterhaltsam. Anschauen!

PS: Danke an Ralf für den Hinweis!