How to get origin property of reverted file in filepond - filepond

I followed filepond doc about Setting Initial Files to prepopulat filepond. Now, I want to write a custom revert function in which I can use different function based on file origin.
The following is a hypothetical code to show what I want to achieve:
#hypothetical code
revert: (uniqueFileId, load, error) => {
console.log('uniqueFileId is +' uniqueFileId);
const origin = ? ; //cannot figure out how to get file origin.
if (origin =='1'){ // origin is input
// run default function to remove input file
} else if (origin =='2'){ // origin is limbo
// run custom function to remove limbo file from server
});
} else { // origin is local
// run custom function to remove local file from server
}
error('oh my goodness');
// Should call the load method when done, no parameters required
load();
},
Question 1:
I cannot get origin of the file. I tried following code inside of revert function, none of them worked. How should I get the origin of the file?
const origin = origin;
console.log('origin is ' + origin); // console not printing anything, no error message.
const origin1 = FilePond.getFile().origin;
console.log('origin1 is ' + origin1);// console not printing anything, no error message.
Question 2:
suppose i can get origin of the file, how should I write function to remove input file? (in the origin == 1 case)? One thing I found was that when I click cancel button on newly added file, the uniqueFileId was 'success'. I am not sure if this is the way it should be because the file hasn't been uploaded or I have done something wrong.
In the case of 'LIMBO', the uniqueFileId was correctly shown as the file name such as '1.jpg'. I was able to pass this Id to the server.

The server.revert function is only called for limbo origins and input files that have been processed. For local files the server.remove function is used. The origin is not available in the server methods.
If you do need it you could store a separate list of files and compare the file id. In the server.revert method you can then use that list to see what kind of file it is.
const myFiles = {
'myuniquefileid': 'limbo',
'myotheruniquefileid': 'local',
}
FilePond.create({
server: {
revert: (uniqueFileId, load, error) => {
// origin
const origin = myFiles[uniqueFileId];
// more code
}
}
})

Related

Checksum Error while uploading files to BackBlaze (B2) using Ajax request

I have spent an awful lot of time trying to upload files to b2 using clientside ajax requests (vue-dropzone.js), and even though I supplied the file's valid sha1 checksum, the b2 server still responds with "checksum did not match data received" with status code 400. I've checked and rechecked the checksums with all the tools I have and I'm still not able to trace the source of the error. Its as if something happens to the file while its in transit or something.
I've uploaded the same files using the command line tool and it works fine but when I upload via ajax using the exact same sha1 checksum it doesn't work.
My questions are:
Does b2 even allow file uploads through ajax?
If it does allow uploads via ajax then what am i doing wrong?
Does the files remain valid when uploaded using "X-Bz-Content-Sha1", " do_not_verify". Cause I've tried that only to get invalid files when I downloaded them back.
Are there other things I need to know about uploading files to b2 using ajax requests
Please view my ajax codes see if I got anything wrong:
sending(file, xhr, formData) {
// This function runs for each file right before they are sent by dropezone.
// This is a good opportunity to insert file specific values
// in this case the file's upload url, name and auth token
let fileName = '';
console.log('this is file type', file.type);
if (file.type.includes('image')) {
fileName = 'images/${uuid.v1()}.png';
} else if (file.type.includes('video')) {
fileName = 'videos/${uuid.v1()}.${file.type.split(' / ')[1]}';
}
const url = appConfig.serverAddress + '/catalog/submitFiles';
console.log('this is sha1_hash', this.uploadInfo.sha1_hash);
// open the xhr request and insert the file's upload url here
xhr.open('Post', this.uploadInfo.url, true);
// set b2's mandatory request headers
// xhr.setRequestHeader(
// 'Authorization',
// 'Bearer ' + store.getters.getUserIdToken,
// );
xhr.setRequestHeader('Authorization', this.uploadInfo.authorizationToken);
xhr.setRequestHeader('X-Bz-Content-Sha1', this.uploadInfo.sha1_hash);
xhr.setRequestHeader('X-Bz-File-Name', fileName);
xhr.setRequestHeader('Content-Type', 'b2/x-auto');
formData = new FormData();
formData.append('files', file);
// the rest will be handled by dropzones upload pipeline
}
You are sending the file using form encoding, which causes the SHA-1 validation to fail since B2 is expecting the raw file data, with no encoding. The doc for b2_upload_file says:
The file to be uploaded is the message body and is not encoded in any way. It is not URL encoded. It is not MIME encoded.
I'm not an expert on vue-dropzone, but I'm guessing you need to just delete the two lines referencing formData. It looks like the default upload pipeline will send the raw file content.

Using http.GetFile how to prevent bad url requests from creating new files

I am using the http.getFile function to download files from an api. I am having a issue where files are still created, even though the url passed to getFile is invalid or returning errors. After some research it appears the getFile will always create a new file, is there a way to prevent getFile from creating a new file if the url is invalid?
The only work around I can think is to check the file size after calling the getFile and deleting it if there is no data?
In the example below I was tying to use the File.exists, but it always returns true.
return http.getFile(fullUrl, filePath)
.then(function(r){
// Test - Check if file Exists
console.log("Check File Exist: " + fs.File.exists(filePath));
}, function(error) {
});
Just check if the "fullUrl" is a valid url before requesting:
var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*#)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%#!\-\/]))?/
var isUrlValid = regexp.test(fullUrl);
if(isUrlValid){
http.getFile(fullUrl, filePath)
}

Getting file contents when using DropzoneJS

I really love the DropZoneJS component and am currently wrapping it in an EmberJS component (you can see demo here). In any event, the wrapper works just fine but I wanted to listen in on one of Dropzone's events and introspect the file contents (not the meta info like size, lastModified, etc.). The file type I'm dealing with is an XML file and I'd like to look "into" it to validate before sending it.
How can one do that? I would have thought the contents would hang off of the file object that you can pick up on many of the events but unless I'm just missing something obvious, it isn't there. :(
This worked for me:
Dropzone.options.PDFDrop = {
maxFilesize: 10, // Mb
accept: function(file, done) {
var reader = new FileReader();
reader.addEventListener("loadend", function(event) { console.log(event.target.result);});
reader.readAsText(file);
}
};
could also use reader.reaAsBinaryString() if binary data!
Ok, I've answer my own question and since others appear interested I'll post my answer here. For a working demo of this you can find it here:
https://ui-dropzone.firebaseapp.com/demo-local-data
In the demo I've wrapped the Dropzone component in the EmberJS framework but if you look at the code you'll find it's just Javascript code, nothing much to be afraid of. :)
The things we'll do are:
Get the file before the network request
The key thing we need become familiar with is the HTML5 API. Good news is it is quite simple. Take a look at this code and maybe that's all you need:
/**
* Replaces the XHR's send operation so that the stream can be
* retrieved on the client side instead being sent to the server.
* The function name is a little confusing (other than it replaces the "send"
* from Dropzonejs) because really what it's doing is reading the file and
* NOT sending to the server.
*/
_sendIntercept(file, options={}) {
return new RSVP.Promise((resolve,reject) => {
if(!options.readType) {
const mime = file.type;
const textType = a(_textTypes).any(type => {
const re = new RegExp(type);
return re.test(mime);
});
options.readType = textType ? 'readAsText' : 'readAsDataURL';
}
let reader = new window.FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = () => {
reject(reader.result);
};
// run the reader
reader[options.readType](file);
});
},
https://github.com/lifegadget/ui-dropzone/blob/0.7.2/addon/mixins/xhr-intercept.js#L10-L38
The code above returns a Promise which resolves once the file that's been dropped into the browser has been "read" into Javascript. This should be very quick as it's all local (do be aware that if you're downloading really large files you might want to "chunk" it ... that's a more advanced topic).
Hook into Dropzone
Now we need to find somewhere to hook into in Dropzone to read the file contents and stop the network request that we no longer need. Since the HTML5 File API just needs a File object you'll notice that Dropzone provides all sorts of hooks for that.
I decided on the "accept" hook because it would give me the opportunity to download the file and validate all in one go (for me it's mainly about drag and dropping XML's and so the content of the file is a part of the validation process) and crucially it happens before the network request.
Now it's important you realise that we're "replacing" the accept function not listening to the event it fires. If we just listened we would still incur a network request. So to **overload* accept we do something like this:
this.accept = this.localAcceptHandler; // replace "accept" on Dropzone
This will only work if this is the Dropzone object. You can achieve that by:
including it in your init hook function
including it as part of your instantiation (e.g., new Dropzone({accept: {...})
Now we've referred to the "localAcceptHandler", let me introduce it to you:
localAcceptHandler(file, done) {
this._sendIntercept(file).then(result => {
file.contents = result;
if(typeOf(this.localSuccess) === 'function') {
this.localSuccess(file, done);
} else {
done(); // empty done signals success
}
}).catch(result => {
if(typeOf(this.localFailure) === 'function') {
file.contents = result;
this.localFailure(file, done);
} else {
done(`Failed to download file ${file.name}`);
console.warn(file);
}
});
}
https://github.com/lifegadget/ui-dropzone/blob/0.7.2/addon/mixins/xhr-intercept.js#L40-L64
In quick summary it does the following:
read the contents of the file (aka, _sendIntercept)
based on mime type read the file either via readAsText or readAsDataURL
save the file contents to the .contents property of the file
Stop the send
To intercept the sending of the request on the network but still maintain the rest of the workflow we will replace a function called submitRequest. In the Dropzone code this function is a one liner and what I did was replace it with my own one-liner:
this._finished(files,'locally resolved, refer to "contents" property');
https://github.com/lifegadget/ui-dropzone/blob/0.7.2/addon/mixins/xhr-intercept.js#L66-L70
Provide access to retrieved document
The last step is just to ensure that our localAcceptHandler is put in place of the accept routine that dropzone supplies:
https://github.com/lifegadget/ui-dropzone/blob/0.7.2/addon/components/drop-zone.js#L88-L95
using the FileReader() solution is working amazingly good for me:
Dropzone.autoDiscover = false;
var dz = new Dropzone("#demo-upload",{
autoProcessQueue:false,
url:'upload.php'
});
dz.on("drop",function drop(e) {
var files = [];
for (var i = 0; i < e.dataTransfer.files.length; i++) {
files[i] = e.dataTransfer.files[i];
}
var reader = new FileReader();
reader.onload = function(event) {
var line = event.target.result.split('\n');
for ( var i = 0; i < line.length; i++){
console.log(line);
}
};
reader.readAsText(files[files.length-1]);

AngularJS setting headers on GET Request

I'm implementing a login authentication and the backend developer wants me to pass along the key value pairs in the header when i make a GET request. I'm new to AngularJS and I think my problem is the format of my header. I'm able to get a status 200 in Advanced Rest client (chrome extension for testing apis) with this format below. That is the raw format of the key value pairs if i put curly brackets around them or quotes or even a comma it throws an error so i'm very certain that should be the correct format.
identity: foo
password: bar
I've done every format possible to try to replicate it in the above example. So in my Code it goes like this, and i always get an error.
var config = {headers:{'identity': 'foo', 'password':'bar'}};
this.GetUser = function (config) {
return $http.get($rootScope.endPoint + '/user/email_token)', config);
};
you can do it like this:
$http.defaults.headers.common['identity'] = 'foo';
$http.defaults.headers.common['password'] = 'bar';
and call the api without additional properties
this.GetUser = function () {
return $http.get($rootScope.endPoint + '/user/email_token)');
};

Query logging tool for Firefox

I am looking for a way to log my own queries I submit to Google in Firefox. Is there a way so I can store them in a log file?
Cheers.
Do you need write an add-on and you can use many tools for solve this.
You can chose:
HTTP Observers
Listening to events on tabs
Load Events
WebProgressListeners
https://developer.mozilla.org/en-US/Add-ons/Overlay_Extensions/XUL_School/Intercepting_Page_Loads
https://developer.mozilla.org/en/docs/Listening_to_events_on_all_tabs
To log JS msj (error, warnings, logs) to disk, set the environment variable XRE_CONSOLE_LOG to the path to the filename. i.e. export XRE_CONSOLE_LOG=/path/to/logfile or set XRE_CONSOLE_LOG=C:\path\to\logfile.
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/XULRunner/Debugging_XULRunner_applications
Or you can create files
https://developer.mozilla.org/en-US/Add-ons/Code_snippets/File_I_O
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");
// get the "data.txt" file in the profile directory
var file = FileUtils.getFile("ProfD", ["GoogleQuery.txt"]);
// You can also optionally pass a flags parameter here. It defaults to
// FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE;
var ostream = FileUtils.openSafeFileOutputStream(file);
var converter = Components.classes["#mozilla.org/intl/scriptableunicodeconverter"].
createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
var istream = converter.convertToInputStream(data);
// The last argument (the callback) is optional.
NetUtil.asyncCopy(istream, ostream, function(status) {
if (!Components.isSuccessCode(status)) {
// Handle error!
return;
}
// Data has been written to the file.
//data is your string of your Google queries
});
Here is an add-on for Firefox or IE to log queries
http://www.lemurproject.org/querylogtoolbar/

Resources