Send file from javascript to Python via Ajax - javascript

I'm having a problem sending a file object to python through an ajax call.
I'm using Dropzone just as my "file uploader interface" and I'm sending a call when certain button is pressed.
In python when I try to process the file, it says " 'str' object has no attribute 'seek' "
My JS Code:
...
window.$form_add_file = $("#form_add_file");
var file = dropzone.files[0];
...
var formData = $form_add_file.serializeArray();
if(file){
$modal_add_file.find($drop_add_file).removeClass("error");
var filetype = file.type.split("/")[0].toLowerCase();
var hasFile = checkFileType(filetype);
if(!hasFile) { filetype = "file" }
formData.push(
{ name: "file", value: file },
{ name: "file_type", value: filetype },
{ name: "file_name", value: file.name },
{ name: "file_size", value: file.size }
);
} else {
error = true;
$modal_add_file.find($drop_add_file).addClass("error");
return false;
}
if(!error){
$.ajax({
method: "POST",
url: host + "json.references.new",
data: formData,
cache: false,
dataType: 'json',
success: function(data){
if(data){
if(data.error){
modalMessage($modal_add_file, data.error, "ok");
} else {
refreshData(data);
}
}
},
error: function(error){
modalMessage($modal_add_file, oops_message, "ok");
}
});
}
My Python Code:
try:
file_path = os.path.join(path, file_name)
temp_file_path = file_path + '~'
file.seek(0) # error happen here
with open(temp_file_path, 'wb') as output_file:
shutil.copyfileobj(file, output_file)
os.rename(temp_file_path, file_path)
I've been searching for this on the internet and found nothing yet.
Sorry for the poor english.
Thanks in advance!

seek is a method for file objects, not strings.
I think your code snippet is missing some lines, but if file is supposed to be the file pointed to by file_path then you should first open the file with file = open(file_path, 'rb'). New file objects should start reading at the 0th position, so file.seek(0) should be unnecessary.

Related

Javascript Callback function after download Excel

I need to send mail to user after downloading .csv file. I am not sure how to set callback function after file gets downloaded.
$.ajax({
url: '#Url.Action("GetAllCustomer", "Customers")',
type: 'POST',
data: { 'customerIds': strCustomerId },
success: function (result) {
if (result == "Success") {
location.href = '#Url.Action("DownloadFile", "Customers", new { extension = "csv"})';
} else {
toastLast = toastr.error("No data found", "Generating File");
}
}
});
In above code in first call i am getting all the customers. On success callback i am calling DownloadFile method to download csv file. i have requirement to send mail after downloading file but i am not sure how will i know that file is downloaded. Or Can I achieve with some other way.
Please find my DownloadFile method of controller as below.
public ActionResult DownloadFile(string extension)
{
var dateTime = DateTime.Now.ToString("M.dd.yy");
var fileName = dateTime + " Application File." + extension;
var array = TempData["Output"] as byte[];
if (array != null)
{
var file = File(array, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
return file;
}
else
{
return new EmptyResult();
}
}
Don't use this line
location.href = '#Url.Action("DownloadFile", "Customers", new { extension = "csv"})';
Instead use a ajax request to the Action method
$.ajax({
type: "POST",
url: '#Url.Action("DownloadFile", "Customers")',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(){
//add your sccuess handlings
}
error: function(){
//handle errors
}
});

AJAX POST successful but does not do anything

I am building a desktop app using electron. I want to keep the list of all the recent files opened, for this I am using jquery ajax. here is my code
// this function is expected to add a file entry to my json file
this.add_recent_file = function(file_id, file_name, date_opened) {
// Execute the ajax command.
$.ajax({
type: 'POST',
url: './data/recent-files.json',
dataType: 'json',
data: {
id: file_id,
name: file_name,
date: date_opened
},
success: function() {
console.log("Success");
}
});
}
and here is my sample json file:
[
{
"id" : "1",
"name": "File.json",
"date": "24-feb-2018"
}
]
the problem is that console says 'Success' but no changes in json file. Reloading the page didn't change anything.
You can use node.js filesystem to write to the json file. check out the following code.
var fs = require('fs');
var $ = require('jquery');
this.add_recent_file = function (object) {
$.ajax({
type: 'GET',
url: './data/recent-files.json',
dataType: 'json',
success: function (files) {
// append the entry to the array.
files[files.length] = object;
// Get JSON string representation of the array.
var str = JSON.stringify(files);
// Now write it to the json file.
fs.writeFileSync(recent_file_url, str);
},
error: function () {
alert('Error updating json file.');
}
});
}
As stated by #Gerrit Luimstra, you need a backend, If you're using PHP, you might use something like this:
data/update.php
<?php
$id = $_POST['id'];
$name = $_POST['name'];
$dateX = $_POST['date'];
//update database code here
Right now you are using AJAX to POST data to a JSON file and hope that this will update the file. This however is not the case.
What you can do instead is use Electron's file system to write changes to the JSON file.
In this case, your function would become something like:
this.add_recent_file = function(file_id, file_name, date_opened) {
// Create the JSON content
var data = {
id: file_id,
name: file_name,
date: date_opened
};
// If you want to prettify the JSON content
data = JSON.stringify(data, null, 2);
// Write it to the file
fs.writeFileSync('../path/to/recent-files.json', data);
}
This however requires you to use the node filesystem package.

How to send file to apps script using plain POST request?

im doing simple file uploader to apps script but I faced some troubles with uploading data as file. Lets say I have this code:
function doPost(e) {
console.log(e)
}
and I do a simple POST request in node.js
let formData = {
theFile: {
value: fs.createReadStream('myawersome.file'),
options: {
filename: 'myawersome.file',
contentType: 'some/mimetype'
}
}
}
let params = {
url: 'my-script-url',
followAllRedirects: true,
formData: formData
}
request.post(params)
So, whats the problem. I dont see any files in my e param in doPost. That is my console.log output
{"queryString":"","parameter":{},"contextPath":"","parameters":{},"contentLength":9483}
I can see that I have some data in request, but everything is empty. e.parameters.theFile and e.theFile are undefined. Where is my file?
the call of createReadStream just create the stream but don't read the file
to read the file, try that :
var rs = fs.createReadStream('myawersome.file');
rs.on("data", function (chunk) {
var content = chunk.toString();
var formData = {
theFile: {
value: content,
options: {
filename: 'myawersome.file',
contentType: 'some/mimetype'
}
}
}
var params = {
url: 'my-script-url',
followAllRedirects: true,
formData: formData
}
request.post(params)
});
rs.resume(); // this launches the read

Trying to POST multipart/form-data by javascript to web api

Here i have a form in which i have a input type file to upload my file when the upload button is click i need to post the multipart/form-data to web api
where i upload the file to Minio Server.I have pasted the javascript and web api i use below.
When i press upload button after i get 500 (Internal Server Error).Help me with suggestions.
$("#upload").click(function () {
var file = new FormData($('#uploadform')[0]);
file.append('tax_file', $('input[type=file]')[0].files[0]);
$.ajax({
type: "POST",
url: 'http://localhost:53094/api/values',
data: file,
//use contentType, processData for sure.
contentType: "multipart/form-data",
processData: false,
beforeSend: function () {},
success: function (msg) {
$(".modal .ajax_data").html("<pre>" + msg +
"</pre>");
$('#close').hide();
},
error: function () {
$(".modal .ajax_data").html(
"<pre>Sorry! Couldn't process your request.</pre>"
);
$('#done').hide();
}
});
});
[HttpPost]
public string Post(IFormFile file)
{
try
{
var stream = file.OpenReadStream();
var name = file.FileName;
minio.PutObjectAsync("student-maarklist", "sample.jpeg", stream, file.Length);
return "Success";
}
catch (Exception ex)
{
return ex.Message;
}
}
I think you need not mention localhost just the path to the file will do. or replace it with IP of the localhost.
Sorry i have dont a mistake the name i appended in javascript is not save as the name i gave in web api.
I changed,
file.append('tax_file', $('input[type=file]')[0].files[0]);
To
file.append('file', $('input[type=file]')[0].files[0]);
and it worked .

$.ajax inside BeforeUpload Event - Plupload

This app is an image uploading tool that uploads images directly from client browser to Amazon S3 using Plupload. So far, everything is working good except this issue.
I've this code forBeforeUpload event.
init: {
BeforeUpload: function (up, file) {
$.ajax({
url: '/ServerTime.ashx',
dataType: 'text',
data: { format: "yyyy-MM-dd_HH.mm.ss.fffffff" },
type: 'POST',
cache: false
}).done(function (data) {
console.log("Before setting ImageName: " + data);
imageName = data + ".JPG";
console.log("After setting ImageName: " + imageName);
up.settings.multipart_params = {
'key': key,
'Filename': imageName,
'acl': 'public-read',
'success_action_status': '201',
'AWSAccessKeyId': accessKey,
'policy': policyDocument,
'signature': policySignature
};
});
}
}
However, I've this error when try to upload a file:
HTTP Error. Upload URL might be wrong or doesn't exist.
On Console, it is printing the expected result as follows:
Before setting ImageName: 2014-04-04_13.33.45.1155072
After setting ImageName: 2014-04-04_13.33.45.1155072.JPG
I guess there is something wrong maybe because I'm using AJAX to get time from server. On the other hand, trying the following code is working without any issue.
init: {
BeforeUpload: function (up, file) {
up.settings.multipart_params = {
'key': "This_Is_Folder_Name/This_Is_File_Name.JPG",
'Filename': "This_Is_File_Name.JPG",
'acl': 'public-read',
'success_action_status': '201',
'AWSAccessKeyId': accessKey,
'policy': policyDocument,
'signature': policySignature
};
}
}
Notice that, this time I'm using static names for Filename and key, and there is no AJAX either
I really need help with this issue. Please suggest me. What I'm doing wrong with using AJAX to get server time and use it as file name?
Thanks.
You might be able to override some of their code by doing the following:
init: {
BeforeUpload: function (up, file) {
$.ajax({
url: '/ServerTime.ashx',
dataType: 'text',
data: { format: "yyyy-MM-dd_HH.mm.ss.fffffff" },
type: 'POST',
cache: false
}).done(function (data) {
console.log("Before setting ImageName: " + data);
imageName = data + ".JPG";
console.log("After setting ImageName: " + imageName);
up.settings.multipart_params = {
'key': key,
'Filename': imageName,
'acl': 'public-read',
'success_action_status': '201',
'AWSAccessKeyId': accessKey,
'policy': policyDocument,
'signature': policySignature
};
file.status = plupload.UPLOADING;
up.trigger("UploadFile", file);
});
return false;
}
}
This would cancel their trigger, so you would have to trigger it yourself. Please note, I have not tested this.
EDIT: I'm not sure if up and file are out of scope though...
If you look in the Plupload source code you'll see this:
// Private methods
function uploadNext() {
var file, count = 0, i;
if (this.state == plupload.STARTED) {
// Find first QUEUED file
for (i = 0; i < files.length; i++) {
if (!file && files[i].status == plupload.QUEUED) {
file = files[i];
if (this.trigger("BeforeUpload", file)) {
file.status = plupload.UPLOADING;
this.trigger("UploadFile", file);
}
} else {
count++;
}
}
// All files are DONE or FAILED
if (count == files.length) {
if (this.state !== plupload.STOPPED) {
this.state = plupload.STOPPED;
this.trigger("StateChanged");
}
this.trigger("UploadComplete", files);
}
}
}
The line that says if (this.trigger("BeforeUpload", file)) { will determine whether the return of the trigger call is truthy or falsy. If truthy, it will next trigger "UploadFile". What that means is that the uploading of the file does not wait for asynchronous code to execute in your BeforeUpload function. As soon as that function returns, the upload can begin. Any async ajax call you make inside your BeforeUpload function will resolve after "UploadFile" is triggered.

Categories

Resources