diff --git a/src/input/picasa.js b/src/input/picasa.js index 9a196e9..02ecb2d 100644 --- a/src/input/picasa.js +++ b/src/input/picasa.js @@ -10,34 +10,32 @@ const path = require('path') class Picasa { constructor () { + // memory cache of all Picasa files read so far this.folders = {} } album (dir) { - const entry = loadPicasa(dir) + const entry = this.folderMetadata(dir) // album metadata is stored in a section called [Picasa] return entry.Picasa || null } file (filepath) { const dir = path.dirname(filepath) - if (!this.folders[dir]) { - this.folders[dir] = loadPicasa(dir) - } + const entry = this.folderMetadata(dir) // file metadata is stored in a section called [FileName.ext] - const entry = this.folders[dir] const filename = path.basename(filepath) const fileParts = filename.split('.') return getIniValue(entry, fileParts) } -} - -function loadPicasa (dirname) { - const inipath = path.join(dirname, 'picasa.ini') - const content = loadIfExists(inipath) - if (!content) { - // return an empty hash, as if the picasa.ini file existed but was empty - return {} - } else { - return ini.parse(content) + folderMetadata (dirname) { + // try reading from cache first + if (this.folders[dirname]) { + return this.folders[dirname] + } + // otherwise try to read the file from disk + const inipath = path.join(dirname, 'picasa.ini') + const content = loadIfExists(inipath) + this.folders[dirname] = content ? ini.parse(content) : {} + return this.folders[dirname] } } diff --git a/test/input/picasa.spec.js b/test/input/picasa.spec.js index b799b5d..c30afe4 100644 --- a/test/input/picasa.spec.js +++ b/test/input/picasa.spec.js @@ -1,3 +1,5 @@ +const fs = require('fs') +const sinon = require('sinon') const should = require('should/as-function') const Picasa = require('../../src/input/picasa.js') @@ -38,6 +40,14 @@ describe('Picasa', function () { const meta = picasa.album('holidays') should(meta).eql(null) }) + it('returns if the Picasa file is invalid', function () { + mock({ + 'holidays/picasa.ini': '[[invalid' + }) + const picasa = new Picasa() + const meta = picasa.album('holidays') + should(meta).eql(null) + }) it('returns raw file metadata as read from the INI file', function () { mock({ 'holidays/picasa.ini': PICASA_INI @@ -68,4 +78,16 @@ describe('Picasa', function () { const meta = picasa.file('holidays/IMG_0002.jpg') should(meta).eql(null) }) + it('only reads the file from disk once', function () { + mock({ + 'holidays/picasa.ini': PICASA_INI + }) + sinon.spy(fs, 'readFileSync') + const picasa = new Picasa() + picasa.album('holidays') + picasa.album('holidays') + picasa.file('holidays/IMG_0001.jpg') + picasa.file('holidays/IMG_0002.jpg') + should(fs.readFileSync.callCount).eql(1) + }) })