Use name from picasa for albums if available

pull/312/head
Darrell Mozingo 3 years ago committed by Romain
parent 54256dd2a4
commit 915f951c8d

@ -2,22 +2,22 @@ const _ = require('lodash')
const path = require('path') const path = require('path')
const Album = require('../model/album') 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 // returns a top-level album for the home page
// under which all files are grouped into sub-albums // under which all files are grouped into sub-albums
// and finalised recursively (calculate stats, etc...) // and finalised recursively (calculate stats, etc...)
const home = group(collection, mapper, opts.homeAlbumName) const home = group(collection, mapper, opts, picasaReader)
home.finalize(opts) home.finalize(opts)
return home 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 // this hashtable will contain all albums, with the full path as key
// e.g. groups['holidays/tokyo'] // e.g. groups['holidays/tokyo']
var groups = { var groups = {
// the home album is indexed as '.' // the home album is indexed as '.'
// the value of '.' is local to this function, and doesn't appear anywhere else // 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 // put all files in the right albums
// a file can be in multiple albums // a file can be in multiple albums
@ -29,7 +29,7 @@ function group (collection, mapper, homeAlbumName) {
.uniq() .uniq()
.value() .value()
albums.forEach(albumPath => { albums.forEach(albumPath => {
createAlbumHierarchy(groups, albumPath) createAlbumHierarchy(groups, albumPath, opts, picasaReader)
groups[albumPath].files.push(file) groups[albumPath].files.push(file)
}) })
}) })
@ -37,17 +37,27 @@ function group (collection, mapper, homeAlbumName) {
return groups['.'] return groups['.']
} }
function createAlbumHierarchy (allGroupNames, segment) { function createAlbumHierarchy (allGroupNames, segment, opts, picasaReader) {
if (!allGroupNames.hasOwnProperty(segment)) { if (!allGroupNames.hasOwnProperty(segment)) {
// create parent albums first // create parent albums first
var parent = path.dirname(segment) const parent = path.dirname(segment)
if (parent !== '.') { 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 // then create album if it doesn't exist
// and attach it to its parent // and attach it to its parent
var lastSegment = path.basename(segment) allGroupNames[segment] = new Album({ title })
allGroupNames[segment] = new Album({ title: lastSegment })
allGroupNames[parent].albums.push(allGroupNames[segment]) 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
}

@ -13,11 +13,8 @@ class Picasa {
this.folders = {} this.folders = {}
} }
album (dir) { album (dir) {
if (!this.folders[dir]) { const entry = loadPicasa(dir)
this.folders[dir] = loadPicasa(dir)
}
// album metadata is stored in a section called [Picasa] // album metadata is stored in a section called [Picasa]
const entry = this.folders[dir]
return entry.Picasa || null return entry.Picasa || null
} }
file (filepath) { file (filepath) {

@ -51,7 +51,7 @@ exports.run = function (opts, callback) {
// finished, we can create the albums // finished, we can create the albums
emitter.on('done', stats => { emitter.on('done', stats => {
const mapper = new AlbumMapper(opts.albumsFrom, opts) 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) callback(null, files, album)
observer.complete() observer.complete()
}) })

@ -1,10 +1,13 @@
const path = require('path') const path = require('path')
const should = require('should/as-function') const should = require('should/as-function')
const sinon = require('sinon')
const hierarchy = require('../../src/input/hierarchy.js') const hierarchy = require('../../src/input/hierarchy.js')
const Album = require('../../src/model/album.js') const Album = require('../../src/model/album.js')
const fixtures = require('../fixtures') 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 () { describe('hierarchy', function () {
beforeEach(function () { beforeEach(function () {
@ -14,7 +17,7 @@ describe('hierarchy', function () {
describe('root album', function () { describe('root album', function () {
it('creates a root album (homepage) to put all sub-albums', function () { it('creates a root album (homepage) to put all sub-albums', function () {
const mapper = mockMapper(file => ['all']) 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') should(home.title).eql('Home')
}) })
@ -26,7 +29,7 @@ describe('hierarchy', function () {
it('defaults the homepage to index.html', function () { it('defaults the homepage to index.html', function () {
const mapper = mockMapper(file => ['all']) 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.path).eql('index.html')
should(home.url).eql('index.html') should(home.url).eql('index.html')
}) })
@ -48,7 +51,7 @@ describe('hierarchy', function () {
fixtures.photo({ path: 'IMG_000002.jpg' }) fixtures.photo({ path: 'IMG_000002.jpg' })
] ]
const mapper = mockMapper(file => [value]) 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.albums.length).eql(0)
should(home.files.length).eql(2) should(home.files.length).eql(2)
should(home.files[0].filename).eql('IMG_000001.jpg') should(home.files[0].filename).eql('IMG_000001.jpg')
@ -58,13 +61,33 @@ describe('hierarchy', function () {
}) })
describe('nested albums', 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 () { it('can group media into a single folder', function () {
const files = [ const files = [
fixtures.photo({ path: 'IMG_000001.jpg' }), fixtures.photo({ path: 'IMG_000001.jpg' }),
fixtures.photo({ path: 'IMG_000002.jpg' }) fixtures.photo({ path: 'IMG_000002.jpg' })
] ]
const mapper = mockMapper(file => ['all']) 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.length).eql(1)
should(home.albums[0].title).eql('all') should(home.albums[0].title).eql('all')
should(home.albums[0].files).eql([files[0], files[1]]) should(home.albums[0].files).eql([files[0], files[1]])
@ -76,7 +99,7 @@ describe('hierarchy', function () {
fixtures.photo({ path: 'two/IMG_000002.jpg' }) fixtures.photo({ path: 'two/IMG_000002.jpg' })
] ]
const mapper = mockMapper(file => [path.dirname(file.path)]) 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.length).eql(2)
should(home.albums[0].title).eql('one') should(home.albums[0].title).eql('one')
should(home.albums[0].files).eql([files[0]]) should(home.albums[0].files).eql([files[0]])
@ -90,7 +113,7 @@ describe('hierarchy', function () {
fixtures.photo({ path: 'IMG_000002.jpg' }) fixtures.photo({ path: 'IMG_000002.jpg' })
] ]
const mapper = mockMapper(file => ['one/two']) 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.length).eql(1)
should(home.albums[0].title).eql('one') should(home.albums[0].title).eql('one')
should(home.albums[0].albums.length).eql(1) should(home.albums[0].albums.length).eql(1)
@ -104,7 +127,7 @@ describe('hierarchy', function () {
fixtures.photo({ path: 'one/two/IMG_000002.jpg' }) fixtures.photo({ path: 'one/two/IMG_000002.jpg' })
] ]
const mapper = mockMapper(file => [path.dirname(file.path)]) 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.length).eql(1)
should(home.albums[0].title).eql('one') should(home.albums[0].title).eql('one')
should(home.albums[0].files).eql([files[0]]) should(home.albums[0].files).eql([files[0]])
@ -118,7 +141,7 @@ describe('hierarchy', function () {
fixtures.photo({ path: 'one/IMG_000001.jpg' }) fixtures.photo({ path: 'one/IMG_000001.jpg' })
] ]
const mapper = mockMapper(file => ['.', '/', path.dirname(file.path)]) 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.length).eql(1)
should(home.files[0].filename).eql(files[0].filename) should(home.files[0].filename).eql(files[0].filename)
should(home.albums.length).eql(1) should(home.albums.length).eql(1)
@ -132,7 +155,7 @@ describe('hierarchy', function () {
fixtures.photo({ path: 'one/IMG_000001.jpg' }) fixtures.photo({ path: 'one/IMG_000001.jpg' })
] ]
const mapper = mockMapper(file => ['one', path.dirname(file.path)]) 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.length).eql(1)
should(home.albums[0].title).eql('one') should(home.albums[0].title).eql('one')
should(home.albums[0].files).eql(files) should(home.albums[0].files).eql(files)

Loading…
Cancel
Save