Männer, die auf Ziegen starren
Das Szenario und die Schauspieler sollten den Film verkaufen. George Clooney, Ewan McGregor, Jeff Bridges und Kevin Spacey spielen die Hauptrollen in einer absurden Geschichte um von der US-Armee im Zuge der Hippiebewegung ausgebildeten Jedikrieger, die mittels eventuell vorhandenen übernatürlichen Fähigkeiten alle Kriege beenden sollten. Ob es diese Kräfte gibt, daran lässt der Film immer einen Hauch Zweifel.
Ewan McGregor spielt einen Reporter, der von seiner Frau verlassen wird und daraufhin in den Irakkrieg zieht. Er kommt erst gar nicht über die Grenze, trifft dann aber George Clooney, den Jeff Bridges in dieser Hippie-Einheit ausgebildet hatte. Kevin Spacey war da auch drin und neidisch und mischt dann auch im Irak nochmal mit.
Das ganze ist schon ein bisschen amüsant und nicht langweilig, aber es ist auch nicht richtig lustig. Gerade wenn man das mit Wayne's World vergleicht. Oder wenn man wegen Jeff Bridges an The Big Lebowski denkt, dann fehlt hier die ganze Atmosphäre. Für eine Komödie ist das nicht gut genug, ein absurdes Szenario und gute Schauspieler reichen manchmal eben nicht.
Wayne's World
Diese Komödie ist unlösbar mit Mike Myers verbunden. Dessen Filme mit Austin Powers ich toll fand, und Love Guru wie der Rest der Welt dann nicht mehr. Wenn man sich Wayne's World anschaut ist der Kontrast verblüffend: Auch dieser Film ist albern, aber gleichzeitig irgendwie cool und vor allem nicht eklig.
Wayne's World ist von der Struktur her eine romantische Komödie. Aber die Frau und der Protagonist passen auf den ersten Blick nicht, Cassandra (Tia Carrere) und Wayne optisch ein ungleiches Paar. Ein paar Szenen durchbrechen das gut.
Dazu sind Wayne und sein Partner Garth Algar (Dana Carvey) schon an sich absurde Charaktere, erfolglose Rockfans, die eine unfreiwillig komische Fernsehsendung im Keller von Waynes Eltern produzieren. Die ein Produzent kaufen will, der natürlich an Cassandra interessiert ist. Damit ist die Handlung dann klar.
Nur dass das alles noch teilweise im Stil einer Doku gefilmt wird, Wayne und Garth dann auch direkt zur Kamera und also zum Zuschauer reden, Mittel für einige der Gags.
Die Komödie funktioniert, die meisten Witze sitzen. Natürlich sind es eben Popkulturanspielungen aus einem anderen Jahrtausend (und manche die man kennt wurden wohl hier geprägt), aber das macht es weder langweilig noch unlustig.
Blade Runner 2049
Nicht jeder mag Blade Runner. Aber für andere ist es ein absoluter Kultfilm. Einen Nachfolger zu so einem Film zu machen muss schwierig sein: So viele Chancen, alte Fans zu vergraulen, das Ansehen des Vorgängers zu beschädigen oder in das andere Extrem zu rennen: Nur absolute Fans des Vorgängers anzusprechen.
Meinem Eindruck nach ist Blade Runner 2049 ein toller Film geworden, der diese Schwierigkeiten hervorragend löst. Ich will Spoiler vermeiden, daher sei zur Handlung nur gesagt dass sie sich wieder um einen Blade Runner dreht, der Replikanten jagt. Und dabei auf eine größere Sache stößt.
Der Film ist gelungen, weil er:
- Die Ästhetik des Vorgängers einfängt und doch auch eigene Akzente setzt. Und dabei ganz nebenbei hervorragend aussieht.
- Die Welt behutsam erweitert.
- Die vorherige Handlung nicht ignoriert.
- Trotzdem nicht alle Mysterien löst.
- Hervorragende Schauspieler hat. Und damit meine ich nicht nur Ryan Gosling, sondern auch Ana de Armas und Robin Wright.
Man vergleiche das mit Star Wars, besonders Harrison Fords Rolle.
Ich muss das mit der Ästhetik nochmal betonen. Da sind zwei Aspekte: Da ist diese Kopie der futuristischen, aber düsteren Stadt. Mit fliegenden Autos, leuchtenden Plakaten und gigantischer menschenfeindlicher Architektur. Diese Szenen vermitteln genau den gleichen Eindruck wie zuvor, als ob sie die gleiche Technik verwendet hätten. Und dann sind da Erweiterungen, die Hologramme beispielsweise oder die weiten Landschaften außerhalb, die 2049 einen eigenen Charakter geben. Unheimlich gut gemacht.
Der ersten Blade Runner gefiel mir übrigens, aber ich habe ihn nur einmal und vor nicht zu langer Zeit gesehen.
Umfrage zu Pipes
Ein paar von euch hatten ja Pipes ausprobiert. Ich bin derzeit sehr am Überlegen, wie sich die Seite im nächsten Jahr entwickeln soll. Ich habe ein paar Ideen, will aber gar nicht zu sehr beeinflussen, denn: Ich habe zum Ideensammeln eine Umfrage angelegt. Wer ein bisschen Interesse an der Seite hat sei hiermit herzlich gebeten, die (sehr kurze!) Umfrage auszufüllen oder mir auf sonstigem Wege seinen Eindruck oder seine Ideen zukommen zu lassen.
Später schreibe ich dazu bestimmt noch etwas mehr.
Rubys FastGettext ist tatsächlich schnell
Ich war mal wieder am Performance-Debuggen von pc-kombo. Die Seite soll schneller laden, wenn der Cache noch nicht befüllt ist, was doch immer wieder Besucher trifft. Dabei stolperte ich über diesen Abschnitt des Flamegraphs:
tt
ist der Übersetzungshelfer, lru-redux der genutzte Cache, Grundlage das Gem i18n. Und dieser Abschnitt machte einen gewichtigen Teil des Seitenladevorgangs aus.
Also habe ich das alte Übersetzungssystem auf FastGettext umgestellt. Der Code in Sinatra sieht in etwa so aus:
helpers do include FastGettext::Translation def t(token, opts = {}) _(token.to_s) % opts end end configure do FastGettext.add_text_domain('pckombo', path: 'locales', type: :yaml) end before do FastGettext.text_domain = 'pckombo' if request.env['HTTP_ACCEPT_LANGUAGE'] languages = HTTP::Accept::Languages.parse(request.env['HTTP_ACCEPT_LANGUAGE']) languages.each do |language| case language.locale when /en[_]*/ FastGettext.locale = "us" break when /de[_]*/ FastGettext.locale = "de" break when /fr[_]*/ FastGettext.locale = "fr" break when /es[_]*/ FastGettext.locale = "es" break end end end end
Die alten yaml-Übersetzungen konnten weiterverwendet werden. So beginnt z.B. die locales/de.yml:
de: cpu: Prozessor
Es ist also fast eine einfach so einsetzbare Alternative mit minimalen Codeänderungen.
Das Ergebnis:
Die Übersetzungen beim ersten Laden brauchen nun einen Bruchteil der Zeit. Das beste daran: Das wird nicht nur den speziellen Seitenaufruf beschleunigen den ich da betrachtet hatte, sondern generell der gesamten Webseite helfen.
Wer Übersetzungen in Ruby umsetzen muss, für den ist FastGettext ist definitiv einen Blick wert.
Categories setzen mit Rubys RSS-Modul
Ruby kann ja RSS lesen und schreiben, aber die Dokumentation für das Modul ist ungenügend und es scheint generell wenig genutzt zu werden, sodass man auch wenig Hilfe findet. Ich stand jetzt vor einem Rätsel: Wie kann ich den Items in einem erstellten RSS-Feed Kategories hinzufügen, also category
setzen? Doch jetzt habe ich es gelöst. Und zwar geht das so:
rss = RSS::Maker.make("rss2.0") do |maker| … maker.items.new_item do |newItem| … categories = [{name: 'abc', scheme: 'https://www.example.com'}] categories.each do |category| target = newItem.categories.new_category target.content = category[:name] target.domain = category[:scheme] end end
Xapian/Omega in Ruby/Sinatra integrieren
Wie baut man am besten eine Suchmaschine für eine einzelne Webseite? In meinem Fall war das Szenario so: Ich habe eine Sammlung statischer HTML-Dokumente, will aber eine Suchfunktion anbieten. Also brauchte ich etwas, was die ganzen HTML-Dokumente indexiert und dann durchsuchen kann. Genau das kann Xapian. Speziell für Webseiten gibt es vom Xapian-Projekt die vorgefertigte Omega-Suchmachine.
Also, Xapian kann alles mögliche durchsuchen, man könnte dem Xapian-Index auch programmatisch Elemente der Datenbank hinzufügen. Und es muss nicht für eine Webseite sein, es kann auch sonstwo eingebunden werden – mancher mag sich an xapian als nervenden Prozess in Ubuntu erinnern. Ich aber wollte nur HTML-Seiten durchsuchbar machen und das online anbieten, und genau dafür ist Omega gedacht. Allerdings: Omega hat ein eigenes Webfrontend, das per CGI eingebunden wird. Das wollte ich nicht nutzen, denn ich habe sowieso schon ein zusätzliches dynamisches Backend laufen, und die Template-Funktion von Omega sah unschön und kompliziert aus.
Xapian und Xapian-Fu installieren
Xapian samt Omega sollte in den Quellen sein. Bei mir mit void:
sudo xbps-install xapian-omega
Dazu empfehle ich für die Sinatra-Integration das Gem xapian-fu. Also in die Gemfile:
gem 'xapian-fu'
und dann installieren mit bundle install
.
Allerdings reichte das nicht. Xapian-fu braucht die Ruby-bindings von xapian, und die waren bei mir nicht in den Quellen enthalten. Also muss in dem Fall noch das Archiv xapian-bindings heruntergeladen und die Ruby-Bindings kompiliert werden:
unp xapian-bindings-* cd xapian-bindings-VERSION ./configure --with-ruby cd ruby make sudo make install
Mit omindex indexieren
Omindex installierte sich in den PATH und ist einfach bedienbar. Meine HTML-Dateien liegen im Ordner public/, Bilder sollten ignoriert werden, dafür kam ich auf diesen Befehl:
omindex --db omega/data/default/ --filter image/*:skip public/
Der Code in Sinatra
Statt jetzt den CGI-Part von Omega zu nutzen übernimmt Sinatra mit Xapian-Fu die Suche:
require 'sinatra' require 'xapian-fu' include XapianFu get '/search' do searchterm = params['searchterm'] db = XapianDb.new(:dir => 'omega/data/default/', :create => false) results = db.search(searchterm).map{|match| {url: match.data.split("\n").detect{|x| x.start_with?('url=')}.to_s.sub('url=', ''), caption: match.data.split("\n").detect{|x| x.start_with?('caption=')}.to_s.sub('caption=', '')} } erb :search, locals: {searchresults: results, searchterm: searchterm} end
Man sieht: Der Code nimmt die Datenbank als Quelle, die vorher omindex angelegt hat.
Die Zuweisung in den results-Hash ist hässlich. Ich fand leider keinen Weg, mit xapian-fu die Suchergebnisse richtig strukturiert auszulesen. Nur match.data
ist zugänglich, womit man etwas anfangen kann. Der Weg über einen XapianDocValueAccessor, mit dem man wohl die Felder gezielt auslesen können sollte, funktionierte bei mir nicht. Eventuell codiert omindex den Suchindex zu speziell.
Die Suchergebnisse gehen dann an ein ERB-Template:
<h1>Search results for <%= h searchterm %></h1> <% if searchresults.size > 0 %> <ol id="searchresults"> <% searchresults.select{|item| ! item[:caption].empty? }.each do |result| %> <li> <a href="<%= result[:url] %>"> <span><%= result[:caption] %></span> </a> </li> <% end %> </ol>
Xapian/Omega ist keine Lösung, wenn die Webseite nur aus statischen HTML-Seiten bestehen darf. Aber es ist wohl eine gute Lösung wenn es einen echten Server gibt. Die Integration in Ruby/Sinatra ist relativ einfach.
Dass die xapian-bindings nicht einfach per gem installierbar sind ist der problematischste Punkt, auch das vorgelagerte indexieren wird nicht in jedes Projekt gut passen. Ohne statischen Webseitengenerator im Zentrum würde ich omega und omindex ignorieren und stattdessen nur mit xapian-fu arbeiten. Dann kämen die Daten eben direkt aus der Datenbank.
Hier aber war das Parsen der HTML-Seiten die perfekte Lösung.
Robocop (2014)
Die Geschichte des Remakes ähnelt sehr der Geschichte der Vorlage, soweit ich mich an sie erinnere. Ein guter Polizist wird schwer verletzt. Anstatt ihn sterben zu lassen wird er in einen Robocop verwandelt, noch ein Cyborg, aber einem Großteil seiner Menschlichkeit beraubt. Was natürlich keine gute Sache ist und entsprechend schiefgeht - wobei hier mit weniger direktem Kampf um Kontrolle über ihn als vielmehr Robocop als Mittel zum Zweck.
Da gibt es dann wenige Überraschungen. Aber dafür ordentliche Actionszenen, eine geradlinige Story, keine schlechten Schauspieler. Mir gefiel, wie offensichtlich die Parallele zwischen dem Bestreben nach Robotern als Sicherheitskräfte und der schon bestehenden Praxis des Mordens per Roboter gezogen wird, zu Fox News als Propagandamaschine und dem US-Nationalismus als Faschismus.
An ein paar Stellen stolpert die Story, z.B. wenn der eigentlich als positive Figur positionierte Doktor ohne besonderen Zwang seine Prinzipien verrät und Robocop manipuliert. Wie der dann dieser Manipulation auf einmal entgehen kann, wunderbarerweise. Und wie der Oberbösewicht am Ende sich bewusst blöd verhält. Eben alles ein bisschen sehr einfach.
Fraglich auch was das Remake über das Original hinaus liefert. Und das war ja wohl schon kein besonders guter Film. Aber ich erwartete einen sehr schlechten Film, und so schlecht war das gar nicht. Eher ein kompetenter Actionfilm ohne besondere Größe mit einer mittlerweile nicht mehr originellen Story.