I've followed the letter of the law (Javscript SDK) along with numerous variations but thus far I have not been able to save an image to a Parse.File. I'm starting think this is code they never finished before they abandoned the platform?
This is my error:
Failed to construct 'File': 2 arguments required, but only 0 present.
This is my code:
var base64 = $base64.encode(unescape(encodeURIComponent('a string')));
var file = new Parse.File("logo.png", { base64: base64});
file.save().then(function(){
var newLogo = new Parse.File();
newLogo.set('step2.png', file);
newLogo.save().then(function(){
offer.set("Alogo.png", newLogo);
offer.save();
}).then(function(){}, function(error){console.log(error);});
});
It saves no image or note of 'Alogo.png' or anything dealing with a logo in my ParseDB. Any help you could offer would be much appreciated!
For once, Parse was right on point. The issue was not with my code but with Angular and it's lack of recognition of 'file' tags in html. This post/tutorial proved very useful as it has a directive that enables angular to recognize post tags so that angular can add files to the model.
http://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs
Related
I’d like to use javascript to create and save a large .csv file client-side. This has been asked and answered before (see 1, 2, 3, or 4, for example), and this comes down to two approaches (among others):
Use FileSaver.js to implement w3c’s saveAs():
var lines = ["line 1,cell 11,cell 12\n","line 2,cell 21,cell 22\n"];
var type = "text/csv;charset=utf-8";
var blob = new Blob(lines,{"type":type});
saveAs(blob,"download.csv");
Use a[download] and a data uri:
var lines = ["line 1,cell 11,cell 12\n","line 2,cell 21,cell 22\n"];
var type = "text/csv;charset=utf-8";
var downloader = $('<a download href="data:'+type+','+escape(lines.join(''))+'"></a>')
.appendTo("body")
downloader[0].click();
downloader.remove();
My problem is that my file can be gigantic: 18 million lines and 2.5 Gb (and I’d like to be able to handle more). Creating lines uses too much memory and crashes the site. But there’s no reason to store lines in the browser’s memory just to save it to the hard drive. Is there a way to create a progressive download using javascript (in other words, start the download but keep appending lines as I calculate them)? Or would my only option be to download the file as separate chunks that the user must then join together?
If you are using HTML5, you can try using the FileSytem API. See here for information on the subject, and here for a more practical example on how to create and access files fron the client-side.
I'm trying to render a JBIG2 image in a browser. This script, which is part of pdf.js appears to do this:
https://github.com/mozilla/pdf.js/blob/master/src/core/jbig2.js
Only it does not have instructions on its usage as it is usually executed as a dependency of pdf.js (for complete PDF rendering, which I don't want or need.)
Can anyone figure out how I would use this script to render a JBIG2 image on a web page?
As nobody has helped you out with this, let me at least share my progress on this problem:
<script src="arithmetic_decoder.js"></script>
<script src="util.js"></script>
<script src="jbig2.js"></script>
<script>
var jbig2 = new Jbig2Image();
httpRequest = new XMLHttpRequest();
httpRequest.responseType = 'arraybuffer';
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
var data = jbig2.parseChunks([{
data:new Uint8Array(httpRequest.response),
start:0,
end:httpRequest.response.byteLength
}]);
for (var i = 0; i < data.length; i++)
data[i] ^= 0xFF;
console.log(data);
} else {
alert('There was a problem with the request.');
}
}
};
httpRequest.open('GET', "sample.jbig2");
httpRequest.send();
</script>
So, this makes all the relevant dependencies clear, it contains the way I believe the parseChunks function should be called (I am sure about the Uint8Array part in combination with the arraybuffer from the XMLHttpRequest, not sure whether I shouldn't first slice it up or anything like that). The array returned to data looks like some sort of pixel array, but lacking any information about width or height I am not sure how to continue. Additionally the sample .jbig2 file you provided gives a corruption error in STDU viewer (the only free app I could find to view .jbig2 files), so I couldn't check whether the image is mostly white (as the resulting data seems to suggest) nor drawing the result by hand seemed like a good idea as I didn't have any width or height. If you wish to draw it the way to go is of course a canvas element (ideally you should construct a pixeldataarray and then use putImageData).
Now, let me outline a way for you to 'figure' out the rest of the solution. What would work best probably is forking pdf.js, adding logging, generating a pdf with just a single jbig2 image and then observing how exactly the above array gets drawn to a canvas (and how/where the dimensions are determined).
JBIG2 used in PDF spec are a subset of full JBIG2 specification (so called embedded profile). For example, in pdf you can have a jbig2 stream that can reference only a single shared symbol dictionary. The full spec does not have this restriction and it also defines a format to bring all pieces together (all of which is missing in pdfjs).
In summary, what you are looking for is technically possible (with some effort), but it is not simple.
Could you process it server side?
There's a good post on stackoverflow on using Java or tools
Print PDF that contains JBIG2 images
Sorry about the vague title but I'm a bit lost so it's hard to be specific. I've started playing around with Firefox extensions using the add-on SDK. What I'm trying to to is to watch a page for changes, a Twitch.tv chat window in this case, and save those changes to a file.
I've gotten this to work, every time something changes on the page it gets saved. But, "unusual" characters like for example something in Korean doesn't get saved properly. I think this has to do with encoding of the file/string? I tried saving the same characters by copy-pasting them into notepad, it asked me to save in Unicode and when I did everything worked fine. So I figured, ok, I'll change the encoding of the log file to unicode as well before writing to it. Didn't exactly work... Now all the characters were in some kind of foreign language.
The code I'm using to write to the file is this:
var {Cc, Ci, Cu} = require("chrome");
var {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
var file = FileUtils.getFile("Desk", ["mylogfile.txt"]);
var stream = FileUtils.openFileOutputStream(file, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_APPEND);
stream.write(data, data.length);
stream.close();
I looked at the description of FileUtils.jsm over at MDN and as far as I can tell there's no way to tell it which encoding I want to use?
If you don't know a fix could you give me some good search terms because I seem to be coming up short on that front. Since I know basically nothing on the subject I'm flailing around in the dark a bit at the moment.
edit:
This is what I ended up with (for now) to get this thing working:
var {Cc, Ci, Cu} = require("chrome");
var {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
var file = Cc['#mozilla.org/file/local;1']
.createInstance(Ci.nsILocalFile);
file.initWithPath('C:\\temp\\temp.txt');
if(!file.exists()){
file.create(file.NORMAL_FILE_TYPE, 0666);
}
var charset = 'UTF-8';
var fileStream = Cc['#mozilla.org/network/file-output-stream;1']
.createInstance(Ci.nsIFileOutputStream);
fileStream.init(file, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_APPEND, 0x200, false);
var converterStream = Cc['#mozilla.org/intl/converter-output-stream;1']
.createInstance(Ci.nsIConverterOutputStream);
converterStream.init(fileStream, charset, data.length,
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
converterStream.writeString(data);
converterStream.close();
fileStream.close();
Dumping just the raw bytes (well, raw jschars actually) won't work. You need to first convert the data into some sensible encoding.
See e.g. the File I/O Snippets. Here are the crucial bits of creating a converter output stream wrapper:
var converter = Components.classes["#mozilla.org/intl/converter-output-stream;1"].
createInstance(Components.interfaces.nsIConverterOutputStream);
converter.init(foStream, "UTF-8", 0, 0);
converter.writeString(data);
converter.close(); // this closes foStream
Another way is to use OS.File + TextConverter:
let encoder = new TextEncoder(); // This encoder can be reused for several writes
let array = encoder.encode("This is some text"); // Convert the text to an array
let promise = OS.File.writeAtomic("file.txt", array, // Write the array atomically to "file.txt", using as temporary
{tmpPath: "file.txt.tmp"}); // buffer "file.txt.tmp".
It might be even possible to mix both. OS.File has the benefit that it will write data and access files off the main thread (so it won't block the UI while the file is being written).
The JavaScript process generates a lot of data (200-300MB). I would like to save this data for further analysis but the best I found so far is saving using this example http://jsfiddle.net/c2U2T/ which is not an option for me, because it looks like it requires all the data being available before starting the downloading. But what I need is something like
var saver = new Saver();
saver.save(); // The Save As ... dialog appears
saver.onaccepted = function () { // user accepted saving
for (var i = 0; i < 1000000; i++) {
saver.write(Math.random());
}
};
Of course, instead of the Math.random() will be some meaningful construction.
#dader - I would build upon dader's example.
Use HTML5 FileSystem API - but instead of writing to the file each and every line (more IO than it is worth), you can batch some of the lines in memory in a javascript object/array/string, and only write it to the file when they reach a certain threshold. You are thus appending to a local file as the process chugs (makes it easy to pause/restart/stop etc)
Of note is the following, which is an example of how you can spawn the dialoge to request the amount of data that you would need (it sounds large). Tested in chrome.:
navigator.persistentStorage.queryUsageAndQuota(
function (usage, quota) {
var availableSpace = quota - usage;
var requestingQuota = args.size + usage;
if (availableSpace >= args.size) {
window.requestFileSystem(PERSISTENT, availableSpace, persistentStorageGranted, persistentStorageDenied);
} else {
navigator.persistentStorage.requestQuota(
requestingQuota, function (grantedQuota) {
window.requestFileSystem(PERSISTENT, grantedQuota - usage, persistentStorageGranted, persistentStorageDenied);
}, errorCb
);
}
}, errorCb);
When you are done you can use Javascript to open a new window with the url of that blob object that you saved which you can retrieve via: fileEntry.toURL()
OR - when it is done crunching you can just display that URL in an html link and then they could right click on it and do whatever Save Link As that they want.
But this is something that is new and cool that you can do entirely in the browser without needing to involve a server in any way at all. Side note, 200-300MB of data generated by a Javascript Process sounds absolutely huge... that would be a concern for whether you are storing the "right" data...
What you actually are trying to do is a kind of streaming. I mean FileAPI is not suited for the task. Instead, I could suggest two options :
The first, using XHR facility, ie ajax, by splitting your data into several chunks which will sequencially be sent to the server, each chunk in its own request along with an id ( for identifying the stream ) and a position index ( for identifying the chunk position ). I won't recommend that, since it adds work to break up and reassemble data, and since there's a better solution.
The second way of achieving this is to use Websocket API. It allows you to send data sequentially to the server as it is generated. Following a usual stream API. I think you definitely need this.
This page may be a good place to start at : http://binaryjs.com/
That's all folks !
EDIT considering your comment :
I'm not sure to perfectly get your point though but, what about HTML5's FileSystem API ?
There are a couple examples here : http://www.html5rocks.com/en/tutorials/file/filesystem/ among which this sample that allows you to append data to an existant file. You can also create a new file, etc. :
function onInitFs(fs) {
fs.root.getFile('log.txt', {create: false}, function(fileEntry) {
// Create a FileWriter object for our FileEntry (log.txt).
fileEntry.createWriter(function(fileWriter) {
fileWriter.seek(fileWriter.length); // Start write position at EOF.
// Create a new Blob and write it to log.txt.
var blob = new Blob(['Hello World'], {type: 'text/plain'});
fileWriter.write(blob);
}, errorHandler);
}, errorHandler);
}
EDIT 2 :
What you're trying to do is not possible using javascript as said on SO here. Tha author nonetheless suggest to use Java Applet to achieve needed behaviour.
To put it in a nutshell, HTML5 Filesystem API only provides a sandboxed filesystem, ie located in some hidden directory of the browser. So if you want to access the true filesystem, using java would be just fine considering your use case. I guess there is an interface between java and javascript here.
But if you want to make your data only available from the browser ( constrained by same origin policy ), use FileSystem API.
I'm working on a PhoneGap application that captures images using the camera and, later, uploads them. There are two modes of operation for camera in PhoneGap: raw base64 encoded data or a file URI.
The docs themselves say:
Note: The image quality of pictures taken using the camera on newer
devices is quite good. Encoding such images using Base64 has caused
memory issues on some of these devices (iPhone 4, BlackBerry Torch
9800). Therefore, using FILE_URI as the 'Camera.destinationType' is
highly recommended.
So I'm keen to use FILE_URI option. This works great and you can even show the images in IMG tags. The URL looks like this:
file://localhost/var/mobile/Applications/4FE4642B-944C-449BB-9BD6-1E442E47C7CE/tmp/photo_047.jpg
However, at some point later I want to read the contents of the file to upload to a server. I was going to do this using the FileReader type. This doesn't work and I think it's because I can't access the file at the URL above.
The error code I get back from readDataUrl is 1 > FileError.NOT_FOUND_ERR = 1;
Any ideas how I can get to the file? I tried just accessing the last part of the path (photo_047.jpg) based on another sample I saw but no luck.
I'm just getting started with PhoneGap, and given the age of this question you may have found an answer already, but I'll give it a try anyway.
First, would you be able to use the built-in FileTransfer object? It takes a file: URI as an argument.
If FileTransfer won't work for you, and you need to read the file data yourself, you'll need the PhoneGap File objects, like FileReader , as you said. But most of those expect a plain pathname -- not a URI -- to specify the file to work with. The reason you're getting NOT_FOUND_ERR is because it's trying to open a file named file:/localhost/var....
Here's a quick one-liner to extract the path part from your URI:
var path = /file:\/\/.*?(\/.*)/.exec(fileuri)[1];
Hope this helps!
The answer from jgarbers was of help to me but it did not solve the problem. I realized the camera stores photos in Temp folder instead of Document folder. Setting my local file system to temporary allowed it to find the correct location for the camera images.
window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, ...
...
window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, ...
...
var path = /file://.?(/.)/.exec(fileuri)[1];
Ref. above jgarbers and Rik answers (solution has been tested successfully on iOs 7)
you can user the file transfer plugin for uploading any file to the server.
//// pass your file uri to the mediafie param
function uploadFile(mediaFile) {
var ft = new FileTransfer();
path = mediaFile.fullPath;
name = mediaFile.name;
////your service method url
var objUrl = http://example.com;
ft.upload(path,
objUrl,
function (result) {
alert("Success");
},
function (error) {
alert('Error uploading file ' + path + ': ' + error.code);
},
{ fileName: name });
}