I am aware that performing a stat on an uploaded file will only give creation/modified/access dates at the time the file was uploaded.
So a very quick question, is there any way for FineUploader to access the original file meta-data for these fields and send it along with the upload request?
From what I understand, this is probably not possible, but it never hurts to ask!
This feature is not natively supported by Fine Uploader. You could open up an issue if you think it would be a useful feature.
That being said, you can do it using Fine Uploader's callbacks and the FileAPI. The best you could do in any browser right now is get the lastModifiedDate using the FileAPI and add that to the parameters for each file in your onSubmitted callback,
var getLastModifiedDate = function(file) {
/* Cross-broswer File API shim to get Last Modified Date of a file */
}
var fineuploader = new qq.FineUploader/* ... */
/* snippet */
callbacks: {
onSubmitted: function(id, name) {
var file = fineuploader.getFile(id),
lastModified = getLastModifiedDate(file);
fineuploader.setParams({ lastModified: lastModified }, id);
});
}
/* snippet */
I found this question and answer which has an example and a shim to retrieve the lastModifiedDate.
Related
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]);
This question goes for mp3 and wav files as well.
I have set up an express.js server which basically sends the required files as follows:
res.sendFile('someImage.png', {root: './images'});
Then on the client-side, I receive the image with:
var req = new XMLHttpRequest();
...
req.onreadystatechange = function(e) {
if(req.readyState != 4) return;
...
writeMyFile(null, e.target.response, someCallback);
}
...
So in the response I do have my file. I want to write this file in to my local filesystem. I implement write as follows:
var writeMyFile = function(err, file, someCallback) {
this.dir.getFile('myImages/someImage.png', {create: true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
var blob = new Blob([file], {type: 'image/png'});
fileWriter.write(blob);
}, someCallback);
}, someCallback);
};
After executing these, I see a png file is created in myImages folder. It is however twice the size of the original file, and it is considered as corrupted by the operating system. Preview cannot view the image. Same goes for mp3/wav files as well, they are twice the size and won't play on any players and etc..
What am I doing wrong here? How can I write those files into filesystem appropiately?
The code above works perfectly when files are json objects. We suspect there might be an encoding problem, but no idea for fixes so far.
Finally, I am using the closure compiler.
Thanks for your help.
After sleeping on the problem, I found out the solution which was incredibly simple. So here it is for future reference.
On Xhr Request, make sure to set the responseType to arrayBuffer or blob before sending the request. In my case it is arrayBuffer because I already had a blob builder which would act on the data received. That is:
...
req.responseType = 'arraybuffer';
req.onreadystatechange = ...
req.send();
It turns out that Mime Type in blob construction won't affect these binary files to be written. In my case, I could store mp3 songs perfectly where I had their MIME as: 'image/png'. However I am not sure if this has other implications, I am just simply saying that the files worked ok no matter which type I had set.
I am uploading the file using the IBM Social Business Toolkit and now want to add tag(s) to it. Either as part of the upload or immediately afterwards. In the javadocs I can see that the FileService has a method to add a comment to a file. I can't see an equivalent for Tags though.
There is a Java method to update a tag on a community file - but it is broken in the most recent version of Smartcloud. It has actually been fixed in the most recent GitHub version of the code but it is not available for download as of April 2015.
The bug is reported here https://github.com/OpenNTF/SocialSDK/issues/1624. The method SHOULD be updateCommunityFileMetadata and with that we could add TAGs as Metadata. That would be simple to add to the end of the "addFile" Java method.
The sample code to TAG a file can be found here in the playgroup - it is updating the Meta Data via JavaScript API
https://greenhouse.lotus.com/sbt/sbtplayground.nsf/JavaScriptSnippets.xsp#snippet=Social_Files_API_UpdateCommunityFileMetadata
to TAG a file use the following
function tagFile(yourFileId, yourDocUnid){
require([ "sbt/connections/FileService", "sbt/dom", "sbt/json" ], function(FileService, dom, json) {
var fileService = new FileService();
var fileId = yourFileId
var docId = yourDocUnid
var tagArray = [];
tagArray.push(docId)
fileService.updateCommunityFileMetadata({
id: fileId,
tags: tagArray
}, communityId).then(function(file) {
dom.setText("json", json.jsonBeanStringify(file));
}, function(error) {
dom.setText("json", json.jsonBeanStringify(error));
});
});
}
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/
I want to build a website like Facebook style, and for start i am building a chat system using ajax. For now, all the messages that are sent to the chat system are saved in a xml file which looks like this:
<messages>
<message from="jhon" time="2:00">Hi!</message>
</messages>
My question is if it is fine to use the xml file like i do here, or a database is the solution. Can someone explain to me how to use xml in the right way also in the chat or a messages system if it is necessary at all?
Thank you!
I made an exercise (for school) that worked in a simular way:
<post>
<time>15:25</time>
<name>myUserName</name>
<message>testbla</message>
</post>
I used a PHP-script (provided by the teacher) to write in the file (in the format like before) each time there is a new message being sent by the user. While it was working well, there were a few problems I encountered:
In order to keep the chat updated, I had to reload the chat 3600 times per hour. This is no problem. However, because I was using XML, I had to download the file 3600x per hour, which is definitely not an elegant solution; with only a few messages, the site consumed about 20-40 MB data each hour. (you do the math!)
There were also issues with the special chars that conflicted to XML: <, > and &. I had to either escape them, remove them from the user input OR use CDATA to prevent XML from crashing due to syntax errors. (XML is very sensitive for this!) Additional difficulty was to prevent that others could send bad code. Generally, try to eliminate this while updating your XML-file.
With the above in mind, I would recommend searching for a more elegant solution than XML; JSON might be lighter to handle. Alternatively, MYSQL/PHP allow you to send only the last messages, so you don't have to send the whole file over and over again. (I don't have any PHP/MYSQL-expertise at this moment, so I cannot help you with that right now)
You asked how you could make your XML-chat happen. To give you some direction, I will give you some snippets of my code (with jQuery):
/* this function gets chat logs from XML and manipulate the content to a
div used for the chat-content. It is being evaluated each second by
an interval that calls the function each 1000 ms. (not included in this code) */
function getChatLogs() {
var chatLogs = "";
$.ajax({
url: "chat_log.xml",
success: function(data) {
$(data).find("post").each(function() {
var timeMessage = $(this).find("time").text();
var nameSender = $(this).find("name").text();
var contentMessage = $(this).find("message").text();
chatLogs += "<article><time>" + timeMessage + "</time> <strong>" + nameSender + "</strong> <p>" + contentMessage+ "</p></article>";
});
$("#chat").html(chatLogs);
}
});
}
/* this function handles messages being send by the user */
function sendInput(keyCode) {
if(keyCode === 13 && $("#post").val() != "") {
var name = localStorage.getItem("username"); // I used localstorage fo username
var time = currentTime();
var message = $("#post").val();
$.ajax({
type: "POST",
url: "save.php",
data: {"name": name, "time": time, "message": message},
success: function(data) {
$("#post").val(""); // (clear the chat-input)
}
});
}
}
Bonus tip: you XML-file MUST be well formed. You can easily check if this is the case by opening the XML-file straight in Chrome. If there are issues, it will give an error.