my blobstore_image model:

        db.define_table('blobstore_image',
          db.version_info,
          Field('blob_key', 'upload', notnull=True, 
requires=IS_LENGTH(1048576),
                represent=lambda image : A('download', _href=URL(
                    r=request, c='gae_blobstore', f='download', 
args=[image])),
                label="Image"),
          Field('image_url', length=500),
          Field('name', length=128,
                requires=IS_NOT_IN_DB(db, 'blobstore_image.name')),
          Field('type', length=128, requires=IS_IN_SET(['i_classify',
                                                        'my_images',
                                                        'by_type'],
                                                       zero=None)),
          migrate=True)


my upload controller:

def upload_image():
  """
  This is the integration of the GAE blobstore with the image upload process

  @TODO: figure out how to test this.  image upload is going to be kinda
   difficult to spoof
  """
  #@TODO: how do we deal with deleting an image?
  logging.info(repr(request.post_vars))

  fields=['name',
          'type',
          'blob_key']

  form = SQLFORM(db.blobstore_image, fields=fields,
                 formstyle='divs')
  if request.args and request.args[0]:
    form = SQLFORM(db.blobstore_image, request.args[0], fields=fields,
                   upload=URL(r=request, c='gae_blobstore', f='preview'),
                 formstyle='divs')

  if request.env.web2py_runtime_gae:
    from google.appengine.ext import blobstore
    from google.appengine.api.images import get_serving_url
    import uuid
    #get the blob_info.  NOTE this MUST be done before any other operations 
on
    # the request vars.  otherwise something modifies them (perhaps the form
    # validators) in a way that makes this not work
    blob_info = None
    if request.vars.blob_key == '':
        #it seems that prod blobstore returns empty string instead of None 
when
        #there are no changes to the image
        request.vars.blob_key = None
    if request.vars.blob_key != None:
        blob_info = blobstore.parse_blob_info(request.vars.blob_key)
        del request.vars['blob_key']

    upload_url = blobstore.create_upload_url(URL(r=request,f='upload_image',
                                                 args=request.args,
                                                
 vars={'redir':URL(r=request,c='dataadmin', f='index')}))

    form['_action']=upload_url
    #since we are setting the action after the form was initially created we
    # need to reset the form.custom.begin
    (begin, end) = form._xml()
    form.custom.begin = XML("<%s %s>" % (form.tag, begin))

    if form.accepts(request.vars,session, formname="uploadimage"):
        #@TODO: can this be a post-validation function?
        #get the record we just inserted/modified
        row = db(db.blobstore_image.id == form.vars.id).select().first()
        if request.vars.blob_key__delete == 'on' or \
            (blob_info and (row and row.blob_key)):
            #remove from blobstore because of delete or update of image
            decoded_key = base64.b64decode(row.blob_key.split('.')[0])
            blobstore.delete(decoded_key)
            #remove reference in the artwork record
            row.update_record(blob_key=None)
        if blob_info:
            logging.info("adding blob_key " + str(blob_info.key()))
            #add reference to image in this record
            key = base64.b64encode(str(blob_info.key())) +"." + 
blob_info.content_type.split('/')[1]
            url = get_serving_url(str(blob_info.key()))
            
            row.update_record(blob_key = key, image_url = url)

        crud.archive(form)
        session.flash="Image saved"
        #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,f='upload_image', 
args=form.vars.id))
    elif form.errors:
        #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 blob_info:
            blobstore.delete(blob_info.key())
        #Raise the HTTP exception so that the response content stays empty.
        #calling redirect puts content in the body which fails the blob 
upload
        redirvars = {}
        redirvars['form_errors']=True
        redirvars['error_dict'] = form.errors
        raise HTTP(303,
                   Location= URL(r=request,f='upload_image', 
args=request.args,
                                 vars=redirvars))
  return dict(form=form,
              aahome=A("data Home", _href=URL(r=request, f='index')),
              back=A("Query view",
                     _href=URL(r=request, f='query', 
args=['blobstore_image'])))


hope that helps!

cfh

Reply via email to