mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
reworked caching metadata...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
4cd1da4060
commit
da63da2f2c
@ -446,7 +446,7 @@ var ElectronHostActions = actions.Actions({
|
|||||||
...this.images[this.current]
|
...this.images[this.current]
|
||||||
}, function(c){
|
}, function(c){
|
||||||
electron.clipboard.write({
|
electron.clipboard.write({
|
||||||
title: that.images.getImageFileName(),
|
bookmark: that.images.getImageFileName(),
|
||||||
text: url,
|
text: url,
|
||||||
// XXX this seems not to work with images with exif
|
// XXX this seems not to work with images with exif
|
||||||
// orientation -- the ig orientation seems to be
|
// orientation -- the ig orientation seems to be
|
||||||
|
|||||||
@ -121,7 +121,7 @@ var MetadataReaderActions = actions.Actions({
|
|||||||
|
|
||||||
return new Promise(function(resolve, reject){
|
return new Promise(function(resolve, reject){
|
||||||
if(!force
|
if(!force
|
||||||
&& !(img.metadata || {}).ImageGridPartialMetadata){
|
&& (img.metadata || {}).ImageGridMetadata == 'full'){
|
||||||
return resolve(img.metadata) }
|
return resolve(img.metadata) }
|
||||||
|
|
||||||
fs.readFile(full_path, function(err, file){
|
fs.readFile(full_path, function(err, file){
|
||||||
@ -150,19 +150,20 @@ var MetadataReaderActions = actions.Actions({
|
|||||||
reject(data)
|
reject(data)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// store metadata...
|
|
||||||
// XXX
|
|
||||||
|
|
||||||
// convert to a real dict...
|
// convert to a real dict...
|
||||||
// NOTE: exiftool appears to return an array
|
// NOTE: exiftool appears to return an array
|
||||||
// object rather than an actual dict/object
|
// object rather than an actual dict/object
|
||||||
// and that is not JSON compatible....
|
// and that is not JSON compatible....
|
||||||
var m = {}
|
that.images[gid].metadata =
|
||||||
Object.keys(data).forEach(function(k){ m[k] = data[k] })
|
Object.assign(
|
||||||
|
// XXX do we need to update or overwrite??
|
||||||
that.images[gid].metadata = m
|
that.images[gid].metadata || {},
|
||||||
|
data,
|
||||||
// XXX
|
{
|
||||||
|
ImageGridMetadataReader: 'exiftool/ImageGrid',
|
||||||
|
// mark metadata as full read...
|
||||||
|
ImageGridMetadata: 'full',
|
||||||
|
})
|
||||||
that.markChanged
|
that.markChanged
|
||||||
&& that.markChanged('images', [gid]) }
|
&& that.markChanged('images', [gid]) }
|
||||||
|
|
||||||
|
|||||||
@ -342,8 +342,8 @@ var SharpActions = actions.Actions({
|
|||||||
&& Math.max(m.width, m.height) < size)
|
&& Math.max(m.width, m.height) < size)
|
||||||
|| (fit == 'outside'
|
|| (fit == 'outside'
|
||||||
&& Math.min(m.width, m.height) < size)){
|
&& Math.min(m.width, m.height) < size)){
|
||||||
logger && logger.emit('skipping', to)
|
skipping(gid)
|
||||||
return false }
|
return }
|
||||||
// continue...
|
// continue...
|
||||||
return img })
|
return img })
|
||||||
: Promise.resolve(img))
|
: Promise.resolve(img))
|
||||||
@ -362,8 +362,8 @@ var SharpActions = actions.Actions({
|
|||||||
fse.removeSync(to)
|
fse.removeSync(to)
|
||||||
// skip...
|
// skip...
|
||||||
} else {
|
} else {
|
||||||
logger && logger.emit('skipping', to)
|
skipping(gid)
|
||||||
return false } }
|
return } }
|
||||||
|
|
||||||
// write...
|
// write...
|
||||||
return img
|
return img
|
||||||
@ -508,7 +508,8 @@ var SharpActions = actions.Actions({
|
|||||||
if(!base_path){
|
if(!base_path){
|
||||||
var preview = img.preview = img.preview || {}
|
var preview = img.preview = img.preview || {}
|
||||||
preview[parseInt(size) + 'px'] = name
|
preview[parseInt(size) + 'px'] = name
|
||||||
that.markChanged('images', [gid]) }
|
that.markChanged
|
||||||
|
&& that.markChanged('images', [gid]) }
|
||||||
|
|
||||||
return [gid, size, name] }) }) })
|
return [gid, size, name] }) }) })
|
||||||
.flat()) }],
|
.flat()) }],
|
||||||
@ -519,13 +520,68 @@ var SharpActions = actions.Actions({
|
|||||||
// ...and/or have a generic abort protocol triggered when loading...
|
// ...and/or have a generic abort protocol triggered when loading...
|
||||||
// ...use task queue???
|
// ...use task queue???
|
||||||
// XXX make each section optional...
|
// XXX make each section optional...
|
||||||
// XXX revise name...
|
cacheMetadata: ['- Sharp|Image/',
|
||||||
cacheImageMetadata: ['- Sharp|Image/',
|
core.doc`Cache metadata
|
||||||
core.doc`
|
|
||||||
|
Cache metadata for current image...
|
||||||
|
.cacheMetadata()
|
||||||
|
.cacheMetadata('current')
|
||||||
|
-> promise([ gid | null ])
|
||||||
|
|
||||||
|
Force cache metadata for current image...
|
||||||
|
.cacheMetadata(true)
|
||||||
|
.cacheMetadata('current', true)
|
||||||
|
-> promise([ gid | null ])
|
||||||
|
|
||||||
|
Cache metadata for all images...
|
||||||
|
.cacheMetadata('all')
|
||||||
|
-> promise([ gid | null, .. ])
|
||||||
|
|
||||||
|
Force cache metadata for all images...
|
||||||
|
.cacheMetadata('all', true)
|
||||||
|
-> promise([ gid | null, .. ])
|
||||||
|
|
||||||
|
Cache metadata for specific images...
|
||||||
|
.cacheMetadata([ gid, .. ])
|
||||||
|
-> promise([ gid | null, .. ])
|
||||||
|
|
||||||
|
Force cache metadata for specific images...
|
||||||
|
.cacheMetadata([ gid, .. ], true)
|
||||||
|
-> promise([ gid | null, .. ])
|
||||||
|
|
||||||
|
|
||||||
|
NOTE: this will effectively update metadata format to the new spec...
|
||||||
`,
|
`,
|
||||||
function(images, logger){
|
function(images, logger){
|
||||||
var that = this
|
var that = this
|
||||||
|
|
||||||
|
// handle logging and processing list...
|
||||||
|
// NOTE: these will maintain .__metadata_reading helping
|
||||||
|
// avoid processing an image more than once at the same
|
||||||
|
// time...
|
||||||
|
var done = function(gid, msg){
|
||||||
|
logger && logger.emit(msg || 'done', gid)
|
||||||
|
if(that.__metadata_reading){
|
||||||
|
that.__metadata_reading.delete(gid)
|
||||||
|
if(that.__metadata_reading.size == 0){
|
||||||
|
delete that.__metadata_reading } }
|
||||||
|
return gid }
|
||||||
|
var skipping = function(gid){
|
||||||
|
return done(gid, 'skipping') }
|
||||||
|
|
||||||
|
var force = false
|
||||||
|
if(images === true){
|
||||||
|
force = true
|
||||||
|
images = null
|
||||||
|
|
||||||
|
} else if(logger === true){
|
||||||
|
force = true
|
||||||
|
logger = arguments[2] }
|
||||||
|
|
||||||
|
// NOTE: we are caching this to avoid messing things up when
|
||||||
|
// loading before this was finished...
|
||||||
|
var cached_images = this.images
|
||||||
|
|
||||||
// get/normalize images...
|
// get/normalize images...
|
||||||
//images = images || this.current
|
//images = images || this.current
|
||||||
images = images
|
images = images
|
||||||
@ -541,9 +597,12 @@ var SharpActions = actions.Actions({
|
|||||||
: images == 'current' ?
|
: images == 'current' ?
|
||||||
this.current
|
this.current
|
||||||
: images
|
: images
|
||||||
images = images instanceof Array ?
|
images = (images instanceof Array ?
|
||||||
images
|
images
|
||||||
: [images]
|
: [images])
|
||||||
|
.filter(function(gid){
|
||||||
|
return !that.__metadata_reading
|
||||||
|
|| !that.__metadata_reading.has(gid) })
|
||||||
|
|
||||||
logger = logger !== false ?
|
logger = logger !== false ?
|
||||||
(logger || this.logger)
|
(logger || this.logger)
|
||||||
@ -551,13 +610,6 @@ var SharpActions = actions.Actions({
|
|||||||
logger = logger && logger.push('Caching image metadata')
|
logger = logger && logger.push('Caching image metadata')
|
||||||
logger && logger.emit('queued', images)
|
logger && logger.emit('queued', images)
|
||||||
|
|
||||||
// NOTE: we are caching this to avoid messing things up when
|
|
||||||
// loading before this was finished...
|
|
||||||
var cached_images = this.images
|
|
||||||
|
|
||||||
var loaded = this.ribbons
|
|
||||||
&& new Set(this.ribbons.getImageGIDs())
|
|
||||||
|
|
||||||
/*/ XXX set this to tmp for .location.load =='loadImages'
|
/*/ XXX set this to tmp for .location.load =='loadImages'
|
||||||
// XXX add preview cache directory...
|
// XXX add preview cache directory...
|
||||||
// - user defined path
|
// - user defined path
|
||||||
@ -573,36 +625,62 @@ var SharpActions = actions.Actions({
|
|||||||
|
|
||||||
return images
|
return images
|
||||||
.mapChunks(function(gid){
|
.mapChunks(function(gid){
|
||||||
|
var img = cached_images[gid]
|
||||||
|
var path = img && that.getImagePath(gid)
|
||||||
|
;(that.__metadata_reading =
|
||||||
|
that.__metadata_reading || new Set())
|
||||||
|
.add(gid)
|
||||||
|
|
||||||
|
// skip...
|
||||||
|
if(!(img && path
|
||||||
|
&& (force
|
||||||
|
// high priority must be preset...
|
||||||
|
|| (img.orientation == null
|
||||||
|
&& img.flipped == null)
|
||||||
|
// update metadata...
|
||||||
|
|| (img.metadata || {}).ImageGridMetadata == null))){
|
||||||
|
skipping(gid)
|
||||||
|
return }
|
||||||
|
|
||||||
return sharp(that.getImagePath(gid))
|
return sharp(that.getImagePath(gid))
|
||||||
.metadata()
|
.metadata()
|
||||||
.catch(function(){
|
.catch(function(){
|
||||||
logger && logger.emit('skipping', gid) })
|
skipping(gid) })
|
||||||
.then(function(metadata){
|
.then(function(metadata){
|
||||||
// XXX what should we return in case of an error???
|
// no metadata...
|
||||||
if(metadata == null){
|
if(metadata == null){
|
||||||
|
skipping(gid)
|
||||||
return }
|
return }
|
||||||
|
|
||||||
var img = cached_images[gid]
|
|
||||||
|
|
||||||
var o = normalizeOrientation(metadata.orientation)
|
var o = normalizeOrientation(metadata.orientation)
|
||||||
// NOTE: we need to set orientation to something
|
;(force || img.orientation == null)
|
||||||
// or we'll check it again and again...
|
// NOTE: we need to set orientation to something
|
||||||
img.orientation = o.orientation || 0
|
// or we'll check it again and again...
|
||||||
img.flipped = o.flipped
|
&& (img.orientation = o.orientation || 0)
|
||||||
|
;(force || img.flipped == null)
|
||||||
|
&& (img.flipped = o.flipped)
|
||||||
|
|
||||||
|
// mark metadata as partially read...
|
||||||
|
// NOTE: this will intentionally overwrite the
|
||||||
|
// previous reader mark/mode...
|
||||||
|
img.metadata =
|
||||||
|
Object.assign(
|
||||||
|
img.metadata || {},
|
||||||
|
{
|
||||||
|
ImageGridMetadataReader: 'sharp/exif-reader/ImageGrid',
|
||||||
|
// mark metadata as partial read...
|
||||||
|
// NOTE: partial metadata will get reread by
|
||||||
|
// the metadata feature upon request...
|
||||||
|
ImageGridMetadata: 'partial',
|
||||||
|
})
|
||||||
|
|
||||||
// read the metadata...
|
// read the metadata...
|
||||||
var exif = metadata.exif
|
var exif = metadata.exif
|
||||||
&& exifReader(metadata.exif)
|
&& exifReader(metadata.exif)
|
||||||
exif
|
exif
|
||||||
&& Object.assign(
|
&& Object.assign(
|
||||||
(img.metadata = img.metadata || {}),
|
img.metadata,
|
||||||
exifReader2exiftool(exif),
|
exifReader2exiftool(exif))
|
||||||
// mark metadata as partial read...
|
|
||||||
//
|
|
||||||
// NOTE: partial metadata will get reread by
|
|
||||||
// the metadata feature upon request...
|
|
||||||
// XXX revise name...
|
|
||||||
{ ImageGridPartialMetadata: true })
|
|
||||||
|
|
||||||
// if image too large, generate preview(s)...
|
// if image too large, generate preview(s)...
|
||||||
// XXX EXPERIMENTAL...
|
// XXX EXPERIMENTAL...
|
||||||
@ -619,16 +697,16 @@ var SharpActions = actions.Actions({
|
|||||||
base_path,
|
base_path,
|
||||||
logger) }
|
logger) }
|
||||||
|
|
||||||
that.markChanged('images', [gid])
|
that.markChanged
|
||||||
|
&& that.markChanged('images', [gid])
|
||||||
logger && logger.emit('done', gid)
|
that.ribbons
|
||||||
|
|
||||||
// update loaded image to use the orientation...
|
|
||||||
loaded
|
|
||||||
&& loaded.has(gid)
|
|
||||||
&& that.ribbons.updateImage(gid)
|
&& that.ribbons.updateImage(gid)
|
||||||
|
|
||||||
return gid }) }) }],
|
return done(gid) }) }) }],
|
||||||
|
cacheAllMetadata: ['- Sharp|Image/',
|
||||||
|
core.doc`Cache all metadata
|
||||||
|
NOTE: this is a shorthand to .cacheMetadata('all', ..)`,
|
||||||
|
'cacheMetadata: "all" ...'],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -653,7 +731,7 @@ module.Sharp = core.ImageGridFeatures.Feature({
|
|||||||
// XXX this is best done in a thread + needs to be abortable (on .load(..))...
|
// XXX this is best done in a thread + needs to be abortable (on .load(..))...
|
||||||
['loadImages',
|
['loadImages',
|
||||||
function(){
|
function(){
|
||||||
this.cacheImageMetadata('all') }],
|
this.cacheMetadata('all') }],
|
||||||
//*/
|
//*/
|
||||||
|
|
||||||
// set orientation if not defined...
|
// set orientation if not defined...
|
||||||
@ -667,12 +745,12 @@ module.Sharp = core.ImageGridFeatures.Feature({
|
|||||||
// function(gid){
|
// function(gid){
|
||||||
['updateImage',
|
['updateImage',
|
||||||
function(_, gid){
|
function(_, gid){
|
||||||
var img = this.images[gid]
|
var that = this
|
||||||
img
|
this.cacheMetadata(gid, false)
|
||||||
&& img.orientation == null
|
.then(function([res]){
|
||||||
&& this.cacheImageMetadata(gid, false)
|
res
|
||||||
&& this.logger
|
&& that.logger
|
||||||
&& this.logger.emit('Caching metadata for', gid) }],
|
&& that.logger.emit('Cached metadata for', gid) }) }],
|
||||||
|
|
||||||
// XXX need to:
|
// XXX need to:
|
||||||
// - if image too large to set the preview to "loading..."
|
// - if image too large to set the preview to "loading..."
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user