If you benefit from web2py hope you feel encouraged to pay it forward by contributing back to society in whatever form you choose!


  • 0
    cfhowes  11 years ago
    Thanks for the great tutorial. I made some changes when i implemented it to support a table that has more data than just the uploaded image, and i also figured out how to get the blob_info w/o creating a new dummy request. I also made it handle the deletion requests, and update requests (assuming that the same blob is only referenced in 1 record) my gae.py (there are different names for the tables and fields here, i was hoping to make it generic but have not yet done that)
    
    from google.appengine.ext import blobstore
    from google.appengine.ext import webapp
    from google.appengine.ext.webapp import blobstore_handlers
    from google.appengine.ext.webapp.util import run_wsgi_app
    import uuid
    import logging
    
    #web2py controller, handle gae blobstore upload
    def upload():
        logging.info("in upload")
        logging.info(request.args)
        logging.info(request.vars)
        #@TOD: make the table name and field parameters to pass in
        table_name = 'artwork'
    
        form = SQLFORM(db[table_name])
        if request.args and request.vars.id:
            form = SQLFORM(db[table_name], request.vars.id)
    
        if form.accepts(request.vars, session):
            logging.info("form accepted")
            row = db(db[table_name].id == form.vars.id).select().first()
            if request.vars.preview_image__delete == 'on' or \
                (form.vars.preview_image and row.blob_key):
                #remove from blobstore
                key = row.blob_key
                blobstore.delete(key)
                #remove reference here
                row.update_record(blob_key=None, preview_image=None)
            if form.vars.preview_image:
                logging.info("new image")
                #@TODO: delete old image if replacing.
                blob_info = blobstore.parse_blob_info(form.vars.preview_image)
                row.update_record(preview_image = \
                    table_name+".preview_image."+str(uuid.uuid4()).replace('-','')+".jpg",
                    blob_key = blob_info.key())
            crud.archive(form)
        else:
            logging.info("form not accepted")
            logging.info(form.errors)
            session.flash=BEAUTIFY(form.errors)
            #there was an error, let's delete the newly uploaded image
            if request.vars.preview_image != None:
                logging.info("deleting new image")
                blob_info = blobstore.parse_blob_info(request.vars.preview_image)
                blobstore.delete(blob_info.key())
    
    
        logging.info("all done")
        #Raise the HTTP exception so that the response content stays empty.  calling
        #redirect puts content in the body which fails the blob upload
        raise HTTP(303,
                   Location=URL(r=request,c='form',f='artwork',args=request.vars.id or []))
    
    
    def download():
    
        #handle non-gae download
        if not request.env.web2py_runtime_gae or not request.args[0]:
            return response.download(request,db)
    
        #handle gae download
        my_uploads=db(db.artwork.preview_image==request.args[0]).select()[0]
        if not my_uploads.blob_key:
            return None
        blob_info = blobstore.get(my_uploads.blob_key)
    
        response.headers['X-AppEngine-BlobKey'] = my_uploads.blob_key;
        response.headers['Content-Type'] = blob_info.content_type;
        response.headers['Content-Disposition'] = "attachment; filename=%s" % blob_info.filename
        return response.body.getvalue()
    
    

Commented on:

Describes how to use the Google blobstore API, allowing files up to 50MB to be used when a web2py project is hosted on Google App Engine

Hosting graciously provided by:
Python Anywhere