Store a file using Crud

33 views
Skip to first unread message

Manu Grandío

unread,
Sep 4, 2014, 5:20:57 AM9/4/14
to web...@googlegroups.com
Hi!

I want to allow users to store files in my web application by both these methods:
  • By uploading the file from their hard drives
  • By providing a URL where the file is located. Then, there's no upload and the controller downloads the file and inserts it in the database.

I know how to accomplish that with a FORM and a db.table.insert, however I would like to use Crud if it's possible. Here is a simplified version (without any error checking) of what I've tried:

# In models/db_documents.py
db
.define_table('documents',
   
Field('name'),
   
Field('description'),
   
Field('url'),
   
Field('file_', 'upload'))

# In controllers/documents.py
import urllib2
from gluon.tools import Crud

def upload_document():
   
"""
    Let users store files either by:
      - uploading the file, or
      - providing a URL where the file is located
    """

   
def download_document(form):
       
"""Download the file if the user provided a URL, and store it in
        form.vars.file_
        """

       
if form.vars.url != '':
            form
.vars.file_ = urllib2.urlopen(form.vars.url) # Doesn't work

    crud
= Crud(db)
    crud
.settings.create_onvalidation.documents.append(download_document)
    form
= crud.create(db.documents, next='document_uploaded')
   
return {'form': form}


It works well in the first case, 'upload a file', but I don't know how to address the second case, 'provide a URL'. Specifically I don't know how to insert the file in the database after having downloaded it with urllib2. In the code you can see that I tried with:

form.vars.file_ = urllib2.urlopen(form.vars.url)

and it doesn't work. When the file is uploaded by the user (instead of providing a URL) I've seen that form.vars.file_ is an instance of FieldStorage. Probably that's why assigning a file-like object (the one returned by urllib2.urlopen) directly to form.vars.file_ doesn't work. Also I haven't found FieldStorage in the web2py documentation so probably it's an internal class and cannot create an instance myself. That makes me think maybe I cannot solve my problem with Crud.

Surprisingly, assigning a string to form.vars.file_ works in some way. I mean, doing:

form.vars.file_ = urllib2.urlopen(form.vars.url).read() # Assign a string

instead of:

form.vars.file_ = urllib2.urlopen(form.vars.url) # Assign a file-like object

web2py creates a text file named 'file.txt' and stores the content of the string in it. If there is a way to change the default 'file.txt' name I think I will be fine too. I want to preserve the original name and extension.

Cheers,

Manu

Reply all
Reply to author
Forward
0 new messages