Deutsche Zope User Group
Gast 1 Benutzer online
DZUG-News

Neue Produkte in ein anderes Verzeichnis installieren

Neue Produkte in ein anderes Verzeichnis installieren, um sie von Standardprodukten unterscheiden zu k�nnen.

Wer kennt das Problem nicht: Um neue Produkte zu testen, muss man sie in das lib/python/Products Verzeichnis im Zope-Verzeichnis kopieren. Nach einiger Zeit wird es un�bersichtlich und man kann die Standardprodukte nicht mehr von den nachinstallierten Produkten unterscheiden.

In diesem HowTo wird beschrieben, wie man beliebige weitere Produktverzeichnisse hinzuf�gen kann.

Vorgang

  • Verzeichnisse anlegen [1], [2]
    $ cd $ZOPE
    $ mkdir AddedProducts
    $ mkdir TestingProducts
    $ cd lib/python/Products
    $ mkdir AddProductsDir
    Damit werden die drei Verzeichnisse $ZOPE/AddedProducts (f�r neue Produkte), $ZOPE/TestingProducts (f�r Produkte, die man testen will) und $ZOPE/lib/python/Products/AddProductsDir angelegt

  • Script anlegen
    $ZOPE/lib/python/Products/AddProductsDir/__init__.py

import Products
import sys, os

addingDirs = [$ZOPE/AddedProducts, '$ZOPE/TestingProducts']

for DIR in addingDirs:
    if not os.path.exists(DIR): continue

    for PATH in Products.__path__:
        PATH = os.path.abspath(PATH)
        if DIR in (PATH, PATH + os.sep): break
    else:
        Products.__path__.append(DIR)

  • Zope neu starten
    Unter Debian: $ zopectl force-reload
    Unter anderen Linux-Distributionen muss man Zope komplett herunterfahren und dann neu starten. Ein $ zopectl restart reicht zumindest unter Debian nicht.

Erkl�rung

Products.__path__ enth�lt eine Dictionary mit allen Verzeichnissen, in denen nach Zope-Produkten gesucht werden soll (siehe dazu z.B. $ZOPE/lib/python/OFS/Application.py Funktion get_products()). Durch import Products wird die Klasse Products in den lokalen Namensraum importiert. append() f�gt dem Dictionary ein weiteres Element zu.

Die beiden for-Schleifen und die �berpr�fungen im Code sind nicht zwingend notwendig, verhinderen aber m�gliche Fehler. Die �u�ere for-Schleife durchl�uft das Dictionary, welches die Pfade enth�lt, die man hinzuf�gen will. Die erste �berpr�fung l��t die for-Schleife zum n�chsten Element springen, wenn das Verzeichnis nicht existiert. Die innere for-Schleife �berpr�ft, ob der Pfad schon in Products.__path__ ist, damit ein Pfad nicht ein zweites Mal hinzugef�gt wird. Erst wenn dieser Test positiv verl�uft, wird der Pfad zu Products.__path__ hinzugef�gt, ansonsten wird das n�chste Element der �u�eren for-Schleife angesprungen.

Dies alles h�tte man theoretisch in jeder beliebigen Datei machen k�nnen, die von Zope ausgef�hrt wird. Im Products-Verzeichnis muss man aber keine Datei patchen, da jedes Unterverzeichnis von Zope automatisch importiert wird und die darin enthaltene __init__.py ausgef�hrt wird.

Vielleicht wundern sich einige Anf�nger, wieso Products.__path__ die Methode append() besitzt. Das liegt daran, das es sich bei __path__ um ein Dictionary handelt und jedes Dictionary eingebaute Funktionen wie eben append() besitzt.

Da in Python grunds�tzlich Verweise (entspricht Pointern in C) und nicht Kopien von Variablen wie z.B. in PHP gemacht werden, reicht es, die Klasse Products zu importieren, um sie dann im gesamten Kontext zu �ndert. So etwas nennt man im �brigen im Zope Jargon "Monkey Patch".

Gotchas

  • Wenn das mit Products.__path__.append() deklarierte Verzeichnis nicht existiert oder Zope dieses Verzeichnis nicht lesen kann, dann startet Zope nicht mehr (Panic (300) z2 Startup exception). Dies wird durch if not os.path.exists(DIR): continue verhindert.

Quellen

Basiert auf: Define additional Products directories

�berpr�fungsroutinen aus dem Python Cookbock von O'Reilly (4.22 , Page 148)

Konventionen

[1] $ZOPE entspricht den Verzeichnis, in dem die ZOPE-Binaries und Scripte abgelegt sind. Bitte diesen Zeichenkette bei der Eingabe durch den entsprechenden Verzeichnisnamen ersetzen. Unter Debian entspricht das /usr/lib/zope, unter SuSE IMHO /opt/zope.
[2] Befehle, die in einer Shell (Eingabeaufforderung) eingegeben werden, sind wie *$ Befehl" formatiert. Das bedeutet, das man an der Eingabeaufforderung nach dem $ bzw. # die Worte "Befehl" eingibt und dann dr�ckt. Das $ nicht mit eingeben!
[3] Die Namen von Funktionen, Klassen und Dateien au�erhalb von Befehlen werden fett geschrieben.
[4] Dateiinhalte werden kursiv geschrieben.

Geschrieben von Tiran . Letzte �nderung 01.04.2003 22:10.