Seite 2 von 2

Verfasst: Montag 3. August 2009, 19:03
von BlackJack
@iScream: Du hast das Falsche verschwinden lassen. Der Code sollte in eine Funktion, die dann in der ``if __name__``-Überprüfung aufgerufen wird.

``global`` sollte man grundsätzlich meiden. Wenn Du nicht weisst wie man mit Funktionen arbeitet, solltest Du wirklich mal das Tutorial in der Python-Dokumentation durcharbeiten.

Wieso weisst Du nicht, wie Du ohne das Arbeitsverzeichnis zu wechseln an die Bilder kommst? Du *tust* das doch sogar schon für das Zielverteichnis, weil man ja immer nur in einem Arbeitsverzeichnis gleichzeitig sein kann.

Für das `capturedate` würde ich nicht die `str()`-Repräsentation von dem `date`-Objekt nehmen, sondern dessen `strftime()`-Methode. Dann kannst Du auch gleich Unterstriche einsetzen, und musst die nicht hinterher ersetzen.

Ein ``except`` ohne eine konkrete Ausnahme in dem dann auch noch einfach gar nichts gemacht wird, ist keine gute Idee. Damit kann man Fehlersituationen "maskieren", nach denen man sich im Ernstfall dumm und dusselig sucht, weil man wichtige Informationen einfach nicht bekommt.

@Pascal: Bei `os.chdir()` muss man *programmweit* immer aufpassen, dass man an jeder Stelle weiss, welches Verzeichnis zur Laufzeit das Aktuelle an dieser Stelle ist. Spätestens wenn man das auch in Bibliotheken macht, oder mehrere Threads benutzt, wird so ein Programm unwartbar. Schon bei bedingten Verzweigungen kann es unübersichtlich werden, weil man für jeden möglichen Auführungspfad sicherstellen muss, das die Verzeichniswechselei richtig läuft und nicht irgendwo mal "übergangen" wird.

Verfasst: Montag 3. August 2009, 20:12
von Pascal
BlackJack hat geschrieben: @Pascal: Bei `os.chdir()` muss man *programmweit* immer aufpassen, dass man an jeder Stelle weiss, welches Verzeichnis zur Laufzeit das Aktuelle an dieser Stelle ist. Spätestens wenn man das auch in Bibliotheken macht, oder mehrere Threads benutzt, wird so ein Programm unwartbar. Schon bei bedingten Verzweigungen kann es unübersichtlich werden, weil man für jeden möglichen Auführungspfad sicherstellen muss, das die Verzeichniswechselei richtig läuft und nicht irgendwo mal "übergangen" wird.
Gut, das seh ich ein.
bei shutil.copy müsste man dann allerdings (START+'/pic.jpg' , ZIEL) angeben. Dann geht das auch. (Das war nämlich mein Problem, deswegen der Verzeichnis wechsel)

Und noch eine Frage hinterher:
Wäre shutil.copy2 nicht eigentlich besser geeignet?
Oder shutil.move ?

Verfasst: Montag 3. August 2009, 20:19
von iScream
Bitte erklärt das nochmal genauer, ich verstehe es leider noch nicht ganz.
Das Programm soll also mit "if __name__" aufgerufen werden?
Es sollte nur aus einer Funktion bestehen?!

Das except sollte zunächst auch nur zur Maskierung dienen. Arbeite ich noch dran ;)

Verfasst: Montag 3. August 2009, 20:51
von EyDu

Code: Alles auswählen

#deine Funktionen hier

def main():
    #hier dein Code, der auch die Funktionen auruft

if __name__ == "__main__":
    main()
Dann wird sichergestellt, dass die "main"-Funktion nur dann ausgeführt wird, wenn die Datei ausgeführt wird. Wird nur das Modul importiert, dann passiert nichts.

@Pascal:
Pascal hat geschrieben:bei shutil.copy müsste man dann allerdings (START+'/pic.jpg' , ZIEL) angeben
Nein, dann möchtest du "os.path.join" benutzen.

Verfasst: Montag 3. August 2009, 20:58
von Pascal
ich habe mal probiert das os.chdir() zu vermeiden
Das Programm ist jetzt allerdings noch ungetestet (Hatte keine passende Verzeichnisse)

Code: Alles auswählen

import shutil
import os
import datetime
from tkFileDialog import askdirectory 

print 'Startverzeichnis wählen:'
start=askdirectory()

print 'Zielverzeichnes wählen:'
ziel=askdirectory()

print 'Alle gefundenen Bilder in %s werden nach %s kopiert' %(start, ziel)

print 'Sollen die Bilder nach dem kopieren aus dem Startverzeichnis gelöscht werden? (Y oder N)'
bilder_loeschen=raw_input()
d={'Y':True, 'N': False}
try:
     bilder_loeschen=d[bilder_loeschen]
except KeyError:
     print 'Du Idiot! Nur Y oder N eingeben'
    #raise SystemExit('Selber Schuld! (Gib beim nächsten Mal Y oder N ein!)')


bilder=[]
for dat in os.listdir(start):
     if dat[:-4] in ['.jpg', '.JPG', '.gif', '.png', '.bmp']:
          bilder.append(dat)

#ordner erstellen und kopieren

for bild in bilder:
     aufnahme=str(datetime.date.fromtimestamp(os.path.getatime(bild)))
     
     if not os.path.isdir(os.path.join(ziel, aufnahme)):
          os.mkdir(os.path.join(ziel, aufnahme))

     shutil.copy(os.path.join(start, bild), os.path.join(ZIEL, aufnahme))
     
     if bilder_loeschen:
          os.remove(os.path.join(start, bild))
          print bild, 'wurde nach ', aufnahme, 'verschoben'
     else:
          print bild, 'wurde nach ', aufnahme, 'kopiert'
     

print 
print 'Vorgang abgeschlossen'
Ich hoffe ich hab nichts übersehen :roll:

Verfasst: Montag 3. August 2009, 21:25
von jbs

Code: Alles auswählen

import shutil
import os
import datetime
from tkFileDialog import askdirectory
from tkMessageBox import askyesno

def movefiles(from_, to, keepold=False):
	print 'Alle gefundenen Bilder in %s werden nach %s kopiert' %(start, ziel)
	for file in os.listdir(from_):
		if filter( file.lower().endswith, ['.jpg', '.gif', '.png', '.bmp'])
			#ist das so sinnvoll?
			aufnahme=str(datetime.date.fromtimestamp(os.path.getatime(file)))
			
			try:
				os.mkdir(os.path.join(to, aufnahme))
			except OSError, error:
				if error.errno !=17:
					raise
			if keepold:
				shutil.copy(os.path.join(from_, file), os.path.join(to, aufnahme))
				print bild, 'wurde nach ', aufnahme, 'kopiert'
			else:
				shutil.move(os.path.join(from_, file), os.path.join(to, aufnahme))
				print bild, 'wurde nach ', aufnahme, 'verschoben'



def main():
	#wieso nochmal schreiben wenn per gui gefragt wird?
	print 'Startverzeichnis wählen:'
	start=askdirectory()

	print 'Zielverzeichnes wählen:'
	ziel=askdirectory()
	
	movefiles(start, ziel, askyesno('Achtung', 'remove old?'))
	print 'Vorgang abgeschlossen' 

if __name__ == '__main__':
	main()
ich habe es mal etwas bereinigt, ist aber auch noch etwas verbesserungswürdig

Verfasst: Montag 3. August 2009, 21:39
von EyDu
- zum Beispiel nur eine Sprache verwenden
- file nicht zu überschreiben
- und

Code: Alles auswählen

if keepold:
    shutil.copy(os.path.join(from_, file), os.path.join(to, aufnahme))
else:
    shutil.move(os.path.join(from_, file), os.path.join(to, aufnahme))
als

Code: Alles auswählen

action = shutil.copy if keepod else shutil.move
action(os.path.join(from_, file), os.path.join(to, aufnahme))
Sonst sind es ja nur noch sehr kleine Kleinigkeiten.

Verfasst: Montag 3. August 2009, 21:58
von jbs
EyDu hat geschrieben:- file nicht zu überschreiben
:oops:

bei der sprache war ich einfach zu faul :D

Verfasst: Montag 3. August 2009, 22:57
von BlackJack
Ich habe auch mal etwas (ungetestetes) gehackt:

Code: Alles auswählen

#!/usr/bin/env python
from __future__ import division, with_statement
import errno
import os
import shutil
from datetime import date as Date
from tkFileDialog import askdirectory


def is_jpg(filename):
    return filename.lower().endswith('.jpg')


def iter_jpg_names(path):
    return (os.path.join(path, f) for f in os.listdir(path) if is_jpg(f))


def copy_file(source_path, target_path):
    date = Date.fromtimestamp(os.path.getatime(source_path))
    full_target_path = os.path.join(target_path, date.strftime('%Y_%m_%d'))
    try:
        os.mkdir(full_target_path)
    except OSError, error:
        if error.errno != errno.EEXIST:
            raise
    shutil.copy(source_path, full_target_path)


def main():
    source_path = askdirectory()
    target_path = askdirectory()
    for jpg_filename in iter_jpg_names(source_path):
        copy_file(jpg_filename, target_path)
        print '%r wurde nach %r kopiert' % (jpg_filename, full_target_path)
    print 'Vorgang abgeschlossen.'


if __name__ == '__main__':
    main()
@jbs: So umgeht man die "magische" 17 für den Fall, dass der Pfad schon existiert.

Verfasst: Dienstag 4. August 2009, 12:37
von jbs
man lernt nie aus

Verfasst: Dienstag 4. August 2009, 22:00
von iScream
Hey ;)

Es gibt sicher noch Verbesserungmöglichkeiten am Code, doch er übertrifft jetzt schon meine Erwartungen an Komfort und Funktionalität bei weitem :wink:

Ich möchte euch allen danken, dass ihr euch soviel Zeit genommen habt. Ich habe viel Neues gelernt und einen gut funktionierendes Skript, was mich von einer weiteren Windows-Software erlöst und mich somit Linux näher bringt ;)


lg,
iScream

Verfasst: Dienstag 4. August 2009, 22:49
von Pascal
Allerdings ist das immernochnicht das, was du wolltest.
Die Bilder werden nämlich nicht nach dem Aufnahmedatum einsortiert!

Verfasst: Mittwoch 5. August 2009, 12:35
von mkesper
iScream: Hast du schon von digikam gehört? Ist eine komplette Fotoverwaltung mit Bewertung, Tagging, mächtigen Plugins etc. und läuft unter GNU/Linux. Ein echter Grund zum Wechseln. :)