mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 03:10:07 +00:00 
			
		
		
		
	almost done with gen3 implementation of buildcache (buildcache2.py)...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									a10097daa1
								
							
						
					
					
						commit
						c8cd7d1bf0
					
				
							
								
								
									
										217
									
								
								buildcache2.py
									
									
									
									
									
								
							
							
						
						
									
										217
									
								
								buildcache2.py
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | |||||||
| #======================================================================= | #======================================================================= | ||||||
| 
 | 
 | ||||||
| __version__ = '''0.0.01''' | __version__ = '''0.0.01''' | ||||||
| __sub_version__ = '''20130521232425''' | __sub_version__ = '''20130522014220''' | ||||||
| __copyright__ = '''(c) Alex A. Naanou 2011''' | __copyright__ = '''(c) Alex A. Naanou 2011''' | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -20,7 +20,7 @@ import gid | |||||||
| 
 | 
 | ||||||
| #----------------------------------------------------------------------- | #----------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| config = { | CONFIG = { | ||||||
| 	'absolute-path': False, | 	'absolute-path': False, | ||||||
| 
 | 
 | ||||||
| 	'cache-image-name': '%(guid)s - %(name)s', | 	'cache-image-name': '%(guid)s - %(name)s', | ||||||
| @ -49,12 +49,12 @@ config = { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| data = { | DATA = { | ||||||
| 	'version': '2.0', | 	'version': '2.0', | ||||||
| 	'current': None, | 	'current': None, | ||||||
| 	'ribbons': [], | 	'ribbons': (), | ||||||
| 	'order': [], | 	'order': (), | ||||||
| 	'image_file': 'images.json', | 	'image_file': None, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| IMAGE_EXT = OR(*( | IMAGE_EXT = OR(*( | ||||||
| @ -71,17 +71,30 @@ TARGET: %(target-file)s | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #----------------------------------------------------------------------- | #----------------------------------------------------------------------- | ||||||
|  | # Helpers... | ||||||
| 
 | 
 | ||||||
|  | #------------------------------------------------------------pathjoin--- | ||||||
| def pathjoin(*p): | def pathjoin(*p): | ||||||
| 	''' | 	''' | ||||||
| 	''' | 	''' | ||||||
| 	return ('/'.join(p)).replace('//', '/') | 	return ('/'.join(p)).replace('//', '/') | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | #-------------------------------------------------------------getpath--- | ||||||
|  | def getpath(root, path, absolute=False): | ||||||
|  | 	''' | ||||||
|  | 	''' | ||||||
|  | 	if absolute == True: | ||||||
|  | 		return 'file:///' + urllib2.quote(pathjoin(root, path), safe='/:') | ||||||
|  | 	else: | ||||||
|  | 		return urllib2.quote(path, safe='/') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #-------------------------------------------------------------log_err--- | ||||||
| def log_err(path, e, source_file, target_file): | def log_err(path, e, source_file, target_file): | ||||||
| 	''' | 	''' | ||||||
| 	''' | 	''' | ||||||
| 	err_file = pathjoin(path, config['error']) | 	err_file = pathjoin(path, CONFIG['error']) | ||||||
| 	if not os.path.exists(err_file): | 	if not os.path.exists(err_file): | ||||||
| 		err = open(err_file, 'w') | 		err = open(err_file, 'w') | ||||||
| 	else: | 	else: | ||||||
| @ -94,6 +107,7 @@ def log_err(path, e, source_file, target_file): | |||||||
| 		}) | 		}) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | #------------------------------------------------------------hash_gid--- | ||||||
| def hash_gid(img, force=False): | def hash_gid(img, force=False): | ||||||
| 	''' | 	''' | ||||||
| 	Generate gid based on preview file content. | 	Generate gid based on preview file content. | ||||||
| @ -105,7 +119,58 @@ def hash_gid(img, force=False): | |||||||
| 	return sha.sha(img.tostring()).hexdigest() | 	return sha.sha(img.tostring()).hexdigest() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def build_cache_dirs(path, config=config): | #-----------------------------------------------------report_progress--- | ||||||
|  | def report_progress(img, status): | ||||||
|  | 	''' | ||||||
|  | 	''' | ||||||
|  | 	# created all previews... | ||||||
|  | 	if False not in status: | ||||||
|  | 		print '.', | ||||||
|  | 	# created no previews... | ||||||
|  | 	elif True not in status: | ||||||
|  | 		print '-', | ||||||
|  | 	# created some previews... | ||||||
|  | 	else: | ||||||
|  | 		print 'p', | ||||||
|  | 	return img | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #-----------------------------------------make_inline_report_progress--- | ||||||
|  | def make_inline_report_progress(state=None): | ||||||
|  | 	if state == None: | ||||||
|  | 		state = {} | ||||||
|  | 	def _inline_report_progress(img, status): | ||||||
|  | 		created = state.get('created', 0) | ||||||
|  | 		skipped = state.get('skipped', 0) | ||||||
|  | 		partial = state.get('partial', 0) | ||||||
|  | 
 | ||||||
|  | 		# created all previews... | ||||||
|  | 		if False not in status: | ||||||
|  | 			created += 1 | ||||||
|  | 			state['created'] = created | ||||||
|  | 
 | ||||||
|  | 		# created no previews... | ||||||
|  | 		elif True not in status: | ||||||
|  | 			skipped += 1 | ||||||
|  | 			state['skipped'] = skipped | ||||||
|  | 
 | ||||||
|  | 		# created some previews... | ||||||
|  | 		else: | ||||||
|  | 			partial += 1 | ||||||
|  | 			state['partial'] = partial | ||||||
|  | 
 | ||||||
|  | 		print 'Previews created: %s partial: %s skipped: %s...\r' % (created, partial, skipped), | ||||||
|  | 
 | ||||||
|  | 		return img | ||||||
|  | 	return _inline_report_progress | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #----------------------------------------------------------------------- | ||||||
|  | # API... | ||||||
|  | 
 | ||||||
|  | #----------------------------------------------------build_cache_dirs--- | ||||||
|  | def build_cache_dirs(path, config=CONFIG): | ||||||
| 	''' | 	''' | ||||||
| 	Build cache directory tree. | 	Build cache directory tree. | ||||||
| 	''' | 	''' | ||||||
| @ -116,14 +181,15 @@ def build_cache_dirs(path, config=config): | |||||||
| 			os.makedirs(p) | 			os.makedirs(p) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def build_images(path, config=config, gid_generator=hash_gid): | #--------------------------------------------------------build_images--- | ||||||
|  | def build_images(path, config=CONFIG, gid_generator=hash_gid): | ||||||
| 	''' | 	''' | ||||||
| 	Build image structures update images.json in cache. | 	Build image structures update images.json in cache. | ||||||
| 	''' | 	''' | ||||||
| 	absolute_path = config['absolute-path'] | 	absolute_path = config['absolute-path'] | ||||||
| 
 | 
 | ||||||
| 	for name in os.listdir(path): | 	for name in os.listdir(path): | ||||||
| 		iid, ext = os.path.splitext(name) | 		fname, ext = os.path.splitext(name) | ||||||
| 
 | 
 | ||||||
| 		if ext != IMAGE_EXT: | 		if ext != IMAGE_EXT: | ||||||
| 			continue | 			continue | ||||||
| @ -132,28 +198,146 @@ def build_images(path, config=config, gid_generator=hash_gid): | |||||||
| 
 | 
 | ||||||
| 		img =  { | 		img =  { | ||||||
| 			'id': gid_generator(source_path), | 			'id': gid_generator(source_path), | ||||||
|  | 			'name': name, | ||||||
| 			'type': 'image', | 			'type': 'image', | ||||||
| 			'state': 'single', | 			'state': 'single', | ||||||
| 			'path': None, | 			'path': getpath(path, name, absolute_path), | ||||||
| 			'ctime': os.path.getctime(source_path), | 			'ctime': os.path.getctime(source_path), | ||||||
| 			'preview': {}, | 			'preview': {}, | ||||||
| 		} | 		} | ||||||
| 		if absolute_path == True: |  | ||||||
| 			img['path'] = 'file:///' + urllib2.quote(pathjoin(path, name), safe='/:') |  | ||||||
| 		else: |  | ||||||
| 			img['path'] = urllib2.quote(name) |  | ||||||
| 
 | 
 | ||||||
| 		yield img | 		yield img | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def build_previews(image): | #------------------------------------------------------build_previews--- | ||||||
|  | # NOTE: this will create images in the file system. | ||||||
|  | def build_previews(image, path=None, config=CONFIG, dry_run=True): | ||||||
|  | 	''' | ||||||
|  | 
 | ||||||
|  | 	NOTE: this needs the cache directory structure present. | ||||||
|  | 	''' | ||||||
|  | 	status = [] | ||||||
|  | 	# config... | ||||||
|  | 	absolute_path = config['absolute-path'] | ||||||
|  | 	dirs = config['cache-structure'] | ||||||
|  | 	sizes = config['sizes']  | ||||||
|  | 	cache_name = config['cache-image-name'] | ||||||
|  | 
 | ||||||
|  | 	# data... | ||||||
|  | 	gid = image['id'] | ||||||
|  | 	img_name = image['name'] | ||||||
|  | 	name = os.path.splitext(img_name)[0] | ||||||
|  | 	img_path = image['path'] | ||||||
|  | 
 | ||||||
|  | 	if absolute_path == False: | ||||||
|  | 		source_path = os.path.join(path, img_path) | ||||||
|  | 	else: | ||||||
|  | 		# XXX is this the best way??? | ||||||
|  | 		o = urllib2.urlopen(img_path) | ||||||
|  | 		source_path = o.fp.name | ||||||
|  | 		o.close() | ||||||
|  | 
 | ||||||
|  | 	img = Image.open(source_path, 'r') | ||||||
|  | 
 | ||||||
|  | 	# biggest preview is the original image... | ||||||
|  | 	image['preview'][str(max(*img.size)) + 'px'] = img_path | ||||||
|  | 
 | ||||||
|  | 	# previews... | ||||||
|  | 	for k, spec in sizes.items(): | ||||||
|  | 
 | ||||||
|  | 		if k in image['preview'].keys(): | ||||||
|  | 			continue | ||||||
|  | 
 | ||||||
|  | 		# build the two paths: relative and full... | ||||||
|  | 		n = pathjoin(dirs[k], cache_name % {'guid': gid, 'name': img_name}) | ||||||
|  | 		p = pathjoin(path, n) | ||||||
|  | 
 | ||||||
|  | 		# do not upscale images... | ||||||
|  | 		if max(*img.size) <= spec: | ||||||
|  | 			continue | ||||||
|  | 
 | ||||||
|  | 		# add image to index... | ||||||
|  | 		if not os.path.exists(p): | ||||||
|  | 			scale = spec/float(max(*img.size)) | ||||||
|  | 			preview = img.resize((int(img.size[0]*scale), int(img.size[1]*scale)), Image.ANTIALIAS) | ||||||
|  | 
 | ||||||
|  | 			if not dry_run: | ||||||
|  | 				preview.save(p) | ||||||
|  | 			else: | ||||||
|  | 				preview.close() | ||||||
|  | 
 | ||||||
|  | 			##!!! metadata??? | ||||||
|  | 
 | ||||||
|  | 			status += [True]  | ||||||
|  | 
 | ||||||
|  | 		# image exists... | ||||||
|  | 		else: | ||||||
|  | 			status += [False]  | ||||||
|  | 
 | ||||||
|  | 		image['preview'][str(spec) + 'px'] = getpath(path, n, absolute_path) | ||||||
|  | 
 | ||||||
|  | 	return image, status | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #----------------------------------------------------------build_data--- | ||||||
|  | def build_data(images, path, config=CONFIG): | ||||||
| 	''' | 	''' | ||||||
| 	''' | 	''' | ||||||
|  | 	images_index = {} | ||||||
|  | 	marked = [] | ||||||
|  | 	data = DATA.copy() | ||||||
|  | 	ribbon = [] | ||||||
|  | 
 | ||||||
|  | 	for image in images: | ||||||
|  | 		gid = image['id']  | ||||||
|  | 
 | ||||||
|  | 		images_index[gid] = image | ||||||
|  | 		ribbon += [gid] | ||||||
|  | 
 | ||||||
|  | 	ribbon.sort(lambda a, b: cmp(images_index[b]['ctime'], images_index[a]['ctime'])) | ||||||
|  | 
 | ||||||
|  | 	data['ribbons'] = [ribbon] | ||||||
|  | 	data['order'] = ribbon[:] | ||||||
|  | 	data['current'] = ribbon[0] | ||||||
|  | 
 | ||||||
|  | 	return data, images_index, marked | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #----------------------------------------------------------------------- | #----------------------------------------------------------------------- | ||||||
|  | # High-level API... | ||||||
| 
 | 
 | ||||||
|  | #---------------------------------------------------------build_cache--- | ||||||
|  | ##!!! DO NOT OVERWRITE EXISTING DATA... | ||||||
|  | def build_cache(path, config=CONFIG, gid_generator=hash_gid,  | ||||||
|  | 		report_progress=report_progress, dry_run=False): | ||||||
|  | 	''' | ||||||
|  | 	''' | ||||||
|  | 	absolute_path = config['absolute-path'] | ||||||
|  | 
 | ||||||
|  | 	build_cache_dirs(path, config) | ||||||
|  | 
 | ||||||
|  | 	data, images, marked = build_data( | ||||||
|  | 			(report_progress(*build_previews(img, path, config, dry_run=dry_run)) | ||||||
|  | 				for img in build_images(path, config, gid_generator)),  | ||||||
|  | 			path, config) | ||||||
|  | 
 | ||||||
|  | 	images_file = config['images'] | ||||||
|  | 	data_file = config['data'] | ||||||
|  | 	marked_file = config['marked'] | ||||||
|  | 
 | ||||||
|  | 	data['image_file'] = getpath(path, images_file, absolute_path) | ||||||
|  | 
 | ||||||
|  | 	if not dry_run: | ||||||
|  | 		##!!! DO NOT OVERWRITE EXISTING DATA... | ||||||
|  | 		with open(os.path.join(path, images_file), 'w') as f: | ||||||
|  | 			json.dump(images, f, indent=4) | ||||||
|  | 		with open(os.path.join(path, data_file), 'w') as f: | ||||||
|  | 			json.dump(data, f, indent=4) | ||||||
|  | 		with open(os.path.join(path, marked_file), 'w') as f: | ||||||
|  | 			json.dump(marked, f, indent=4) | ||||||
|  | 
 | ||||||
|  | 	return data | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -164,5 +348,6 @@ if __name__ == '__main__': | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| #======================================================================= | #======================================================================= | ||||||
| #                                            vim:set ts=4 sw=4 nowrap : | #                                            vim:set ts=4 sw=4 nowrap : | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user