Eine .py im Unterordner aufrufen und starten

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Batt0sa1
User
Beiträge: 15
Registriert: Montag 21. April 2008, 23:15

Hi @ll...

ich versuche gerade in eine Menüleiste, abhängig von den vorhandenen Ordnern im Ordner "plugins", Menüeinträge zu erzeugen. Wenn man dann einen Eintrag anklickt, soll das ensprechende Plugin starten (jeder Ordner enthält eine start.py)....

Die Unterordner kann ich mittlerweile auslesen. Nur wie kann ich in die "start.py" wechseln und die Startfunktion starten?
Bisher bin ich so weit:

Code: Alles auswählen

def Plugins():
    #in den Ordner 'plugins' wechseln
    list = []
    path = os.path.abspath(os.path.join(os.path.curdir, u"plugins"))    
    #iterieren
    for foldername in os.listdir(path):
            start = open(foldername+'/start.py', 'r')
            list.append([foldername, 'Beschreibung', start.start, '', '',True])
    print list
Momentan meckert Python (sicher berechtigterweise ^^):
No such file or directory: u'.svn/start
Hab ich ein Verständnisproblem, oder geht das doch irgendwie?
(muss das evtl. über einen Import geschehen?)

Ich bin über jegliche Hilfe froh :D

[Edit]
PS.: die Menüleiste existiert schon und erwartet eine Liste mit:
[Name, Beschreibung und startfunktion]
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

1.) Für das Zusammensetzen von Pfadnamen gibt es join()
2.) Die Fehlermeldung ist doch eindeutig! Es gibt in dem Ordner eben keine start.py Datei! Also fange diese Exception ab.

Edit: Also ich verstehe noch nicht genau, was Du eigentlich machen willst! Wenn es um Funktionalität geht, kann ein open natürlich nicht funktionieren. Damit öffnest Du ja nur eine Datei zum Lesen. Generell ist import die Lösung, wenn es um das Einbinden von Python Modulen geht.

Vielleicht versuchst Du doch noch einmal genauer zu beschreiben, was Du erreichen willst! (Stichworte: Runtime vs. Desgintime!)
Benutzeravatar
Batt0sa1
User
Beiträge: 15
Registriert: Montag 21. April 2008, 23:15

Dann versuche ich es nochmal zu erklären:

1. es existiert ein Framework
2. in dieses Framework soll ein Plugin importiert werden
3. dieses Plugin befindet sich im Ordner "plugins', besitzt eine Datei namens 'start.py', welche wiederum die Funktion 'start' hat.

In die Menüleiste des Frameworks sollen nun alle Unterordner (von 'plugins') mit ihrem Namen angezeigt werden und sobald eins ausgewählt wurde, in den entsprechenden Unterordner gegangen und die startfunktion ausgeführt werden.

Das Open nicht so der wirklich gute Ansatz ist, konnte ich mir schon fast denken... Also geht so etwas nur über import?
Wie wäre denn dann der richtige Ansatz?
Ich meine mitten in der Laufzeit kann ich doch nicht mehr importieren oder?

Ansonsten:
deinen 1. Punkt verstehe ich nicht wirklich, was ist denn an meiner Lösung falsch?
Und zu dem 2. mag ja sein, dass Python die Datei nicht findet, ich hab sie aber definitiv angelegt...

Bisher hab ich mit Pfadangaben wenig gearbeitet und kenne mich da überhaupt nicht aus. Im Großen und Ganzen bin ich auch eher Anfänger...
Deshalb stelle ich ja die Fragen :)

PS.: Runtime vs. Designtime sagt mir ehrlich gesagt noch viel weniger...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Batt0sa1 hat geschrieben:Dann versuche ich es nochmal zu erklären:

1. es existiert ein Framework
ok. Ist das gegeben und Du musst damit klar kommen, oder hast Du das so gesignt?
2. in dieses Framework soll ein Plugin importiert werden
3. dieses Plugin befindet sich im Ordner "plugins', besitzt eine Datei namens 'start.py', welche wiederum die Funktion 'start' hat.
ok
In die Menüleiste des Frameworks sollen nun alle Unterordner (von 'plugins') mit ihrem Namen angezeigt werden und sobald eins ausgewählt wurde, in den entsprechenden Unterordner gegangen und die startfunktion ausgeführt werden.
ok
Das Open nicht so der wirklich gute Ansatz ist, konnte ich mir schon fast denken... Also geht so etwas nur über import?
Also imho ist das der beste Ansatz - aber die Experten im Forum hier sind andere ;-) Außer natürlich das es sich um quasi abgeschottete eigene Programme handelt. Dann wäre wohl ein Aufruf mit subprocess ideal.
Wie wäre denn dann der richtige Ansatz?
Ich meine mitten in der Laufzeit kann ich doch nicht mehr importieren oder?
Wieso nicht? Hast Du es mal probiert?
Ansonsten:
deinen 1. Punkt verstehe ich nicht wirklich, was ist denn an meiner Lösung falsch?
das "+" ;-)
Und zu dem 2. mag ja sein, dass Python die Datei nicht findet, ich hab sie aber definitiv angelegt...
Ich glaube kaum, dass Du in einem .svn-Ordner danach suchen willst ;-) (Oder sie da wirklich existiert!)
PS.: Runtime vs. Designtime sagt mir ehrlich gesagt noch viel weniger...
ok, ist jetzt nicht mehr wichtig, da ich nun weiß, was Du tun willst. Generell geht es darum, ob vor Programmstart klar ist, was vorhanden ist, oder es während das Programm läuft zu zusätzlichen Funktionalitäten kommen soll.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ok, ich hab ein wenig Mist erzählt: import funzt auch mitten im Code, aber nicht per String, also folgendes geht eben so nicht:

Code: Alles auswählen

mod = "random"
import mod
Allerdings steht dazu im wiki einiges interessantes:
[wiki]Import[/wiki]
Benutzeravatar
Batt0sa1
User
Beiträge: 15
Registriert: Montag 21. April 2008, 23:15

Das Framework ist gegeben und ich habe dafür ein Plugin entwickelt.
Da die Pluginschnittstelle aber noch nicht steht (momentan ist sie hart gecodet), wollte ich eine einfügen.

Das man nicht während der Laufzeit importiert, habe ich einfach mal inerpretiert, da alle Programme und Scripte die ich bisher in Python gesehen habe, dies prinzipiell am Anfang der Datei erledigt haben....
Ist mir aber wenn beides (import bzw. open) funzt relativ egal.
Hauptsache die Funktionalität ist bei allen Beriebssystemen gleich :)
Prinzip "Function over Design" *g*
Generell geht es darum, ob vor Programmstart klar ist, was vorhanden ist, oder es während das Programm läuft zu zusätzlichen Funktionalitäten kommen soll.
Es sind vor Programmstart alle Funktionalitäten bekannt.

[edit]
ich bin deinem Link mal gefolgt und da steht relativ weit unten ein Beispiel...
werde mich mal dran versuchen und wenn ich eine Lsg. hab schreib ich sie hier rein (oder frag nochmal ^^)
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Hyperion hat geschrieben:Ok, ich hab ein wenig Mist erzählt: import funzt auch mitten im Code, aber nicht per String[...]
Falsch. Schau dir mal __import__ an. ;)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

DasIch hat geschrieben:
Hyperion hat geschrieben:Ok, ich hab ein wenig Mist erzählt: import funzt auch mitten im Code, aber nicht per String[...]
Falsch. Schau dir mal __import__ an. ;)
"__import__" ist was anderes als "import" ;-)
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Ja schon, aber man kann das gleiche mit machen ;)
Benutzeravatar
Batt0sa1
User
Beiträge: 15
Registriert: Montag 21. April 2008, 23:15

Das hab ich jetzt gezaubert :)
Importieren geht, wenn man eine __init__.py (kann leer sein) in die entsprechenden Unerordner hineinfügt :idea:

Code: Alles auswählen

def Plugins():
    #in den Ordner 'plugins' wechseln
    list = []
    path = os.path.abspath(os.path.join(os.path.curdir, u"plugins"))    
    #iterieren
    for foldername in os.listdir(path):
        #versteckte und py - Dateien verhindern
        if foldername.startswith(".") or (foldername.endswith("py") 
                                      or foldername.endswith("pyc") 
                                      or foldername.endswith("pyo")):
            continue 
        try:
            #in jedem Ordner die Readme auslesen und die Datei start.py importieren
            #
            f_path = os.path.join(path, foldername, 'Readme.txt')
            file = open(f_path,"r")
            Beschreibung = file.readlines(1)
            import start
        except:
            pass
        try:
            list.append([str(foldername), str(Beschreibung), start.startmenu, '', '',True])
        except:
            pass
    return list
Als Liste kriege ich dann soetwas hier:
['Plugin', "['hier steht eine Beschreibung\\n']", <function startmenu at 0x8d35374>, '', '', True]
Soweit eigentlich fast alles schick :)
Die Menüeinträge sind in jedem Fall da.
Nur 2 Sachen die noch stören...

1.: der (rote) Beschreibungstext sieht sehr komisch aus... wie krieg ich da die eckigen Klammern und das "\n" weg? Liegt glaube ich an "readlines()"
und das zweite wohl schwierigere Problem:
wie kann ich Übergabewerte mitgeben? Momentan kann mein Plugin nicht aufgerufen werden, da meinem (und allen zukünftigen) Plugin(s) ja keine Übergabewerte mitgegeben werden. Mein Lösungsansatz wäre gewesen, die benötigten Objekte in die Readme zu schreiben, aber das hat bisher noch nicht gefruchtet.

PS.: hab grad mitgekriegt, dass das doch nicht so ganz funzt wie es sollte... bei "import start", importiert er die falsche. D.h. er springt nicht in den Ordner "plugins" :evil:
Benutzeravatar
Batt0sa1
User
Beiträge: 15
Registriert: Montag 21. April 2008, 23:15

Bin nun noch einen kleinen Schritt weiter. Wie man am Code sehen kann hab ich mir die Module zusammengesetzt und importiere sie nun dynamisch :)
In der Menüleiste wird auch soweit alles angezeigt.

Der Fehler gestern war wohl ein Verständnisproblem denke ich mal...
Es wird wohl doch nicht automatisch aus dem aktuellem Ordner importiert :D
Jedenfalls habe ich, indem ich in jedem Ordner eine __init__.py angelegt habe, mir diese aufrufbar gestaltet.

Der Code:

Code: Alles auswählen

def Plugins(parent):
    '''ToDo: die benötigten Übergabewerte der Pugin-Startfunktion irgendwie auslesen
            '''
    #in den Ordner 'plugins' wechseln
    list = []
    m_path = os.path.abspath(os.path.join(os.path.curdir))
    path = os.path.abspath(os.path.join(os.path.curdir, u"plugins"))    
    #iterieren
    for foldername in os.listdir(path):
        #versteckte und py - Dateien ausblenden
        if foldername.startswith(".") or (foldername.endswith("py") 
                                      or foldername.endswith("pyc")):
            continue 
        try:
            #in jedem Ordner die Readme auslesen und die Datei start.py importieren
            f_path = os.path.join(path, foldername, 'Readme.txt')
            file = open(f_path,"r")
            Beschreibung = file.readlines(1)

        except:
            logging.debug(u"keine Readme.txt gefunden in "+ f_path + " gefunden")
        #import plugins
        try:
            pluginort =  "plugins."+foldername+".start"
            #__import__ akzeptiert Strings als Übergabewert
            plugin = __import__(pluginort)
        except:
            logging.debug(u"konnte kein Startmodul in "+ pluginort + " finden")
            
        try:
            list.append([str(foldername), str(Beschreibung), plugin.__init__, '', '',True])
        except:
            logging.debug(u"konnte Modul "+ foldername + " nicht laden")

    #print list
    return list
Hab aber immer noch ein relativ elementares Problem:
Wenn ich nun den Menüeintrag auswähle (klicke) kriege ich die folgende Fehlermeldung:
TypeError: module.__init__() argument 1 must be string, not CommandEvent

Wie kann ich es hier hinkriegen das Plugin zu initialisieren und Werte (evtl. dynamisch) zu übergeben?
Regelt das die __init__ im Ordner oder sollte ich mir eine in das Modul schreiben. Beide Ansaätze haben bisher nichts gebracht, aber das heißt bei mir ja nichts *g*
Ich krieg bestenfalls die obige Fehlermeldung :(

Wäre toll wenn jemand noch einen Tip hätte :wink:
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

`__import__` gibt bei leerem ``fromlist``-Argument das Package zurück, und nicht das Modul. Wenn `__init__` also eine Funktion im ``start``-Modul ist, müsste dort also ``plugin.start.__init__`` stehen und nicht ``plugin.__init__``. Ansonsten ist, zumindest für mich, nicht ersichtlich, wie die Plugins jetzt aufgebaut sind oder woher der besagte Fehler überhaupt kommt, aus dem geposteten Code jedenfalls nicht.

Außerdem ist das [mod]imp[/mod]-Modul noch interessant, bei dem man auch Pfade übergeben kann.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Benutzeravatar
Batt0sa1
User
Beiträge: 15
Registriert: Montag 21. April 2008, 23:15

Hab zwar deinen Tip mit "fromlist" nicht verstanden, aber nach ein wenig goggeln bin ich auf eine Mailingliste gestossen wo es nochmal erklaert wurde...
Damit hab ich dann das Hauptproblem loesen koennen :D

Aber nochmal zu deiner Frage, die Struktur soll prinzipiell so aussehen:

/Programmordner
+enthaelt Hauptdateien
-------/Gesamt_Pluginordner
-------/__init__.py (ohne "richtigen" Code, nur Disclaimer und Sachen wie __author__)
-----------/Pluginordner
-----------/ __init__.py Inhalt wie oben)
-----------/ start.py initialisiert plugin (enthaelt eine Funktion "start")

Initialisieren und importieren krieg ich jetzt aber hin :)
Was mir jetzt noch weiterhelfen wuerde, waere wenn mir jetzt noch jemand sagen kann, wie ich da einen Uebergabewert mitgeben kann...

Der Code sieht jetzt so aus:

Code: Alles auswählen

def Plugins(parent):
    '''ToDo: die benoetigten Uebergabewerte der Startfunktion irgendwie auslesen
            '''
    #in den Ordner 'plugins' wechseln
    list = []
    path = os.path.abspath(os.path.join(os.path.curdir, u"plugins"))    
    #iterieren
    for foldername in os.listdir(path):
        #versteckte und py - Dateien ausblenden
        if foldername.startswith(".") or (foldername.endswith("py") 
                                      or foldername.endswith("pyc")):
            continue 
        try:
            #in jedem Ordner die Readme auslesen und die Datei start.py importieren
            f_path = os.path.join(path, foldername, 'Readme.txt')
            file = open(f_path,"r")
            Beschreibung = file.readlines(1)

        except:
            logging.debug(u"keine Readme.txt gefunden in "+ f_path + " gefunden")
        #import plugins
        try:#start.py
            pluginort =  "plugins"#."+foldername#+".start"
            #print pluginort
            #__import__ akzeptiert Strings als Uebergabewert
            plugin = __import__("plugins."+foldername+".start", globals(), locals(), ['start'])
            #print plugin.__author__
        except:
            logging.debug(u"konnte kein Startmodul in "+ pluginort + " finden")
            
        try:
            '''hier wuerde ich gerne soetwas wie plugin.Start(parent) machen ;)'''

            list.append([str(foldername), str(Beschreibung), plugin.Start, '', '',True])
        except:
            logging.debug(u"konnte Modul "+ foldername + " nicht laden")

    #print list
    return list
Der 3. Wert in der "list" - Liste wird fuer das Menue gebraucht.
in der Funktion die das Menue erstellt sieht das grob gesagt so aus:

Code: Alles auswählen

menu = wx.Menu().Append(wx.NewId(),list[0],list[1],list[3])
self.Bind(wx.EVT_MENU,list[2],menu)
Tipps und Hilfestellungen sind weiterhin willkommen :D

[Edit]
Kann das Problem jetzt noch ein wenig weiter eingrenzen...
Wenn ich einen Übergabewert mitgebe (parent), sperrt sich mein Plugin!
Da ich im Plugin mit dem Frame und einer Liste arbeite, beides bei der Menüinitialisierung aber anscheinend noch nicht vorhanden, meckert Python.

[Doppeledit]
Nachdem ich nun die Menüinitialisierung nach hinten versetzt habe, scheint erstmal fast alles zu stimmen...
Aber anscheinend wird mit dem Menüeintrag auch das Plugin gestartet...
Wie kann man das verhindern?
Hab es über:

Code: Alles auswählen

 if __name__ == __main__:
 main()
probiert, dass hat aber (bisher) nichts bewirkt
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Batt0sa1 hat geschrieben:-----------/ start.py initialisiert plugin (enthaelt eine Funktion "start")
Das deckt sich aber doch wieder nicht mit dem Code, im Code schreibst du ``plugin.Start``.
Batt0sa1 hat geschrieben:Nachdem ich nun die Menüinitialisierung nach hinten versetzt habe, scheint erstmal fast alles zu stimmen...
Aber anscheinend wird mit dem Menüeintrag auch das Plugin gestartet...
Wie kann man das verhindern?
Hab es über:

Code: Alles auswählen

 if __name__ == __main__:
 main()

probiert, dass hat aber (bisher) nichts bewirkt
Das hat nichts bewirkt? Das müsste, wenn man nicht gerade etwas wie ``import __main__`` oder so gemacht hat, zumindest einen `NameError` werfen, und wenn man den dann behoben hat, einen `IndentationError`. Und was heißt, das Plugin wird gestartet? Bei einem import wird eben alles auf Modulebene ausgeführt. Wenn man das nicht will, muss man den Code eben in eine Art init-Funktion packen, die der Plugin-Loader dann aufruft.

Ansonsten wäre vllt ein minimales, ausführbares Codebeispiel des Problems nicht schlecht, weil mit "sperrt sich mein Plugin" oder "meckert Python" kann man reichlich wenig anfangen.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Benutzeravatar
Batt0sa1
User
Beiträge: 15
Registriert: Montag 21. April 2008, 23:15

Hab jetzt gerade eine Lösung gefunden.
Scheint soweit erstmal zu funktionieren...

Code: Alles auswählen

def Plugins(parent):
    '''ToDo: die benötigten Übergabewerte der Startfunktion irgendwie auslesen
            '''
    #in den Ordner 'plugins' wechseln
    list = []
    path = os.path.abspath(os.path.join(os.path.curdir, u"plugins"))    
    #iterieren
    def test(event):
        plugin.Start(parent)
        event.Skip()
    for foldername in os.listdir(path):
        #versteckte und py - Dateien ausblenden
        if foldername.startswith(".") or (foldername.endswith("py") 
                                      or foldername.endswith("pyc")):
            continue 
        try:
            #in jedem Ordner die Readme auslesen
            f_path = os.path.join(path, foldername, 'Readme.txt')
            file = open(f_path,"r")
            Beschreibung = file.readlines(1)
        except:
            logging.debug(u"keine Readme.txt gefunden in "+ f_path + " gefunden")
        
        #import plugins
        try:
            #die Datei start.py aus /plugins/Plugin-name importieren
            pluginort =  "plugins."+foldername
            #__import__ akzeptiert Strings als Übergabewert
            plugin = __import__("plugins."+foldername+".start", globals(), locals(), ['start'])
            #print plugin.__author__, plugin.__date__
        except:
            logging.debug(u"konnte kein Startmodul in "+ pluginort + " finden")
            
        #try:
        #Listeneintrag für das PluginMenu hinzufügen
        list.append([str(foldername), str(Beschreibung), test, '', '', True])
        #except:
        #    logging.debug(u"konnte Modul "+ foldername + " nicht laden")
            

    return list
Wobei mein Plugin start.py so aussieht:

Code: Alles auswählen

def Start(self):
    shapes = self.canvas.shapes
    malkasten = self.frame 
    ...(Code)
Woran aber nun das Problem lag, dass das Plugin aufgerufen wurde und "python meckerte" ^^ kann ich ehrlich gesagt nicht sagen...
Ich tippe darauf, dass ich versucht habe, zwanghaft ein Attribut mit dem Event zu übergeben. Da ich mich aber an eine Hilfe von Gerold erinnert habe (http://www.python-forum.de/topic-14651.html)
bin ich auf die Lösung gekommen...


Inwieweit das jetzt Stylekonform (o.ä.) ist, kann ich nicht sagen...
Ich hoffe mal, dass das eine "normale" Lösung ist :?
Mit dem Thread hier bin ich dann auf die Lösung gekommen *GG*
-->http://www.python-forum.de/topic-15733.html
Fabian Kochem
User
Beiträge: 36
Registriert: Mittwoch 5. April 2006, 14:11
Wohnort: Köln

Wenn ich kurz was dazu einwerfen darf:
Über das (mitgelieferte) Modul imp erhälst du direkten Zugriff auf die Implementation des "import"-Statements. Damit sollte es relativ einfach sein, einen kleinen Plugin-Manager zu basteln.
Habe ich selbst auch schonmal in einem Projekt benutzt, hinterher konnte man über die Konsole sogar zur Laufzeit die Plugins neu einlesen, sodass nicht jedes Mal die komplette Applikation neu initialisiert werden musste. Wenn du mit dem Modul nicht klarkommst, kann ich den Quellcode nochmal raussuchen.
Benutzeravatar
Batt0sa1
User
Beiträge: 15
Registriert: Montag 21. April 2008, 23:15

Fabian Kochem hat geschrieben:(...) kann ich den Quellcode nochmal raussuchen.
Na zu dem Angebot sag ich doch nicht "Nein" :D
Funzt nämlich doch nicht ganz so wie es soll...
(momentan wird immer das zuletzt importierte Modul aufgerufen)

Ein Beispiel würde mir da stark weiterhelfen 8)
Benutzeravatar
Batt0sa1
User
Beiträge: 15
Registriert: Montag 21. April 2008, 23:15

Ich will euch ja meine Lösung nicht vorenthalten :D

Das Problem war, dass ich zwar alle Module importieren, aber sie nicht im wx.Menu aufrufen konnte... Es wurde immer nur das zuletzt importierte Modul ausgeführt (was auch logisch ist, da dem "self.plugin" ja immer wieder neue Werte hinzugefügt wurden)

Egal...
Ich hab es jetzt mit einer Liste für alle importierten Module gelöst, die Ids verglichen und das Ganze in eine Klasse gefügt :)
Irgendwie empfinde ich es zwar ein weinig als Frickelei *g* (gibt sicher elegantere Lösungen), aber es funzt bisher ganz gut...
Um das Menü zu füllen, wird die Klasse Plugins (s.u.) initialisiert:

Code: Alles auswählen

 list = Plugins().Pluginmenulist(parent)
Die Klasse:

Code: Alles auswählen

class Plugins():
    ''' diese Klasse importiert die Plugins in die Menüleiste und (später) auch in die Toolbar 
    ToDo: die benötigten Übergabewerte der Startfunktion möglicherweise auslesen
            '''
    def startplugin(self, event):
        menubar = self.parent.GetMenuBar()
        #finde Menüeintrag, mit dem Namen "[1]"  
        for _ in self.pluginlist:
            '''getriggerte ID des events abgleichen mit allen Einträgen im Pluginmenü
            sobald ein Menüname gefunden wurde der PlugIn starten'''
            id = menubar.FindMenuItem('Plugin',_[1])  
            if  event.GetId() == id:
                    #print menubar.GetLabel(id)
                    plugin = _[0]
                    plugin.Start(self.parent)
                    break
            else:
                continue
        event.Skip()       
        
    def Pluginmenulist(self, parent): 
        '''in dieser Funktion werden die Plugin-Menüeinträge erzeugt ''' 
        logging.debug('Pluginmenu wird erstellt')
        list = []
        self.pluginlist = []
        path = os.path.abspath(os.path.join(os.path.curdir, u"plugins"))    
        i = 0   
        self.parent = parent
        self.plugin = None
        for foldername in os.listdir(path):                                 #iterieren über den pluginordner
            if foldername.startswith(".") or (foldername.endswith(".py")     #versteckte und 
                                          or foldername.endswith(".pyc")):   #py - Dateien ausblenden
                continue 
            try:
                #in jedem Ordner die Readme auslesen
                logging.debug('Modul '+ foldername +' wird geladen')
                f_path = os.path.join(path, foldername, 'Readme.txt')
                file = open(f_path,"r")
                Beschreibung = file.readlines(1)
            except:
                logging.debug(u"keine Readme.txt gefunden in "+ f_path + " gefunden")
            
#------------import plugins------------------------------------------------------------
            #die Datei start.py aus /plugins/Plugin-name importieren
            pluginort =  "plugins."+foldername
            #__import__ akzeptiert Strings als Übergabewert
            try:
                self.plugin = __import__("plugins."+foldername+".start", globals(), locals(), ['start'])
            except:
                plugin = None
                logging.debug(u"konnte kein Startmodul in "+ pluginort + " für Plugin" + foldername + " finden")
            try:
                #Listeneintrag für das PluginMenu hinzufügen
                list.append([str(foldername), str(Beschreibung), self.startplugin, '', '', True]) 
            except:
                logging.debug(u"konnte Modul "+ foldername + " nicht hinzufügen")
            self.pluginlist.append([self.plugin, str(foldername)]) #speichert alle importierten Startfunktionen
        logging.debug('keine weiteren Plugins zum importieren gefunden')
        return list
Und die zurückgegeben Liste wird dann in der Form:

Code: Alles auswählen

plugin = menu.Append(wx.NewId(),list[0],list[1])
parent.Bind(wx.EVT_MENU, list[2], plugin)
in einer "for" - Schleife verwendet...
Den ganzen Code kann ich aber nicht auseinander klamüsern, da ich ja nur die oben genannte Schnittstelle geschrieben habe 8)
Falls aber jemand vor dem selben Problem steht und trotz allem nicht weiter kommt, versuche ich es zur Not aber gerne nochmal...
^^

Veglichen mit meinem Startversuch ist es ja doch ein wenig größer geworden. Auf jeden Fall Danke für die Tipps, ich wäre sonst wohl nur sehr schwer auf den Trichter gekommen :)
THX @ all
Fabian Kochem
User
Beiträge: 36
Registriert: Mittwoch 5. April 2006, 14:11
Wohnort: Köln

Sorry, ein bisschen verspätet - aber vielleicht ja doch noch ganz interessant:

Code: Alles auswählen

    def loadPlugin(self, filename):
	"""
	    Try to load a plugin in plugins/filename via imp.
	"""
	
	# File has .py extension
	if filename[-3:] == ".py":
	    plugin_file = filename[:-3]
	    
	    # Import file via imp and try to load class Plugin
	    (n, f, s) = imp.find_module(plugin_file, ['plugins'])
	    inst = imp.load_module(plugin_file, n, f, s).Plugin(self.propolice)
Ein Plugin sähe z.B. so aus und läge in ./plugins/auth.py:

Code: Alles auswählen

class Plugin:
    def __init__(self, propolice):
        """ """
        self.propolice = propolice
        self.propolice.plugins.registerCommand("auth", self.auth, require_channel=0, require_privmsg=1, require_level="none")
        self.propolice.plugins.registerModule("auth_logout", self.logout, re.compile("^:(.*)!.*@.* QUIT .*$"))
Aufruf mit .loadPlugin("auth.py"), in inst hättest du dann die Instanz aus auth.py.
Antworten