Archiv Juli 2005

Daves neuer OPML Editor mit Blog

Ich spiele gerade mit dem OPML-Editor von Dave Winer rum, mit dem er jetzt sein Blog macht. Sieht ganz witzig aus und kann einiges. Mein OPML-Blog hat einige der Erkenntnisse die ich damit gemacht habe gesammelt. Ich werde jetzt sicherlich nicht einfach mal eben so umsteigen - das wäre Quark, das ist nicht unbedingt meine Zielsoftware. Aber es macht Spaß mal wieder mit etwas ganz anderem zu spielen.

Leider hat der OPML Editor einige der Krankheiten von Radio Userland und Frontier geerbt, speziell Umlautehandhabung ist nicht so wirklich rund (ich hätte gerne endlich mal durchgängige UTF-8 Unterstützung) und das Laufzeitverhalten ist zwar besser als bei Radio, aber es zieht immer noch sporadisch zu viel CPU.

Das Konzept von gerenderten Outlines hat aber durchaus Charme. Nur leider sind noch viele Teile des Renderings nicht wirklich für normale User zugänglich - man kann zwar das uralte Table-Layout editieren und was anderes draus machen, aber die OPMLs werden mit dem internen OPML Renderer umgesetzt und die HTML-Fragmente sind nicht so einfach zu ändern - und damit zum Beispiel die Änderung der Sprache recht mühsam, genauso wie die vollständige Ausmerzung von Layouttabellen.

Mehr wird sicherlich nach und nach auf dem OPML Blog landen, hier werd ich maximal ein paar Fazits schreiben.

HEW Cyclassics 2005

Ein wirklich nettes Rennen - immer wieder erstaunlich wie selbst fast eine Viertelstunde Vorsprung nicht ausreicht um bei dem Rennen auch einen Sieg nach Hause zu fahren. Auch immer wieder erstaunlich wie die Kommentatoren jedes Mal erzählen das das Hauptfeld zu spät anfährt - so langsam sollten die das doch kennen.

Die Quickstep-Aktion jedenfalls war klasse - so sauber den Fassa Bortolo Leuten nach deren Sprintaufbau den Sieg und die Treppchenpositionen wegzunehmen ist wirklich super. Auch wenn ich natürlich lieber Zabel vorne gesehen hätte

Merkelnix krampft auch

Nur damit niemand glaubt nur die SPD hätte hirnlose Parolen in die Welt zu schreien: "Arbeit wieder in Deutschland möglich machen" ist der Grund warum sie die Mehrwertsteuer erhöhen wollen:

Unions-Kanzlerkandidatin Angela Merkel hat die von CDU und CSU geplante Erhöhung der Mehrwertsteuer verteidigt. Die Union wolle damit das Ziel erreichen, die Arbeitskosten zu senken, sagte sie in einem Interview des "Bericht aus Berlin". Es gehe darum, "Arbeit wieder in Deutschland möglich zu machen und damit die soziale Sicherung zu ermöglichen", sagte die CDU-Chefin weiter.

Sorry, aber wie saublöd ist das denn? Soziale Sicherung durch eine Anhebung der Mehrwertsteuer, die am heftigsten die trifft, die ihren Konsum nicht weiter reduzieren können weil er eh nur noch aus Grundnahrungsmitteln und anderen fürs Überleben notwendigen Ausgaben besteht?

Softwarepatente - Kommentar bei der NY Times

Die NY Times fragt warum Bill Gates 3,000 neue Patente will und findet eine massive Belagerung des Patentbüros mit Bergen von Softwarepatenten, die oft einfach nur Trivialpatente sind (wie das zitierte Patent zum Zufügen/Entfernen von Leerzeichen in Dokumenten). Der Kommentator stellt in dem Kommentar eine Forderung auf (nachdem er überlegt ob man Microsoft nicht einfach alle Patente entziehen sollte die sie schon haben):

Perhaps that is going too far. Certainly, we should go through the lot and reinstate the occasional invention embodied in hardware. But patent protection for software? No. Not for Microsoft, nor for anyone else.

Und das aus dem Land das die Softwarepatente schon lange hat und das immer wieder von den Softwarepatentproponenten in der EU als Grund für eine notwendige weltweite Harmonisierung gebracht wird.

Nein, Softwarepatente sind auch dort nicht gern gesehen und nicht wirklich sinnvoll. Auch Dan Bricklin - dem einen oder anderen noch als Visicalc-Vater bekannt - findet das:

Mr. Bricklin, who has started several software companies and defensively acquired a few software patents along the way, says he, too, would cheer the abolition of software patents, which he sees as the bane of small software companies. "The number of patents you can run into with a small product is immense," he said. As for Microsoft's aggressive accumulation in recent years, he asked, "Isn't Microsoft the poster child of success without software patents?"

Und warum macht Microsoft das jetzt? Der dafür zuständige Manager gibt einen Grund, wie er nur einem BWLer einfallen kann, so blöd ist der:

"We realized we were underpatenting," Mr. Smith explained. The company had seen studies showing that other information technology companies filed about two patents for every $1 million spent on research and development. If Microsoft was spending $6 billion to $7.5 billion annually on its R&D, it would need to file at least 3,000 applications to keep up with the Joneses.

Ok, alleine schon die Idee der Patentanmeldung alleine von Zahlen aus der Branche zu orientieren ist hirnrissig, aber wie blöd muss man sein um einen Bezug zwischen der Patentanzahl und dem Umsatz im Bereich Forschung und Entwicklung zu ziehen?

Die NY Times zieht da auch die Parallele zur Pharmaindustrie, die - zumindestens laut eigenen Aussagen - bei einem Forschungseinsatz von 20 Millionen froh ist dann ein Patent auf ein Medikament zu bekommen (wobei das schon kritisch genug ist, wie man gerade bei der AIDS-Bekämpfung in Afrika sehen konnte).

Und der Fallout wird bei der NY Times auch gut zusammengefasst:

Last year at a public briefing, Kevin R. Johnson, Microsoft's group vice president for worldwide sales, spoke pointedly of "intellectual property risk" that corporate customers should take into account when comparing software vendors. On the one side, Microsoft has an overflowing war chest and bulging patent portfolio, ready to fight - or cross-license with - any plaintiff who accuses it of patent infringement. On the other are the open-source developers, without war chest, without patents of their own to use as bargaining chips and without the financial means to indemnify their customers.

Die Frage, was Jefferson (der Gründer des US Patentsystems) dazu sagen würde, was heute alles Patente bekommen soll, ist da durchaus berechtigt. In seinem Sinne - der ja eigentlich eher auf den Schutz der wirklichen erfinderischen Genialität vor der Ausnutzung durch Konzerne galt - ist das ganze definitiv nicht.

Wahlkampf, Wahlkrampf ...

Münte on the Roll: Linkspartei "politisch und juristisch abstrus". Ich hab allerdings den Eindruck das er der SPD mehr damit helfen würde ihr ein Programm zu verpassen das die normalen Bürger wieder anspricht, anstatt einfach nur die Angst vor Links zu schüren und Verleumdungen (sorry, aber die Kombination aus PDS und WASG in der offenen Liste ist vielleicht merkwürdig, aber juristisch wohl einwandfrei - etwas anderes zu behaupten also schlicht Verleumdung) zu verbreiten.

Wenn die SPD im Wahlkampf nicht mehr schafft als nur ins Horn der Unionsparteien gegen die angebliche Gefahr von Links zu stossen, wird die SPD sich schlicht ins politische Aus begeben - mit so einem Murks gewinnt man keine Wahl. Wenn die SPD nur noch eine Union mit roter Krawatte ist, kann sie mir gestohlen bleiben ...

Writing a Simple Filesystem Browser with Django

Dieser Artikel ist mal wieder in Englisch, da er auch für die Leute auf #django interessant sein könnte. This posting will show how to build a very simple filesystem browser with Django. This filesystem browser behaves mostly like a static webserver that allows directory traversal. The only speciality is that you can use the Django admin to define filesystems that are mounted into the namespace of the Django server. This is just to demonstrate how a Django application can make use of different data sources besides the database, it's not really meant to serve static content (although with added authentication it could come in quite handy for restricted static content!).

Even though the application makes very simple security checks on passed in filenames, you shouldn't run this on a public server - I didn't do any security tests and there might be buttloads of bad things in there that might expose your private data to the world. You have been warned. We start as usual by creating the filesystems application with the django-admin.py startapp filesystems command. Just do it like you did with your polls application in the first tutorial. Just as an orientation, this is how the myproject directory does look like on my development machine:


.
|-- apps
| |-- filesystems
| | |-- models
| | |-- urls
| | `-- views
| `-- polls
| |-- models
| |-- urls
| `-- views
|-- public_html
| `-- admin_media
| |-- css
| |-- img
| | `-- admin
| `-- js
| `-- admin
|-- settings
| `-- urls
`-- templates
 `-- filesystems

After creating the infrastructure, we start by building the model. The model for the filesystems is very simple - just a name for the filesystem and a path where the files are actually stored. So here it is, the model:


 from django.core import meta

class Filesystem(meta.Model):

fields = ( meta.CharField('name', 'Name', maxlength=64), meta.CharField('path', 'Path', maxlength=200), )

def repr(self): return self.name

def get_absolute_url(self): return '/files/%s/' % self.name

def isdir(self, path): import os p = os.path.realpath(os.path.join(self.path, path)) if not p.startswith(self.path): raise ValueError(path) return os.path.isdir(p)

def files(self, path=''): import os import mimetypes p = os.path.realpath(os.path.join(self.path, path)) if not p.startswith(self.path): raise ValueError(path) l = os.listdir(p) if path: l.insert(0, '..') return [(f, os.path.isdir(os.path.join(p, f)), mimetypes.guess_type(f)[0] or 'application/octetstream') for f in l]

def file(self, path): import os import mimetypes p = os.path.realpath(os.path.join(self.path, path)) if p.startswith(self.path): (t, e) = mimetypes.guess_type(p) return (p, t or 'application/octetstream') else: raise ValueError(path)

admin = meta.Admin( fields = ( (None, {'fields': ('name', 'path')}), ), list_display = ('name', 'path'), search_fields = ('name', 'path'), ordering = ['name'], )


As you can see, the model and the admin is rather boring. What is interesting, though, are the additional methods isdir , files and file . isdir just checks wether a given path below the filesystem is a directory or not. files returns the files of the given path below the filesystems base path and file returns the real pathname and the mimetype of a given file below the filesystems base path. All three methods check for validity of the passed in path - if the resulting path isn't below the filesystems base path, a ValueError is thrown. This is to make sure that nobody uses .. in the path name to break out of the defined filesystem area. So the model includes special methods you can use to access the filesystems content itself, without caring for how to do that in your views. It's job of the model to know about such stuff.

The next part of your little filesystem browser will be the URL configuration. It's rather simple, it consists of the line in settings/urls/main.py and the myproject.apps.filesystems.urls.filesystems module. Fist the line in the main urls module:


 from django.conf.urls.defaults import *

urlpatterns = patterns('',
 (r'^files/', include('myproject.apps.filesystems.urls.filesystems')),
 )

Next the filesystems own urls module:


 from django.conf.urls.defaults import *

urlpatterns = patterns('myproject.apps.filesystems.views.filesystems',
 (r'^$', 'index'),
 (r'^(?P<filesystem_name>.*?)/(?P<path>.*)$', 'directory'),
 )

You can now add the application to the main settings file so you don't forget to do that later on. Just look for the INSTALLED_APPS setting and add the filebrowser:


 INSTALLED_APPS = (
 'myproject.apps.polls',
 'myproject.apps.filesystems'
 )

One part is still missing: the views. This module defines the externally reachable methods we defined in the urlmapper. So we need two methods, index and directory . The second one actually doesn't work only with directories - if it get's passed a file, it just presents the contents of that file with the right mimetype. The view makes use of the methods defined in the model to access actual filesystem contents. Here is the source for the views module:


 from django.core import template_loader
 from django.core.extensions import DjangoContext as Context
 from django.core.exceptions import Http404
 from django.models.filesystems import filesystems
 from django.utils.httpwrappers import HttpResponse

def index(request):
 fslist = filesystems.getlist(orderby=['name'])
 t = templateloader.gettemplate('filesystems/index')
 c = Context(request, {
 'fslist': fslist,
 })
 return HttpResponse(t.render(c))

def directory(request, filesystem_name, path):
 import os
 try:
 fs = filesystems.getobject(name exact=filesystemname)
 if fs.isdir(path):
 files = fs.files(path)
 tpl = templateloader.gettemplate('filesystems/directory')
 c = Context(request, {
 'dlist': [f for (f, d, t) in files if d],
 'flist': [{'name':f, 'type':t} for (f, d, t) in files if not d],
 'path': path,
 'fs': fs,
 })
 return HttpResponse(tpl.render(c))
 else:
 (f, mimetype) = fs.file(path)
 return HttpResponse(open(f).read(), mimetype=mimetype)
 except ValueError: raise Http404
 except filesystems.FilesystemDoesNotExist: raise Http404
 except IOError: raise Http404

See how the elements of the directory pattern are passed in as parameters to the directory method - the filesystem name is used to find the right filesystem and the path is used to access content below that filesystems base path. Mimetypes are discovered using the mimetypes module from the python distribution, btw.

The last part of our little tutorial are the templates. We need two templates - one for the index of the defined filesystems and one for the content of some path below some filesystem. We don't need a template for the files content - file content is delivered raw. So first the main index template:


{% if fslist %}
<h1>defined filesystems</h1> <ul> {% for fs in fslist %}
<li><a href="{{ fs.get_absolute_url }}">{{ fs.name }}</a></li> {% endfor %}
</ul> {% else %}
<p>Sorry, no filesystems have been defined.</p> {% endif %}

The other template is the directory template that shows contents of a path below the filesystems base path:


 {% if dlist or flist %}
 <h1>Files in //{{ fs.name }}/{{ path }}</h1> <ul> {% for d in dlist %}
 <li> <a href="{{ fs.getabsoluteurl }}{{ path }}{{ d }}/" >{{ d }}</a> </li> {% endfor %}
 {% for f in flist %}
 <li> <a href="{{ fs.getabsoluteurl }}{{ path }}{{ f.name }}" >{{ f.name }}</a> ({{ f.type }})</li> {% endfor %}
 </ul> {% endif %}

Both templates need to be stored somewhere in your TEMPLATE PATH. I have set up a path in the TEMPLATE PATH with the name of the application: filesystems . In there I stored the files as index.html and directory.html . Of course you normally would build a base template for the site and extend that in your normal templates. And you would add a 404.html to handle 404 errors. But that's left as an exercise to the reader.After you start up your development server for your admin (don't forget to set DJANGO SETTINGS MODULE accordingly!) you can add a filesystem to your database (you did do django-admin.py install filesystems sometime in between? No? Do it now, before you start your server). Now stop the admin server, change your DJANGO SETTINGS MODULE and start the main settings server. Now you can surf to http://localhost:8000/files/(at least if you did set up your URLs and server like I do) and browse the files in your filesystem. That's it. Wasn't very complicated, right? Django is really simple to use

Zerospan scheint eine P2P-Software mit Verschlüsselung und Integration von Bonjour (ex-Rendevouz, ex-Zeroconf) zu sein. So richtig schlau werd ich nicht draus, denn der Download enhält keine Doku und das Wiki mit der Doku ist zur Zeit kaputt, daher mal geblogmarked um es mir später mal anzugucken.

Ausbildung als Billiglohnschiene

Was hinter der Forderung des DIHK nach Halbierung des Lehrlingsgrundgehaltes und Flexibilisierung der Arbeitszeiten steckt, wird einem klar wenn man sich Zitate des DIHK-Vorsitzenden ansieht:

"Mein Vorschlag ist, eine bundesweite Basisvergütung von 270 Euro einzuführen", sagte er der Zeitung "Die Welt". Er rechtfertigte seinen Vorstoß damit, dass so mehr Lehrstellen finanziert werden könnten. "Eine Ausbildungsvergütung von bis zu 800 Euro ist für viele Betriebe einfach zu hoch."

"Die Arbeitszeiten müssen den Bedürfnissen der Branchen besser angepasst werden." Es ergebe keinen Sinn, dass eine 17-jährige Restaurantfachfrau um 22.00 Uhr gehen müsse, "wenn noch alle Tische besetzt sind"

Da gehts einfach nur darum billige Arbeitskräfte zu haben, aber nicht darum eine fachgerechte Ausbildung zu gewährleisten. Aber die Forderungen sind ja nicht neu.

Und was die deutsche Wirtschaft von Ausbildung hält, sieht man ja auch an der Tatsache das die Ausbildungsplätze im Vergleich zum Vorjahr wieder 10% runter sind - und damit wieder Jugendliche ohne Ausbildungsplätze geblieben sind, trotz aller Versprechungen der Wirtschaft. Ohne Nichtausbildungsabgabe für grössere Unternehmen wird sich das auch nicht ändern. Aber darüber jammern das es keine ausgebildeten Fachkräfte gibt, das kann die Wirtschaft ganz famos ...

Beckstein on the Roll

Keine Ahnung wie das Kraut heisst das er nimmt, aber es hinterlässt schwere Hirnschäden: Beckstein will deutsches Guantanamo. Abgesehen davon das er auch Verdächtigen in den Kopf schiessen will und Ausländer erstmal in Lager packen will, weil ja auf keinen Fall potentielle Terroristen frei rumlaufen dürfen (durchgeknallte Politiker wie er dürfen aber nicht nur frei rumlaufen sondern auch noch frei ihre Meinung äussern), er ist auch verfassungsfeindlich eingestellt:

Beckstein kritisierte auch das Urteil des Bundsverfassungsgericht, dass in einem Urteil zur niedersächsischen Gesetzgebung klare Eingrenzungen bei der vorbeugenden Telefonüberwachung verlangt hatte. Es müsse zwischen Sicherheits- und Freiheitsinteressen neu abgewogen werden, sagte Beckstein: "Dass der Intimbereich von Terroristen geschützt sein soll, ist für mich schwer erträglich."

Tut mir leid, Herr Beckstein, aber Sie sind in der Prüfung durchgefallen. Denn das Verfassungsgericht schützt nicht explizit den Intimbereich von Terroristen - sondern den Intimbereich der Bürger. Und der steht als schützenswertes Gut im Grundgesetz.

Warum wird eigentlich so einer nicht vom Verfassungsschutz beobachtet? Seine Verfassungsfeindlichkeit ist doch wirklich mehrfach dokumentiert ...

Novell will SCO an den Kragen

Und ihre Betrachtungen über die Rechtslage würden - wenn sie denn vor Gericht Bestand haben - SCO wirklich eine empfindliche Schlappe verpassen.

Der ganze SCO-Linux-Film ist ja recht spannend, aber ganz ehrlich: die Längen zwischen den Actionszenen sind doch ein bischen übertriebn

Pluto raus oder ein Neuer rein?

Astronomen haben ausserhalb der Pluto-Umlaufbahn einen Matschklumpen gefunden der mindestens so gross, warscheinlich aber sogar deutlich grösser als Pluto ist - Planet or Not, Pluto Now Has Far-Out Rival:

Astronomers announced yesterday that they had found a lump of rock and ice that was larger than Pluto and the farthest known object in the solar system. The discovery will probably rekindle debate over the definition of "planet" and whether Pluto still merits the designation.

Jetzt gehts drum ob Pluto seinen Planetenstatus verliert, oder der Neue auch Planet wird.

Wer mit PostgreSQL und Frontier arbeiten will, einfach die PostgreSQL Extension for Frontier installieren. Für Mac und Windows.

Vom Umgang mit Security

Unter ISS geht gegen Veröffentlichung des Vortrags über Cisco-Schwachstellen vor findet man eine Beschreibung wie sich Cisco und ISS Sicherheit vorstellen: massive Eingriffe in die Äusserungsrechte eines Vortragenden auf der Black-Hat-Konferenz. Ok, der war Ex-Mitarbeiter von ISS und hat wohl Informationen genutzt die er nicht veröffentlichen sollte - aber genau diese hirnrissige Geheimniskrämerei ist es ja, die Sicherheit unterminiert - denn das die Angreifer dieses Wissen früher oder später erlangen ist garantiert - wenn Sicherheitslücken existieren, werden sie früher oder später gefunden. Findet Sie jemand der darüber öffentlich berichtet, kann man sich wenigstens dagegen wehren und Gegenmaßnahmen einleiten. Wird die Veröffentlichung unterdrückt, ist der Leidtragende letztendlich der Endanwender - der keine Möglichkeit bekommt sich überhaupt abzusichern - und sei es im Notfall durch Wechsel zu einem anderen Routerhersteller.

Von daher ist es in der Tat so: weder ISS noch Cisco machen damit ein gutes Bild in der Öffentlichkeit. Im Gegenteil, deren Zensurversuche sind eigentlich nur noch ein Argument bei zukünftigen Produktentscheidungen sich gegen Cisco zu entscheiden - denn man kann deren Sicherheitsaussagen ja ganz offensichtlich nicht trauen.

Wer glaubte das ISO Zeitangaben einfach nur die YYYY-MM-TT HH:MM:SS.HS ist, vergesst es: International standard date and time notation. War ja klar, ist ja ein ISO Standard ...

Leichen im Keller

Jede Software hat sie - irgendwelche Leichen im Keller die anfangen zu stinken wenn man sie findet. Django leider auch. Und zwar die Behandlung von Unicode. Der automatisch generierte Admin in Django schickt immer XHTML und utf-8 raus an den Browser. Die Browser schicken daher auch utf-8 zurück. Jetzt gibt es aber Browser die bei solchen Sachen dann ein etwas anderes Format für die zu schickenden Daten benutzen - das sogenannte Multipart-Format. Dieses wird verwendet weil es die einzige garantierte Methode in HTTP-POST ist, bei der man einen Zeichensatz mitschicken kann.

Dummerweise parsed Django diese Multipart-POSTs mit dem email Modul von Python. Dieses produziert dann fleissig Unicode-Strings aus den als utf-8 markierten Parts. Was ja auch an und für sich korrekt ist - nur sind im Django-Source überall im Sourcecode str() Aufrufe verstreut. Und die krachen dann natürlich, wenn sie unicode vorgeworfen bekommen in dem Zeichen oberhalb von chr(128) drin sind.

Ich hab mir den Source mal angeguckt, der realistischste Ansatz dürfte sein in Django einfach generell dafür zu sorgen das auch Unicode-Ergebnisse dann wieder nach utf-8 gewandelt werden, so das intern nur normale Python-Strings benutzt werden. Das klappt auch soweit, aber es gibt dann noch Probleme mit manchen Datenbanken die bei Speicherung von utf-8 Inhalten das erkennen und dann beim Lesen der Inhalte wieder Unicode produzieren - SQLite ist so eine Datenbank.

Tja, das wird nicht ganz einfach zu beheben sein. Ich hab mich schon mal dran versucht, das ist ein ziemlich ekliges Thema und leider in Django überhaupt nicht berücksichtigt worden - und daher kracht es an allen Ecken und Enden. Mal gucken ob ich da nicht doch noch was brauchbares hinkriege ...

Was mir auch noch aufgefallen ist: Django schickt den Content-type nur über ein meta-Tag mit http-equiv raus. Das ist ein übler Hack, wesentlich besser wäre es wenn der Content-type korrekt als Header gesetzt wäre, dann kann auch nix schief gehen wenn z.B. Apache einen Default-Charset zufügen will. Und die Browser würden auch wesentlich reproduzierbarer reagieren.

Jedenfalls ist das wieder der typische Fall von amerikanischen Programmierern. Die erzählen einem gerne das man einfach nur auf Unicode und utf-8 wechseln soll wenn man von seinen Zeichensatzkodierungsproblemen berichtet, aber ich habe bisher noch keine Software eines amerikanischen Programmierers gesehen die Unicode korrekt gehandhabt hätte ...

Ansonsten gibts in Django noch so die eine oder andere Klinke - besonders nervig, weil nicht dokumentiert, aber leicht zu lösen: die Standard-Zeitzone in Django ist America/Chicago. Dazu muss man dann nur eine Variable TIME_ZONE mit 'Europe/Berlin' als Wert in sein settings-File schreiben und noch einen kleinen Patch anwenden, damit Django mit dem '-' als Zeitzonentrennzeichen klarkommt. Oh Mann, wenn Amerikaner schon mal Software schreiben ...

Irgendwie steigt im Moment gerade meine Motivation mir doch erstmal Ruby on Rails genauer anzugucken, schliesslich sind das Dänen die damit angefangen haben und die sollten zumindestens solche Sachen richtig hinkriegen (wenn nur nicht dieser nette automatische Administrationsteil von Django wäre - der ist es ja genau auf den ich es abgesehen hätte. Warum hat sowas nur keiner für ROR eingebaut, menno ...)

Update: Ich hab am entsprechenden Ticket zum Unicode-Problem einen Patch angehängt (einfach nach ganz unten scrollen) der erstmal das Problem halbwegs in den Griff bekommt - sofern man kein SQLite einsetzt, da SQLite immer Unicode-Strings zurückliefert und die dann auch wieder Stress machen. Aber zumindestens mit PostgreSQL funktionieren jetzt Umlaute in Django. Die Lösung ist nicht wirklich perfekt, aber zumindestens mit nur wenig Codeänderung reinzubringen. Eine richtige Lösung würde wohl grössere Codeumbauten erfordern.

Ein weiterer Patch hängt am Ticket zum Zeitzonenproblem, mit dem Patch kann man dann auch TIME_ZONE = 'Europe/Berlin' benutzen um die Zeitangaben zum Beispiel in der Änderungshistorie in der richtigen Zeitzone zu bekommen.

In solchen Momenten wünscht man sich commit-Rechte zu Django, um solche recht überschaubaren Patches selber reinstellen zu können

Noch ein Update: Adrian war im Chat gestern und heute und die Probleme mit Unicode sind weitestgehend raus. Nur mit SQLite gibts noch Stress, aber da hab ich den Patch schon fertig. Und die Zeitzonengeschichte ist auch behoben im SVN. Und er hat Unittests begonnen. Sehr sinnvoll, wenn man dann mal auf Dauer das ganze Framework sauber durchtesten kann nach einem Patch ...

Linkhaftung nach dem Heise-Urteil

Nach diesem Interview beim WDR gilt: "Jeder, der so einen Link setzt, ist dran":

Man muss eben sehr gut aufpassen. Aufgrund dieser neuen Urteile muss man sich überlegen: Auf wen setze ich einen Link? Früher hat man als Privatperson gesagt: 'Komm, ich hau da hundert Links hintereinander' und war ganz stolz. Heute muss man sich wirklich überlegen, ob der, auf den man einen Link setzt, wirklich vertrauenswürdig ist. Man muss diese Links dann auch in regelmäßigen Abständen gegenchecken und prüfen, was sich auf der gelinkten Seite tut.

Womit - wenn es denn tatsächlich so wäre - faktisch das privat betriebene Infoangebot tot wäre auf kurz oder lang, denn niemand kann seine ganzen Links durchprüfen. Ich hab hier fast 5000 Artikel im Blog, die werd ich garantiert nie alle durchgucken können ob da irgendwo irgendwas ist das irgendwem quer aufstösst.

Und so hat dieses Urteil wieder einen weiteren Nagel in den Sarg des Internet getrieben, nur weil Richter immer wieder diese Scheinrechte von Rechteabzockern höher als die freie Meinungsäusserung und die freie Berichterstattung einstufen

Wer wie ich in die Situation kommt das er die Unicode-Strings in PySQLite2 nicht mag und utf8 Bytestrings braucht: PysqliteFactories sind hier die Lösung, nicht Konverter. Denn Konverter müssten auf jede Spielart von varchar registriert werden die in Benutzung ist - die Row Factories hingegen sind da ziemlich agnostisch und praktisch. Und wenn man schon eine eigene Cursor-Klasse benutzt: diese einfach als Cursor Factory auslegen die dann mit self.row_factory der Instanz eine Row Factory verpasst.

Sysadmins Day

Lisa9 zeigt wie man anständig einem Sysadmin huldigt! Sogar DAU-tauglich mit bebilderter Anleitung

Abridged guide to HTTP Caching ist eine Beschreibung der wichtigsten Caching-Header in HTTP und wie sie verwendet werden sollten.

JSAN ist das für JavaScript was CPAN für Perl ist - ein zentrales Verzeichnis und Downloadbereich für JavaScript Sourcen und Paket.

Linux-VServer ist ein Kernel-Patch und ein Satz Utilities die es ermöglichen auf einer Basismaschine eine Reihe von virtuellen Linux-Kisten laufen zu haben deren Resourcen stark gegeneinander abgeschottet sind. chroot on steroids, oder am ehesten mit BSD Jails zu vergleichen. Interessant für Hosting-Projekte bei denen virtuelle Rootserver gefordert sind. Ist sogar in der aktuellen Debian drin.

Tor Network Status liefert eine Übersicht über Exit-Nodes im tor Netzwerk mit Trafficangaben, erlaubten Ports und IP-Daten. Nett. (gefunden über den Rabenhorst)

typo ist eine Blogsoftware für Ruby on Rails mit scheinbar schon recht weit ausgebauten Features. Speziell auch mit gutem Caching (produziert statische Seiten) für High-Traffic-Sites, bei denen dann Teile per JavaScript weiter dynamisch gehalten werden. Klingt danach das ich mir das nochmal angucken werde wenn mein ROR-Buch ankommt ...

Und die Erde ist doch eine Scheibe - von wegen. Dagegen ansingen!

Django, lighttpd and FCGI, second take

In my first take at this stuff I gave a sample on how to run django projects behind lighttpd with simple FCGI scripts integrated with the server. I will elaborate a bit on this stuff, with a way to combine lighttpd and Django that gives much more flexibility in distributing Django applications over machines. This is especially important if you expect high loads on your servers. Of course you should make use of the Django caching middleware, but there are times when even that is not enough and the only solution is to throw more hardware at the problem.

Update: I maintain my descriptions now in my trac system. See the lighty+FCGI description for Django.

Caveat: since Django is very new software, I don't have production experiences with it. So this is more from a theoretical standpoint, incorporating knowledge I gained with running production systems for several larger portals. In the end it doesn't matter much what your software is - it only matters how you can distribute it over your server farm.

To follow this documentation, you will need the following packages and files installed on your system:

  • [Django][2] itself - currently fetched from SVN. Follow the setup instructions or use python setup.py install .
  • [Flup][3] - a package of different ways to run WSGI applications. I use the threaded WSGIServer in this documentation.
  • [lighttpd][4] itself of course. You need to compile at least the fastcgi, the rewrite and the accesslog module, usually they are compiled with the system.
  • [Eunuchs][5] - only needed if you are using Python 2.3, because Flup uses socketpair in the preforked servers and that is only available starting with Python 2.4
  • [django-fcgi.py][6] - my FCGI server script, might some day be part of the Django distribution, but for now just fetch it here. Put this script somewhere in your $PATH, for example /usr/local/bin and make it executable.
  • If the above doesn't work for any reason (maybe your system doesn't support socketpair and so can't use the preforked server), you can fetch [django-fcgi-threaded.py][7] - an alternative that uses the threading server with all it's problems. I use it for example on Mac OS X for development.

Before we start, let's talk a bit about server architecture, python and heavy load. The still preferred Installation of Django is behind Apache2 with mod python2. mod python2 is a quite powerfull extension to Apache that integrates a full Python interpreter (or even many interpreters with distinguished namespaces) into the Apache process. This allows Python to control many aspects of the server. But it has a drawback: if the only use is to pass on requests from users to the application, it's quite an overkill: every Apache process or thread will incorporate a full python interpreter with stack, heap and all loaded modules. Apache processes get a bit fat that way.

Another drawback: Apache is one of the most flexible servers out there, but it's a resource hog when compared to small servers like lighttpd. And - due to the architecture of Apache modules - mod_python will run the full application in the security context of the web server. Two things you don't often like with production environments.

So a natural approach is to use lighter HTTP servers and put your application behind those - using the HTTP server itself only for media serving, and using FastCGI to pass on requests from the user to your application. Sometimes you put that small HTTP server behind an Apache front that only uses mod proxy (either directly or via mod rewrite) to proxy requests to your applications webserver - and believe it or not, this is actually a lot faster than serving the application with Apache directly!

The second pitfall is Python itself. Python has a quite nice threading library. So it would be ideal to build your application as a threaded server - because threads use much less resources than processes. But this will bite you, because of one special feature of Python: the GIL. The dreaded global interpreter lock. This isn't an issue if your application is 100% Python - the GIL only kicks in when internal functions are used, or when C extensions are used. Too bad that allmost all DBAPI libraries use at least some database client code that makes use of a C extension - you start a SQL command and the threading will be disabled until the call returns. No multiple queries running ...

So the better option is to use some forking server, because that way the GIL won't kick in. This allows a forking server to make efficient use of multiple processors in your machine - and so be much faster in the long run, despite the overhead of processes vs. threads.

For this documentation I take a three-layer-approach for distributing the software: the front will be your trusted Apache, just proxying all stuff out to your project specific lighttpd. The lighttpd will have access to your projects document root and wil pass on special requests to your FCGI server. The FCGI server itself will be able to run on a different machine, if that's needed for load distribution. It will use a preforked server because of the threading problem in Python and will be able to make use of multiprocessor machines.

I won't talk much about the first layer, because you can easily set that up yourself. Just proxy stuff out to the machine where your lighttpd is running (in my case usually the Apache runs on different machines than the applications). Look it up in the mod_proxy documentation, usually it's just ProxyPass and ProxyPassReverse.

The second layer is more interesting. lighttpd is a bit weird in the configuration of FCGI stuff - you need FCGI scripts in the filesystem and need to hook those up to your FCGI server process. The FCGI scripts actually don't need to contain any content - they just need to be in the file system.

So we start with your Django project directory. Just put a directory public html in there. That's the place where you put your media files, for example the admin media directory. This directory will be the document root for your project server. Be sure only to put files in there that don't contain private data - private data like configs and modules better stay in places not accessible by the webserver. Next set up a lighttpd config file. You only will use the rewrite and the fastcgi modules. No need to keep an access log, that one will be written by your first layer, your apache server. In my case the project is in /home/gb/work/myproject - you will need to change that to your own situation. Store the following content as /home/gb/work/myproject/lighttpd.conf


 server.modules = ( "mod_rewrite", "mod_fastcgi" )
 server.document-root = "/home/gb/work/myproject/public_html"
 server.indexfiles = ( "index.html", "index.htm" )
 server.port = 8000
 server.bind = "127.0.0.1"
 server.errorlog = "/home/gb/work/myproject/error.log"

fastcgi.server = (
"/main.fcgi" => (
"main" => (
"socket" => "/home/gb/work/myproject/main.socket"
 )
 ),
"/admin.fcgi" => (
"admin" => (
"socket" => "/home/gb/work/myproject/admin.socket"
 )
 )
 )

url.rewrite = (
"^(/admin/.*)$" => "/admin.fcgi$1",
"^(/polls/.*)$" => "/main.fcgi$1"
 )

mimetype.assign = (
".pdf" => "application/pdf",
".sig" => "application/pgp-signature",
".spl" => "application/futuresplash",
".class" => "application/octet-stream",
".ps" => "application/postscript",
".torrent" => "application/x-bittorrent",
".dvi" => "application/x-dvi",
".gz" => "application/x-gzip",
".pac" => "application/x-ns-proxy-autoconfig",
".swf" => "application/x-shockwave-flash",
".tar.gz" => "application/x-tgz",
".tgz" => "application/x-tgz",
".tar" => "application/x-tar",
".zip" => "application/zip",
".mp3" => "audio/mpeg",
".m3u" => "audio/x-mpegurl",
".wma" => "audio/x-ms-wma",
".wax" => "audio/x-ms-wax",
".ogg" => "audio/x-wav",
".wav" => "audio/x-wav",
".gif" => "image/gif",
".jpg" => "image/jpeg",
".jpeg" => "image/jpeg",
".png" => "image/png",
".xbm" => "image/x-xbitmap",
".xpm" => "image/x-xpixmap",
".xwd" => "image/x-xwindowdump",
".css" => "text/css",
".html" => "text/html",
".htm" => "text/html",
".js" => "text/javascript",
".asc" => "text/plain",
".c" => "text/plain",
".conf" => "text/plain",
".text" => "text/plain",
".txt" => "text/plain",
".dtd" => "text/xml",
".xml" => "text/xml",
".mpeg" => "video/mpeg",
".mpg" => "video/mpeg",
".mov" => "video/quicktime",
".qt" => "video/quicktime",
".avi" => "video/x-msvideo",
".asf" => "video/x-ms-asf",
".asx" => "video/x-ms-asf",
".wmv" => "video/x-ms-wmv"
 )

I bind the lighttpd only to the localhost interface because in my test setting the lighttpd runs on the same host as the Apache server. In multi server settings you will bind to the public interface of your lighttpd servers, of course. The FCGI scripts communicate via sockets in this setting, because in this test setting I only use one server for everything. If your machines would be distributed, you would use the "host" and "port" settings instead of the "socket" setting to connect to FCGI servers on different machines. And you would add multiple entries for the "main" stuff, to distribute the load of the application over several machines. Look it up in the lighttpd documentation what options you will have.

I set up two FCGI servers for this - one for the admin settings and one for the main settings. All applications will be redirected through the main settings FCGI and all admin requests will be routed to the admin server. That's done with the two rewrite rules - you will need to add a rewrite rule for every application you are using.

Since lighttpd needs the FCGI scripts to exist to pass along the PATH_INFO to the FastCGI, you will need to touch the following files: /home/gb/work/myprojectg/public_html/admin.fcgi ``/home/gb/work/myprojectg/public_html/main.fcgi

They don't need to contain any code, they just need to be listed in the directory. Starting with lighttpd 1.3.16 (at the time of this writing only in svn) you will be able to run without the stub files for the .fcgi - you just add "check-local" => "disable" to the two FCGI settings. Then the local files are not needed. So if you want to extend this config file, you just have to keep some very basic rules in mind:

  • every settings file needs it's own .fcgi handler
  • every .fcgi needs to be touched in the filesystem - this might go away in a future version of lighttpd, but for now it is needed
  • load distribution is done on .fcgi level - add multiple servers or sockets to distribute the load over several FCGI servers
  • every application needs a rewrite rule that connects the application with the .fcgi handler

Now we have to start the FCGI servers. That's actually quite simple, just use the provided django-fcgi.py script as follows:


 django-fcgi.py --settings=myproject.work.main
 --socket=/home/gb/work/myproject/main.socket
 --minspare=5 --maxspare=10 --maxchildren=100
 --daemon

django-fcgi.py --settings=myproject.work.admin
 --socket=/home/gb/work/myproject/admin.socket
 --maxspare=2 --daemon

Those two commands will start two FCGI server processes that use the given sockets to communicate. The admin server will only use two processes - this is because often the admin server isn't the server with the many hits, that's the main server. So the main server get's a higher-than-default setting for spare processes and maximum child processes. Of course this is just an example - tune it to your needs.

The last step is to start your lighttpd with your configuration file: lighttpd -f /home/gb/work/myproject/lighttpd.conf

That's it. If you now access either the lighttpd directly at http://localhost:8000/polls/ or through your front apache, you should see your application output. At least if everything went right and I didn't make too much errors.

Eunuchs liefert ein paar Funktionen nach die unter Python 2.3 noch nicht verfügbar sind. Speziell socketpair und recvmsg/sendmsg sind da sehr wichtig - für Serverprogrammierung mit preforked Servern zum Beispiel.

Noch son Fragebogen

Aus meiner Mailbox von Lisa Sonnabend:

Im Rahmen meiner Abschlussarbeit am Institut für Kommunikationswissenschaft und Medienforschung der Ludwigs-Maximilians-Universität München führe ich eine Befragung unter Webloglesern zum Thema „Glaubwürdigkeit von Weblogs“ durch. Es handelt sich um eine der ersten wissenschaftlichen Untersuchungen zum Phänomen Weblogs in Deutschland.

Es soll geklärt werden, ob Weblogs in gewissen Punkten wie Fairness oder Unvoreingenommenheit bereits als ähnlich vertrauenswürdig und kompetent gesehen werden wie traditionelle Medien – und in welchen Punkten große Unterschiede herrschen. Darüber hinaus wird mit der Befragung untersucht, welche besonderen Qualitäten Weblogs aus Sicht der Rezipienten haben und welchen Stellenwert diese für die Nutzer spielen. Anhand der Ergebnisse soll anschließend eine Prognose über das zukünftige Gewicht von Weblogs in der Medienlandschaft gefällt werden.

Und ich soll den Link ins Blog packen, damit Leute dabei mitmachen. Nagut, mach ich das doch mal, auch wenn ich mich frage was für eine Kompetenz und Vertrauenswürdigkeit die alten Medien eigentlich haben sollen

Hier gehts zum Fragebogen

präventive Telefonüberwachung is nich

Denn das Verfassungsgericht erklärt präventive Telefonüberwachung für nichtig. Betrifft primär Niedersachsen, aber ähnliche Situationen gibt es auch in anderen Bundesländern. Gut wenn mal dem ganzen Überwachungsfetischismus ein Riegel vorgeschoben wird.

es gibt Tage da hasst mein Computer mich

Zum Beispiel wenn ich mit Flup spiele und statt des threaded Servers einen forked Server nehmen will. Und feststelle, das der dann aber die Funktion socketpair benötigt. Die aber dummerweise nur ab Python 2.4 verfügbar ist, welches zwar auf Debian Sarge da ist, aber dafür gibts in der Debian Sarge für Python 2.4 keinen Psycopg - welcher wiederum Voraussetzung für Django und PostgreSQL ist, weshalb ich mich überhaupt ja nur mit FastCGI beschäftige. PsycoPG selber installieren macht keinen Spaß, da man dafür nicht nur die PostgreSQL Header braucht, die normal installiert werden, sondern auch ein paar interne Header - also im Prinzip einen Build-Tree. Und dann braucht man noch die egenix-mx-base Header, die man nur für Python 2.3 kriegt, also müsste man das auch selber installieren. Backports aus der nächsten Debian geht auch nicht, da die gerade auf PostgreSQL 8.0 umbauen und Sarge ja noch 7.4 benutzt und ich nicht gleich das ganze System upgraden wollte. Und so dreht man sich im Kreis und kommt sich leicht verarscht vor vor lauter Abhängigkeiten und Versionskonflikten.

Und was macht man also als Lösung, weil der threaded Server dummerweise nur Segfaults im Psycopg produziert? Man nimmt den threaded Server, verbietet ihm das threaden und startet ihn über den spawn-fcgi vom lighttpd, oder direkt vom lighttpd. Was aber irgendwie auch wieder dämlich ist, da dann immer pro FCGI-Server 3 Threads rumgammeln, von denen 2 nur in der Prozessliste stehen und nix zu tun haben. Und das alles nur weil mod python2 (was für Django gebraucht wird) Apache2 voraussetzt, der wiederum mod perl2 voraussetzt, welches inkompatibel zum alten mod perl ist, weshalb bei mir eine ganze Reihe von meinen Sites nicht mehr laufen würden, würde ich auf Apache2 umstellen. Was ich eh nicht will, weil Apache2 mit mod python arschlangsam ist. Und schon wieder verarscht worden. Ich hätte mir echt einen sinnvolleren Beruf suchen sollen.

Wer nix kapiert hat: macht nix, ist Technik, ist nicht wichtig, wollte das einfach nur mal gesagt haben.

Higher-Order Perl ist ein Buch (zur Zeit Papier, aber soll demnächst frei im Netz lesbar sein) das sich mit higher order functions und Perl beschäftigt - könnte ganz interessant sein, Perl bietet da eine ganze Menge Features versteckt unter all den geschweiften Klammern und anderen Sonderzeichen ...

Running Django with FCGI and lighttpd

Diese Dokumentation ist für einen grösseren Kreis als nur .de gedacht, daher das ganze in Neuwestfälisch Englisch. Sorry. Update: I maintain the actually descriptions now in my trac system. See the FCGI+lighty description for Django. There are different ways to run Django on your machine. One way is only for development: use the django-admin.py runserver command as documented in the tutorial. The builtin server isn't good for production use, though. The other option is running it with mod_python. This is currently the preferred method to run Django. This posting is here to document a third way: running Django behind lighttpd with FCGI.

First you need to install the needed packages. Fetch them from their respective download address and install them or use preinstalled packages if your system provides those. You will need the following stuff:

  • [Django][2] itself - currently fetched from SVN. Follow the setup instructions or use python setup.py install .
  • [Flup][3] - a package of different ways to run WSGI applications. I use the threaded WSGIServer in this documentation.
  • [lighttpd][4] itself of course. You need to compile at least the fastcgi, the rewrite and the accesslog module, usually they are compiled with the system.

First after installing ligthttpd you need to create a lighttpd config file. The configfile given here is tailored after my own paths - you will need to change them to your own situation. This config file activates a server on port 8000 on localhost - just like the runserver command would do. But this server is a production quality server with multiple FCGI processes spawned and a very fast media delivery.


 # lighttpd configuration file
 #
 ############ Options you really have to take care of ####################

server.modules = ( "mod_rewrite", "mod_fastcgi", "mod_accesslog" )

server.document-root = "/home/gb/public_html/"
 server.indexfiles = ( "index.html", "index.htm", "default.htm" )

 these settings attch the server to the same ip and port as runserver would do

server.errorlog = "/home/gb/log/lighttpd-error.log"
 accesslog.filename = "/home/gb/log/lighttpd-access.log"

fastcgi.server = (
"/myproject-admin.fcgi" => (
"admin" => (
"socket" => "/tmp/myproject-admin.socket",
"bin-path" => "/home/gb/public_html/myproject-admin.fcgi",
"min-procs" => 1,
"max-procs" => 1
 )
 ),
"/myproject.fcgi" => (
"polls" => (
"socket" => "/tmp/myproject.socket",
"bin-path" => "/home/gb/public_html/myproject.fcgi"
 )
 )
 )

url.rewrite = (
"^(/admin/.*)$" => "/myproject-admin.fcgi$1",
"^(/polls/.*)$" => "/myproject.fcgi$1"
 )

This config file will start only one FCGI handler for your admin stuff and the default number of handlers (each one multithreaded!) for your own site. You can finetune these settings with the usual ligthttpd FCGI settings, even make use of external FCGI spawning and offloading of FCGI processes to a distributed FCGI cluster! Admin media files need to go into your lighttpd document root.

The config works by translating all standard URLs to be handled by the FCGI script for each settings file - to add more applications to the system you would only duplicate the rewrite rule for the /polls/ line and change that to choices or whatever your module is named. The next step would be to create the .fcgi scripts. Here are the two I am using:


 #!/bin/sh
 # this is myproject.fcgi - put it into your docroot

export DJANGOSETTINGSMODULE=myprojects.settings.main

/home/gb/bin/django-fcgi.py

 #!/bin/sh
 # this is myproject-admin.fcgi - put it into your docroot

export DJANGOSETTINGSMODULE=myprojects.settings.admin

/home/gb/bin/django-fcgi.py

These two files only make use of a django-fcgi.py script. This is not part of the Django distribution (not yet - maybe they will incorporate it) and it's source is given here:


 #!/usr/bin/python2.3

def main():
 from flup.server.fcgi import WSGIServer
 from django.core.handlers.wsgi import WSGIHandler
 WSGIServer(WSGIHandler()).run()

if name == 'main':
 main()

As you can see it's rather simple. It uses the threaded WSGIServer from the fcgi-module, but you could as easily use the forked server - but as the lighttpd already does preforking, I think there isn't much use with forking at the FCGI level. This script should be somewhere in your path or just reference it with fully qualified path as I do. Now you have all parts togehter. I put my lighttpd config into /home/gb/etc/lighttpd.conf , the .fcgi scripts into /home/gb/public_html and the django-fcgi.py into /home/gb/bin . Then I can start the whole mess with /usr/local/sbin/lighttpd -f etc/lighttpd.conf . This starts the server, preforkes all FCGI handlers and detaches from the tty to become a proper daemon. The nice thing: this will not run under some special system account but under your normal user account, so your own file restrictions apply. lighttpd+FCGI is quite powerfull and should give you a very nice and very fast option for running Django applications. Problems:

  • under heavy load some FCGI processes segfault. I first suspected the fcgi library, but after a bit of fiddling (core debugging) I found out it's actually the psycopg on my system that segfaults. So you might have more luck (unless you run Debian Sarge, too)

  • Performance behind a front apache isn't what I would have expected. A lighttpd with front apache and 5 backend FCGI processes only achieves 36 requests per second on my machine while the django-admin.py runserver achieves 45 requests per second! (still faster than mod_python via apache2: only 27 requests per second) Updates:

  • the separation of the two FCGI scripts didn't work right. Now I don't match only on the .fcgi extension but on the script name, that way /admin/ really uses the myproject-admin.fcgi and /polls/ really uses the myproject.fcgi.

  • I have [another document online][6] that goes into more details with regard to load distribution

flup: random Python WSGI stuff - eine Sammlung von WSGI-Server-Adaptern für FCGI, SCGI und Apache Jakarta 1.3 Protokolle sowie noch ein paar WSGI-Middlewares zur Authentifizierung, Komprimierung und Fehlerhandling.

Idiotische Patente die elfundelfzigste

Immer wenn man meint, man hätte schon das idiotischste Patent geseheh, kommts garantiert noch dämlicher - Microsoft will Smileys patentieren:

Der am Donnerstag veröffentlichte Patentantrag beschreibt ein Verfahren, um selbst erzeugte Emoticon-Bildchen als Zeichenfolgen zu kodieren, die sich in Textnachrichten einbetten lassen.

Leonardo ist ein CMS mit Blog und Wiki Modulen in Python. Im Moment noch recht schlicht als CGI, soll aber auf WSGI und Paste umgestellt werden und könnte dann ganz interessant als generelle CMS-Komponenten in einer WSGI-Lösung sein.

Python Paste ist ein Meta-Framework - ein Framework zur Erstellung neuer Web-Frameworks auf WSGI-Basis. Viele interessante Middleware-Module und eine Reimplementation von WebWare auf WSGI-Basis.

Scotland Yard erschiesst Unschuldigen

Mitlerweile ist ja klar das der von der britischen Polizei Erschossene unschuldig war. Und trotzdem: Scotland Yard verteidigt Kopfschuss-Praxis. Der frühere Scotland Yard Leiter:

"Es gibt nur einen sicheren Weg, einen Selbstmordattentäter zu stoppen, der davon überzeugt ist, seine Mission auszuüben - sein Gehirn sofort zu zerstören, vollständig", schrieb er in der Sonntagszeitung "News of the World". "Das heißt, ihn mit zerstörerischer Wucht in den Kopf zu schießen, ihn sofort zu töten."

Man muss dabei bedenken, das waren Polizisten in Zivil - eine Panikreaktion wenn eine Gruppe bewaffneter Menschen in Zivilkleidung hinter einem her sind ist ja wohl vorprogrammiert. Das dann als Begründung für einen gezielten Kopfschuss zu nehmen ist mehr als nur Zynismus.

Hinrichtungen auf Verdacht als Antwort auf Terror - damit wird der angebliche Schutz der Gesellschaft selber zum Terror und zur Gefahr für jeden Bürger. Die Unmenschlichkeit der Polizei-Vertreter in der Verteidigung dieser Praxis - Police chief 'sorry' over death - ist einfach nur abstoßend.

Seaside ist ein flexibles und sehr interessantes Web-Framework in Smalltalk. Tutorials hatte ich schon mal dazu gelinkt, aber das Framework selber noch nicht - jedenfalls nicht an seiner neuen Adresse. Läuft auf Squeak und Visual Works - und durch deren breite Verfügbarkeit fast auf allem das sich Computer nennen darf und eine TCP/IP-Verbindung zur Aussenwelt hat.

verpflichtetes Versicherungssponsoring durch den Staat?

Bundesaussenminister Fischer will eine verbindliche Riester-Rente - fragt sich natürlich der Leser was der Aussenminister damit zu tun hat, aber egal:

Bundesaußenminister Joschka Fischer hat sich für die Einführung einer verpflichtenden privaten Rentenversicherung ausgesprochen. "Das Rentensystem muss bezahlbar sein. Ich wünsche mir, dass die Riester-Rente endlich verbindlich eingeführt wird und wir die Menschen zur privaten Vorsorge ermutigen"

Soso. Zur privaten Vorsorge ermutigen. Dazu dann eine verpflichtende Teilnahme an der grössten Versicherungsabzocke aller Zeiten - der Riester-Rente, deren Renditen bescheiden sind und deren Zahlungsabsicherungen mehr als fragwürdig sind.

Man könnte natürlich auch einfach ein Modell einer Bürgerversicherung wählen, bei dem jeder in die staatlichen Sozialversicherungen einzahlt, ohne Besserverdienenden ein Schlupfloch nach draussen zu lassen - gerade im Rahmen der tollen Ideen wie Ich-AG und vermehrter Selbstständigkeit wird nämlich das Sozialversicherungssystem noch weiter ausgehöhlt. Aber das wäre ja eine intelligente Lösung. Die Staatlichen Sozialversicherungen haben nämlich den Vorteil das sie durch die Verfassung gewissen Regeln unterworfen sind - und der Staat sicherstellen muss, das auch die entsprechenden Leistungen erbracht werden.

Statt dessen wird also weiter die private Versicherungsbranche gesponsort und nach Fischers Vorstellungen auch noch mit ner Pflicht für den Bürger. Ja sowas bringt Aufschwung, sowas macht Sinn. Das die Bürger da nur über den Tisch gezogen werden und viele Modelle reine Beutelschneiderei sind und eine Auszahlungssicherheit in keinster Weise gegeben ist, ignorieren wir einfach mal.

Eins ist sicher: bei der Idiotie unserer Politiker gibts demnächst viel zu verdienen in der Versicherungsbranche. Die dann vermutlich nichts besseres zu tun hat als unsere dann privaten Zwangsrenten an der Börse zu verzocken und an Hedgefonds zu verhökern.

Verrückter Vinokourov ...

... schnappt der einfach den Sprintermannschaften den Sieg in Paris vor der Nase weg. Damit hat nun wirklich niemand gerechnet. Erst greift er sich noch zwei Sekunden Gutschrift im Kampf um die Gesamtwertung und da den 5. Platz ab und dann will er einfach sich nicht einreihen und den Sprintern das Feld überlassen. Klasse Aktion, solche Überraschungen mag ich

Da wird Otto wieder schäumen

Owl Content

Jetzt muss er warscheinlich gegen die EU wettern, denn die EU-Kommission pocht auf Unabhängigkeit der Datenschutzbehörden:

Die EU-Kommision hat gegen Deutschland ein Vertragsverletzungsverfahren wegen Missachtung der EU-Datenschutzrichtlinie eingeleitet. Sie beanstandet, dass die Aufsicht über die Gewährleistung der Privatsphäre hierzulande in staatlicher Hand ruht. Die "derzeitige Organisation der für die Überwachung der Datenverarbeitung im nicht-öffentlichen Bereich zuständigen Kontrollstellen" sei "nicht mit Gemeinschaftsrecht vereinbar", heißt es in einem heise online vorliegenden Schreiben der Generaldirektion für Justiz, Freiheit und Sicherheit.

In wieweit man in Anbetracht der Bestrebungen zu längeren Speicherzeiten für Komunikationsdaten innerhalb der EU viel auf das plötzliche Eintreten der EU-Kommission für den Datenschutz geben sollte ist eine ganz andere Sache ...

GNU Modula-2 war mir bisher unbekannt. Schön das sich Modula-2 auch in der GNU-Compilerfamilie wiederfindet. Auch wenn Modula-2 für mich nur noch historisches Interesse hat - dynamische Sprachen wie Python sind mir einfach wesentlich lieber. Aber es gab mal Zeiten als ich noch fleissig in Modula-2 programmiert habe.

MochiKit ist eine JavaScript-Bibliothek mit einer ganzen Reihe von Erweiterungen für JavaScript. Vor allem Iteratoren, vernünftige funktionale Konzepte (filter, map, partial application), aber auch eine ganze Reihe neuer Ideen, wie zum Beispiel eine sehr nette AJAX-Integration. Sieht schon ganz nett aus, muss ich mal mit rumspielen.

Spitzenköche kämpfen für Linda - und wollen eine Unterschriftenaktion starten. Hey, meine Unterschrift habt ihr dafür. Schliesslich bin ich bei Kartoffeln extrem wählerisch. Und nein, da reichts nicht das die neue Kartoffelsorte einen Namen aus Startrek Voyager trägt

Von Pechvögeln und Favoriten

Naja, heute war eines auf jeden Fall ganz klar (neben der Tatsache das Armstrong halt immer noch besser als Ullrich fährt, auch beim Zeitfahren): Rasmussen ist der Pechvogel des Tages. Zwei Stürze, 5 Defekte und über 7 Minuten eingetütet bekommen, das tut weh. Zum Glück ist er angekommen und er kann sich trösten: auch heute bekommt er ein gepunktetes Trikot übergestreift.

Die nächste Tour zeichnet sich mit den Favoriten auch ab: Ullrich und Basso ganz oben in der Liste. Vinokourov sicherlich auch ein Favorit, aber definitiv mit deutlichem Abstand. Mag ja sein das irgendwann ein neuer Fahrer nachkommt - aber die drei sind auf jeden Fall beim Kampf um den Sieg dabei.

Interessanter wird es allemal wenn Armstrong nicht mehr antritt - die Favoriten fürs nächste Jahr liegen definitiv deutlich enger beieinander und damit dürften die Kämpfe auch wieder spannender werden. Ullrich und Vinokourov klar die deutlich stärkeren Zeitfahrer, Basso der deutlich bessere Bergfahrer - das wird mit Sicherheit spannend.

Nur eins kapier ich auch am Ende der Tour nicht: wieso T-Mobile den Zabel nicht mitgenommen haben. Diese Pfeifen.

Und wieder mal Django

Django - das kommende Webframework für Python - hat jetzt SQLite 3 Support. Damit ist eine Installation einer Entwicklungsumgebung für Django-Projekte jetzt extrem simpel geworden: Python 2.3 oder Python 2.4 muss da sein und ansonsten noch SQLite3 und PySQLite2. Auf dem Mac ist also im Prinzip schon alles da, ausser PySQLite2 - letzteres kann man sich aber von www.pysqlite.org holen und einfach mittels sudo python setup.py install installieren. Und schon kann man mit Django loslegen und die Tutorials durcharbeiten. Kein Apache mehr nötig, kein PostgreSQL (zwar die netteste aller SQL-Datenbanken, aber trotzdem für eine Entwicklungsumgebung auf Notebook manchmal einfach Overkill) und vor allem nicht psycopg - dessen Installation leider einen fast vollständigen PostgreSQL-Source-Tree erfordert. Es gibt also keine Ausrede für Pythonistas mehr sich nicht mit Django zu beschäftigen

Internet-Pranger der US-Strafverfolgungsbehörden

Scheiss auf Persönlichkeitsrechte, im Land der Mutigen und Freien stellt das US-Justizministerium eine Sexualstraftäter-Datenbank ins Netz. Und wer glaubt das wär ja nicht so schlimm, trifft ja nur Vergewaltiger und Pädophile:

Die Online-Aktivitäten der US-amerikanischen Strafverfolger richten sich nicht nur gegen verurteilte Straftäter. Die Polizei von Chicago hat kürzlich eine Site in Betrieb genommen, auf der Personen abgebildet und mit Namen veröffentlicht werden, die der "Unterstützung der Prostitution" verdächtigt werden. Auf der Site findet sich der Hinweis, dass die aufgeführten Personen als unschuldig gelten, bis ein Gericht ihre Schuld festgestellt hat.

Toll, nicht war? Hängen wir dein Bild einfach mal an den Pranger, den kleinen Nebensatz wird der Lynchmob sicherlich lesen bevor er das Seil auspackt und mit deinem Arsch zum nächsten Baum zieht. Und sowieso, Sexualstraftäter kann man als Begriff ja garnicht weit genug fassen ...

Grosser Lauschangriff auch in Sachsen Verfassungswidrig

Owl Content

Sachsens Verfassungsgerichtshof kippt in Teilen den "Großen Lauschangriff" und natürlich fühlen die Poltiker sich trotzdem bestätigt, es müssen ja nur die Gesetze geändert werden - sorry, aber das sehe ich anders. Die Denke muss geändert werden und es ist schade das die Verfassungsrichter nicht da deutlicher werden.

Apache modauthtkt ist ein Framework für Single-Signon in Apache-basierten Lösungen über Technikgrenzen (CGI, mod_perl und was sonst noch so existiert) hinweg. Müsste ich mir mal angucken, könnte für mich interessant sein.

Doohan alias Scotty gestorben

Scotty wurde zum letzten Mal hochgebeamt - und diesmal wird ihn wohl keiner aus dem Musterpuffer seines Transporters rekonstruieren können. Trinken wir ein Gläschen Scotch auf ihn.

Wie die BWLer unter Bertelsmann in die Bildungspolitik einziehen

Bei Telepolis gefunden: TP: Durchsetzung von Controlling und Ranking auf allen Ebenen:

Wäre ein kritischer Ökonom zum Kongress geladen gewesen, er hätte die Strategie der Bertelsmänner wohl so formuliert: Demokratische Entscheidungsfindung und offene Diskussion wird ersetzt durch Steuerungsverfahren aus der neueren Betriebswirtschaftslehre. Überzuckert wird alles mit dynamischen Anglizismen aus dem Marketing-Babbel, dahinter aber stecken oft Ideen aus dem BWL-Fach Controlling. Früher sprach man prosaischer vom Rechnungswesen/Interne Revision, meinte aber dasselbe: die innerbetriebliche Steuerung und Kontrolle von Produktionsprozessen. Die erfolgt mittels Nutzwertanalyse, Erfolgsrechnung, Budgetierung, Profit Center, Kennzahlen für alles und jedes etc.

Meine persönliche Abneigung gegen die BWL als meines Erachtens viel zu kurzsichtige Vision von Markt sollte ja mitlerweile bekannt sein. Die Verknüpfung mit einem recht scheinheilig agierenden Grossverlagshaus macht das ganze aber dann wirklich brisant - denn solche Konzerne haben nunmal in erster Linie eigene wirtschaftliche Interessen und sollten daher aus Bildungspolitischen Diskussionen rausgehalten werden, ganz besonders sind sie definitiv die falschen um sie in bildungspolitische Entscheidungsfindungen als Berater einzubinden. Aber im Zuge der Privatisierungsgeilheit der Politiker werden immer wieder solche Böcke geschossen - verbunden mit den dabei automatisch entstehenden Marketinglügen die von solchen Unternehmen dann zur Festigung der eigenen Route aufgebaut werden (wie z.B. die im Text zitierte Umfrage über Studiengebühren, bei der einfach der Weg des kostenlosen Studiums ausgeschlossen wurde - und dann behauptet wurde, das Studenten mehrheitlich für Studiengebühren wären).

Das grösste Problem bei dieser engen Verknüpfung mit der Wirtschaft - egal ob jetzt Bertelsmann in der Bildungspolitik oder andere Firmen in anderen Bereichen - ist die fehlende demokratische Kontrolle. Politiker werden noch rudimentär kontrolliert, öffentliche Einrichtungen sind durch das neue Informationsgesetz zur Offenlegung vieler Bereiche gezwungen, aber Entscheidungsfindungen in privatwirtschaftlichen Einrichtungen unterliegen diesen Kontrollen nicht. Wenn Politiker sich aber zum Beispiel auf Untersuchungen aus der Wirtschaft berufen wird man über das Informationsfreiheitsgesetz zwar bis zu dem Punkt kommen - das die Entscheidung auf einer Studie von Institut Sowieso basiert - aber über die Struktur und den eigentlichen Inhalt der Studie erfährt man unter Umständen garnichts. Und damit ist die Kontrolle durch die Bevölkerung stumpf ausgehebelt.

Gerade bei der Wichtigkeit der Bildungspolitik muss meines Erachtens jeder Einfluss von Wirtschaft und Industrie ausgeschlossen werden. Völlig egal was diese fordern - sie haben in der politischen Gestaltung der Bildungspolitik nichts verloren. Aber leider verkaufen unsere Politiker die politische Steuerung immer wieder an privatwirtschaftliche Institute, anstatt die Arbeit selber zu machen. Und sie verkaufen damit unsere Zukunft und unsere Souveränität als Gesellschaft an die Wirtschaft.