Convert blob to file and upload to s3 - meteor

I am trying to convert a blob to a file but s3 doesn't return any error or results.
$('#frontPictureCropp').cropper('getCroppedCanvas').toBlob(function(blob) {
var file = new File([blob], imageId + '.png', {type: "image/png"});
console.log(file);
S3.upload({
files: file,
path:"IL"
},function(e,r){
if(e)console.log(e);
if(r) {
console.log(r);
var imageData = [r._id, r.secure_url];
}
});
});
file in the console:
Thu Jan 19 2017 13:53:03 GMT+0200 (IST)
name
:
"HJ3ZnCq842EPKbnDx.png"
size
:
42562
type
:
"image/png"
webkitRelativePath
:
""

Related

File uploads to s3 using Meteor Slingshot stopped working with error 403

I have been using meteor-slingshot to upload files to amazon S3 for some time. All of a sudden none of my upload functions seems to work. I am getting the following error when I try to upload files.
Error uploading errorClass {error: "Forbidden - 403", reason: "Failed to upload file to cloud storage", details: undefined, message: "Failed to upload file to cloud storage [Forbidden - 403]", errorType: "Meteor.Error"…}
All the uploads were working fine last week, and all of a sudden I am getting the above error in all my projects. I don't know if its some problem with the slingshot package or if some change has been made to s3 policies.
This is the code I am using
Slingshot.fileRestrictions("myFileUploads", {
allowedFileTypes: ["image/png", "image/jpeg", "image/gif" ,],
maxSize: null // 10 MB (use null for unlimited).
});
Slingshot.createDirective("myFileUploads", Slingshot.S3Storage, {
bucket: "*****",
acl: "public-read",
region : "ap-southeast-1",
AWSAccessKeyId : "MyAccessKey",
AWSSecretAccessKey : "MySecretKey",
authorize: function () {
return true;
},
key: function (file) {
var imageName = getUniqueID()
return "images/" + imageName;
}
});
getUniqueID = function(){
this.length = 8;
this.timestamp = +new Date;
var ts = this.timestamp.toString();
var parts = ts.split( "" ).reverse();
var id = "";
var _getRandomInt = function( min, max ) {
return Math.floor( Math.random() * ( max - min + 1 ) ) + min;
}
for( var i = 0; i < this.length; ++i ) {
var index = _getRandomInt( 0, parts.length - 1 );
id += parts[index];
}
return id;
}
This is my CORS configuration
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
And my bucket policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MyBucketName/*"
}
]
}

Compress .xls/xlsx files into .zip files jsZip

I'm a newbie to the field of javascript/angularJS, so please bear with me.I need a way to convert .xls/.xlsx files into .zip files by using jsZip library. I'm making use of alasql for generating the .xls file. I've looked all over for any possible solutions to create zip file of all xls files, but haven't come across any demo. (.txt and .doc files generate just fine, but .xls files does not open if jsZip is used). Any help would be appreciated!!
What I need is an xls file to be generated dynamically, and the same file to be compressed as zip
EDIT :-
Here's some of the code which I tried (but with no success)
var newExcelData = {'Name':'abc'};
//var res = alasql("SELECT * INTO XLSX('Summary.xlsx',{headers:true}) FROM ? ", [newExcelData]);
var zip = new JSZip();
zip.file(alasql("SELECT * INTO XLSX('Summary.xlsx',{headers:true}) FROM ? ", [newExcelData]));
zip.generateAsync({ type: "blob" })
.then(function (content) {
saveAs(content, "example.zip");
});
PS:- I'm able to make it work in case of generating .xls file.
Please refer below code:-
var newExcelData = {'Name':'abc', 'Age':'12'};
var zip = new JSZip();
zip.file("test.xls", [newExcelData]);
zip.generateAsync({ type: "blob" })
.then(function (content) {
saveAs(content, "example.zip");
});
But although excel sheet is generated, on opening excel sheet is blank.
Please help!!
Hi, here's an update :-
I've tried to make use of js-xlsx library - https://github.com/SheetJS/js-xlsx - to generate xls file and then zip it. Please refer the below code..
function Create_Zip() {
function datenum(v, date1904) {
if (date1904) v += 1462;
var epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}
function sheet_from_array_of_arrays(data, opts) {
var ws = {};
var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 } };
for (var R = 0; R != data.length; ++R) {
for (var C = 0; C != data[R].length; ++C) {
if (range.s.r > R) range.s.r = R;
if (range.s.c > C) range.s.c = C;
if (range.e.r < R) range.e.r = R;
if (range.e.c < C) range.e.c = C;
var cell = { v: data[R][C] };
if (cell.v === null) continue;
var cell_ref = XLSX.utils.encode_cell({ c: C, r: R });
if (typeof cell.v === 'number') cell.t = 'n';
else if (typeof cell.v === 'boolean') cell.t = 'b';
else if (cell.v instanceof Date) {
cell.t = 'n'; cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
}
else cell.t = 's';
ws[cell_ref] = cell;
}
}
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
return ws;
}
var data = [[1, 2, 3], [true, false, null, "sheetjs"], ["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"], ["baz", null, "qux"]];
var ws_name = "SheetJS";
function Workbook() {
if (!(this instanceof Workbook)) return new Workbook();
this.SheetNames = [];
this.Sheets = {};
}
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'binary' });
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
var jsonse = JSON.stringify([s2ab(wbout)]);
var testblob = new Blob([jsonse], { type: "application/json" });
console.log(testblob);
var zip = new JSZip();
zip.file("trial.xls", testblob);
var downloadFile = zip.generateAsync({ type: "blob" });
saveAs(downloadFile, 'test.zip');
}
But, the problem here is that I keep getting this error: 'The data of 'trial.xls' is in an unsupported format !' in the console :(. Is there any way I can make this work?
I'm at my wits end now :(
Not an answer (see below) but an explanation of what's going on:
To add a file, JSZip needs its binary content (as Blob, Uint8Array, etc). The line zip.file("test.xls", [newExcelData]); can't work for example: [newExcelData] is not a binary content but an array of js object.
What you need to figure out is how to get the content of the xlsx file. SELECT * INTO XLSX('Summary.xlsx') will trigger a download and return 1, it's not what you want. I searched on my side but can't find a way to do it with alasql.
Once/if you find the solution, the JSZip part looks correct.
Edit, following your switch to js-xlsx:
You use JSZip v2 (needed by js-xlsx) which doesn't support Blob inputs. However, wbout is a binary string which is supported:
zip.file("trial.xls", wbout, {binary: true});
Then, replace zip.generateAsync (added in JSZip v3):
var downloadFile = zip.generate({type: "blob" });
saveAs(downloadFile, 'test.zip');
Here is the solution I found using JSZip, XLSX and File Saver libraries.
Import:
import * as XLSX from "xlsx";
import JSZip from 'jszip';
import { saveAs } from 'file-saver';
Here is an example of compressing a .xlsx inside a zip:
let zip = new JSZip();
const jsonData = [
{
"Product": "Red Velvet Cupcake",
"Price": "6",
"GluttenFree": "Yes",
},
{
"Product": "Cheesecake",
"Price": "15",
"GluttenFree": "No",
}
];
const workBook: XLSX.WorkBook = XLSX.utils.book_new();
const workSheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(jsonData);
XLSX.utils.book_append_sheet(workBook, workSheet, 'Bakery');
const workBookBuffer = XLSX.write(workBook, { bookType: 'xlsx', type: 'array' });
const fileData = new Blob([workBookBuffer], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'});
zip.file('Products.xlsx', fileData);
zip.generateAsync({type:"blob"}).then(function (blob) {
saveAs(blob, "WorkBooks.zip");
});
This code generates a zip file named 'WorkBooks.zip' that contains the file 'Products.xlsx'. This is how the excel looks like:
Some file-saver examples: https://www.tabnine.com/code/javascript/modules/file-saver.
Here is the JSZip method used:
https://stuk.github.io/jszip/documentation/api_jszip/file_data.html

How can I pipe the output from gulp-w3c-css to the console

When I follow the examples for gulp-w3c-css I am unable to get the results to print in the console instead of in an output directory.
Compare how I am using CSSLint and W3C-CSS below. I'd like the function to be identical.
var gulp = require('gulp'),
csslint = require('gulp-csslint'),
cssvalidate = require('gulp-w3c-css');
gulp.task('csslint', () =>
gulp.src('testcss/laxhjalpen.css')
.pipe(csslint('.csslintrc'))
.pipe(csslint.reporter())
);
// Does not work
gulp.task('cssvalid', () =>
gulp.src('testcss/*css')
.pipe(cssvalidate())
// Next line works but is not what I want
.pipe(gulp.dest('reports'))
// I suppose I need to get this construct to work but I can't
.pipe(gutil.buffer(function(err, files) {
if (err) {
gutil.log('An error occured', err);
} else {
// No idea what to write
// files - array of validation results (from manual)
}
}))
);
The very best solution would be just to have a reporter function that works like the csslint.reporter does.
The gulp-w3c-css plugin serializes the validation results for each file to JSON and stores that JSON in the file.contents property. The format of that JSON serialization looks roughly like the following (for more details see the w3c-css documentation):
{
errors: [ { line: 5, message: 'Some error' },
{ line: 42, message: 'Some error' } ],
warnings: [ { line: 13, message: 'Some warning' },
{ line: 23, message: 'Some warning' } ]
}
So all you have to do is parse that JSON and then log the information to the console in any way you want.
Here's a simple example of how you could do it:
var gulp = require('gulp');
var cssvalidate = require('gulp-w3c-css');
var gutil = require('gulp-util');
var map = require('map-stream');
gulp.task('cssvalid', function () {
return gulp.src('testcss/*css')
.pipe(cssvalidate())
.pipe(map(function(file, done) {
if (file.contents.length == 0) {
console.log('Success: ' + file.path);
console.log(gutil.colors.green('No errors or warnings\n'));
} else {
var results = JSON.parse(file.contents.toString());
results.errors.forEach(function(error) {
console.log('Error: ' + file.path + ': line ' + error.line);
console.log(gutil.colors.red(error.message) + '\n');
});
results.warnings.forEach(function(warning) {
console.log('Warning: ' + file.path + ': line ' + warning.line);
console.log(gutil.colors.yellow(warning.message) + '\n');
});
}
done(null, file);
}));
});
I used map-stream instead of gutil.buffer() so that the results for each file are printed as soon as they are available instead of printing everything at the very end.

Access nested array in Autoform method-update

I am trying to get the value of a nested array from a method that updates an Autoform generated form.
I have a schema set up like this...
Schema.ContactDetails = new SimpleSchema({
orderedBy: {
type: String,
label: "Ordered By",
optional: true,
},
[...]
)};
Orders.attachSchema(new SimpleSchema({
[...]
orderDetails: {
type: Schema.OrderDetails,
optional: true,
blackbox: true
},
[...]
)};
I then have an Autoform set up with this...
{{#autoForm collection="Orders" id="updateOrderForm" type="method-update" meteormethod="updateOrder" doc=this}}
[...]
{{/autoForm}}
And this is the updateOrder method...
updateOrder: function (doc,doc_id) {
check(doc, Orders.simpleSchema());
console.log(doc);
//Modify doc here
Orders.update({_id: doc_id}, doc);
},
The above console.log(doc); outputs the following...
{ '$set':
{ createdBy: 'o5Wye6LLMGNXLn7HY',
createdAt: Sat Apr 09 2016 22:15:27 GMT+1000 (AEST),
'contactDetails.orderedBy': 'MvCun8p6vxndj3cr8',
updatedAt: Mon Apr 11 2016 11:47:31 GMT+1000 (AEST) },
'$unset':
{ […]
My problem is that I need to get the 'contactDetails.orderedBy' value in the updateOrder method but I can't seem to access it. I have tried the following...
var orderedBy = doc.$set.contactDetails.orderedBy;
Exception while invoking method 'updateOrder' TypeError: Cannot read property 'orderedBy' of undefined
var orderedBy = doc.$set.'contactDetails.orderedBy';
Unexpected token error
Thanks in advance
Answered here...Dynamically access object property using variable
and here...Extract value from object using javascript
var orderedBy = doc.$set['contactDetails.orderedBy'];

How to read value when using model.save() or fetch()?

Man = Backbone.Model.extend({
url:'/test.aspx',
initialize: function(){
},
defaults: {
name:'Jim',
age: '38'
},
validate:function(attributes){
if(attributes.name == '') {
return "name can't be null";
}
}
});
var man = new Man;
man.set({name:'the5fire'});
man.save(); //the format is json{"name":"the5fire","age":38}
In test.aspx.cs, how can I read this value {"name":"the5fire","age":38} ?
I have tried Request.Form.ToString() but found no data there.
Chrome developer tools shows this json-format data in the "request payload" block.
update:
If I use man.fetch({ data: { Pagesize: '1', PageIndex: '111' } ), then on the server side, I can use Request.Params["PageIndex"]. But how can I get the name? the age?
You can access the raw body of the request via HttpRequest.InputStream and convert it to a string :
string jsonstring = new System.IO.StreamReader(Request.InputStream).ReadToEnd();
You would then deserialize this string to get an object, for example:
using System.Web.Script.Serialization;
JavaScriptSerializer jss = new JavaScriptSerializer();
var d = jss.Deserialize<dynamic>(jsonstring);
string name = (string)d["name"];

Resources