#======================================================================= __version__ = '''0.0.01''' __sub_version__ = '''20130714221105''' __copyright__ = '''(c) Alex A. Naanou 2011''' #----------------------------------------------------------------------- import os import sha import md5 import base64 import time import pyexiv2 as metadata #----------------------------------------------------------------------- # XXX need a strategy to check if two files that have the same GID are # identical, and if so, need to destinguish them in the GID... # might be a good idea to add a file hash # XXX not yet sure if this is unique enough to avoid conflicts if one # photographer has enough cameras... # XXX also might be wise to add a photographer ID into here... ##!!! add gid info section to identify the options used to greate a gid, e.g. EXIF date vs. ctime, etc. ##!!! do a general revision and remove leacy... def image_gid(path, date=None, format='%(artist)s-%(date)s-%(name)s', date_format='%Y%m%d-%H%M%S', default_artist='Unknown', use_ctime=False, hash_func=lambda s: sha.sha(s).hexdigest()): ''' Calculate image GID. Main gid criteria: - unique - calculable from the item (preferably any sub-item) - human-readable Default format: -- Example: Alex_A.Naanou-20110627-195706-DSC_1234 If hash_func is not None, then the function will be used to generate a hex hash from the above string. Supported fields: %(artist)s - Exif.Image.Artist field, stripped and spaces replaced with underscores. If no artist info is set this will be set to default_artist. %(date)s - Exif.Photo.DateTimeOriginal formated to date_format argument. %(name)s - file name. NOTE: date and time are the date and time the image was made ('Exif.Image.DateTime') NOTE: need EXIF data to generate a GID ''' # get the filename... data = { 'name': os.path.splitext(os.path.split(path)[-1])[0], } ##!!! this might fail... i = metadata.ImageMetadata('%s' % path) try: i.read() except IOError: # can't read exif... i = None # check if we need a date in the id... if '%(date)s' in format: if date is not None: data['date'] = time.strftime(date_format, time.gmtime(date)) elif use_ctime or i is None: date = os.path.getctime(path) data['date'] = time.strftime(date_format, time.gmtime(date)) else: date = i['Exif.Photo.DateTimeOriginal'].value data['date'] = date.strftime(date_format) # check if we need an artist... if '%(artist)s' in format: data['artist'] = default_artist if i is not None: try: # set the artist if in EXIF... a = i['Exif.Image.Artist'].value.strip().replace(' ', '_') if a != '': data['artist'] = a except KeyError: pass if hash_func is not None: return hash_func(format % data) return format % data #--------------------------------------------------handle_commandline--- def handle_commandline(): from optparse import OptionParser parser = OptionParser() ##!!! need to define the path so that it shoes up in -h parser.add_option('-t', '--text', dest='format', action='store_const', const='text', default='sha', help='output GUID in base64 format.') parser.add_option('-b', '--base64', dest='format', action='store_const', const='base64', default='sha', help='output GUID in text format.') parser.add_option('-s', '--sha', dest='format', action='store_const', const='sha', default='sha', help='output GUID in sha format.') options, args = parser.parse_args() if len(args) != 1: parser.print_usage() else: IN_PATH = args[0] IN_PATH = IN_PATH.replace('\\', '/') if options.format == 'text': print image_gid(IN_PATH, hash_func=None) elif options.format == 'base64': # also remove the trailing \n... print image_gid(IN_PATH, hash_func=lambda s: base64.encodestring(s).strip()) else: print image_gid(IN_PATH) #----------------------------------------------------------------------- if __name__ == '__main__': handle_commandline() #======================================================================= # vim:set ts=4 sw=4 nowrap :