Skip to content

Instantly share code, notes, and snippets.

@Buom01
Created February 23, 2017 12:09
Show Gist options
  • Select an option

  • Save Buom01/d88243099d27d23c236634a59bda53a1 to your computer and use it in GitHub Desktop.

Select an option

Save Buom01/d88243099d27d23c236634a59bda53a1 to your computer and use it in GitHub Desktop.
A simple exemple of file upload using `dropbox` V2 API, `ostrio:files` and ImageMagick (gm package)
/*
Code based on: https://github.com/VeliovGroup/Meteor-Files/wiki/DropBox-Integration/5bc0adcba782f404994ff6a972fdf18ee5fec14a
This forked version probably need any verifications
*/
import {
blog_schema //Using simple-schema
} from "../schema/collection.blog.js";
import {
FilesCollection
} from 'meteor/ostrio:files';
if (Meteor.isServer) {
var gm = Npm.require('gm').subClass({
imageMagick: true
});
var Dropbox = Npm.require('dropbox');
var Request = Npm.require('request');
var fs = Npm.require('fs');
var bound = Meteor.bindEnvironment(function(callback) {
return callback();
});
var dbx = new Dropbox({
accessToken: process.env.DROPBOX_TOKEN //Use your app token
});
var dropboxPrefix = "/blog";
}
var blog = new Mongo.Collection('blog');
blog.attachSchema(blog_schema);
var blogCover = new FilesCollection({
debug: false, // Change to `true` for debugging
throttle: false,
storagePath: '/tmp',
downloadRoute: "/uploads",
collectionName: 'blogCover',
allowClientCode: false,
onBeforeUpload: function(file) {
// Allow upload files under 10MB, and only in png/jpg/jpeg formats
if(!Roles.userIsInRole(this.userId, ['admin', 'modo'])){
return "Vous n'avez pas les droits suffisants"; //The user needs more rights to do this
}else if (file.size > 5242880) {
return 'Please upload image lower than 5MB (current:' + file.size + 'Byte)';
} else if (!/png|jpg|jpeg/i.test(file.extension)) {
return 'Please upload image with png or jpg extension (current:' + file.extension + ')';
} else {
return true;
}
},
onAfterUpload: function(fileRef) {
try{
//Resize
var self = this;
var dest = {
meta: {}
};
dest.path = fileRef.path.replace(/(png|jpeg)$/, "jpg");
dest.extension = "jpg";
dest.type = "image/jpeg";
var imageComputing = gm(fileRef.path).autoOrient().gravity('Center');
var size = Meteor.wrapAsync(imageComputing.size, imageComputing)();
if (size.height > 1000 || size.width > 1000) {
imageComputing = imageComputing.resize(1000, 1000);
}
imageComputing = imageComputing.strip().type("Optimize").compress('JPEG').quality('75').interlace("plane");
Meteor.wrapAsync(imageComputing.write, imageComputing)(dest.path);
dest.size = fs.statSync(dest.path).size;
if (fileRef.path != dest.path) {
fs.unlinkSync(fileRef.path);
}
var size = Meteor.wrapAsync(imageComputing.size, imageComputing)();
var upd = {
$set: {}
};
upd['$set']['versions.original'] = dest;
blogCover.update(fileRef._id, upd);
var upd = {
$set: {}
};
dest.meta.createdAt = new Date();
dest.meta.name = fileRef.name.replace(/\.[a-z]*$/i, '');
dest.meta.width = size.width;
dest.meta.height = size.height;
upd['$set'] = dest;
blogCover.update(fileRef._id, upd);
fileRef.path = dest.path;
fileRef.size = dest.size;
fileRef.type = dest.type;
fileRef.extension = dest.extension;
fileRef.meta = dest.meta;
fileRef.versions.original = dest;
// In onAfterUpload callback we will move file to DropBox
var makeUrl = function(path, fileRef, version) {
dbx.sharingCreateSharedLink({path: path, short_url: false}).then(function(response){
bound(function() {
var url = response.url.replace('dl=0','raw=1');
var upd = {
$set: {}
};
upd['$set']["versions." + version + ".meta.pipeFrom"] = url;
upd['$set']["versions." + version + ".meta.pipePath"] = path;
self.collection.update({
_id: fileRef._id
}, upd, function(error) {
if (error) return console.error(error);
// Unlink original files from FS
// after successful upload to DropBox
self.unlink(self.collection.findOne(fileRef._id), version);
});
});
}).catch(function(err){
console.error(err);
});
};
var writeToDB = function(fileRef, version, data) {
// DropBox already uses random URLs
// No need to use random file names
dbx.filesUpload({path: dropboxPrefix+'/' + fileRef._id + "-" + version + "." + fileRef.extension, contents: data,autorename:false}).then(function(response){
bound(function() {
// Generate downloadable link
makeUrl(response.path_display, fileRef, version);
});
}).catch(function(err){
bound(function(){
console.error(err);
});
});
};
var readFile = function(fileRef, vRef, version) {
fs.readFile(vRef.path, function(error, data) {
bound(function() {
if (error) return console.error(error);
writeToDB(fileRef, version, data);
});
});
};
var sendToStorage = function(fileRef) {
_.each(fileRef.versions, function(vRef, version) {
readFile(fileRef, vRef, version);
});
};
sendToStorage(fileRef);
}catch(err){
console.log('Removing '+fileRef.path);
fs.unlink(fileRef.path, function(err){
if(err) console.error(err);
});
photos.remove({
_id: fileRef._id
}, function(err) {
if (err) console.error(err);
});
}
},
onBeforeRemove: function(cursor) {
return false;
},
interceptDownload: function(http, fileRef, version) {
var path, ref, ref1, ref2;
path = (ref = fileRef.versions) != null ? (ref1 = ref[version]) != null ? (ref2 = ref1.meta) != null ? ref2.pipeFrom : void 0 : void 0 : void 0;
if (path) {
// If file is moved to DropBox
// We will pipe request to DropBox
// So, original link will stay always secure
Request({
url: path,
headers: _.pick(http.request.headers, 'range', 'accept-language', 'accept', 'cache-control', 'pragma', 'connection', 'upgrade-insecure-requests', 'user-agent')
}).on('response', function(response) {
if (response.statusCode == 200) {
response.headers = _.pick(response.headers, 'accept-ranges', 'cache-control', 'connection', 'content-disposition', 'content-length', 'content-type', 'date', 'etag');
response.headers['Cache-control'] = "only-if-cached, public, max-age=2592000";
}
}).pipe(http.response);
return true;
} else {
// While file is not yet uploaded to DropBox
// We will serve file from FS
return false;
}
}
});
if (Meteor.isServer) {
// Intercept File's collection remove method
// to remove file from DropBox
var _origRemove = blogCover.remove;
blogCover.remove = function(search) {
var cursor = this.collection.find(search);
cursor.forEach(function(fileRef) {
_.each(fileRef.versions, function(vRef) {
var ref;
if (vRef != null ? (ref = vRef.meta) != null ? ref.pipePath : void 0 : void 0) {
client.remove(vRef.meta.pipePath, function(error) {
bound(function() {
if (error) {
console.error(error);
}
});
});
}
});
});
// Call original method
_origRemove.call(this, search);
};
}
if(Meteor.isClient) window.blogCover = blogCover;
export var blogCover;
import "./methods.blog.js";
import "./publication.blog.js";
export var blog;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment