From 915f951c8dcb690a9b9d2941885665ec59decd73 Mon Sep 17 00:00:00 2001 From: Darrell Mozingo Date: Wed, 24 Nov 2021 00:39:59 -0500 Subject: [PATCH] Use name from picasa for albums if available --- src/input/hierarchy.js | 30 ++++++++++++++++--------- src/input/picasa.js | 5 +---- src/steps/step-index.js | 2 +- test/input/hierarchy.spec.js | 43 +++++++++++++++++++++++++++--------- 4 files changed, 55 insertions(+), 25 deletions(-) diff --git a/src/input/hierarchy.js b/src/input/hierarchy.js index a84bc0b..023322d 100644 --- a/src/input/hierarchy.js +++ b/src/input/hierarchy.js @@ -2,22 +2,22 @@ const _ = require('lodash') const path = require('path') const Album = require('../model/album') -exports.createAlbums = function (collection, mapper, opts) { +exports.createAlbums = function (collection, mapper, opts, picasaReader) { // returns a top-level album for the home page // under which all files are grouped into sub-albums // and finalised recursively (calculate stats, etc...) - const home = group(collection, mapper, opts.homeAlbumName) + const home = group(collection, mapper, opts, picasaReader) home.finalize(opts) return home } -function group (collection, mapper, homeAlbumName) { +function group (collection, mapper, opts, picasaReader) { // this hashtable will contain all albums, with the full path as key // e.g. groups['holidays/tokyo'] var groups = { // the home album is indexed as '.' // the value of '.' is local to this function, and doesn't appear anywhere else - '.': new Album(homeAlbumName) + '.': new Album(opts.homeAlbumName) } // put all files in the right albums // a file can be in multiple albums @@ -29,7 +29,7 @@ function group (collection, mapper, homeAlbumName) { .uniq() .value() albums.forEach(albumPath => { - createAlbumHierarchy(groups, albumPath) + createAlbumHierarchy(groups, albumPath, opts, picasaReader) groups[albumPath].files.push(file) }) }) @@ -37,17 +37,27 @@ function group (collection, mapper, homeAlbumName) { return groups['.'] } -function createAlbumHierarchy (allGroupNames, segment) { +function createAlbumHierarchy (allGroupNames, segment, opts, picasaReader) { if (!allGroupNames.hasOwnProperty(segment)) { // create parent albums first - var parent = path.dirname(segment) + const parent = path.dirname(segment) if (parent !== '.') { - createAlbumHierarchy(allGroupNames, parent) + createAlbumHierarchy(allGroupNames, parent, opts, picasaReader) } + + const picasaName = getPicasaName(segment, opts, picasaReader) + const lastSegment = path.basename(segment) + const title = picasaName || lastSegment + // then create album if it doesn't exist // and attach it to its parent - var lastSegment = path.basename(segment) - allGroupNames[segment] = new Album({ title: lastSegment }) + allGroupNames[segment] = new Album({ title }) allGroupNames[parent].albums.push(allGroupNames[segment]) } } + +function getPicasaName (segment, opts, picasaReader) { + const fullPath = path.join(opts.input, segment) + const picasaFile = picasaReader.album(fullPath) + return picasaFile != null ? picasaFile.name : null +} diff --git a/src/input/picasa.js b/src/input/picasa.js index 0ef82e2..9a196e9 100644 --- a/src/input/picasa.js +++ b/src/input/picasa.js @@ -13,11 +13,8 @@ class Picasa { this.folders = {} } album (dir) { - if (!this.folders[dir]) { - this.folders[dir] = loadPicasa(dir) - } + const entry = loadPicasa(dir) // album metadata is stored in a section called [Picasa] - const entry = this.folders[dir] return entry.Picasa || null } file (filepath) { diff --git a/src/steps/step-index.js b/src/steps/step-index.js index a794d10..f7f2b88 100644 --- a/src/steps/step-index.js +++ b/src/steps/step-index.js @@ -51,7 +51,7 @@ exports.run = function (opts, callback) { // finished, we can create the albums emitter.on('done', stats => { const mapper = new AlbumMapper(opts.albumsFrom, opts) - const album = hierarchy.createAlbums(files, mapper, opts) + const album = hierarchy.createAlbums(files, mapper, opts, picasaReader) callback(null, files, album) observer.complete() }) diff --git a/test/input/hierarchy.spec.js b/test/input/hierarchy.spec.js index 8b3efb7..351dbd8 100644 --- a/test/input/hierarchy.spec.js +++ b/test/input/hierarchy.spec.js @@ -1,10 +1,13 @@ const path = require('path') const should = require('should/as-function') +const sinon = require('sinon') const hierarchy = require('../../src/input/hierarchy.js') const Album = require('../../src/model/album.js') const fixtures = require('../fixtures') +const Picasa = require('../../src/input/picasa') -const DEFAULT_OPTS = { homeAlbumName: 'Home' } +const DEFAULT_OPTS = { homeAlbumName: 'Home', input: '' } +const picasaReader = new Picasa() describe('hierarchy', function () { beforeEach(function () { @@ -14,7 +17,7 @@ describe('hierarchy', function () { describe('root album', function () { it('creates a root album (homepage) to put all sub-albums', function () { const mapper = mockMapper(file => ['all']) - const home = hierarchy.createAlbums([], mapper, DEFAULT_OPTS) + const home = hierarchy.createAlbums([], mapper, DEFAULT_OPTS, picasaReader) should(home.title).eql('Home') }) @@ -26,7 +29,7 @@ describe('hierarchy', function () { it('defaults the homepage to index.html', function () { const mapper = mockMapper(file => ['all']) - const home = hierarchy.createAlbums([], mapper, DEFAULT_OPTS) + const home = hierarchy.createAlbums([], mapper, DEFAULT_OPTS, picasaReader) should(home.path).eql('index.html') should(home.url).eql('index.html') }) @@ -48,7 +51,7 @@ describe('hierarchy', function () { fixtures.photo({ path: 'IMG_000002.jpg' }) ] const mapper = mockMapper(file => [value]) - const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS) + const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS, picasaReader) should(home.albums.length).eql(0) should(home.files.length).eql(2) should(home.files[0].filename).eql('IMG_000001.jpg') @@ -58,13 +61,33 @@ describe('hierarchy', function () { }) describe('nested albums', function () { + it('uses album title from Picasa file if available', function () { + const files = [ + fixtures.photo({ path: 'IMG_000001.jpg' }) + ] + const mapper = mockMapper(file => ['all']) + + const opts = { ...DEFAULT_OPTS, input: '/root' } + + const expectedPath = path.join(opts.input, 'all') + + const picasa = new Picasa() + sinon.stub(picasa, 'album').withArgs(expectedPath) + .returns({ name: 'picasa-name' }) + + const home = hierarchy.createAlbums(files, mapper, opts, picasa) + should(home.albums.length).eql(1) + should(home.albums[0].title).eql('picasa-name') + should(home.albums[0].files).eql([files[0]]) + }) + it('can group media into a single folder', function () { const files = [ fixtures.photo({ path: 'IMG_000001.jpg' }), fixtures.photo({ path: 'IMG_000002.jpg' }) ] const mapper = mockMapper(file => ['all']) - const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS) + const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS, picasaReader) should(home.albums.length).eql(1) should(home.albums[0].title).eql('all') should(home.albums[0].files).eql([files[0], files[1]]) @@ -76,7 +99,7 @@ describe('hierarchy', function () { fixtures.photo({ path: 'two/IMG_000002.jpg' }) ] const mapper = mockMapper(file => [path.dirname(file.path)]) - const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS) + const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS, picasaReader) should(home.albums.length).eql(2) should(home.albums[0].title).eql('one') should(home.albums[0].files).eql([files[0]]) @@ -90,7 +113,7 @@ describe('hierarchy', function () { fixtures.photo({ path: 'IMG_000002.jpg' }) ] const mapper = mockMapper(file => ['one/two']) - const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS) + const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS, picasaReader) should(home.albums.length).eql(1) should(home.albums[0].title).eql('one') should(home.albums[0].albums.length).eql(1) @@ -104,7 +127,7 @@ describe('hierarchy', function () { fixtures.photo({ path: 'one/two/IMG_000002.jpg' }) ] const mapper = mockMapper(file => [path.dirname(file.path)]) - const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS) + const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS, picasaReader) should(home.albums.length).eql(1) should(home.albums[0].title).eql('one') should(home.albums[0].files).eql([files[0]]) @@ -118,7 +141,7 @@ describe('hierarchy', function () { fixtures.photo({ path: 'one/IMG_000001.jpg' }) ] const mapper = mockMapper(file => ['.', '/', path.dirname(file.path)]) - const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS) + const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS, picasaReader) should(home.files.length).eql(1) should(home.files[0].filename).eql(files[0].filename) should(home.albums.length).eql(1) @@ -132,7 +155,7 @@ describe('hierarchy', function () { fixtures.photo({ path: 'one/IMG_000001.jpg' }) ] const mapper = mockMapper(file => ['one', path.dirname(file.path)]) - const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS) + const home = hierarchy.createAlbums(files, mapper, DEFAULT_OPTS, picasaReader) should(home.albums.length).eql(1) should(home.albums[0].title).eql('one') should(home.albums[0].files).eql(files)