Change file names before uploading with SWFUpload - javascript

I am using SWFUpload to allow users to upload multiple files in any browser. A user can provide custom file names for the files being uploaded. How can I iterate through all the queued files and update the name of the file to the custom name before the file is uploaded.
If I can't change the file name, how do I add a post parameter to each file being uploaded to make the change on the server side? I know how to add parameters for all files but how would I do it for each file?

You can't update the actual name of the file that gets sent in the POST body of the file upload because internally, SWFUpload is using a FileReference which doesn't let you change any of the file's properties before uploading it (and there's no way to get proper upload progress without using a FileReference to do the uploading, so this isn't something that can really be changed).
However, you should be able to add an extra POST parameter per file via the addFileParam function. Its signature is:
addFileParam(file_id:String, name:String, value:String):Boolean

Related

AWS S3 presigned-url: How to make sure that the file type is correct?

The HTTP headers (Content-Type) and the metadata that an HTML file input returns (file.type) are not reliable and could be easily bypassed by hackers. So how do you make sure that the file that is going to be uploaded to S3 has the correct file type when using AWS s3 presigned[-post]-urls?
There are packages like file-type that can detect the actual type of a file. But the problem is that in order to detect the file type they need the content of the file as a buffer or Uint8Array. So I have to send the file twice. Once to the server to detect the file type and the presigned-url (if it has a correct type), and once for actually uploading it to s3, which is obviously a bad thing.

Android webview - how to fetch a file from external storage

I have a mobile app that wraps around the web-app, using webview.
The web-app has a button to open a large .zip file (e.g. 100 MB).
The user clicks a button, and selects a .zip file.
This triggers an onChange function with a variable of type File (Blob), which includes attributes like:
file name
file size
file type (application/zip)
The javascript code then parses the .zip file, extracts specific data within it and uses it within the web-app.
This works well within the web-app, when the app is called via the Chrome browser.
For example when operated in chrome browser on an Android phone, I can pull the .zip file and open it in the web-app.
I want to do the same but using the mobile app.
I am able to pick up the .zip file using a File Chooser, and pass it to Webview but I have problems to fetch the file from the Javascript code.
For reference, I am able to pass an image, by creating a data_uri using stringBuilder and passing the content (as data:image/jpeg;base64).
But the zip file is much larger.
When calling fetch(fileUri) from the Javascript side I'm getting errors.
I'm using the following uri
/storage/emulated/0/Android/data/com.example/files/Download/file2.zip
The fetch succeeds but returns a blob with size of 165 (i.e. not the actual size of the file) which hosts the error message:
{
"error": "Not Found",
"message": "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
}
The program flow is like so:
I select a .zip file via FileChooser.
In onActivityResult, the uri value is /document/msf:12858 (seen via uri = intent.getData();)
The uri needs to be mapped into a real path file url, such that the fileUrl will be passed to webview.
Webview will then fetch the file using the fileUrl.
I searched how to get the real path file url when selecting a file with FileChooser, and found
this, and this links.
I wasn't able to get the real file path, so I decided to read the file and write it to another location, so I can get a file path. (this is not efficient and done just to check the functionality).
I create the new file using the following code:
InputStream stream = context.getContentResolver().openInputStream(uri);
File file2 = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "file2.zip");
writeBytesToFile(stream, file2);
I don't see any errors when creating the file, and when creating the file, the number of bytes that are read and written to the new file are as expected.
For file2, I get a value of:
/storage/emulated/0/Android/data/com.example/files/Download/file2.zip
Then, within the Javascript code I fetch this file path.
But I'm getting a Blob with the "file-not-found" content as above.
So:
How can I verify that the file is indeed created and that the path can be fetched from webview?
How can I get the real file path of the original selected file, so I don't have to read and write the original file to new location just to get the file path?
Thanks
I was able to get the file from external storage by doing the following steps:
create an initial uri (uri1)
The uri is created by:
creating a temporary file (file1) in the storage dir via
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
I'm not sure why a temporary file need to be created but if I don't create a file I cannot get the uri.
createFile3
get the uri via
Uri uri1 = FileProvider.getUriForFile(context, "com.example.android.fileprovider", file1);
create an intent with the following attributes:
Intent.ACTION_OPEN_DOCUMENT
category: Intent.CATEGORY_OPENABLE
type: "application/zip"
extra attribute: fileIntent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri1);
this opens a dialog box for selecting openable zip files in the Downloads directory,
after the file is selected, a new uri (uri2) is created that includes the name of the selected file.
extract the name of the file via
String fileName = getFileName(context, uri2);
create the dirPath by appending the filename
dirPath = "/data/user/0/com.example/" + fileName;
if the dirPath does not exist (first time), write the file to its dirPath location.
on successive ocassions dirPath exists, so there is no need to re-write the file.
open the file with regular Java means, e.g. via
ZipFile zip = new ZipFile(dirPath);

Javascript: Use an object, instead of path to it for specific function

I'm using the excel-as-json module (https://github.com/stevetarver/excel-as-json) and I have set it up so that it translates my .xlsx files to .json, but I now changed it so that the .xlsx is uploaded by the user in the front-end of the app.
I would like to run the convert on the uploaded Excel file, but since I am getting the user to upload it - I don't actually have a path to it, only the file object itself. So excel-as-json tells me that it cannot find the src file [Object object]
The excel as json function call is:
convertExcel(src, dst, options, callback);
What is the best way to pass the object as src? What if I store the .xlsx in my mongoDB, could I pass in its path easier then?
Not solution, but workaround: Get user to copy in path to file and use this. Based on answer from: Getting file full path when uploading file in html in firefox
Note this workaround only works for localhost
Solution I solved my issue by using a different module - sheet.js. I get the user to upload their file using an <input> tag and then use sheet.js to parse it into json, before sending it to the server where it will be stored.

Questions about extract.autodesk.io - taking a file path instead of choosing with the file chooser

I'm trying to modify the project so I could plug in a file path or a file as a variable instead of the user choosing the model file. So I'm looking for where the actual upload happens.
In submitProject():
https://github.com/cyrillef/extract.autodesk.io/blob/master/www/js/app.js#L129
I see that it just sends (with an ajax request) an object that holds the file name and unique identifier but not the actual binary file.
In here:
https://github.com/cyrillef/extract.autodesk.io/blob/master/www/js/upload-flow.js#L34
there's r.upload(), is this the actual upload of the model?
Does it start to upload the file right as you press ok in the file chooser?
Is there a way to give it a file path to upload instead of uploading with the form and file chooser?
The author of this sample should be on Christmas vacation, I just downloaded and setup the extractor sample on my machine, with a little debug into the code, let me try to answer as much as I can.
In general, I think some of your understanding is correct, but let me explain a little more:
For a local file to be uploaded and translated, there are actually 2 steps of actual “upload”.
As you mentioned, when you press ok in the file chooser, yes, the file will be first uploaded to the "extractor" server as you noticed by some methods like r.upload(), it’s actually using a JavaScript library call “flow.js", which provides multiple simultaneous, stable, fault-tolerant and resumable/restartable file uploads via the HTML5 File API. I am not expert on this, but you can check that module about how to use it to upload a file.
By now, your file is uploaded from client to the "extractor" server, but if you want to translate the file to "svf", the file is required to be uploaded to Autodesk Server(OSS), that is done by clicking “submit my project” buton, when you click this button, as you mentioned, from client, it will call the method submitProject() in https://github.com/cyrillef/extract.autodesk.io/blob/master/www/js/app.js, this method will send a post request of “/api/projects” to the "extractor" server, if you check the code at server side https://github.com/cyrillef/extract.autodesk.io/blob/master/server/projects.js , you can see the extractor server actually upload the file to Autodesk OSS, and then triggers the translation service.
This feature (passing a URL string vs a file binary) is already implemented. You can use the uri: edit box and paste your file URL there. It supports http(s) or S3 uri with access token.
The physical upload happens in this file, whereas the SubmitProject() code sends only information as JSON. The JSON object only contains a reference to the file which was uploaded using flow.js. But would contain the uri string if you had choose that method.

How to specify filename with extension using AWS S3 presigned post?

referring to this: http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/PresignedPost.html
When having users upload directly to S3 from browser. You can specify the URL that user must post the resource to.
You can also use ${filename} to have the path based on the file name of the object in question.
However, we just want the file type rather than the full name because we want a predicable location on the resource.
for example, we want the url to be /folder/1234.png rather than /folder/mypic.png after the user uploads a file called mypic.png.
To be clear, if we specify /folder/1234 then the png extension is lost. The file type could be any image.
Since we don't know the file extension it seems like the only way to get it is through ${filename}
Is there some other type of template type variable like ${filetype}?
Any other solutions?

Categories