How to use Python/CGI for file uploading - javascript

I'm trying to make a file uploader page that will prompt the user for a file and will upload while displaying progress.
At the moment I've managed to make a simple HTML page that can calls my python script. The python script will then get the file and upload in 1000 byte chunks.
I have two main problem (mainly due to be completely new to this):
1) I can't get the file size to calculate percentage
2) I don't know how to communicate between the server side python and whatever is in the page to update the progress status;presumably javascript.
Am I going about everything the wrong way? Or is there a solution to my woes?
Here is my python code:
#!/usr/local/bin/python2.5
import cgi, os
import cgitb; cgitb.enable()
try:
import msvcrt
msvcrt.setmode (0, os.O_BINARY)
msvcrt.setmode (1, os.O_BINARY)
except ImportError:
pass
form = cgi.FieldStorage()
upload = form['file']
if upload.filename:
name = os.path.basename(upload.filename)
out = open('/home/oetzi/webapps/py/' + name, 'wb', 1000)
message = "The file '" + name + "' was uploaded successfully"
while True:
packet = upload.file.read(1000)
if not packet:
break
out.write(packet)
out.close()
else:
message = "Derp... could you try that again please?"
print """\
Content-Type: text/html\n
<html><body>
<p>%s</p>
</body></html>
""" % (message,)

This is more complex than it seems, given how file uploading works in the HTTP protocol. Most web servers will give control to the CGI script only when the uploaded file has been completely transferred, so there's no way to give feedback in the meanwhile.
There are some Python libraries that attempt to tackle this issue, though. For example: gp.fileupload (works with WSGI, not CGI).
The trick is to provide a way to query the upload progress via AJAX while still transferring the uploaded file. This is of no use if the web server (for example, Apache or nginx) is not configured to support the upload progress feature because you will probably see a 0% to 100% jump in the progress bar.
I suggest you try Plupload, which works on the client-side and is much simpler.

Related

Automatic file downloader

I want to download files from a web page that offers public downloads.
I have little experience with the world of web pages, so initially I wrote a simple script using selenium that solves the problem, however I find this way of getting the data too twisted. Therefore, I have tried to download the file via POST requests, investigating a little the "Network" panel of tools I managed to find the request that apparently orders the download.
The button that appears surrounded in the image launches the three requests that appear on the right, except the first time the file is downloaded, one more request appears (this can be seen above the highlighted requests).
However, the response of this request, far from being the content that would allow me to write the desired file, is more like a fragment of html code that corresponds to the content displayed when in the network panel I double click on "downloadDir":
What could I be missing? Does anyone know how to solve the problem or it is not possible by this way?
You should use requests package instead of executing curl or other processes:
import requests
response = requests.post('https://localhost:4000/bananas/12345.png', data = '[ 1, 2, 3, 4 ]')
data = response.content
data contains the downloaded content after that, which you can store to disk for instance:
with open(path, 'wb') as s:
s.write(data)

How to download zip file from server side to client side (django to react)

On my django server side, I have a file that downloads some files from s3 and then zips them together. I then want to send that zip file to the client side and download it on client side. However, when ever I try to open the zip file on the client side I get a An error occurred while loading the archive
I am running on Ubuntu 14.04 with a django backend and a react frontend. I tried passing the file as a tar file, but that didn't work either. I have also tried many different ways of passing the zip file to the HTResponse, but I always get the same error. Right now to try to make it work, I am just trying to download a zip file I have downloaded on my local computer.
I have tried a bunch of different content_types from application/zip, to octet/stream and force download.
django backend
zip_path = '/home/konstantin/Downloads/sup.zip'
content_path = mime.guess_type(zip_path)
with open(zip_path, 'rb') as zip_file:
response = HttpResponse(zip_file, content_type='application/zip')
response['Content-Length'] = str(os.stat(zip_path).st_size)
response['Content-Disposition'] = 'attachment; filename={}'.format('willthiswork.zip')
return response
react front end (we have a program that changes python to js). The response of the ajax call is passed directly into this method.
def download(self,url):
data = __new__(Blob([url], {"type": "octet/stream"}))
csvURL = window.URL.createObjectURL(data)
tempLink = document.createElement('a')
tempLink.href = csvURL
tempLink.download = 'willthiswork.zip'
tempLink.click()
Expected result: Zip file downloads on client side and is openable
Actual result: Zip file downloads, but cannot be opened.
so I finally figure it out. For some reason all the standard solutions of just passing an a regular httpresponse did not work for me, but this answer worked for me. Why? Idk. but it did.
https://stackoverflow.com/a/29939024/11312013

Javascript: Save uploaded file

I would like to save uploaded file using javascript, in my linux server. The code I wrote is:
if (uploadInput.files.length == 0) {
console.log("No file is uploaded. ");
} else {
console.log("File uploaded.");
var file = uploadInput.files[0];
}
Now I would like to save that file as "files/upload.csv". Can anyone please advise, how can I do it?
Thanks in advance
What I'm going to do is walk you through the logic, instead of providing code. There is just not enough information here on what you want to do to provide actual code and the sample you provided is a very small part of what the actual solution would need to include.
I'm assuming the code you wrote above is meant to run on a website visitor's browser (client-side). Client-side code can't save to a server. What it can do, is send the file contents to the server. But then you'd need something on the server side to process that file contents and actually save it to the server-side files directory.
One method to send the file contents from the client to the server is to use AJAX - you can do this with native javascript, but I would recommend looking into a library such as Jquery, which makes it a lot easier. See http://api.jquery.com/jquery.ajax/ This AJAX code will need a communication point on the server to send the file contents to. From your profile it seems you're familiar with PHP. You could make a php file on the server (say receivefilecontents.php) that takes in input from that client-side AJAX call, and then saves it to a server directory - you could also do this in Python, Java or a number of other languages.

Is it possible to generate image using HTML5 canvas on a server side?

I'd like to ask if is possible to generate canvas image on a server side.
I wonder if someone has already experiences with it.
Why do I need something like that?
I'm planning to create client side canvas, which will contain some image + shapes (based on some data) and user must be able to e.g. draw new shapes, download all together as PNG, delete shapes... all this should be possible.
BUT, there should be also option to pick images from a list (imagine data grid view + checkboxes) on client side and download all selected images together as single ZIP file.
Requirement is, that images should be rendered the same way as on client side canvas (image + shapes). So I would like to take JavaScript code that generates canvas on client side and use it also on server side. Please note, that whole application will run on ASP.NET (IIS).
What came first on my mind as a first option is:
request from client to server (list of IDs, + some properties like a ZIP file name)
ASP.NET server perform a request(s) to NodeJS for images (+ parameters)
NodeJS will generate canvas and return an image for each request
ASP.NET server will pack all images returned from NodeJS and return them to a client
Question 1: Will this work?
Question 2: Can I somehow get rid of NodeJS? Current web application is build on ASP.NET MVC which runs on IIS and I don't want to mess server with another web server.
Question 3: Maybe I could be able to get rid of NodeJS by creating hidden canvas elements (will be rendered?) on a client, send their images from client to server by ajax and then let client download them as ZIP. (network bandwith is NOT a problem, it will be on a fast local network)
Thanks for sharing your experiences!
UPDATE
Another possibility I found is openning page in IE using powershell. Here's a working sample I have (but I'm not sure if this is the best solution).
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate("http://localhost:8080/img/id") # or whatever page that contains canvas
$ie.visible=$false
while($ie.Busy) {Start-Sleep -m 500}
$doc=$ie.document
while(!$doc)
{
Write-Host -NoNewLine ".";
Start-Sleep -m 50
$doc=$ie.document
}
$canvas = $doc.getElementByID("canvasID")
Start-Sleep -m 1000 # sometimes need additional time to render canvas background image
$img = $canvas.toDataURL("image/png", 1)
$base64data = $img.Split("{,}")[1]
$bytes = [System.Convert]::FromBase64String($base64data)
[io.file]::WriteAllBytes('c:\temp\CanvasImage.png', $bytes)

save as PDF: recommend a server solution to receive raw data from client and send back PDF to client?

My project requires me to add a "SaveAs PDF" feature. I was looking for a pure JavaScript solution which does this just in client end, however, was told that it's not implementable, at least for now.
jsPDF currently is still a limited version, not support graph and others. So now I am looking for a stable open-srouce free solution to set up a server web service, that receive data from client-end and send back the produced PDF file or a link for user to save to their disk.
The data from client is determined by client user, which means, not the whole page. User can choose to save a map, a table, or all of them into PDF file.
Any recommendations?
PS: in Windows environment
You might check out the ReportLab Toolkit - it includes an Open Source Python library for creating PDFs. (You didn't specify what server-side language you wanted, but Python is pretty widely supported.)
If you need something that can be coded in Javascript, one option might be PhantomJS. This tool allows you to run a headless Webkit browser from the command line, and among other things it can render and save webpages as PDFs. Slippy uses this approach, so you might be able to get example code from that project. Scripting the PDF creation would probably be much faster in PhantomJS than in Python, but it's likely to be much slower (it has to fire up a Webkit instance) and server installation might be complicated.
I've create this function in javascript which send on iframe to the server:
function download(url, datas){
if(url && datas){
var inputs = '', value,
iframe = '<iframe name="iframeDownload" id="iframeDownload" width=0 height=0></iframe>';
$(iframe).appendTo('body');
datas.forEach(function(data){
name = encodeURI(data.get('name'));
value = encodeURI(data.get('value'));
inputs+='<input name="'+name+'" value="'+value+'"/>';
});
$('<form action="'+url+'" method="post" target="iframeDownload">'+inputs+'</form>').appendTo('body').submit().remove(); // .appendTo and remove() are needed for firefox
$(iframe).remove();
};
};
I'm encoding the input name and value to be able to send data.
On my server, I'm using php, so to decode this, you need: rawurldecode. If you define the name of the inputs as "fileName" and "file" you can write this:
$fileName = rawurldecode($_POST['fileName']);
$file = rawurldecode($_POST['file']);
After than, to force the download, you need to send the corrects header. I'm using this function:
function download($filename, $file) {
header('Content-disposition: attachment; filename="'.$filename.'"');
header('Content-Type: application/force-download');
header('Content-Length: '. filesize($file));
readfile($file);
}
If you don't need to send the file from javascript because it's created on the server side, just add the path of your file to the download function.
If you're using PHP, You can use fpdf to generate the pdf.

Categories

Resources