def attach(self, upload=None, ckCsrfToken=''): Attachments = request.registry['ir.attachment'] res = { "uploaded": 1, "fileName": upload.filename, } try: image_data = upload.read() image = Image.open(cStringIO.StringIO(image_data)) w, h = image.size if w * h > 42e6: # Nokia Lumia 1020 photo resolution raise ValueError( "Image size excessive, uploaded images must be smaller than 42 million pixel" ) if image.format in ('PNG', 'JPEG'): image_data = tools.image_save_for_web(image) attachment_id = Attachments.create( request.cr, request.uid, { 'name': upload.filename, 'datas': image_data.encode('base64'), 'datas_fname': upload.filename, 'res_model': 'ir.ui.view', }, request.context) res['url'] = Attachments.read( request.cr, request.uid, [attachment_id], ['website_url'], context=request.context)[0]['website_url'] except Exception, e: logger.exception("Failed to upload image to attachment") res['error'] = {'message': unicode(e)}
def attach(self, func, upload=None, url=None, disable_optimization=None, **kwargs): # the upload argument doesn't allow us to access the files if more than # one file is uploaded, as upload references the first file # therefore we have to recover the files from the request object Attachments = request.registry[ 'ir.attachment'] # registry for the attachment table uploads = [] message = None if not upload: # no image provided, storing the link and the image name name = url.split("/").pop() # recover filename attachment_id = Attachments.create( request.cr, request.uid, { 'name': name, 'type': 'url', 'url': url, 'public': True, 'res_model': 'ir.ui.view', }, request.context) uploads += Attachments.read( request.cr, request.uid, [attachment_id], ['name', 'mimetype', 'checksum', 'url'], request.context) else: # images provided try: attachment_ids = [] for c_file in request.httprequest.files.getlist('upload'): data = c_file.read() try: image = Image.open(cStringIO.StringIO(data)) w, h = image.size if w * h > 42e6: # Nokia Lumia 1020 photo resolution raise ValueError( u"Image size excessive, uploaded images must be smaller " u"than 42 million pixel") if not disable_optimization and image.format in ( 'PNG', 'JPEG'): data = tools.image_save_for_web(image) except IOError, e: pass attachment_id = Attachments.create( request.cr, request.uid, { 'name': c_file.filename, 'datas': data.encode('base64'), 'datas_fname': c_file.filename, 'public': True, 'res_model': 'ir.ui.view', }, request.context) attachment_ids.append(attachment_id) uploads += Attachments.read( request.cr, request.uid, attachment_ids, ['name', 'mimetype', 'checksum', 'url'], request.context) except Exception, e: logger.exception("Failed to upload image to attachment") message = unicode(e)
def attach(self, func, upload=None, url=None, disable_optimization=None, **kwargs): # the upload argument doesn't allow us to access the files if more than # one file is uploaded, as upload references the first file # therefore we have to recover the files from the request object Attachments = request.registry["ir.attachment"] # registry for the attachment table uploads = [] message = None if not upload: # no image provided, storing the link and the image name name = url.split("/").pop() # recover filename attachment_id = Attachments.create( request.cr, request.uid, {"name": name, "type": "url", "url": url, "public": True, "res_model": "ir.ui.view"}, request.context, ) uploads += Attachments.read( request.cr, request.uid, [attachment_id], ["name", "mimetype", "checksum", "url"], request.context ) else: # images provided try: attachment_ids = [] for c_file in request.httprequest.files.getlist("upload"): data = c_file.read() try: image = Image.open(cStringIO.StringIO(data)) w, h = image.size if w * h > 42e6: # Nokia Lumia 1020 photo resolution raise ValueError( u"Image size excessive, uploaded images must be smaller " u"than 42 million pixel" ) if not disable_optimization and image.format in ("PNG", "JPEG"): data = tools.image_save_for_web(image) except IOError, e: pass attachment_id = Attachments.create( request.cr, request.uid, { "name": c_file.filename, "datas": data.encode("base64"), "datas_fname": c_file.filename, "public": True, "res_model": "ir.ui.view", }, request.context, ) attachment_ids.append(attachment_id) uploads += Attachments.read( request.cr, request.uid, attachment_ids, ["name", "mimetype", "checksum", "url"], request.context ) except Exception, e: logger.exception("Failed to upload image to attachment") message = unicode(e)
def attach(self, func, upload=None, url=None, disable_optimization=None): Attachments = request.registry['ir.attachment'] website_url = message = None if not upload: website_url = url name = url.split("/").pop() attachment_id = Attachments.create( request.cr, request.uid, { 'name': name, 'type': 'url', 'url': url, 'res_model': 'ir.ui.view', }, request.context) else: try: image_data = upload.read() image = Image.open(io.StringIO(image_data)) w, h = image.size if w * h > 42e6: # Nokia Lumia 1020 photo resolution raise ValueError( "Image size excessive, uploaded images must be smaller " "than 42 million pixel") if not disable_optimization and image.format in ('PNG', 'JPEG'): image_data = image_save_for_web(image) attachment_id = Attachments.create( request.cr, request.uid, { 'name': upload.filename, 'datas': image_data.encode('base64'), 'datas_fname': upload.filename, 'res_model': 'ir.ui.view', }, request.context) [attachment] = Attachments.read(request.cr, request.uid, [attachment_id], ['website_url'], context=request.context) website_url = attachment['website_url'] except Exception as e: logger.exception("Failed to upload image to attachment") message = str(e) return """<script type='text/javascript'> window.parent['%s'](%s, %s); </script>""" % (func, json.dumps(website_url), json.dumps(message))
def attach(self, func, upload=None, url=None, disable_optimization=None): # the upload argument doesn't allow us to access the files if more than # one file is uploaded, as upload references the first file # therefore we have to recover the files from the request object Attachments = request.registry['ir.attachment'] # registry for the attachment table uploads = [] message = None if not upload: # no image provided, storing the link and the image name uploads.append({'website_url': url}) name = url.split("/").pop() # recover filename attachment_id = Attachments.create(request.cr, request.uid, { 'name':name, 'type': 'url', 'url': url, 'res_model': 'ir.ui.view', }, request.context) else: # images provided try: attachment_ids = [] for c_file in request.httprequest.files.getlist('upload'): image_data = c_file.read() image = Image.open(cStringIO.StringIO(image_data)) w, h = image.size if w*h > 42e6: # Nokia Lumia 1020 photo resolution raise ValueError( u"Image size excessive, uploaded images must be smaller " u"than 42 million pixel") if not disable_optimization and image.format in ('PNG', 'JPEG'): image_data = image_save_for_web(image) attachment_id = Attachments.create(request.cr, request.uid, { 'name': c_file.filename, 'datas': image_data.encode('base64'), 'datas_fname': c_file.filename, 'res_model': 'ir.ui.view', }, request.context) attachment_ids.append(attachment_id) uploads = Attachments.read( request.cr, request.uid, attachment_ids, ['website_url'], context=request.context) except Exception, e: logger.exception("Failed to upload image to attachment") message = unicode(e)
def attach(self, func, upload=None, url=None, disable_optimization=None): Attachments = request.registry['ir.attachment'] website_url = message = None if not upload: website_url = url name = url.split("/").pop() attachment_id = Attachments.create(request.cr, request.uid, { 'name': name, 'type': 'url', 'url': url, 'res_model': 'ir.ui.view', }, request.context) else: try: image_data = upload.read() image = Image.open(cStringIO.StringIO(image_data)) w, h = image.size # ---Add by surekha technologies------------ # to allow user to upload image of any size....... ''' if w*h > 42e6: # Nokia Lumia 1020 photo resolution raise ValueError( u"Image size excessive, uploaded images must be smaller " u"than 42 million pixel") ''' if not disable_optimization and image.format in ('PNG', 'JPEG'): image_data = image_save_for_web(image) attachment_id = Attachments.create(request.cr, request.uid, { 'name': upload.filename, 'datas': image_data.encode('base64'), 'datas_fname': upload.filename, 'res_model': 'ir.ui.view', }, request.context) [attachment] = Attachments.read( request.cr, request.uid, [attachment_id], ['website_url'], context=request.context) website_url = attachment['website_url'] except Exception, e: #logger.exception("Failed to upload image to attachment") message = unicode(e)
def _image(self, cr, uid, model, id, field, response, max_width=maxint, max_height=maxint, cache=None, context=None): """ Fetches the requested field and ensures it does not go above (max_width, max_height), resizing it if necessary. Resizing is bypassed if the object provides a $field_big, which will be interpreted as a pre-resized version of the base field. If the record is not found or does not have the requested field, returns a placeholder image via :meth:`~._image_placeholder`. Sets and checks conditional response parameters: * :mailheader:`ETag` is always set (and checked) * :mailheader:`Last-Modified is set iif the record has a concurrency field (``__last_update``) The requested field is assumed to be base64-encoded image data in all cases. """ Model = self.pool[model] id = int(id) ids = Model.search(cr, uid, [('id', '=', id)], context=context) if not ids and 'website_published' in Model._fields: ids = Model.search(cr, openerp.SUPERUSER_ID, [('id', '=', id), ('website_published', '=', True)], context=context) if not ids: return self._image_placeholder(response) concurrency = '__last_update' [record] = Model.read(cr, openerp.SUPERUSER_ID, [id], [concurrency, field], context=context) if concurrency in record: server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT try: response.last_modified = datetime.datetime.strptime( record[concurrency], server_format + '.%f') except ValueError: # just in case we have a timestamp without microseconds response.last_modified = datetime.datetime.strptime( record[concurrency], server_format) # Field does not exist on model or field set to False if not record.get(field): # FIXME: maybe a field which does not exist should be a 404? return self._image_placeholder(response) response.set_etag(hashlib.sha1(record[field]).hexdigest()) response.make_conditional(request.httprequest) if cache: response.cache_control.max_age = cache response.expires = int(time.time() + cache) # conditional request match if response.status_code == 304: return response data = record[field].decode('base64') image = Image.open(cStringIO.StringIO(data)) response.mimetype = Image.MIME[image.format] filename = '%s_%s.%s' % (model.replace('.', '_'), id, str(image.format).lower()) response.headers['Content-Disposition'] = 'inline; filename="%s"' % filename if (not max_width) and (not max_height): response.data = data return response w, h = image.size max_w = int(max_width) if max_width else maxint max_h = int(max_height) if max_height else maxint if w < max_w and h < max_h: response.data = data else: size = (max_w, max_h) img = image_resize_and_sharpen(image, size, preserve_aspect_ratio=True) image_save_for_web(img, response.stream, format=image.format) # invalidate content-length computed by make_conditional as # writing to response.stream does not do it (as of werkzeug 0.9.3) del response.headers['Content-Length'] return response
def _image(self, cr, uid, model, id, field, response, max_width=maxint, max_height=maxint, cache=None, context=None): """ Fetches the requested field and ensures it does not go above (max_width, max_height), resizing it if necessary. Resizing is bypassed if the object provides a $field_big, which will be interpreted as a pre-resized version of the base field. If the record is not found or does not have the requested field, returns a placeholder image via :meth:`~._image_placeholder`. Sets and checks conditional response parameters: * :mailheader:`ETag` is always set (and checked) * :mailheader:`Last-Modified is set iif the record has a concurrency field (``__last_update``) The requested field is assumed to be base64-encoded image data in all cases. """ Model = self.pool[model] id = int(id) ids = Model.search(cr, uid, [('id', '=', id)], context=context) if not ids and 'website_published' in Model._fields: ids = Model.search(cr, openerp.SUPERUSER_ID, [('id', '=', id), ('website_published', '=', True)], context=context) if not ids: return self._image_placeholder(response) concurrency = '__last_update' [record] = Model.read(cr, openerp.SUPERUSER_ID, [id], [concurrency, field], context=context) if concurrency in record: server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT try: response.last_modified = datetime.datetime.strptime( record[concurrency], server_format + '.%f') except ValueError: # just in case we have a timestamp without microseconds response.last_modified = datetime.datetime.strptime( record[concurrency], server_format) # Field does not exist on model or field set to False if not record.get(field): # FIXME: maybe a field which does not exist should be a 404? return self._image_placeholder(response) response.set_etag(hashlib.sha1(record[field]).hexdigest()) response.make_conditional(request.httprequest) if cache: response.cache_control.max_age = cache response.expires = int(time.time() + cache) # conditional request match if response.status_code == 304: return response if model == 'ir.attachment' and field == 'url' and field in record: path = record[field].strip('/') # Check that we serve a file from within the module if os.path.normpath(path).startswith('..'): return self._image_placeholder(response) # Check that the file actually exists path = path.split('/') resource = openerp.modules.get_module_resource(*path) if not resource: return self._image_placeholder(response) data = open(resource, 'rb').read() else: data = record[field].decode('base64') image = Image.open(cStringIO.StringIO(data)) response.mimetype = Image.MIME[image.format] filename = '%s_%s.%s' % (model.replace('.', '_'), id, str( image.format).lower()) response.headers[ 'Content-Disposition'] = 'inline; filename="%s"' % filename if (not max_width) and (not max_height): response.data = data return response w, h = image.size max_w = int(max_width) if max_width else maxint max_h = int(max_height) if max_height else maxint if w < max_w and h < max_h: response.data = data else: size = (max_w, max_h) img = image_resize_and_sharpen(image, size, preserve_aspect_ratio=True) image_save_for_web(img, response.stream, format=image.format) # invalidate content-length computed by make_conditional as # writing to response.stream does not do it (as of werkzeug 0.9.3) del response.headers['Content-Length'] return response
def attach(self, func, upload=None, url=None, disable_optimization=None, **kwargs): # the upload argument doesn't allow us to access the files if more than # one file is uploaded, as upload references the first file # therefore we have to recover the files from the request object Attachments = request.registry['ir.attachment'] # registry for the attachment table uploads = [] message = None if not upload: # no image provided, storing the link and the image name name = url.split("/").pop() # recover filename attachment_id = Attachments.create(request.cr, request.uid, { 'name': name, 'type': 'url', 'url': url, 'public': True, 'res_model': 'ir.ui.view', }, request.context) uploads += Attachments.read(request.cr, request.uid, [attachment_id], ['name', 'mimetype', 'checksum', 'url'], request.context) else: # images provided try: attachment_ids = [] for c_file in request.httprequest.files.getlist('upload'): pngtype = c_file.filename.split('.')[1] if pngtype in ['png','jpg', u'png', u'jpg', 'JPEG', u'JPEG']: url, read_data = self.imageUploadS3(c_file) exit_args = [('url', '=', str(url))] exit_ids = Attachments.search(request.cr, request.uid, exit_args) if not exit_ids: len_data = base64.encodestring(read_data) file_size = len(len_data.decode('base64')) attachment_id = Attachments.create(request.cr, request.uid, { 'name': c_file.filename, # 'datas': read_data.encode('base64'), 'datas_fname': c_file.filename, 'public': True, 'res_model': 'ir.ui.view', 's3_file_size': file_size, 'type': 'url', 'url': url, 's3target': 's3', }, request.context) attachment_ids.append(attachment_id) else: attachment_ids += exit_ids else: data = c_file.read() try: image = Image.open(cStringIO.StringIO(data)) w, h = image.size if w*h > 42e6: # Nokia Lumia 1020 photo resolution raise ValueError( u"Image size excessive, uploaded images must be smaller " u"than 42 million pixel") if not disable_optimization and image.format in ('PNG', 'JPEG'): data = tools.image_save_for_web(image) except IOError, e: pass attachment_id = Attachments.create(request.cr, request.uid, { 'name': c_file.filename, 'datas': data.encode('base64'), 'datas_fname': c_file.filename, 'public': True, 'res_model': 'ir.ui.view', }, request.context) attachment_ids.append(attachment_id) uploads += Attachments.read(request.cr, request.uid, attachment_ids, ['name', 'mimetype', 'checksum', 'url'], request.context) except Exception, e: _logger.exception("Failed to upload image to attachment") message = unicode(e)
def _image( self, cr, uid, model, id_or_ids, field, response, max_width=maxint, max_height=maxint, cache=None, context=None ): """ Fetches the requested field and ensures it does not go above (max_width, max_height), resizing it if necessary. Resizing is bypassed if the object provides a $field_big, which will be interpreted as a pre-resized version of the base field. If the record is not found or does not have the requested field, returns a placeholder image via :meth:`~._image_placeholder`. Sets and checks conditional response parameters: * :mailheader:`ETag` is always set (and checked) * :mailheader:`Last-Modified is set iif the record has a concurrency field (``__last_update``) The requested field is assumed to be base64-encoded image data in all cases. """ Model = self.pool[model] ids = isinstance(id_or_ids, (list, tuple)) and id_or_ids or [int(id_or_ids)] ids = Model.search(cr, uid, [("id", "in", ids)], context=context) if not ids: return self._image_placeholder(response) concurrency = "__last_update" [record] = Model.read(cr, openerp.SUPERUSER_ID, ids, [concurrency, field], context=context) if concurrency in record: server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT try: response.last_modified = datetime.datetime.strptime(record[concurrency], server_format + ".%f") except ValueError: # just in case we have a timestamp without microseconds response.last_modified = datetime.datetime.strptime(record[concurrency], server_format) # Field does not exist on model or field set to False if not record.get(field): # FIXME: maybe a field which does not exist should be a 404? return self._image_placeholder(response) response.set_etag(hashlib.sha1(record[field]).hexdigest()) response.make_conditional(request.httprequest) if cache: response.cache_control.max_age = cache response.expires = int(time.time() + cache) # conditional request match if response.status_code == 304: return response if model == "ir.attachment" and field == "url" and field in record: path = record[field].strip("/") # Check that we serve a file from within the module if os.path.normpath(path).startswith(".."): return self._image_placeholder(response) # Check that the file actually exists path = path.split("/") resource = openerp.modules.get_module_resource(*path) if not resource: return self._image_placeholder(response) data = open(resource, "rb").read() else: data = record[field].decode("base64") image = Image.open(cStringIO.StringIO(data)) response.mimetype = Image.MIME[image.format] filename = "%s_%s.%s" % (model.replace(".", "_"), ids[0], str(image.format).lower()) response.headers["Content-Disposition"] = 'inline; filename="%s"' % filename if (not max_width) and (not max_height): response.data = data return response w, h = image.size max_w = int(max_width) if max_width else maxint max_h = int(max_height) if max_height else maxint if w < max_w and h < max_h: response.data = data else: size = (max_w, max_h) img = image_resize_and_sharpen(image, size, preserve_aspect_ratio=True) image_save_for_web(img, response.stream, format=image.format) # invalidate content-length computed by make_conditional as # writing to response.stream does not do it (as of werkzeug 0.9.3) del response.headers["Content-Length"] return response