diff --git a/README.md b/README.md
index 0a69e5afd..a701bcd25 100644
--- a/README.md
+++ b/README.md
@@ -1,110 +1,102 @@
-history
-=======
-
-Your personal **history** storyboarded with photo and video albums. Associate photos with their meta data including geocode, caption, friends (characters)... in XML albums.
-* Plot thumbnails on a map
-* Code runs on static web hosts
-* Includes administration tools for XML generation
-* Free & open source (dependant on other open source projects see indiviual licenses)
-
-[Demo site 0.15.0](http://danactive.github.io/history/)
-
-
-Basic Demo Usage
-------
-
-* Clone this repository.
-* Open Index.htm in Firefox.
-* Click View Photo Galleries.
-* Click Sample.
-* From there it becomes more obvious.
-
-Technologies
-------
-####Viewing
-* XML databases for photo/video galleries
-* XSLT to transform XML to HTML/CSS/JavaScript/jQuery
-* JavaScript/jQuery for the pagination & lightbox
-
-####Administration
-* Node.js to support AJAX & image manipulation
-* AJAX to read the XML gallery data
-
-
-Dependancies
-------
-Included in this project
-* [jQuery](http://jquery.com/) via bower
-* [ColorBox (jQuery plugin)](http://www.jacklmoore.com/colorbox) via bower
-* [Mapstraction (mapping)](http://mapstraction.com/) build 2.0.18
-* [Google Maps (map provider)](https://developers.google.com/maps/) v3
-* [Twitter Bootstrap (admin)](http://twitter.github.com/bootstrap/) v2.0.3
-* [Fluid 960 Grid System (admin)](http://www.designinfluences.com/fluid960gs/)
-
-To use the administration tools
-* [node.js](http://nodejs.org/)
-* [hapi.js](http://hapijs.org/)
-* [GraphicsMagick](https://www.npmjs.com/package/gm) Install GraphicsMagick before npm
-* [bower](http://bower.io/) via npm
- * npm install -g bower
-
-Folder structures
--------
-* admin/ - administration files for generating XML. Copy and paste the XML structure into the albums
-* gallery-demo/ - demonstration of a gallery with the sample album inside
-* node_modules/ - Backup of installed modules for Node.js
-* .gitignore - blacklist files/folders for GitHub
-* README.md - this file
-* index.htm - Home page when avoiding Node.js
-* video.htm - Reads a query string and generates the HTML5 video tags
-* app.js - Node.js code for creating a web server
-* webserver_node START.bat - (Windows) Executes the Node.js web server for localhost viewing and administration image manipulation
-* webserver_node VIEW.url - (Windows) Opens http://localhost in default browser
-
-Photo/video album XML schemas
--------
-### Current schema (2.0)
-
-Example
-
-
-
- demo
- sample
- 1.8
-
- -
- 1
- 2001-03-21-01.jpg
-
- 49.25
- -123.1
-
- Vancouver, BC
- Granville Island
- An oversized avocado
- Lunch
-
- -
- 1
- 2012-fireplace.mp4
- 2012-fireplace.webm
- Vancouver, BC
- Home
- Video: Fireplace
- A sample HTML5 video in both MP4 and WebM formats
- 1280720
-
- 49.25
- -123.1
-
-
-
-
-License
--------
-History is open-source and released under the [BSD License.](http://www.opensource.org/licenses/bsd-license.php)
-
-Versioning
--------
-http://semver.org/
+history
+=======
+
+Your personal **history** storyboarded with photo and video albums. Associate photos with their meta data including geocode, caption, friends (characters)... in XML albums.
+* Plot thumbnails on a map
+* Code runs on static web hosts
+* Includes administration tools for XML generation
+* Free & open source (dependant on other open source projects see indiviual licenses)
+
+[Demo site 0.15.0](http://danactive.github.io/history/)
+
+
+Basic Demo Usage
+------
+
+* Clone this repository.
+* Open Index.htm in Firefox.
+* Click View Photo Galleries.
+* Click Sample.
+* From there it becomes more obvious.
+
+Technologies
+------
+####Viewing
+* XML databases for photo/video galleries
+* XSLT to transform XML to HTML/CSS/JavaScript/jQuery
+* JavaScript/jQuery for the pagination & lightbox
+
+####Administration
+* Node.js to support AJAX & image manipulation
+* AJAX to read the XML gallery data
+
+
+Dependancies
+------
+Included in this project
+* [jQuery](http://jquery.com/) via bower
+* [ColorBox (jQuery plugin)](http://www.jacklmoore.com/colorbox) via bower
+* [Mapstraction (mapping)](http://mapstraction.com/) build 2.0.18
+* [Google Maps (map provider)](https://developers.google.com/maps/) v3
+* [Twitter Bootstrap (admin)](http://twitter.github.com/bootstrap/) v2.0.3
+* [Fluid 960 Grid System (admin)](http://www.designinfluences.com/fluid960gs/)
+
+To use the administration tools
+* [node.js](http://nodejs.org/)
+* [hapi.js](http://hapijs.org/)
+* [GraphicsMagick](https://www.npmjs.com/package/gm) Install GraphicsMagick before npm
+* [bower](http://bower.io/) via npm
+ * npm install -g bower
+
+Folder structures
+-------
+* admin/ - administration files for generating XML. Copy and paste the XML structure into the albums
+* gallery-demo/ - demonstration of a gallery with the sample album inside
+* node_modules/ - Backup of installed modules for Node.js
+* .gitignore - blacklist files/folders for GitHub
+* README.md - this file
+* index.htm - Home page when avoiding Node.js
+* video.htm - Reads a query string and generates the HTML5 video tags
+* app.js - Node.js code for creating a web server
+* webserver_node START.bat - (Windows) Executes the Node.js web server for localhost viewing and administration image manipulation
+* webserver_node VIEW.url - (Windows) Opens http://localhost in default browser
+
+Photo/video album XML schemas
+-------
+### Current schema (2.0)
+
+Example
+
+
+
+ demo
+ sample
+ 1.8
+
+ -
+ 1
+ 2001-03-21-01.jpg
+
+ 49.25
+ -123.1
+
+ Vancouver, BC
+ Granville Island
+ An oversized avocado
+ Lunch
+
+ -
+ 1
+ 2012-fireplace.mp4
+ 2012-fireplace.webm
+ Vancouver, BC
+ Home
+ Video: Fireplace
+ A sample HTML5 video in both MP4 and WebM formats
+ 1280720
+
+ 49.25
+ -123.1
+
+
+
diff --git a/changelog.md b/changelog.md
index b89850b79..764d61301 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,14 @@
# Changelog
+### 1.3.0 - hapi plugins for exists and rename
+#### 2016-Feb-09
+* Exist green code coverage
+* Rename green code coverage
+* Dev-mode no gulp
+
+### 1.2.0 - hapi.js v12
+#### 2016-Jan-30
+
### 1.1.0 - Up-to-date and passes
#### 2016-Jan-24
* All tests pass
@@ -75,4 +84,4 @@
* Sample album with three Vancouver markers on map
* jQuery v1.7.2
* Mapstraction Build 2.0.18 - pre-release using Google Maps v3
-* ColorBox v1.3.19
\ No newline at end of file
+* ColorBox v1.3.19
diff --git a/package.json b/package.json
index 18f22842d..3f98ecc62 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"gulp-mocha": "^2.2.0",
"gulp-plumber": "^1.0.1",
"gulp-rename": "^1.2.0",
+ "lout": "^8.1.1",
"node-notifier": "^4.1.2"
},
"scripts": {
@@ -67,9 +68,8 @@
},
"homepage": "https://github.com/danactive/history",
"engines": {
- "node": ">=0.10.35"
+ "npm": ">3"
},
"readmeFilename": "README.md",
- "tuxharness": "./tuxharness.js",
- "engines" : { "npm" : ">3" }
+ "tuxharness": "./tuxharness.js"
}
diff --git a/plugins/exists/lib/index.js b/plugins/exists/lib/index.js
index ddc98225b..f1f0f0c2d 100644
--- a/plugins/exists/lib/index.js
+++ b/plugins/exists/lib/index.js
@@ -1,35 +1,23 @@
'use strict';
-/*
-* #######
-* # # # # #### ##### ####
-* # # # # # # #
-* ##### ## # #### # ####
-* # ## # # # #
-* # # # # # # # # #
-* ####### # # # #### # ####
-*
-*/
/**
Verify if a path exists on the file system
-@method folderExists
-@param {string} path absolute path (file or folder) on the file system
+@method pathExists
+@param {string} path relative/absolute path (file or folder) on the file system
@param {promise}
**/
-function folderExists(verifyPath) {
+function pathExists(verifyPath) {
return new Promise((resolve, reject) => {
- const fs = require('fs');
- const appRoot = require('app-root-path');
- let verifiedPath = verifyPath;
-
- if (verifyPath.charAt(0) === '.' || verifyPath.charAt(0) === '/') { // convert relative to absolute
- verifiedPath = appRoot.resolve(verifyPath);
+ const boom = require('boom');
+ if (verifyPath === undefined) {
+ reject(boom.notFound(`pathExists module: is missing a path to verify`));
}
+ const verifiedPath = require('path').isAbsolute(verifyPath) ?
+ verifyPath : require('app-root-path').resolve(verifyPath);
- fs.stat(verifiedPath, (error, type) => {
- const boom = require('boom');
+ require('fs').stat(verifiedPath, (error, type) => {
if (error) {
- return reject(boom.notFound(`File system path is missing ${error}`));
+ return reject(boom.notFound(`pathExists module: File system path is missing ${error}`));
}
if (type.isFile() || type.isDirectory()) {
return resolve(verifiedPath);
@@ -37,4 +25,4 @@ function folderExists(verifyPath) {
});
});
}
-exports.folderExists = folderExists;
+exports.pathExists = pathExists;
diff --git a/plugins/exists/package.json b/plugins/exists/package.json
index 5f874d50b..3d6ca888c 100644
--- a/plugins/exists/package.json
+++ b/plugins/exists/package.json
@@ -1,6 +1,6 @@
{
"name": "history-exists",
- "version": "1.2.0",
+ "version": "2.0.0",
"description": "Verify if folder path exists",
"main": "index.js",
"scripts": {
diff --git a/plugins/exists/test/index.js b/plugins/exists/test/index.js
index 651966bc6..13792ca3d 100644
--- a/plugins/exists/test/index.js
+++ b/plugins/exists/test/index.js
@@ -3,30 +3,30 @@ const test = require('tape');
test('Real relative file exists', (assert) => {
const module = require('../lib');
- const testFolder = './plugins/exists/test/fixtures/exists.txt';
+ const testPath = './plugins/exists/test/fixtures/exists.txt';
- module.folderExists(testFolder)
+ module.pathExists(testPath)
.then(() => {
assert.pass('Resolved promise is returned');
assert.end();
})
.catch(() => {
- assert.fail(`File system is missing folder (${testFolder})`);
+ assert.fail(`File system is missing folder (${testPath})`);
assert.end();
});
});
test('Real relative folder exists', (assert) => {
const module = require('../lib');
- const testFolder = './plugins/exists/test/fixtures';
+ const testPath = './plugins/exists/test/fixtures';
- module.folderExists(testFolder)
+ module.pathExists(testPath)
.then(() => {
assert.pass('Resolved promise is returned');
assert.end();
})
.catch(() => {
- assert.fail(`File system is missing folder (${testFolder})`);
+ assert.fail(`File system is missing folder (${testPath})`);
assert.end();
});
});
@@ -34,15 +34,15 @@ test('Real relative folder exists', (assert) => {
test('Real absolute file exists', (assert) => {
const module = require('../lib');
const path = require('path');
- const testFolder = path.join(__dirname, './fixtures/exists.txt');
+ const testPath = path.join(__dirname, './fixtures/exists.txt');
- module.folderExists(testFolder)
+ module.pathExists(testPath)
.then((verifiedPath) => {
- assert.equal(verifiedPath, testFolder, 'Resolved path matches');
+ assert.equal(verifiedPath, testPath, 'Resolved path matches');
assert.end();
})
.catch(() => {
- assert.fail(`File system is missing folder (${testFolder})`);
+ assert.fail(`File system is missing folder (${testPath})`);
assert.end();
});
});
@@ -50,15 +50,15 @@ test('Real absolute file exists', (assert) => {
test('Real absolute folder exists', (assert) => {
const module = require('../lib');
const path = require('path');
- const testFolder = path.join(__dirname, './fixtures');
+ const testPath = path.join(__dirname, './fixtures');
- module.folderExists(testFolder)
+ module.pathExists(testPath)
.then((verifiedPath) => {
- assert.equal(verifiedPath, testFolder, 'Resolved path matches');
+ assert.equal(verifiedPath, testPath, 'Resolved path matches');
assert.end();
})
.catch(() => {
- assert.fail(`File system is missing folder (${testFolder})`);
+ assert.fail(`File system is missing folder (${testPath})`);
assert.end();
});
});
@@ -66,11 +66,11 @@ test('Real absolute folder exists', (assert) => {
test('Fake absolute path does not exists', (assert) => {
const module = require('../lib');
const path = require('path');
- const testFolder = path.join(__dirname, './fixtures/fakeFolder');
+ const testPath = path.join(__dirname, './fixtures/fakeFolder');
- module.folderExists(testFolder)
+ module.pathExists(testPath)
.then(() => {
- assert.fail(`File system found a fake folder (${testFolder})`);
+ assert.fail(`File system found a fake folder (${testPath})`);
assert.end();
})
.catch((error) => {
diff --git a/plugins/rename/lib/index.js b/plugins/rename/lib/index.js
index bc7df683a..db7be62d1 100644
--- a/plugins/rename/lib/index.js
+++ b/plugins/rename/lib/index.js
@@ -9,11 +9,17 @@ exports.register = (server, options, next) => {
config: {
handler: (request, reply) => {
const filenames = request.payload.filenames;
- require('../../exists/lib').folderExists(request.payload.source_folder)
+ require('../../exists/lib').pathExists(request.payload.source_folder)
.then(() => require('./filenames').getFutureFilenames(request.payload.prefix, filenames.length))
.then((futureFilenames) => {
- require('./rename').renamePaths(request.payload.source_folder, filenames, futureFilenames.filenames);
- reply(futureFilenames.xml);
+ require('./rename').renamePaths(
+ request.payload.source_folder,
+ filenames,
+ futureFilenames.filenames,
+ {
+ renameAssociated: request.payload.rename_associated,
+ });
+ reply({ xml: futureFilenames.xml });
})
.catch((error) => {
let boomError;
@@ -26,13 +32,24 @@ exports.register = (server, options, next) => {
reply(boomError);
});
},
- tags: ['api'],
+ tags: ['api', 'plugin', 'v1'],
validate: {
payload: {
- filenames: joi.array().items(joi.string().regex(/^[-\w^&'@{}[\],$=!#().%+~ ]+$/)).min(1).max(80).required(),
- prefix: joi.string().isoDate().required(),
- source_folder: joi.string().trim().required(),
- target_folder: joi.string().trim(),
+ filenames: joi.array().items(joi.string().regex(/^[-\w^&'@{}[\],$=!#().%+~ ]+$/))
+ .min(1).max(80).required().example('["DSC01229.JPG"]'),
+ prefix: joi.string().isoDate().required().example('2016-12-31'),
+ source_folder: joi.string().trim().required().example('/public/todo/'),
+ rename_associated: joi.boolean().default(false)
+ .description(`JPG and RAW or video and still image are common ` +
+ `associated pairs that should rename together`),
+ },
+ },
+ response: {
+ schema: {
+ xml: joi.string().required().regex(/]*>(.*?)<\/photo>/)
+ .example(`2016-04-05-37.jpg` +
+ `2016-04-05-64.jpg` +
+ `2016-04-05-90.jpg`),
},
},
},
diff --git a/plugins/rename/lib/rename.js b/plugins/rename/lib/rename.js
index c43c80175..4f1a45f8f 100644
--- a/plugins/rename/lib/rename.js
+++ b/plugins/rename/lib/rename.js
@@ -1,4 +1,49 @@
'use strict';
+
+/**
+Find associated path and filename based on file without extension
+
+@method findAssociated
+@param {string} [sourceFolder] Folder that contains the raw camera photo files
+@param {string} [filename] path and filename with or without extension
+@return {Promise} array of string associated filenames with absolute path
+**/
+function findAssociated(sourceFolder, filename) {
+ return new Promise((resolve, reject) => {
+ const path = require('path');
+ const absolutePath = path.isAbsolute(sourceFolder) ? path.join(sourceFolder, filename) :
+ require('app-root-path').resolve(path.join('../../', sourceFolder, filename));
+ const file = absolutePath.substr(0, absolutePath.length - path.extname(absolutePath).length); // strip extension
+
+ require('glob')(`${file}.*`, (error, files) => {
+ if (error) {
+ reject(require('boom').wrap(error));
+ }
+ resolve(files);
+ });
+ });
+}
+exports.findAssociated = findAssociated;
+
+/**
+Reassign associated filename based on file without extension
+
+@method reassignAssociated
+@param {string[]} [absoluteFolderFilenames] Filenames that contains the raw camera photo files with absolute path
+@param {string} [futureFile] Future file (without extension) of renamed new name based on date
+@return {Promise} associated filenames with path
+**/
+function reassignAssociated(absoluteFolderFilenames, futureFile) {
+ return new Promise((resolve) => {
+ const path = require('path');
+ resolve(absoluteFolderFilenames.map(filename => {
+ const fileParts = path.parse(filename);
+ return path.join(fileParts.dir, futureFile + fileParts.ext);
+ }));
+ });
+}
+exports.reassignAssociated = reassignAssociated;
+
/**
Renamed file paths
@@ -6,38 +51,80 @@ Renamed file paths
@param {string} [sourceFolder] Folder that contains the raw camera photo files
@param {string[]} [filenames] Current filenames (file and extension) of raw camera photo files
@param {string[]} [futureFilenames] Future filenames (file and extension) of renamed camera photo files
-@return {json}
+@param {object} options Additional optional options
+@param {bool} options.renameAssociated Find matching files with different extensions, then rename them
+@return {Promise}
**/
-function renamePaths(sourceFolder, filenames, futureFilenames) {
+function renamePaths(sourceFolder, filenames, futureFilenames, _options) {
return new Promise((resolve, reject) => {
const fs = require('fs');
const exists = require('../../exists/lib');
const boom = require('boom');
- const q = require('async').queue((rename, next) => {
- exists.folderExists(rename.oldName)
- .then(() => {
- fs.rename(rename.oldName, rename.newName, (error) => {
- if (error) {
- reject(boom.wrap(error));
- }
- next();
- });
- })
+ const options = _options || {};
+ const async = require('async');
+
+ const q = async.queue((rename, next) => {
+ function renameFile() {
+ fs.rename(rename.oldName, rename.newName, (error) => {
+ if (error) {
+ reject(boom.wrap(error));
+ }
+ next();
+ });
+ }
+ exists.pathExists(rename.oldName)
+ .then(renameFile)
.catch((error) => {
reject(boom.wrap(error));
});
}, 2);
+ {
+ const path = require('path');
+ const fullPath = require('app-root-path').resolve(path.join('../../', sourceFolder, '/'));
+ const filenamePairs = filenames.map((filename, index) => {
+ return { current: filename, future: futureFilenames[index] };
+ });
+ const transformFilenames = (pair, cb) => {
+ if (options.renameAssociated) {
+ let oldNames;
+ findAssociated(fullPath, pair.current)
+ .then(associatedFilenames => {
+ oldNames = associatedFilenames;
+ const endWithoutExt = pair.future.length - path.extname(pair.future).length;
+ const futureFile = pair.future.substr(0, endWithoutExt); // strip extension
+ return reassignAssociated(associatedFilenames, futureFile);
+ })
+ .then(reassignFilenames => {
+ const reassignPairs = oldNames.map((oldName, index) => {
+ return { oldName, newName: reassignFilenames[index] };
+ });
+ return cb(null, reassignPairs);
+ });
+ } else {
+ const oldName = fullPath + pair.current;
+ const newName = fullPath + pair.future;
+
+ return cb(null, { oldName, newName });
+ }
+ };
+ async.map(filenamePairs, transformFilenames, (error, transformedPairs) => {
+ if (error) {
+ throw boom.wrap(error);
+ }
+
+ if (Array.isArray(transformedPairs)) {
+ transformedPairs.forEach((pair) => {
+ q.push(pair);
+ });
+ } else {
+ q.push(transformedPairs);
+ }
+ });
+ }
+
// assign a callback
q.drain = () => resolve(true);
-
- const path = require('path');
- const appRoot = require('app-root-path');
- filenames.forEach((filename, index) => {
- const oldName = appRoot.resolve(path.join('../../', sourceFolder, filename));
- const newName = appRoot.resolve(path.join('../../', sourceFolder, futureFilenames[index]));
- q.push({ oldName, newName });
- });
});
}
exports.renamePaths = renamePaths;
diff --git a/plugins/rename/package.json b/plugins/rename/package.json
index c37fabba8..5001c8a78 100644
--- a/plugins/rename/package.json
+++ b/plugins/rename/package.json
@@ -1,6 +1,6 @@
{
"name": "history-rename",
- "version": "1.1.0",
+ "version": "2.0.0",
"description": "Rename files",
"main": "index.js",
"scripts": {
@@ -29,6 +29,7 @@
"npm": ">3"
},
"dependencies": {
- "app-root-path": "^1.0.0"
+ "app-root-path": "^1.0.0",
+ "glob": "^7.0.0"
}
}
diff --git a/plugins/rename/test/fixtures/renameable/bee.bat b/plugins/rename/test/fixtures/renameable/bee.bat
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/rename/test/fixtures/renameable/bee.bin b/plugins/rename/test/fixtures/renameable/bee.bin
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/rename/test/fixtures/renameable/bee.bmp b/plugins/rename/test/fixtures/renameable/bee.bmp
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/rename/test/fixtures/renameable/dee.dat b/plugins/rename/test/fixtures/renameable/dee.dat
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/rename/test/fixtures/renameable/dee.doc b/plugins/rename/test/fixtures/renameable/dee.doc
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/rename/test/fixtures/renameable/dee.docx b/plugins/rename/test/fixtures/renameable/dee.docx
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/rename/test/fixtures/renameable/el.log b/plugins/rename/test/fixtures/renameable/el.log
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/rename/test/fixtures/renameable/em.md b/plugins/rename/test/fixtures/renameable/em.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/rename/test/fixtures/renameable/pee.pdf b/plugins/rename/test/fixtures/renameable/pee.pdf
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/rename/test/fixtures/renameable/pee.psd b/plugins/rename/test/fixtures/renameable/pee.psd
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/rename/test/fixtures/renameable/tee.tar b/plugins/rename/test/fixtures/renameable/tee.tar
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/rename/test/fixtures/renameable/tee.tax b/plugins/rename/test/fixtures/renameable/tee.tax
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/rename/test/index.js b/plugins/rename/test/index.js
index db1004830..ddbd11074 100644
--- a/plugins/rename/test/index.js
+++ b/plugins/rename/test/index.js
@@ -17,9 +17,9 @@ test('Verify /rename route', (assert) => {
method: 'POST',
url: '/rename',
payload: {
- filenames: ['aitch.html', 'gee.gif', 'pee.png'],
+ filenames: ['aitch.html', 'gee.gif', 'em.md'],
prefix,
- source_folder: '/rename/test/fixtures/renameable',
+ source_folder: './plugins/rename/test/fixtures/renameable/FAKE',
},
};
server.inject(request, (result) => {
@@ -40,13 +40,13 @@ test('Verify /rename route', (assert) => {
method: 'POST',
url: '/rename',
payload: {
- filenames: ['aitch.html', 'gee.gif', 'pee.png'],
+ filenames: ['aitch.html', 'gee.gif', 'em.md'],
prefix,
- source_folder: '/plugins/rename/test/fixtures/renameable',
+ source_folder: './plugins/rename/test/fixtures/renameable',
},
};
server.inject(request, (response) => {
- st.equal(response.result, `${prefix}-37.jpg` +
+ st.equal(response.result.xml, `${prefix}-37.jpg` +
`${prefix}-64.jpg` +
`${prefix}-90.jpg`);
st.equal(response.statusCode, 200);
@@ -58,7 +58,52 @@ test('Verify /rename route', (assert) => {
assert.test('-Restore filenames to original', (st) => {
setTimeout(() => {
const filenames = [`${prefix}-37.jpg`, `${prefix}-64.jpg`, `${prefix}-90.jpg`];
- const futureFilenames = ['aitch.html', 'gee.gif', 'pee.png'];
+ const futureFilenames = ['aitch.html', 'gee.gif', 'em.md'];
+ const sourceFolder = './plugins/rename/test/fixtures/renameable';
+ const module = require('../lib/rename');
+
+ module.renamePaths(sourceFolder, filenames, futureFilenames)
+ .then((result) => {
+ st.equal(result, true, 'No errors');
+ st.end();
+ })
+ .catch((error) => {
+ st.fail(`Rename failed ${error}`);
+ st.end();
+ });
+ }, 1100);
+ });
+
+ assert.test('-Rename filename based on prefix with associated files', (st) => {
+ const server = new hapi.Server();
+ server.connection({ port: 8000 });
+ server.register(plugins, (error) => {
+ if (error) {
+ return st.fail(error);
+ }
+ const request = {
+ method: 'POST',
+ url: '/rename',
+ payload: {
+ filenames: ['dee.dat', 'pee.pdf'],
+ prefix,
+ source_folder: './plugins/rename/test/fixtures/renameable',
+ rename_associated: true,
+ },
+ };
+ server.inject(request, (response) => {
+ st.equal(response.result.xml, `${prefix}-50.jpg` +
+ `${prefix}-90.jpg`);
+ st.equal(response.statusCode, 200);
+ st.end();
+ });
+ });
+ });
+
+ assert.test('-Restore filenames to original with associated files', (st) => {
+ setTimeout(() => {
+ const filenames = [`${prefix}-50.dat`, `${prefix}-50.doc`, `${prefix}-50.docx`, `${prefix}-90.pdf`, `${prefix}-90.png`, `${prefix}-90.psd`];
+ const futureFilenames = ['dee.dat', 'dee.doc', 'dee.docx', 'pee.pdf', 'pee.png', 'pee.psd'];
const sourceFolder = './plugins/rename/test/fixtures/renameable';
const module = require('../lib/rename');
diff --git a/plugins/rename/test/rename.js b/plugins/rename/test/rename.js
index 140b6915a..244d9c64f 100644
--- a/plugins/rename/test/rename.js
+++ b/plugins/rename/test/rename.js
@@ -1,70 +1,234 @@
'use strict';
const test = require('tape');
+/*
+* ####### #
+* # # # # ##### # # #### #### #### #### # ## ##### ###### #####
+* # # ## # # # # # # # # # # # # # # # # # #
+* ##### # # # # # # # # #### #### # # # # # # # ##### # #
+* # # # # # # # ####### # # # # # # ###### # # # #
+* # # # ## # # # # # # # # # # # # # # # # # # #
+* # # # # ##### # # #### #### #### #### # # # # ###### #####
+*
+*/
+test('Find many associated relative filenames', (assert) => {
+ const sourceFolder = './plugins/rename/test/fixtures/renameable/';
+ const file = 'bee';
+ const associatedFilenames = [`${file}.bat`, `${file}.bin`, `${file}.bmp`];
+ const module = require('../lib/rename');
+
+ module.findAssociated(sourceFolder, associatedFilenames[0])
+ .then((filenames) => {
+ if (filenames.length === 0) {
+ assert.fail(`No filenames found`);
+ assert.end();
+ }
+ assert.plan(filenames.length);
+ filenames.forEach((filename, index) => {
+ const associatedFilename = associatedFilenames[index];
+ assert.ok(filename.indexOf(associatedFilename.substr(1)) !== -1,
+ `Found associated filenames with path ${associatedFilename}`);
+ });
+ })
+ .catch((error) => assert.fail(`Associated files is not found (${error})`));
+});
+
+test('Find many associated absolute filenames', (assert) => {
+ const sourceFolder = require('app-root-path').resolve('./test/fixtures/renameable/');
+ const file = 'bee';
+ const associatedFilenames = [`${file}.bat`, `${file}.bin`, `${file}.bmp`];
+ const module = require('../lib/rename');
+
+ module.findAssociated(sourceFolder, associatedFilenames[0])
+ .then((filenames) => {
+ if (filenames.length === 0) {
+ assert.fail(`No filenames found`);
+ assert.end();
+ }
+ assert.plan(filenames.length);
+ filenames.forEach((filename, index) => {
+ const associatedFilename = associatedFilenames[index];
+ assert.ok(filename.indexOf(associatedFilename.substr(1)) !== -1,
+ `Found associated filenames with path ${associatedFilename}`);
+ });
+ })
+ .catch((error) => assert.fail(`Associated files is not found (${error})`));
+});
+
+test('Find no associated filenames', (assert) => {
+ const sourceFolder = './plugins/rename/test/fixtures/renameable/';
+ const filename = 'FAKE';
+ const associatedFilenames = [];
+ const module = require('../lib/rename');
+
+ assert.plan(1);
+ module.findAssociated(sourceFolder, filename)
+ .then((files) => assert.deepEqual(files, associatedFilenames, `Correctly found no files from fake path`))
+ .catch((error) => assert.fail(`Associated files is not found (${error})`));
+});
+
+/*
+*###### #
+*# # ###### ## #### #### # #### # # # # #### #### #### #### # ## ##### ###### #####
+*# # # # # # # # # # ## # # # # # # # # # # # # # # # #
+*###### ##### # # #### #### # # # # # # # #### #### # # # # # # # ##### # #
+*# # # ###### # # # # ### # # # ####### # # # # # # ###### # # # #
+*# # # # # # # # # # # # # ## # # # # # # # # # # # # # # # # #
+*# # ###### # # #### #### # #### # # # # #### #### #### #### # # # # ###### #####
+*
+*/
+test('Reassign many associated absolute filenames', (assert) => {
+ const filepath = require('app-root-path').resolve('./plugins/rename/test/fixtures/renameable/');
+ const absoluteAssociatedFilenames = [`${filepath}bee.bat`, `${filepath}bee.bin`, `${filepath}bee.bmp`];
+ const futureFile = 'future';
+ const futureAssociatedFilenames = [
+ `${filepath}${futureFile}.bat`,
+ `${filepath}${futureFile}.bin`,
+ `${filepath}${futureFile}.bmp`,
+ ];
+ const module = require('../lib/rename');
+
+ assert.plan(1);
+ module.reassignAssociated(absoluteAssociatedFilenames, futureFile)
+ .then((futureFilenames) => {
+ assert.deepEqual(futureAssociatedFilenames, futureFilenames, 'Reassigned filenames match');
+ });
+});
+
+/*
+* ###### ######
+* # # ###### # # ## # # ###### # # ## ##### # # ####
+* # # # ## # # # ## ## # # # # # # # # #
+* ###### ##### # # # # # # ## # ##### ###### # # # ###### ####
+* # # # # # # ###### # # # # ###### # # # #
+* # # # # ## # # # # # # # # # # # # #
+* # # ###### # # # # # # ###### # # # # # # ####
+*
+*/
test('Rename real source folder', (assert) => {
- const filenames = ['cee.css', 'jay.js', 'tee.txt'];
+ const filenames = ['cee.css', 'jay.js', 'el.log'];
const futureFilenames = ['changed.css', 'renamed.js', 'temp.txt'];
const sourceFolder = './plugins/rename/test/fixtures/renameable';
const module = require('../lib/rename');
+ assert.plan(1);
module.renamePaths(sourceFolder, filenames, futureFilenames)
- .then((success) => {
- assert.equal(success, true, 'No errors');
- assert.end();
- })
- .catch((error) => {
- assert.fail(`Rename failed ${error}`);
- assert.end();
- });
+ .then(success => assert.equal(success, true, 'No errors'))
+ .catch(error => assert.fail(`Rename failed ${error}`));
});
test('Restore real source folder', (assert) => {
const filenames = ['changed.css', 'renamed.js', 'temp.txt'];
- const futureFilenames = ['cee.css', 'jay.js', 'tee.txt'];
+ const futureFilenames = ['cee.css', 'jay.js', 'el.log'];
const sourceFolder = './plugins/rename/test/fixtures/renameable';
const module = require('../lib/rename');
+ assert.plan(1);
module.renamePaths(sourceFolder, filenames, futureFilenames)
- .then((success) => {
- assert.equal(success, true, 'No errors');
- assert.end();
- })
- .catch((error) => {
- assert.fail(`Rename failed ${error}`);
- assert.end();
- });
+ .then(success => assert.equal(success, true, 'No errors'))
+ .catch(error => assert.fail(`Rename failed ${error}`));
});
test('Caught fake source folder', (assert) => {
- const filenames = ['cee.css', 'jay.js', 'tee.txt'];
+ const filenames = ['cee.css', 'jay.js', 'el.log'];
const futureFilenames = ['changed.css', 'renamed.js', 'temp.txt'];
const sourceFolder = './plugins/rename/test/fixtures/FAKE';
const module = require('../lib/rename');
+ assert.plan(1);
module.renamePaths(sourceFolder, filenames, futureFilenames)
- .then(() => {
- assert.fail('Code incorrectly found a fake folder');
- assert.end();
- })
- .catch(() => {
- assert.pass('Fake folder not found');
- assert.end();
- });
+ .then(() => assert.fail('Code incorrectly found a fake folder'))
+ .catch(() => assert.pass('Fake folder not found'));
});
-test('Caught fake filenames', (assert) => {
- const filenames = ['FAKEcee.css', 'FAKEjay.js', 'FAKEtee.txt'];
+test('Caught fake source filenames', (assert) => {
+ const filenames = ['FAKEcee.css', 'FAKEjay.js', 'FAKEel.log'];
const futureFilenames = ['changed.css', 'renamed.js', 'temp.txt'];
const sourceFolder = './plugins/rename/test/fixtures/renameable';
const module = require('../lib/rename');
+ assert.plan(1);
module.renamePaths(sourceFolder, filenames, futureFilenames)
- .then(() => {
- assert.fail('Code incorrectly found a fake filename');
- assert.end();
+ .then(() => assert.fail('Code incorrectly found a fake filename'))
+ .catch(() => assert.pass('Fake filename not found'));
+});
+
+test('Rename associated is false so one filename', (assert) => {
+ const filenames = ['bee.bat'];
+ const futureFilenames = ['rename_grouped.bat'];
+ const sourceFolder = './plugins/rename/test/fixtures/renameable';
+ const module = require('../lib/rename');
+
+ module.renamePaths(sourceFolder, filenames, futureFilenames, { renameAssociated: false })
+ .then(success => {
+ assert.plan(3);
+ assert.equal(success, true, 'No errors');
+ const exist = require('../../exists/lib');
+ exist.pathExists(`${sourceFolder}/bee.bin`)
+ .then(() => assert.pass('Associated bee.bin file remains untouched'))
+ .catch(error => assert.fail(`Bee.bin file does not exist ${error}`));
+ exist.pathExists(`${sourceFolder}/bee.bmp`)
+ .then(() => assert.pass('Associated bee.bmp file remains untouched'))
+ .catch(error => assert.fail(`Bee.bmp file does not exist ${error}`));
+ })
+ .catch(error => assert.fail(`Rename failed ${error}`));
+});
+
+test('Restore associated is false so one filename', (assert) => {
+ const filenames = ['rename_grouped.bat'];
+ const futureFilenames = ['bee.bat'];
+ const sourceFolder = './plugins/rename/test/fixtures/renameable';
+ const module = require('../lib/rename');
+
+ assert.plan(1);
+ module.renamePaths(sourceFolder, filenames, futureFilenames, { renameAssociated: false })
+ .then(success => assert.equal(success, true, 'No errors'))
+ .catch(error => assert.fail(`Rename failed ${error}`));
+});
+
+test('Rename associated is true so six filenames', (assert) => {
+ const filenames = ['bee.bat', 'tee.txt'];
+ const futureFilenames = ['rename_grouped.bat', 'rename_associated.txt'];
+ const sourceFolder = './plugins/rename/test/fixtures/renameable';
+ const module = require('../lib/rename');
+
+ module.renamePaths(sourceFolder, filenames, futureFilenames, { renameAssociated: true })
+ .then((success) => {
+ assert.plan(7);
+ assert.equal(success, true, 'No errors');
+ const exist = require('../../exists/lib');
+ exist.pathExists(`${sourceFolder}/rename_grouped.bat`)
+ .then(() => assert.pass('Associated rename_grouped.bat file renamed with associated'))
+ .catch(error => assert.fail(`Rename_grouped.bin file does not exist ${error}`));
+ exist.pathExists(`${sourceFolder}/rename_grouped.bin`)
+ .then(() => assert.pass('Associated rename_grouped.bin file renamed with associated'))
+ .catch(error => assert.fail(`Rename_grouped.bin file does not exist ${error}`));
+ exist.pathExists(`${sourceFolder}/rename_grouped.bmp`)
+ .then(() => assert.pass('Associated rename_grouped.bmp file remains with associated'))
+ .catch(error => assert.fail(`Rename_grouped.bmp file does not exist ${error}`));
+ exist.pathExists(`${sourceFolder}/rename_associated.txt`)
+ .then(() => assert.pass('Associated rename_associated.txt file renamed with associated'))
+ .catch(error => assert.fail(`Rename_associated.tar file does not exist ${error}`));
+ exist.pathExists(`${sourceFolder}/rename_associated.tar`)
+ .then(() => assert.pass('Associated rename_associated.tar file renamed with associated'))
+ .catch(error => assert.fail(`Rename_associated.tar file does not exist ${error}`));
+ exist.pathExists(`${sourceFolder}/rename_associated.tar`)
+ .then(() => assert.pass('Associated rename_associated.tar file remains with associated'))
+ .catch(error => assert.fail(`Rename_associated.tar file does not exist ${error}`));
})
- .catch(() => {
- assert.pass('Fake filename not found');
- assert.end();
+ .catch((error) => {
+ assert.fail(`Rename failed (${error})`);
});
});
+
+test('Restore associated is true so six filenames', (assert) => {
+ const filenames = ['rename_grouped.bat', 'rename_associated.txt'];
+ const futureFilenames = ['bee.bat', 'tee.txt'];
+ const sourceFolder = './plugins/rename/test/fixtures/renameable';
+ const module = require('../lib/rename');
+
+ assert.plan(1);
+ module.renamePaths(sourceFolder, filenames, futureFilenames, { renameAssociated: true })
+ .then((success) => assert.equal(success, true, 'No errors'))
+ .catch((error) => assert.fail(`Rename failed ${error}`));
+});
diff --git a/src/js/directory_contents.browser.js b/src/js/directory_contents.browser.js
index bab0b9238..e17bd74b5 100644
--- a/src/js/directory_contents.browser.js
+++ b/src/js/directory_contents.browser.js
@@ -104,7 +104,8 @@
data: {
filenames: JSON.stringify(getSortedAssets()),
prefix: formattedDate,
- source_folder: "." + qs.folder
+ source_folder: "." + qs.folder,
+ rename_associated: true
},
success: function (response) {
var $spinner = $("#spinner"),
diff --git a/src/js/server.js b/src/js/server.js
index e913ab9b5..95f2ee7ac 100644
--- a/src/js/server.js
+++ b/src/js/server.js
@@ -2,50 +2,51 @@
'use strict';
const hapi = require('hapi'),
- server = new hapi.Server(),
- pkg = require('../../package');
+ server = new hapi.Server(),
+ pkg = require('../../package');
server.connection({ "port": 8000 });
server.register([
- { register: require('inert') },
- { register: require('vision') },
- { register: require('./route.js') },
- {
- register: require('../../plugins/rename/lib'),
- routes: { prefix: '/admin' }
- },
- {
- register: require('hapi-swagger'),
- options: { info: { title: 'history API', version: pkg.version } }
- }
+ { register: require('inert') },
+ { register: require('vision') },
+ { register: require('./route.js') },
+ {
+ register: require('../../plugins/rename/lib'),
+ routes: { prefix: '/admin' }
+ },
+ {
+ register: require('hapi-swagger'),
+ options: { info: { title: 'history API', version: pkg.version } }
+ },
+ { register: require('lout') }
], function (error) {
- const notifier = require('node-notifier'),
- hoek = require('hoek');
+ const notifier = require('node-notifier'),
+ hoek = require('hoek');
- hoek.assert(!error, error);
- var dust = require('dustjs-linkedin'),
- dustViews = require("fs").readFileSync("./public/views.min.js");
-
- require("tuxharness");
- dust.loadSource(dustViews);
- console.log('Views loaded to cache');
+ hoek.assert(!error, error);
+ var dust = require('dustjs-linkedin'),
+ dustViews = require("fs").readFileSync("./public/views.min.js");
- server.start();
- console.log('Server running at ' + server.info.uri);
- notifier.notify({
- title: 'Server event',
- message: 'Running at ' + server.info.uri
+ require("tuxharness");
+ dust.loadSource(dustViews);
+ console.log('Views loaded to cache');
+
+ server.start();
+ console.log('Server running at ' + server.info.uri);
+ notifier.notify({
+ title: 'Server event',
+ message: 'Running at ' + server.info.uri
});
});
server.views({
- "defaultExtension": "dust",
- "engines": {
- "dust": require('hapi-dust')
- },
- "isCached": true,
- "path": '../views',
- "partialsPath": '../views',
- "relativeTo": __dirname
-});
\ No newline at end of file
+ "defaultExtension": "dust",
+ "engines": {
+ "dust": require('hapi-dust')
+ },
+ "isCached": true,
+ "path": '../views',
+ "partialsPath": '../views',
+ "relativeTo": __dirname
+});