| 
									
										
										
										
											2016-01-08 07:30:51 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | *  | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | **********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // XXX this is a hack...
 | 
					
						
							|  |  |  | // 		...need a way to escape these so as not to load them in browser...
 | 
					
						
							|  |  |  | if(typeof(process) != 'undefined'){ | 
					
						
							|  |  |  | 	var fs = require('fs') | 
					
						
							|  |  |  | 	var path = require('path') | 
					
						
							|  |  |  | 	var exiftool = require('exiftool') | 
					
						
							|  |  |  | 	var promise = require('promise') | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | define(function(require){ var module = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //var DEBUG = DEBUG != null ? DEBUG : true
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var actions = require('lib/actions') | 
					
						
							|  |  |  | var core = require('features/core') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							| 
									
										
										
										
											2016-01-12 04:47:40 +03:00
										 |  |  | // XXX make metadata a prop of image... (???)
 | 
					
						
							|  |  |  | // XXX Q: should we standardise metadata field names and adapt them to 
 | 
					
						
							|  |  |  | // 		lib???
 | 
					
						
							| 
									
										
										
										
											2016-01-08 07:30:51 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | var MetadataActions = actions.Actions({ | 
					
						
							|  |  |  | 	getMetadata: ['- Image/Get metadata data', | 
					
						
							| 
									
										
										
										
											2016-01-11 04:29:08 +03:00
										 |  |  | 		function(image){ | 
					
						
							|  |  |  | 			var gid = this.data.getImage(image) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(this.images && this.images[gid]){ | 
					
						
							|  |  |  | 				return this.images[gid].metadata || {} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return null | 
					
						
							|  |  |  | 		}], | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 	setMetadata: ['- Image/Set metadata data', | 
					
						
							| 
									
										
										
										
											2016-01-11 04:29:08 +03:00
										 |  |  | 		function(image, metadata, merge){ | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 			var gid = this.data.getImage(image) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(this.images && this.images[gid]){ | 
					
						
							|  |  |  | 				if(merge){ | 
					
						
							|  |  |  | 					var m = this.images[gid].metadata | 
					
						
							|  |  |  | 					Object.keys(metadata).forEach(function(k){ | 
					
						
							|  |  |  | 						m[k] = metadata[k] | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					this.images[gid].metadata = metadata | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | var Metadata =  | 
					
						
							|  |  |  | module.Metadata = core.ImageGridFeatures.Feature({ | 
					
						
							| 
									
										
										
										
											2016-01-11 04:29:08 +03:00
										 |  |  | 	title: '', | 
					
						
							|  |  |  | 	doc: '', | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 	tag: 'metadata', | 
					
						
							| 
									
										
										
										
											2016-01-11 04:29:08 +03:00
										 |  |  | 	depends: [ | 
					
						
							|  |  |  | 		'base', | 
					
						
							|  |  |  | 	], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 	actions: MetadataActions, | 
					
						
							| 
									
										
										
										
											2016-01-11 04:29:08 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //---------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | // Metadata reader/writer...
 | 
					
						
							| 
									
										
										
										
											2016-01-11 04:29:08 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | // XXX add Metadata writer...
 | 
					
						
							|  |  |  | var MetadataReaderActions = actions.Actions({ | 
					
						
							| 
									
										
										
										
											2016-01-11 04:29:08 +03:00
										 |  |  | 	// XXX should this be sync???
 | 
					
						
							|  |  |  | 	// XXX should this process multiple images???
 | 
					
						
							| 
									
										
										
										
											2016-01-08 07:30:51 +03:00
										 |  |  | 	// XXX also check the metadata/ folder (???)
 | 
					
						
							|  |  |  | 	// XXX this uses .markChanged(..) form filesystem.FileSystemWriter 
 | 
					
						
							|  |  |  | 	// 		feature, but technically does not depend on it...
 | 
					
						
							|  |  |  | 	// XXX should we store metadata in an image (current) or in fs???
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 	readMetadata: ['- Image/Get metadata data', | 
					
						
							| 
									
										
										
										
											2016-01-08 07:30:51 +03:00
										 |  |  | 		function(image, force){ | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var gid = this.data.getImage(image) | 
					
						
							|  |  |  | 			var img = this.images[gid] | 
					
						
							|  |  |  | 			var full_path = path.normalize(img.base_path +'/'+ img.path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return new promise(function(resolve, reject){ | 
					
						
							|  |  |  | 				if(!force && img.metadata){ | 
					
						
							|  |  |  | 					return resolve(img.metadata) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				fs.readFile(full_path, function(err, file){ | 
					
						
							|  |  |  | 					if(err){ | 
					
						
							|  |  |  | 						return reject(err) | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					exiftool.metadata(file, function(err, data){ | 
					
						
							|  |  |  | 						if(err){ | 
					
						
							|  |  |  | 							reject(err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						} else if(data.error){ | 
					
						
							|  |  |  | 							reject(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							// store metadata...
 | 
					
						
							|  |  |  | 							// XXX 
 | 
					
						
							|  |  |  | 							that.images[gid].metadata = data | 
					
						
							|  |  |  | 							that.markChanged && that.markChanged(gid) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							resolve(data) | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		}], | 
					
						
							| 
									
										
										
										
											2016-01-08 07:45:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 	// XXX take image Metadata and write it to target...
 | 
					
						
							|  |  |  | 	writeMetadata: ['- Image/Set metadata data', | 
					
						
							| 
									
										
										
										
											2016-01-08 07:45:47 +03:00
										 |  |  | 		function(image, target){ | 
					
						
							| 
									
										
										
										
											2016-01-09 04:59:57 +03:00
										 |  |  | 			// XXX
 | 
					
						
							| 
									
										
										
										
											2016-01-08 07:45:47 +03:00
										 |  |  | 		}] | 
					
						
							| 
									
										
										
										
											2016-01-08 07:30:51 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | var MetadataReader =  | 
					
						
							| 
									
										
										
										
											2016-01-12 04:47:40 +03:00
										 |  |  | module.MetadataReader = core.ImageGridFeatures.Feature({ | 
					
						
							| 
									
										
										
										
											2016-01-08 07:30:51 +03:00
										 |  |  | 	title: '', | 
					
						
							|  |  |  | 	doc: '', | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:47:40 +03:00
										 |  |  | 	tag: 'fs-metadata', | 
					
						
							| 
									
										
										
										
											2016-01-08 07:30:51 +03:00
										 |  |  | 	depends: [ | 
					
						
							| 
									
										
										
										
											2016-01-12 04:47:40 +03:00
										 |  |  | 		'metadata', | 
					
						
							| 
									
										
										
										
											2016-01-08 07:30:51 +03:00
										 |  |  | 	], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	isApplicable: function(){  | 
					
						
							|  |  |  | 		return this.runtime == 'nw' || this.runtime == 'node' }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 	actions: MetadataReaderActions, | 
					
						
							| 
									
										
										
										
											2016-01-08 07:30:51 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-11 04:29:08 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-08 07:45:47 +03:00
										 |  |  | //---------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | // Metadata editor/viewer...
 | 
					
						
							| 
									
										
										
										
											2016-01-09 01:55:19 +03:00
										 |  |  | //
 | 
					
						
							|  |  |  | // XXX first instinct is to use browse with editable fields as it will
 | 
					
						
							|  |  |  | // 		give us: 
 | 
					
						
							|  |  |  | // 			- searchability
 | 
					
						
							|  |  |  | // 			- navigation
 | 
					
						
							|  |  |  | // 			- ...
 | 
					
						
							|  |  |  | // 		missing functionality:
 | 
					
						
							|  |  |  | // 			- editor/form on open event
 | 
					
						
							|  |  |  | // 				- inline (preferred)
 | 
					
						
							|  |  |  | // 				- modal-form
 | 
					
						
							|  |  |  | // 			- table-like layout
 | 
					
						
							|  |  |  | // 				- template???
 | 
					
						
							|  |  |  | // 				- script layout tweaking (post-update)
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // 		...need to think about this...
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:47:40 +03:00
										 |  |  | // XXX add a way to sort fields...
 | 
					
						
							| 
									
										
										
										
											2016-01-08 07:45:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-09 04:59:57 +03:00
										 |  |  | // XXX this should basically be platform independent...
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | var MetadataUIActions = actions.Actions({ | 
					
						
							| 
									
										
										
										
											2016-01-12 04:47:40 +03:00
										 |  |  | 	config: { | 
					
						
							|  |  |  | 		'metadata-field-order': [ | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2016-01-13 18:04:56 +03:00
										 |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 	showMetadata: ['Image/Show metadata', | 
					
						
							| 
									
										
										
										
											2016-01-09 04:59:57 +03:00
										 |  |  | 		function(image, force){ | 
					
						
							|  |  |  | 			image = this.data.getImage(image) | 
					
						
							| 
									
										
										
										
											2016-01-10 04:59:50 +03:00
										 |  |  | 			// XXX make a list with two .text elements per list item:
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 			// 			.text.field		- metadata field name
 | 
					
						
							|  |  |  | 			// 			.text.value		- metadata field value 
 | 
					
						
							| 
									
										
										
										
											2016-01-10 04:59:50 +03:00
										 |  |  | 			// 		Add CSS:
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 			// 			.metadata-browser .list>div .text {
 | 
					
						
							| 
									
										
										
										
											2016-01-10 04:59:50 +03:00
										 |  |  | 			// 				display: inline-block;
 | 
					
						
							|  |  |  | 			// 				width: 50%;
 | 
					
						
							|  |  |  | 			// 			}
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 			// 			.metadata-browser .list>div .text:first-child {
 | 
					
						
							| 
									
										
										
										
											2016-01-10 04:59:50 +03:00
										 |  |  | 			// 				text-align: right; 
 | 
					
						
							|  |  |  | 			// 			}
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 			// 			.metadata-browser .list>div .text:first-child:after {
 | 
					
						
							| 
									
										
										
										
											2016-01-10 04:59:50 +03:00
										 |  |  | 			// 				content: ": ";
 | 
					
						
							|  |  |  | 			// 			}
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 			// 			.metadata-browser .list>div .text:last-child {
 | 
					
						
							| 
									
										
										
										
											2016-01-10 04:59:50 +03:00
										 |  |  | 			// 			}
 | 
					
						
							| 
									
										
										
										
											2016-01-09 04:59:57 +03:00
										 |  |  | 		}] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-08 07:45:47 +03:00
										 |  |  | // XXX
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | var MetadataUI =  | 
					
						
							|  |  |  | module.MetadataUI = core.ImageGridFeatures.Feature({ | 
					
						
							| 
									
										
										
										
											2016-01-09 04:59:57 +03:00
										 |  |  | 	title: '', | 
					
						
							|  |  |  | 	doc: '', | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 	tag: 'ui-metadata', | 
					
						
							| 
									
										
										
										
											2016-01-09 04:59:57 +03:00
										 |  |  | 	depends: [ | 
					
						
							|  |  |  | 		'ui', | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 		'metadata', | 
					
						
							| 
									
										
										
										
											2016-01-09 04:59:57 +03:00
										 |  |  | 	], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-12 04:33:10 +03:00
										 |  |  | 	actions: MetadataUIActions, | 
					
						
							| 
									
										
										
										
											2016-01-09 04:59:57 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-08 07:30:51 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************************************************************** | 
					
						
							|  |  |  | * vim:set ts=4 sw=4 :                                                */ | 
					
						
							|  |  |  | return module }) |