Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- import os, webbrowser as wb, time, re, datetime as dt
- from Tkinter import Tk
- import tkFileDialog as fd
- Tk().withdraw() # to stop shell opening for Tkinter
- username = os.environ.get('username')
- path = None
- open_when_done = False
- err_log = os.path.join(os.getenv('dt'),'rename_error_log.txt') # append
- # Globals
- g_sort_type = 'NATURAL' # options allowed for DATE or NATURAL i.e. how Windows would sort by default
- def write_log_file(file_history, reverted=False):
- fname = str(username+'_'+str(dt.datetime.today())[:19]+'.csv').replace(':','-')
- logfile = os.path.join(os.environ.get('logs'), 'rename', fname.replace(' ','_'))
- f = open(logfile, 'w')
- if reverted:
- f.write('These files were reverted!!!\n')
- f.write('Filename, Old Name, New Name\n')
- for row in file_history:
- f.write(str(str(row[0])+', '+row[1]+', '+row[2]+'\n'))
- f.close()
- def revert(file_history):
- for row in file_history:
- new_name = row[2]
- old_name = row[1]
- print '...reverting file', new_name, 'to', old_name
- os.rename(os.path.join(path,new_name), os.path.join(path,old_name))
- def get_range(specific, file_list, excl_list):
- count = len(file_list)
- #find a zero based index range (which goes upto but not including the upper limit)
- if specific == 'Y':
- print '\n'
- print 'Please specify the name of the file you want to start from, you do not need to'
- print 'write the full name, just enough characters for the input to be unique e.g. if'
- print 'two files are called "P30687" and "P30799", a single file could be identifed by'
- print 'entering "P306".\n'
- print 'You can leave either the start filename or end filename empty.'
- c = 0
- while c <> 1:
- c, tmp = 0, None
- print '\n','Range Start:'
- print '-----------'
- first = raw_input('Please enter the file to start from: ').lower()
- if not first:
- start = 0
- break
- for name in file_list:
- if first in name.lower():
- if not tmp:
- tmp = name
- c += 1
- if c == 0:
- print 'No matches were found for string:', first, ', please try again...'
- elif c > 1:
- print 'More than one file found, do you want to start from the first: '+tmp
- if raw_input('(Y/N?): ').upper() == 'Y':
- start, c = file_list.index(tmp), 1
- else:
- 'Okay, please give a more specific name.\n'
- else:
- start = file_list.index(tmp)
- c = 0
- while c <> 1:
- c, tmp = 0, None
- print '\n','Range End:'
- print '---------'
- last = raw_input('Please enter the last file to be included: ').lower()
- if not last:
- end = count
- break
- for name in file_list:
- if last in name.lower():
- if not tmp:
- tmp = name
- c += 1
- if c == 0:
- print 'No matches were found for string:', last, ', please try again...'
- elif c > 1:
- print 'More than one file found, do you want to start from the first: '+tmp+' (Y/N?):'
- if raw_input('> ').upper() == 'Y':
- last, c = file_list.index(tmp)+1, 1
- else:
- 'Okay, please give a more specific name.\n'
- else:
- end = file_list.index(tmp)+1
- else:
- start, end = 0, count
- return start, end, count
- def make_excl_list():
- finished = False
- lst = []
- print '\n'
- print 'You will now be prompted for any text strings that you want to exclude from the'
- print 'renaming process. Please notes that these are not case sensitive i.e. "mar"'
- print 'would exclude any file names containing "MAR" or "Mar" etc. \n'
- while not finished:
- lst.append(raw_input('Enter exclusion text: ').lower())
- if raw_input('Do you want to add any more? (Y/N): ').upper()[0] == 'N':
- finished = True
- return lst
- def rename_files(file_list, file_type):
- happy = False
- excl_list = []
- while not happy:
- print 'No of Digits:'
- print '------------'
- print 'How many digits do you want to use for the numbering e.g. 3 for 001 - 999'
- no_of_digits = int(raw_input('> '))
- print '\n', 'Start No:'
- print '--------'
- if raw_input('Do you want to start from 1? (Y/N): ').upper() == 'Y':
- file_no = 1
- else:
- file_no = int(raw_input('Please enter the number that you want to start from: '))
- print '\n', 'Exclusions:'
- print '----------'
- print 'Do you want to specify any exclusions (i.e. files to be left unchanged) (Y/N)?'
- excl = raw_input('> ').upper()
- if excl == 'Y':
- excl_list = make_excl_list()
- print '\n', 'Range:'
- print '-----'
- print 'Do you want to specify a range of filenames to be renamed (Y/N)?'
- rnge = raw_input('> ').upper()
- start, end, count = get_range(rnge, file_list, excl_list)
- print '\n', 'Prefix:'
- print '------'
- print 'Please enter the prefix that you want to use before the numbers (can be empty)'
- prefix = raw_input('> ')
- print '\n', 'Suffix:'
- print '------'
- print 'Please enter the suffix that you want to use after the numbers (can be empty)'
- print 'For a special suffix of _ and the month the file was last modified enter _mon'
- suffix = raw_input('> ')
- l = len(str(file_no))
- eg = prefix+'0'*(no_of_digits-l)+str(file_no)+suffix+' to '+prefix+'9'*no_of_digits+suffix
- print '\n', 'Naming schema set to:', eg
- print '\n', 'Proceed?'
- print '-------'
- if raw_input('Are you happy to proceed? (Y/N): ').upper() == 'Y':
- happy = True
- else:
- if raw_input('Do you want to change directory? (Y/N): ').upper() == 'Y':
- return False
- else:
- print 'Okay, we can go through the instructions again for the current directory\n'
- file_history = [] # contains a row per file with (file_no, old_name, new_name)
- print '\n', (end - start), file_type, 'files found wuthin range.'
- if raw_input('Do you want to rename these files? (Y/N): ').upper() == 'Y':
- print '\n', 'Starting renaming process...', '\n'
- # loop through specified range within file_list
- for n in range(start,end):
- excluded = False
- if excl == 'Y':
- for ex in excl_list:
- if ex in file_list[n].lower():
- excluded = True
- print '***leaving file', file_list[n], 'because of exclusion:', ex
- if not excluded:
- if suffix == '_mon':
- use_suffix = '_'+time.ctime(os.path.getmtime(os.path.join(path, file_list[n])))[4:7]
- else:
- use_suffix = suffix
- l = len(str(file_no))
- ext = file_list[n][file_list[n].rfind('.'):].lower()
- new_name = prefix+'0'*(no_of_digits-l)+str(file_no)+use_suffix+ext
- file_history.append((file_no, file_list[n], new_name))
- print '...renaming file', file_list[n], 'to', new_name
- os.rename(os.path.join(path,file_list[n]), os.path.join(path,new_name))
- file_no += 1
- if open_when_done:
- print '\n', 'Opening directory...', '\n'
- wb.open(path)
- else:
- return False
- print 'The files have now been re-named. However, a record has been taken of the old'
- print 'file names so that they can be reverted if required.','\n'
- if raw_input('Are you happy with the changes? (Y/N): ').upper() == 'Y':
- write_log_file(file_history, False)
- return True
- else:
- if raw_input('Do you want to revert to the old file name? (Y/N): ').upper() == 'Y':
- revert(file_history)
- write_log_file(file_history, True)
- print '\n', 'The files should now be restored to their original names'
- return True
- def sort_list(l):
- if g_sort_type.upper() == 'DATE':
- file_date_tuple_list, sorted_files = [], []
- for i in l:
- d = os.path.getmtime(os.path.join(path,i))
- file_date_tuple = (i,d)
- file_date_tuple_list.append(file_date_tuple)
- file_date_tuple_list.sort(key=lambda x: x[1])
- for i in file_date_tuple_list:
- sorted_files.append(i[0])
- return sorted_files
- else:
- convert = lambda text: int(text) if text.isdigit() else text.lower()
- alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
- return sorted(l, key = alphanum_key)
- def get_file_extensions(file_type):
- if file_type == 'image':
- lst = [
- '.bmp', #Bitmap Image File
- '.dds', #DirectDraw Surface
- '.dng', #Digital Negative Image File
- '.gif', #Graphical Interchange Format File
- '.jpg', #JPEG Image
- '.png', #Portable Network Graphic
- '.psd', #Adobe Photoshop Document
- '.pspimage', #PaintShop Pro Image
- '.tga', #Targa Graphic
- '.thm', #Thumbnail Image File
- '.tif', #Tagged Image File
- '.yuv', #YUV Encoded Image File
- '.mov', #Movie File
- '.avi',
- '.mp4'
- ]
- return lst
- def make_list():
- selected = False
- while not selected:
- # Date or natural sort used to order contents as Windows does
- content = sort_list(os.listdir(path))
- print '\n', 'The current directory selected is:','\n', path,'\n'
- file_type = 'image'
- ext_list = get_file_extensions(file_type)
- file_list = []
- for name in content:
- if name[name.rfind('.'):].lower() in ext_list:
- file_list.append(name)
- print ''
- if len(file_list) == 0:
- print 'No image files have been found', '\n'
- else:
- selected = rename_files(file_list, file_type)
- return path
- def get_dir():
- global path
- tmp_path, pict = None, None
- computer = os.environ.get('computername')
- if computer.lower() == 'prosser-pc':
- if os.getenv('username').lower() == 'rachel.prosser':
- pict = os.path.join('E:\Users', os.getenv('username'), 'Pictures', 'Family Photos')
- else:
- pict = os.path.join('E:\Users', os.getenv('username'), 'Pictures')
- else:
- pict = os.path.join(os.environ.get('userprofile'), 'Pictures')
- # start user from relevant pictures directory...
- os.chdir(pict)
- while not path:
- # if tmp_path assigned at end of previous loop use this, otherwise prompt for dir...
- if tmp_path:
- path = tmp_path
- tmp_path = None
- else:
- print 'Please select a directory to rename images...', '\n'
- path = fd.askdirectory()
- # false is returned if something goes wrong causing the loop to continue
- path = make_list()
- if raw_input('Do you want to Continue? (Y\N): ').upper() == 'Y':
- if raw_input('Do you want to use the same directory again? (Y\N): ').upper() == 'Y':
- tmp_path = path #store to use in next loop
- path = None #this will cause the loop to continue
- def main():
- print 'Program written by Chris Prosser for his beloved wife Rachel.', '\n'
- print 'This program allows the user to select a directory and rename all of the files'
- print 'of a given type within that directory.', '\n'
- try:
- get_dir()
- except NameError:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
- print 'An error occurred, the details shown below will be written to an error log file:'
- print err_log
- print ''.join('!! ' + line for line in lines)
- with open(err_log, "a") as myfile:
- myfile.write(''.join('!! ' + line for line in lines))
- else:
- print '\n', '*** PROCESS COMPLETE ***'
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement