def handlePostRequest(self): action = self.request.get('action', None) data = None try: if action != self.ACTION_ADMIN: data = self.request.POST['data'] except KeyError: self.addMessage('You must upload a file.') else: if action == self.ACTION_HAZARD: key = blobstore.parse_blob_info(data) zfile = ZipFile(blobstore.BlobReader(key), 'r') reader = HazardsImporter(zfile) if reader.read(): self.addMessage('The operation was successful.', self.MSG_TYPE_SUCCESS) else: self.addMessage('<strong>Error</strong>: %s' % reader.error) key.delete() if action == self.ACTION_INGREDIENT: key = blobstore.parse_blob_info(data) user = User.load(users.get_current_user()) if not user: user = User.system_user() reader = IngredientsImporter(blobstore.BlobReader(key), user) if reader.read(): self.addMessage('The operation was successful.', self.MSG_TYPE_SUCCESS) else: self.addMessage('<strong>Error</strong>: %s' % reader.error) key.delete() if action == self.ACTION_ADMIN: email = self.request.get('email') user = User.find_by_email(email) if not user: user = User.create_by_email(email) admin_role = Role.get_admin_role() UserRole.create(user, admin_role) self.addMessage( 'The admin "%s" was successfully added.' % email, self.MSG_TYPE_SUCCESS) self.addCommon() self.setActivePage('Utilities')
def get_uploads(self, field_name=None): """Get uploads sent to this handler. Args: field_name: Only select uploads that were sent as a specific field. Returns: A list of BlobInfo records corresponding to each upload. Empty list if there are no blob-info records for field_name. """ if self.__uploads is None: self.__uploads = collections.defaultdict(list) for key, value in list(self.request.params.items()): if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: self.__uploads[key].append( blobstore.parse_blob_info(value)) if field_name: return list(self.__uploads.get(field_name, [])) else: results = [] for uploads in six.itervalues(self.__uploads): results.extend(uploads) return results
def item_create(): form = ItemForm() if form.validate_on_submit(): item = Item() item.title = form.title.data item.seller_id = current_user.get_id() item.slug = slugify(form.title.data) item.description = form.description.data item.price = Price(fixed_value=form.price.data*100, currency='USD') if form.image.has_file(): blob = blobstore.parse_blob_info(to_fieldstorage(form.image.data)) item.image = blob.key() item.youtube = form.youtube.data item.active = form.active.data item.expiry = datetime.datetime.now() + datetime.timedelta(days=form.expires_in.data) private_viewer_emails = [_.strip() for _ in form.private_viewers.data.split(',')] item.private_viewer_keys = [user.key for user in UserProfile.query(UserProfile.email.IN(private_viewer_emails))] k = item.put() flash(_T('Your item has been created!'), 'success') return redirect(url_for('item', id=k.id(), slug=item.slug)) return render_template('item/create.html', form=form, action=blobstore.create_upload_url(url_for('item_create')), title=_T('Create Item'))
def get_uploads(self): """Get all uploads sent to this controller. Returns: A dictionary mapping field names to a list of blobinfo objects. This blobinfos will have an additional cloud_storage property if they have been uploaded to cloud storage but be aware that this will not be persisted. """ if self.__uploads is None: self.__uploads = {} for key, value in self.controller.request.params.items(): if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: blob_info = blobstore.parse_blob_info(value) cloud_info = blobstore.parse_file_info(value) # work around mangled names blob_info = blobstore.BlobInfo.get(blob_info.key()) # Add cloud storage data setattr(blob_info, 'cloud_storage', cloud_info) self.__uploads.setdefault(key, []).append(blob_info) return self.__uploads
def get_uploads(self, field_name=None): """Get uploads sent to this controller. Args: field_name: Only select uploads that were sent as a specific field. Returns: A list of BlobInfo records corresponding to each upload. Empty list if there are no blob-info records for field_name. """ if self.__uploads is None: self.__uploads = {} for key, value in self.controller.request.params.items(): if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: info = blobstore.parse_blob_info(value) self.__uploads.setdefault(key, []).append(info) results = [] if field_name: try: results = list(self.__uploads[field_name]) except KeyError: pass else: for uploads in self.__uploads.itervalues(): results += uploads # Workaround for mangled filenames return blobstore.BlobInfo.get([x.key() for x in results])
def getUploads(self, field_name = None): """ Get uploads sent to this handler. Cheeky borrowed from blobstore_handlers.py - © 2007 Google Inc. Args: field_name: Only select uploads that were sent as a specific field. Returns: A list of BlobInfo records corresponding to each upload. Empty list if there are no blob-info records for field_name. """ uploads = collections.defaultdict(list) for key, value in request.current.get().request.params.items(): if isinstance(value, cgi.FieldStorage): if "blob-key" in value.type_options: uploads[key].append(blobstore.parse_blob_info(value)) if field_name: return list(uploads.get(field_name, [])) results = [] for uploads in uploads.itervalues(): results.extend(uploads) return results
def deserialize(self, field, pstruct): logger.debug('widget:deserialize, %s, %s', field, pstruct) if pstruct is null: return null upload = pstruct.get('upload') uid = pstruct.get('uid') if hasattr(upload, 'file'): # the upload control had a file selected blob_info = blobstore.parse_blob_info(upload) data = filedict(self.tmpstore._to_dict(blob_info)) if uid: # previous file exists del self.tmpstore[uid] else: # the upload control had no file selected if not uid: # no previous file exists return null else: # a previous file should exist data = self.tmpstore.get(uid) # but if it doesn't, don't blow up if data is None: return null return data
def post(self): """Do upload post.""" error_messages = [] blob_info_dict = {} for key, value in self.request.params.items(): if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: blob_info = blobstore.parse_blob_info(value) blob_info_dict[value.name] = blob_info logging.info("got blob: %s" % value.name) self.store_blob(value.name, blob_info, error_messages) if error_messages: logging.error('Upload errors: %r', error_messages) blobstore.delete(blob_info_dict.values()) self.response.set_status(303) # TODO: fix up this format self.response.headers.add_header( "Location", '/error?%s' % '&'.join('error_message=%s' % urllib.quote(m) for m in error_messages)) else: query = ['/nonstandard/upload_complete?camliversion=1'] query.extend('blob%d=%s' % (i + 1, k) for i, k in enumerate(blob_info_dict.iterkeys())) self.response.set_status(303) self.response.headers.add_header("Location", str('&'.join(query)))
def get_uploads(self, field_name=None): """Get uploads sent to this controller. Args: field_name: Only select uploads that were sent as a specific field. Returns: A list of BlobInfo records corresponding to each upload. Empty list if there are no blobinfo records for field_name. """ if self.__uploads is None: self.__uploads = {} for key, value in self.controller.request.params.items(): if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: info = blobstore.parse_blob_info(value) self.__uploads.setdefault(key, []).append(info) results = [] if field_name: try: results = list(self.__uploads[field_name]) except KeyError: pass else: for uploads in self.__uploads.itervalues(): results += uploads # Workaround for mangled filenames return blobstore.BlobInfo.get([x.key() for x in results])
def get_uploads(self, field_name=None): """Get uploads sent to this handler. Args: field_name: Only select uploads that were sent as a specific field. Returns: A list of BlobInfo records corresponding to each upload. Empty list if there are no blob-info records for field_name. """ if self.__uploads is None: self.__uploads = {} for key, value in self.request.params.items(): if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: self.__uploads.setdefault(key, []).append( blobstore.parse_blob_info(value)) if field_name: try: return list(self.__uploads[field_name]) except KeyError: return [] else: results = [] for uploads in self.__uploads.itervalues(): results += uploads return results
def post(self): """Do upload post.""" error_messages = [] blob_info_dict = {} for key, value in self.request.params.items(): if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: blob_info = blobstore.parse_blob_info(value) blob_info_dict[value.name] = blob_info logging.info("got blob: %s" % value.name) self.store_blob(value.name, blob_info, error_messages) if error_messages: logging.error('Upload errors: %r', error_messages) blobstore.delete(blob_info_dict.values()) self.response.set_status(303) # TODO: fix up this format self.response.headers.add_header("Location", '/error?%s' % '&'.join( 'error_message=%s' % urllib.quote(m) for m in error_messages)) else: query = ['/nonstandard/upload_complete?camliversion=1'] query.extend('blob%d=%s' % (i + 1, k) for i, k in enumerate(blob_info_dict.iterkeys())) self.response.set_status(303) self.response.headers.add_header("Location", str('&'.join(query)))
def get_uploads(request, field_name=None, populate_post=False): """Get uploads sent to this handler. Args: field_name: Only select uploads that were sent as a specific field. populate_post: Add the non blob fields to request.POST Returns: A list of BlobInfo records corresponding to each upload. Empty list if there are no blob-info records for field_name. """ if hasattr(request,'__uploads') == False: fields = cgi.FieldStorage(request.META['wsgi.input'], environ=request.META) request.__uploads = {} if populate_post: request.POST = {} for key in fields.keys(): field = fields[key] if isinstance(field, cgi.FieldStorage) and 'blob-key' in field.type_options: request.__uploads.setdefault(key, []).append(blobstore.parse_blob_info(field)) elif populate_post: request.POST[key] = field.value if field_name: try: return list(request.__uploads[field_name]) except KeyError: return [] else: results = [] for uploads in request.__uploads.itervalues(): results += uploads return results
def item_update(id, slug): item = Item.get_or_404(id, slug) if not item.editable_by(current_user): abort(403) form = ItemForm() if form.validate_on_submit(): item.title = form.title.data item.description = form.description.data item.price = Price(fixed_value=form.price.data*100, currency='USD') item.active = form.active.data item.expiry = datetime.datetime.now() + datetime.timedelta(days=form.expires_in.data) private_viewer_emails = [_.strip() for _ in form.private_viewers.data.split(',')] item.private_viewer_keys = [user.key for user in UserProfile.query(UserProfile.email.IN(private_viewer_emails))] if form.image.has_file(): app.logger.debug(form.image.data) app.logger.debug(dir(form.image.data)) app.logger.debug(form.image.data.mimetype_params) blob = blobstore.parse_blob_info(to_fieldstorage(form.image.data)) item.image = blob.key() item.put() flash(_T('Item updated'), 'success') return redirect(url_for('item', id=id, slug=slug)) form = ItemForm(title=item.title, description=item.description, price=item.price.fixed_value / 100, youtube=item.youtube, private_viewers=','.join([user.username for user in ndb.get_multi(item.private_viewer_keys)]), active=item.active) return render_template('item/update.html', form=form, id=id, slug=slug, action=blobstore.create_upload_url(url_for('item_update', id=id, slug=slug)), title=_T('Update Item') + ' %s' % item.title)
def post(self): algorithm = self.request.get('algorithm_method') blob_key = blobstore.parse_blob_info(self.request.POST[image_name]) img = ImageDB(mImage = blob_key) img.put() #redirect to the debug page that shows the image #self.redirect(image_debug_page_sub % {"blobid" : img.key().id()}) self.redirect(comparison_page_sub % {"blobid" : img.key().id(), "algorithm_method" : algorithm})
def get_blob_info(self): import cgi if self.data is None or not isinstance(self.data, cgi.FieldStorage) or not 'blob-key' in self.data.type_options: return None info = blobstore.parse_blob_info(self.data) if not info: return None return info
def process_blob_input(cls, context, input): for key, value in input.items(): if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: try: blob_info = blobstore.parse_blob_info(value) context.blob_unused.append(blob_info.key()) except blobstore.BlobInfoParseError as e: pass
def upload_image(): """ This is where an artist uploads a work of art. """ form = SQLFORM(db.xim, _name='xim_form', fields=['title', 'description', 'image']) if request.env.web2py_runtime_gae: from google.appengine.ext import blobstore 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.image != None: blob_info = blobstore.parse_blob_info(request.vars.image) upload_url = blobstore.create_upload_url(URL(r=request,f='upload_image', args=request.args)) form['_action']=upload_url if form.accepts(request.vars,session, formname="ximform"): #@TODO: can this blob-key update be a post-validation function? #get the record we just inserted/modified row = db(db.xim.id == form.vars.id).select().first() if request.vars.image__delete == 'on' or \ (form.vars.image != None and (row and row.blob_key)): #remove from blobstore because of delete or update of image key = row.blob_key blobstore.delete(key) #remove reference in the xim record row.update_record(blob_key=None, image=None) if form.vars.image != None: #add reference to image in this record row.update_record(image = \ "xim.image."+str(uuid.uuid4()).replace('-','')+".jpg", blob_key = blob_info.key()) crud.archive(form) #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='list_blob_images')) 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 request.vars.image != None: 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 raise HTTP(303, Location= URL(r=request,f='upload_image')) return dict(form=form)
def get_uploads2(request, name): if hasattr(request, '__uploads') == False: request.META['wsgi.input'].seek(0) fields = cgi.FieldStorage(request.META['wsgi.input'], environ=request.META) try: field = fields[name] return blobstore.parse_blob_info(field) except: return None
def _convert_value(self, value, path=None): if path is None: path = self._code_name if not self._repeated: value = [value] out = [] total = len(value) - 1 for i, v in enumerate(value): if not self._upload: if not isinstance(v, dict) and not self._required: continue out.append(self._structured_property_format(v, path)) else: if not isinstance(v, cgi.FieldStorage): if self._required: raise FormatError('invalid_input') else: continue # These will throw errors if the 'v' is not cgi.FileStorage and it does # not have compatible blob-key. file_info = blobstore.parse_file_info(v) blob_info = blobstore.parse_blob_info(v) # We only accept jpg/png. This list can be and should be customizable # on the property option itself? if file_info.content_type not in ('image/jpeg', 'image/jpg', 'image/png'): # First line of validation based on meta data from client. raise FormatError('invalid_image_type') new_image = self.get_modelclass()(**{ 'size': file_info.size, 'content_type': file_info.content_type, 'gs_object_name': file_info.gs_object_name, 'image': blob_info.key(), '_sequence': total - i }) out.append(new_image) if not out: # if field is not required, and there isnt any processed return non # existent if not self._required: return tools.Nonexistent else: raise FormatError('required') # otherwise required if self._upload: if self._process_config.get( 'transform') or self._process_config.get('copy'): self.process(out) else: self.generate_serving_urls(out) if self._process_config.get('measure', True): self.generate_measurements(out) map(lambda x: self.save_blobs_on_success(x.image), out) if not self._repeated: out = out[0] return out
def handler(gae_handler): # prepare request = gae_handler.request response = gae_handler.response route = {} params = dict(gae_handler.request.params) if adminonly or admin_only: user = users.get_current_user() if not user: url = users.create_login_url(request.uri) elif not users.is_current_user_admin(): url = '/%s/' % area gae_handler.redirect(url) if routes: for r in routes: if re.search(r, request.path): route = re.search(r, request.path).groupdict() if uploader: uploads = defaultdict(list) for k,v in gae_handler.params.items(): if isinstance(v,cgi.FieldStorage) and 'blob-key' in v.type_options: uploads[k].append( blobstore.parse_blob_info(v)) fn_args = uploader and [uploads, gae_handler] or [gae_handler, route, params] try: context = fn(gae_handler, route, params) except TypeError as te: context = fn(gae_handler) tmpl = template or context.get("__template",None) redirect = redirect_to or context.get("__redirect_to",None) if redirect: return gae_handler.redirect(redirect) if response_type == "html": tmpl_name = tmpl or fn.__name__ + ".html" tmpl_path = "%s/%s" % (folder or area,tmpl_name) tmpl_file = jinja_environment.get_template(tmpl_path) context.update({ 'request' : request, 'app_version' : os.environ["CURRENT_VERSION_ID"], 'is_dev_env' : os.environ["SERVER_SOFTWARE"].startswith("Dev"), 'session' : gae_handler.session, 'page_theme' : pagetheme or "shared/_master.html", }) return tmpl_file.render( context ) elif response_type == "json": response.headers["Content-Type"] = "application/json" return json.encode( context )
def process(self, formdata=None, obj=None, **kwargs): super(CsvImportForm, self).process(formdata, obj, **kwargs) if formdata: value = formdata.get('file', None) if isinstance(value, cgi.FieldStorage) and 'blob-key' in value.type_options: info = blobstore.parse_blob_info(value) self.file.data = info.key() logging.error('CSV file uploaded, blob key is %s' % self.file.data) else: self.file.data = None logging.error('No file element in formdata')
def process_formupload(req): for key,value in req.form.items(): if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: blobinfo = blobstore.parse_blob_info(value) item = Item( created_by=req.get("user_id"), media_file_key=str(blobinfo.key()), media_file_mime=blobinfo.content_type, media_filename=blobinfo.filename) item.put() return req.redirect(req.uri.server_uri()+'/item/'+str(item.key().id()))
def process_upload(req): user = users.get_current_user() filename = '' for key,value in req.form.items(): if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: blobinfo = blobstore.parse_blob_info(value) filename = blobinfo.filename item = Item( created_by=req.get("user_id"), media_file_key=str(blobinfo.key()), media_file_mime=blobinfo.content_type, media_filename=blobinfo.filename) item.put() req.res.body = 'uploaded '+filename
def process_blob_input(cls, input): uploaded_blobs = [] for key, value in input.iteritems(): if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: try: blob_info = blobstore.parse_blob_info(value) uploaded_blobs.append(blob_info.key()) except blobstore.BlobInfoParseError as e: pass if uploaded_blobs: blobs = {'delete': uploaded_blobs} # By default, we set that all uploaded blobs must be deleted in 'finally' phase. # However, we use blob specialized properties to control intermediate outcome of action. tools.mem_temp_set(settings.BLOBKEYMANAGER_KEY, blobs)
def get_uploads(request, field_name=None, populate_post=False): """Get uploads sent to this handler. Args: field_name: Only select uploads that were sent as a specific field populate_post: Add the non blob fields to request.POST Returns: A list of BlobInfo records corresponding to each upload Empty list if there are no blob-info records for field_name """ results = [] # the __uploads attribute in the request object is used # only to cache the file uploads so that we need not # have to go through the process of reading HTTP request # original file if it has already been read in the same request. if hasattr(request,'__uploads') == False: request.META['wsgi.input'].seek(0) fields = cgi.FieldStorage(request.META['wsgi.input'], environ=request.META) request.__uploads = {} if populate_post: request.POST = {} for key in fields.keys(): field = fields[key] if isinstance( field, cgi.FieldStorage) and 'blob-key' in field.type_options: request.__uploads.setdefault(key, []).append( blobstore.parse_blob_info(field)) elif populate_post: request.POST[key] = field.value if field_name: try: results = list(request.__uploads[field_name]) except KeyError: return [] else: for uploads in request.__uploads.itervalues(): results += uploads request.file_uploads = results return results
def _convert_value(self, value): out = [] if not self._repeated: value = [value] for v in value: # This alone will raise error if the upload is malformed. try: blob = blobstore.parse_blob_info(v).key() except: blob = blobstore.BlobKey(v) out.append(blob) if not self._repeated: try: out = out[0] except IndexError as e: out = None return out
def _parseField(request, key, field): """Parses one field. Handles BlobInfo objects and adds the 'name' field for Django. """ if isinstance(field, cgi.FieldStorage) and 'blob-key' in field.type_options: blob_info = blobstore.parse_blob_info(field) uploads = request.__uploads.setdefault(key, []) uploads.append(blob_info) # Put the BlobInfo in the POST data and format it for Django by # adding the name property. blob_info.name = blob_info.filename request.file_uploads[key] = blob_info elif isinstance(field, list): request.POST[key] = [f.value for f in field] else: request.POST[key] = field.value
def return_upload(): from google.appengine.ext import blobstore from google.appengine.api import images blob_info = blobstore.parse_blob_info(request.vars.content) blob_key = blob_info.key() cached_url = images.get_serving_url(blob_key) original_filename = blob_info.filename logger.info(blob_key) logger.info(original_filename) db.user_photo.update_or_insert( db.user_photo.user_id == request.vars.user_id, user_id=request.vars.user_id, blob_key=blob_key, original_filename=original_filename, cached_url=cached_url) return cached_url
def get_uploads(request, field_name=None, populate_post=False): """Get uploads sent to this handler. Args: field_name: Only select uploads that were sent as a specific field. populate_post: Add the non blob fields to request.POST Returns: A list of BlobInfo records corresponding to each upload. Empty list if there are no blob-info records for field_name. """ if hasattr(request, '__uploads') == False: request.META['wsgi.input'].seek(0) fields = cgi.FieldStorage(request.META['wsgi.input'], environ=request.META) request.__uploads = {} if populate_post: request.POST = {} for key in fields.keys(): field = fields[key] if isinstance( field, cgi.FieldStorage) and 'blob-key' in field.type_options: request.__uploads.setdefault(key, []).append( blobstore.parse_blob_info(field)) elif populate_post: request.POST[key] = field.value if field_name: try: return list(request.__uploads[field_name]) except KeyError: return [] else: results = [] for uploads in request.__uploads.itervalues(): results += uploads return results
def get_blobinfo_from_post(request): result = [] request.META['wsgi.input'].seek(0) fields = cgi.FieldStorage(request.META['wsgi.input'], environ=request.META) values = [] try: imagefields = fields["image"] except KeyError: return result if isinstance(imagefields, list): for i in imagefields: values.append( i ) else: values.append( imagefields ) for value in values: blob_info=blobstore.parse_blob_info(value) if blob_info.size == 0: blob_info.delete() else: result.append(blob_info) return result
def _get_uploads(self): """ Lazy decode and store file uploads from either: * base64 encoded form body data * the app engine blob store upload_url machinery If we're handling an image, adds a `${key}_serving_url` string property. """ if self._uploads is None: self._uploads = {} for key, value in self.request.params.iteritems(): blob_key = None # If we're dealing with a post from the blob store upload url, # get the blob key from the already stored blob. if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: info = blobstore.parse_blob_info(value) blob_key = info.key() # Otherwise if we're dealing with our own base64 encoded data # decode it, save a blob and use its key. elif value and key in self._upload_files and not is_empty_file( value): mime_type = self._upload_files.get(key) try: data = base64.b64decode(encode_to_utf8(value)) except TypeError, err: logging.warning(err, exc_info=True) else: blob_key = self._write_file(mime_type, data) # Either way, if we have a blob key, add it to self._uploads # and, if it's an image then set the corresponding `serving_url`. if blob_key is not None: mime_type = self._upload_files.get(key) if mime_type == 'image/jpeg': serving_key = '%s_serving_url' % key serving_url = images.get_serving_url(blob_key) self._uploads[serving_key] = serving_url self._uploads[key] = blob_key
def value_format(self, value): if self._repeated and not isinstance(value, list): value = [value] if (self._repeated and (not len(value) or not isinstance(value[0], cgi.FieldStorage))) or (not self._repeated and not isinstance(value, cgi.FieldStorage)): return super(_BaseImageProperty, self).value_format(value) value = self._property_value_format(value) if value is Nonexistent: return value if not self._repeated: value = [value] out = [] for i, v in enumerate(value): if isinstance(v, dict): out.append(self._structured_property_format(v)) else: if not isinstance(v, cgi.FieldStorage) and not self._required: return Nonexistent # If the field is not required, and it's not an actual upload, immediately return Nonexistent. # These will throw errors if the 'v' is not cgi.FileStorage and it does not have compatible blob-key. file_info = blobstore.parse_file_info(v) blob_info = blobstore.parse_blob_info(v) meta_required = ('image/jpeg', 'image/jpg', 'image/png') # We only accept jpg/png. This list can be and should be customizable on the property option itself? if file_info.content_type not in meta_required: raise orm.PropertyError('invalid_image_type') # First line of validation based on meta data from client. new_image = self.get_modelclass()(**{'size': file_info.size, 'content_type': file_info.content_type, 'gs_object_name': file_info.gs_object_name, 'image': blob_info.key(), '_sequence': i}) out.append(new_image) if self._process_config.get('transform') or self._process_config.get('copy'): self.process(out) else: self.generate_serving_urls(out) if self._process_config.get('measure', True): self.generate_measurements(out) map(lambda x: self.save_blobs_on_success(x.image), out) if not self._repeated: out = out[0] return out
def _get_uploads(self): """ Lazy decode and store file uploads from either: * base64 encoded form body data * the app engine blob store upload_url machinery If we're handling an image, adds a `${key}_serving_url` string property. """ if self._uploads is None: self._uploads = {} for key, value in self.request.params.iteritems(): blob_key = None # If we're dealing with a post from the blob store upload url, # get the blob key from the already stored blob. if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: info = blobstore.parse_blob_info(value) blob_key = info.key() # Otherwise if we're dealing with our own base64 encoded data # decode it, save a blob and use its key. elif value and key in self._upload_files and not is_empty_file(value): mime_type = self._upload_files.get(key) try: data = base64.b64decode(encode_to_utf8(value)) except TypeError, err: logging.warning(err, exc_info=True) else: blob_key = self._write_file(mime_type, data) # Either way, if we have a blob key, add it to self._uploads # and, if it's an image then set the corresponding `serving_url`. if blob_key is not None: mime_type = self._upload_files.get(key) if mime_type == 'image/jpeg': serving_key = '%s_serving_url' % key serving_url = images.get_serving_url(blob_key) self._uploads[serving_key] = serving_url self._uploads[key] = blob_key
def POST(self): import cgi fields = cgi.FieldStorage() file_fields = fields['media'] if not isinstance(file_fields, list): file_fields = [file_fields] for field in file_fields: media = Media() try: blob_info = blobstore.parse_blob_info(field) key = str(blob_info.key()) small_img = images.Image(blob_key=key) big_img = images.Image(blob_key=key) media.name = blob_info.filename.decode('utf-8') media.blobstore_key = key except: source = field.value media.name = field.filename.decode('utf-8') media.source = source small_img = images.Image(source) big_img = images.Image(source) small_img.resize(width=200, height=150) small_img.im_feeling_lucky() small_thumb = small_img.execute_transforms(output_encoding=images.JPEG) big_img.resize(width=650, height=1000) big_img.im_feeling_lucky() big_thumb = big_img.execute_transforms(output_encoding=images.JPEG) media.small = small_thumb media.big = big_thumb media.save() raise web.seeother('/admin/media')
def get_uploads(self, field_name=None): """Get uploads sent to this handler. Args: field_name: Only select uploads that were sent as a specific field. Returns: A list of BlobInfo records corresponding to each upload. Empty list if there are no blob-info records for field_name. """ if self.__uploads is None: self.__uploads = collections.defaultdict(list) for key, value in self.request.params.items(): if isinstance(value, cgi.FieldStorage): if 'blob-key' in value.type_options: self.__uploads[key].append(blobstore.parse_blob_info(value)) if field_name: return list(self.__uploads.get(field_name, [])) else: results = [] for uploads in self.__uploads.itervalues(): results.extend(uploads) return results
def handle_http_request( env, start_response, dict=dict, isinstance=isinstance, urlunquote=urlunquote, unicode=unicode, get_response_headers=lambda: None ): reqlocal.template_error_traceback = None try: http_method = env['REQUEST_METHOD'] ssl_mode = env['wsgi.url_scheme'] == 'https' if http_method == 'OPTIONS': start_response(*RESPONSE_OPTIONS) return [] if http_method not in SUPPORTED_HTTP_METHODS: start_response(*RESPONSE_NOT_IMPLEMENTED) return [] _path_info = env['PATH_INFO'] if isinstance(_path_info, unicode): _args = [arg for arg in _path_info.split(u'/') if arg] else: _args = [ unicode(arg, 'utf-8', 'strict') for arg in _path_info.split('/') if arg ] kwargs = {} for part in [ sub_part for part in env['QUERY_STRING'].lstrip('?').split('&') for sub_part in part.split(';') ]: if not part: continue part = part.split('=', 1) if len(part) == 1: value = None else: value = part[1] key = urlunquote(part[0].replace('+', ' ')) if value: value = unicode( urlunquote(value.replace('+', ' ')), 'utf-8', 'strict' ) else: value = None if key in kwargs: _val = kwargs[key] if isinstance(_val, list): _val.append(value) else: kwargs[key] = [_val, value] continue kwargs[key] = value ctx = Context(env, ssl_mode) router = handle_http_request.router if router: _info = router(ctx, _args, kwargs) if not _info: logging.error("No handler found for: %s" % _path_info) raise NotFound name, args = _info else: if _args: name = _args[0] args = _args[1:] else: name = '/' args = () if name not in HANDLERS: logging.error("Handler not found: %s" % name) raise NotFound handler, renderers, config = HANDLERS[name] json = config['json'] # Parse the POST body if it exists and is of a known content type. if http_method == 'POST': content_type = env.get('CONTENT-TYPE', '') if not content_type: content_type = env.get('CONTENT_TYPE', '') if ';' in content_type: content_type = content_type.split(';', 1)[0] if json or content_type == 'application/json': payload = json_decode(env['wsgi.input'].read()) if json and not (json is True): kwargs[json] = payload else: kwargs.update(payload) elif content_type in VALID_REQUEST_CONTENT_TYPES: post_environ = env.copy() post_environ['QUERY_STRING'] = '' if config['post_encoding']: ctx.request_body = env['wsgi.input'].read() env['wsgi.input'] = StringIO(ctx.request_body) post_encoding = config['post_encoding'] else: post_encoding = 'utf-8' post_data = FieldStorage( environ=post_environ, fp=env['wsgi.input'], keep_blank_values=True ).list or [] for field in post_data: key = field.name if field.filename: if config['blob']: value = parse_blob_info(field) else: value = field else: value = unicode(field.value, post_encoding, 'strict') if key in kwargs: _val = kwargs[key] if isinstance(_val, list): _val.append(value) else: kwargs[key] = [_val, value] continue kwargs[key] = value def get_response_headers(): # Figure out the HTTP headers for the response ``cookies``. cookie_output = SimpleCookie() for name, values in ctx._response_cookies.iteritems(): name = str(name) cookie_output[name] = values.pop('value') cur = cookie_output[name] for key, value in values.items(): if key == 'max_age': key = 'max-age' if key not in COOKIE_KEY_NAMES: continue cur[key] = value if cookie_output: raw_headers = ctx._raw_headers + [ ('Set-Cookie', ck.split(' ', 1)[-1]) for ck in str(cookie_output).split('\r\n') ] else: raw_headers = ctx._raw_headers str_headers = []; new_header = str_headers.append for k, v in raw_headers: if isinstance(k, unicode): k = k.encode('utf-8') if isinstance(v, unicode): v = v.encode('utf-8') new_header((k, v)) return str_headers if 'submit' in kwargs: del kwargs['submit'] if 'callback' in kwargs: ctx.json_callback = kwargs.pop('callback') if env.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest': ctx.ajax_request = 1 if '__ajax__' in kwargs: ctx.ajax_request = 1 del kwargs['__ajax__'] if config['ssl'] and RUNNING_ON_GOOGLE_SERVERS and not ssl_mode: raise NotFound if config['xsrf']: if 'xsrf' not in kwargs: raise AuthError("XSRF token not present.") provided_xsrf = kwargs.pop('xsrf') if not secure_string_comparison(provided_xsrf, ctx.xsrf_token): raise AuthError("XSRF tokens do not match.") if config['admin'] and not ctx.is_admin: raise NotFound if (not config['anon']) and (not ctx.user_id): if ctx.ajax_request: ctx.response_headers['Content-Type'] = 'application/json' raise HTTPContent(encode_json({ "error": { "type": "AuthError", "redirect": ctx.get_login_url() } })) raise Redirect(ctx.get_login_url()) # Try and respond with the result of calling the handler. content = handler(ctx, *args, **kwargs) for renderer in renderers: if ctx.end_pipeline: break if content is None: content = { 'content': '' } elif not isinstance(content, dict): content = { 'content': content } if isinstance(renderer, str): content = ctx.render_mako_template(renderer, **content) else: content = renderer(ctx, **content) if content is None: content = '' elif isinstance(content, unicode): content = content.encode('utf-8') raise HTTPContent(content) # Return the content. except HTTPContent, payload: content = payload.content if 'Content-Type' not in ctx.response_headers: ctx.response_headers['Content-Type'] = 'text/html; charset=utf-8' ctx.response_headers['Content-Length'] = str(len(content)) start_response(('%d %s\r\n' % ctx._status), get_response_headers()) if http_method == 'HEAD': return [] return [content]
def handle_http_request(env, start_response, dict=dict, isinstance=isinstance, urlunquote=urlunquote, unicode=unicode, get_response_headers=lambda: None): reqlocal.template_error_traceback = None try: http_method = env['REQUEST_METHOD'] ssl_mode = env['wsgi.url_scheme'] == 'https' if http_method == 'OPTIONS': start_response(*RESPONSE_OPTIONS) return [] if http_method not in SUPPORTED_HTTP_METHODS: start_response(*RESPONSE_NOT_IMPLEMENTED) return [] _path_info = env['PATH_INFO'] if isinstance(_path_info, unicode): _args = [arg for arg in _path_info.split(u'/') if arg] else: _args = [ unicode(arg, 'utf-8', 'strict') for arg in _path_info.split('/') if arg ] kwargs = {} for part in [ sub_part for part in env['QUERY_STRING'].lstrip('?').split('&') for sub_part in part.split(';') ]: if not part: continue part = part.split('=', 1) if len(part) == 1: value = None else: value = part[1] key = urlunquote(part[0].replace('+', ' ')) if value: value = unicode(urlunquote(value.replace('+', ' ')), 'utf-8', 'strict') else: value = None if key in kwargs: _val = kwargs[key] if isinstance(_val, list): _val.append(value) else: kwargs[key] = [_val, value] continue kwargs[key] = value ctx = Context(env, ssl_mode) router = handle_http_request.router if router: _info = router(ctx, _args, kwargs) if not _info: logging.error("No handler found for: %s" % _path_info) raise NotFound name, args = _info else: if _args: name = _args[0] args = _args[1:] else: name = '/' args = () if name not in HANDLERS: logging.error("Handler not found: %s" % name) raise NotFound handler, renderers, config = HANDLERS[name] json = config['json'] # Parse the POST body if it exists and is of a known content type. if http_method == 'POST': content_type = env.get('CONTENT-TYPE', '') if not content_type: content_type = env.get('CONTENT_TYPE', '') if ';' in content_type: content_type = content_type.split(';', 1)[0] if json or content_type == 'application/json': payload = json_decode(env['wsgi.input'].read()) if json and not (json is True): kwargs[json] = payload else: kwargs.update(payload) elif content_type in VALID_REQUEST_CONTENT_TYPES: post_environ = env.copy() post_environ['QUERY_STRING'] = '' if config['post_encoding']: ctx.request_body = env['wsgi.input'].read() env['wsgi.input'] = StringIO(ctx.request_body) post_encoding = config['post_encoding'] else: post_encoding = 'utf-8' post_data = FieldStorage(environ=post_environ, fp=env['wsgi.input'], keep_blank_values=True).list or [] for field in post_data: key = field.name if field.filename: if config['blob']: value = parse_blob_info(field) else: value = field else: value = unicode(field.value, post_encoding, 'strict') if key in kwargs: _val = kwargs[key] if isinstance(_val, list): _val.append(value) else: kwargs[key] = [_val, value] continue kwargs[key] = value def get_response_headers(): # Figure out the HTTP headers for the response ``cookies``. cookie_output = SimpleCookie() for name, values in ctx._response_cookies.iteritems(): name = str(name) cookie_output[name] = values.pop('value') cur = cookie_output[name] for key, value in values.items(): if key == 'max_age': key = 'max-age' if key not in COOKIE_KEY_NAMES: continue cur[key] = value if cookie_output: raw_headers = ctx._raw_headers + [ ('Set-Cookie', ck.split(' ', 1)[-1]) for ck in str(cookie_output).split('\r\n') ] else: raw_headers = ctx._raw_headers str_headers = [] new_header = str_headers.append for k, v in raw_headers: if isinstance(k, unicode): k = k.encode('utf-8') if isinstance(v, unicode): v = v.encode('utf-8') new_header((k, v)) return str_headers if 'submit' in kwargs: del kwargs['submit'] if 'callback' in kwargs: ctx.json_callback = kwargs.pop('callback') if env.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest': ctx.ajax_request = 1 if '__ajax__' in kwargs: ctx.ajax_request = 1 del kwargs['__ajax__'] if config['ssl'] and RUNNING_ON_GOOGLE_SERVERS and not ssl_mode: raise NotFound if config['xsrf']: if 'xsrf' not in kwargs: raise AuthError("XSRF token not present.") provided_xsrf = kwargs.pop('xsrf') if not secure_string_comparison(provided_xsrf, ctx.xsrf_token): raise AuthError("XSRF tokens do not match.") if config['admin'] and not ctx.is_admin: raise NotFound if (not config['anon']) and (not ctx.user_id): if ctx.ajax_request: ctx.response_headers['Content-Type'] = 'application/json' raise HTTPContent( encode_json({ "error": { "type": "AuthError", "redirect": ctx.get_login_url() } })) raise Redirect(ctx.get_login_url()) # Try and respond with the result of calling the handler. content = handler(ctx, *args, **kwargs) for renderer in renderers: if ctx.end_pipeline: break if content is None: content = {'content': ''} elif not isinstance(content, dict): content = {'content': content} if isinstance(renderer, str): content = ctx.render_mako_template(renderer, **content) else: content = renderer(ctx, **content) if content is None: content = '' elif isinstance(content, unicode): content = content.encode('utf-8') raise HTTPContent(content) # Return the content. except HTTPContent, payload: content = payload.content if 'Content-Type' not in ctx.response_headers: ctx.response_headers['Content-Type'] = 'text/html; charset=utf-8' ctx.response_headers['Content-Length'] = str(len(content)) start_response(('%d %s\r\n' % ctx._status), get_response_headers()) if http_method == 'HEAD': return [] return [content]