| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | *  | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | **********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //var DEBUG = DEBUG != null ? DEBUG : true
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-07 03:19:41 +04:00
										 |  |  | // XXX move this to the config...
 | 
					
						
							|  |  |  | var PREVIEW_SIZES = [ | 
					
						
							|  |  |  | 	// NOTE: this is first so as to prevent the hi-res from loading...
 | 
					
						
							|  |  |  | 	// XXX this is best to be screen sized or just a little bigger...
 | 
					
						
							|  |  |  | 	1280, | 
					
						
							|  |  |  | 	150, | 
					
						
							|  |  |  | 	350, | 
					
						
							|  |  |  | 	900 | 
					
						
							|  |  |  | ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // load the target-specific handlers...
 | 
					
						
							|  |  |  | // CEF
 | 
					
						
							|  |  |  | if(window.CEF_dumpJSON != null){ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	console.log('CEF mode: loading...') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var dumpJSON = CEF_dumpJSON | 
					
						
							|  |  |  | 	var listDir = CEF_listDir | 
					
						
							|  |  |  | 	var removeFile = CEF_removeFile | 
					
						
							|  |  |  | 	var runSystem = CEF_runSystem | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // node-webkit
 | 
					
						
							|  |  |  | } else if(window.require != null){ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	console.log('node-webkit mode: loading...') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-13 21:03:29 +04:00
										 |  |  | 	var path = require('path') | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | 	var fs = require('fs') | 
					
						
							| 
									
										
										
										
											2013-06-21 17:23:09 +04:00
										 |  |  | 	var fse = require('fs.extra') | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | 	var proc = require('child_process') | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 	var node_crypto = require('crypto') | 
					
						
							| 
									
										
										
										
											2013-07-13 21:03:29 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-04 19:00:38 +04:00
										 |  |  | 	//var exif = require('exif2')
 | 
					
						
							| 
									
										
										
										
											2013-07-13 21:03:29 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | 	var gui = require('nw.gui') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-13 21:03:29 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	window.osPath = function(p){ | 
					
						
							| 
									
										
										
										
											2013-07-14 04:45:56 +04:00
										 |  |  | 		return path | 
					
						
							| 
									
										
										
										
											2014-08-09 01:42:03 +04:00
										 |  |  | 			// we can have two types of path:
 | 
					
						
							|  |  |  | 			// 	file:///some/path			-> /some/path
 | 
					
						
							|  |  |  | 			// 	file:///X:/some/other/path	-> X:/some/other/path
 | 
					
						
							|  |  |  | 			.normalize(p.replace(/file:\/+([a-zA-Z]:\/|\/)/, '$1')) | 
					
						
							| 
									
										
										
										
											2013-07-14 04:45:56 +04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	window.execPathPush = function(p){ | 
					
						
							| 
									
										
										
										
											2013-07-14 21:46:55 +04:00
										 |  |  | 		process.env.PATH += ';' + path.normalize(path.dirname(process.execPath) + '/' + p) | 
					
						
							| 
									
										
										
										
											2013-07-13 21:03:29 +04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-13 20:33:41 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// paths to included utils...
 | 
					
						
							| 
									
										
										
										
											2013-07-14 04:45:56 +04:00
										 |  |  | 	execPathPush('./vips/bin') | 
					
						
							| 
									
										
										
										
											2013-07-13 20:33:41 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | 	// Things ImageGrid needs...
 | 
					
						
							|  |  |  | 	// XXX do we need assync versions??
 | 
					
						
							|  |  |  | 	window.listDir = function(path){ | 
					
						
							| 
									
										
										
										
											2014-01-30 08:53:27 +04:00
										 |  |  | 		if(!fs.existsSync(osPath(path))){ | 
					
						
							|  |  |  | 			return null | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-07-13 21:03:29 +04:00
										 |  |  | 		return fs.readdirSync(osPath(path)) | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-06-21 16:58:33 +04:00
										 |  |  | 	// XXX make this work across fs...
 | 
					
						
							|  |  |  | 	// XXX this will not overwrite...
 | 
					
						
							| 
									
										
										
										
											2013-11-06 03:44:14 +04:00
										 |  |  | 	// XXX set ctime to the same value as the original...
 | 
					
						
							| 
									
										
										
										
											2013-06-21 16:58:33 +04:00
										 |  |  | 	window.copyFile = function(src, dst){ | 
					
						
							| 
									
										
										
										
											2013-07-01 18:05:50 +04:00
										 |  |  | 		var deferred = $.Deferred() | 
					
						
							| 
									
										
										
										
											2013-07-13 21:03:29 +04:00
										 |  |  | 		src = osPath(src) | 
					
						
							|  |  |  | 		dst = osPath(dst) | 
					
						
							| 
									
										
										
										
											2013-06-21 16:58:33 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-13 21:03:29 +04:00
										 |  |  | 		var path = dst.split(/[\\\/]/) | 
					
						
							| 
									
										
										
										
											2013-06-21 16:58:33 +04:00
										 |  |  | 		path.pop() | 
					
						
							|  |  |  | 		path = path.join('/') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-01 18:05:50 +04:00
										 |  |  | 		// make dirs...
 | 
					
						
							| 
									
										
										
										
											2013-06-21 16:58:33 +04:00
										 |  |  | 		if(!fs.existsSync(path)){ | 
					
						
							|  |  |  | 			console.log('making:', path) | 
					
						
							| 
									
										
										
										
											2013-06-21 17:23:09 +04:00
										 |  |  | 			fse.mkdirRecursiveSync(path) | 
					
						
							| 
									
										
										
										
											2013-06-21 16:58:33 +04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(!fs.existsSync(dst)){ | 
					
						
							| 
									
										
										
										
											2013-06-21 17:23:09 +04:00
										 |  |  | 			// NOTE: this is not sync...
 | 
					
						
							| 
									
										
										
										
											2013-07-01 18:05:50 +04:00
										 |  |  | 			fse.copy(src, dst, function(err){ | 
					
						
							|  |  |  | 				if(err){ | 
					
						
							|  |  |  | 					deferred.reject(err) | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					deferred.resolve() | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 			return deferred | 
					
						
							| 
									
										
										
										
											2013-06-21 16:58:33 +04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-07-01 18:05:50 +04:00
										 |  |  | 		deferred.notify(dst, 'exists') | 
					
						
							|  |  |  | 		return deferred.resolve() | 
					
						
							| 
									
										
										
										
											2013-06-21 16:58:33 +04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | 	window.dumpJSON = function(path, data){ | 
					
						
							| 
									
										
										
										
											2013-07-13 21:03:29 +04:00
										 |  |  | 		path = osPath(path) | 
					
						
							| 
									
										
										
										
											2013-06-13 19:42:42 +04:00
										 |  |  | 		var dirs = path.split(/[\\\/]/) | 
					
						
							|  |  |  | 		dirs.pop() | 
					
						
							|  |  |  | 		dirs = dirs.join('/') | 
					
						
							|  |  |  | 		// build path...
 | 
					
						
							|  |  |  | 		if(!fs.existsSync(dirs)){ | 
					
						
							| 
									
										
										
										
											2013-06-21 17:23:09 +04:00
										 |  |  | 			console.log('making:', path) | 
					
						
							|  |  |  | 			fse.mkdirRecursiveSync(path) | 
					
						
							| 
									
										
										
										
											2013-06-13 19:42:42 +04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | 		return fs.writeFileSync(path, JSON.stringify(data), encoding='utf8') | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	window.removeFile = function(path){ | 
					
						
							| 
									
										
										
										
											2013-07-13 21:03:29 +04:00
										 |  |  | 		return fs.unlinkSync(osPath(path)) | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	window.runSystem = function(path){ | 
					
						
							| 
									
										
										
										
											2013-07-13 21:03:29 +04:00
										 |  |  | 		return proc.exec('"'+osPath(path)+'"', function(error, stdout, stderr){ | 
					
						
							| 
									
										
										
										
											2013-06-08 15:10:38 +04:00
										 |  |  | 			if(error != null){ | 
					
						
							|  |  |  | 				console.error(stderr) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 	// XXX this uses vips...
 | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 	window.getVipsField = function(field, source){ | 
					
						
							|  |  |  | 		if(source in IMAGES){ | 
					
						
							|  |  |  | 			var img = IMAGES[source] | 
					
						
							|  |  |  | 			var source = normalizePath(img.path) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		var getter = $.Deferred() | 
					
						
							| 
									
										
										
										
											2014-01-24 19:38:29 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 21:09:51 +04:00
										 |  |  | 		var data = '' | 
					
						
							|  |  |  | 		var p = proc.spawn('vips', ['im_header_string', field, osPath(source)]) | 
					
						
							|  |  |  | 		p.stdout.on('data', function(d){ | 
					
						
							|  |  |  | 				data += d.toString() | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		p.stdout.on('end', function(){ | 
					
						
							|  |  |  | 				getter.resolve(data.trim()) | 
					
						
							| 
									
										
										
										
											2014-01-24 19:38:29 +04:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 21:09:51 +04:00
										 |  |  | 		/* XXX do we need these??? | 
					
						
							|  |  |  | 		p.on('error', function(code){ | 
					
						
							|  |  |  | 				// XXX
 | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		p.on('close', function(code){ | 
					
						
							|  |  |  | 				getter.resolve(data) | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		*/ | 
					
						
							| 
									
										
										
										
											2014-01-24 19:38:29 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 		return getter | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// NOTE: source can be either gid or a path...
 | 
					
						
							|  |  |  | 	window.getImageOrientation = function(source){ | 
					
						
							|  |  |  | 		var getter = $.Deferred() | 
					
						
							|  |  |  | 		getVipsField('exif-ifd0-Orientation', source) | 
					
						
							|  |  |  | 			.done(function(o){ | 
					
						
							|  |  |  | 				getter.resolve(orientationExif2ImageGrid(parseInt(o))) | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		return getter | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 	// NOTE: source can be either gid or a path...
 | 
					
						
							| 
									
										
										
										
											2013-07-08 07:48:03 +04:00
										 |  |  | 	// XXX handle errors...
 | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 	window._getImageSize = function(dimension, source){ | 
					
						
							|  |  |  | 		if(source in IMAGES){ | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 			var img = IMAGES[source] | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 			var source = normalizePath(img.path) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		var getter = $.Deferred() | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// get max/min dimension...
 | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 		if(dimension == 'max' || dimension == 'min'){ | 
					
						
							|  |  |  | 			$.when( | 
					
						
							|  |  |  | 					_getImageSize('width', source),  | 
					
						
							|  |  |  | 					_getImageSize('height', source)) | 
					
						
							|  |  |  | 				.done(function(w, h){ | 
					
						
							|  |  |  | 					getter.resolve(Math[dimension](w, h)) | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 		// get dimension...
 | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 		} else if(dimension == 'width' || dimension == 'height') { | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 			getVipsField(dimension, source) | 
					
						
							|  |  |  | 				.done(function(res){ | 
					
						
							|  |  |  | 					getter.resolve(parseInt(res)) | 
					
						
							|  |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 		// wrong dimension...
 | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			return getter.reject('unknown dimension:' + dimension) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return getter | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-12 01:11:31 +04:00
										 |  |  | 	// XXX API to add to $PATH...
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-01 04:47:17 +04:00
										 |  |  | 	// preview generation...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2013-07-07 22:20:41 +04:00
										 |  |  | 	// possible modes:
 | 
					
						
							| 
									
										
										
										
											2013-07-07 19:46:45 +04:00
										 |  |  | 	// 		- optimized
 | 
					
						
							|  |  |  | 	// 			use closest rscale and minimal factor
 | 
					
						
							| 
									
										
										
										
											2013-07-07 22:20:41 +04:00
										 |  |  | 	// 			previews might get artifacts associated with small scale factors
 | 
					
						
							| 
									
										
										
										
											2013-07-08 04:36:59 +04:00
										 |  |  | 	// 			0.5x time
 | 
					
						
							| 
									
										
										
										
											2013-07-07 19:46:45 +04:00
										 |  |  | 	// 		- best
 | 
					
						
							|  |  |  | 	// 			only use scale factor (rscale=1)
 | 
					
						
							| 
									
										
										
										
											2013-07-07 22:20:41 +04:00
										 |  |  | 	// 			1x time (fixed set of previews: 1280, 150, 350, 900)
 | 
					
						
							| 
									
										
										
										
											2013-07-08 04:36:59 +04:00
										 |  |  | 	// 		- fast_r 
 | 
					
						
							| 
									
										
										
										
											2013-07-07 22:20:41 +04:00
										 |  |  | 	// 			make previews using nearest rscale (factor is rounded)
 | 
					
						
							| 
									
										
										
										
											2013-07-08 04:36:59 +04:00
										 |  |  | 	// 			will produce inexact preview sizes
 | 
					
						
							|  |  |  | 	// 			0.4x time
 | 
					
						
							|  |  |  | 	// 		- fast_f
 | 
					
						
							|  |  |  | 	// 			same as fast_r but factor is floored rather than rounded
 | 
					
						
							|  |  |  | 	// 			will priduce previews the same size or larger than requested
 | 
					
						
							| 
									
										
										
										
											2013-07-07 22:20:41 +04:00
										 |  |  | 	// 		- rscale
 | 
					
						
							|  |  |  | 	// 			only use rscale (factor=1)
 | 
					
						
							|  |  |  | 	// 			produces only fixed size previews
 | 
					
						
							| 
									
										
										
										
											2013-07-08 04:36:59 +04:00
										 |  |  | 	// 			0.3x time
 | 
					
						
							| 
									
										
										
										
											2013-07-07 22:20:41 +04:00
										 |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: rscale should be used for exactly tuned preview sizes...
 | 
					
						
							|  |  |  | 	// NOTE: this will add already existing previews to IMAGES[gid]...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2013-07-01 04:47:17 +04:00
										 |  |  | 	// XXX make this not just vips-specific...
 | 
					
						
							|  |  |  | 	// XXX path handling is a mess...
 | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 	// XXX looks a bit too complex for what it is -- revise!
 | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 	window.makeImagePreviews = function(gid, sizes, mode, no_update_loaded){ | 
					
						
							| 
									
										
										
										
											2013-07-08 04:36:59 +04:00
										 |  |  | 		mode = mode == null ? 'fast_f' : mode | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-15 18:56:21 +04:00
										 |  |  | 		var cache_dir = CONFIG.cache_dir | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 		var img = IMAGES[gid] | 
					
						
							|  |  |  | 		var source = normalizePath(img.path) | 
					
						
							| 
									
										
										
										
											2013-07-13 21:03:29 +04:00
										 |  |  | 		var name = gid +' - '+ source.split(/[\\\/]/).pop() | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 		var compression = 90 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var previews = [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-01 04:21:14 +04:00
										 |  |  | 		// prepare the sizes we are going to be working with...
 | 
					
						
							|  |  |  | 		if(sizes == null){ | 
					
						
							| 
									
										
										
										
											2013-07-07 03:19:41 +04:00
										 |  |  | 			sizes = PREVIEW_SIZES | 
					
						
							| 
									
										
										
										
											2013-07-01 04:21:14 +04:00
										 |  |  | 		} else if(typeof(sizes) == typeof(123)){ | 
					
						
							|  |  |  | 			sizes = [ sizes ] | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-01 04:21:14 +04:00
										 |  |  | 		// build usable local path (without 'file:///')...
 | 
					
						
							| 
									
										
										
										
											2013-12-15 18:56:21 +04:00
										 |  |  | 		var cache_path = normalizePath(cache_dir) | 
					
						
							| 
									
										
										
										
											2013-07-13 21:03:29 +04:00
										 |  |  | 		cache_path = osPath(cache_path) | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-01 04:21:14 +04:00
										 |  |  | 		// get cur image size...
 | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 		var size_getter = _getImageSize('max', source) | 
					
						
							| 
									
										
										
										
											2013-07-07 22:20:41 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 		for(var i=0; i < sizes.length; i++){ | 
					
						
							|  |  |  | 			var size = sizes[i] | 
					
						
							| 
									
										
										
										
											2013-07-01 04:47:17 +04:00
										 |  |  | 			// XXX get this from config...
 | 
					
						
							|  |  |  | 			var target_path = [ cache_path, size+'px' ].join('/') | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			var deferred = $.Deferred() | 
					
						
							|  |  |  | 			previews.push(deferred) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 			[function(size, target_path, deferred){ | 
					
						
							| 
									
										
										
										
											2013-07-01 04:21:14 +04:00
										 |  |  | 				// wait for current image size if needed...
 | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 				size_getter.done(function(source_size){ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-26 05:17:32 +04:00
										 |  |  | 					// handle existing previews...
 | 
					
						
							|  |  |  | 					if(fs.existsSync(target_path +'/'+ name)){ | 
					
						
							| 
									
										
										
										
											2013-07-01 04:47:17 +04:00
										 |  |  | 						// see if we know about the preview...
 | 
					
						
							|  |  |  | 						if(img.preview == null || !((size+'px') in img.preview)){ | 
					
						
							|  |  |  | 							var preview_path = [target_path, name].join('/') | 
					
						
							|  |  |  | 							// add the preview to the image object...
 | 
					
						
							| 
									
										
										
										
											2013-12-15 18:56:21 +04:00
										 |  |  | 							img.preview[size+'px'] = './' + cache_dir +'/'+ preview_path.split(cache_dir).pop() | 
					
						
							| 
									
										
										
										
											2013-07-01 04:47:17 +04:00
										 |  |  | 							// mark image dirty...
 | 
					
						
							| 
									
										
										
										
											2013-12-15 03:38:15 +04:00
										 |  |  | 							imageUpdated(gid) | 
					
						
							| 
									
										
										
										
											2013-07-01 04:47:17 +04:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-07-26 05:17:32 +04:00
										 |  |  | 						//console.log('>>> Preview:', name, '('+size+'): Exists.')
 | 
					
						
							| 
									
										
										
										
											2013-07-01 04:47:17 +04:00
										 |  |  | 						deferred.notify(gid, size, 'exists') | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 						return deferred.resolve() | 
					
						
							| 
									
										
										
										
											2013-07-26 05:17:32 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					// skip previews larger than cur image...
 | 
					
						
							|  |  |  | 					} else if(source_size <= size){ | 
					
						
							|  |  |  | 						//console.log('>>> Preview:', name, '('+size+'): Skipped.')
 | 
					
						
							|  |  |  | 						deferred.notify(gid, size, 'skipped') | 
					
						
							|  |  |  | 						return deferred.resolve() | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-01 04:21:14 +04:00
										 |  |  | 					// create the directory then go to its content...
 | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 					// XXX check for errors...
 | 
					
						
							|  |  |  | 					fse.mkdirRecursive(target_path, function(err){ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						var preview_path = [target_path, name].join('/') | 
					
						
							|  |  |  | 						var factor = source_size / size | 
					
						
							| 
									
										
										
										
											2013-07-07 19:46:45 +04:00
										 |  |  | 						// this can be 1, 2, 4 or 8...
 | 
					
						
							|  |  |  | 						var rscale = 1 | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-07 22:20:41 +04:00
										 |  |  | 						// speed things up with read-scaling and rounding the scale factor...
 | 
					
						
							| 
									
										
										
										
											2013-07-08 04:36:59 +04:00
										 |  |  | 						if(['fast_r', 'fast_f', 'optimized', 'rscale'].indexOf(mode) >= 0){ | 
					
						
							| 
									
										
										
										
											2013-07-07 22:20:41 +04:00
										 |  |  | 							while(rscale < 8){ | 
					
						
							|  |  |  | 								if(rscale*2 >= factor){ | 
					
						
							|  |  |  | 									break | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 								rscale *= 2 | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							factor = factor / rscale | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-07-08 04:36:59 +04:00
										 |  |  | 						// factor processing...
 | 
					
						
							|  |  |  | 						if(mode == 'fast_r'){ | 
					
						
							|  |  |  | 							factor = Math.max(Math.round(factor), 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						} else if(mode == 'fast_f'){ | 
					
						
							|  |  |  | 							// NOTE: .floor(...) will make the images larger than
 | 
					
						
							|  |  |  | 							// 		the requested size, this will avaoid scale-up
 | 
					
						
							|  |  |  | 							// 		artifacts...
 | 
					
						
							|  |  |  | 							factor = Math.max(Math.floor(factor), 1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-07 22:20:41 +04:00
										 |  |  | 						} else if(mode == 'rscale'){ | 
					
						
							|  |  |  | 							factor = 1 | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 21:09:51 +04:00
										 |  |  | 						var p = proc.spawn('vips', [ | 
					
						
							|  |  |  | 								'im_shrink', | 
					
						
							|  |  |  | 								osPath(source) +':'+ rscale, | 
					
						
							|  |  |  | 								preview_path +':'+ compression, | 
					
						
							|  |  |  | 								factor, | 
					
						
							|  |  |  | 								factor | 
					
						
							|  |  |  | 							]) | 
					
						
							|  |  |  | 						// XXX is this the correct wat to deal with errors???
 | 
					
						
							|  |  |  | 						var error = '' | 
					
						
							|  |  |  | 						p.stderr.on('data', function(data){ | 
					
						
							|  |  |  | 							error += data.toString() | 
					
						
							|  |  |  | 						}) | 
					
						
							|  |  |  | 						//p.stderr.on('end', function(data){
 | 
					
						
							|  |  |  | 						//})
 | 
					
						
							|  |  |  | 						p.on('close', function(code){ | 
					
						
							|  |  |  | 							// error...
 | 
					
						
							|  |  |  | 							if(code != 0){ | 
					
						
							|  |  |  | 								deferred.notify(gid, size, 'error', error) | 
					
						
							|  |  |  | 								deferred.reject() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							// ok...
 | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								// NOTE: the size of the real preview 
 | 
					
						
							|  |  |  | 								// 		generated might different from 
 | 
					
						
							|  |  |  | 								// 		the target size...
 | 
					
						
							|  |  |  | 								deferred.notify(gid, size, 'done') | 
					
						
							|  |  |  | 								// update the image structure...
 | 
					
						
							|  |  |  | 								if(!('preview' in img)){ | 
					
						
							|  |  |  | 									img.preview = {} | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 								img.preview[size+'px'] = './' + cache_dir +'/'+ preview_path.split(cache_dir).pop() | 
					
						
							|  |  |  | 								// mark image dirty...
 | 
					
						
							|  |  |  | 								imageUpdated(gid) | 
					
						
							|  |  |  | 								// we are done...
 | 
					
						
							|  |  |  | 								deferred.resolve() | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						}) | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 					}) | 
					
						
							|  |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 			}(size, target_path, deferred)] | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 		var res = $.when.apply(null, previews) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// update loaded images...
 | 
					
						
							|  |  |  | 		if(!no_update_loaded){ | 
					
						
							|  |  |  | 			res.done(function(){ | 
					
						
							|  |  |  | 				var o = getImage(gid) | 
					
						
							|  |  |  | 				if(o.length > 0){ | 
					
						
							|  |  |  | 					updateImage(o) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return res | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// XXX needs more testing...
 | 
					
						
							|  |  |  | 	// 		- for some reason this is a bit slower than the queued version
 | 
					
						
							|  |  |  | 	// 			...in spite of being managed by node.js
 | 
					
						
							|  |  |  | 	// 		- will this be faster on SMP/multi-core?
 | 
					
						
							|  |  |  | 	window.makeImagesPreviews = function(gids, sizes, mode){ | 
					
						
							|  |  |  | 		gids = gids == null ? getClosestGIDs() : gids | 
					
						
							|  |  |  | 		return $.when.apply(null, gids.map(function(gid){ | 
					
						
							|  |  |  | 			return makeImagePreviews(gid, sizes, mode) | 
					
						
							|  |  |  | 		})) | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 	// Queued version of makeImagesPreviews(...)
 | 
					
						
							| 
									
										
										
										
											2013-07-11 03:55:53 +04:00
										 |  |  | 	window.makeImagesPreviewsQ = function(gids, sizes, mode){ | 
					
						
							| 
									
										
										
										
											2013-07-08 01:59:30 +04:00
										 |  |  | 		gids = gids == null ? getClosestGIDs() : gids | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-23 06:56:17 +04:00
										 |  |  | 		var queue = getWorkerQueue('Generate previews', 4) | 
					
						
							| 
									
										
										
										
											2014-02-22 08:06:30 +04:00
										 |  |  | 			.filling() | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 04:12:56 +04:00
										 |  |  | 		// attach the workers to the queue...
 | 
					
						
							| 
									
										
										
										
											2013-07-11 03:55:53 +04:00
										 |  |  | 		$.each(gids, function(_, gid){ | 
					
						
							| 
									
										
										
										
											2014-01-23 06:56:17 +04:00
										 |  |  | 			queue.enqueue(makeImagePreviews, gid, sizes, mode) | 
					
						
							| 
									
										
										
										
											2013-07-11 04:12:56 +04:00
										 |  |  | 				// XXX do we need to report seporate previews???
 | 
					
						
							| 
									
										
										
										
											2013-07-11 03:55:53 +04:00
										 |  |  | 				//.progress(function(state){ queue.notify(state) })
 | 
					
						
							| 
									
										
										
										
											2014-01-23 06:56:17 +04:00
										 |  |  | 				.always(function(){ console.log(gid, 'done') }) | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-22 08:06:30 +04:00
										 |  |  | 		return queue.doneFilling() | 
					
						
							| 
									
										
										
										
											2013-06-30 02:01:47 +04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-06 03:44:14 +04:00
										 |  |  | 	// format: "20130102-122315"
 | 
					
						
							|  |  |  | 	window.getEXIFDate = function(source){ | 
					
						
							|  |  |  | 		var getter = $.Deferred() | 
					
						
							|  |  |  | 		getVipsField('exif-ifd0-Date and Time', source) | 
					
						
							|  |  |  | 			.done(function(date){ | 
					
						
							|  |  |  | 				getter.resolve(date | 
					
						
							|  |  |  | 					// remove substrings in braces...
 | 
					
						
							|  |  |  | 					.replace(/\([^)]*\)/, '') | 
					
						
							|  |  |  | 					.trim() | 
					
						
							|  |  |  | 					.replace(/:/g, '') | 
					
						
							|  |  |  | 					.replace(/ /g, '-')) | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		return getter | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	window.getEXIFGID = function(source, make_text_gid){ | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 		if(source in IMAGES){ | 
					
						
							|  |  |  | 			var img = IMAGES[source] | 
					
						
							|  |  |  | 			var source = normalizePath(img.path) | 
					
						
							| 
									
										
										
										
											2013-07-04 19:00:38 +04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 		var getter = $.Deferred() | 
					
						
							| 
									
										
										
										
											2013-07-04 19:00:38 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 		$.when( | 
					
						
							|  |  |  | 				getVipsField('exif-ifd0-Artist', source), | 
					
						
							| 
									
										
										
										
											2013-11-06 03:44:14 +04:00
										 |  |  | 				getEXIFDate(source)) | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 			.done(function(artist, date){ | 
					
						
							| 
									
										
										
										
											2013-07-10 00:30:33 +04:00
										 |  |  | 				// Artist...
 | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 				artist = artist | 
					
						
							| 
									
										
										
										
											2013-11-06 03:44:14 +04:00
										 |  |  | 					// remove substrings in braces...
 | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 					.replace(/\([^)]*\)/, '') | 
					
						
							|  |  |  | 					.trim() | 
					
						
							|  |  |  | 				artist = artist == '' ? 'Unknown' : artist | 
					
						
							| 
									
										
										
										
											2013-11-06 03:44:14 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-10 00:30:33 +04:00
										 |  |  | 				// Date...
 | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 				// XXX if not set, get ctime...
 | 
					
						
							| 
									
										
										
										
											2013-11-06 03:44:14 +04:00
										 |  |  | 				// XXX
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-10 00:30:33 +04:00
										 |  |  | 				// File name...
 | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 				var name = source.split(/[\\\/]/).pop().split('.')[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				var text_gid = artist +'-'+ date +'-'+ name | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// text gid...
 | 
					
						
							|  |  |  | 				if(make_text_gid){ | 
					
						
							|  |  |  | 					getter.resolve(text_gid) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// hex gid...
 | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					var h = node_crypto.createHash('sha1') | 
					
						
							|  |  |  | 					h.update(text_gid) | 
					
						
							|  |  |  | 					var hex_gid = h.digest('hex') | 
					
						
							| 
									
										
										
										
											2013-07-04 19:00:38 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 					getter.resolve(hex_gid) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2013-07-10 00:30:33 +04:00
										 |  |  | 			// XXX handle arrors in a more informative way...
 | 
					
						
							|  |  |  | 			.fail(function(){ | 
					
						
							|  |  |  | 				getter.reject() | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2013-07-08 05:43:54 +04:00
										 |  |  | 		return getter | 
					
						
							| 
									
										
										
										
											2013-07-04 19:00:38 +04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-01 17:16:12 +04:00
										 |  |  | 	// UI-specific...
 | 
					
						
							|  |  |  | 	window.toggleFullscreenMode = createCSSClassToggler( | 
					
						
							|  |  |  | 			document.body,  | 
					
						
							|  |  |  | 			'.full-screen-mode', | 
					
						
							|  |  |  | 			function(action){ | 
					
						
							|  |  |  | 				gui.Window.get().toggleFullscreen() | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 	window.closeWindow = function(){ | 
					
						
							|  |  |  | 		gui.Window.get().close() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	window.showDevTools = function(){ | 
					
						
							|  |  |  | 		gui.Window.get().showDevTools() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	window.reload = function(){ | 
					
						
							|  |  |  | 		gui.Window.get().reload() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	window.setWindowTitle = function(text){ | 
					
						
							| 
									
										
										
										
											2013-12-15 18:56:21 +04:00
										 |  |  | 		var title = text +' - '+ CONFIG.app_name | 
					
						
							| 
									
										
										
										
											2013-07-01 17:16:12 +04:00
										 |  |  | 		gui.Window.get().title = title | 
					
						
							|  |  |  | 		$('.title-bar .title').text(title) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | 	// load UI stuff...
 | 
					
						
							|  |  |  | 	$(function(){ | 
					
						
							|  |  |  | 		$('<div class="title-bar"/>') | 
					
						
							|  |  |  | 			.append($('<div class="title"></div>') | 
					
						
							|  |  |  | 				.text($('title').text())) | 
					
						
							|  |  |  | 			.append($('<div class="button close" onclick="closeWindow()">×</div>')) | 
					
						
							|  |  |  | 			.appendTo($('body')) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-13 19:42:42 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | // PhoneGap
 | 
					
						
							|  |  |  | } else if(false){ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	console.log('PhoneGap mode: loading...') | 
					
						
							|  |  |  | 	// XXX
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// stubs...
 | 
					
						
							|  |  |  | 	window.toggleFullscreenMode = function(){} | 
					
						
							|  |  |  | 	window.closeWindow = function(){} | 
					
						
							|  |  |  | 	window.showDevTools = function(){} | 
					
						
							|  |  |  | 	window.reload = function(){} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-10 00:30:33 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-08 05:46:57 +04:00
										 |  |  | // Bare Chrome...
 | 
					
						
							|  |  |  | } else { | 
					
						
							|  |  |  | 	console.log('Chrome mode: loading...') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// stubs...
 | 
					
						
							|  |  |  | 	window.toggleFullscreenMode = function(){} | 
					
						
							|  |  |  | 	window.closeWindow = function(){} | 
					
						
							|  |  |  | 	window.showDevTools = function(){} | 
					
						
							|  |  |  | 	window.reload = function(){} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************************************************************** | 
					
						
							|  |  |  | * vim:set ts=4 sw=4 :                                                */ |