| 
									
										
										
										
											2012-03-10 19:16:07 +04:00
										 |  |  | #======================================================================= | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | __version__ = '''0.0.01''' | 
					
						
							| 
									
										
										
										
											2013-07-14 22:15:00 +04:00
										 |  |  | __sub_version__ = '''20130714221105''' | 
					
						
							| 
									
										
										
										
											2012-03-10 19:16:07 +04:00
										 |  |  | __copyright__ = '''(c) Alex A. Naanou 2011''' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #----------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import os | 
					
						
							| 
									
										
										
										
											2012-03-13 18:36:53 +04:00
										 |  |  | import sha | 
					
						
							|  |  |  | import md5 | 
					
						
							| 
									
										
										
										
											2013-03-22 14:32:48 +04:00
										 |  |  | import base64 | 
					
						
							| 
									
										
										
										
											2012-03-15 15:25:03 +04:00
										 |  |  | import time | 
					
						
							| 
									
										
										
										
											2012-03-10 19:16:07 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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... | 
					
						
							| 
									
										
										
										
											2012-03-20 01:39:22 +04:00
										 |  |  | ##!!! 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... | 
					
						
							| 
									
										
										
										
											2012-03-15 15:25:03 +04:00
										 |  |  | def image_gid(path, date=None,  | 
					
						
							|  |  |  | 		format='%(artist)s-%(date)s-%(name)s',  | 
					
						
							| 
									
										
										
										
											2012-03-13 22:48:46 +04:00
										 |  |  | 		date_format='%Y%m%d-%H%M%S',  | 
					
						
							|  |  |  | 		default_artist='Unknown', | 
					
						
							| 
									
										
										
										
											2012-03-15 15:25:03 +04:00
										 |  |  | 		use_ctime=False, | 
					
						
							| 
									
										
										
										
											2013-03-22 14:32:48 +04:00
										 |  |  | 		hash_func=lambda s: sha.sha(s).hexdigest()): | 
					
						
							| 
									
										
										
										
											2012-03-10 19:16:07 +04:00
										 |  |  | 	'''
 | 
					
						
							| 
									
										
										
										
											2013-03-19 15:00:29 +04:00
										 |  |  | 	Calculate image GID. | 
					
						
							| 
									
										
										
										
											2012-03-10 19:16:07 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Main gid criteria: | 
					
						
							|  |  |  | 	 	- unique | 
					
						
							|  |  |  | 	 	- calculable from the item (preferably any sub-item) | 
					
						
							|  |  |  | 	 	- human-readable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Default format: | 
					
						
							|  |  |  | 		<artist>-<datetime>-<filename> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Example: | 
					
						
							|  |  |  | 		Alex_A.Naanou-20110627-195706-DSC_1234	 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-19 15:00:29 +04:00
										 |  |  | 	If hash_func is not None, then the function will be used to generate  | 
					
						
							| 
									
										
										
										
											2012-03-13 18:36:53 +04:00
										 |  |  | 	a hex hash from the above string. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-10 19:16:07 +04:00
										 |  |  | 	Supported fields: | 
					
						
							| 
									
										
										
										
											2012-03-13 18:36:53 +04:00
										 |  |  | 		%(artist)s	- Exif.Image.Artist field, stripped and spaces replaced | 
					
						
							|  |  |  | 					  with underscores. | 
					
						
							| 
									
										
										
										
											2013-03-27 18:13:52 +04:00
										 |  |  | 					  If no artist info is set this will be set to default_artist. | 
					
						
							|  |  |  | 		%(date)s	- Exif.Photo.DateTimeOriginal formated to date_format argument. | 
					
						
							| 
									
										
										
										
											2012-03-10 19:16:07 +04:00
										 |  |  | 		%(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], | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-03-13 22:48:46 +04:00
										 |  |  | 	##!!! this might fail... | 
					
						
							|  |  |  | 	i = metadata.ImageMetadata('%s' % path) | 
					
						
							| 
									
										
										
										
											2012-03-17 00:44:04 +04:00
										 |  |  | 	try: | 
					
						
							|  |  |  | 		i.read() | 
					
						
							|  |  |  | 	except IOError: | 
					
						
							|  |  |  | 		# can't read exif... | 
					
						
							|  |  |  | 		i = None | 
					
						
							| 
									
										
										
										
											2012-03-10 19:16:07 +04:00
										 |  |  | 	# check if we need a date in the id... | 
					
						
							|  |  |  | 	if '%(date)s' in format: | 
					
						
							| 
									
										
										
										
											2012-03-15 15:25:03 +04:00
										 |  |  | 		if date is not None: | 
					
						
							|  |  |  | 			data['date'] = time.strftime(date_format, time.gmtime(date)) | 
					
						
							| 
									
										
										
										
											2012-03-17 00:44:04 +04:00
										 |  |  | 		elif use_ctime or i is None: | 
					
						
							| 
									
										
										
										
											2012-03-15 15:25:03 +04:00
										 |  |  | 			date = os.path.getctime(path) | 
					
						
							|  |  |  | 			data['date'] = time.strftime(date_format, time.gmtime(date)) | 
					
						
							|  |  |  | 		else: | 
					
						
							| 
									
										
										
										
											2013-03-22 14:32:48 +04:00
										 |  |  | 			date = i['Exif.Photo.DateTimeOriginal'].value | 
					
						
							| 
									
										
										
										
											2012-03-15 15:25:03 +04:00
										 |  |  | 			data['date'] = date.strftime(date_format) | 
					
						
							| 
									
										
										
										
											2012-03-10 19:16:07 +04:00
										 |  |  | 	# check if we need an artist... | 
					
						
							|  |  |  | 	if '%(artist)s' in format: | 
					
						
							| 
									
										
										
										
											2012-03-17 00:44:04 +04:00
										 |  |  | 		data['artist'] = default_artist | 
					
						
							|  |  |  | 		if i is not None: | 
					
						
							|  |  |  | 			try: | 
					
						
							| 
									
										
										
										
											2013-03-27 18:13:52 +04:00
										 |  |  | 				# set the artist if in EXIF... | 
					
						
							|  |  |  | 				a = i['Exif.Image.Artist'].value.strip().replace(' ', '_') | 
					
						
							|  |  |  | 				if a != '': | 
					
						
							|  |  |  | 					data['artist'] = a | 
					
						
							| 
									
										
										
										
											2012-03-17 00:44:04 +04:00
										 |  |  | 			except KeyError: | 
					
						
							|  |  |  | 				pass | 
					
						
							| 
									
										
										
										
											2012-03-10 19:16:07 +04:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-13 18:36:53 +04:00
										 |  |  | 	if hash_func is not None: | 
					
						
							| 
									
										
										
										
											2013-03-22 14:32:48 +04:00
										 |  |  | 		return hash_func(format % data) | 
					
						
							| 
									
										
										
										
											2012-03-10 19:16:07 +04:00
										 |  |  | 	return format % data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-14 22:15:00 +04:00
										 |  |  | #--------------------------------------------------handle_commandline--- | 
					
						
							|  |  |  | def handle_commandline(): | 
					
						
							| 
									
										
										
										
											2013-03-22 14:32:48 +04:00
										 |  |  | 	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) | 
					
						
							| 
									
										
										
										
											2012-03-13 18:36:53 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-14 22:15:00 +04:00
										 |  |  | #----------------------------------------------------------------------- | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  | 	handle_commandline() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-13 18:36:53 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-10 19:16:07 +04:00
										 |  |  | #======================================================================= | 
					
						
							|  |  |  | #                                            vim:set ts=4 sw=4 nowrap : |