Fotos von Kamera laden und sortieren

Du hast eine Idee für ein Projekt?
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.
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

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 ?
iScream
User
Beiträge: 11
Registriert: Samstag 25. Juli 2009, 11:15

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 ;)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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.
Das Leben ist wie ein Tennisball.
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

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:
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

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
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

- 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.
Das Leben ist wie ein Tennisball.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

EyDu hat geschrieben:- file nicht zu überschreiben
:oops:

bei der sprache war ich einfach zu faul :D
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.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

man lernt nie aus
iScream
User
Beiträge: 11
Registriert: Samstag 25. Juli 2009, 11:15

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
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

Allerdings ist das immernochnicht das, was du wolltest.
Die Bilder werden nämlich nicht nach dem Aufnahmedatum einsortiert!
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

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. :)
Antworten