mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 03:10:07 +00:00 
			
		
		
		
	mostly done with migration, need testing...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									1126cf979b
								
							
						
					
					
						commit
						532702ee80
					
				| @ -1706,17 +1706,28 @@ module.FileSystemLoaderURLHistoryUI = core.ImageGridFeatures.Feature({ | |||||||
| 
 | 
 | ||||||
| var FileSystemWriterActions = actions.Actions({ | var FileSystemWriterActions = actions.Actions({ | ||||||
| 	config: { | 	config: { | ||||||
| 		//'index-filename-template': '${DATE}-${KEYWORD}.${EXT}',
 |  | ||||||
| 
 | 
 | ||||||
| 		'export-path': null, | 		// main settings...
 | ||||||
|  | 		'export-settings': { | ||||||
|  | 			'path': null, | ||||||
|  | 
 | ||||||
|  | 			'include-virtual': true, | ||||||
|  | 			'clean-target': true, | ||||||
|  | 
 | ||||||
|  | 			// NOTE: file extension is added automatically...
 | ||||||
|  | 			// NOTE: see .formatImageName(..) for format docs...
 | ||||||
|  | 			'preview-name-pattern': '%(fav)l%n%(-%c)c', | ||||||
|  | 
 | ||||||
|  | 			// XXX is this used???
 | ||||||
|  | 			//'level-directory-name': 'fav',
 | ||||||
|  | 
 | ||||||
|  | 			// XXX do we need both???
 | ||||||
|  | 			'preview-size': 1000, | ||||||
|  | 			'preview-size-limit': 'no limit', | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		// history / presets...
 | ||||||
| 		'export-paths': [], | 		'export-paths': [], | ||||||
| 
 |  | ||||||
| 		'export-include-virtual': true, |  | ||||||
| 		'export-clean-target': true, |  | ||||||
| 
 |  | ||||||
| 		// NOTE: file extension is added automatically...
 |  | ||||||
| 		// NOTE: see .formatImageName(..) for format docs...
 |  | ||||||
| 		'export-preview-name-pattern': '%(fav)l%n%(-%c)c', |  | ||||||
| 		'export-preview-name-patterns': [ | 		'export-preview-name-patterns': [ | ||||||
| 			'%(fav)l%n%(-bookmarked)b%(-%c)c', | 			'%(fav)l%n%(-bookmarked)b%(-%c)c', | ||||||
| 			'%(fav)l%n%(-bookmarked)b%(-m)m%(-%c)c', | 			'%(fav)l%n%(-bookmarked)b%(-m)m%(-%c)c', | ||||||
| @ -1724,23 +1735,6 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 			'%(fav)l%i-%n', | 			'%(fav)l%i-%n', | ||||||
| 			'%(fav)l%g-%n', | 			'%(fav)l%g-%n', | ||||||
| 		], | 		], | ||||||
| 
 |  | ||||||
| 		// This is used in .exportIndex(..) to resolve name conflicts...
 |  | ||||||
| 		//
 |  | ||||||
| 		// NOTE: this is applied ONLY if there is a naming conflict...
 |  | ||||||
| 		// NOTE: see .formatImageName(..) for format docs...
 |  | ||||||
| 		// XXX adding a %c is more human-readable but is unstable as
 |  | ||||||
| 		// 		depends on gid order, %g resolves this problem but is 
 |  | ||||||
| 		// 		not very intuitive...
 |  | ||||||
| 		//'export-conflicting-image-name': '%n%(-%g)c',
 |  | ||||||
| 		'export-conflicting-image-name': '%n%(-%c)c', |  | ||||||
| 
 |  | ||||||
| 		'export-level-directory-name': 'fav', |  | ||||||
| 		'export-level-directory-names': [ |  | ||||||
| 			'fav', |  | ||||||
| 			'select', |  | ||||||
| 		], |  | ||||||
| 
 |  | ||||||
| 		// XXX add options to indicate:
 | 		// XXX add options to indicate:
 | ||||||
| 		// 		- long side
 | 		// 		- long side
 | ||||||
| 		// 		- short side
 | 		// 		- short side
 | ||||||
| @ -1754,8 +1748,6 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 			'1280', | 			'1280', | ||||||
| 			'1920', | 			'1920', | ||||||
| 		], | 		], | ||||||
| 		'export-preview-size': 1000, |  | ||||||
| 
 |  | ||||||
| 		'export-preview-size-limits': [ | 		'export-preview-size-limits': [ | ||||||
| 			'no limit', | 			'no limit', | ||||||
| 			'900', | 			'900', | ||||||
| @ -1763,9 +1755,213 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 			'1280', | 			'1280', | ||||||
| 			'1920', | 			'1920', | ||||||
| 		], | 		], | ||||||
|  | 		'export-level-directory-names': [ | ||||||
|  | 			'fav', | ||||||
|  | 			'select', | ||||||
|  | 		], | ||||||
|  | 
 | ||||||
|  | 		//'index-filename-template': '${DATE}-${KEYWORD}.${EXT}',
 | ||||||
|  | 		 | ||||||
|  | 		// This is used in .exportIndex(..) to resolve name conflicts...
 | ||||||
|  | 		//
 | ||||||
|  | 		// NOTE: this is applied ONLY if there is a naming conflict...
 | ||||||
|  | 		// NOTE: see .formatImageName(..) for format docs...
 | ||||||
|  | 		// XXX adding a %c is more human-readable but is unstable as
 | ||||||
|  | 		// 		depends on gid order, %g resolves this problem but is 
 | ||||||
|  | 		// 		not very intuitive...
 | ||||||
|  | 		// XXX is this used???
 | ||||||
|  | 		//'export-conflicting-image-name': '%n%(-%g)c',
 | ||||||
|  | 		'export-conflicting-image-name': '%n%(-%c)c', | ||||||
|  | 
 | ||||||
|  | 		/* XXX LEGACY... | ||||||
|  | 		'export-path': null, | ||||||
|  | 		'export-include-virtual': true, | ||||||
|  | 		'export-clean-target': true, | ||||||
|  | 		'export-preview-name-pattern': '%(fav)l%n%(-%c)c', | ||||||
|  | 		'export-level-directory-name': 'fav', | ||||||
|  | 		'export-preview-size': 1000, | ||||||
| 		'export-preview-size-limit': 'no limit', | 		'export-preview-size-limit': 'no limit', | ||||||
|  | 		//*/
 | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | 	// XXX document data format...
 | ||||||
|  | 	// XXX should %T / %I be global or current crop???
 | ||||||
|  | 	// XXX add comments...
 | ||||||
|  | 	// 		%comment - add comment if present
 | ||||||
|  | 	// 		%(...%comment )comment - add comment if present
 | ||||||
|  | 	// 		...need a better name...
 | ||||||
|  | 	// XXX add tags/keywords... 
 | ||||||
|  | 	// 		%(tag|...)k - if image is tagged with tag add text
 | ||||||
|  | 	formatImageName: ['- File/', | ||||||
|  | 		core.doc` | ||||||
|  | 
 | ||||||
|  | 		Filename patterns: | ||||||
|  | 		 	%n		- name without extension | ||||||
|  | 		 | ||||||
|  | 		 	%gid	- full image gid | ||||||
|  | 		 	%g		- short gid | ||||||
|  | 		 | ||||||
|  | 		 	%i		- image index in ribbon | ||||||
|  | 		 	%I		- global image index | ||||||
|  | 
 | ||||||
|  | 			%r		- ribbon number | ||||||
|  | 			%R		- ribbon number counting from the bottom | ||||||
|  | 		 | ||||||
|  | 		 	%t 		- total number of images in ribbon | ||||||
|  | 		 	%T		- total number of images | ||||||
|  | 		 | ||||||
|  | 		 	%(...)m	- add text in braces if image marked | ||||||
|  | 		 	%(...)b	- add text in braces if image is bookmark | ||||||
|  | 		 | ||||||
|  | 		 	%(...)C	- add text in braces if there are name conflicts. | ||||||
|  | 						NOTE: this will be added to all images. | ||||||
|  | 		 	%(...)c	- add text in braces if there are name conflicts  | ||||||
|  | 						present, but only if the current image has a  | ||||||
|  | 						conflicting name. | ||||||
|  | 		 	%c		- number in set of conflicting names (default: 0). | ||||||
|  | 						NOTE: this is not stable and can change depending | ||||||
|  | 							on image order. | ||||||
|  | 
 | ||||||
|  | 			%(...)l	- image level path, level depth corresponds to ribbon  | ||||||
|  | 						number counting from the bottom | ||||||
|  | 						NOTE: if level is 0 this resolves to '/' | ||||||
|  | 						Example: '%(x)lz.jop' will resolve to '/z.jpg' for bottom  | ||||||
|  | 							ribbon and to 'x/x/x/z.jpg' for ribbon #3 from the | ||||||
|  | 							bottom. | ||||||
|  | 			%(...)L	- image level path, level depth corresponds to ribbon  | ||||||
|  | 						number counting from the top | ||||||
|  | 						NOTE: if level is 0 this resolves to '/' | ||||||
|  | 
 | ||||||
|  | 		NOTE: file extension is added automatically. | ||||||
|  | 		NOTE: all group patterns (i.e. '%(..)x') can include other patterns. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 		Examples: | ||||||
|  | 			These examples are for image 123.jpg at position 2 of 10 (15th | ||||||
|  | 			of 100 total), bookmarked but not marked, in ribbon 1 in a  | ||||||
|  | 			set of 3 ribbons. | ||||||
|  | 
 | ||||||
|  | 			'%(fav)l%i-%n'		-> 'fav/02-123.jpg' | ||||||
|  | 
 | ||||||
|  | 			'%(other)L/%I-John-Smith-%n%(-b)b%(-m)m' | ||||||
|  | 								-> '/10-John-Smith-123-b.jpg' | ||||||
|  | 
 | ||||||
|  | 			'%(best)b/%i of %t - J. Smith - %n' | ||||||
|  | 								-> 'best/02 of 10 - J. Smith - 123.jpg' | ||||||
|  | 
 | ||||||
|  | 		`,
 | ||||||
|  | 		function(pattern, name, data){ | ||||||
|  | 			pattern = pattern || '%f' | ||||||
|  | 			data = data || {} | ||||||
|  | 			var gid = data.gid | ||||||
|  | 			if(!gid && name in this.images){ | ||||||
|  | 				gid = name | ||||||
|  | 				name = null | ||||||
|  | 			} | ||||||
|  | 			gid = gid || this.current | ||||||
|  | 			var ribbon = this.data.getRibbon(gid) | ||||||
|  | 			data = Object.assign({},  | ||||||
|  | 				this.images[gid] || {},  | ||||||
|  | 				data) | ||||||
|  | 
 | ||||||
|  | 			name = name  | ||||||
|  | 				|| pathlib.basename( | ||||||
|  | 					data.path || ((data.name || '') + (data.ext || ''))) | ||||||
|  | 			name = name == '' ?  | ||||||
|  | 				gid  | ||||||
|  | 				: name | ||||||
|  | 			var ext = pathlib.extname(name) | ||||||
|  | 			var to_ext = data.ext  | ||||||
|  | 				|| ext | ||||||
|  | 
 | ||||||
|  | 			var tags = data.tags || this.data.getTags(gid) | ||||||
|  | 
 | ||||||
|  | 			// XXX revise defaults...
 | ||||||
|  | 			var len = data.len || this.data.ribbons[ribbon].len | ||||||
|  | 			var total_len = data.total_len || this.data.length | ||||||
|  | 			var r_len = data.r_len || Object.keys(this.data.ribbons).length | ||||||
|  | 
 | ||||||
|  | 			var i = data.i || this.data.getImageOrder('ribbon', gid) | ||||||
|  | 			var I = data.I || this.data.getImageOrder('loaded', gid) | ||||||
|  | 			var r = data.r || this.data.getRibbonOrder(gid) | ||||||
|  | 			var R = data.R || r_len - r - 1 | ||||||
|  | 
 | ||||||
|  | 			// pad with zeros...
 | ||||||
|  | 			i = (i+'').padStart((len + '').length, '0') | ||||||
|  | 			I = (I+'').padStart((total_len + '').length, '0') | ||||||
|  | 			r = (r+'').padStart((r_len + '').length, '0') | ||||||
|  | 			R = (R+'').padStart((r_len + '').length, '0') | ||||||
|  | 			//i = ((('1e'+(len+'').length)*1 + i) + '').slice(1)
 | ||||||
|  | 			//I = ((('1e'+(total_len+'').length)*1 + I) + '').slice(1)
 | ||||||
|  | 
 | ||||||
|  | 			var conflicts = data.conflicts | ||||||
|  | 
 | ||||||
|  | 			return pattern | ||||||
|  | 				// file name...
 | ||||||
|  | 				.replace(/%n/, name.replace(ext, '')) | ||||||
|  | 
 | ||||||
|  | 				// gid...
 | ||||||
|  | 				.replace(/%gid/, gid) | ||||||
|  | 				// XXX get the correct short gid length...
 | ||||||
|  | 				.replace(/%g/, gid.slice(-6)) | ||||||
|  | 
 | ||||||
|  | 				// order...
 | ||||||
|  | 				.replace(/%i/, i) | ||||||
|  | 				.replace(/%I/, I) | ||||||
|  | 
 | ||||||
|  | 				// ribbon order...
 | ||||||
|  | 				.replace(/%r/, r) | ||||||
|  | 				.replace(/%r/, R) | ||||||
|  | 				 | ||||||
|  | 				// totals...
 | ||||||
|  | 				.replace(/%t/, len) | ||||||
|  | 				.replace(/%T/, total_len) | ||||||
|  | 
 | ||||||
|  | 				// conflict count...
 | ||||||
|  | 				.replace(/%c/, (conflicts && conflicts[gid]) ?  | ||||||
|  | 					conflicts[gid].indexOf(gid)  | ||||||
|  | 					: 0) | ||||||
|  | 
 | ||||||
|  | 				// metadata...
 | ||||||
|  | 				// XXX
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 				// Group patterns...
 | ||||||
|  | 
 | ||||||
|  | 				// tags...
 | ||||||
|  | 				// XXX test: %n%(b)b%(m)m%e
 | ||||||
|  | 				.replace( | ||||||
|  | 					/%\(([^)]*)\)m/, tags.indexOf('marked') >= 0 ? '$1' : '') | ||||||
|  | 				.replace( | ||||||
|  | 					/%\(([^)]*)\)b/, tags.indexOf('bookmark') >= 0 ? '$1' : '') | ||||||
|  | 				// XXX
 | ||||||
|  | 				//.replace(
 | ||||||
|  | 				//	/%\(([^)]*)\)k/, tags.indexOf('bookmark') >= 0 ? '$1' : '')
 | ||||||
|  | 
 | ||||||
|  | 				// conflicts...
 | ||||||
|  | 				.replace( | ||||||
|  | 					/%\(([^)]*)\)C/, conflicts ? '$1' : '') | ||||||
|  | 				.replace( | ||||||
|  | 					/%\(([^)]*)\)c/, (conflicts || {})[gid] ? '$1' : '') | ||||||
|  | 
 | ||||||
|  | 				// level...
 | ||||||
|  | 				.replace( | ||||||
|  | 					/%\(([^)]*)\)L/,  | ||||||
|  | 					function(match, level, offset, str){ | ||||||
|  | 						return (offset == 0 ? '' : '/')  | ||||||
|  | 							+(new Array(r*1)).fill(level).join('/') | ||||||
|  | 							+(match.length + offset == str.length ? '' : '/') }) | ||||||
|  | 				.replace( | ||||||
|  | 					/%\(([^)]*)\)l/, | ||||||
|  | 					function(match, level, offset, str){ | ||||||
|  | 						return (offset == 0 ? '' : '/')  | ||||||
|  | 							+(new Array(r_len - r*1 - 1)).fill(level).join('/') | ||||||
|  | 							+(match.length + offset == str.length ? '' : '/') }) | ||||||
|  | 
 | ||||||
|  | 				+ to_ext | ||||||
|  | 		}], | ||||||
|  | 	 | ||||||
|  | 
 | ||||||
| 	// XXX should this be sync???
 | 	// XXX should this be sync???
 | ||||||
| 	backupDir: ['- File/', | 	backupDir: ['- File/', | ||||||
| 		function(path, logger){ | 		function(path, logger){ | ||||||
| @ -1908,27 +2104,35 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 	// 		of max_size...
 | 	// 		of max_size...
 | ||||||
| 	// XXX log gid count instead of file count...
 | 	// XXX log gid count instead of file count...
 | ||||||
| 	exportIndex: ['- File/Export/Export index', | 	exportIndex: ['- File/Export/Export index', | ||||||
|  | 		core.doc` | ||||||
|  | 
 | ||||||
|  | 			.exportIndex(path) | ||||||
|  | 			.exportIndex(settings) | ||||||
|  | 
 | ||||||
|  | 		`,
 | ||||||
| 		function(path, max_size, include_orig, clean_target_dir, logger){ | 		function(path, max_size, include_orig, clean_target_dir, logger){ | ||||||
| 			var that = this | 			var that = this | ||||||
|  | 			var settings | ||||||
| 			logger = logger || this.logger | 			logger = logger || this.logger | ||||||
| 			logger = logger && logger.push('Export index') | 			logger = logger && logger.push('Export index') | ||||||
| 
 | 
 | ||||||
| 			max_size = parseInt(max_size || this.config['export-preview-size-limit']) || null | 			if(typeof(path) != typeof('str')){ | ||||||
| 			// XXX make this dependant on max_size....
 | 				settings = path | ||||||
| 			include_orig = include_orig || true | 				path = settings.path } | ||||||
| 
 | 			settings = this.config['export-settings'] || {} | ||||||
| 			// XXX is this correct???
 |  | ||||||
| 			// 		...get this from config...
 |  | ||||||
| 			path = path || './exported' |  | ||||||
| 			path = util.normalizePath(path) |  | ||||||
| 
 |  | ||||||
| 			// XXX resolve env variables in path...
 | 			// XXX resolve env variables in path...
 | ||||||
| 			// 		...also add ImageGrid specifics: $IG_INDEX, ...
 | 			// 		...also add ImageGrid specifics: $IG_INDEX, ...
 | ||||||
| 			// XXX
 | 			// XXX
 | ||||||
|  | 			path = path || './exported' | ||||||
|  | 			path = util.normalizePath(path) | ||||||
|  | 
 | ||||||
|  | 			max_size = parseInt(max_size || settings['preview-size-limit']) || null | ||||||
|  | 			// XXX make this dependant on max_size....
 | ||||||
|  | 			include_orig = include_orig || true | ||||||
| 
 | 
 | ||||||
| 			// clear/backup target...
 | 			// clear/backup target...
 | ||||||
| 			clean_target_dir = clean_target_dir === undefined ?  | 			clean_target_dir = clean_target_dir === undefined ?  | ||||||
| 				this.config['export-clean-target']  | 				settings['clean-target']  | ||||||
| 				: clean_target_dir | 				: clean_target_dir | ||||||
| 			clean_target_dir | 			clean_target_dir | ||||||
| 				&& fse.existsSync(path) | 				&& fse.existsSync(path) | ||||||
| @ -2148,183 +2352,6 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 			return Promise.all(queue) | 			return Promise.all(queue) | ||||||
| 		}], | 		}], | ||||||
| 
 | 
 | ||||||
| 	// XXX document data format...
 |  | ||||||
| 	// XXX should %T / %I be global or current crop???
 |  | ||||||
| 	// XXX add comments...
 |  | ||||||
| 	// 		%comment - add comment if present
 |  | ||||||
| 	// 		%(...%comment )comment - add comment if present
 |  | ||||||
| 	// 		...need a better name...
 |  | ||||||
| 	// XXX add tags/keywords... 
 |  | ||||||
| 	// 		%(tag|...)k - if image is tagged with tag add text
 |  | ||||||
| 	formatImageName: ['- File/', |  | ||||||
| 		core.doc` |  | ||||||
| 
 |  | ||||||
| 		Filename patterns: |  | ||||||
| 		 	%n		- name without extension |  | ||||||
| 		 |  | ||||||
| 		 	%gid	- full image gid |  | ||||||
| 		 	%g		- short gid |  | ||||||
| 		 |  | ||||||
| 		 	%i		- image index in ribbon |  | ||||||
| 		 	%I		- global image index |  | ||||||
| 
 |  | ||||||
| 			%r		- ribbon number |  | ||||||
| 			%R		- ribbon number counting from the bottom |  | ||||||
| 		 |  | ||||||
| 		 	%t 		- total number of images in ribbon |  | ||||||
| 		 	%T		- total number of images |  | ||||||
| 		 |  | ||||||
| 		 	%(...)m	- add text in braces if image marked |  | ||||||
| 		 	%(...)b	- add text in braces if image is bookmark |  | ||||||
| 		 |  | ||||||
| 		 	%(...)C	- add text in braces if there are name conflicts. |  | ||||||
| 						NOTE: this will be added to all images. |  | ||||||
| 		 	%(...)c	- add text in braces if there are name conflicts  |  | ||||||
| 						present, but only if the current image has a  |  | ||||||
| 						conflicting name. |  | ||||||
| 		 	%c		- number in set of conflicting names (default: 0). |  | ||||||
| 						NOTE: this is not stable and can change depending |  | ||||||
| 							on image order. |  | ||||||
| 
 |  | ||||||
| 			%(...)l	- image level path, level depth corresponds to ribbon  |  | ||||||
| 						number counting from the bottom |  | ||||||
| 						NOTE: if level is 0 this resolves to '/' |  | ||||||
| 						Example: '%(x)lz.jop' will resolve to '/z.jpg' for bottom  |  | ||||||
| 							ribbon and to 'x/x/x/z.jpg' for ribbon #3 from the |  | ||||||
| 							bottom. |  | ||||||
| 			%(...)L	- image level path, level depth corresponds to ribbon  |  | ||||||
| 						number counting from the top |  | ||||||
| 						NOTE: if level is 0 this resolves to '/' |  | ||||||
| 
 |  | ||||||
| 		NOTE: file extension is added automatically. |  | ||||||
| 		NOTE: all group patterns (i.e. '%(..)x') can include other patterns. |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 		Examples: |  | ||||||
| 			These examples are for image 123.jpg at position 2 of 10 (15th |  | ||||||
| 			of 100 total), bookmarked but not marked, in ribbon 1 in a  |  | ||||||
| 			set of 3 ribbons. |  | ||||||
| 
 |  | ||||||
| 			'%(fav)l%i-%n'		-> 'fav/02-123.jpg' |  | ||||||
| 
 |  | ||||||
| 			'%(other)L/%I-John-Smith-%n%(-b)b%(-m)m' |  | ||||||
| 								-> '/10-John-Smith-123-b.jpg' |  | ||||||
| 
 |  | ||||||
| 			'%(best)b/%i of %t - J. Smith - %n' |  | ||||||
| 								-> 'best/02 of 10 - J. Smith - 123.jpg' |  | ||||||
| 
 |  | ||||||
| 		`,
 |  | ||||||
| 		function(pattern, name, data){ |  | ||||||
| 			pattern = pattern || '%f' |  | ||||||
| 			data = data || {} |  | ||||||
| 			var gid = data.gid |  | ||||||
| 			if(!gid && name in this.images){ |  | ||||||
| 				gid = name |  | ||||||
| 				name = null |  | ||||||
| 			} |  | ||||||
| 			gid = gid || this.current |  | ||||||
| 			var ribbon = this.data.getRibbon(gid) |  | ||||||
| 			data = Object.assign({},  |  | ||||||
| 				this.images[gid] || {},  |  | ||||||
| 				data) |  | ||||||
| 
 |  | ||||||
| 			name = name  |  | ||||||
| 				|| pathlib.basename( |  | ||||||
| 					data.path || ((data.name || '') + (data.ext || ''))) |  | ||||||
| 			name = name == '' ?  |  | ||||||
| 				gid  |  | ||||||
| 				: name |  | ||||||
| 			var ext = pathlib.extname(name) |  | ||||||
| 			var to_ext = data.ext  |  | ||||||
| 				|| ext |  | ||||||
| 
 |  | ||||||
| 			var tags = data.tags || this.data.getTags(gid) |  | ||||||
| 
 |  | ||||||
| 			// XXX revise defaults...
 |  | ||||||
| 			var len = data.len || this.data.ribbons[ribbon].len |  | ||||||
| 			var total_len = data.total_len || this.data.length |  | ||||||
| 			var r_len = data.r_len || Object.keys(this.data.ribbons).length |  | ||||||
| 
 |  | ||||||
| 			var i = data.i || this.data.getImageOrder('ribbon', gid) |  | ||||||
| 			var I = data.I || this.data.getImageOrder('loaded', gid) |  | ||||||
| 			var r = data.r || this.data.getRibbonOrder(gid) |  | ||||||
| 			var R = data.R || r_len - r - 1 |  | ||||||
| 
 |  | ||||||
| 			// pad with zeros...
 |  | ||||||
| 			i = (i+'').padStart((len + '').length, '0') |  | ||||||
| 			I = (I+'').padStart((total_len + '').length, '0') |  | ||||||
| 			r = (r+'').padStart((r_len + '').length, '0') |  | ||||||
| 			R = (R+'').padStart((r_len + '').length, '0') |  | ||||||
| 			//i = ((('1e'+(len+'').length)*1 + i) + '').slice(1)
 |  | ||||||
| 			//I = ((('1e'+(total_len+'').length)*1 + I) + '').slice(1)
 |  | ||||||
| 
 |  | ||||||
| 			var conflicts = data.conflicts |  | ||||||
| 
 |  | ||||||
| 			return pattern |  | ||||||
| 				// file name...
 |  | ||||||
| 				.replace(/%n/, name.replace(ext, '')) |  | ||||||
| 
 |  | ||||||
| 				// gid...
 |  | ||||||
| 				.replace(/%gid/, gid) |  | ||||||
| 				// XXX get the correct short gid length...
 |  | ||||||
| 				.replace(/%g/, gid.slice(-6)) |  | ||||||
| 
 |  | ||||||
| 				// order...
 |  | ||||||
| 				.replace(/%i/, i) |  | ||||||
| 				.replace(/%I/, I) |  | ||||||
| 
 |  | ||||||
| 				// ribbon order...
 |  | ||||||
| 				.replace(/%r/, r) |  | ||||||
| 				.replace(/%r/, R) |  | ||||||
| 				 |  | ||||||
| 				// totals...
 |  | ||||||
| 				.replace(/%t/, len) |  | ||||||
| 				.replace(/%T/, total_len) |  | ||||||
| 
 |  | ||||||
| 				// conflict count...
 |  | ||||||
| 				.replace(/%c/, (conflicts && conflicts[gid]) ?  |  | ||||||
| 					conflicts[gid].indexOf(gid)  |  | ||||||
| 					: 0) |  | ||||||
| 
 |  | ||||||
| 				// metadata...
 |  | ||||||
| 				// XXX
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 				// Group patterns...
 |  | ||||||
| 
 |  | ||||||
| 				// tags...
 |  | ||||||
| 				// XXX test: %n%(b)b%(m)m%e
 |  | ||||||
| 				.replace( |  | ||||||
| 					/%\(([^)]*)\)m/, tags.indexOf('marked') >= 0 ? '$1' : '') |  | ||||||
| 				.replace( |  | ||||||
| 					/%\(([^)]*)\)b/, tags.indexOf('bookmark') >= 0 ? '$1' : '') |  | ||||||
| 				// XXX
 |  | ||||||
| 				//.replace(
 |  | ||||||
| 				//	/%\(([^)]*)\)k/, tags.indexOf('bookmark') >= 0 ? '$1' : '')
 |  | ||||||
| 
 |  | ||||||
| 				// conflicts...
 |  | ||||||
| 				.replace( |  | ||||||
| 					/%\(([^)]*)\)C/, conflicts ? '$1' : '') |  | ||||||
| 				.replace( |  | ||||||
| 					/%\(([^)]*)\)c/, (conflicts || {})[gid] ? '$1' : '') |  | ||||||
| 
 |  | ||||||
| 				// level...
 |  | ||||||
| 				.replace( |  | ||||||
| 					/%\(([^)]*)\)L/,  |  | ||||||
| 					function(match, level, offset, str){ |  | ||||||
| 						return (offset == 0 ? '' : '/')  |  | ||||||
| 							+(new Array(r*1)).fill(level).join('/') |  | ||||||
| 							+(match.length + offset == str.length ? '' : '/') }) |  | ||||||
| 				.replace( |  | ||||||
| 					/%\(([^)]*)\)l/, |  | ||||||
| 					function(match, level, offset, str){ |  | ||||||
| 						return (offset == 0 ? '' : '/')  |  | ||||||
| 							+(new Array(r_len - r*1 - 1)).fill(level).join('/') |  | ||||||
| 							+(match.length + offset == str.length ? '' : '/') }) |  | ||||||
| 
 |  | ||||||
| 				+ to_ext |  | ||||||
| 		}], |  | ||||||
| 	 |  | ||||||
| 	// XXX might also be good to save/load the export options to .ImageGrid-export.json
 | 	// XXX might also be good to save/load the export options to .ImageGrid-export.json
 | ||||||
| 	// XXX resolve env variables in path... (???)
 | 	// XXX resolve env variables in path... (???)
 | ||||||
| 	// XXX make custom previews (option)...
 | 	// XXX make custom previews (option)...
 | ||||||
| @ -2339,6 +2366,9 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 	exportDirs: ['- File/Export/Export ribbons as directories', | 	exportDirs: ['- File/Export/Export ribbons as directories', | ||||||
| 		core.doc`Export ribbons as directories
 | 		core.doc`Export ribbons as directories
 | ||||||
| 
 | 
 | ||||||
|  | 			.exportDirs(path) | ||||||
|  | 			.exportDirs(settings) | ||||||
|  | 
 | ||||||
| 		NOTE: see .formatImageName(..) for pattern syntax details. | 		NOTE: see .formatImageName(..) for pattern syntax details. | ||||||
| 		`,
 | 		`,
 | ||||||
| 		function(path, pattern, level_dir, size, include_virtual, clean_target_dir, logger){ | 		function(path, pattern, level_dir, size, include_virtual, clean_target_dir, logger){ | ||||||
| @ -2347,6 +2377,14 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 			var that = this | 			var that = this | ||||||
| 			var base_dir = this.location.path | 			var base_dir = this.location.path | ||||||
| 
 | 
 | ||||||
|  | 			if(typeof(path) != typeof('str')){ | ||||||
|  | 				settings = path | ||||||
|  | 				path = settings.path } | ||||||
|  | 			settings = this.config['export-settings'] || {} | ||||||
|  | 			// XXX resolve env variables in path...
 | ||||||
|  | 			// 		...also add ImageGrid specifics: $IG_INDEX, ...
 | ||||||
|  | 			// XXX
 | ||||||
|  | 			path = path || './exported-dirs' | ||||||
| 			path = util.normalizePath(path) | 			path = util.normalizePath(path) | ||||||
| 
 | 
 | ||||||
| 			// XXX resolve env variables in path...
 | 			// XXX resolve env variables in path...
 | ||||||
| @ -2357,8 +2395,7 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 					// and skip windows drives...
 | 					// and skip windows drives...
 | ||||||
| 					&& !/^[a-z]:[\\\/]/i.test(path)){ | 					&& !/^[a-z]:[\\\/]/i.test(path)){ | ||||||
| 				// XXX do we need to normalize???
 | 				// XXX do we need to normalize???
 | ||||||
| 				path = this.location.path +'/'+ path | 				path = this.location.path +'/'+ path } | ||||||
| 			} |  | ||||||
| 
 | 
 | ||||||
| 			var to_dir = path | 			var to_dir = path | ||||||
| 
 | 
 | ||||||
| @ -2366,16 +2403,22 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 			// XXX should this store the last set???
 | 			// XXX should this store the last set???
 | ||||||
| 			level_dir = level_dir === undefined ? | 			level_dir = level_dir === undefined ? | ||||||
| 				level_dir  | 				level_dir  | ||||||
| 				: (level_dir || this.config['export-level-directory-name'] || 'fav') | 				: (level_dir  | ||||||
| 			size = size || this.config['export-preview-size'] || 1000 | 					|| settings['level-directory-name']  | ||||||
| 			pattern = pattern || this.config['export-preview-name-pattern'] || '%f' | 						|| 'fav') | ||||||
|  | 			size = size  | ||||||
|  | 				|| settings['preview-size']  | ||||||
|  | 				|| 1000 | ||||||
|  | 			pattern = pattern  | ||||||
|  | 				|| settings['preview-name-pattern']  | ||||||
|  | 				|| '%f' | ||||||
| 			include_virtual = include_virtual === undefined ? | 			include_virtual = include_virtual === undefined ? | ||||||
| 				this.config['export-include-virtual'] | 				settings['include-virtual'] | ||||||
| 				: include_virtual | 				: include_virtual | ||||||
| 
 | 
 | ||||||
| 			// clear/backup target...
 | 			// clear/backup target...
 | ||||||
| 			clean_target_dir = clean_target_dir === undefined ?  | 			clean_target_dir = clean_target_dir === undefined ?  | ||||||
| 				this.config['export-clean-target']  | 				settings['clean-target']  | ||||||
| 				: clean_target_dir | 				: clean_target_dir | ||||||
| 			clean_target_dir | 			clean_target_dir | ||||||
| 				&& fse.existsSync(to_dir) | 				&& fse.existsSync(to_dir) | ||||||
| @ -2528,23 +2571,7 @@ module.FileSystemWriter = core.ImageGridFeatures.Feature({ | |||||||
| // 		- save if not base path present (browser)
 | // 		- save if not base path present (browser)
 | ||||||
| var FileSystemWriterUIActions = actions.Actions({ | var FileSystemWriterUIActions = actions.Actions({ | ||||||
| 	config: { | 	config: { | ||||||
| 		'export-dialog-mode': 'Full index', | 		// NOTE: for more docs on export settings see FileSystemWriter.config...
 | ||||||
| 
 |  | ||||||
| 		// export settings...
 |  | ||||||
| 		//
 |  | ||||||
| 		// NOTE: these are defined and set in .__export_dialog_fields__[..]
 |  | ||||||
| 		//'export-paths': [ .. ], 
 |  | ||||||
| 		//'export-preview-name-patterns': [ .. ],
 |  | ||||||
| 		//'export-preview-size-limits': [ .. ],
 |  | ||||||
| 		//
 |  | ||||||
| 		// XXX LEGACY: these settings have moved to 'export-settings' below...
 |  | ||||||
| 		//'export-dialog-mode': 'Images only',
 |  | ||||||
| 		//'export-path': './', 
 |  | ||||||
| 		//'export-preview-name-pattern': '%f',
 |  | ||||||
| 		//'export-preview-size': 1000,
 |  | ||||||
| 		//'export-preview-size-limit': 'no limit',
 |  | ||||||
| 		//'export-include-virtual': 'no',
 |  | ||||||
| 		//'export-clean-target': 'yes',
 |  | ||||||
| 
 | 
 | ||||||
| 		'export-dialog-modes': { | 		'export-dialog-modes': { | ||||||
| 			// XXX is this the right title???
 | 			// XXX is this the right title???
 | ||||||
| @ -2597,20 +2624,13 @@ var FileSystemWriterUIActions = actions.Actions({ | |||||||
| 		//		// NOTE: this is set/used by .exportDialog(..)
 | 		//		// NOTE: this is set/used by .exportDialog(..)
 | ||||||
| 		//		'mode': 'Images only',
 | 		//		'mode': 'Images only',
 | ||||||
| 		//
 | 		//
 | ||||||
| 		// 		// NOTE: these are defined and set in .__export_dialog_fields__[..]
 | 		//		// NOTE: for more info see FileSystemWriter.config['export-settings']...
 | ||||||
| 		//		'path': './', 
 | 		//		...
 | ||||||
| 		//		'preview-name-pattern': '%f',
 |  | ||||||
| 		//		'preview-size': 1000,
 |  | ||||||
| 		//		'preview-size-limit': 'no limit',
 |  | ||||||
| 		//		'include-virtual': 'no',
 |  | ||||||
| 		//		'clean-target': 'yes',
 |  | ||||||
| 		//
 |  | ||||||
| 		//		// ...
 |  | ||||||
| 		// 	}
 | 		// 	}
 | ||||||
| 		//
 | 		//
 | ||||||
| 		// XXX this will accumulate settings from all export modes, is this correct???
 | 		// XXX this will accumulate settings from all export modes, is this correct???
 | ||||||
| 		// XXX this is not yet used by the actual export actions, only for the UI...
 | 		// XXX this is not yet used by the actual export actions, only for the UI...
 | ||||||
| 		'export-settings': {}, | 		//'export-settings': {},
 | ||||||
| 
 | 
 | ||||||
| 		//
 | 		//
 | ||||||
| 		// Format:
 | 		// Format:
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user