"The Whitespace Thing" for OCaml - Einrückung als Syntax-Element (ala Python und Haskell) für OCaml. Interessant. Wobei allerdings OCaml eh schon nur geringen Syntax-Overhead hat, so das ich das eigentlich nicht für nötig halte.
programmierung - 3.10.2005 - 22.11.2005
Dejavu - Trac - ein weiterer Object-Relational-Mapper für Python. Klingt aber in Punkten ganz interessant.
Kritische Lücke in Content Management System Mambo
PHP entwickelt sich immer mehr zum Sicherheits-Müllhaufen:
Nicht immer erhöht unter PHP das Deaktivieren von register_globals die Sicherheit. Manchmal öffnet sich dadurch erst eine Schwachstelle. So auch im Falle des Content Management System Mambo, das laut eines Postings auf der Sicherheits-Mailing-Liste Full Disclosure eine Schwachstelle enthält, mit der es Angreifern möglich ist, eigenen Code auf dem Server auszuführen.
Dazu trägt sicherlich bei, das es kaum eine Sprache - ausser vielleicht noch Perl - so viel Cruft mit sich rum, wie PHP. Das Ergebnis zeigt sich dann immer wieder in esoterischen Problemen, die dann selbst Leute erwischen, die eigentlich von der Erfahrung her auf sowas vorbereitet sein müssten.
Apples WebObjects mit neuen Lizenzbedingungen
Apple hat die Lizenzfragen zu WebObjects geklärt - Deployment auf Linux-Kisten ist jetzt auch ganz normal erlaubt. Damit ist die XCode-Umgebung mit WebObjects jetzt also komplett von Entwicklung bis Deployment Freibier.
Realitätsverlust bei SAP-Vorständlern
SAP-Vorstand wettert gegen Open Source:
Ansonsten sei es wichtig, nicht zu sehr mit dem Code hochwertiger Softwareprogramme herumzuspielen.
Moment mal. "hochwertige Softwareprogramme". Der arbeitet doch bei SAP? Wo haben die denn irgendwelche hochwertigen Softwareprogramme? Ich mein, wenn man "hochwertig" mal nicht als "hoffnungslos überteuerter Schrott" betrachtet, wie er das wohl tut?

wikiCalc - eine Mixtur aus Tabellenkalkulation und Wiki. Strange. Von Mr. Visicalc himself. Trotz Perl derzeit nur Windows-tauglich. Nunja, Spreadsheets passen für mich zu Perl und Windows - alles schmuddeliger Kram
sql relay ist ein SQL connection pool der verschiedenste Datenbanken bedienen kann und die Verbindungen von Clients zur Datenbank über einen zentralen Pool abwickelt. Ideal in Multi-Host-Umgebungen und wenn die Connecton-Last zu hoch ist (z.B. erzeugt Django pro Request eine Connection).
coverage ist ein Tool zur Erstellung von Coverage-Übersichten - also welche Teile eines Programms ausgeführt wurden und welche nicht. Sinnvoll als Ergänzung für unittests, damit man sicher ist, das die unittests auch alle Bereiche des Codes abdecken.
Ein Test-Framework für Django
DjangoTesting ist Teil meines DjangoStuff-Projekts und der Beginn eines Testframeworks für Django, das dem Testframework von Ruby on Rails nachempfunden ist. Derzeit sind nur Modelltests implementiert, Request/Response-Tests sind geplant.
Das Testframework basiert ausschließlich auf unittest und django, sodass Sie keine zusätzlichen Module benötigen (außer meinem DjangoStuff-Projekt natürlich). Es bietet python-basierte Fixture-Notationen (Fixtures sind einfach nur Python-Klassen mit Attributen in einer DATA-Unterklasse) und ein grundlegendes Befehlszeilen-Tool, um diese Tests und Fixtures zu nutzen.
Tests und Fixtures werden in Anwendungen und Projekten gespeichert, sodass Sie anwendungsspezifische Tests haben können (besonders nützlich bei generischen Anwendungen) und projektübergreifende Tests, die mehrere Anwendungen integrieren.
Ich denke, ein gutes Testframework wäre wirklich wichtig für Django-Anwendungen, insbesondere für Anwendungen, die zwischen Projekten geteilt werden sollen. Aber ich denke auch, dass ein gutes Testframework auch etwas "Banging" braucht - also habe ich es als kleines Subprojekt für mich selbst gestartet. Aber wenn es zu etwas Nützlichem heranwächst, werde ich mich für die Aufnahme in den Django-Trunk entscheiden.
Selenium ist ein Testautomator für Webanwendungen. Es läuft direkt im Browser und benutzt IFrames und JavaScript um sich in die zu testende Seite zu hängen.
Case/When/Otherwise für Django
Wenn du böse Pläne für eine Switch-Anweisung in Django hast (hia rjwittams!), könntest du einen Blick auf mein TagLib werfen. Dort gibt es eine case/when/otherwise-Anweisung. Sie ist ganz einfach zu verwenden:
{% case variable %}
{% when "value1" %}
{% endwhen %}
{% when "value2" %}
{% endwhen %}
{% otherwise %}
{% endotherwise %}
{% endcase %}
Der Grund für die Tag-Struktur ist, dass der Django-Template-Parser in der parsefor-Funktion nur nach parameterlosen Block-Schließtags sucht und du daher keine einfache Lösung wie diese verwenden kannst:
{% if condition %}
{% elif condition %}
{% else %}
{% endif %}
Du müsstest viel von dem Template-Parser in eine parsefor-Funktion kopieren, die nach einem Token mit einem Tag und Parametern sucht, um den aktuellen Block zu schließen.
Ich habe mich daher für den Ansatz mit den bereichsbezogenen Tags entschieden, bei dem das "case"-Tag nur eine Kontextvariable "case" setzt und sie mit einem Wörterbuch mit "value" und "fired" füllt - wobei letztere ein Auslöser ist, der von jedem "when"-Tag ausgelöst werden kann, um zu verhindern, dass andere "when"-Tags oder das "otherwise"-Tag sich selbst auslösen. Ein bisschen hässlich, aber funktionierend.
Ad-hoc-Organisation in CM-Systemen
Adhoc organization ist der Name, den ich den grundlegenden Designentscheidungen für mein neues Content-Management-System (Blog-System, persönliches Wiki, digitale Bilderschuhschachtel - was auch immer) gegeben habe. Es kommt gut voran, auch wenn ich es bisher nur als Beispielanwendung genutzt habe, um meine kleinen Tools aus dem DjangoStuff-Pseudo-Projekt zu nutzen. Und es ist immer noch eine der besten Möglichkeiten zu sehen, wie Tagging oder Suche oder der neue Kalendertag oder andere Dinge genutzt werden.
Aber es kommt so gut voran, dass ich denke, ich werde in der Lage sein, einige Websites in naher Zukunft umzustellen. Die grundlegenden Designentscheidungen sind in dem verlinkten Dokument in meinem Trac-Wiki etwas dokumentiert. Das Hauptziel für mich ist es, etwas zu bekommen, das ich genauso einfach für die Bildpräsentation wie für die Textpräsentation nutzen kann und das mir ermöglicht, beide Teile wirklich zu integrieren. So dass Artikel wirklich aus einer Vielzahl von Medien und Text bestehen können.
Es macht Spaß, an einem Projekt zu arbeiten, bei dem man das Modell von Zeit zu Zeit abreißen und einen Teil davon neu aufbauen kann oder große Refactoring-Entscheidungen trifft, die einen für eine Weile mit einem kaputten Haufen Python-Bullshit zurücklassen.
cucumber2 ist ein sehr interessanter Object-Relational-Mapper für Python und PostgreSQL, der unter anderem auch die Tabellenvererbung in PostgreSQL unterstützt.
PostgreSQL 8.1
PostgreSQL 8.1 mit Two-Phase-Commits und Benutzerrollen:
Transaktionen können nun auf mehreren Rechnern mit PREPARE TRANSACTION vorbereitet und später gemeinsam ausgeführt werden. Fällt eine Maschine nach dem PREPARE aus, lässt sich die Transaktion nach dem Neustart per COMMIT korrekt abschließen.
Yes!
"Fitting on" some framework
Wie können Sie feststellen, ob ein Framework zu Ihrer Denkweise passt? Es ist nicht so, dass Sie einfach in den Spiegel schauen könnten, um zu sehen, ob es Ihnen gefällt. Sie benötigen andere Wege, um das zu entscheiden. Eine Möglichkeit, dies zu entscheiden, ist die Produktivität - wie schnell Sie Ihr Projekt zum Laufen bringen.
Aber erzählt Ihnen das wirklich die ganze Geschichte? Was, wenn das Projekt etwas völlig anderes gewesen wäre? Haben Sie einfach den Sweet Spot des Frameworks getroffen? Hatten Sie einfach nur Glück?
Eine Möglichkeit, zu entscheiden, ob ein bestimmtes Framework, eine Sprache oder ein Werkzeug zu meiner Arbeitsweise passt, besteht darin, die grundlegenden Abstraktionen zu betrachten, die mir dieses Werkzeug bietet. Und zu prüfen, wie ich sie verwenden kann und wie natürlich sie zu meinem Denken passen - stoße ich auf Probleme, weiß ich nicht sofort, welche Abstraktion ich verwenden soll, welches Werkzeug ich ziehen soll? Oder fallen die Dinge einfach an ihren Platz?
Ich habe relativ früh entdeckt, dass ich in der Programmierung etwas ungewöhnlich bin, weil ich nicht meine eigenen Abstraktionen baue und versuche, sie in das zu übersetzen, was die Sprache oder das Framework mir gibt, sondern dass ich beginne, direkt in den Abstraktionen und Syntaxen zu denken, die mir gegeben werden - aber nur wenn sie zu meiner Art passen.
Das ist für mich also das ultimative Maß dafür, ob ein Framework wirklich in mein Denken passt: von Zeit zu Zeit zu prüfen, ob ich Übersetzungen versuche oder ob die Dinge einfach fließen. "In den Flow zu kommen" ist für mich heutzutage das Wichtigste.
Wie schneidet Django also ab? quite nicely. Es gibt mir wirklich, was ich in den meisten Fällen brauche, es gibt nur sehr wenige Bereiche, in denen "der Flow" unterbrochen wird, in denen ich um Probleme herumdenken muss, anfangen muss, Übersetzungen zu machen. Ein Bereich ist das spezielle Verhalten von Eingabefeldern - dies wird derzeit in Django mit parametrisierten Instanzen von vordefinierten Feldklassen durchgeführt. Es gibt keine wirklich schöne Möglichkeit, Subklassen zu erstellen, man endet damit, Code aus anderen Teilen der Django-Quelldatei zu kopieren - definitiv "den Flow" brechend.
Aber die meisten anderen Teile fallen einfach an ihren Platz: Middleware für die globale Verwaltung des Request-Response-Bereichs. Template-Loader für - nun ja - Template-Loading (ja, es ist keine große Sache - aber in der Lage zu sein, Ihren eigenen Template-Loader zu schreiben, ist wirklich hilfreich). Die urlpatterns - hey, das ist wirklich eine coole Idee, weil Sie aufgrund der absolut lockeren Kopplung nicht einmal versuchen, Ihre URLs nach Ihrer Code-Struktur zu modellieren, sondern dazu neigen, sie zu entwerfen. Und so sollte es sein.
Models sind leistungsfähig genug, um die modellbezogene Funktionalität wirklich dorthin zu verlagern (obwohl das Class MODULE-Zeug es noch schöner machen wird, besonders das etwas hässliche module_globals-Ding). Es wäre cool, wenn Model-Klassen Mixin-Klassen unterstützen würden, so dass abstrakte Apps Dinge bereitstellen könnten, die einfach von den Benutzern referenziert werden, um Funktionalität hinzuzufügen. Aber Sie können viele dieser Probleme mit generierten Klassen lösen - dank Python-Introspektion (obwohl Sie ein wenig über die Django-Modellmagie wissen müssen).
Die meisten komplexen Dinge tendieren dazu, in Template-Tags und generische Ansichten zu gehen - mein CMS-Projekt hat derzeit nur 3 Ansichtsfunktionen seiner eigenen, der Rest ist in generische Ansichten abstrahiert (für die Suche und das Tagging). Template-Tags könnten etwas einfacher zu schreiben sein, insbesondere der Parser ist zu primitiv - eine Bibliothek von Hilfsfunktionen zum einfachen Zerlegen der Tag-Zeichenkette wäre gut (hey, vielleicht schreibe ich eine, die Grundlagen sind bereits in meinem SVN-Repository).
Template-Filter sind ein bisschen ein hässliches Entlein - sie sehen den Anforderungszusammenhang nicht, so dass sie nicht viel mehr tun können, als das eingehende Objekt und einige konstante Parameter zu übernehmen. Ich denke, sie sollten den Kontext übergeben bekommen, so dass sie, wenn nötig, ein bisschen schlauer sein könnten (wie z.B. das Auflösen eines Parameters gegen den Kontext durch Filter ermöglichen).
Generische Ansichten sind auch ganz schön - auch wenn ich die vordefinierten nicht so oft verwende. Der Hauptgrund dafür ist, dass ich oft damit ende, die generischen Ansichten in einigen Code zu wickeln, der ihr Verhalten modifiziert - und dann ist es oft einfacher, einfach meine eigenen zu erstellen. Aber sie sind großartig für den ersten Einstieg in Bereiche, hängen Sie sie einfach in Ihr Projekt ein und die Funktionalität ist verfügbar. Sie können sie immer durch Ihre eigenen Ansichtsfunktionen austauschen, wenn Sie feststellen, dass Sie sie benötigen.
Und der Admin, das eine Ding, das Django aus der Masse herausstechen lässt? In meinen ersten Spielprojekten habe ich ihn geliebt, in späteren habe ich ihn nicht verwendet (die Galerie braucht ihn nicht), aber mit dem CMS-Projekt habe ich das erste Projekt gemacht, das ihn wirklich stark nutzt. Und ich muss sagen, ich mag ihn. Er sollte etwas flexibler werden (der new_admin-Zweig könnte dabei helfen, da er mehr Dinge in Templates verschiebt, so dass sie überschrieben werden können), aber insgesamt ist er wirklich cool und nützlich.
Zwei Dinge sind jedoch definitiv für den Admin erforderlich: vollständige Transaktionsunterstützung, die an die Anforderung-Antwort gebunden ist (Ticket #9 im Django Trac), weil das Ändern von Dingen und das Ende mit inkonsistenten Tabellen kein Spaß ist. Wie z.B. eine Ausnahme zu erhalten, weil etwas in repr gebrochen ist, so dass der Log-Eintrag nicht geschrieben wird, aber das Objekt wird geschrieben. Natürlich bemerken Sie es nicht, gehen zurück, senden erneut und enden mit zwei Objekten und immer noch keiner Log-Nachricht ...
Das andere, was benötigt wird: grundlegende Haken für objektbasierte Authentifizierung. Kein vollständiges ACL oder so etwas, nur einige wirklich einfache Haken vom Admin zum Modell, die der Benutzer definieren kann, um dem Admin mitzuteilen, ob ein bestimmtes Objekt bearbeitbar sein sollte oder nur schreibgeschützt angezeigt werden sollte. Das Hauptproblem mit der aktuellen Lösung ist, dass sie nur vollständige Tabellen behandelt - Sie können dem Admin nicht einmal mitteilen, dass ein bestimmter Benutzer nur an der aktuellen Site arbeiten kann und keine Objekte anderer Sites ändern kann (mein CMS-Projekt macht starken Gebrauch von der Multi-Site-Fähigkeit in Django - ein Admin-Server sollte mehrere Sites in einer Admin-Oberfläche verwalten).
Aber alles in allem ist das Erstellen von Web-Apps mit Django wirklich Spaß. Es ist nicht nur produktiv für mich, es fühlt sich natürlich an, Dinge auf die Django-Art zu tun. Also ja, Django passt zu meinem Denkstil. Scheint genau ins Schwarze getroffen zu haben.
Der JavaScript Interactive Interpreter ist ein nettes Spielzeug: man kann JavaScript-Ausdrücke eingeben und die Ergebnisse direkt sehen. Also im Prinzip eine JavaScript-Shell - nur läuft die natürlich dann im Browserfenster.
Markdown für Django
Django enthält bereits einen Markdown-Filter (in contrib.markup), dennoch habe ich meine eigene Markdown für Django Mini-Anwendung erstellt. Die Hauptvorteile sind die Verknüpfung mit Django-Modellen (durch Verwendung generischer Modellabfragen und get absolute url), eine generische Dokumentationsansicht, die das Umschalten der Sprache handelt, und eine schöne Makro-Einrichtung für Markdown. Makros sind eine nützliche Möglichkeit, Markdown zu erweitern, indem Django-Vorlagenschnipsel geschrieben werden, die immer dann aufgerufen werden, wenn der Benutzer das Makro in seiner Markdown-Quelle aufruft.
Es war früher Teil des CMS-Projekts, aber ich denke, es ist nützlich in sich und so viel besser in das Stuff-Pseudo-Projekt einzubauen.
Scatha and Glaurung sind zwei Schachprogramme in OpenMCL geschrieben, mit dem Cocoa-Support von OpenMCL. Nette Beispiele dafür, wie man mit OpenMCL native OS X Anwendungen bauen kann - und interessant zu spielen sind sie auch, vor allem die hexagonal-Schach-Version.
Twisted Buch ist raus
Wer sein Hirn nicht so ohne weiteres in die verdrehte Welt von Twisted quetschen kann, dem hilft vielleicht Twisted Network Programming Essentials - ein neues Buch zu der wohl mächtigsten Internet-Protokoll-Plattfor für Python.
akaDAV - Lightweight WebDAV server and python module ist ein WebDAV Modul für Twisted. Damit kann man sich seinen eigenen WebDAV Server basteln. Könnte nütlich für mich sein, weil ich dann das Teil unter Userrechten laufen lassen kann, statt unter den Rechten des Webservers ...
Googles Web Accelerator and Damager
Google at it again - Ian sagt eigentlich schon alles, was es dazu zu sagen gibt. Google behauptet, sie wollten nicht "evil" sein. Aber dafür sind sie grenzenlos dämlich, wie sich am wiederholten Start des Web-Damagers zeigt.
Was macht der Web-Accelerator, und warum ist er so ein dämliches Stück Software? Nunja, er verfolgt einfach nur Links. Und zwar im Vorab, bevor der Benutzer es macht - sozusagen spekulatives Webcrawlen, nur eben privat für den Benutzer. Das klingt ja erstmal garnicht so schlimm, ausser das Server mit Traffic bombardiert werden, den sie möglicherweise so nie hätten - denn jeder Link wird schön weitergewandert, auch wenn der User da garnicht hin geht. Und das multipliziert mit den Benutzern die das Teil einsetzen ...
Aber der Traffic ist nicht das eigentliche Problem - das eigentliche Problem kommt erst, wenn man sich überlegt in welchem Context das Teil läuft. Und zwar hängt es ja auf dem privaten Rechner des Benutzers, zwischen Browser und Netz. Einfach ein eigener kleiner Proxy. Der für seine Arbeit sich Cookies und ähnliches merkt und an die Seiten dann Requests schickt, die so aussehen als kämen sie vom Browser des Benutzers. Mit dessen Security-Headern. Und Cookies.
Abgesehen davon, das ich es nicht sonderlich prall fände wenn meine Header mit Passwörtern oder Sessioncookies woanders als im Browser und im Zielserver auftauchen - diese Vorgehensweise ermöglicht es dem Webaccelerator sich auch Bereiche anzugucken, die ein zentraler Crawler nicht sehen würde. Nämlich zum Beispiel Seitenbereiche, die hinter Logins liegen. Content-Management-Systeme, bei denen nach Login zusätzliche Links auftauchen. Wikis, deren Edit-Links dann kommen, wenn jemand eine Session startet. Webmailsysteme, bei denen jede Mail als ein Link abgebildet ist.
All diese Systeme haben eines gemeinsam: für verändernde Aktionen ist nicht immer ein Formular-Absenden notwendig. Oft reicht es, einen Link zu klicken. Die aktuelle Version einer Seite im Wiki zu löschen, um schnell Wikispam zu beseitigen - ein einfacher Link, nur für den angemeldeten Benutzer sichtbar. Die Mail im Webmail-Postfach, die bei Aufruf automatisch auf gelesen gesetzt wird. Der Veröffentlichen-Link im CMS, mit dem eine Seite scharfgeschaltet wird.
Natürlich versuchen verantwortungsvolle Programmierer von Webanwendungen die destruktiven Aktionen hinter Formulare (und damit POST Requests) zu packen, damit nicht ein einfacher Link irgendwas zerstört. Aber das passiert in der Regel nur in den öffentlich zugänglichen Bereichen, bei denen sonst die Webrobots der diversen Suchmaschinen und Spam-Automaten sonst Chaos verursachen würden.
Aber gerade in den durch Login abgeschotteten Bereichen rechnet man normalerweise eben nicht mit Automatenklicks - und baut daher Komfortfeatures ein, weil man ja sicher sein kann, das ein Link bewusst und in Absicht geklickt wird.
Tja, bis dann der Web Accelerator von Google kam. Von der Firma, die von sich behauptet das Web kapiert zu haben. Schönen Dank auch, ihr Arschlöcher.
PS: und entgegen der ersten Version schickt die neue Version keinen Header mehr mit, an dem man die Prefetch-Requests erkennen könnte um sie in solchen kritischen Bereichen zu blocken.
python webdav server ist noch ein WebDAV Server für Python - seit 2000 nicht mehr aktualisiert, aber wenns funktioniert, könnte es reichen. Vielleicht verständlicher als Twisted-Code.
Generischer Suchdienst für Django
Wenn Ihre Django-Anwendung Suchfunktionen benötigt, können Sie Ihre eigene Lösung entwickeln. Oder Sie können meine generische Suchansicht verwenden. Diese bietet einen Parser für Abfragen und eine Suchmaschinerie, die für moderate Datenbankgrößen geeignet ist. Sie bietet eine erweiterbare, google-ähnliche Syntax.
Das Hauptproblem ist, dass Django keine OR-Abfragekombinationen unterstützt und dass es keine "icontainsnot"-Abfragen unterstützt. Die Suchmaschine führt daher mehrere Selektionen durch, um eine Abfrage zu erhalten. Sie beginnt mit dem längsten Suchbegriff und geht von diesem Ergebnisdatensatz aus in der Größe nach unten, wobei sie ihn von einem Schritt zum nächsten einschränkt. Da sie jedoch den letzten Ergebnisdatensatz im Speicher behalten muss (mindestens die Liste der IDs), kann dies Probleme für Ihren Server verursachen, wenn Ihre Datenbank zu viele Zeilen enthält (insbesondere wenn die Benutzer dumme Abfragen durchführen, die große Ergebnisdatensätze erzeugen).
Vielleicht wird dies in Zukunft einige Optimierungen lernen, um es besser mit größeren Datenbanken funktionieren zu lassen, aber es ist ganz gut als Suchmaschine für Ihren Blog oder Standard-Content-Management-Systeme.
Version Control with SVK
Version Control with SVK ist ein Online-Buch über SVK - ein verteiltes Versionssystem, das sehr gut mit SVN und CVS (unter anderem) harmoniert. Und gerade für die Arbeit mit Patches für Upstream-Systeme und für lokale Forks von Open Source Software eine ziemliche Erleichterung bietet.
Das Buch ist alles andere als Komplett, aber man findet schon eine ganze Menge an Informationen darin.
Sehr einfache Ansichtsfunktionen
Manchmal hast du eine ganze Reihe von wirklich einfachen View-Funktionen in deinem Django-Projekt (ja, das ist für dich, bitprophet!). View-Funktionen, die eigentlich nicht mehr sind als ein einfacher Render-to-Response-Aufruf - nimm eine Vorlage, nimm einige Daten aus der Anforderung, packe sie hinein und rendere eine Antwort. Es ist eher langweilig, sie aufzuschreiben, und es verletzt das DRY-Prinzip. Was also tun? Schreibe deine eigene generische Ansicht.
from django.core.extensions \
import render_to_response
def simple_view(request, template, **kwargs):
return render_to_response(
template, kwargs)
Das ist alles. Eine einfache und schöne View-Funktion, die genau das tut - eine Vorlage rendern. Sie kann sogar mit Kontextvariablen aus dem URL-Muster gefüttert werden. Verwende es wie folgt in deiner URL-Konfiguration:
urlpatterns = patterns('',
(r'^page/(?P<arg>.*)/$', 'cool.simple_view',
{'template': 'app/mytemplate'}),
)
Auf diese Weise wird eine /page/foo/ Ansicht an die Vorlage 'app/mytemplate' mit einem Kontext geroutet, der nur die Variable 'arg' mit dem Wert 'foo' enthält. Und du wirst nie wieder diese einfachen View-Funktionen schreiben müssen. Für extra Würze könntest du einen context_instance = DjangoContext(request) in den Render-to-Response-Aufruf werfen, um sogar den authentifizierten Benutzer und so weiter aus der Anforderung zu erhalten.
Modul-Hacking für Django
Django selbst konstruiert dynamisch Modellmodule aus Ihren Modellklassen. Das habe ich in meinem ersten Ansatz für die abstrakte Tagging-Anwendung verwendet. Jetzt habe ich eine bessere Lösung in der aktuellen Version gefunden - ich kann das dynamische Modul selbst relativ einfach modifizieren, eine dynamische Modellklasse generieren und diese in das Modellmodul einfügen. Was es tatsächlich tut, ist nur das Nachahmen dessen, was passiert, wenn Python eine Klasse definiert - die meisten Dinge werden ohnehin von der Meta.ModelBase-Metaklasse in Django erledigt. Ich musste nur einige Modul-Hacking-Sachen hinzufügen. Python-Introspektion ist großartig!
Was Sie dadurch erhalten, ist eine viel sauberere Schnittstelle, um die Tagrelation-Klasse für Ihr Modell zu erstellen - nur ein Funktionsaufruf, kein albernes Subclassing oder überflüssige Zuweisung. Alles geschieht wie von Zauberhand.
Es ist Magie.
Twisted Names muss ich mir mal angucken - ein DNS server in Python auf Twisted-Basis. Könnte ich ja auf DB-Benutzung umstricken, als Alternative zum PowerDNS.
Aperture
War ja schon angekündigt, jetzt ist es da - Aperture. Von Apple. Das Video dazu ist nett, sieht sehr brauchbar aus, was die gemacht haben. Und ich würde mir sogar die fast 500 Euronen gefallen lassen - ok, Photoshop-Updates wären für mich billiger, aber Aperture ist nunmal RAW-zentrisch aufgebaut und Photoshop hat nur einen RAW Importer. Aber was mir garnicht passt: die Hardwareanforderungen. Die Programmierer haben einen an der Waffel.
Ja, Fotobearbeitung braucht Speicher - sind schliesslich viele Daten. Und man braucht auch anständig leistungsfähige Hardware für den Einsatz von Filtern. Und ja, auch ne schnelle Grafikkarte ist brauchbar. Aber die Minimalanforderungen für Aperture liegen schon teilweise jenseits von Gut und Böse - zumal man ja weiss, wie diese Minimalanforderungen dann funktionieren werden - warscheinlich ähnlich gut wie Mac OS X mit 256 MB Speicher ...
Sorry, aber Bildbearbeitung ist nicht Raketenwissenschaft und auch nicht Wettersimulation - was soll diese völlig überzogene Resourcenforderung der Software? Haben heutige Programmierere komplett das Optimieren verlernt?
Mensch, ich hab vor noch nicht allzulanger Zeit mit Photoshop 5 auf einem 128 MB RAM Applem it 275 Mhz 603e CPU einen ganzen Film eingescanned und dann abgearbeitet. Natürlich sind RAW-Bilder grösser - aber wozu soll eine Bildbearbeitung einen Dual-G5 erforderlich machen? Bescheuert. Größenwahnsinnig.
Also werd ich wohl doch einfach weiter mit PHotoshop 7 arbeiten, auch wenn mir da immer noch der Open-Dialog abstürzt unter Tiger. Das tuts wenigstens brauchbar auf meinem netten, alten 12" Powerbook (ja, das mit 867 Mhz und nur 640 MB Speicher). Für meine Zwecke reichts, ich will nicht erst mehrere Tausend Euronen über den Tisch schieben, nur um das Bildbearbeitungsprogramm starten zu können ...
Tagging mit Django
Da die Frage, wie man Tagging mit Django umsetzt, ziemlich oft auftaucht, habe ich eine kleine Lösung für dieses Problem geschrieben: AbstractTagging. Dies ist eine generische Anwendung und generische Ansichten, die Ihnen eine sehr einfache Lösung bieten, um Tagging zu jedem Modell hinzuzufügen, das Sie in Ihren Django-Apps haben. Es wird derzeit von mir in meinem CMS-Projekt verwendet. Der Quellcode befindet sich im Stuff-Projekt.
Es war ein bisschen seltsam, es zu bauen, weil ich eine Basisklasse dynamisch konstruieren musste, die Sie in Ihren Modellen unterklassen können - dies liegt an der Magie in django.core.meta, wo Modellklassen in Module umgewandelt werden. Aber das Ergebnis ist, glaube ich, ganz schön.
Keine Ahnung ob es wirklich The Coolest DHTML / JavaScript Calendar ist, aber er sieht ganz nett aus. Und hat ein paar recht wichtige Features - wie z.B. die Möglichkeit, ihn zu verschieben.
call of the noodle
Da schreibt einer an einem Lisp-Compiler für Python-Bytecode - sehr interessant, da man damit die Python Libraries unter einem Lisp-Dialekt benutzen könnte. Mal schauen wenn der erste Release kommt, wie der Lisp-Dialekt aussehen wird und was für Features er abdecken wird. Mit Unterstützung für Lisp-Makros wäre es sehr interessant.
Django als CMS verwenden
Ich arbeite derzeit an einer meiner Websites - Content-type: matter-transport/sentient-life-form. Es war zuvor eine Apache::MiniWiki-basierte Website und befindet sich nun im Übergang zu einer Django-basierten Website. Die Idee hinter dem Code für diese Website ist es, ein CMS auf Basis von Django zu erstellen, das vollständig die Django-Administration verwendet. Die Benutzer sollten also in der Lage sein, alle Verwaltung nur in der Administration durchzuführen, während die Website selbst ein wenig wie ein Wiki funktioniert. Autoverlinkung, Autoeditierung fehlender Seiten, Editlinks, Versionierung (derzeit in der Quelle fehlend) - all das sollte auf Basis der von der Django-Administration bereitgestellten Tools erfolgen.
Allerdings handelt es sich dabei nicht um eine vollständige Website - die verlinkte Website ist fast leer, ich habe nie viel dort hochgeladen. Es ist eher ein Projekt, um tiefer in die Django-Administration einzutauchen, um zu sehen, wie es ist, darin zu arbeiten - damit ich über diese Dinge Bescheid weiß, wenn ich beginne, echte Projekte zu erstellen.
Der Code selbst ist frei verfügbar - und es gibt bereits eine nette Sache darin. Es ist ein Template-Loader, der Inhalte aus der Datenbank statt aus dem Dateisystem oder aus Python-Eiern lädt. Es ist unter #633 bei Django "ticketed", sodass es eines Tages in django.contrib aufgenommen werden könnte.
Geschäftsmodell von Open Source ...
... allein das zu hören macht mir schon Pickel. Diese absolute Unfähigkeit von Interessenverbänden aus der Wirtschaft sich eine Motivation ohne Geschäftsmodell vorstellen zu können - traurig.
Tailor - Versionsvermittler
Tailor ist ein Python Script das Changesets zwischen verschiedenen Versionssystemen austauschen kann. Im Prinzip kann man damit auch Repositories in anderen Versionssystemen spiegeln.
Trac on Darcs
Ich liebe ja bekanntermaßen Trac als Projektwerkzeug - und bin mit Subversion als Versionierung (oder neuerdings mit SVK als auf Subversion aufsetzendem Versionswerkzeug) ganz zufrieden. Aber darcs hat mich auch begeistert, weils so schön unbürokratisch ist - und jetzt gibts auch Trac auf Darcs - eine gepatchte Version, die eben mit darcs statt Subversion zusammenarbeitet. Ich glaub, ich werd mir das mal näher angucken ...
Der gleiche Patch erlaubt auch ein Bazaar-NG Backend für Trac - was ganz besonders interessant ist, weil sowohl Trac als auch Bazaar-NG in Python geschrieben sind. Ich glaube auch den Teil sollte ich mir mal angucken.
Und gerade wurde ich im IRC noch darauf hingewiesen, das SCons auch Python ist - ein ziemlich netter Ersatz für das doch schon arg in die Jahre gekommene Make.
Klingt schon fast nach Developer-Nirvana das ganze
Falls mal jemand so wie ich einem Kollegen ohne SQL-Erfahrung bezüglich Oracle aufs Pferd helfen soll: Oracle/SQL Tutorial. Ganz nett gemacht.
SVK - Subversion distributed
SVK ist ein verteiltes Versionssystem mit einer Besonderheit: es kann Trees anderer Versionssysteme (unter anderem SVN) spiegeln und darauf dann Arbeitskopien definieren. Man kann also ein Subversion-Repository eines Projektes spiegeln, einen eigenen lokalen Branch anlegen, darin arbeiten und die Änderungen lokal versionieren. Wenn dann der eigene Branch soweit ist, kann man einen Commit gegen das Ursprungsrepository machen, oder sich einfach einen Diff ziehen und dem Entwickler zuschicken. Sehr nette Sache, ganz besonders wegen der guten Integration mit Subversion.
Für vim: snippetsEmu emuliert die Snippet-Funktion von TextMate, nur halt mit vim Makros.
Wie man in Python Accent-Zeichen in ihr Basiszeichen umwandelt. Ziemlich banaler Ansatz, aber für viele Zwecke völlig ausreichend. Für richtige Lösungen gibts dann PyICU ...
Keine Ahnung ob ich das schon mal hatte, aber Caching Tutorial for Web Authors and Webmasters sieht nach einer brauchbaren Beschreibung der Caching-Direktiven in HTTP aus, mit Erläuterungen für Anwendungsprogrammierer.
Django i18n status
I worked a bit more on the i18n stuff in django today and finally switched my gallery to the i18n branch. You can now see the strings on that site with either english or german settings. Other languages get english output (so if you are in Germany and still see english strings - check the language settings in your browser, wether German is defined with higher priority than English).
The code works quite nice and I think I will give it a week or so to settle and than start to put finishing touches to it - like adding much more translation hooks to the django source.
Ajax mal anders
Subway's new Ajax framework hat einen interessanten Ansatz: per inspect wird Python-Source aus einer Methode geholt und dann nach JavaScript übersetzt. Natürlich wird dabei nur ein Subset von Python unterstützt, aber die Idee ist recht interessant - Python-Syntax für JavaScript.
Natürlich werden die semantischen Unterschiede zwischen Pythons und JavaScripts Interpreterablauf einen früher oder später beissen, aber für einfachere Sachen (und viele Ajax-Sachen sind tatsächlich recht banaler Code auf JavaScript-Seite) kann man so ohne JavaScript-Source aufbauen.
Das ganze würde natürlich wesentlich eleganter ausfallen, wenn Python eine vernüntige Makrosprache integriert hätte - bzw. wenn man in Python Makros in der Art bauen könnte, wie man es in Common Lisp kann. Damit wäre die Definition des Subsets und die Erstellung des JavaScripts daraus wesentlich eleganter machbar. Eventuell könnte hier P hillip J. Ebys Arbeit an Konfigurationssprachen helfen - es ist ja im Prinzip der Ansatz einer Makro-Einrichtung für Python.
Ich persönlich würde daher bei Python eher einen Ansatz verfolgen bei dem durch Python-Code-Ablauf (also nicht Parsen und Compilieren) JavaScript generiert wird - denn viele Ajax-Funktionalitäten sind recht standardisierte Abläufe. Es wird in der Regel der DOM-Tree manipuliert, nach festen Vorgaben, mit Daten die über JSON angeliefert werden. Das meiste liesse sich gut standardisieren. Allerdings hab ich da noch keinen konkreten Code parat, bisher ist Ajax bei mir immer noch direkter JavaScript-Code - allerdings mit Hilfe von MochiKit.
Mal schauen was sich im Ajax-Python-Land noch so tut. CrackAjax ist zumindestens mal ein weiterer Ansatz, der möglicherweise andere inspiriert das ganze etwas besser auszubauen.
Pragmatic Ajax wird ein Buch (derzeit noch im Beta-Stadium - man kann aber schon vorbestellen und kriegt dann die Betas als PDF) über Ajax und die ganzen Sachen rundrum. Die Pragmatic Bookshelf Bücher sind meist recht pragmatisch (ach) und angenehm zu lesen, könnte sich also lohnen.
WSGI and WSGI Middleware is Easy beschreibt wie man mit WSGI Middleware arbeitet und was das eigentlich ist.
RobotFlow basiert auf FlowDesigner - sowas wie Open Source LabView - und ist eine grafische Robot-Programmier-Plattform, vergleichbar zu RoboLab. Leider aber noch kein LegOS Backend (oder wenigstens eins für den Lego Mindstorms Bytecode) für RobotFlow
OpenMCL 1.0 ist raus - nach einer doch recht langen Zeit endlich mal ein anständiger Versionssprung
Python Paste Power
Python Paste Power ist ein sehr interessanter Artikel über Python Paste, das Metaframework von Ian Bicking. Es macht die Anwendung und Verteilung von Web-Anwendungen in Python sehr viel einfacher (jedenfalls wenn das Framework mit dem man die Anwendung bauen will Paste Support hat).
IRC Logger-Aktualisierung
Der IRC-Logger funktioniert einwandfrei, aber ich war nicht zufrieden mit der Abhängigkeit von muh - also habe ich meinen eigenen kleinen Logger-Bot in Python geschrieben, basierend auf irclib. Er funktioniert gut und tut genau das, was ich möchte - Logging. Ich fühle mich immer ein bisschen unwohl, wenn IRC-Bots Befehlsstrukturen und so etwas haben und ich brauche eigentlich nichts davon ...
Jetzt ist das Projekt größtenteils abgeschlossen - Sie müssen nur das Django-Admin verwenden, um Kanäle zu Ihrer Datenbank hinzuzufügen, den Logger-Bot auf einen IRC-Host verweisen und sehen, wie er Kanäle beitritt und mit dem Logging beginnt.
Oh, es gibt noch Dinge zu tun - zum Beispiel muss der Bot die Liste der Kanäle neu scannen, damit er neu hinzugefügte Kanäle erkennt und gelöschte Kanäle verlässt (und vielleicht sollte ich die Aktivierung/Deaktivierung von Kanälen hinzufügen, damit ich Kanäle für eine Weile deaktivieren kann, ohne die Archive zu verlieren), aber für den Moment loggt er nur #django und dafür ist es gut genug.
37signals mal wieder
Diesmal Writeboard son Teil zum gemeinsamen Editieren von Texten über das Web. Im Prinzip vielleicht sowas wie SubEthaEdit für ganz arme. Aus der FAQ:
Is this some sort of wiki?
No way. Not at all. Nope. Wikis are icky. Writeboard is about writing and editing solo or with others. It's all about the words. Wikis are about way more than that which is why they are generally pretty confusing to most folks.
Ja, klar, Wikis are icky. Und schwer zu verstehen. Logisch. Mag für jemanden zutreffen der Todolisten-Programme für genialer als geschnittenes Weissbrot hält. Sorry, aber langsam wirds einfach nur noch lächerlich was aus dem Laden kommt. Banalprogramme werden nicht intelligenter dadurch, das man sie in Bonbonfarbe packt ...
Retrocomputing - MIT CADR Lisp Machines
Yeeeehaaaa! Der Sourcecode der MIT CADR Lisp Machines - dem Vorläufer der meisten High-End-Lispmaschinen - ist unter einer BSD-Lizenz freigegeben worden!
Das dürfte hoffentlich dem CADR Lisp Emulator weiteren Auftrieb geben. In letzter Zeit wars ja etwas ruhig um den Emulator geworden.
Wenn jetzt sich endlich Symbolics dazu durchringen könnte ihre OpenGenera-Plattform auf OS X zu portieren, wäre ich noch glücklicher
Und noch ein paar weiter Neuigkeiten zum Emulator - es gibt den ersten Support für ChaosNet, inclusive einem Fileserver für Linux. Und das im Link angesprochene Lispmachine-Board fänd ich ziemlich cool ...