Skip to content

Instantly share code, notes, and snippets.

@dantheman213
Last active April 26, 2016 01:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dantheman213/fa57f315ce9fb4fc8b3e to your computer and use it in GitHub Desktop.
Save dantheman213/fa57f315ce9fb4fc8b3e to your computer and use it in GitHub Desktop.
Move media files in a downloads directory using a "grep-like" selector that will copy all target files to the desired media location. This script was designed to easily move many files using a single grep selector quickly to another folder via the command-line.
#!/usr/bin/nodejs
// Easily copy and sync media from downloads area to target location
//
// Daniel Gillespie
// 2016
//
// Install required packages where you're placing script
// npm install --save prompt-sync chalk exec-sync rsync
//
// Environment Variables (CHANGE THESE)
// Target Copy Folder(s)
// array ex ['/home/user/downloads/', '/home/user/documents/']
// include a "/" at the end of the path.
var mediaLocations = null;
// Video extensions
// These are the file extensions to search for when copying files
var videoExtensions = ['mp4', 'mkv', 'mpg', 'mpeg', 'avi', 'mov', 'wmv', 'm4v', '3gp'];
///////// DON'T MODIFY ANYTHING PAST THIS LINE /////////
// libraries
var fs = require('fs'),
path = require('path'),
prompt = require('prompt-sync').prompt,
chalk = require('chalk'),
execSync = require('exec-sync'),
Rsync = require('rsync');
// globals
var args = process.argv.slice(2);
var mediaPath = null;
var Text = {
Error: function(str) {console.log(chalk.bold.red(str));},
Green: function(str) {console.log(chalk.green(str));},
Yellow: function(str) {console.log(chalk.yellow(str));},
Output: function(str) {console.log(chalk.white(str));}
};
// primary code
String.prototype.escapeInput = function() {
return this.replace(/ /g, '\\ ');
};
function checkArguments() {
if(args.length != 1) {
Text.Error('\nNot enough arguments to continue.. aborting!');
Text.Error('Usage: mediamove.js <grep-like search pattern>\n');
process.exit(0);
}
}
function checkEnvironment() {
if(mediaLocations == null || mediaLocations.length < 1) {
Text.Error('Not all evironment variables set within script! Please check top of script before proceeding.\n');
process.exit(0);
}
}
function getDirectorySelection() {
var currentDir = mediaPath;
var dirList = null;
var selectedDirPath = null;
Text.Green('\nWhich directory would you like target file(s) to be moved?');
var regexFilter = /^\d+$/;
var bInputComplete = false;
while(!bInputComplete) {
console.log('currentDir:' + currentDir);
dirList = getListDirectories(currentDir);
if(dirList.length < 1) {
// no items
Text.Yellow('No directories are within this directory. Type "d" to use this directory.');
} else {
for(var k = 0; k < dirList.length; k++) {
Text.Output(k + ' - ' + dirList[k]);
}
}
Text.Green('\nWhich directory would you like target file(s) to be moved? choices [0-999/d - done/e - exit]');
var cin = prompt();
if(cin === "d") {
// done
bInputComplete = true;
Text.Green('Copying all target files to ' + currentDir);
// break loop to continue
} else if (cin === "e") {
Text.Output("Exiting...");
process.exit(0);
} else if (cin == null || !regexFilter.test(cin)) {
Text.Error('Numbers are only accepted! Try again.');
} else {
var choice = parseInt(cin);
if(choice < 0 || choice > dirList.length-1) {
Text.Error('Invalid choice! Please select a valid number representing a directory!\n');
} else {
selectedDirPath = dirList[choice];
currentDir += selectedDirPath + '/';
Text.Output('Navigating to ' + currentDir + '\n');
}
}
}
return currentDir;
}
function main() {
Text.Green("Starting...");
checkArguments();
checkEnvironment();
var sourceFileList = confirmCopyFiles();
chooseMediaPath();
var dirPath = getDirectorySelection(); // final target path
copyFilesToTargetLocation(dirPath, sourceFileList);
}
function copyFilesToTargetLocation(targetDirectory, fileList) {
if(fileList.length > 0) {
for(var k = 0; k < fileList.length; k++) {
var filename = fileList[k].substr(fileList[k].lastIndexOf('/') + 1);
Text.Yellow('\nCopying ' + filename + ' -> ' + targetDirectory + filename + '\n\n');
var rsync = new Rsync().
flags('ah').
set('progress').
source(fileList[k]).
destination(targetDirectory + '.');
rsync.execute(function(error, code, cmd) {
if(error) {
Text.Error('Copy failed!');
Text.Error(error);
process.exit(1);
}
Text.Green('Operation Complete!');
process.exit(0);
}, function(data) {
// progress
Text.Yellow(data);
});
}
}
}
function getListDirectories(dirPath) {
return fs.readdirSync(dirPath).filter( function(file) {
var bResult = false;
try {
bResult = fs.statSync(path.join(dirPath, file)).isDirectory();
} catch(ex) { }
return bResult;
});
}
function chooseMediaPath() {
if(mediaLocations.length > 1) {
var regexFilter = /^\d+$/;
var bInputComplete = false;
while(!bInputComplete) {
Text.Green('\nWhich target directory would you like to copy to? type [0-99] or "e" for exit.');
for(var k = 0; k < mediaLocations.length; k++) {
Text.Yellow(k + '. ' + mediaLocations[k]);
}
var cin = prompt();
if (cin === "e") {
Text.Output("Exiting...");
process.exit(0);
} else if (cin == null || !regexFilter.test(cin)) {
Text.Error('Numbers are only accepted! Try again.');
} else {
var choice = parseInt(cin);
mediaPath = mediaLocations[choice];
break;
}
}
} else {
// only one path
mediaPath = mediaLocations[0];
}
}
function confirmCopyFiles() {
var pwd = execSync('pwd');
var command = 'find ' + pwd + ' -regex ".*\\.\\(' + videoExtensions.join('\\|') + '\\)" | grep ' + args[0];
var response = execSync(command);
Text.Output('\n\nAre these the files you would like to select for moving?');
Text.Output(response);
var regexFilter = /^(?:y|n)$/;
var bInputComplete = false;
while(!bInputComplete) {
Text.Output('\nAre the files above correct? [y/n]');
var cin = prompt();
if(cin == null || !regexFilter.test(cin)) {
Text.Error('Only "y" and "n" are accepted! Try again.');
} else {
if(cin === "n") {
process.exit(0);
} else {
execSync('sleep 1');
bInputComplete = true;
}
}
}
return response.split('\n');
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment