Archiv 31. 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 ...

Einfacher Dateisystem-Browser mit Django schreiben

Dieser Artikel ist mal wieder in Englisch, da er auch für die Leute auf #django interessant sein könnte. Dieser Beitrag zeigt, wie man einen sehr einfachen Dateisystem-Browser mit Django erstellt. Dieser Dateisystem-Browser verhält sich größtenteils wie ein statischer Webserver, der die Verzeichnisnavigation ermöglicht. Die einzige Besonderheit ist, dass Sie das Django-Admin verwenden können, um Dateisysteme zu definieren, die in den Namensraum des Django-Servers eingebunden werden. Dies dient nur zur Demonstration, wie eine Django-Anwendung verschiedene Datenquellen neben der Datenbank nutzen kann. Es ist nicht wirklich dazu gedacht, statischen Inhalt zu servieren (obwohl es mit hinzugefügter Authentifizierung quite nützlich für eingeschränkten statischen Inhalt sein könnte!).

Auch wenn die Anwendung sehr einfache Sicherheitsprüfungen an den übergebenen Dateinamen durchführt, sollten Sie dies nicht auf einem öffentlichen Server ausführen - ich habe keine Sicherheitstests durchgeführt und es könnte buttloads von schlechten Dingen geben, die Ihre privaten Daten der Welt preisgeben könnten. Sie wurden gewarnt. Wir beginnen wie üblich mit der Erstellung der Dateisystem-Anwendung mit dem Befehl django-admin.py startapp filesystems. Machen Sie es einfach so, wie Sie es mit Ihrer Umfrageanwendung im ersten Tutorial gemacht haben. Nur zur Orientierung, so sieht die myproject-Verzeichnis auf meiner Entwicklungsmaschine aus:


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

Nach der Erstellung der Infrastruktur beginnen wir mit dem Aufbau des Modells. Das Modell für die Dateisysteme ist sehr einfach - nur ein Name für das Dateisystem und ein Pfad, an dem die Dateien tatsächlich gespeichert sind. Hier ist es also, das Modell:


 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'], )


Wie Sie sehen können, ist das Modell und das Admin eher langweilig. Was interessant ist, sind jedoch die zusätzlichen Methoden `isdir`, `files` und `file`. `isdir` überprüft, ob ein gegebener Pfad unter dem Dateisystem ein Verzeichnis ist oder nicht. `files` gibt die Dateien des angegebenen Pfades unter dem Basispfad des Dateisystems zurück und `file` gibt den echten Dateipfad und den MIME-Typ einer gegebenen Datei unter dem Basispfad des Dateisystems zurück. Alle drei Methoden überprüfen die Gültigkeit des übergebenen Pfades - wenn der resultierende Pfad nicht unter dem Basispfad des Dateisystems liegt, wird eine ValueError ausgelöst. Dies soll sicherstellen, dass niemand `..` im Pfadnamen verwendet, um aus dem definierten Dateisystem-Bereich auszubrechen. Das Modell enthält also spezielle Methoden, die Sie verwenden können, um auf den Inhalt des Dateisystems selbst zuzugreifen, ohne sich Gedanken darüber zu machen, wie dies in Ihren Ansichten zu tun ist. Es ist die Aufgabe des Modells, solche Dinge zu kennen.

Der nächste Teil Ihres kleinen Dateisystem-Browsers wird die URL-Konfiguration sein. Sie ist eher einfach, sie besteht aus der Zeile in `settings/urls/main.py` und dem Modul `myproject.apps.filesystems.urls.filesystems`. Zuerst die Zeile im Haupt-URLs-Modul:

from django.conf.urls.defaults import *

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


Als nächstes das eigene URLs-Modul der Dateisysteme:

from django.conf.urls.defaults import *

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


Sie können die Anwendung nun der Haupt-Einstellungsdatei hinzufügen, damit Sie es später nicht vergessen. Suchen Sie einfach nach der Einstellung INSTALLED_APPS und fügen Sie den Dateibrowser hinzu:

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


Ein Teil fehlt noch: die Ansichten. Dieses Modul definiert die extern erreichbaren Methoden, die wir im URL-Mapper definiert haben. Wir benötigen also zwei Methoden, `index` und `directory`. Die zweite funktioniert tatsächlich nicht nur mit Verzeichnissen - wenn sie eine Datei übergeben bekommt, präsentiert sie einfach den Inhalt dieser Datei mit dem richtigen MIME-Typ. Die Ansicht macht Gebrauch von den in dem Modell definierten Methoden, um auf den tatsächlichen Dateisysteminhalt zuzugreifen. Hier ist der Quellcode für das Ansichtsmodul:

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


Sehen Sie, wie die Elemente des Verzeichnismusters als Parameter an die Directory-Methode übergeben werden - der Dateisystemname wird verwendet, um das richtige Dateisystem zu finden, und der Pfad wird verwendet, um den Inhalt unter dem Basispfad dieses Dateisystems zuzugreifen. MIME-Typen werden mit dem mimetypes-Modul aus der Python-Distribution ermittelt, übrigens.

Der letzte Teil unseres kleinen Tutorials sind die Vorlagen. Wir benötigen zwei Vorlagen - eine für den Index der definierten Dateisysteme und eine für den Inhalt eines Pfades unter einem Dateisystem. Wir benötigen keine Vorlage für den Dateiinhalt - der Dateiinhalt wird roh geliefert. Zuerst also die Hauptindexvorlage:

{% if fslist %}

definierte Dateisysteme

{% else %}

Entschuldigung, es wurden keine Dateisysteme definiert.

{% endif %}

Die andere Vorlage ist die Verzeichnisvorlage, die den Inhalt eines Pfades unter dem Basispfad des Dateisystems anzeigt:

{% if dlist or flist %}

Dateien in //{{ fs.name }}/{{ path }}

    {% for d in dlist %}
  • {{ d }}
  • {% endfor %} {% for f in flist %}
  • {{ f.name }} ({{ f.type }})
  • {% endfor %}
{% endif %}


Beide Vorlagen müssen irgendwo in Ihrem TEMPLATE-PFAD gespeichert werden. Ich habe einen Pfad im TEMPLATE-PFAD mit dem Namen der Anwendung eingerichtet: `filesystems`. Dort habe ich die Dateien als `index.html` und `directory.html` gespeichert. Natürlich würden Sie normalerweise eine Basisvorlage für die Website erstellen und diese in Ihren normalen Vorlagen erweitern. Und Sie würden eine `404.html` hinzufügen, um 404-Fehler zu behandeln. Aber das bleibt als Übung für den Leser. Nachdem Sie Ihren Entwicklungsserver für Ihr Admin gestartet haben (vergessen Sie nicht, DJANGO SETTINGS MODULE entsprechend einzustellen!), können Sie ein Dateisystem zu Ihrer Datenbank hinzufügen (haben Sie irgendwann zwischenzeitlich `django-admin.py install filesystems` gemacht? Nein? Machen Sie es jetzt, bevor Sie Ihren Server starten). Jetzt stoppen Sie den Admin-Server, ändern Sie Ihr DJANGO SETTINGS MODULE und starten Sie den Haupt-Einstellungsserver. Jetzt können Sie zu [http://localhost:8000/files/](http://localhost:8000/files/) surfen (zumindest wenn Sie Ihre URLs und Ihren Server so eingerichtet haben wie ich) und die Dateien in Ihrem Dateisystem durchsuchen. Das ist alles. War nicht sehr kompliziert, oder? Django ist wirklich einfach zu verwenden.

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.