How to convert files to jpeg in meteor in collectionFS - javascript

I am using Graphicsmagick and also installed the required plugins cfs:gm and libjpeg-dev, and I use FILE SYSTEM adapter here is my code
Avatar = new FS.Collection("avatars", {
stores: [
new FS.Store.FileSystem("avatars",
{
path: '~/uploads',
beforeWrite: function(fileObj) {
return {
extension: 'jpg',
type: 'image/jpg'
};
},
transformWrite:function(fileObj, readStream, writeStream) {
gm(readStream, fileObj.name()).resize('200', '200').stream('JPG').pipe(writeStream);
}
})
],
filter: {
maxSize:1000000,
allow: {
contentTypes: ['image/*']
}
}
});
Avatar.allow({
insert: function (userId, doc) {
if(doc.owner != userId)
return false;
else
return true;
},
remove: function (userId,doc) {
if(doc.owner != userId)
return false;
else
return true;
},
download: function () {
return true;
},
update: function (userId,doc) {
if(doc.owner != userId)
return false;
else
return true;
}
});
But it doesn't seem to convert at all instead I get some empty file, when I try to access it from file url here is what I get
Error in method "/cfs/files/:value/:value/", Error: Error: start must be <= end
at new ReadStream (fs.js:1489:13)
at Object.fs.createReadStream (fs.js:1450:10)
at Object.FS.StorageAdapter.createReadStream (packages/cfs_filesystem/packages/cfs_filesystem.js:67:1)
at Object.self.adapter.createReadStreamForFileKey (packages/cfs_storage-adapter/packages/cfs_storage-adapter.js:83:1)
at [object Object].FS.Transform.createReadStream (packages/cfs_storage-adapter/packages/cfs_storage-adapter.js:392:1)
at Object.self.adapter.createReadStream (packages/cfs_storage-adapter/packages/cfs_storage-adapter.js:93:1)
at Object.httpGetHandler (packages/cfs_access-point/packages/cfs_access-point.js:408:1)
at Object.accessPoint.get (packages/cfs_access-point/packages/cfs_access-point.js:675:1)
at packages/cfs_http-methods/packages/cfs_http-methods.js:582:1
The code is good as long as I don't convert images,am I missing something here?

Same problem, I have similar code :-(
edit:
I had an error in
{path: '~/uploads'}, (with } incorrect)

Related

Tabulator not working with remote pagination and ajaxURLGenerator

I have an issue with tabulator (4.9.1) and the pagination, when I try to configure it with remote pagination and ajaxUrlGenerator function, it never pass into the generator function, after investigating the code I've noticed that the code of tabulator do the following :
Tabulator.prototype._loadInitialData = function () {
var self = this;
if (self.options.pagination && self.modExists("page")) {
self.modules.page.reset(true, true);
if (self.options.pagination == "local") {
if (self.options.data.length) {
self.rowManager.setData(self.options.data, false, true);
} else {
if ((self.options.ajaxURL || self.options.ajaxURLGenerator) && self.modExists("ajax")) {
self.modules.ajax.loadData(false, true).then(function () {}).catch(function () {
if (self.options.paginationInitialPage) {
self.modules.page.setPage(self.options.paginationInitialPage);
}
});
return;
} else {
self.rowManager.setData(self.options.data, false, true);
}
}
if (self.options.paginationInitialPage) {
self.modules.page.setPage(self.options.paginationInitialPage);
}
} else {
if (self.options.ajaxURL) {
self.modules.page.setPage(self.options.paginationInitialPage).then(function () {}).catch(function () {});
} else {
self.rowManager.setData([], false, true);
}
}
} else {
if (self.options.data.length) {
self.rowManager.setData(self.options.data);
} else {
if ((self.options.ajaxURL || self.options.ajaxURLGenerator) && self.modExists("ajax")) {
self.modules.ajax.loadData(false, true).then(function () {}).catch(function () {});
} else {
self.rowManager.setData(self.options.data, false, true);
}
}
}
};
using the ajaxURLGenerator with the 'local' configuration makes it work correctly in remote.
But then it doesn't do the progressive pagination and doesn't pass the parameters correctly in the ajaxURLGenerator function, probably due to the parsing mecanism that is not called in 'local' mode for the data :
Page.prototype.trigger = function () {
var _this81 = this;
var left;
return new Promise(function (resolve, reject) {
switch (_this81.mode) {
case "local":
left = _this81.table.rowManager.scrollLeft;
_this81.table.rowManager.refreshActiveData("page");
_this81.table.rowManager.scrollHorizontal(left);
_this81.table.options.pageLoaded.call(_this81.table, _this81.getPage());
resolve();
break;
case "remote":
case "progressive_load":
case "progressive_scroll":
_this81.table.modules.ajax.blockActiveRequest();
_this81._getRemotePage().then(function () {
resolve();
}).catch(function () {
reject();
});
break;
default:
console.warn("Pagination Error - no such pagination mode:", _this81.mode);
reject();
}
});
};
At the end it is loading, but all the data when the server return just a json list, but it fail when receiving the object expected for the remote pagination.
Does anyone had the same issue with remote pagination and ajaxURLGenerator? Anyone has an idea how to solve it, without modifying the library?
Thanks in advance

Javascript validation - Check if a string is a correct object

I have a textarea where I need to put an object like that
[{
name: 'digitrust',
params: {
init: {
member: 'example_member_id',
site: 'example_site_id'
},
callback: function(digiTrustResult) {
if (digiTrustResult.success) {
var el = document.getElementById('dtidOutput');
console.log('Success', digiTrustResult.identity)
} else {
console.error('Digitrust init failed')
}
}
},
storage: {
type: 'html5',
name: 'pbjsdigitrust',
expires: 60
}
}]
I save this string in a mysql db and after I print it in a javascript object with php (laravel)
#if(!empty($useridobj))
try {
useridobj = {!! $useridobj !!};
if(typeof useridobj != 'object'){
useridobj = '';
}
} catch(err) {
useridobj = ''
}
#endif
If I put a correct obj in this textarea all works fine. But if I put something wrong like that
[{name:'digitrust',para]
console return an error.
So I'd like to validate the field first, in javascript (angular.js). I try something like that
if(!eval("var this_useridobj = "+ this.form.get("useridobj").value)){
this.form.get("useridobj").setErrors({ server: "UserId Object is not an object!" });
console.warn(this.form.get("useridobj"));
return false;
}
It doesn't work. Someone can help me please?
Thank u
Maybe you should validate in server side, eval or Function in the example above have some security issues, see this. Here you have a possible approach, but that Function executes anything:
document.getElementById("validate").addEventListener("click",()=>{
const json = document.getElementById("json").value;
const valid = (()=>{
try {
return (typeof (Function("return "+json))() === 'object')?true:false;
}
catch(error) {
return false;
}})();
console.log(valid)
});
//Try alert("something") in the textarea
<textarea id="json">{prop:[1,2,3}</textarea>
<button id="validate">
validate
</button>

Multiple Image uploading error in angularjs

Here I am getting one issue while uploading multiple images on AngularJS. Here is my code and the error I'm getting.
$scope.saveFile = function(file) {
return Upload.upload({
url: CONFIG.apiUrl + '/fileupload',
data: {
fileUpload: file
}
}).success(function(data) {
console.log("RSPPPPPPP", data.file._id);
$scope.photoId = data.file._id;
console.log("sdvfbghjm,kjhgfdsa", $scope.photoId);
})
return $scope.saveFile;
//}
};
$scope.Addprojects = function(prodetails) {
if (prodetails.image1_id) {
$scope.prodetails.file.push(prodetails.image1_id);
//console.log("image1", prodetails.file);
}
if (prodetails.image2_id) {
$scope.prodetails.file.push(prodetails.image2_id);
//console.log("image2", prodetails.file);
}
//console.log(prodetails.file.length);
if (prodetails.file.length == 2) {
alert(prodetails.file.length);
$scope.saveFile(prodetails.file[0]).then(function(res) {
console.log("poooototot", res);
$scope.saveFile(prodetails.file[1]).then(function(res) {
$scope.Addprojectsimg(prodetails);
console.log("", Addprojectsimg);
alert('hai');
});
});
} else if (prodetails.file.length == 1) {
$scope.saveFile(prodetails.file[0]).then(function(res) {
alert("ok");
$scope.Addprojectsimg(prodetails);
});
} else {
$scope.Addprojectsimg(prodetails);
}
};
$scope.Addprojectsimg = function(prodetails){
console.log("projectadding",prodetails,$scope.photoId);
prodetails.image1_id= $scope.photoId;
console.log("SUB",prodetails);
$http.post(CONFIG.apiUrl+"/projectsubmit", prodetails).success(function(data, status) {
console.log("prorespons",data);
alert("images uploaded sucessfully");
})
};
Error
Error: $scope.saveFile(...).then is not a function
addprojectctrl/$scope.Addprojects#http://192.168.3.40:8081/2016/ANGULAR2016/ang-social/js/controllers.js:208:7
anonymous/fn#http://192.168.3.40:8081/2016/ANGULAR2016/ang-social/bower_components/angular/angular.js line 13365 > Function:2:332
ngEventHandler/http://192.168.3.40:8081/2016/ANGULAR2016/ang-social/bower_components/angular/angular.js:23613:17
$RootScopeProvider/this.$gethttp://192.168.3.40:8081/2016/ANGULAR2016/ang-social/bower_components/angular/angular.js:16052:16
$RootScopeProvider/this.$gethttp://192.168.3.40:8081/2016/ANGULAR2016/ang-social/bower_components/angular/angular.js:16152:20
ngEventHandler/<#http://192.168.3.40:8081/2016/ANGULAR2016/ang-social/bower_components/angular/angular.js:23618:17
n.event.dispatch#http://192.168.3.40:8081/2016/ANGULAR2016/ang-social/bower_components/jquery/dist/jquery.min.js:3:7467
n.event.add/r.handle#http://192.168.3.40:8081/2016/ANGULAR2016/ang-social/bower_components/jquery/dist/jquery.min.js:3:5583
return logFn.apply(console, args);
Please guide me to fix this issue. I think it small error only but i am new to AngularJS.
Your $scope.saveFile function isn't returning a promise, it should be like this:
$scope.saveFile = function(file) {
return Upload.upload({
url: CONFIG.apiUrl+'/fileupload',
data: {fileUpload: file}
}).success(function(data){
console.log("RSPPPPPPP",data.file._id);
$scope.photoId = data.file._id;
console.log("sdvfbghjm,kjhgfdsa",$scope.photoId);
});
};

Upload images associated to a meteor collection

I'm having a hard time understanding the whole process of uploading images to a certain Meteor collection eg.(the belongs_to and has_one association with rails).
I have a portfolioitem collection, this is the file:
PortfolioItems = new Mongo.Collection('portfolioItems');
ownsDocument = function(userId, doc) {
return doc && doc.userId === userId;
}
PortfolioItems.allow({
update: function(userId, portfolioItem) { return ownsDocument(userId, portfolioItem); },
remove: function(userId, portfolioItem) { return ownsDocument(userId, portfolioItem); },
});
Meteor.methods({
portfolioItemInsert: function(portfolioItemAttributes) {
check(Meteor.userId(), String);
check(portfolioItemAttributes, {
title: String
});
var portfolioItemWithSameTitle = PortfolioItems.findOne({ title: portfolioItemAttributes.title});
if (portfolioItemWithSameTitle) {
return {
portfolioItemExists: true,
_id: portfolioItemWithSameTitle._id
}
}
var user = Meteor.user();
var portfolioItem = _.extend(portfolioItemAttributes, {
userId: user._id,
submitted: new Date()
});
var portfolioItemId = PortfolioItems.insert(portfolioItem);
return {
_id: portfolioItemId
};
}
});
This is the submit.js template for submitting portfolio items:
Template.submit.events({
'submit #submit-form': function(e) {
e.preventDefault();
var portfolioItem = {
title: $(e.target).find('#submit-title').val()
};
Meteor.call('portfolioItemInsert', portfolioItem, function(error, result) {
if (error) {
return alert(error.reason);
}
if(result.portfolioItemExists) {
alert('Title already taken!');
pause();
}
Router.go('portfolioItemPage', {_id: result._id});
});
}
});
Did you give a try to FSCollection? if not i think its a good option to accomplish this.
You can just declare the collection.
I Suggest you to use GridFS.
just run this 2 commands
meteor add cfs:standard-packages
meteor add cfs:gridfs
Declare the collections like any others.
Images = new FS.Collection("Images", {
stores: [new FS.Store.GridFS("Images")]
});
And you can associate the Simple collection with the FSCollection using metadata.
Template.exampe.events({
'click #addImage':function(){
var file = $('#inputPng').get(0).files[0],
fsFile = new FS.File(file);
fsFile.metadata = {
ownerId:Meteor.userId(),
title:$(e.target).find('#submit-title').val()
}
Images.insert(fsFile,function(err,result){
if(!err){
console.log(result)
}
})
}
})
At this moment the README on the fsCollection its empty so I made a little DEMO about this.

How to get Email.send to send emails in the future (7 days, 14 days from now, etc)

I need to send email reminders to people in the future. I have implemented MomentJS and I can get dates I'd need my email to send, I just couldn't find anything in meteor docs for Email.send(options) to have anything there. Is there a different package you can recommend?
Here is some of my code as per #richsilv 's advice
createTransfer.js (client)
Template.createTransfer.events({
'submit form': function (event, template) {
event.preventDefault();
Transfers.insert(transfer, function (error, id) {
if (error) {
showError(error);
} else {
Session.set('files');
showAlert('Transfers sent!');
transfer._id = id;
Meteor.call('sendEmail', transfer);
scheduleEmail(transfer); // send reminder email
Router.go('viewTransfer', {_id: id});
}
});
// scheduleEmail(transfer);
console.log(transfer);
function scheduleEmail(transfer) {
if (transfer.invoice.due == "7 Days"){
console.log('its due in 7 days');
if (moment(transfer.date).add(7, 'days').calendar() == moment(new Date()).format("MM/DD/YYYY")) {
Meteor.call('sendMail',transfer);
}
} else if (transfer.invoice.due == "14 Days") {
if (moment(transfer.date).add(14, 'days').calendar() == moment(new Date()).format("MM/DD/YYYY")) {
Meteor.call('sendMail',transfer);
}
} else if (transfer.invoice.due == "30 Days") {
if (moment(transfer.date).add(30, 'days').calendar() == moment(new Date()).format("MM/DD/YYYY")) {
Meteor.call('sendMail',transfer);
}
} else if (transfer.invoice.due == "90 Days") {
if (moment(transfer.date).add(90, 'days').calendar() == moment(new Date()).format("MM/DD/YYYY")) {
Meteor.call('sendMail',transfer);
}
} else {
console.log('need to initiate cron!');
var thisId = FutureEmails.insert(transfer);
console.log('inserted into db');
Meteor.call('addCronMail',thisId, transfer);
}
}
methods.js (lib)
Meteor.methods({
sendMail: function(transfer) {
check([transfer.senderEmail,
transfer.recipientEmail,
transfer.message,
// transfer.invoice.total
], [String]);
// Let other method calls from the same client start running,
// without waiting for the email sending to complete.
this.unblock();
transfer.url = Meteor.absoluteUrl() +'transfer/' + transfer._id;
var template = 'invoice-due';
Email.send({
to: transfer.recipientEmail,
bcc: transfer.senderEmail,
from: transfer.senderEmail,
subject: transfer.senderEmail + ' sent you files!',
html: Handlebars.templates[template](transfer)
});
},
addCronMail: function(id, transfer) {
SyncedCron.add({
name: id,
schedule: function(parser) {
return parser.recur().on(transfer.date).fullDate();
},
job: function() {
sendMail(transfer);
FutureEmails.remove(id);
SyncedCron.remove(id);
return id;
}
});
}
});
cron.js (server)
Meteor.startup(function() {
FutureEmails.find().forEach(function(mail) {
if (moment(mail.date).format("MMM Do YY") == moment(new Date()).format("MMM Do YY")) {
sendMail(mail)
} else {
addCronMail(mail._id, mail);
}
});
SyncedCron.start();
});
As requested, although note that this is not tested, so you might have to play around with it.
$ meteor add percolatestudio:synced-cron
Then something like this on the server:
FutureEmails = new Meteor.Collection('future_emails'); // server-side only
// "details" should be an object containing a date, plus required e-mail details (recipient, content, etc.)
function sendMail(details) {
Email.send({
from: details.from,
to: details.to,
etc....
});
}
function addCronMail(id, details) {
SyncedCron.add({
name: id,
schedule: function(parser) {
return parser.recur().on(details.date).fullDate();
},
job: function() {
sendMail(details);
FutureEmails.remove(id);
SyncedCron.remove(id);
return id;
}
});
}
function scheduleEmail(details) {
if (details.date < new Date()) {
sendMail(details);
} else {
var thisId = FutureEmails.insert(details);
addCronMail(thisId, details);
}
}
Meteor.startup(function() {
FutureEmails.find().forEach(function(mail) {
if (mail.date < new Date()) {
sendMail(mail)
} else {
addCronMail(mail._id, mail);
}
});
SyncedCron.start();
});
Then just call scheduleEmail(details) whenever you want to schedule a new mail.
Hope that's helpful!

Categories

Resources