Soweit ganz gut,....

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.
Gast

hallo zusammen,

ich habe mir ein skript geschrieben, dass mir meine cgi-skripten, die ich für localhost entwickle so abgleicht, dass sie auch am webserver funktionieren. dieser weicht in der konfiguration in einigen punkten ab.
dabei wird einerseits zuerst in einem bestimmten verzeichnis am lokalen rechner eine kopie abgelegt und andererseits, sofern eine verbindung besteht, dieselbige sofort hochgeladen.
eigentlich klappt alles wunderbar, es gibt nur noch kleinigkeiten, die ich klären möchte.
ihr könnt natürlich auch gern anmerken was ihr bedenklich findet, was ich vielleicht anders machen sollte usw.

wenn ihr was gut findet dürt ihr es auch festhalten, grins,

hier mal das skript, das ist bereits die fassung mit gut:

Code: Alles auswählen

#!/usr/bin/python


import sys, os, pickle, ftplib
from re import *
from Tkinter import*
from ScrolledText import*
import tkMessageBox



class FtpUpload:


    def __init__(self,my_filename):
        try:
            my_conn=ftplib.FTP\
                     ('domain','user','password')
            my_conn.cwd('/html/cgi-bin')
            my_conn.storbinary\
                     ('STOR %s' % my_filename, open(my_new_lin_path+my_filename, 'rb'))
            a.my_listbox_b.insert(0,"Sucess, "+my_filename+" saved und uploaded!")
        except:
            a.my_listbox_b.insert(0,"No connection, "+my_filename+" saved bot not uploaded")

  


class ChangeContentForServer:
    
        
    def __init__(self,my_choice,my_dir_index,my_configuration='n'):
        
        self.my_choice=my_choice
        self.my_dir_index=my_dir_index
        for i in self.my_choice:
            
            self.my_filename=self.my_dir_index[int(i)]
            f=file(my_lin_path+self.my_filename,'r')
            self.my_content=f.read()
            f.close()
            self.first_change_in_my_file()


    def first_change_in_my_file(self):
        self.my_content_new=self.my_content.replace\
                             ('#!/usr/bin/python','#!/usr/local/bin/python')
        self.second_change_in_my_file()
        

    def second_change_in_my_file(self):
        self.my_content_list=self.my_content_new.splitlines()
        self.my_content_list.insert(1,"\n")
        self.my_content_list.insert(2,"import sys")
        self.my_content_list.insert\
                              (3,"sys.path.append('/var/www/web188/html/cgi-bin/module')")
        
        self.my_content_ready=''
        for i in self.my_content_list:
            self.my_content_ready=self.my_content_ready+i+'\n'
        self.third_change_in_my_file()
        
 
    def third_change_in_my_file(self):
        if self.my_content_ready.find('/var/www/html/'):
            self.my_content_ready=self.my_content_ready.replace\
                                   ('/var/www/html/','/var/www/web188/html/')
        self.fourth_change_in_my_file()


    def fourth_change_in_my_file(self):
        if self.my_content_ready.find('localhost'):
            self.my_content_ready=self.my_content_ready.replace\
                                   ('localhost','crossoverguitar.weberanto.net')
        self.ask_new_file_exists()
      

    def ask_new_file_exists(self):
        if os.access(my_new_lin_path+self.my_filename, os.F_OK):
            my_answer=tkMessageBox.askyesno\
                 ("Warnung","Datei "+self.my_filename+" exisitert! ueberschreiben?") 
            if my_answer==1:
                self.write_new_file()
            else:
                tkMessageBox.showinfo\
                    ("Info","Datei "+self.my_filename+" wird uebersprungen!")
        else:
           self.write_new_file()
           

    def write_new_file(self):
        f=file(my_new_lin_path+self.my_filename,'w')
        f.write(self.my_content_ready)
        f.close()
        c=FtpUpload(self.my_filename)


        

class WindowForClassChange:

    
    def __init__(self):
         
        self.my_root=my_root=Tk()

        my_root.wm_geometry('+20+20')
        my_root.title("Window")
        my_root.resizable(0,0)
        my_root.protocol("WM_DELETE_WINDOW", self.mainexit)

        #Abstand der Elemente
        self.my_distance_x=5 #Abstand horizontal
        self.my_distance_y=5 #Abstand vertikal

        #Die Buttons bekommen alle dieselbe Breite
        self.my_width=20
   
        #Farbe wird auch von la verwendet
        self.my_color="#FFFFFF"
        self.my_label=Label(my_root,bg=self.my_color,text="///GARO_GUI")
        self.my_label.grid\
                (row=0,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)
      
        self.my_scrollbar_a=Scrollbar(self.my_root, orient="vertical")

        self.my_listbox_a=Listbox\
                (self.my_root,width=50,height=20,selectmode=MULTIPLE,yscrollcommand=self.my_scrollbar_a.set)
        
        self.my_scrollbar_a["command"]=self.my_listbox_a.yview
        self.my_scrollbar_a.grid(row=1,column=2,padx=self.my_distance_x,pady=self.my_distance_y)
        
        self.my_listbox_a.grid\
                (row=1,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)
        
        self.my_dir_index = [f for f in os.listdir(dir) if f.endswith('.py')] 
        self.my_dir_index.sort()

        for i in range(0,len(self.my_dir_index)):
   
            self.my_listbox_a.insert("end",(i+1,self.my_dir_index[i]))
        

        self.my_scrollbar_b=Scrollbar(self.my_root, orient="vertical")

        self.my_listbox_b=Listbox\
                (self.my_root,width=50,height=2,selectmode=MULTIPLE,yscrollcommand=self.my_scrollbar_b.set)
        
        self.my_scrollbar_b["command"]=self.my_listbox_b.yview
        self.my_scrollbar_b.grid(row=2,column=2,padx=self.my_distance_x,pady=self.my_distance_y)
        
        self.my_listbox_b.grid(row=2,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)
 
        self.my_button_1=Button(my_root,width=self.my_width,text="Start",\
                        command=self.auswerten)
        self.my_button_1.grid(row=3,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)

        self.my_button_2=Button(my_root,text="Prog. Beenden",width=10,\
                           command=self.ende)
        self.my_button_2.grid \
        (row=4,column=0,columnspan=2,padx=10,pady=10)

        #my_root.mainloop()


    def auswerten(self):
        self.my_choice=self.my_listbox_a.curselection()
        self.my_listbox_b.delete(0,END)
        if self.my_choice:
            b=ChangeContentForServer(self.my_choice,self.my_dir_index)
        else:
            tkMessageBox.showerror\
                    ("Fehler","Zuerst Datei(en) auswaehlen!")
       

    def ende(self):

        my_answer=tkMessageBox.askyesno\
                 ("Warnung","Sicher beenden?")
        if my_answer==1:
            sys.exit(0)
        

    def mainexit(self):
        self.my_root.withdraw()
        

if __name__=='__main__':

    if len(sys.argv) > 1:
        dir = sys.argv[1]
    else:
        dir = "."
    f=file('/var/www/cgi-bin/config.txt','r')
    my_conf=pickle.load(f)
    f.close()
    my_lin_path=my_conf['my_lin_path']
    my_new_lin_path=my_conf['my_new_lin_path']
    

    a=WindowForClassChange()
    mainloop()
   
    
nun:
1. ich habe keine möglichkeit gefunden, oder ich hab eins meiner berühmten bretter vorm kopf, der hochgeladenen datei, gleich die richtigen rechte zu verpassen. mit

Code: Alles auswählen

os.chmod()
ging es mal nicht,
2. ich verstehe nicht ganz, warum

Code: Alles auswählen

mainloop
an der stelle stehen muss, wo es zur zeit ist.
schreibe ich nämlich am ende des konstruktors;

Code: Alles auswählen

my_root.mainloop()
dann gibt es beim ftp upload die fehlermeldung, dass a nicht bekannt ist. und das geht mir net ganz ein, denn a wird ja global definiert. a muss ich ansprechen um in die untere listbox die entsprechende statusmeldung auszugeben.

die dinge hätte ich noch gern geklärt, ansonsten läuft es wie geschmiert und ich bin froh den ganzen sergel nicht mehr manuell machen zu müssen.

mfg

rolgal
BlackJack

Man sollte nie einfach nur 'except' schreiben. Dort landen dann alle Exceptions, auch solche, mit denen Du gar nicht rechnest. Das kann die Fehlersuche extrem erschweren.

Das Fortsetzen von Zeilen mit '\' ist generell Geschmackssache -- ich benutze zum Beispiel lieber Klammern. In 99% der Fälle wo Zeilen zu lang werden, hat man eh schon Klammern gesetzt. Das jemand die Argumente von der Funktion an der Stelle trennt, die Du häufig benutzt, habe ich ehrlich gesagt noch nie gesehen. Wie gesagt Geschmackssache, aber es sieht IMHO komisch aus.

Wieso ist FtpUpload eine Klasse? Das ist kein Java, es ist durchaus normal Funktionen auf Modulebene zu definieren.

Das gleiche gilt im Grunde für ChangeContentForServer. Das ist nur eine Ansammlung von Funktionen, die nacheinander ausgeführt werden. Wobei die Verkettung komisch ist und die Namen absolut nichtssagend. Wie ich gerade sehe benennst Du die Daten my_content_* auch immer geringfügig um.

Die erste Änderung sollte nicht nötig sein, wenn Du in den Skripten '#!/usr/bin/env python' als erste Zeile hast. Dann sollte der Python-Interpreter automatisch gefunden werden, wenn er im $PATH liegt.

Das zusammenfügen einer Liste mit Zeichenketten, so dass immer '\n' eingefügt wird, geht schneller mit '\n'.join(aList) als mit einer Schleife in der immer eine Zeichenkette an eine vorhandene angefügt wird.

Das 'a' nicht bekannt ist, wenn mainloop() im Konstruktor aufgerufen wird, liegt daran, dass zu dem Zeitpunkt das 'a' wirklich noch nicht existiert. Das wird an den Rückgabewert des Konstruktors gebunden, die __init__() kehrt aber nicht zurück wenn mainloop() aufgerufen wird.

Nachtrag: Kannst Du die ganzen Variablen Daten nicht in eine Konfigurationsdatei auslagern und die dann auf beiden Rechnern importieren/laden?
Gast

hallo blackjack,


Das Fortsetzen von Zeilen mit '\' ist generell Geschmackssache -- ich benutze zum Beispiel lieber Klammern. In 99% der Fälle wo Zeilen zu lang werden, hat man eh schon Klammern gesetzt. Das jemand die Argumente von der Funktion an der Stelle trennt, die Du häufig benutzt, habe ich ehrlich gesagt noch nie gesehen. Wie gesagt Geschmackssache, aber es sieht IMHO komisch aus.
ja stimmt, ich bin da am rumprobieren, meistens mache ich einfach irgendwo spontan einen '\'. sicher nicht die eleganteste lösung.

Wieso ist FtpUpload eine Klasse? Das ist kein Java, es ist durchaus normal Funktionen auf Modulebene zu definieren.
wirklich notwendig sind klassen sowieso ganz selten, allerdings verwende ich sie gerne um funktionen zusammenzufassen, die zusammengehören.
einfacher handzuhaben sind sie auch, gerade wenn man anordnungen austauscht oder eine hinzufügt usw.

bei ftpupload insofern sinnlos, als es bis jetzt nur den konstruktor gibt, sollte sich aber ändern.
Die erste Änderung sollte nicht nötig sein, wenn Du in den Skripten '#!/usr/bin/env python' als erste Zeile hast. Dann sollte der Python-Interpreter automatisch gefunden werden, wenn er im $PATH liegt.
tut er aber leider nicht, werden sie am webserver auch nicht ändern.
Das zusammenfügen einer Liste mit Zeichenketten, so dass immer '\n' eingefügt wird, geht schneller mit '\n'.join(aList) als mit einer Schleife in der immer eine Zeichenkette an eine vorhandene angefügt wird.
guter tipp, danke, werde ich bald umsetzen.

Nachtrag: Kannst Du die ganzen Variablen Daten nicht in eine Konfigurationsdatei auslagern und die dann auf beiden Rechnern importieren/laden?
gibt es da große vorteile, die ich nicht sehe?

mfg und vielen dank für deine anregungen

rolgal
BlackJack

Also das mit den Klassen ist echt ein Missbrauch des Klassenkonzepts. Um Funktionen zu gruppieren, die zusammengehören sind Module da. Klassen sollen in erster Linie Daten zusammenfassen und dann die Funktionen aufnehmen um diese zusammengefassten Daten zu manipulieren.

Mein Nachtrag ist vielleicht nicht ganz klar formuliert gewesen: Ich meinte damit, dass Du eine Datei anlegst, wo die ganzen Daten drinstehen, die Du mit Deinem Skript ersetzt. Da stehen bei Dir auf dem lokalen Rechner die Werte für den lokalen Rechner drin und auf dem Server die für den Server (Pfade etc.). Das Problem mit der ersten Zeile könntest Du lösen indem Du auf Deinem Rechner einen symbolischen Link auf den Python-Interpreter unter /usr/local/bin anlegst. Der Vorteil den ich dabei sehe ist, dass dieses Skript da oben dann nur noch den Upload erledigen muss und nichts mehr an den Skripten verändern braucht.

Noch ein Nachtrag zu den Variablennamen: Ohne es nachgeprüft zu haben sollte der Code auch ohne das Präfix 'my_' überall funktionieren. Das macht die Namen nur unnötig länger ohne wirklich Informationen für den Leser zu enthalten.
Gast

hallo,
Klassen sollen in erster Linie Daten zusammenfassen und dann die Funktionen aufnehmen um diese zusammengefassten Daten zu manipulieren.
ich finde das passiert auch. ich wollte kein modul, sondern allles in einer datei haben.
Mein Nachtrag ist vielleicht nicht ganz klar formuliert gewesen: Ich meinte damit, dass Du eine Datei anlegst, wo die ganzen Daten drinstehen, die Du mit Deinem Skript ersetzt. Da stehen bei Dir auf dem lokalen Rechner die Werte für den lokalen Rechner drin und auf dem Server die für den Server (Pfade etc.). Das Problem mit der ersten Zeile könntest Du lösen indem Du auf Deinem Rechner einen symbolischen Link auf den Python-Interpreter unter /usr/local/bin anlegst. Der Vorteil den ich dabei sehe ist, dass dieses Skript da oben dann nur noch den Upload erledigen muss und nichts mehr an den Skripten verändern braucht.
also abgesehen von der ersten zeile, wenn ich es richtig verstehe, dann wird das skript ja doch mehr tun als nur den upload erledigen, aber die daten, pfade usw. zusätzlich aus einer datei auslesen. oder hast du das doch anders gemeint?

zu my_
angefangen habe ich das, als ich einige male resevierte namen versehentlich verwendet habe. deutsche variablen , mit denen das viel seltener passieren kann wollte ich aber nicht. allerdings bin ich von der lösung auch nicht mehr so überzeugt.

mfg

rolgal
Gast

hallo nochmal,
Also das mit den Klassen ist echt ein Missbrauch des Klassenkonzepts.
das kann ich natürlich verantworten, hoffe kann mich mit der neuen version rehabilitieren :D
die verschiedensten aufgaben können egal ob mit oder ohne klasse auf jeden fall in eine funktion zusammengefasst werden. bei einer version mit klassen, würde ich nur noch die variablenzuweisungen in den konstruktor schreiben,

hier die version ohne klassen für den austausch und upload:

Code: Alles auswählen

#!/usr/bin/python


import sys, os, pickle, ftplib
from re import *
from Tkinter import*
from ScrolledText import*
import tkMessageBox




def upload(my_filename):
    try:
        my_conn=ftplib.FTP\
                 ('doamin','user','password')
        my_conn.cwd('/html/cgi-bin')
        my_conn.storbinary\
                 ('STOR %s' % my_filename, open(my_new_lin_path+my_filename, 'rb'))
        a.my_listbox_b.insert(0,"Sucess, "+my_filename+" saved und uploaded!")
    except:
        a.my_listbox_b.insert(0,"No connection, "+my_filename+" saved bot not uploaded")



def write_new_file(my_filename,my_content_ready):
    f=file(my_new_lin_path+my_filename,'w')
    f.write(my_content_ready)
    f.close()
    upload(my_filename)



def ask_new_file_exists(my_filename,my_content_ready):
    if os.access(my_new_lin_path+my_filename, os.F_OK):
        my_answer=tkMessageBox.askyesno\
             ("Warnung","Datei "+my_filename+" exisitert! ueberschreiben?") 
        if my_answer==1:
            write_new_file(my_filename,my_content_ready)
        else:
            tkMessageBox.showinfo\
                ("Info","Datei "+my_filename+" wird uebersprungen!")
    else:
       write_new_file(my_filename,my_content_ready)



def changecontent(my_choice,my_dir_index):
    for i in my_choice:
        
        my_filename=my_dir_index[int(i)]
        f=file(my_lin_path+my_filename,'r')
        my_content=f.read()
        f.close()

        my_content_new=my_content.replace\
                             ('#!/usr/bin/python','#!/usr/local/bin/python')
   

        my_content_list=my_content_new.splitlines()
        my_content_list.insert(1,"\n")
        my_content_list.insert(2,"import sys")
        my_content_list.insert\
                              (3,"sys.path.append('/var/www/web188/html/cgi-bin/module')")
    
        my_content_ready='\n'.join(my_content_list)
               

        if my_content_ready.find('/var/www/html/'):
            my_content_ready=my_content_ready.replace\
                                   ('/var/www/html/','/var/www/web188/html/')

        if my_content_ready.find('localhost'):
            my_content_ready=my_content_ready.replace\
                                   ('localhost','crossoverguitar.weberanto.net')
        ask_new_file_exists(my_filename,my_content_ready)


        

class WindowForClassChange:

    
    def __init__(self):
         
        self.my_root=my_root=Tk()

        my_root.wm_geometry('+20+20')
        my_root.title("Window")
        my_root.resizable(0,0)
        my_root.protocol("WM_DELETE_WINDOW", self.mainexit)

        #Abstand der Elemente
        self.my_distance_x=5 #Abstand horizontal
        self.my_distance_y=5 #Abstand vertikal

        #Die Buttons bekommen alle dieselbe Breite
        self.my_width=20
   
        #Farbe wird auch von la verwendet
        self.my_color="#FFFFFF"
        self.my_label=Label(my_root,bg=self.my_color,text="///GARO_GUI")
        self.my_label.grid\
                (row=0,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)
      
        self.my_scrollbar_a=Scrollbar(self.my_root, orient="vertical")

        self.my_listbox_a=Listbox\
                (self.my_root,width=50,height=20,selectmode=MULTIPLE,yscrollcommand=self.my_scrollbar_a.set)
        
        self.my_scrollbar_a["command"]=self.my_listbox_a.yview
        self.my_scrollbar_a.grid(row=1,column=2,padx=self.my_distance_x,pady=self.my_distance_y)
        
        self.my_listbox_a.grid\
                (row=1,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)
        
        self.my_dir_index = [f for f in os.listdir(dir) if f.endswith('.py')] 
        self.my_dir_index.sort()

        for i in range(0,len(self.my_dir_index)):
   
            self.my_listbox_a.insert("end",(i+1,self.my_dir_index[i]))
        

        self.my_scrollbar_b=Scrollbar(self.my_root, orient="vertical")

        self.my_listbox_b=Listbox\
                (self.my_root,width=50,height=2,selectmode=MULTIPLE,yscrollcommand=self.my_scrollbar_b.set)
        
        self.my_scrollbar_b["command"]=self.my_listbox_b.yview
        self.my_scrollbar_b.grid(row=2,column=2,padx=self.my_distance_x,pady=self.my_distance_y)
        
        self.my_listbox_b.grid(row=2,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)
 
        self.my_button_1=Button(my_root,width=self.my_width,text="Start",\
                        command=self.evaluate)
        self.my_button_1.grid(row=3,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)

        self.my_button_2=Button(my_root,text="Prog. Beenden",width=10,\
                           command=self.ende)
        self.my_button_2.grid \
        (row=4,column=0,columnspan=2,padx=10,pady=10)



    def evaluate(self):
        self.my_choice=self.my_listbox_a.curselection()
        self.my_listbox_b.delete(0,END)
        if self.my_choice:
            changecontent(self.my_choice,self.my_dir_index)
        else:
            tkMessageBox.showerror\
                    ("Fehler","Zuerst Datei(en) auswaehlen!")
       

    def ende(self):

        my_answer=tkMessageBox.askyesno\
                 ("Warnung","Sicher beenden?")
        if my_answer==1:
            sys.exit(0)
        

    def mainexit(self):
        self.my_root.withdraw()

        
        

if __name__=='__main__':

    if len(sys.argv) > 1:
        dir = sys.argv[1]
    else:
        dir = "."
    f=file('/var/www/cgi-bin/config.txt','r')
    my_conf=pickle.load(f)
    f.close()
    my_lin_path=my_conf['my_lin_path']
    my_new_lin_path=my_conf['my_new_lin_path']
    

    a=WindowForClassChange()
    mainloop()

      
    

gibts echt keine möglichkeit rechte nach dem ftp upload zu vergeben?
das nervt mich nämlich total!

mfg

rolgal
BlackJack

Ich meinte, dass Du die Daten wie '/var/www/web188/html/', 'crossoverguitar.weberanto.net' usw. in eine Konfugurationsdatei verlegen kannst und diese von Deinen CGI-Skripten einlesen lässt. Wenn Du dann noch auch dem Rechner, wo Du die Rechte dazu hast einen symbolischen Link auf den Python-Interpreter legst, so dass er dort erreichbar ist, wo er auf dem Webserver liegt, dann brauchst Du die Skripte nur noch hochladen ohne sie verändern zu müssen. Du musst nur lokal und auf dem Webserver die richtigen Einträge in der Konfigurationsdatei machen. Das kann entweder ein Python-Modul zum importieren sein, oder Du schaust Dir mal das Modul 'ConfigParser' an.

Mittlerweile hast Du alle Änderungen ja in einer Funktion zusammengelegt, aber ich wollte nochmal eine Begründung gegen das "verketten" von Funktionen nachliefern: Man kann dann einzelne Funktionen nicht testen. Ein Vorteil von Python ist der interaktive Interpreter in dem man einfach seine Module importieren kann und dann die Funktionen und Klassen "live" und einzeln ausprobieren kann.

Zum neuen Code:

Code: Alles auswählen

if my_content_ready.find('/var/www/html/'):
            my_content_ready=my_content_ready.replace\ 
                                   ('/var/www/html/','/var/www/web188/html/')
Die if-Abfrage ist zum einen überflüssig weil ein Ersetzen von einem nicht vorhandenen Text keinen Fehler verursacht. In dem Fall wird einfach nichts ersetzt und der Originaltext zurückgegeben. Ausserdem tut das 'if' nicht das was Du erwartest. Wenn der Suchtext nicht enthalten ist, dann gibt find() eine -1 zurück und das ist als Wahrheitswert betrachtet ein True.

Hier sind noch zwei Hilffunktionen, die vielleicht nützlich sind:

Code: Alles auswählen

def multi_replace(text, replacements):
    for old, new in replacements:
        text = text.replace(old, new)
    return text

def insert_after_first_line(text, insertion_text):
    split_pos = text.find('\n') + 1
    return text[:split_pos] + insertion_text + text[split_pos:]
Die erste führt mehrere Ersetzungen nacheinander durch und die zweite fügt Text nach der ersten Zeile ein ohne den gesamten Text in Zeilen zu zerlegen und hinterher wieder zusammenzufügen. Test:

Code: Alles auswählen

print multi_replace('foo bar', (('foo', 'frobnicate'),
                                ('bar', 'baz')))

text = ('#!/usr/bin/env python\n'
        '# The script starts here\n')

insertion = ('import sys\n'
             'sys.path.append("/var/www/web188/html/cgi-bin/module")\n')

print insert_after_first_line(text, insertion)
Ergibt:

Code: Alles auswählen

frobnicate baz
#!/usr/bin/env python
import sys
sys.path.append("/var/www/web188/html/cgi-bin/module")
# The script starts here
Gast

hi blackjack,

danke, werde ich gleich mal alles in ruhe durchgehen.

laden möchte ich die sachen nicht, da gefällt mir die idee mit dem skript schon besser.
die idee mit der zweiten funktion ( text.find('\n') + 1) hatte ich auch schon, aber mir kam es nicht so gut vor, aber offensichtlich war die idee gar net schlecht. ist sicherlich weniger aufwendig, als den ganzen text zu zerlegen und dann wieder zusammensetzen.

jedenfalls danke, dass du dich so viel mit der sache beschäftigt hast.

ach ja replacments - übergebe ich am besten ein dictionary, oder?

mfg

rolgal
Gast

hi blackjack,

ich glaube in das bestehende skript lassen sich deine ideen wie folgt am schnellsten integrieren:

Code: Alles auswählen

#!/usr/bin/python


import sys, os, pickle, ftplib
from re import *
from Tkinter import*
from ScrolledText import*
import tkMessageBox




def pickle_load(my_path):
    f=file(my_path,'r')
    my_result=pickle.load(f)
    f.close()
    return my_result
    



def upload(my_filename):
    try:
        my_conn=ftplib.FTP\
                 ('domain','user','pw')
        my_conn.cwd('/html/cgi-bin')
        my_conn.storbinary\
                 ('STOR %s' % my_filename, open(my_new_lin_path+my_filename, 'rb'))
        a.my_listbox_b.insert(0,"Sucess, "+my_filename+" saved und uploaded!")
    except:
        a.my_listbox_b.insert(0,"No connection, "+my_filename+" saved bot not uploaded")



def write_new_file(my_filename,my_content):
    f=file(my_new_lin_path+my_filename,'w')
    f.write(my_content)
    f.close()
    upload(my_filename)



def ask_new_file_exists(my_filename,my_content):
    if os.access(my_new_lin_path+my_filename, os.F_OK):
        my_answer=tkMessageBox.askyesno\
             ("Warnung","Datei "+my_filename+" exisitert! ueberschreiben?") 
        if my_answer==1:
            write_new_file(my_filename,my_content)
        else:
            tkMessageBox.showinfo\
                ("Info","Datei "+my_filename+" wird uebersprungen!")
    else:
       write_new_file(my_filename,my_content)



def changecontent(my_choice,my_dir_index):

    my_replacements=pickle_load('/var/www/cgi-bin/replacements.txt')
    my_replacements=my_replacements.items()
    for i in my_choice:
        
        my_filename=my_dir_index[int(i)]
        f=file(my_lin_path+my_filename,'r')
        my_content=f.read()
        f.close()


        for old, new in my_replacements:
            my_content = my_content.replace(old, new)

        insertion_text=('import sys\n'
             'sys.path.append("/var/www/web188/html/cgi-bin/module")\n')
        
        split_pos = my_content.find('\n') + 1
        my_content=my_content[:split_pos] + insertion_text + my_content[split_pos:]
          

        ask_new_file_exists(my_filename,my_content)

       

class WindowForClassChange:

    
    def __init__(self):
         
        self.my_root=my_root=Tk()

        my_root.wm_geometry('+20+20')
        my_root.title("Window")
        my_root.resizable(0,0)
        my_root.protocol("WM_DELETE_WINDOW", self.mainexit)

        #Abstand der Elemente
        self.my_distance_x=5 #Abstand horizontal
        self.my_distance_y=5 #Abstand vertikal

        #Die Buttons bekommen alle dieselbe Breite
        self.my_width=20
   
        #Farbe wird auch von la verwendet
        self.my_color="#FFFFFF"
        self.my_label=Label(my_root,bg=self.my_color,text="///GARO_GUI")
        self.my_label.grid\
                (row=0,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)
      
        self.my_scrollbar_a=Scrollbar(self.my_root, orient="vertical")

        self.my_listbox_a=Listbox\
                (self.my_root,width=50,height=20,selectmode=MULTIPLE,yscrollcommand=self.my_scrollbar_a.set)
        
        self.my_scrollbar_a["command"]=self.my_listbox_a.yview
        self.my_scrollbar_a.grid(row=1,column=2,padx=self.my_distance_x,pady=self.my_distance_y)
        
        self.my_listbox_a.grid\
                (row=1,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)
        
        self.my_dir_index = [f for f in os.listdir(dir) if f.endswith('.py')] 
        self.my_dir_index.sort()

        for i in range(0,len(self.my_dir_index)):
   
            self.my_listbox_a.insert("end",(i+1,self.my_dir_index[i]))
        

        self.my_scrollbar_b=Scrollbar(self.my_root, orient="vertical")

        self.my_listbox_b=Listbox\
                (self.my_root,width=50,height=2,selectmode=MULTIPLE,yscrollcommand=self.my_scrollbar_b.set)
        
        self.my_scrollbar_b["command"]=self.my_listbox_b.yview
        self.my_scrollbar_b.grid(row=2,column=2,padx=self.my_distance_x,pady=self.my_distance_y)
        
        self.my_listbox_b.grid(row=2,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)
 
        self.my_button_1=Button(my_root,width=self.my_width,text="Start",\
                        command=self.evaluate)
        self.my_button_1.grid(row=3,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)

        self.my_button_2=Button(my_root,text="Prog. Beenden",width=10,\
                           command=self.ende)
        self.my_button_2.grid \
        (row=4,column=0,columnspan=2,padx=10,pady=10)



    def evaluate(self):
        self.my_choice=self.my_listbox_a.curselection()
        self.my_listbox_b.delete(0,END)
        if self.my_choice:
            changecontent(self.my_choice,self.my_dir_index)
        else:
            tkMessageBox.showerror\
                    ("Fehler","Zuerst Datei(en) auswaehlen!")
       

    def ende(self):

        my_answer=tkMessageBox.askyesno\
                 ("Warnung","Sicher beenden?")
        if my_answer==1:
            sys.exit(0)
        

    def mainexit(self):
        self.my_root.withdraw()

        
        

if __name__=='__main__':

    if len(sys.argv) > 1:
        dir = sys.argv[1]
    else:
        dir = "."
        
    my_conf=pickle_load('/var/www/cgi-bin/config.txt')
    my_lin_path=my_conf['my_lin_path']
    my_new_lin_path=my_conf['my_new_lin_path']
    

    a=WindowForClassChange()
    mainloop()    
mfg

rolgal
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Also bei der länge eurer Quellcodes überlege ich ob ein nopaste Service nicht ganz ok wäre.. nur wie lange speichert so ein Service die Codes?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Gast

hi leonidas,...

was meinst du? ich kann dir net folgen.

mfg

rolgal
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich überlege grad ob es nicht sinnvoller wäre eure Codes in einen Nopaste Service [1] [2] auszulagern, damit die Posts nicht so lang werden.

[1] RAFB
[2] PHP/FI
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Gast

hi leonidas,...

ich kann mich ja zrückhalten und nur noch das posten, was sich geändert hat. die gui hätte ich mir z.b. sparen können.

vielleicht hilfts was.

kann man ja auch noch nachträglich rausnehmen per edit

mfg

rolgal
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ist ja nicht meine Datenbank, ich habe mir nur gedacht, das man ein bischen Resourcen schonen könnte. War aber nur ein Vorschlag!
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Gast

ja, wenn ich es tun soll, mach ich es, muss man mir halt nur sagen.

mfg

rolgal
Gast

hi blackjack,....

vielleicht guckste nochmal rein, die funktionen rufen sich nicht nacheinander auf, deshalb könnte man sie dann auch importieren in einem anderen kontext, ich glaube das hast du auch mal gemeint bzw. du würdest sie überhaupt in ein modul geben oder?

da ich mehrere guis habe, habe ich mir ein modul guis geschrieben und das führte zu den entsprechenden änderungen..
ich denke es ist jetzt ein schönes stück weiter:

Code: Alles auswählen

#!/usr/bin/python


import sys, os, pickle, ftplib
from guis import *




def pickle_load(my_path):
    f=file(my_path,'r')
    my_result=pickle.load(f)
    f.close()
    return my_result
    



def upload(my_filename):
    try:
        my_conn=ftplib.FTP\
                 ('domain','user','password')
        my_conn.cwd('/html/cgi-bin')
        my_conn.storbinary\
                 ('STOR %s' % my_filename, open(my_new_lin_path+my_filename, 'rb'))
        b.my_listbox_b.insert(0,"Sucess, "+my_filename+" saved und uploaded!")
    except:
        b.my_listbox_b.insert(0,"No connection, "+my_filename+" saved bot not uploaded")



def write_new_file(my_filename,my_content):
    f=file(my_new_lin_path+my_filename,'w')
    f.write(my_content)
    f.close()




def ask_new_file_exists(my_filename):
    my_test=os.access(my_new_lin_path+my_filename, os.F_OK)
    return my_test


def insert_text(my_content):
    insertion_text=('import sys\n'
     'sys.path.append("/var/www/web188/html/cgi-bin/module")\n')
    
    split_pos=my_content.find('\n')+1
    my_content=my_content[:split_pos]+insertion_text+my_content[split_pos:]
    return my_content
    


def changecontent(my_content,my_replacements):

    for old, new in my_replacements:
        my_content=my_content.replace(old, new)

    return my_content          



       

class WindowForClassChange(WindowForApps):

    
    def __init__(self):
        WindowForApps.__init__(self)
         
        my_root=self.my_root

 
        self.my_scrollbar_a=Scrollbar(self.my_root, orient="vertical")

        self.my_listbox_a=Listbox\
                (self.my_root,width=50,height=20,selectmode=MULTIPLE,yscrollcommand=self.my_scrollbar_a.set)
        
        self.my_scrollbar_a["command"]=self.my_listbox_a.yview
        self.my_scrollbar_a.grid(row=1,column=2,padx=self.my_distance_x,pady=self.my_distance_y)
        
        self.my_listbox_a.grid\
                (row=1,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)
        
        self.my_dir_index = [f for f in os.listdir(dir) if f.endswith('.py')] 
        self.my_dir_index.sort()

        for i in range(0,len(self.my_dir_index)):
   
            self.my_listbox_a.insert("end",(i+1,self.my_dir_index[i]))
        

        self.my_scrollbar_b=Scrollbar(self.my_root, orient="vertical")

        self.my_listbox_b=Listbox\
                (self.my_root,width=50,height=2,selectmode=MULTIPLE,yscrollcommand=self.my_scrollbar_b.set)
        
        self.my_scrollbar_b["command"]=self.my_listbox_b.yview
        self.my_scrollbar_b.grid(row=2,column=2,padx=self.my_distance_x,pady=self.my_distance_y)
        
        self.my_listbox_b.grid(row=2,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)
 
        self.my_button_1=Button(my_root,width=self.my_width,text="Start",\
                        command=self.evaluate)
        self.my_button_1.grid(row=3,column=0,columnspan=2,padx=self.my_distance_x,pady=self.my_distance_y)



    def evaluate(self):
        self.my_choice=self.my_listbox_a.curselection()
        self.my_listbox_b.delete(0,END)
        if self.my_choice:
            my_replacements=pickle_load('/var/www/cgi-bin/replacements.txt')
            my_replacements=my_replacements.items()
            
            for i in self.my_choice:
                
                my_filename=self.my_dir_index[int(i)]
                f=file(my_lin_path+my_filename,'r')
                my_content=f.read()
                f.close()
                
                my_content=changecontent(my_content,my_replacements)
                my_content=insert_text(my_content)
                
                my_test=ask_new_file_exists(my_filename)
                if my_test==True:
                    my_answer=tkMessageBox.askyesno\
                     ("Warnung","Datei "+my_filename+" exisitert! ueberschreiben?") 
                    if my_answer==1:
                        write_new_file(my_filename,my_content)
                    else:
                        tkMessageBox.showinfo\
                         ("Info","Datei "+my_filename+" wird uebersprungen!")
                else:
                    write_new_file(my_filename,my_content)
                upload(my_filename)

                        
        else:
            tkMessageBox.showerror\
             ("Fehler","Zuerst Datei(en) auswaehlen!")
       

        
        

if __name__=='__main__':

    if len(sys.argv) > 1:
        dir = sys.argv[1]
    else:
        dir = "."
        
    my_conf=pickle_load('/var/www/cgi-bin/config.txt')
    my_lin_path=my_conf['my_lin_path']
    my_new_lin_path=my_conf['my_new_lin_path']
    

    b=WindowForClassChange()
    mainloop()

        
        
    
wenn dir oder jmd. anderen noch was wichtiges auffällt, bitte wissen lassen, danke

mfg

rolgal
BlackJack

So auf die Schnelle fallen mir nur zwei Sachen auf:

Pickle-Daten sind Binärdaten (auch das alte "Text" Format) und sollten deshalb immer in Dateien geschrieben bzw. aus Dateien gelesen werden, die als Binärdateien geöffnet wurden, also mit 'wb' bzw. 'rb'. Nur mit 'w' bzw. 'r' funktioniert nur solange man die pickle-Daten immer nur unter dem gleichen Betriebssystem liest, unter denen sie auch gespeichert wurden.

Und in upload() ist immer noch ein ``except`` ohne eine Ausnahme, d.h. da wird jede Ausnahme behandelt als wenn es keine Verbindung gegeben hat. Zum Beispiel auch wenn es Probleme beim öffnen der Datei gab.
Gast

hi,...

Pickle-Daten sind Binärdaten (auch das alte "Text" Format) und sollten deshalb immer in Dateien geschrieben bzw. aus Dateien gelesen werden, die als Binärdateien geöffnet wurden, also mit 'wb' bzw. 'rb'. Nur mit 'w' bzw. 'r' funktioniert nur solange man die pickle-Daten immer nur unter dem gleichen Betriebssystem liest, unter denen sie auch gespeichert wurden.
gut, werde ich gleich mal ändern
Und in upload() ist immer noch ein ``except`` ohne eine Ausnahme, d.h. da wird jede Ausnahme behandelt als wenn es keine Verbindung gegeben hat. Zum Beispiel auch wenn es Probleme beim öffnen der Datei gab.
wie sollte das dann konkret aussehen?
mit try,except hatte ich es noch nie so ganz. aber wird auch noch werden :D

danke einstweilen

mfg

rolgal
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

rolgal hat geschrieben:
Und in upload() ist immer noch ein ``except`` ohne eine Ausnahme, d.h. da wird jede Ausnahme behandelt als wenn es keine Verbindung gegeben hat. Zum Beispiel auch wenn es Probleme beim öffnen der Datei gab.
wie sollte das dann konkret aussehen?
mit try,except hatte ich es noch nie so ganz. aber wird auch noch werden :D
Beispiel aus einem meiner aktuelleren Programme:

Code: Alles auswählen

try:
    station = parser()
    station.feed(station.pagecontent)
    tr = station.currenttrack().split(' - ', 1)
    self.model.set_value(iterator, 2, tr[0])
    self.model.set_value(iterator, 3, tr[1])
except whatsonair.IncompatibleParser:
    self.update.set_label('Update failed')
except IOError:
    self.update.set_label('Network error')
Damit wird die Ausnahme IOError anders behandelt als whatsonair.IncompatibleParser.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Gast

hi leonidas,....

würde es dann reichen, wenn ich z.b. schreibe
[/code]
except no_connection

Code: Alles auswählen


?

mfg rolgal
Antworten