Hi Iap, Have you seen my series of blog posts about handling uploads to the blobstore?
http://blog.notdot.net/tag/blobstore -Nick Johnson On Sun, Jan 16, 2011 at 11:08 PM, Iap <[email protected]> wrote: > HI, Nick > Thanks for your reply, I have fired a feature request in the tracking > system. > > After several days survey, I have completed a not prefect workaround for > multiple uploading. > Hope this will help to those people with the same issue before the official > solution. > > The workaround is based on uploadify(http://www.uploadify.com/), the idea > is: > 1. Requests the create_upload_url() with the "onCheck" event of uploadify. > The create_upload_url() has to be called many times to create several > sessions if multiple files will be uploaded. > > 2. Because the uploadify does not send cookie with the uploading request, > if the action url requires login, the authentication will be failed. In > order to recover the user object later, the user instance's key has to be > passed in the redirected url (as well as extra data of validation to protect > from cracking). > > 3. Update the url of action in every uploadify onComplete or onError event. > This will consume the urls gotten in the step 1. > > 4. In the handler which is redirected from the > blobstore.create_upload_url(), verify the protection data if any, then > recover the instance concerns to the user and handles the blobinfo. > > There are the example codes: > > In javascript: > $('#file_upload').uploadify({ > 'script' : '', // will be assigned later > 'auto' : true, > 'multi': true, > > 'checkScript':'url_to_handler_which_calls_create_upload_url()', > 'onCheck' : function(event,data,key) { > var urls = > $('#file_upload').data('upload_urls') > urls = urls.concat(data.data) > var url = urls.shift() > $('#file_upload').data('upload_urls',urls) > > $('#file_upload').uploadifySettings('script',url) > return false > }, > 'onComplete':function (event, ID, fileObj, response, data){ > var urls = $('#file_upload').data('upload_urls') > var url = urls.shift() > $('#file_upload').data('upload_urls',urls) > if (!url) { > return > } > $('#file_upload').uploadifySettings('script',url) > }, > 'onError':function(event,ID,fileObj,errorObj) { > var urls = $('#file_upload').data('upload_urls') > var url = urls.shift() > if (!url) { > // the last uploading causes error > return > } > $('#file_upload').data('upload_urls',urls) > $('#file_upload').uploadifySettings('script',url) > } > }); > > in GAE handler: > > ## > ## handles the url_to_handler_which_calls_create_upload_url() > ## (this is implementation specific) > ## > class ResourceUploadHandler(blobstore_handlers.BlobstoreUploadHandler): > > ## because the uploadify do the onCheck with javascript, > ## the cookie will be sent, so it can be sure that > ## get_current_user() is not None. > def get_urls(self,n): > user = users.get_current_user() > assert user > ## remember to add extra validation data > success_path ='resource/upload/'?email=%s' % (user.email) > upload_urls = [] > for i in range(0,n): > upload_urls.append( blobstore.create_upload_url(success_path) ) > if n==1: > upload_urls = upload_urls[0] > return json(upload_urls) > > ## The "post" will be called twice, firstly for checking, > ## then for uploading actual data. This is not required, > ## you can separate into two individual handlers of course. > > ## Because the uploadify do uploading with Flash, > ## it does not send cookie when uploading file data, > ## the login_required will be failed. > #@login_required > def post(self): > blobinfos = [] > for blobinfo in self.get_uploads(): > blobinfos.append(blobinfo) > if not blobinfos: > ## requested by "onCheck" of uploadify, > n = len(self.request.form.keys()) > ## excludes the extra key -- "folder" > return self.get_urls(n - 1) > > ## here comes the actual uploading > ## do validation here to protect from cracking > #data_to_verify = self.request.args.get('extra_data') > #do_the_verification(data_to_verify) > > ## do the job > email = self.request.args.get('email') > user_entity = retrive_the_user_entity_from_email(email) > for blobinfo in blobinfos: > whatever_you_like_to_do_with(blobinfo) > > iap > > 2011/1/12 Nick Johnson (Google) <[email protected]> > > Hi Iap, >> >> Unfortunately, the blobstore doesn't currently support this use-case. We >> may add support for invariant upload URLs and alternate encapsulation >> methods in future - feel free to file a feature request in the issue >> tracker! >> >> -Nick Johnson >> >> On Wed, Jan 12, 2011 at 3:54 PM, Iap <[email protected]> wrote: >> >>> Hi, >>> The official API requires two steps to create an entry in blobstore. >>> Firstly, get an URL by create_upload_url(), then receive the BlobKey in >>> redirected handler. >>> >>> That doesn't fit into my case. Because: >>> In client side, I use ajax to send data, which does not send data with >>> "multipart/form-data", >>> instead it sends with "X-Requested-With" header and >>> "application/octet-stream" content-type. >>> That is because it want to send multiple files one by one immediately, >>> soon after user has selected the files to upload. (see >>> http://valums.com/ajax-upload/) >>> >>> The url, returned by create_upload_url() can only handles >>> "multi-part/formdata" >>> and reject any extra querystring , the filename goes there (ex. >>> create_upload_url()+'?qqfile=test.jpg'). >>> So I can not create the blobstore entity by the official two-steps >>> procedure. >>> >>> But I can not find any other way to create blobstore entity. >>> Any suggestions are appreciated. Thanks in advance. >>> >>> iap >>> >> >> > > -- > You received this message because you are subscribed to the Google Groups > "Google App Engine" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]<google-appengine%[email protected]> > . > For more options, visit this group at > http://groups.google.com/group/google-appengine?hl=en. > -- Nick Johnson, Developer Programs Engineer, App Engine Google Ireland Ltd. :: Registered in Dublin, Ireland, Registration Number: 368047 -- You received this message because you are subscribed to the Google Groups "Google App Engine" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.
