Search code examples
pythoniphoneimagegoogle-app-engineblobstore

Upload an image from iphone to GAE blobstore


I spent all this morning looking for a clear example on how to upload a picture taken with an iPhone to the blobstore, but without succeed.

Currently I have my iPhone app developed, which can send pics to the server in PHP, with this code in the server:

// Function to upload a photo in a file and save data in the DB
function upload($photoData, $descr, $phone) {
    // Folder to upload data
    $path = $_SERVER['DOCUMENT_ROOT']."/program/data/";

    // Check if there was no error during the file upload
    if ($photoData['error'] == 0) {
        $result = query("INSERT INTO pics(descr, phone) VALUES('%s','%s')", $descr, $phone);
        if (!$result['error']) {
            // Inserted in the database, go on with file storage
            // Obtain database link (in lib.php)
            global $link;

            // Get the last automatically generated ID
            $idPhoto = mysqli_insert_id($link);

            // Move the temporarily stored file to a convenient location
            if (move_uploaded_file($photoData['tmp_name'], $path.$idPhoto.".jpg")) {
                // File moved, all good, generate thumbnail
                thumb($path.$idPhoto.".jpg", 180);
                print json_encode(array('successful' => 1));
            } else {
                errorJson('Upload on server problem');
            }
        } else {
            errorJson('Save database problem: '.$result['error']);
        }
    } else {
        errorJson('Upload malfunction.');
    }
}

The part in Objective-C that makes this works is (I'm using AFNetworking and the object API sharedInstance is an AFJSONRequestOperation class):

// Upload the image and the description to the web service
[[API sharedInstance] commandWithParams:[NSMutableDictionary dictionaryWithObjectsAndKeys:
                                             @"upload", @"command",
                                             UIImageJPEGRepresentation(originalPhoto, 70), @"file",
                                             description, @"descr",
                                             phoneNumber, @"phone",
                                             nil]
                               onCompletion:^(NSDictionary *json) {
                                   // Finished and response from server
                                   if (![json objectForKey:@"error"]) {
                                       // Success
                                       [[[UIAlertView alloc]initWithTitle:@"Info"
                                                                  message:@"Thanks"
                                                                 delegate:nil
                                                        cancelButtonTitle:@"Dismiss"
                                                        otherButtonTitles: nil] show];

                                       // Send a notification so the main view can reload the data
                                       [[NSNotificationCenter defaultCenter] postNotificationName:@"updateStream" object:nil];
                                   } else {
                                       // Error
                                       NSString* errorMsg = [json objectForKey:@"error"];
                                       [UIAlertView error:errorMsg];
                                   }
                               }];

This works fine and the images are saved on the server. But I want to make the same with datastore, which you can't save files. So I made a webpage to practice on save images, and I can upload images without any problem in the blobstore from an standard web form. This is the code I'm using to save it in GAE (forget about my own helper classes or functions like PicturePageHandler or render_page):

# Get and post for the create page
class Create(PicturePageHandler, blobstore_handlers.BlobstoreUploadHandler):
    def get(self):
        if self.user_logged_in():
            # The session for upload a file must be new every reload page
            uploadUrl = blobstore.create_upload_url('/addPic')
            self.render_page("addPicture.htm", form_action=uploadUrl)

    def post(self):
        if self.user_logged_in():
            # Create a dictionary with the values, we will need in case of error
            templateValues = self.template_from_request()
            # Test if all data form is valid
            testErrors = check_fields(self)

            if testErrors[0]:
                # No errors, save the object
                try:
                    # Get the file and upload it
                    uploadFiles = self.get_uploads('picture')
                    # Get the key returned from blobstore, for the first element
                    blobInfo = uploadFiles[0]
                    # Add the key and the permanent url to the template
                    templateValues['blobKey'] = blobInfo.key()
                    templateValues['servingUrl'] = images.get_serving_url(blobInfo.key(), size=None)

                    # Save all
                    pic = Picture.save(self.user.key, **templateValues)
                    if pic is None:
                        logging.error('Picture save error.')

                    self.redirect("/myPics")

                except:
                    self.render_page("customMessage.htm", custom_msg=_("Problems while uploading the picture."))
            else:
                # Errors, render the page again, with the values, and showing the errors
                templateValues = custom.prepare_errors(templateValues, testErrors[1])
                # The session for upload a file must be new every reload page
                templateValues['form_action'] = blobstore.create_upload_url('/addPic')

                self.render_page("addPicture.htm", **templateValues)

My questions are:

  1. Can I still using my Objective-C JSON call to upload a picture to the server or must I completely change the way to upload the picture?
  2. How can I change the Python server code to get the picture from the JSON, if it is possible?

Solution

  • It's not exactly what you're after, but this might help:

    http://brunofuster.wordpress.com/2011/03/11/uploading-an-image-from-iphone-to-appengine-blobstore-using-vraptor/