-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I use the following python script to copy pictures from my digital camera to my picture bank. It copies files to folders based on creation date (eg 2010/01-January/24. January/Picture.jpg). It also handles duplicate file names. I'm not sure if it can help you. Note: you might want to change to month names back to english, ref line 55.
Regards Stein #!/usr/bin/python3 # Filename sortImg2Folder.py # Move images og files to folders based on creation time. # Folder format example: 2010/05-May 2010/filename.jpg # It uses exiv2 or mtime to determine folder structure. # Version: 0.9 # # Copyright 2010 Stein Erik Gullvik [email protected] # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # Notes: # Will use EXIV2 if installed. (pyexif not yet # ported to python3). # #TODO #Various, see TODOs in file #Command line option to parse file name for creation date import os import datetime from shutil import move #from subprocess import getstatusoutput import subprocess import re #TODO Needed? Posibly to run piped bash commands... #Variable setup SearchDir = os.curdir #Current dir DestFolderTop = "/home/stein/Bilder/sortert/" #trailing / optional Year = "" Month = "" MonthNumber = "" Day = "" UseExiv2 = False # # Functions # def MonthNrToMonth(month): #print("MonthNrToMonth", month) if int(month) > 12: quit("Fatal error: month larger that 12") Months = ["Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"] return Months[int(month)-1] def ProcessFolder(folder): '''Process files in folder, if file process is folder reprocess new folder''' for file in os.listdir(folder): if os.path.isfile(os.path.abspath(os.path.join(folder, file))): ProcessFile(folder, file) if os.path.isdir(file): ProcessFolder(file) def ProcessFile(folder, file): #mv file, check that file does not exists #Which file to move, list extension: jpg, 3gp, gif case insensitiv FindCreationDate(os.path.abspath(os.path.join(folder, file))) #print("filename " + os.path.abspath(os.path.join(folder, file))) CheckValidName(os.path.abspath(os.path.join(folder, file))) #Sanity check folder names NewFolder = Year CreateFolder(NewFolder) NewFolder = NewFolder + os.sep + MonthNumber + "-" + Month CreateFolder(NewFolder) NewFolder= NewFolder + os.sep + Day + "-" + Month + " " + Year CreateFolder(NewFolder) #Move file if not exists in target folder if os.path.exists(os.path.abspath(os.path.join(DestFolderTop, NewFolder, file))) == False: move(os.path.abspath(os.path.join(folder, file)), os.path.normpath(os.path.join(DestFolderTop, NewFolder))) else: #Split extension from filname root, ext = os.path.splitext(file) n=1 #Try with new filename running = True while running == True: NewFilname = root + "-" + format(n) + ext if os.path.exists(os.path.abspath(os.path.join(DestFolderTop, NewFolder, NewFilname))) == True: n += 1 if n > 99: #If more that 99 tries, abort this file and resume next file. print("Error: File:", os.path.abspath(os.path.join(DestFolderTop, NewFolder, NewFilname)), "exists! Didn't mv file") running = False else: move(os.path.abspath(os.path.join(folder, file)), os.path.normpath(os.path.join(DestFolderTop, NewFolder, NewFilname))) running = False def CreateFolder(NewFolder): #TODO error handler #Check if folder exists or create if os.path.exists(os.path.join(DestFolderTop, NewFolder)) == False: #Create folder name based on date os.mkdir(os.path.join(DestFolderTop, NewFolder)) def FindCreationDate(file): #Determine creation date def useMtime(file): global Year, Month, MonthNumber, Day mtime = datetime.datetime.fromtimestamp(os.path.getmtime(file)) Year = Month = MonthNumber = Day = "" #Zerorize Year = mtime.strftime("%Y") MonthNumber = mtime.strftime("%m") Month = MonthNrToMonth(MonthNumber) #Manually get month, strftime only has english names... #Month = mtime.strftime("%B").title() #title(): Uppercase first letter Day = mtime.strftime("%d") def useExiv(file): global Year, Month, MonthNumber, Day root, ext = os.path.splitext(file) #For the time being, only process exiv2 with jpg/ jpeg. See man exiv2 for more extensions if ext.lower() == ".jpg" or ext.lower() == ".jpeg": cmd = '''exiv2 pr "''' + file + '''" |xargs|sed -e s/".*imestamp : "/""/g|cut -d" " -f 1|cut -d":" -f1''' Year = RunBash(cmd) #print("Year:", Year) #status, Year = getstatusoutput(cmd) if status != 0: print("Error: exiv failed with year") useMtime(file) cmd = '''exiv2 pr "''' + file + '''" |xargs|sed -e s/".*imestamp : "/""/g|cut -d" " -f 1|cut -d":" -f2''' #Have to encase filname with "" to ensure whitespace filename is handled correctly MonthNumber = RunBash(cmd) #status, MonthNumber = getstatusoutput(cmd) if status != 0: print("Error: exiv failed with month") useMtime(file) cmd = '''exiv2 pr "''' + file + '''" |xargs|sed -e s/".*imestamp : "/""/g|cut -d" " -f 1|cut -d":" -f3''' Day = RunBash(cmd) #status, Day = getstatusoutput(cmd) if status != 0: print("Error: exiv failed with day") useMtime(file) #Have to manually calculate Monthname #print("YMmD", Year, MonthNumber, Month, Day) Month = MonthNrToMonth(MonthNumber) #print("YMmD", Year, MonthNumber, Month, Day) else: useMtime(file) if UseExiv2 == True: useExiv(file) else: useMtime(file) def CheckValidName(filename): # Logical check of date, ie. year four digit, month between 1-12, day between 1-31 global Year, Month, MonthNumber, Day #print(filename) def isint(intvalue): #Returns True if int and not empty try: int(intvalue) return True except Exception: return False if isint(Year) == False or int(Year) < 1000 or int(Year) > 9999: msg="Fatal error: Year not defined correctly.\nYear value: \"" + format(Year) + "\"" + "\nFilename: " + filename quit(msg) if Month == "": msg="Fatal error: Month not defined correctly.\nMonth value: \"" + format(Month) + "\"" + "\nFilename: " + filename quit(msg) if isint(MonthNumber) == False or int(MonthNumber) < 1 or int(MonthNumber) > 12: msg="Fatal error: MonthNumber not defined correctly.\nMonthNumber value: \"" + format(MonthNumber) + "\"" + "\nFilename: " + filename quit(msg) if isint(Day) == False or int(Day) < 1 or int(Day) > 31: msg="Fatal error: Day not defined correctly.\nDay value: \"" + Day + "\"" + "\nFilename: " + filename quit(msg) def RunBash(cmd): #TODO check exiv2 errorlevel out = subprocess.getoutput(cmd) return out #This is the stdout from the shell command # # Main # #Variable check #Check DestFolderTop exists if os.path.exists(DestFolderTop) == False: os.mkdir(DestFolderTop) #mode not set, debian deafults to 755. #Check if EXIV2 is installed status, output = subprocess.getstatusoutput("which exiv2") if status == 0: UseExiv2 = True # Set to True to enable exiv2 #Process all files in folder, then dive into folder and do the same ProcessFolder(SearchDir) On 13. feb. 2011 21:45, Marshall wrote: > I am trying to make a complete backup of all of our family > pictures. The main issue is that they are mixed in with backups of > several computers/OSs. What I would like to do is like a find all > jpgs, cp them to a single folder, which I can do, but in the case > of a duplicate name, rename the file being copied. I know there are > multiple files of the same name, but I'm not sure how to have cp > rename the file being moved when it is taking the output from a > find command. If I figure it out, I will post back, if not, TIA and > see you all Tuesday! > > Sent from my iPhone > --------------------------------------------------------------------- > > Archive http://marc.info/?l=jaxlug-list&r=1&w=2 > RSS Feed > http://www.mail-archive.com/[email protected]/maillist.xml > Unsubscribe [email protected] > > -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk1Y8P0ACgkQIx+MdL75im1q3QCfYRfnUzn+EBYRbMashoEkShtt EhwAn3SB3t6LNRj65ieGxe4KQLzHWett =YUTh -----END PGP SIGNATURE----- --------------------------------------------------------------------- Archive http://marc.info/?l=jaxlug-list&r=1&w=2 RSS Feed http://www.mail-archive.com/[email protected]/maillist.xml Unsubscribe [email protected]

