R: Hast du dir eigentlich extra Basilikum für's Video geholt?

Daniel: Nee, Michel holt sich ständig welchen, der crazy MoFo.

R: Sah aber sehr gut aus. Kudos, Michel!

Daniel: Hä? Wofür denn? Der ist doch nur gekauft und da abgeladen! Da gehört überhaupt kein Talent dazu! Ich verlange, dass du dein Kudos zurücknimmst!

R: Michel hat bestimmt gewusst, aus welchem Winkel du filmen würdest und dann extra Basilikum besorgt und da abgestellt.

Daniel: Da halte ich es doch für realistischer, dass die Mondlandung gefälscht war. 9/11 war vielleicht ein Inside Job, aber der Basilikum bestimmt nicht.

R: Der Basilikum war filmisches Genie, geradezu meisterhaft!

Daniel: Oskar an das Basilikum?

R: Oskar an den Bühnendesigner!

Daniel: Aber war es nicht vielmehr mein filmerisches Genie, diesen Topf voll Unkraut da stehen zu lassen, bevor ich mit dem Backvorgang begann? Ich glaube schon! Michel war gar nicht in der Wohnung!

R: Aber da haben wir den Punkt: er hat es hingestellt, du hast es stehen gelassen. DAZU gehört null Talent.

Daniel: Aber ich habe das Geschirr, das die Pflanze vollständig versteckt hätte, abgespült und weggeräumt! Gehört dazu nicht visionäres Talent?

R: Okay … Du bekommst eine Nominierung. Aber Michel gewinnt.

Daniel: Weil Michel das ganze Geschirr erst angehäuft hatte, das vor seiner Pflanze stand?

R: Wie konnte ich vergessen, dass Michel immer Schuld hat an den Geschirrbergen.

Daniel: Ich vergesse das nie. WIE KÖNNTE ICH AUCH.

Achtung, Disclaimer: Michel ist NICHT alleine Schuld am Geschirrberg. Auch ich benutze Geschirr. Alle Mietparteien der Wohnung sind am Geschirrberg beteiligt.

Backen (VOR WUT) – Losstopshow 39

Ein Jahr Berlin. Wow. In diesem Video gibt es keine Highlights, aber dafür … anderes.

Lesetagebuch 5

Die neue Lesetagebuch-Version wurde letzte Nacht auf den Server geschubst.

Weise Programmierer sagen immer »Was auch immer du machst, mach auf keinen Fall einen kompletten Rewrite«, und darum bin ich Anfang des Jahres losgezogen um einen kompletten Rewrite zu machen. Wie ein echter Profi.

In den bisherigen Versionen hatte ich meine Datenbankanbindung selbst geschrieben. Das bewegte sich zwischen »Alle Objekte sind Dictionaries und enthalten nur, was die Datenbank enthält« und »Alle Objekte haben eigene Klassen, die auf verschiedene Weisen mit der Datenbank sprechen, bis auf die ›Später Lesen‹-Einträge, weil ich dafür zu faul bin«.

Natürlich war das kein dauerhaft haltbarer Zustand. Darum fing ich an, die Seite komplett neu zu schreiben, diesmal nicht nur auf Basis von Flask und Jinja2, sondern mit Hilfe von Peewee und WTForms. Peewee ist ein wunderbarer, leichter ORM, der subclassing sehr einfach macht, und WTForms geht mir manchmal auf die Nerven, erspart es mir aber, Formularvalidierung selber schreiben zu müssen.

»Und warum hat das dann so lange gedauert?«, fragt ihr euch jetzt vielleicht, »Du bekamst doch quasi alles geschenkt?«. Tja. John Lennon hat es ja schon gesagt: Das Leben ist, was passiert, während man versucht, einen Rewrite einer Bücherleseplattform zu schreiben.

Fix your life (and your URLs to static files in your Jinja templates)

Whenever you want to link to a static file in Jinja templates, you probably use url_for('static', filename=your_file). That’s great, but it may cause problems with your users, who may keep using a cached version of your kickass CSS file. But it doesn’t have to be that way. Cachebust your URLs for maximum convenience!

import app

app.create_jinja_environment()

def url_for_buster(endpoint, **values):
    if endpoint == 'static':
        filename = values.get('filename', None)
        if filename:
            file_path = os.path.join(app.root_path,
                                     endpoint, filename)
            values['q'] = int(os.stat(file_path).st_mtime)
    return url_for(endpoint, **values)

app.jinja_env.globals.update(url_for=url_for_buster)

Daniel, what are you doing?

Great question! I’m overwriting Jinja’s regular url_for function with a custom function that adds a parameter q to all URLs that link to the static endpoint, but that doesn’t change other URLs. The value of q is the timestamp of the linked file. That way, whenever you update the file, the parameter is changed and the browser thinks it’s a different file.

So, instead of linking /static/style.css, you’ll link to /static/style.css?q=1407762775. Nice.