Fabian Topfstedt

Behind the scenes software developer, system architect and startup guy.

Orange.at: Vom Verlieren eines zufriedenen Kunden

Nach 48 Monaten bietet Orange Österreich den für mich passenden Tarif für 14,50 Euro statt jetzt 40 Euro im Monat an. Ein echter Grund zu wechseln. Aber nutzbar nur für Neukunden. Weil das Bonusprogramm für Bestandskunden nicht abgestellt werden kann. Ein letzter Versuch, Kunde zu bleiben, mit klarem Plan B:

Sehr geehrte Damen und Herren,

hiermit kündige ich meinen Vertrag mit Ihnen, mangels der Möglichkeit, in meinen Wunschtarif wechseln zu können, zum nächstmöglichen Zeitpunkt.

Leider ist es für mich als Bestandskunde im Bonusprogramm (von dem ich in meinen Augen nicht profitiere und das ich jederzeit gerne und ohne Kompensation aufzulösen bereit bin) offenbar nicht möglich, in Ihren folgenden Wunschtarif zu wechseln und Ihnen nach 46 Monaten weiterhin treu bleiben zu können: Business Unlimited 29, SIM only, 14,50 Euro pro Monat und zusätzlich einmalig 49,90 Euro für das Recht einer kurzfristigen Kündigung.

Mich überrascht diese Unflexibilität sehr, sollten Sie den Tarifwechsel für mich transparent doch durchführen können, etwa durch Auflösen meines Bestandstarifs und dem gleichzeitigen Neuanlegen des Wunschtarifs, lassen Sie es mich bitte wissen. Ansonsten gilt die Kündigung.

Mit freundlich-überraschten Grüßen, Fabian Topfstedt

Written on .

car2go - Autos zum Weggehen

# Reservierung

Steht kein car2go in unmittelbarer Nähe, reserviere ich über die iPhone-App "get2car" das nächstgelegene Fahrzeug. 15 Minuten Zeit verbleiben dann, um zur angegebenen Straße und Hausnummer zu gelangen. Ausreichend, wenn es denn dort auch stünde. Unmöglich, wenn es zweihundert Meter entfernt, um die Ecke, in einer anderen Straße steht. Fazit: Autos stehen nicht dort, wo sie sich selbst vermuten. Unter Zeitdruck immer ein Taxi nehmen.

# Datenverbindungsprobleme

Zeigt das Auto ein Problem mit der Datenverbindung, kann man es nicht nutzen und es bleibt verschlossen. Die Fehlermeldung, dass immer nur ein Fahrzeug gleichzeitig ausgeliehen werden kann, ist dann einen Kilometer entfernt so überraschend wie beunruhigend. Für 20ct/Minute kann man sowas über die Hotline klären und in der Zeit fuhr mein Ersatzauto mit anderen Fahrern davon. Fazit: Bei Datenverbindungsproblemen sofort ein Taxi nehmen.

# Regen

Bei Regen funktioniert der RFID-Leser schlecht und häufig gar nicht. "Karte konnte nicht gelesen werden" steht dann im Display, in einem Fall dauerte das ganze fünf Minuten. Fazit: Bei starkem Regen sofort ein Taxi nehmen. Und bei leichtem Regen nicht reservieren.

# Absperren

Am Ziel kann es vorkommen, dass das Auto sich nicht absperren lässt, weil Kofferraum oder Fenster oder Türen nicht geschlossen seien, obwohl sie es sind. Das lässt sich über die teure Hotline in knapp zehn Minuten durch eine Fernsperrung lösen. Zumindest die Kosten für diese Verlängerung wurden mir auf Anfrage erstattet, die Telefonkosten in Höhe der Öffifahrkarte natürlich nicht. Fazit: In Eile sofort ein Taxi nehmen, die Ankunft kann ewig dauern.

Mein Fazit nach insgesamt 26 Fahrten ist also, dass ich bei schönem Wetter und ohne Zeitdruck mit aufgeladenem Telefon ein car2go in Sichtweite ausleihen kann und sonst immer auf Taxi oder den öffentlichen Nahverkehr ausweichen muss. Wirklich schade!

Written on .

A Django Taggit widget with suggestions

To tag my Django models, I am using Alex Gaynor's Django Taggit. In the Django Admin, it renders an ordinary text input field, handling comma separated tags. Since we have a bunch of editors, and all of them are tagging slightly different, it would be useful to suggest tags based on what they are typing. After some research and tracking the eight forks of django-taggit-autocomplete, I came up with a ninth, and a new name: django-taggit-autosuggest". We are using it in production and it looks great with Grappelli:

image0

Written on .

Python: Parallel S3 multipart upload with retries

The fastest way to upload (huge) files to Amazon S3 is using Multipart Upload. Instead of uploading one (huge) file through one connection you split it into (smaller) chunks and upload them through multiple connections in parallel.

In Python, you usually use Mitch Garnaat's boto library to access the Amazon Web Services. Since I usually work with huge video files, I was searching the web for some implementations and thought about how low the memory footprint and disk usage could be. Both Mitch Garnaat and Brad Chapman used the unix split command to create chunks first, doubling the disk usage. Others were creating StringIO objects on demand, eating RAM. So I had a deeper look into Python's IO module and wrote FileChunkIO, which takes the path of the file, an offset (where to start reading), the amount of bytes (where to stop reading) and fakes to be just that chunk (read only of course). As you can read it buffered, it's footprint is pretty low.

An example of my parallel S3 multipart upload with retries using that FileChunkIO is available here:

Written on .

Triple Screen Setup (on a Mac)

image0

In 2007 I bought a 24" screen with a native resolution of 1920x1200 px and added a second one last year. Mounted on a Ergotron LX Dual Side-by-Side Armimage1 they are "floating" above my desk and can be readjusted within seconds. Most of the time I found myself using them both in portrait mode, side by side (2400x1920 px), which allows working active on both without turning the head (and loosing focus). But some of the windows, like documentation, search results and terminals were still hidden. So I added a third screen last week (3600x1920 px).

Two screens can be connected to any ordinary graphics card. For the third screen, I bought a HIS USB DVI Mulitview II Adapterimage2 (~60 Euro), which is the only USB graphics card I found that supports Macs and 1920x1200 screen resolutions. After the beta driver 1.6b3 installation the screen was available, but in landscape mode only, which is a unresolved bug. To solve that issue, download and run Display Rotation Menu X once. It also fixes the rotation setting in the system preferences. The performance of the USB graphics card is good for standard tasks, but insufficient for video playback, where it starts flickering.

If you're about to buy some screens, I can recommend buying Dell. Mine are called 2407WFP-HC, the aspect ratio of 16:10 is great in portrait mode, the PVA panels are matte and color stable and the borders are thin. The current model is called Dell U2410image3 (~480 Euro) and there is also a 23" 1920x1080 (16:9) model called Dell U2311Himage4(~220 Euro).

Written on .

Recover from an encrypted Time Machine backup

Today my SSD died the sudden infant death syndrome, it only got 18 days old. For the muggels among the readers: A SSD is a hard disk for computers, no need to condole or get sad.

Letting TimeMachine back up my data once per hour on an encrypted sparse bundle I did not loose anything but time. But as I found out, booting the OS X DVD and clicking on "Restore System From Backup" does not let you enter the password to read and recover your data, even though it detects that there is one. Instead, you need to open up the Terminal and type "hdiutil attach /Volumes/path/to/your/backups/yourbackup.sparsebundle". It asks you for the password and then mounts your backup volume and allows you to select it in the Restore Utility.

BTW: It was an OSZ Vertex 2 drive. "Back up, back up
Tell me what ya gonna do now" (Lincoln Park).

Written on .

Using PyFlakes with Hudson's Violations Plugin

I recently set up Hudson at schnee von morgen, a continuous integration server that smoothly builds our code (mostly Python) and reports back if the testsuite failed. But Hudson is more than an automated testrunner. The violations plugin for example can display the results of pylint, a tool that reads code and detects errors. The problem is: I don't like pylint, I prefer using PyFlakes. Detecting errors is what I want Hudson to do, not nagging about bad PEP-8 compliance, bad naming and stuff: That's what I'm excellent at (and probably the reason why my co-workers call me "PEP-8 nazi"). PyFlakes does what we all are bad at: Reading code in about no time while still finding about every error. I usually agree with PyFlakes that what it discovers should be fixed, so I'm fine with considering its results to be "errors". And with that assumption in mind I can reformat the output to a format that pylint expresses errors with and make the Violations Plugin read it properly:

In my build command, I added the following line to run pyflakes, reformat the output and write the results to a file called pyflakes.txt.

pyflakes [path_to_src] | awk -F\: '{printf "%s:%s: [E]%s\n", $1, $2, $3}' > pyflakes.txt

Then I configured the violations plugin to read that file: image0

And what I got was a nice graph on the project page mentioning one pylint" error: image1

Written on .

webhook2email: Read what gets POSTed

When you write (or consume) webservices that need some time to process your request, you may end up implementing (or using) a push notification service that gets triggered once the call got processed. In a RESTful world, it's done by POSTing data to a given URL (call it HTTP callback, or "WebHook" if you like buzzwords). A neat technique to build workflows between distributed systems. But before machines interact with each other, some human being must understand and route their communication data.

The best way of understanding what gets POSTed is reading and studying the data. Unfortunately that's not a trivial task if there is no proper documentation with samples available. Therefore I wrote a request handler on Google's App Engine that you can POST data to and that emails you formatted headers, formatted data and plain data in return.

The URL of webhook2email is as follows:

http://webhook2email.appspot.com/?email=[youremailaddress]

If you want to test it right now, open a Terminal and execute the following snippet:

curl -d "hello=nihao&goodluck=haoyun" http://webhook2email.appspot.com/?email=[youremailaddress]

Have fun!

Written on .

Prepaid mobile internet in Croatia

If you want to be online while travelling through Croatia, you should consider buying a "Vipme Broadband" SIM and plug it in your 3G stick (they sell simlocked sticks, probably lacking Mac support). To prevent paying per MB, you can buy data options for one month (50MB, 300MB, 1GB) online, on their free-to-use account page, that does not require a login once you are using their SIM card. Vouchers are available at many kiosks or at the Vip stores and Vip retailers.

Since the Vip store in Zadar really wanted me to buy their stick and refused to give me the proper credentials before my 10 minutes of complaints, here's what you need:

  • APN: data.vip.hr
  • LOGIN: 38591
  • PASS: 38591
  • DNS1: 212.91.97.3
  • DNS2: 212.91.97.4

Written on .

Veranstaltungstipp: Taktwechsel im Mediennutzungsverhalten

Am Donnerstag werde ich im Podium der Expertenrunde über die Auswirkungen der Digitalisierung auf die Film und Fernsehindustrie im Raum D des Wiener Museumsquartiers mitdiskutieren. Die Interdisziplinarität, der Altersunterschied und die vertretenen Firmen versprechen einen spannenden Diskurs und interessante Blickwinkel in die Zukunft.

Die Anmeldung zur Veranstaltung der FilmFonds Wien und FilmTiki ist bis morgen kostenlos per E-Mail möglich.

Written on .

VideoCamp Wien am 30. Januar 2010

VideoCamp Vienna 2010 LogoAm 30. Januar 2010 findet das erste Wiener VideoCamp statt, ein BarCamp zum Thema Onlinevideo. Ob Drehbuch, Dramaturgie, Produktion, Technik, Playout oder Marketing - Das Spektrum ist breit gefächert und wie bei einem BarCamp üblich entscheiden die TeilnehmerInnen über was sie sprechen, nachdenken und diskutieren.

Am besten gleich anmelden, und Sessionvorschläge machen.

Written on .

Digitalks Web 2.0 Handbuch

Das Digitalks Web 2.0 Handbuch, an dem ich mitgeschrieben habe, ist gerade fertig geworden und riecht noch nach Druckerschwärze und warmen Pixeln. Geruchserlebnisse teilen können wir auf dem Digiday im MQ Wien am 17. Oktober 2009.

Written on .

Why we won't enjoy HTML5's video tag

The HTML5 standard introduces the video-tag, that finally allows adding videos in markup without the use of additional plugins. Pretty much like the img-tag embeds images. Google recently published a YouTube-demo using HTML5, which can be viewed in bleeding edge browsers that already understand HTML5, like Safari 4 Beta on a Mac. It pretty much looks like YouTube as we all know it, but with tiny fast motion preview videos instead of images and without Flash. Sounds like your browser is your TV now and everything works out of the box? Far from it!

The major part in compatibility and standards has not been solved yet: Audio and video codec support. Google's demo medium uses H.264 for video and AAC for audio compression, which is the combination your new Adobe Flash Player plugin, your new mobile phone, your new gaming console, your new korean DVD player and probably your new freezer are able to play back. Your browser knows how to display PNG, JPEG and GIF images because it comes with their decoding algorithms. Mozilla's and Opera's proposal was to include the free open source OGG Theora (Video) and OGG Vorbis (Audio) decoders into any browser. A clean pragmatic approach that doesn't cost a dime. But Apple and Nokia didn't like the idea. So the w3c page now reads 'user agents may support any video and audio codecs and container formats' and a red disclaimer adds that going with OGG is still a good idea to not fail completely.

But it will fail completely. We will see more H.264 video and MPEG4 audio, because quality and size are great and we don't have to encode and store a medium more than once to play it back in most browsers and Flash Player 9+. Mozilla, Opera, Safari and Chrome browsers will also support OGG. Microsoft's Internet Explorer won't. Microsoft has all those funny media formats and browsers, and they even have Silverlight. They will play WMV and WMA, and nothing else. And we developers will just continue to do what we like most: Building browser switches, adding capabilities by using browser plugins and testing all versions of IE that have ever been released since August 27, 2001, the birthday of IE6. Show me that I'm wrong Microsoft.

Written on .

Including JavaScript into JavaScript (using Dojo)

Ever thought of including a JavaScript class into another one? Usually you place all required JavaScript modules in the right order within the head of the page where you want to use them. Sometimes I prefer loading the requirements within the script (with checking if it has already been loaded before) instead of writing a lot of documentation.

The following code snippet uses Dojo 1.3+ API to create a script tag and place it to the head as the first child:

var script_url = 'http://www.topfstedt.de/js/foo.js';
var script_obj = dojo.create('script', {
    'src': script_url,
    'type':'text/javascript'
});
dojo.query("head").addContent(script_obj, "first");

Written on .

dctp.tv has landed

Today we launched dctp.tv, a german WebTV site that offers Alexander Kluge's awesome productions in the form of a livestream and on demand video, grouped by topics. The whole project from the idea, the encoding farm, the video management system and the streaming farm to the frontend took us about five months to realize. Finally we are proud to see that our ideas in using Amazon's and Google's cloud computing infrastructure turned out to be both cost-effective and scalable: Our systems took the spike of being featured on SPIEGEL ONLINE's frontpage really well. Enjoy the informative web-television programme!

Written on .

Homeserver weekend project

Within the last weekends I spent some hours building an home server to serve files and to let our Macs do encrypted, wireless backups using TimeMachine [Howto]. It also became a wireless router [Howto] with a miserable latency and throughput - but good enough to act as a fallback.

As hardware I reanimated a Via Epia M10000 Mini-ITX board with a 1000 MHz Nehemiah CPU and mounted it in a new Mini-ITX chassis with a fanless external 60 Watt power supply. As the system harddisk I used my iPod mini's 4 GB MicroDrive using a IDE adapter for about 10 Euros. It is quiet, way faster than I thought and can be dumped to a DVD using a CardReader. I think it's good to have backups of the system you store your backups on. The shared files and time machine backups are stored on a large external USB drive, also easy to backup.

The operating system is Linux (for sure), I installed Ubuntu Server 8.10 and ran into the first issue right after rebooting the fresh installation: The Via Nehemiah CPU does not support all commands the current i386 kernel needs, sudo apt-get linux-generic fixes the problem by installing a generic kernel. Another problem was the noise of the CPU fan, that I finally replaced with a more silent fan. The temperature inside the small case is okay to not worry about burning the flat, but not surprisingly higher than it was before. After a bit of researching I found out that the CPU supports speedstepping in 66 MHz steps from 532 MHz to 997 MHz, and decided that the lowest is fine for me. To enable speedstepping, install cpufrequtils sudo apt-get install cpufrequtils, load the longhaul module by typing sudo modprobe longhaul or forever by adding longhaul directly to /etc/modules, and set the frequency to your preferred value in Hz cpufreq-set -f 532000. The lower the frequency, the lower the power consumption and the heat is. On demand speed stepping using cpufreq -g ondemand didn't work for me, if I'll ever do real computing on the box I'll probably write a cronjob to run every minute and set the frequency due to last minutes load average value that you can check with the following command cat /proc/loadavg | awk '{ print $1 }'.

Update: I wrote a python script to set the frequency on demand. You can download it here: http://pastebin.com/f2e46125.

Written on .

Redmine and Python

Redmine is an open source web application written in Rails. I would call it a collaboration suite: It ships with project management tools (including a calendar, gannt charting and time tracking), a wiki, a document store, a file store, an issue tracker, a message board, source browsing functionality for various (distributed) version control systems, 2.0ish activity streams and ATOM feeds, and some other things you will be happy to see. What I really like, beside the user interface, which is nice and clean, is that you can deactivate all those features on a project level (and reactive if you need them).

One thing I missed was code highlighting for Python when browsing the source. It's much easier to read highlighted, colored code, but as I said, it's a Rails app and Rails developers tend to like Ruby.

Being lucky I found the blog post of Jake Wharton describing how to switch the syntax highlighting engine in an older version of Redmine to Pygments, that has already been installed on my Mac and can otherwise be installed using

sudo easy_install pygments

To ease things up a bit, I cloned the repository of Redmine's 0.8 stable release and changed the code, the stylesheet and some views due to Jake Wharton's instructions. You can download it here or clone the Mercurial repository using

hg clone http://www.bitbucket.org/fabian/redmineforpythonlovers/

Have fun!

Written on .

05.01.People: Pythonic art with NodeBox

Using NodeBox is fun. I wrote TodaysPeople, a Python script that lets tagthe.net extract names of people that are mentioned on the wikipedia page of the current date and renders them in a nice typo on the canvas. The native resolution of the images below is 1920x1200, in case you need a new wallpaper for today.

05.01.People.1

05.01.People.2

05.01.People.3

05.01.People.4

Written on .

Ob Lutz Heilmann mir helfen kann?

image0

Written on .

Web2Expo Berlin start-up lessons

About a week ago I was attending the Web 2.0 Expo Europe in Berlin, a conference discussing the current and the future web from four major perspectives: "Development", "design and user experience", "strategy and business" and "marketing and community". Being a freelance web developer and co-founder of a web start-up, I found myself taking seat in all tracks but "marketing and community" quite balanced, trying to get interdisciplinary recommendations and the lessons from successful players. Cross-posting in Hannes' start.up blog, here's what I found was the essence for his target audience, me:

First off, recapitulate if your idea is innovative and not a clone of sth. already existing. Check your competition. If yours is close to a competitor's idea, make sure you're able to explain what makes the difference. If there's no difference, don't waste you're time. Or don't waste your life, some of the speakers tended to speak more emotional. Think about your team. Are you a team? "Business plans and conditions change, people don't change that fast", to quote an investor. Be able to take feedback and listen. "Why does anybody care? Why will real people use it, not only your coder friends?", Reshma Sohoni (Seedcamp). Be focussed. Be enthusiastic and passioned, and be able to share it. Be globally visible. Think about other markets than North America and other languages than english. In terms of internet users, Asia almost doubles North America, followed by Europe. Build network effects.

Make sure your data can be distributed. Expose data using RESTful Web Service. Offer different content representations, at least JSON or XML. Offer syndication formats like RSS or ATOM whereever you can. "The most successful apps are fundamentally powered by data.", Dion Hinchcliffe. He mentioned later on, that distributing data doesn't need to be a freebie - You can meter API usage and charge for usage. Or add ads to the API results. With a good API you might be able to care about the data only and crowdsource the user interfaces. Yes, interfaces. Plural. Mobile web is emerging! User experience matters. Let the experience be excellent. Think about the ease of sharing experience in the social web, both the good and the bad. And favorize simplicity. As Albert Einstein, who was unfortunately not attending the expo, said: "Make everything as simple as possible, but not simpler.".

Use open standards. OpenID for user authentication, OAuth for API authorization. Microformats describe your content semantically. Use OpenSocial if you're running a social network site. Apache Shindig helps you here.

Technology: Be agile. Use what works well for you. But I still think you really have to know the tools out there, I'm not a big fan of the "It's a problem when it's a problem"-approach. Beside relational databases, the document based expando databases emerge with Apache's CouchDB, Amazon's SimpleDB and Google's BigTable, build to scale. You have to at least think of scaling and fundamental design decisions early. Build you're architecture message driven and use servers like Amazon EC2 instances to react on altering needs and to stay cost-effective. Pay as you go. Have a look at Google's App Engine, which cuts off system administration and lets you deploy in the google cloud. And have a look at its restrictions.

Have fun!

Written on .

"Mobile usability"

image0
"Mobile usability" Originally uploaded by blogsportgruppe (fabian&sillie)

Der erste Eintrag meines "visual strangeness" Sets, in das ich versuche, Eindrücke mit meinem nagelneuen iPhone einzufangen. Number One: "Mobile usability". Exakt mit diesem blauen Kästchen melden in Wien Fußgänger ihren Wunsch der Überquerung der Straße an. Das Betasten des weißen Kreises genügt, und der Vorschlag, die Ampel grün zu schalten wird mit einem Aufleuchten des unteren Hinweistextes und einem Piepen quittiert. Seit nunmehr zwei Monaten fahre ich täglich an dieser Ampel vorbei, und seit etwa dieser Zeit überfahre ich sie unrechtmäßig und genervt nach ein paar Minuten, Tendenz in den Sekundenbereich fallend. Genug Zeit, um die Umgebung wahrzunehmen - und nun entdeckte ich den Clou - Der Fahrradfahrer soll halt drücken. Parkhausprinzip. Ich bin so begeistert von dieser simplen Idee, dass ich das Vorbild für den gesamten Autoverkehr Wiens einführen würde. Induktionsschaltung ist 1.0, getarnte Touchkästchen sie die Lösung. Weniger CO2 Emissionen, Sit-Ups für alle und neue Perspektiven im Dienstleistungsbereich für die Print-Inder.

Written on .

Virtuelle Passbilder

Die Freundin und ich haben uns heute auf faceyourmanga.com virtuelle Passbilder ("Avatare") zusammengeklickt. Erkennt ihr uns? Ja? Na dann los, wir wollen Euch sehen! SillieFabian

Written on .

"Tausche" eine deutsche Bundestagswahlstimme gg. eine österreichische Nationalratswahlstimme

Als in Österreich lebender Deutscher darf ich in Österreich nicht auf nationaler Ebene wählen, wohl aber in Deutschland. Das bedeutet, die mich direkt betreffende Politik kann von mir zumindest nicht durch eine Wahlstimme beeinflusst werden, die für mich nahezu irrelevante in Deutschland aber schon. Das ist nicht nur frustrierend sondern auch einfach nicht nachvollziehbar - zumindest nicht innerhalb der EU.

Einfachste aller Lösungen: Ich überzeuge eine(n) in Deutschland lebende(n) Österreicher(in) bei der kommenden Nationalratswahl von meine Präferenz und bin dafür sehr sehr offen gegenüber seiner/ihrer Präferenz bei der nächsten Bundestagswahl. Ein unrechtmäßiger Stimmentausch ist das selbstverständlich nicht, nur eine recht fixe Überzeugungsarbeit. Bei Interesse bitte melden.

Written on .

older   →