File not uploading to dropbox via python script - python

This problem is just a more in depth explanation of the other problem.
I put the code on github because it's quite a fair bit. I'm sorry for the inconvenience
https://github.com/lonehangman/mccdropdav/blob/master/views.py
Line 100 onwards is where the problems start. For the past week I've tried and failed to upload a file from pages (on iPad) to dropbox through a webdav set up on Google App Engine (GAE).
I can view the contents of my dropbox but when I download or upload from my computer or iPad it always gives an error. I checked the logs and saw that there was a key error for line 110, so I tried to fix this by printing meta_entry, which I then realised was a non existent resource.
(Hence the # make a fake Resource to ease our exporting. On line 106).
This problem left me befuddled for days, but then my friend told me to remove line 152 root.append(self.export_meta_entry(metadata,href=self.request.path)) # first response's href contains exactly what you asked for (relative path)
Doing this got rid of the key error but still wouldn't let me upload to dropbox. The iPad tells me it's uploading but I check my dropbox but no new files are to be seen. Nor can I download files.
The logs don't seem to be picking it up.
Can anyone please explain and try help (If you're not going to help don't bother writing stuff like 'go somewhere else' or 'learn python noob'.)
If there is any more information needed just ask.
I'm quite tired at the time of writing this so it does seemed a bit rushed.

Not looking your entire app, but only your put method (calling Dropbox put_file)
def put(self):
path = '/' + self.request_path
self.client.put_file(ROOT, os.path.dirname(path), self.request.body_file, file_name=os.path.basename(path))
self.response.set_status(201,'Created')
Dropbox API tutorial example of put_file
f = open('working-draft.txt')
response = client.put_file('/magnum-opus.txt', f)
print "uploaded:", response
as well as put_file documentation say the first argument of put_file is the complete path of the file in dropbox tree (including the name of the file), and the second argument is a file-like object.
So something like that may be better
self.client.put_file(path, self.request.body_file)
As you can see, you may look at the return value of put_file to get further information on what happened in your put_filecall. You may adjust your response code according to the response from Dropbox.

Related

google-datastore obtaining the correct blob item key for download

In the google appengine datastore, there is a BlobKey (labled as csv). The key is in the following format: encoded_gs_file:we1o5o7klkllfekomvcndhs345uh5pl31l. I would like to provide a download button to save this information.
The web app is being run using dev_appserver.py and uses python 2.7 (Django) as the backend. Currently, a button exists, but when clicking on it, it returns a 404 error. The download link that the button provides is:
https://localhost:8080/data?key=encoded_gs_file:dwndjndwamwljioihkm
The interesting thing is that, when i go to localhost:8000/datastore and then navigate to the Blobstore Viewer, i can navigate to Entity Kind: GsFileInfo, and there is a key generated. The problem is that it gives a 404.
The other blob item next to is a png and if i use the key for that png, i get a download. What is wrong with the key, how can i get the write key from the datastore.
I'm still scratching my head in regards to your issue, but something that seems suspect is that size is None and finalized is False for your CSV file.
I looked back at your previous question (google cloud: downloading as an CSV) and noticed that you're not calling .close() on your GCS/blobstore file after you finish writing to it.
Maybe that will fix this.

Building a web application that can work with local files

I'd like to build an application (local, not online) by using front-end web technology for the UI, the application simply displays PDFs and has a few text fields for the user to fill in with regards to the current PDF they're viewing, the user can then export their notes and a file path to the document in CSV file format.
comment about file, some more notes, C:\somefolder\doc1.pdf
comment about file, some more notes, C:\somefolder\doc2.pdf
My first issue, JavaScript can't access the local file system, so I used a file upload form which worked except the filepaths were shown as blob filepaths and not the actual system file path. Other than that my "application" worked as intended.
I went and learned Flask in hopes of using python for the back end, which works great except when I pass in the file path to the pdf C:\SomeFolder\doc1.pdf inside the 'src' attribute for an Chrome says it can't access local files. SO I'm back to sqaure one!
How can I go about building this application with local file access?
If you need to access the local files, you can create an endpoint in flask that launches a file dialog GUI. This only works because you application is hosted locally. You can use either tkinter or the native windows API using win32ui.
Assuming you are using the standard Flask format:
from app import app
#app.route('/file_select', methods=['GET', 'POST'])
def file_select():
from tkinter import Tk
from tkinter.filedialog import askopenfilename
root = Tk()
root.withdraw()
# ensure the file dialog pops to the top window
root.wm_attributes('-topmost', 1)
fname = askopenfilename(parent=root)
return jsonify({'filepath': fname})
or using the win32ui API
#app.route('/file_select', methods=['GET', 'POST'])
def file_select():
import win32ui
winobj = win32ui.CreateFileDialog(1, ".pdf", "", 0,
"PDF Files (*.pdf)|*.pdf|All Files (*.*)|*.*|")
winobj.DoModal()
return jsonify({'filepath': winobj.GetPathName()})
Now just add a button that points to the /file_select route and you will open a file dialog via the python local server and return the selected file.
Assuming you are accessing the page via http://localhost:8080/page or something like that, you should serve your content via that approach. Effectively, rather than serving the files as paths on the local file system, you would create an application route and associate it with a handler than retrieves the appropriate PDF from the local filesystem, and then sends back a response containing Content-Type: application/pdf in the HTTP response headers and the bytes of the PDF file in the response body.
To avoid duplicating someone else's solution for the approach described about, I would recommend taking a look at this answer for "Flask handling a PDF as its own page".
Because you are technically sending the response back from localhost -- or whatever name you are serving it with -- rather than trying to load a local file directly from the client's web-page, Chrome shouldn't throw any complaints.
Of course, it's worth noting that best practices should be taken when determining the file to load, if this were going to be anything more than a learning project. In any legitimate system that did this kind of thing, it would be necessary to perform checks on the requested files to ensure a malicious user does not abuse the application to leak files from the local filesystem, beyond those files which are intended to be served. (To that end, you typically might have the src element contain a parameter that is set to the hash/unique ID for the file which is then mapped via some database to the correct path of the file. Alternatively, you might use a param in the src that contains the name of the file without the full path, and then check that the user-provided value for that parameter in the request does not contain any characters outside of a charset like [a-zA-Z0-9_-].) Ultimately, it sounds like this particular warning doesn't apply to your case, but still providing it in case anyone else reads this in the future.
I think mht is exactly what you want. mht is a file extension recongnized by IE. Internally it is an HTML file. IE (only) treats a mht file with the same security restrictions that a exe might have. You could access the file system, delete a file, display a file etc.. It is everything that html/javascript security was trying to prevent. Now that IE has changed significantly I don't know what the support for this is nowadays. I couldn't find a reference page to give you a link, but it is simple enough - just save a html file with an mht extension

Send PDF file from Django website to LogicalDOC

I'm developing my Django website since about 2 months and I begin to get a good global result with my own functions.
But, now I have to start a very hard part (to my mind) and I need some advices, ideas before to do that.
My Django website creates some PDF files from HTML templates with Django variables. Up to now, I'm saving PDF files directly on my Desktop (in a specific folder) but it's completely unsecured.
So, I installed another web application which is named LogicalDoc in order to save PDF file directly on this application. PDF files are created and sent to LogicalDoc.
LogicalDoc owns 2 API : SOAP and REST (http://wiki.logicaldoc.com/rest/#/) and I know that Django could communicate with REST method.
I'm reading this part of Django documentation too in order to understand How I can process : https://docs.djangoproject.com/en/dev/topics/http/file-uploads/
I made a scheme in order to understand what I'm exposing :
Then, I write a script which makes some things :
When the PDF file is created, I create a folder inside LogicalDoc which takes for example the following name : lastname_firstname_birthday
Two possibilities : If the folder exists,I don't create a new folder, else I create it.
Once it's done, I send the PDF file directly inside the folder by comparing PDF name with folder name to do that
I have some questions about this process :
Firstly, is it possible to make this kind of things ?
Is it hard to do that ?
What kind of advices could you give me ?
Thank you so much !
PS : If you need some part of my script, mainly PDF creating part, I can post it just after my question ;)
An idea is pretty simple, however it always requires some practice.
I strongly advice you to use REST api and forget about SOAP as the only thing it can bring to you - is 'pain' :)
If we check documentation, document/create it gives next information.
Endpoint we have to communicate with.
[protocol]://[server]:[port]/document/create
HTTP method to use - POST
List of parameters to provide with your request: body,
document, content
Even more, you can test API by clicking on "Try it out" button and check requests in "Network" tab of your browser (if you open Developer Tools)
I am not sure what kind of metadata do you have to provide in 'document' parameter but what I know you can easy get an idea of what should be done by testing it and putting XML or JSON data into 'document' parameter.
Content is an array of bytes transferred to the server (which would be your file).
To sum up, a request to 'document/create' uri will be simple
body = { 'headers': {},'object': {},}
document = "<note>data</note>"
content=open('report.xls', 'rb') #r - reading, b - binary
r = requests.post('http://logicaldoc/document/create', body=body, document=document, content=content)
Please keep in mind that file transferring requests take time and sometimes you may get timeout exception. Your code will stop and will be waiting for response, so it may be a good idea to get some practice with asyncio or celery. Just keep in mind those kind of possible issues.

pydrive library for google drive is not downloading file in requested format using requests

I have a simple script set up for getting a file off my google drive account and updating it. I have no problems authenticating and getting access to the drive. The file is in the form of a google spreadsheet on the drive. Thus, when I have the pydrive file object, I get the URL of the file in csv format via google_file['exportLinks']['text/csv']. This has worked in the past, however today I tried this same method for a new file, and instead of getting the csv format of the data, I keep getting HTML. In addition, if I copy and paste the link from my google_file['exportLink']['text/csv'] and put it into a browser, the browser will begin to download the file in csv format as requested. I really have no idea what is going on, especially since this has worked in the past.
Here is basically what my code does:
drive = GoogleDrive(gauth)
drivefiles = drive.ListFile().GetList()
form_file = None
for f in drivefiles:
if f['title'] == formFileName:
form_file = f
break
output = requests.get(form_file['exportLinks']['text/csv'])
print output.text #this ends up being HTML, not text/csv
Has anyone else out there seen this problem before? Should I just try to delete and re-add the google spreadsheet file on the drive?
EDIT: UPDATE
So, after changing permissions on the file on google drive from accessible only to people who the file has been shared with to accessible/editable by all, I was able to access and download the file. Does the clients_secret.json file allow a particular google drive user to securely authorize or is that a general key that allows anyone with it to access the Google API in that particular session? Are there any special data that has to be send over the http request if the file has only been shared with a limited set of email addresses?
I also found handling idiosyncrasies of google drive api little bit tricky. I have written a wrapper around google drive api, which makes it relatively easy to deal with it. See if it helps:-
Google Drive Client
Sample code:-
file_id = 'abc'
file_access_token = '34244324324'
scope = 'https://www.googleapis.com/auth/drive.readonly'
path_to_private_key_file = '#'
service_account_name = '284765467291-0qnqb1do03dlaj0crl88srh4pbhocj35#developer.gserviceaccount.com'
drive_client = GoogleDriveClient(
scope = scope,
private_key = open(path_to_private_key_file).read(),
service_account_name = service_account_name)
file = drive_client.get_drive_file(file_id, file_access_token)
Ofcourse, you need to change access variables according to your profile.
In case anyone else has been having problems with this, changing the settings on the file in the drive to "everyone can view" solved the problem - seems that there were some permission restrictions. Would suggest that you look into changing the permissions on the file to the least restrictive setting (as possible) while debugging.

With Objective-C SDK, Google Drive returns 503 Error when uploading a file with non-ASCII title

Since 27th June, when our app tries to upload a file to Google Drive, the server have started returning 503 error (below) when the title of the file is not written with ASCII ones.
"Error Domain=com.google.HTTPStatus Code=503 "The operation couldn’t be completed. (com.google.HTTPStatus error 503.)""
We looked into the problem and have found if the title is written in ascii, the error won't occur. We also tested filename like "日本語.txt" "中文简体繁体.txt" "한국어.txt" "русский язык.txt" and all of them ends with the error above. Of course, if we change the filename to an ascii text, the error vanishes.
I use google-api-objectivec-client library for Google Drive access and what I do is nothing strange - just setting the title property of a GTLDriveFile that is used on upload.
GTLDriveFile *file = [GTLDriveFile object];
file.title = title;
Our code had been working fine for months.
Is there any possible mistake on my uploading file to the server? If not, is there any workaround on the problem? Any help is welcome. Thanks.
P.S.
I also have tested the problem with "DriveSample" app included in the library. The same problem occurred by using "Upload" feature of the app.
30th June (added)
The filename problem seems lies only on "Client Library for iOS".
I tested "Client Library for Python" and found it works fine with non-ascii title.
In case "DriveSample" app I used for testing is not well maintained, I also downloaded another sample from Google called "DrEdit" for verify. Unfortunately, "DrEdit" also couldn't handle the non-ascii title on upload.
Then, I checked the URL each libraries accesses for upload.
Python:
https://www.googleapis.com/upload/drive/v2/files?uploadType=resumable&alt=json
Objective-C:
https://www.googleapis.com/upload/rpc?uploadType=resumable&prettyPrint=false
Python uses exactly the same URL as the Google Drive API Documentation.
However, Objective-C library uses different URL which is not documented.
Couldn't it be possible the URL Objective-C library accesses causes the non-ascii title conversion problem if the library has no problem? Maybe inter-server communication failure or something?
Still, any help is welcome. Thanks!
The problem seems fixed on the server side on 3 July 21:30 PDT.
Thank you for the work, Google.

Categories