Published on Monday, November 3, 2008 .
Am Wochenende hab ich mir wieder einmal ein kleines Deskbar-Applet Plugin geschrieben. Sinn des Plugins ist es mir via dem Notification Framework kleine Erinnerungs-Bobbels auf den Desktop anzuzeigen (ja mit fast 30 verkalkt man immer mehr
). Das ganze schaut dann so aus:

download: notify.py
Ich benutze schon seit Jahren das Deskbar-Applet, ein kleines in
Python geschriebenes Programm aehnlich dem MacOSX Quicksilver oder
Gnome-Do. Durch seine hervorragende Plugin API war es mir jetzt mit sehr geringem
Aufwand möglich 3 Plugins zuschreiben die ich schon immer vermisst hatte

Installation
Eine Deskbar Plugin Installation ist ganz einfach! Plugin unter ~/.gnome2/deskbar-applet/modules-2.20-compatible
abspeichern, Deskbar restarten und das Plugin in den Deskbar Einstellungen aktiviert. Fertig!
Tasque Plugin
Novells Tasque ist ein kleines ToDo Verwaltungstool unter Linux. Es
ist in einer Novell Hackweek entstanden und wird seitdem weiter entwickelt und verbessert. Es kann
verschiedenste Backends als ToDo Speicher benutzen, z.B. RememberTheMilk
oder den Evolution Data Server (EDS). Das Programm ist in seiner Bedienung was Tasks verwalten angeht super,
aber ich vermisse globale Tastaturshortcuts für die schnelle Task Eingabe. Aber dieses Manko wird durch mein
Tasque Deskbar Plugin verbessert. Dieses Plugin “redet” mit Tasque
über den D-Bus und unterstützt das Anlegen eines Task in den verschiedenen vorhandenen Kategorien.
Download: Tasque Plugin
Trac Plugin
Trac ist ein Wiki und Ticketverwaltungs-Web-Applikation.
Ich setze es seit der Programmierung von PyCRMan ein und es leistet mit gute Dienste :). Aber wie bei jeder
Web Applikation laesst die schnelle Eingabe auch hier zuwuenschen uebrig. Daher musste ich einfach ein Deskbar
Plugin dafür schreiben. Die Einstellungen (Trac URL) fuer das Plugin werden im GConf abgelegt und sind somit einfach
via gconf-editor zu aendern. In einer naechsten Version gibt es vielleicht einen Einstellungsdialog ueber die
Deskbar Einstellungen
Das Plugin benoetigt das Trac XML-RPC Plugin.
Es lohnt auch ein Blick auf den Source Code des Trac Deskbar Plugins, dort kann man noch ein paar Standarteinstellungen
zum Ticket vornehmen.
Download: Trac Plugin
Google Calendar Plugin
Wer den Google Calendar nicht kennt ist selbst Schuld :). Es ist ein wunderschoenes
Tool zur Verwaltung von Terminen und durch die Reminderfunktionen (SMS aufs Handy bei einem Termin) auch offline sehr brauchbar.
Also schnell ein Deskbar Plugin geschrieben welches via python-gdata (Google Python API) einen Termin eintragen kann
Das Plugin verwendet Googles QuickAdd Feature.
Die Einstellungen werden auch hier im GConf abgelegt.
Zum Anlegen eines Termins einfach so etwas ins Deskbar reinschreiben: Daves birthday July 15 9am
Download: GCal Plugin
Ich bin vor ein paar Tagen bei der Programmierung von PyCRMan fast verzweifelt. Wie ich schon in einem früheren Eintrag beschrieb, verwende ich Elixir als Wrapper für die Datenbank und mir ist aufgefallen, das Elixir bei meinen Model sehr viele DB-Queries generiert. Die Anzahl der Queries ist so hoch das die Netzwerk Latenzzeiten eine sehr große Rolle spielen
Nach ewig langen erfolglosem Studieren der etwas dürftigen Elixir Dokumentation bin ich nachts um ca. 1 Uhr in der SQLAlchemy Dokumentation fündig geworden. Die “geheimen” Zauberwörter heißen “lazyload” und “eagerload”, wenn ich das nur vorher schon gewußt hätte
Hier ein kleines Beispiel:
Als erstes mal ein kleines Model (ja das ist das Beispiel aus der Elixir Doku
)
from elixir import *
metadata.bind = "sqlite:///:memory:"
metadata.bind.echo = True
class Movie(Entity):
title = Field(String(30))
director = ManyToOne('Director')
def __repr__(self):
return '<Movie "%s">' % (self.title)
class Director(Entity):
name = Field(String(60))
movies = OneToMany('Movie')
def __repr__(self):
return '<Director "%s">' % self.name
setup_all()
create_all()
Jetzt ein paar Werte einfügen:
rscott = Director(name="Ridley Scott")
glucas = Director(name="George Lucas")
unknown = Director(name="Nobody Unknown")
alien = Movie(title="Alien", director=rscott)
swars = Movie(title="Star Wars", director=glucas)
brunner = Movie(title="No Name", director=unknown)
session.flush()
session.clear()
for m in Movie.query.all():
print "Movie: name=%s director=%s" % (m.title, m.director.name)
Wenn man nun auf die letzten sql queries schaut, sieht man das erst alle movies aus der DB geladen werden und dann für jeden einzelnen Film wird der Director einzeln geholt. Ha nun ist klar warum das alles so langsam geht
SELECT __main___movie.id AS __main___movie_id, __main___movie.title AS __main___movie_title, __main___movie.director_id AS __main___movie_director_id
FROM __main___movie ORDER BY __main___movie.oid
[]
SELECT __main___director.id AS __main___director_id, __main___director.name AS __main___director_name
FROM __main___director
WHERE __main___director.id = ?
[1]
SELECT __main___director.id AS __main___director_id, __main___director.name AS __main___director_name
FROM __main___director
WHERE __main___director.id = ?
[2]
SELECT __main___director.id AS __main___director_id, __main___director.name AS __main___director_name
FROM __main___director
WHERE __main___director.id = ?
[3]
Damit aus diesen beispielhaften 4 Queries EINE wird kann man an so einer Stelle eagerload verwenden.
# import eagerload from sqlalchemy
from sqlalchemy.orm import eagerload
for m in Movie.query.options(eagerload("director")).all():
print "Movie: name=%s director=%s" % (m.title, m.director.name)
Und schon ist es eine Query:
SELECT __main___movie.id AS __main___movie_id, __main___movie.title AS __main___movie_title, __main___movie.director_id AS __main___movie_director_id, __main___director_1.id AS __main___director_1_id, __main___director_1.name AS __main___director_1_name
FROM __main___movie LEFT OUTER JOIN __main___director AS __main___director_1 ON __main___movie.director_id = __main___director_1.id ORDER BY __main___movie.oid, __main___director_1.oid
Alternativ zum “eagerload” kann man auch im Model das lazyload abschalten.
class Movie(Entity):
title = Field(String(30))
director = ManyToOne('Director', lazy=False) # <- lazyload now False
def __repr__(self):
return '<Movie "%s">' % (self.title)
Und wenn man mal das ganze Gegenteil braucht, kann man lazyload verwenden und im Model heißt die Option “deferred=True”.
posted with Vim