#!/usr/bin/env python # # Copyright 2012 Ville Rantanen # # this program is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser 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 Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . import sys,os import re import shutil import subprocess from optparse import OptionParser from math import ceil # (c) ville.rantanen@helsinki.fi imagesearch=re.compile('.*\.jpg$|.*\.jpeg$|.*\.gif$|.*\.png$|.*\.svg$|.*\.pdf$',re.I) excludepaths=re.compile('_med|_tn|\..*') DESCFILE='descriptions.csv' def getimagelist(path): ''' Returns a list of images matching the regex ''' list=os.listdir(path) imgs=[] for f in list: if (imagesearch.match(os.path.join(path,f))) and (os.path.isfile(os.path.join(path,f))): imgs.append(f) return imgs def getpathlist(path): ''' Returns a list of subfolders not matching the exclusion regex ''' list=os.listdir(path) paths=[] for d in list: if (not excludepaths.match(d)) and (os.path.isdir(os.path.join(path,d))): paths.append(d) return paths def createdesc(path,list): ''' Runs imagemagick identify to create descriptions of images ''' if len(list)==0: return if os.path.exists(os.path.join(path,DESCFILE)): if options.force: os.remove(os.path.join(path,DESCFILE)) else: print('Descriptions exist, not overwriting.') return outfile=open(os.path.join(path,DESCFILE),'w') n=1 nsum=len(list) for i in list: inpath=os.path.join(path,i) desc=create_description(inpath,options.format) outfile.write(i+"\t"+desc) outfile.flush() print('('+str(n)+'/'+str(nsum)+') '+i+"\t"+desc[0:-1]) n+=1 return def create_description(infile,format): idargs=['identify','-format',format,infile+'[0]'] idp=subprocess.Popen(idargs,stdout=subprocess.PIPE) output = idp.stdout.read() return output def traverse(path): ''' The recursive main function to create the thumbs and seek sub folders ''' print(path) pathlist=getpathlist(path) imagelist=getimagelist(path) print(str(len(pathlist))+' paths') print(str(len(imagelist))+' images') createdesc(path,imagelist) if options.recursive: for p in pathlist: traverse(os.path.join(path,p)) return def execute(): ''' Main execution ''' usage='''Usage: %prog [options] folder folder is the root folder of the image album.''' parser=OptionParser(usage=usage) parser.add_option("-f",action="store_true",dest="force",default=False, help="Force rewriting of descriptions") parser.add_option("--format",type="str",dest="format",default="", help="""Formatting string, see: http://www.imagemagick.org/script/escape.php. Setting this option will override the presets""") parser.add_option("-r",action="store_true",dest="recursive",default=False, help="Recurse in to subfolders") parser.add_option("-p",type="int",dest="preset",default=1, help="presets for descriptions. \"-p 0\" to get the list") global options (options,args)=parser.parse_args() if len(args) != 1 and options.preset!=0: parser.error("incorrect number of arguments") presets=[ '%f: %[EXIF:DateTimeOriginal]', '%f: %wx%h %[size]', '%f
%[EXIF:DateTimeOriginal] %[EXIF:ExposureTime]s F%[EXIF:FNumber]'] if options.preset<1: for row in range(len(presets)): print row+1," ",presets[row] sys.exit(0) if options.format=="": if options.preset>len(presets): parse.error("No such preset") options.format=presets[options.preset-1] traverse(os.path.abspath(args[0])) return execute() sys.exit(0)