|
#!/media/sdr1/home/exko/.nvm/versions/node/v4.0.0/bin/node |
|
'use strict' |
|
|
|
var config = require('./config') |
|
|
|
const FOLDER = 'application/vnd.google-apps.folder' |
|
const DEST_FOLDER = config.root_folder |
|
|
|
var fs = require('fs') |
|
var twilio = require('twilio')(config.TWILIO_SID, config.TWILIO_TOKEN) |
|
var google = require('googleapis') |
|
var async = require('async') |
|
var winston = require('winston') |
|
var _ = require('lodash') |
|
var mime = require('mime') |
|
|
|
var tid = process.argv[2] |
|
var tname = process.argv[3] |
|
var tpath = process.argv[4] |
|
|
|
if (tpath.charAt(tpath.length - 1) !== '/') { |
|
tpath += '/' |
|
} |
|
|
|
var logger = new (winston.Logger)({ |
|
transports: [ |
|
new (winston.transports.Console)(), |
|
new (winston.transports.File)({ filename: './log' }) |
|
] |
|
}) |
|
|
|
logger.info('starting upload!') |
|
logger.info(`${tid} / ${tname} / ${tpath}`) |
|
|
|
var auth = new google.auth.OAuth2( |
|
config.GOOGLE_API_CLIENT_ID, |
|
config.GOOGLE_API_CLIENT_SECRET |
|
) |
|
|
|
auth.credentials.refresh_token = config.GOOGLE_API_REFRESH_TOKEN |
|
|
|
auth.refreshAccessToken(function (err, tokens) { |
|
if (err) { |
|
logger.error(`error retrieving access tokens ${err.error} - '${err.error_description}'`) |
|
process.exit(1) |
|
return |
|
} |
|
|
|
var rootFolder |
|
|
|
var drive = google.drive({ |
|
version: 'v2', |
|
auth: auth |
|
}) |
|
|
|
var uploadQueue = async.queue(function (task, done) { |
|
var filename = getLastPart(task.path) |
|
|
|
logger.info('start uploading: %s', filename) |
|
|
|
var insertOp = { |
|
resource: { |
|
title: filename, |
|
mimeType: task.type, |
|
parents: [ |
|
{ id: task.in } |
|
] |
|
} |
|
} |
|
|
|
if (task.type !== FOLDER) { |
|
insertOp.media = { |
|
mimeType: task.type, |
|
body: fs.createReadStream(task.path) |
|
} |
|
} |
|
|
|
drive.files.insert(insertOp, function (err, uploadedFile) { |
|
logger.info('finished uploading: %s', filename) |
|
done(err, uploadedFile) |
|
}) |
|
}, config.upload_concurrency) |
|
|
|
function upload (folder, _in, depth, done) { |
|
var uploadedFolder |
|
|
|
if (depth > 25) { |
|
logger.warning('maximum depth reached!!!') |
|
done(null) |
|
} |
|
|
|
if (fs.statSync(folder).isFile()) { |
|
logger.info('torrent is just a single file: %s', folder) |
|
uploadQueue.push({ |
|
path: folder, |
|
type: mime.lookup(folder), |
|
in: _in |
|
}, done) |
|
} else { |
|
logger.info('uploading folder: %s', folder) |
|
async.waterfall([ |
|
function (cb) { |
|
uploadQueue.push({ |
|
path: folder, |
|
type: FOLDER, |
|
in: _in |
|
}, cb) |
|
}, |
|
function (newFolder, cb) { |
|
uploadedFolder = newFolder |
|
fs.readdir(folder, cb) |
|
}, |
|
function (fileList, cb) { |
|
var folders = _.filter(fileList, function (f) { |
|
return fs.statSync(`${folder}/${f}`).isDirectory() |
|
}) |
|
|
|
var files = _.filter(fileList, function (f) { |
|
return fs.statSync(`${folder}/${f}`).isFile() |
|
}) |
|
|
|
async.map(files, function (file, cb) { |
|
uploadQueue.push({ |
|
path: `${folder}/${file}`, |
|
type: mime.lookup(file), |
|
in: uploadedFolder.id |
|
}, cb) |
|
}, function (err) { |
|
if (err) return cb(err) |
|
|
|
async.each(folders, function (subFolder, cb) { |
|
upload(`${folder}/${subFolder}`, uploadedFolder.id, (depth + 1), cb) |
|
}, cb) |
|
}) |
|
} |
|
], done) |
|
} |
|
} |
|
|
|
async.series([ |
|
function findOrCreateFolder (cb) { |
|
// find folder to put stuff in |
|
|
|
logger.info('finding a folder to put stuff in') |
|
/* |
|
+----------------------+ |
|
| find folder with | |
|
| "title=DEST_FOLDER" | |
|
+----------------------+ |
|
| |
|
+-(found one)--+-(didn't find one)-+ |
|
| | |
|
v v |
|
+------------------+ +------------------+ |
|
| is it in the | |create new folder | |
|
| trash? |---+ | in root |--+ |
|
+------------------+ | +------------------+ | |
|
| | | |
|
+--(yes)-+ +------(no)--------+ | |
|
| | | |
|
v v | |
|
+------------------+ +------------------+ | |
|
| remove it from | |return destination| | |
|
| trash |-->| folder |<----+ |
|
+------------------+ +------------------+ |
|
*/ |
|
drive.children.list({ |
|
folderId: 'root', |
|
q: `title="${DEST_FOLDER}"` |
|
}, function (err, childList) { |
|
if (err) return cb(err) |
|
|
|
if (childList.items.length > 0) { |
|
var rootFolderId = childList.items[0].id |
|
drive.files.get({ |
|
fileId: rootFolderId, |
|
updateViewedDate: true |
|
}, function (err, _root_folder) { |
|
if (err) { |
|
return cb(err) |
|
} |
|
|
|
rootFolder = _root_folder |
|
if (rootFolder.labels.trashed) { |
|
logger.info(`target folder was in the trash! untrashing...`) |
|
drive.files.untrash({ |
|
fileId: rootFolder.id |
|
}, function (err) { |
|
if (err) { |
|
return cb(err) |
|
} |
|
logger.info('cool! target folder out of the trash. moving on...') |
|
cb(null) |
|
}) |
|
return |
|
} |
|
logger.info(`found one! ${rootFolder.id}`) |
|
cb(null) |
|
}) |
|
return |
|
} |
|
logger.info('did not find one, creating one now...') |
|
drive.files.insert({ |
|
resource: { |
|
title: DEST_FOLDER, |
|
mimeType: FOLDER |
|
} |
|
}, function (err, _new_folder) { |
|
if (err) return cb(err) |
|
|
|
rootFolder = _new_folder |
|
cb(null) |
|
}) |
|
}) |
|
}, |
|
function uploadStuff (cb) { |
|
upload(`${tpath}${tname}`, rootFolder.id, 0, cb) |
|
} |
|
], function (err) { |
|
if (err) { |
|
logger.error('ERROR') |
|
logger.error(err) |
|
return |
|
} |
|
|
|
twilio.sendMessage({ |
|
to: config.NOTIFY_TO_NUMBER, |
|
from: config.NOTIFY_FROM_NUMBER, |
|
body: `so let it be said, so let it be done! '${tname}' finished downloading!` |
|
}, function (err) { |
|
if (err) { |
|
logger.error('ERROR SENDING NOTIFICATION', err) |
|
return |
|
} |
|
|
|
logger.info('sent notification') |
|
}) |
|
|
|
logger.info('successfully finished uploading shit') |
|
}) |
|
}) |
|
|
|
function getLastPart (path) { |
|
if (path.charAt(path.length - 1) === '/') { |
|
path = path.slice(0, -1) |
|
} |
|
|
|
return path.split('/').pop() |
|
} |