Skip to content

Instantly share code, notes, and snippets.

@danzimm
Last active August 29, 2015 14:05
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 danzimm/31dc0ad3059e644b1fda to your computer and use it in GitHub Desktop.
Save danzimm/31dc0ad3059e644b1fda to your computer and use it in GitHub Desktop.
'use strict';
/**
* MAC OSX ONLY
*/
// npm install request async
try{
var request = require('request');
var async = require('async');
var Notification = require('node-notifier');
var notifier = new Notification();
}catch(err){
console.error("[Error] '%s' requires the 'request async node-notifier' packages to work", __filename);
console.error("[Error] run 'cd %s && npm install request async node-notifier' and restart dot-clipboard (or edit download-file.js).", __dirname);
}
var exec = require('child_process').exec;
var crypto = require('crypto');
var os = require('os');
var path = require('path');
var fs = require('fs');
module.exports = {
options: {
outputDir: path.resolve(process.env.HOME, 'Dropbox/Images'),
tmpOutputDir: os.tmpdir(),
fileExts: ['.png', '.jpg', '.jpeg', '.gif'],
notify: true,
askForTags: false,
truncateSha1To: 1000,
separator: '_'
},
run: function(link, f){
link = link.trim();
var parts, filext, filename, notifyMe = this.options.notify, tmp;
parts = link.split(':');
filext = path.extname(link);
filename = path.basename(link);
filename = filename.substr(0, filename.length - filext.length);
tmp = filext.indexOf('?');
if (tmp != -1) {
filext = filext.substr(0, tmp);
}
if (this.options.fileExts.indexOf(filext) == -1 || !(parts[0] == 'http' || parts[0] == 'https')) {
return f();
}
async.waterfall([
downloadFileAndChecksum.bind(null, this.options, link, filext),
checkIfFileExist.bind(null, fileNameComparator(this.options), this.options),
], function(err, tmpFile, fileSha1, alreadyExist){
if(err || alreadyExist){
return f(err);
}
async.waterfall([
askForTags.bind(null, this.options, link),
moveToOutputDir.bind(null, filename, tmpFile, fileSha1, this.options)
], function() {
if (notifyMe) {
notifier.notify({
title: 'dot-clipboard',
message: 'Saved ' + link
});
}
f();
});
}.bind(this));
}
};
function downloadFileAndChecksum(options, link, ext, f){
var tmpFile = path.resolve(options.tmpOutputDir, + new Date() + ext);
var hash = crypto.createHash('sha1');
hash.setEncoding('hex');
var req = request(link)
.on('error', function(err){
f(err);
})
.on('end', function(){
hash.end();
f(null, tmpFile, hash.read());
});
req.pipe(hash, { end: false });
req.pipe(fs.createWriteStream(tmpFile));
}
function checkIfFileExist(comparator, options, tmpFile, fileSha1, f){
fs.readdir(options.outputDir, function(err, files){
if(err){return f(err);}
f(null, tmpFile, fileSha1, files.filter(comparator(fileSha1)).length > 0);
});
}
function fileNameComparator(options){
return function(fileSha1){
return function(filename){
var tmp = filename.split(options.separator);
return tmp[tmp.length-1] === fileSha1.substring(0, options.truncateSha1To);
};
};
}
function askForTags(options, fileLink, f){
if(!options.askForTags){
return f(null, null);
}
var promptTitle = 'Enter tags (separated by \'-\') for file ('+fileLink+')';
var cmd = "osascript -e 'Tell application \"System Events\" to display dialog \""+promptTitle+"\" default answer \"\"' -e 'text returned of result' 2>/dev/null";
exec(cmd, function (error, stdout /*, stderr*/) {
f(null, stdout);
});
}
function moveToOutputDir(filename, tmpFile, fileSha1, options, tags, f){
var file = path.resolve(options.outputDir, filename + options.separator + fileSha1.substring(0, options.truncateSha1To) + (tags ? options.separator + tags : '').trim() + path.extname(tmpFile)).trim();
fs.rename(tmpFile, file, f);
}
@danzimm
Copy link
Author

danzimm commented Sep 2, 2014

eh hacky..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment