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''' | ||||
| __sub_version__ = '''20130521232425''' | ||||
| __sub_version__ = '''20130522014220''' | ||||
| __copyright__ = '''(c) Alex A. Naanou 2011''' | ||||
| 
 | ||||
| 
 | ||||
| @ -20,7 +20,7 @@ import gid | ||||
| 
 | ||||
| #----------------------------------------------------------------------- | ||||
| 
 | ||||
| config = { | ||||
| CONFIG = { | ||||
| 	'absolute-path': False, | ||||
| 
 | ||||
| 	'cache-image-name': '%(guid)s - %(name)s', | ||||
| @ -49,12 +49,12 @@ config = { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| data = { | ||||
| DATA = { | ||||
| 	'version': '2.0', | ||||
| 	'current': None, | ||||
| 	'ribbons': [], | ||||
| 	'order': [], | ||||
| 	'image_file': 'images.json', | ||||
| 	'ribbons': (), | ||||
| 	'order': (), | ||||
| 	'image_file': None, | ||||
| } | ||||
| 
 | ||||
| IMAGE_EXT = OR(*( | ||||
| @ -71,17 +71,30 @@ TARGET: %(target-file)s | ||||
| 
 | ||||
| 
 | ||||
| #----------------------------------------------------------------------- | ||||
| # Helpers... | ||||
| 
 | ||||
| #------------------------------------------------------------pathjoin--- | ||||
| def pathjoin(*p): | ||||
| 	''' | ||||
| 	''' | ||||
| 	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): | ||||
| 	''' | ||||
| 	''' | ||||
| 	err_file = pathjoin(path, config['error']) | ||||
| 	err_file = pathjoin(path, CONFIG['error']) | ||||
| 	if not os.path.exists(err_file): | ||||
| 		err = open(err_file, 'w') | ||||
| 	else: | ||||
| @ -94,6 +107,7 @@ def log_err(path, e, source_file, target_file): | ||||
| 		}) | ||||
| 
 | ||||
| 
 | ||||
| #------------------------------------------------------------hash_gid--- | ||||
| def hash_gid(img, force=False): | ||||
| 	''' | ||||
| 	Generate gid based on preview file content. | ||||
| @ -105,7 +119,58 @@ def hash_gid(img, force=False): | ||||
| 	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. | ||||
| 	''' | ||||
| @ -116,14 +181,15 @@ def build_cache_dirs(path, config=config): | ||||
| 			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. | ||||
| 	''' | ||||
| 	absolute_path = config['absolute-path'] | ||||
| 
 | ||||
| 	for name in os.listdir(path): | ||||
| 		iid, ext = os.path.splitext(name) | ||||
| 		fname, ext = os.path.splitext(name) | ||||
| 
 | ||||
| 		if ext != IMAGE_EXT: | ||||
| 			continue | ||||
| @ -132,28 +198,146 @@ def build_images(path, config=config, gid_generator=hash_gid): | ||||
| 
 | ||||
| 		img =  { | ||||
| 			'id': gid_generator(source_path), | ||||
| 			'name': name, | ||||
| 			'type': 'image', | ||||
| 			'state': 'single', | ||||
| 			'path': None, | ||||
| 			'path': getpath(path, name, absolute_path), | ||||
| 			'ctime': os.path.getctime(source_path), | ||||
| 			'preview': {}, | ||||
| 		} | ||||
| 		if absolute_path == True: | ||||
| 			img['path'] = 'file:///' + urllib2.quote(pathjoin(path, name), safe='/:') | ||||
| 		else: | ||||
| 			img['path'] = urllib2.quote(name) | ||||
| 
 | ||||
| 		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 : | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user