mirror of https://github.com/thumbsup/thumbsup
Merge pull request #143 from thumbsup/output-structure
Support suffix based generated paths instead of folder groupspull/144/merge
commit
63990904d0
@ -0,0 +1,55 @@
|
||||
const path = require('path')
|
||||
const urljoin = require('url-join')
|
||||
|
||||
const BROWSER_SUPPORTED_EXT = /(jpg|jpeg|png|gif)$/i
|
||||
|
||||
exports.folders = function (filepath, rel, options = {}) {
|
||||
const dir = path.dirname(filepath)
|
||||
const name = path.basename(filepath, path.extname(filepath))
|
||||
const ext = path.extname(filepath).substr(1)
|
||||
const photoExt = photoExtension(filepath)
|
||||
const videoExt = options.videoFormat || 'mp4'
|
||||
switch (rel) {
|
||||
case 'photo:thumbnail': return `media/thumbs/${dir}/${name}.${photoExt}`
|
||||
case 'photo:large': return `media/large/${dir}/${name}.${photoExt}`
|
||||
case 'video:thumbnail': return `media/thumbs/${dir}/${name}.jpg`
|
||||
case 'video:poster': return `media/large/${dir}/${name}.jpg`
|
||||
case 'video:resized': return `media/large/${dir}/${name}.${videoExt}`
|
||||
case 'fs:copy': return `media/original/${dir}/${name}.${ext}`
|
||||
case 'fs:symlink': return `media/original/${dir}/${name}.${ext}`
|
||||
case 'fs:link': return join(options.linkPrefix, filepath)
|
||||
default: throw new Error(`Invalid relationship: ${rel}`)
|
||||
}
|
||||
}
|
||||
|
||||
exports.suffix = function (filepath, rel, options = {}) {
|
||||
const dir = path.dirname(filepath)
|
||||
const name = path.basename(filepath, path.extname(filepath))
|
||||
const ext = path.extname(filepath).substr(1)
|
||||
const photoExt = photoExtension(filepath)
|
||||
const videoExt = options.videoFormat || 'mp4'
|
||||
switch (rel) {
|
||||
case 'photo:thumbnail': return `media/${dir}/${name}_${ext}_thumb.${photoExt}`
|
||||
case 'photo:large': return `media/${dir}/${name}_${ext}_large.${photoExt}`
|
||||
case 'video:thumbnail': return `media/${dir}/${name}_${ext}_thumb.jpg`
|
||||
case 'video:poster': return `media/${dir}/${name}_${ext}_poster.jpg`
|
||||
case 'video:resized': return `media/${dir}/${name}_${ext}_large.${videoExt}`
|
||||
case 'fs:copy': return `media/${dir}/${name}.${ext}`
|
||||
case 'fs:symlink': return `media/${dir}/${name}.${ext}`
|
||||
case 'fs:link': return join(options.linkPrefix, filepath)
|
||||
default: throw new Error(`Invalid relationship: ${rel}`)
|
||||
}
|
||||
}
|
||||
|
||||
function photoExtension (filepath) {
|
||||
const extension = path.extname(filepath).substr(1)
|
||||
return extension.match(BROWSER_SUPPORTED_EXT) ? extension : 'jpg'
|
||||
}
|
||||
|
||||
function join (prefix, filepath) {
|
||||
if (prefix.match(/^https?:\/\//)) {
|
||||
return urljoin(prefix, filepath)
|
||||
} else {
|
||||
return path.join(prefix, filepath)
|
||||
}
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
const _ = require('lodash')
|
||||
const should = require('should/as-function')
|
||||
const structure = require('../../src/model/structure')
|
||||
|
||||
const folders = structure.folders
|
||||
const suffix = structure.suffix
|
||||
|
||||
describe('Structure', () => {
|
||||
describe('folders', () => {
|
||||
it('starts with <media>', () => {
|
||||
should(folders('holidays/IMG_0001.jpg', 'photo:thumbnail')).startWith('media/')
|
||||
should(folders('holidays/IMG_0001.jpg', 'photo:large')).startWith('media/')
|
||||
should(folders('holidays/IMG_0001.mp4', 'video:thumbnail')).startWith('media/')
|
||||
should(folders('holidays/IMG_0001.mp4', 'video:poster')).startWith('media/')
|
||||
should(folders('holidays/IMG_0001.mp4', 'video:resized')).startWith('media/')
|
||||
should(folders('holidays/IMG_0001.jpg', 'fs:copy')).startWith('media/')
|
||||
should(folders('holidays/IMG_0001.jpg', 'fs:symlink')).startWith('media/')
|
||||
})
|
||||
|
||||
it('adds thumbnails to a <thumbs> folder', () => {
|
||||
should(folders('holidays/IMG_0001.jpg', 'photo:thumbnail')).startWith('media/thumbs/holidays/')
|
||||
should(folders('holidays/IMG_0001.mp4', 'video:thumbnail')).startWith('media/thumbs/holidays/')
|
||||
})
|
||||
|
||||
it('adds large versions to a <large> folder', () => {
|
||||
should(folders('holidays/IMG_0001.jpg', 'photo:large')).startWith('media/large/holidays/')
|
||||
should(folders('holidays/IMG_0001.mp4', 'video:poster')).startWith('media/large/holidays/')
|
||||
should(folders('holidays/IMG_0001.mp4', 'video:resized')).startWith('media/large/holidays/')
|
||||
})
|
||||
|
||||
it('adds copies and links to an <original> folder', () => {
|
||||
should(folders('holidays/IMG_0001.jpg', 'fs:copy')).startWith('media/original/holidays/')
|
||||
should(folders('holidays/IMG_0001.jpg', 'fs:symlink')).startWith('media/original/holidays/')
|
||||
})
|
||||
|
||||
it('keeps the full original name for copies and links', () => {
|
||||
should(folders('holidays/IMG_0001.jpg', 'fs:copy')).endWith('IMG_0001.jpg')
|
||||
should(folders('holidays/IMG_0001.jpg', 'fs:symlink')).endWith('IMG_0001.jpg')
|
||||
})
|
||||
|
||||
it('preserves the photo thumbnail extension if supported', () => {
|
||||
// lower case
|
||||
should(folders('holidays/IMG_0001.jpg', 'photo:thumbnail')).endWith('IMG_0001.jpg')
|
||||
should(folders('holidays/IMG_0001.jpeg', 'photo:thumbnail')).endWith('IMG_0001.jpeg')
|
||||
should(folders('holidays/IMG_0001.png', 'photo:thumbnail')).endWith('IMG_0001.png')
|
||||
should(folders('holidays/IMG_0001.gif', 'photo:thumbnail')).endWith('IMG_0001.gif')
|
||||
// upper case
|
||||
should(folders('holidays/IMG_0001.JPG', 'photo:thumbnail')).endWith('IMG_0001.JPG')
|
||||
should(folders('holidays/IMG_0001.JPEG', 'photo:thumbnail')).endWith('IMG_0001.JPEG')
|
||||
should(folders('holidays/IMG_0001.PNG', 'photo:thumbnail')).endWith('IMG_0001.PNG')
|
||||
should(folders('holidays/IMG_0001.GIF', 'photo:thumbnail')).endWith('IMG_0001.GIF')
|
||||
})
|
||||
|
||||
it('changes the photo thumbnail extension to jpg if not supported', () => {
|
||||
should(folders('holidays/IMG_0001.tiff', 'photo:thumbnail')).endWith('IMG_0001.jpg')
|
||||
})
|
||||
|
||||
it('supports two different resized video extensions', () => {
|
||||
should(folders('holidays/IMG_0001.mov', 'video:resized', { videoFormat: 'mp4' })).endWith('IMG_0001.mp4')
|
||||
should(folders('holidays/IMG_0001.mov', 'video:resized', { videoFormat: 'webm' })).endWith('IMG_0001.webm')
|
||||
})
|
||||
|
||||
it('always uses jpg for video thumbnails and posters', () => {
|
||||
should(folders('holidays/IMG_0001.mp4', 'video:thumbnail')).endWith('IMG_0001.jpg')
|
||||
should(folders('holidays/IMG_0001.mp4', 'video:poster')).endWith('IMG_0001.jpg')
|
||||
})
|
||||
|
||||
it('can use a file system link', () => {
|
||||
const res = folders('holidays/IMG_0001.jpg', 'fs:link', { linkPrefix: '../..' })
|
||||
should(res).eql('../../holidays/IMG_0001.jpg')
|
||||
})
|
||||
|
||||
it('can use a remote HTTP link', () => {
|
||||
const res = folders('holidays/IMG_0001.jpg', 'fs:link', { linkPrefix: 'http://test.com' })
|
||||
should(res).eql('http://test.com/holidays/IMG_0001.jpg')
|
||||
})
|
||||
})
|
||||
|
||||
describe('suffix', () => {
|
||||
it('starts with <media>', () => {
|
||||
should(suffix('holidays/IMG_0001.jpg', 'photo:thumbnail')).startWith('media/')
|
||||
should(suffix('holidays/IMG_0001.jpg', 'photo:large')).startWith('media/')
|
||||
should(suffix('holidays/IMG_0001.mp4', 'video:thumbnail')).startWith('media/')
|
||||
should(suffix('holidays/IMG_0001.mp4', 'video:poster')).startWith('media/')
|
||||
should(suffix('holidays/IMG_0001.mp4', 'video:resized')).startWith('media/')
|
||||
should(suffix('holidays/IMG_0001.jpg', 'fs:copy')).startWith('media/')
|
||||
should(suffix('holidays/IMG_0001.jpg', 'fs:symlink')).startWith('media/')
|
||||
})
|
||||
|
||||
it('uses an _thumb suffix to denote thumbnails', () => {
|
||||
should(suffix('holidays/IMG_0001.jpg', 'photo:thumbnail')).endWith('holidays/IMG_0001_jpg_thumb.jpg')
|
||||
should(suffix('holidays/IMG_0001.mp4', 'video:thumbnail')).endWith('holidays/IMG_0001_mp4_thumb.jpg')
|
||||
})
|
||||
|
||||
it('uses a _large suffix to resized versions', () => {
|
||||
should(suffix('holidays/IMG_0001.jpg', 'photo:large')).endWith('holidays/IMG_0001_jpg_large.jpg')
|
||||
should(suffix('holidays/IMG_0001.mp4', 'video:resized')).endWith('holidays/IMG_0001_mp4_large.mp4')
|
||||
})
|
||||
|
||||
it('uses a _poster suffix for the video poster', () => {
|
||||
should(suffix('holidays/IMG_0001.jpg', 'video:poster')).endWith('holidays/IMG_0001_jpg_poster.jpg')
|
||||
})
|
||||
|
||||
it('uses the original filenames for copies and symlinks', () => {
|
||||
should(suffix('holidays/IMG_0001.jpg', 'fs:copy')).endWith('holidays/IMG_0001.jpg')
|
||||
should(suffix('holidays/IMG_0001.jpg', 'fs:symlink')).endWith('holidays/IMG_0001.jpg')
|
||||
})
|
||||
|
||||
it('does not have conflicts between generated photo and video files', () => {
|
||||
// photos
|
||||
const photoRels = ['photo:thumbnail', 'photo:large', 'fs:copy']
|
||||
const photos = photoRels.map(rel => suffix('holidays/IMG_0001.jpg', rel))
|
||||
// videos
|
||||
const videoRels = ['video:thumbnail', 'video:poster', 'video:resized', 'fs:copy']
|
||||
const videos = videoRels.map(rel => suffix('holidays/IMG_0001.mp4', rel, { videoFormat: 'mp4' }))
|
||||
// check
|
||||
const all = _.union(photos, videos)
|
||||
should(_.uniq(all).length).eql(all.length)
|
||||
})
|
||||
|
||||
it('can use a file system link', () => {
|
||||
const res = suffix('holidays/IMG_0001.jpg', 'fs:link', { linkPrefix: '../..' })
|
||||
should(res).eql('../../holidays/IMG_0001.jpg')
|
||||
})
|
||||
|
||||
it('can use a remote HTTP link', () => {
|
||||
const res = suffix('holidays/IMG_0001.jpg', 'fs:link', { linkPrefix: 'http://test.com' })
|
||||
should(res).eql('http://test.com/holidays/IMG_0001.jpg')
|
||||
})
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue