Filesplitter

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Dein Programm macht ja munter weiter, wenn man bei der Eingabe von den „Megabyte“ keine Zahl eingibt :o
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Ich seh grad: Es gibt ein `tkinter.simpledialog.askinteger()`. Das ist super! Du brauchst erstens den String nicht noch in ein Integer umzuwandeln und zweitens: Wenn du keine Zahl eingibst, dann wird der Benutzer darauf hingewiesen und er muss die Zahl dann nochmal eintippen.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

EyDu hat geschrieben:Das soll auch dein Script bleiben, aber die Vorschläge sind alle sinnvolle Änderungen. Du kannst sie also nutzen und daraus lernen oder du produzierst weiter gruseligen Code.
Ich hab mich doch noch entschlossen das Programm noch mal mehr oder weniger neu zu schreiben, was den GUI betrifft.

@nomnom Danke für den Tipp.
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

So noch mal neu, Modul getrennt vom GUI.
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Kann man in den Pastebin auch Dateien wie z. B. Icons Hochladen?
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Py-Prog hat geschrieben:Kann man in den Pastebin auch Dateien wie z. B. Icons Hochladen?
Ne, dazu kannst du z.B. bitbucket oder github verwenden.
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Du kannst das Icon auch als base64 kodieren und dann den Text in nem pastebin hochladen.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Da kann ich auch das Icon bei GMX Hochladen, und freigeben.

Gibt's da jetzt nichts auszusetzen oder seit ihr noch beim suchen?
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
BlackJack

@Py-Prog: Nur mal so kurz drüber geschaut:

Schau Dir mal `os.path.split()` an.

Du liest immer noch die ganze aufzuteilende Datei komplett in den Speicher. Mach das mal mit einem DVD-Image. ;-)

Ich würde die auf einen Schlag eingelesene Datenmenge ja mindestens auf die Grösse der einzelnen Ausgabedateien beschränken.

Wenn Du schon die ganze Datei in den Speicher liest, dann weisst Du auch wie viele Bytes und damit auch wieviele Blöcke Du speichern musst, also kann man die ``while True``-Schleife durch eine ``for``-Schleife ersetzen.

In dieser Schleife ist die Unterscheidung ob es sich um den letzten, möglicherweise nicht mehr ganz "vollen" Block handelt, überflüssig. Probier einfach mal aus was beim "slicing" passiert wenn die Endangabe grösser als die Länge der Zeichenkette ist.

`helplist` ist ein unschöner Name der nicht wirklich darüber informiert was die Liste enthält oder wofür sie da ist. Das gleiche gilt für die '.help'-Dateiendung. Und warum ist in dem Dateinamen das "help" doppelt drin?

Überleg Dir mal was mit Dateinamen passiert, die einen Zeilenumbruch enthalten.

`os.chdir()` hat in Programmen im Grunde nichts zu suchen. Ist hier ja auch überflüssig.

Statt die Datei mit den Teilnamen komplett einzulesen und dann das erste Element zu löschen, könnte man die auch einfach zeilenweise einlesen und verarbeiten.

Bei der GUI importierst Du `filesplitter` zweimal.

Dieses hochzählen von `canmake` ist ziemlich undurchsichtig, da sollte man lieber ordentlich benannte Wahrheitswerte verwenden oder es so umschreiben, dass man diese Abfrage(n) gar nicht benötigt. Statt `isfile()` und `isdir()` kann man auch einfach loslegen und auf die Ausnahmen entsprechend reagieren.

Pro laufendem Programm darf es nur ein Exemplar von `Tk` geben. Ansonsten kann bis zu einem harten Programmabsturz alles mögliche passieren. Zusätzliche Fenster zum Hauptfenster kann man mit `Toplevel` erstellen.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

@BlackJack immerhin hast du gesagt das mit dem Abzählen ist keine Gute Idee.
Nun zu dem mit helplist, wenn ich nur 79 Zeichen Pro Zeile haben darf, kann ich schlecht einer Variable einen Namen mit einer Zeichen Länge von 20 zuweisen. Welche namen wären nach deiner sicht sinnvoll? liste_mit_informationen_fuer_datei_zusammensetzung?
Und was ist Toplevel? Ein Modul? Bei mir hat das noch nie ein Problem gegeben.
Und wieso sollte ein Dateiname einen Zeilen Umbruch haben?
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Py-Prog hat geschrieben:Und wieso sollte ein Dateiname einen Zeilen Umbruch haben?

Code: Alles auswählen

 /tmp% touch 'foo
bar'
/tmp% ls -l 'foo
bar'
-rw-r--r--  1 simon  wheel  0 11 Dez 14:21 foo?bar
Mein Dateisystem ist HFS+ (siehe in der Tabelle rechts "Erlaubte Zeichen im Dateinamen")
BlackJack

@Py-Prog: `filepart_info` wäre zum Beispiel ein Name der aussagt was die Liste enthält.

Wenn ich sage dass Du statt `Tk` `Toplevel` verwenden musst, dann könntest Du ja mal überlegen was `Tk` ist und wo das herkommt und daraus schliessen das es wahrscheinlich auch ein Widget ist und ebenfalls in `tkinter` zu finden ist. Das *Du* damit noch keine Probleme hattest, heisst nicht, dass das Programm bei jedem fehlerfrei läuft. Nicht einmal dass es das bei Dir *immer* tut.

Wieso sollte ein Dateiname keinen Zeilenumbruch enthalten?
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

BlackJack hat geschrieben:Du liest immer noch die ganze aufzuteilende Datei komplett in den Speicher. Mach das mal mit einem DVD-Image. ;-)

Ich würde die auf einen Schlag eingelesene Datenmenge ja mindestens auf die Grösse der einzelnen Ausgabedateien beschränken.
Die letzten Wochen hatte ich nicht so viel Zeit und konnte nicht weiter machen, aber jetzt bin ich dazu gekommen. Beim Versuch eine 1,25 GB Große Datei zu öffnen kam ein Fehler. Und jetzt würde mich interessieren wie du von eine Datei die ersten 512 MiB einlesen willst? Zeilen weile brauch ist erst gar nicht versuchen weil eine Datei keine Zeilenumbrüche haben muss.

Werd ich's wohl jemals fertig bringen?
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
BlackJack

@Py-Prog: Schau Dir doch einfach mal die Dokumentation zu den Methoden an, die Datei-Objekte so haben.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Manchmal frag ich mich echt wieso ich mir eigentlich eine Referenz gekauft habe. Wenn ich da mal besser lesen würde, hätte ich schon einige Antworten auf meine Fragen gefunden. :oops: :oops: :oops:
Ich werd mich dann mal an die Arbeit machen.

(Und wenn ich fertig bin wundert euch nicht wenn eine Datei die Vorher einen Zeilen Umbruch hatte danach keinen mehr hat. Sorry aber das muss sein.)
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

So BlackJack, jetzt kannst du dein DVD-Image splitten! :D
Modul und GUI

Also die Hauptsächlichen Änderungen sind, das die Dateiendung nicht mehr angezeigt wird und die datei wird auch nicht komplett gelesen. Zeilen Umbrüche in den Dateinamen werden Gelöscht, weil im helpfile der Dateiname nur in die Erste Zeile stehen darf, ich hoffe das ist zu verschmerzen.
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Jetzt muss ich noch eine funktion schreiben die aus der Helpdatei eine Batch datei erzeugt die das wieder zusammenfügt.
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Das Neue Modul

Code: Alles auswählen

import os.path

def create_batch_file(path, end_path):
    with open(path, 'r') as helpfile:
        info=helpfile.readlines()
        name=info[0].replace('\n', ''); del info[0]
        batch_file_text='COPY /B '
        for filename in info:
            batch_file_text+='"'+filename.replace('\n', '')+'" '
            if filename!=info[len(info)-1]:
                batch_file_text+='+'
            else:
                batch_file_text+=' '+name
    with open(os.path.join(end_path, name+'.bat'), 'w') as batchfile:
        batchfile.write(batch_file_text)

def split(path, size, batchfile=False, end_path=None):
    path_name_list=os.path.split(path)
    directory=path_name_list[0]
    name=path_name_list[1].replace('\n', '')
    if end_path is None:
        end_path=directory
    count=0
    with open(path, 'rb') as f:
        filesize=os.path.getsize(path)
        filepart_info=[name.replace('/', '')+'\n']
        name=os.path.splitext(name)[0] #Löscht die endung des Dateinamen
        while True:
            if ((count*size)+size)>filesize:
                filepart_info.append((name+str(count)+'.spl\n'))
                with open(os.path.join(end_path, name+str(count)+'.spl'), 'wb') as splitfile:
                    splitfile.write(f.read(size))
                    break
            else:
                filepart_info.append(name+str(count)+'.spl\n')
                with open(os.path.join(end_path, name+str(count)+'.spl'), 'wb') as splitfile:
                    splitfile.write(f.read(size))
                    count+=1
                    f.seek(count*size)
    with open(os.path.join(end_path, name+'.help'), 'w') as helpfile:
        helpfile.writelines(filepart_info)
    if batchfile==True:
        create_batch_file(os.path.join(end_path, name+'.help'), end_path)

def join(path, end_path=None):
    if end_path is None:
        end_path=path
    with open(path, 'r') as helpfile:
        info=helpfile.readlines()
    with open(os.path.join(os.path.split(path)[0], info[0][0: len(info[0])-1]), 'wb') as unsplitfile:
        del info[0] #Löscht den Dateinamen aus der liste
        for datei in info:
            datei=datei[0: len(datei)-1]
            with open(os.path.join(end_path.replace('/', '\\'), datei), 'rb') as splitfile:
                unsplitfile.write(splitfile.read())



Der Neue GUI

Code: Alles auswählen

import tkinter
import tkinter.ttk
import tkinter.filedialog
import tkinter.messagebox
import os.path
import filesplitter

def split_window():
    def quelle_suchen():
        quelle=tkinter.filedialog.askopenfilename()
        quelle_entry.delete(0, 'end')
        quelle_entry.insert(0, quelle)
        ziel_entry.delete(0, 'end')
        ziel_entry.insert(0, os.path.dirname(quelle))
    def ziel_suchen():
        ziel=tkinter.filedialog.askdirectory()
        ziel_entry.delete(0, 'end')
        ziel_entry.insert(0, ziel)
    def umrechnen():
        bytetranslater={'Bytes': 0, 'Kibibytes': 10, 'Mebibytes': 20, 'Gibibytes': 30}
        inbytes=int(float(groesse_entry.get().replace(',', '.'))*2**bytetranslater[einheit_combobox.get()])
        return inbytes
    def make_split_file():
        try:
            filesize=umrechnen()
        except ValueError:
            tkinter.messagebox.showerror('Fehler', 'Geben sie eine Zahl ein!')
        except KeyError:
            tkinter.messagebox.showerror('Fehler', 'Wählen sie eine Einheit aus!')
        else:
            try:
                filesplitter.split(quelle_entry.get(), filesize, tkinter.messagebox.askyesno('Filesplitter', 'Soll eine Batchdatei erstellt werden?'), ziel_entry.get())
            except IOError:
                tkinter.messagebox.showerror('Fehler', 'Die Datei könnte nicht gesplittet werden!')

    split_window=tkinter.Toplevel()
    split_window.title('Filesplitter  Split')
    quelle_label=tkinter.Label(split_window, text='Quelle: ')
    quelle_label.grid(row=0, column=0)
    quelle_entry=tkinter.Entry(split_window, width=70)
    quelle_entry.grid(row=0, column=1)
    quelle_button=tkinter.Button(split_window, text='...', command=quelle_suchen)
    quelle_button.grid(row=0, column=2)
    ziel_label=tkinter.Label(split_window, text='Ziel: ')
    ziel_label.grid(row=1, column=0)
    ziel_entry=tkinter.Entry(split_window, width=70)
    ziel_entry.grid(row=1, column=1)
    ziel_button=tkinter.Button(split_window, text='...', command=ziel_suchen)
    ziel_button.grid(row=1, column=2)
    tkinter.Label(split_window).grid(row=2) #Erzeugt eine Leerzeile
    groesse_label=tkinter.Label(split_window, text='Größe: ')
    groesse_label.grid(row=3, column=0)
    groesse_entry=tkinter.Entry(split_window, width=70)
    groesse_entry.grid(row=3, column=1)
    einheit_label=tkinter.Label(split_window, text='Einheit: ')
    einheit_label.grid(row=4, column=0)
    einheitvar = tkinter.StringVar()
    einheit_combobox = tkinter.ttk.Combobox(split_window, textvariable=einheitvar, state='readonly')
    einheit_combobox['values'] = ('Bytes', 'Kibibytes', 'Mebibytes', 'Gibibytes')
    einheit_combobox.set('Mebibytes')
    einheit_combobox.grid(row=4, column=1)
    tkinter.Button(split_window, text='Splitten', command=make_split_file).grid(row=5, column=1)
    
def join_window():
    def infodatei_suchen():
        types=[('Informationsdatei',"*.help")]    
        infodatei=tkinter.filedialog.askopenfilename(filetypes=types)
        infodatei_entry.delete(0, 'end')
        infodatei_entry.insert(0, infodatei)
        ziel_entry.delete(0, 'end')
        ziel_entry.insert(0, os.path.dirname(infodatei))
    def ziel_suchen():
        ziel=tkinter.filedialog.askdirectory()
        ziel_entry.delete(0, 'end')
        ziel_entry.insert(0, ziel)
    def zusammenfügen():
        if os.path.isfile(infodatei_entry.get()) and os.path.isdir(ziel_entry.get()):
            try:
                filesplitter.join(infodatei_entry.get(), ziel_entry.get())
            except IOError:
                tkinter.messagebox.showerror('Fehler', 'Die Datei konnte nicht zusammen gefügt werden!')
        else:
            tkinter.messagebox.showerror('Fehler', 'Die angegebenen Pfäde sind nicht richtig eingegeben!')
    join_window=tkinter.Toplevel()
    join_window.title('Filesplitter  Join')
    infodatei_label=tkinter.Label(join_window, text='Infodatei: ')
    infodatei_label.grid(row=0, column=0)
    infodatei_entry=tkinter.Entry(join_window, width=70)
    infodatei_entry.grid(row=0, column=1)
    infodatei_button=tkinter.Button(join_window, text='...', command=infodatei_suchen)
    infodatei_button.grid(row=0, column=2)
    ziel_label=tkinter.Label(join_window, text='Ziel: ')
    ziel_label.grid(row=1, column=0)
    ziel_entry=tkinter.Entry(join_window, width=70)
    ziel_entry.grid(row=1, column=1)
    ziel_button=tkinter.Button(join_window, text='...', command=ziel_suchen)
    ziel_button.grid(row=1, column=2)
    tkinter.Button(join_window, text='Zusammenfügen', command=zusammenfügen).grid(row=2, column=1)

window=tkinter.Tk()
window.title('Filespliter')
window.geometry('500x30')
menubar=tkinter.Menu(window)
menu=tkinter.Menu(menubar)
menu.add_command(label='Splitten', command=split_window)
menu.add_command(label='Zusammenfügen', command=join_window)
menu.add_separator()
menu.add_command(label='Beenden', command=exit)
menubar.add_cascade(label='Datei', menu=menu)
window.config(menu=menubar)
tkinter.Label(window, text='Mit diesem Programm kann man Dateien Splitten und wieder zusammenfügen.').place(relx=0.2, rely=0.3)
tkinter.mainloop()

Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Filesplitter 1.8

Nur mal so:
wenn ich da schreibe

Code: Alles auswählen

string=string[0: len(string)-1]
könntet ihr auch mal sagen dass das auch so geht:

Code: Alles auswählen

string=string[: -1]
Und das beim entpacken in einem anderen Verzeichnis, die Datei immer noch im Gleichen Ordner landet, wie die spl Dateien. Ist jetzt aber alles verbessert und jetzt kann man auch einen Pfad eingeben der gar nicht existiert, der wird dann (falls möglich) erstellt. Natürlich nur bei Ziel.
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Antworten