Direkt zum Inhalt | Direkt zur Navigation

Benutzerspezifische Werkzeuge

Sie sind hier: Startseite / Tech-Blog

Tech-Blog

Technische Artikel zu Themen: Zope, Plone, Python, Exim, Dovecot, Nagios, Shinken, Bacula und weiteren Open Source Themen...

Plone: Diazo Theme & password_reset: Passwort setzen fehlgeschlagen

Wenn der password_reset in einer Plone Seite mit Diazo basiertem Theme nicht mehr funktioniert und statt dessen, die Meldung "Passwort setzen fehlgeschlagen" erscheint, liegt dies meist an einer fehlerhaften rules.xml.

Fehlendes base-Tag

Das Problem, im Theme fehlt das base-Tag welches Plone selbst rendert.

<base href="http://inqbus-hosting.de/" />

Dieses sollte mit folgender Regel ins Theme übertragen werden.

<drop theme="/html/head/title" />
<drop theme="/html/head/base" />
<drop theme="/html/head/comment()" />
<after
  content="/html/head/base | /html/head/comment() | /html/head/title"
  theme-children="/html/head"
  />

Diazo: CSS Klasse per XSLT in body-Tag einfügen

Manchmal reichen die Möglichkeitenvon Diazo alleine nicht aus um zum Ziel zu gelangen. Im folgenden Beispiel möchte ich zeigen, wie man mit Hilfe von XSLT CSS Klassen, in Abhängigkeit des Vorhandenseins der Portletspalten von Plone, in das body-Tag einfügen kann.

Plone hat ein 3 Spaltenlayout, sofern rechts und links Portlets vorhanden sind. In einigen Bereichen möchte man aber z.B hin und wieder die rechte Spalte ausblenden um mehr Platz zu haben. Hat man jetzt ein fixes Grid-Layout so bleibt die rechte Spalte leer, die mittle Spalte dehnt sich aber nicht aus. Die Lösung kann eine CSS-Klasse im body-Tag sein, welche dann in den Stylesheets als Marker verwendet werden kann.

CSS-Klasse in body-Tag einfügen

<xsl:attribute name="class"><xsl:value-of select="/html/body/@class" /> three_col</xsl:attribute>

Bedingtes Einfügen

<before theme-children="/html/body" method="raw">
  <xsl:attribute name="class"><xsl:value-of select="/html/body/@class" /><xsl:if css:test="#portal-column-one"> col-one</xsl:if><xsl:if css:test="#portal-column-content"> col-content</xsl:if><xsl:if css:test="#portal-column-two"> col-two</xsl:if></xsl:attribute>
</before>

<drop css:theme="#portal-column-one" css:if-not-content="#portal-column-one" />
<drop css:theme="#portal-column-content" css:if-not-content="#portal-column-content" />
<drop css:theme="#portal-column-two" css:if-not-content="#portal-column-two" />

Plone: persistente Utilities manuell entfernen

In Plone werden von vielen Erweiterungen persistente Utilities (local utilities) registriert. Leider werden diese nicht bei allen Erweiterungen auch wieder entfernt, wenn man diese deinstalliert. Dies führt dazu, dass man diese Erweiterungen nicht mehr richtig entfernen kann. Nachfolgend wird erläutert, wie man local utilities manuell entfernt.

Wenn man eine solche fehlerhafte Erweiterung deinstalliert und diese auch aus dem Buildout entfernt, kommt es zu Fehlermeldungen der folgenden Art.

AttributeError: type object 'IWarehouseContainer' has no attribute '__iro__'

Um den Fehler zu beheben, müssen wir die Erweiterung noch einmal im Buildout installieren.

Registrierung finden

Am besten schauen wir uns als erstes den Code der Erweiterung an, der das local utility registriert. Hier zu suchen wir in dem package nach dem Interface 'IWarehouseContainer'.

~/.buildout/eggs/getpaid.warehouse-0.3-py2.7.egg/getpaid/warehouse
$ grep -r "IWarehouseContainer" .

Wir finden hier die Registrierung.

sm.registerUtility(component=warehouses, provided=interfaces.IWarehouseContainer )

Dies wird uns helfen das Utility zu entfernen.

Utility entfernen

Um das local utility zu entfernen starten wir die Instanz mit debug.

./bin/instance debug

Nun holen wir uns den site manager.

sm = app.Plone.getSiteManager()

Anschließend importieren wir das Interface IWarehouseContainer und holen uns das Utility.

from getpaid.warehouse.interfaces import IWarehouseContainer
warehouse = sm.queryUtility( IWarehouseContainer )

Das Utility können wir jetzt mit sm.unregisterUtility(IWarehouseContainer) aus der Registrierung entfernen. Da das Utility selbst IWarehouseContainer nicht implementiert, muss das Interface in diesem Fall mit angegeben werden.

sm.unregisterUtility(warehouse, provided=IWarehouseContainer)

Reguläre Ausdrücke in Python

Mit Regulären Ausdrücken (Regular Expressions) können Texte sehr flexibel und schnell verarbeitet werden. Da man in der Programmierung häufig auf Reguläre Ausdrück angewiesen ist, fasse ich hier ein paar Beispielhafte Lösungen zusammen.

Dokumentation zu regulären Ausdrücken in Python

Ich möchte hier nicht die vorhandene Dokumentation wiederholen, daher sei hiermit auf darauf verwiesen:

Beispiele

Zum testen von Regulären Ausdrücken eigent sich folgender Aufruf:

p = re.search(r'(?P<salutation>^Frau|^Herr)\s+(?P<name>.*)', "Herr Conrad Meier")

Hier wird das Modul re direkt verwendet, was zum testen ok ist, später ist es besser den regulären Ausdruck zu Kompelieren, damit die Operationen schneller ausgeführt werden können.

p = re.compile(r'(?P<salutation>^Frau|^Herr)\s+(?P<name>.*)')
p.search("Herr Conrad Meier")

Adressblock parsen

Wir wollen folgenden Adressblock parsen und Anrede, Name sowie PLZ und Ort auslesen.

ADDRESSBLOCK = u"""
  Inqbus GmbH & Co. KG
  Herr Maik Derstappen
  Geschäftsführer
  Karl-Heine-Str. 99
  04109 Leipzig
  Plagwitz
  Sachsen
  Deutschland"""

Wir definieren uns nun 2 reguläre Ausdrücke, die die Zeile mit der Anrede und dem Namen, sowie die Zeile mit der PLZ und dem Ort beschreiben. In den Ausdrücken werden benannte Guppen erzeugt, um auf diese später einfach zugreifen zu können.

z.B. erzeugt folgender Ausdruck eine Gruppe mit dem Namen salutation, die die Anrede (Frau/Herr) enthält.

(?P<salutation>^Frau|^Herr)
ReSalutationName = re.compile(r'(?P<salutation>^Frau|^Herr)\s+(?P<name>.*)')
ReZipecodeCity = re.compile(r'(?P<zipcode>\d{4,5})\s+(?P<city>.*)')

Im folgenden iterieren wir über die Zeilen des Adressblockes und wenden die regulären ausdrücke auf jede Zeile an. Wenn z.B. der erste Ausdruck ReSalutationName.search(line.strip()) ein Ergebnis zurück liefert, können wir auf die definierten Gruppen (salutation, name) per match_object.group('Gruppenname') zugreifen und bekommen den Teilstring der Gruppe zurück.

for line in ADDRESSBLOCK:
  salutation_name = ReSalutationName.search(line.strip())
  if salutation_name:
    salutation = salutation_name.group('salutation')
    name = salutation_name.group('name')
    continue

  zipcode_city = ReZipecodeCity.search(line.strip())
  if zipcode_city:
    zipcode = zipcode_city.group('zipcode')
    city = zipcode_city.group('city')
    continue

How to install MySQLdb in virtualenv on Debian

To install MySQL-Python with pip, you need some development header files of libmysqlclient.

If you try to install MySQL-Python with pip as follow:

 

pip install MySQL-Python

 

You will get this error, because of missing header files of libmysqlclient:

$ pip install MySQL-Python
Downloading/unpacking MySQL-Python 
Downloading MySQL-python-1.2.3.tar.gz (70Kb): 70Kb downloaded 
Running setup.py egg_info for package MySQL-Python   
sh: 1: mysql_config: not found   
Traceback (most recent call last):     
File "<string>", line 14, in <module>     
File "/home/maik/.virtualenvs/env1/build/MySQL-Python/setup.py", line 15, in <module>       
metadata, options = get_config()     
File "setup_posix.py", line 43, in get_config       
libs = mysql_config("libs_r")     
File "setup_posix.py", line 24, in mysql_config       
raise EnvironmentError("%s not found" % (mysql_config.path,))   
EnvironmentError: mysql_config not found   
Complete output from command python setup.py egg_info:   
sh: 1: mysql_config: not found
Traceback (most recent call last):
File "<string>", line 14, in <module>
File "/home/maik/.virtualenvs/env1/build/MySQL-Python/setup.py", line 15, in <module>
metadata, options = get_config()
File "setup_posix.py", line 43, in get_config
libs = mysql_config("libs_r")
File "setup_posix.py", line 24, in mysql_config
raise EnvironmentError("%s not found" % (mysql_config.path,))
EnvironmentError: mysql_config not found

This error can be solved by installing the libmysqlclient header files.

aptitude install libmysqlclient-dev