Ejemplo n.º 1
0
 def __call__(self, value, size=1048576, allowed_types=None, forbidden_types=None):
     if not value:
         return False
     if not INamed.providedBy(value):
         return False
     if size and value.getSize() > size:
         return _(
             "msg_file_too_big",
             mapping={"size": size},
             default=u"File is bigger than allowed size of ${size} bytes!",
         )
     ftype = splitext(value.filename)[-1]
     # remove leading dot '.' from file extension
     ftype = ftype and ftype[1:].lower() or ""
     if allowed_types and ftype not in allowed_types:
         return _(
             "msg_file_not_allowed",
             mapping={"ftype": ftype.upper()},
             default=u'File type "${ftype}" is not allowed!',
         )
     if forbidden_types and ftype in forbidden_types:
         return _(
             "msg_file_not_allowed",
             mapping={"ftype": ftype.upper()},
             default=u'File type "${ftype}" is not allowed!',
         )
     return False
Ejemplo n.º 2
0
    def toFieldValue(self, value):

        if value is None or value == '':
            return self.field.missing_value

        if INamed.providedBy(value):
            return value

        elif utils.is_file_upload(value):

            filename = safe_basename(value.filename)

            if filename is not None and isinstance(filename, six.binary_type):
                # Work-around for
                # https://bugs.launchpad.net/zope2/+bug/499696
                filename = filename.decode('utf-8')

            value.seek(0)
            data = value.read()
            if data or filename:
                return self.field._type(data=data, filename=filename)
            else:
                return self.field.missing_value

        else:
            if isinstance(value, six.text_type):
                value = value.encode('utf-8')
            return self.field._type(data=value)
Ejemplo n.º 3
0
    def toFieldValue(self, value):

        if value is None or value == '':
            return self.field.missing_value

        if INamed.providedBy(value):
            return value
        elif isinstance(value, FileUpload):

            filename = safe_basename(value.filename)

            if filename is not None and not isinstance(filename, unicode):
                # Work-around for
                # https://bugs.launchpad.net/zope2/+bug/499696
                filename = filename.decode('utf-8')

            value.seek(0)
            data = value.read()
            if data or filename:
                return self.field._type(data=data, filename=filename)
            else:
                return self.field.missing_value

        else:
            return self.field._type(data=str(value))
Ejemplo n.º 4
0
 def file_size(self, file_):
     """Returns the file-size of the `file_` in KB.
     """
     if INamed.providedBy(file_):
         return file_.getSize() / 1024
     else:
         return 0
Ejemplo n.º 5
0
 def filename(self):
     if INamed.providedBy(self.value):
         return self.value.filename
     elif utils.is_file_upload(self.value):
         return safe_basename(self.value.filename)
     else:
         return None
Ejemplo n.º 6
0
def _make_namedfile(value, field, widget):
    """Return a NamedImage or NamedFile instance, if it isn't already one -
    e.g. when it's base64 encoded data.
    """

    if INamed.providedBy(value):
        return value

    string_types = (six.binary_type, six.text_type)
    if isinstance(value, string_types) and IBytes.providedBy(field):
        filename, data = b64decode_file(value)
    elif isinstance(value, dict) or isinstance(value, PersistentDict):
        filename = value['filename']
        data = value['data']

    if INamedBlobImageField.providedBy(field):
        value = NamedBlobImage(data=data, filename=filename)
    elif INamedImageField.providedBy(field):
        value = NamedImage(data=data, filename=filename)
    elif INamedBlobFileField.providedBy(field):
        value = NamedBlobFile(data=data, filename=filename)
    else:
        value = NamedFile(data=data, filename=filename)

    return value
Ejemplo n.º 7
0
    def toFieldValue(self, value):
        
        if value is None or value == '':
            return self.field.missing_value

        if INamed.providedBy(value):
            return value
        elif isinstance(value, FileUpload):
            
            headers = value.headers
            filename = safe_basename(value.filename)
            
            if filename is not None and not isinstance(filename, unicode):
                # Work-around for
                # https://bugs.launchpad.net/zope2/+bug/499696
                filename = filename.decode('utf-8')
            
            contentType = 'application/octet-stream'
            if headers:
                contentType = headers.get('Content-Type', contentType)
            
            value.seek(0)
            data = value.read()
            if data or filename:
                return self.field._type(data=data, contentType=contentType, filename=filename)
            else:
                return self.field.missing_value
        
        else:
            return self.field._type(data=str(value))
Ejemplo n.º 8
0
    def toFieldValue(self, value):

        if value is None or value == '':
            return self.field.missing_value

        if INamed.providedBy(value):
            return value
        elif isinstance(value, FileUpload):

            filename = safe_basename(value.filename)

            if filename is not None and not isinstance(filename, unicode):
                # Work-around for
                # https://bugs.launchpad.net/zope2/+bug/499696
                filename = filename.decode('utf-8')

            value.seek(0)
            data = value.read()
            if data or filename:
                return self.field._type(data=data, filename=filename)
            else:
                return self.field.missing_value

        else:
            return self.field._type(data=str(value))
Ejemplo n.º 9
0
 def file_size(self, file_):
     """Returns the file-size of the `file_` in KB.
     """
     if INamed.providedBy(file_):
         return file_.getSize() / 1024
     else:
         return 0
Ejemplo n.º 10
0
 def __call__(self, value, size=1048576, allowed_types=None,
              forbidden_types=None):
     if not value:
         return False
     if not INamed.providedBy(value):
         return False
     if size and value.getSize() > size:
         return _(
             'msg_file_too_big',
             mapping={'size': size},
             default=u'File is bigger than allowed size of ${size} bytes!'
         )
     ftype = splitext(value.filename)[-1]
     # remove leading dot '.' from file extension
     ftype = ftype and ftype[1:].lower() or ''
     if allowed_types and ftype not in allowed_types:
         return _(
             'msg_file_not_allowed',
             mapping={'ftype': ftype.upper()},
             default=u'File type "${ftype}" is not allowed!'
         )
     if forbidden_types and ftype in forbidden_types:
         return _(
             'msg_file_not_allowed',
             mapping={'ftype': ftype.upper()},
             default=u'File type "${ftype}" is not allowed!'
         )
     return False
Ejemplo n.º 11
0
 def filename(self):
     if self.field is not None and self.value == self.field.missing_value:
         return None
     elif INamed.providedBy(self.value):
         return self.value.filename
     elif isinstance(self.value, FileUpload):
         return safe_basename(self.value.filename)
     else:
         return None
Ejemplo n.º 12
0
 def filename(self):
     if self.field is not None and self.value == self.field.missing_value:
         return None
     elif INamed.providedBy(self.value):
         return self.value.filename
     elif isinstance(self.value, FileUpload):
         return safe_basename(self.value.filename)
     else:
         return None
    def _toFieldSubValue(self, value, current_field_value):
        """
        Converts a subvalue to an `INamedFile`.

        Parameters:
        value -- The value extracted from the request by the widget.
        current_field_value -- The current value of the field on the context.

        Return:
        a value of the fields value_type or it's `missing_value` if the value cannot be converted.

        See plone.formwidget.namedfile.converter.NamedDataConverter
        """

        value_type = self.field.value_type._type
        missing_value = self.field.value_type.missing_value

        if value is None or value == '':
            return missing_value
        elif INamed.providedBy(value):
            return value
        elif isinstance(value, basestring) and value.startswith('index:'):
            # we already have the file
            index = int(value.split(':')[1])
            try:
                return current_field_value[index]
            except IndexError:
                return missing_value
        elif isinstance(value, FileUpload):
            # create a new file

            headers = value.headers
            filename = safe_basename(value.filename)
            if filename is not None and not isinstance(filename, unicode):
                # Work-around for
                # https://bugs.launchpad.net/zope2/+bug/499696
                filename = filename.decode('utf-8')

            contentType = 'application/octet-stream'
            if headers:
                contentType = headers.get('Content-Type', contentType)

            value.seek(0)
            data = value.read()
            if data or filename:
                return value_type(data=data, contentType=contentType, filename=filename)
            else:
                return missing_value

        else:
            return value_type(data=str(value))
Ejemplo n.º 14
0
    def file_upload_id(self):
        """Temporary store the uploaded file contents with a file_upload_id key.
        In case of form validation errors the already uploaded image can then
        be reused.

        This is only useful on a POST request:
        forms should not be using GET,
        especially when you save something to the database.

        Note that if we want this on a GET request,
        we should add a safeWrite call in the code below:
        plone.protect.utils.safeWrite(up.upload_map, self.request)
        Otherwise plone.protect auto csrf will complain for example
        when getting @@site-controlpanel or @@personal-information
        See https://github.com/plone/Products.CMFPlone/issues/2628
        and https://github.com/plone/Products.CMFPlone/issues/2709
        """
        if self.request.method != 'POST':
            return ''
        if self._file_upload_id:
            # cache this property for multiple calls within one request.
            # This avoids storing a file upload multiple times.
            return self._file_upload_id

        upload_id = None
        if self.is_uploaded:
            data = None
            if INamed.providedBy(self.value):
                # previously uploaded and failed
                data = self.value.data
            else:
                self.value.seek(0)
                data = self.value.read()

            upload_id = uuid.uuid4().hex
            up = IFileUploadTemporaryStorage(getSite())
            up.cleanup()
            up.upload_map[upload_id] = PersistentDict(
                filename=self.value.filename,
                data=data,
                dt=datetime.now(),
            )

        self._file_upload_id = upload_id
        return upload_id
Ejemplo n.º 15
0
    def toFieldValue(self, value):

        filename = None
        data = None

        if INamed.providedBy(value):
            filename = value.filename
            data = value.data

        elif isinstance(value, FileUpload):
            filename = safe_basename(value.filename)
            value.seek(0)
            data = value.read()

        if not data:
            return self.field.missing_value

        return b64encode_file(filename, data)
Ejemplo n.º 16
0
    def toFieldValue(self, value):

        filename = None
        data = None

        if INamed.providedBy(value):
            filename = value.filename
            data = value.data

        elif isinstance(value, FileUpload):
            filename = safe_basename(value.filename)
            value.seek(0)
            data = value.read()

        if not data:
            return self.field.missing_value

        return b64encode_file(filename, data)
Ejemplo n.º 17
0
    def get_export_data(
        self,
        portal_type,
        blob_format,
        richtext_format,
        blacklist,
        whitelist,
        query,
    ):
        """Return a list of dicts with a dict for each object.

        The key is the name of the field/value and the value the value.
        """
        all_fields = get_schema_info(portal_type, blacklist, whitelist)

        results = []
        catalog = api.portal.get_tool('portal_catalog')
        if not query:
            query = dict()
        query['portal_type'] = portal_type
        if 'Language' not in query and HAS_MULTILINGUAL and \
                'Language' in catalog.indexes():
            query['Language'] = 'all'

        brains = catalog.unrestrictedSearchResults(query)
        for brain in brains:
            obj = brain.getObject()
            item_dict = dict()

            for fieldname, field in all_fields:
                if fieldname in self.ADDITIONAL_MAPPING:
                    # The way to access the value from this fields is
                    # overridden in ADDITIONAL_MAPPING
                    continue

                try:
                    value = field.get(field.interface(obj))
                except:
                    print("Skipping object at {0}".format(obj.absolute_url()))
                    break

                if not value:
                    # set a value anyway to keep the dimensions of all
                    value = ''
                    # make sure we do no more transforms
                    field = None

                if IRichTextValue.providedBy(value):
                    value = transform_richtext(value, mimetype=richtext_format)

                if IRelationList.providedBy(field):
                    rel_val = []
                    for relation in value:
                        rel_val.append(get_url_for_relation(relation))
                    value = pretty_join(rel_val)

                if IRelationChoice.providedBy(field):
                    value = get_url_for_relation(value)

                if INamed.providedBy(value):
                    value = get_blob_url(value, brain, blob_format, fieldname)

                if ICollection.providedBy(field):
                    r = []
                    for v in value:
                        if INamed.providedBy(v):
                            r.append(u'{0}/@@download/{1}'.format(
                                obj.absolute_url(), fieldname))
                            # r.append(base64.b64encode(v.data))
                        else:
                            r.append(v)
                    value = r

                if IDatetime.providedBy(field) or IDate.providedBy(field):
                    if value.year < 1000:
                        if value.year < 16:
                            year = value.year + 2000
                        else:
                            year = value.year + 1900
                        if IDate.providedBy(field):
                            value = datetime.date(month=value.month,
                                                  day=value.day,
                                                  year=year)
                        elif IDatetime.providedBy(field):
                            value = datetime.datetime(month=value.month,
                                                      day=value.day,
                                                      year=year,
                                                      hour=value.hour,
                                                      minute=value.minute,
                                                      second=value.second)
                    value = api.portal.get_localized_time(value,
                                                          long_format=True)

                if safe_callable(value):
                    value = value()

                if isinstance(value, list) or isinstance(value, tuple):
                    value = pretty_join(value)

                item_dict[fieldname] = value
            else:
                # Update the data with additional info or overridden getters
                item_dict.update(self.additional_data(obj, blacklist))

                results.append(item_dict)
                continue  # executed if the loop ended normally (no break)
            break  # executed if 'continue' was skipped (break)
        return results
Ejemplo n.º 18
0
 def file_size(self):
     if INamed.providedBy(self.value):
         return self.value.getSize() / 1024
     else:
         return 0
Ejemplo n.º 19
0
    def _render_obj(self, obj, new_req=None):
        """
        Render object to string.
        """
        if isinstance(obj, basestring):
            return obj
        if new_req is None:
            new_req = self.request

        try:
            if IResource.providedBy(obj):
                try:
                    f = open(obj.context.path)
                    result = f.read()
                    f.close()
                except AttributeError:
                    result = obj.context.data
                except IOError:
                    log.error("Couldn't open '%s' file with resource" % (
                        obj.context.path))
                    return None

                return result

            if isinstance(obj, (BrowserView, FSPageTemplate, PythonScript)):
                try:
                    return obj()
                except NotFound:
                    log.error("Resource '%s' not found" % repr(obj))
                    return None
            if isinstance(obj, (FSFile, FSImage)):
                return self._render_obj(obj._readFile(None))

            if isinstance(obj, FSDTMLMethod):
                return self._render_obj(obj.read())

            mt = None
            try:
                mt = obj.aq_base.portal_type
            except AttributeError:
                pass

            if mt in self.file_types or isinstance(obj,
                    (ImageField, OFSImage, Pdata, File)):
                return self._render_obj(obj.data)

            if PLONE_RESOURCE_INSTALLED and isinstance(obj, FilesystemFile):
                if not obj.request:
                    obj.request = new_req
                    return obj().read()

            if PLONE_APP_BLOB_INSTALLED and IBlobWrapper.providedBy(obj):
                return obj.data

            if PLONE_NAMEDFILE_INSTALLED and \
                INamed.providedBy(obj):
                return obj.data

            if IBaseObject.providedBy(obj) or isinstance(obj, PloneSite) or \
                DEXTERITY_INSTALLED and IDexterityContent.providedBy(obj):
                default_page_helper = getMultiAdapter((obj, self.request),
                        name='default_page')
                def_page_id = default_page_helper.getDefaultPage()
                if def_page_id:
                    def_page = obj[def_page_id]
                    return self._render_obj(def_page)

                view_name = obj.getLayout()
                view = queryMultiAdapter((obj, new_req), name=view_name)
                if view_name == 'language-switcher':
                    lang = new_req.get('LANGUAGE')
                    def_page = getattr(obj, lang, None)
                    if def_page:
                        return self._render_obj(def_page)
                if view:
                    try:
                        return view.context()
                    except (ContentProviderLookupError, TypeError):
                        pass

                view = obj.restrictedTraverse(view_name, None)
                if view:
                    try:
                        return view.context()
                    except (AttributeError, TypeError):
                        try:
                            return view()
                        except Exception, error:
                            log.warning(
                                "Unable to render view: '%s'! Error occurred: %s" % (
                                    view, error))
                else:
                    try:
                        return obj()
                    except AttributeError:
                        pass

        finally:
            pass

        log.warning("Not recognized object '%s'!" % repr(obj))
        return None
Ejemplo n.º 20
0
 def file_size(self):
     if INamed.providedBy(self.value):
         return byteDisplay(self.value.getSize())
     else:
         return "0 KB"
Ejemplo n.º 21
0
 def file_size(self):
     if INamed.providedBy(self.value):
         return byteDisplay(self.value.getSize())
     else:
         return "0 KB"
def export_file(result, header_mapping, request=None):
    if not result:
        return None

    if request is None:
        request = getRequest()

    transforms = api.portal.get_tool('portal_transforms')
    catalog = api.portal.get_tool("portal_catalog")

    data = []
    for row in result:
        items_dict = dict()
        if getattr(row, 'getObject', None):
            obj = row.getObject()
        else:
            obj = row
        for d in header_mapping:
            fieldid = d['field']
            if obj is None:
                items_dict[d['header']] = row(fieldid)
                continue
            if fieldid == '_path':
                path = obj.getPhysicalPath()
                virtual_path = request.physicalPathToVirtualPath(path)
                items_dict[d['header']] = (
                    '/'.join(virtual_path)).decode('utf-8')
                continue
            elif fieldid == '_url':
                items_dict[d['header']] = (obj.absolute_url()).decode('utf-8')
                continue

            value = ""
            for schemata in iterSchemata(obj):
                if fieldid not in schemata:
                    continue
                field = schemata[fieldid]

                try:
                    value = field.get(schemata(obj))
                except AttributeError:
                    continue
                if value is field.missing_value:
                    continue
                if IRichTextValue.providedBy(value):
                    # Convert to plain text
                    value = transforms.convertTo(target_mimetype='text/plain',
                                                 orig=value.raw_encoded,
                                                 encoding=value.encoding,
                                                 mimetype=value.mimeType)
                    value = safe_unicode(value.getData())
                    break

                if IList.providedBy(field):
                    # Check if items in list point to objects and use titles
                    # instead
                    names = []
                    for item_id in value:
                        # Loop through choices
                        query = dict(id=item_id)
                        results = catalog(**query)
                        if results:
                            names.append(results[0].Title)
                    if names:
                        value = names
                    value = ', '.join(value)
                    break

                if INamed.providedBy(value):
                    # Image, file field
                    value = u'{0}/@@download/{1}'.format(row.getURL(), fieldid)
                    break

                serializer = ISerializer(field)
                value = serializer(value, {})
                break

            # Added due to an ascii error related to csv export. We convert to
            # unicode as unicodecsv requires unicode
            value = safe_unicode(value)

            items_dict[d['header']] = value

        data.append(items_dict)

    dataset = tablib.Dataset()
    dataset.dict = data

    return dataset
Ejemplo n.º 23
0
 def is_uploaded(self):
     return utils.is_file_upload(self.value)\
         or INamed.providedBy(self.value)
Ejemplo n.º 24
0
 def file_size(self):
     if INamed.providedBy(self.value):
         return self.value.getSize() / 1024
     else:
         return 0
Ejemplo n.º 25
0
    def get_export_data(
        self,
        portal_type,
        blob_format,
        richtext_format,
        blacklist,
        whitelist,
        query,
    ):
        """Return a list of dicts with a dict for each object.

        The key is the name of the field/value and the value the value.
        """
        all_fields = get_schema_info(portal_type, blacklist, whitelist)

        results = []
        catalog = api.portal.get_tool('portal_catalog')
        if not query:
            query = dict()
        query['portal_type'] = portal_type
        if 'Language' not in query and HAS_MULTILINGUAL and \
                'Language' in catalog.indexes():
            query['Language'] = 'all'

        if 'path' not in query:
            query['path'] = {}
            query['path']['query'] = '/'.join(self.context.getPhysicalPath())

        brains = catalog(query)
        for brain in brains:
            obj = brain.getObject()
            item_dict = dict()

            for fieldname, field in all_fields:
                if fieldname in self.ADDITIONAL_MAPPING:
                    # The way to access the value from this fields is
                    # overridden in ADDITIONAL_MAPPING
                    continue

                value = field.get(field.interface(obj))
                if not value:
                    # set a value anyway to keep the dimensions of all
                    value = ''
                    # make sure we do no more transforms
                    field = None

                if IRichTextValue.providedBy(value):
                    value = transform_richtext(value, mimetype=richtext_format)

                if IRelationList.providedBy(field):
                    rel_val = []
                    for relation in value:
                        rel_val.append(get_url_for_relation(relation))
                    value = pretty_join(rel_val)

                if IRelationChoice.providedBy(field):
                    value = get_url_for_relation(value)

                if INamed.providedBy(value):
                    value = get_blob_url(value, brain, blob_format, fieldname)

                if IDatetime.providedBy(field) or IDate.providedBy(field):
                    value = api.portal.get_localized_time(value,
                                                          long_format=True)

                if safe_callable(value):
                    value = value()

                if isinstance(value, list) or isinstance(value, tuple):
                    value = pretty_join(value)

                if HAS_GEOLOCATION and isinstance(value, Geolocation):
                    value = value.__dict__
                item_dict[fieldname] = value

            # Update the data with additional info or overridden getters
            item_dict.update(self.additional_data(obj, blacklist))

            results.append(item_dict)
        return results
Ejemplo n.º 26
0
    def get_export_data(
        self,
        portal_type,
        blob_format,
        richtext_format,
        blacklist,
        whitelist,
        query,
    ):
        """Return a list of dicts with a dict for each object.

        The key is the name of the field/value and the value the value.
        """
        all_fields = get_schema_info(portal_type, blacklist, whitelist)

        results = []
        catalog = api.portal.get_tool('portal_catalog')
        if not query:
            query = dict()
        query['portal_type'] = portal_type
        if 'Language' not in query and HAS_MULTILINGUAL and \
                'Language' in catalog.indexes():
            query['Language'] = 'all'

        brains = catalog(query)
        for brain in brains:
            obj = brain.getObject()
            item_dict = dict()

            for fieldname, field in all_fields:
                if fieldname in self.ADDITIONAL_MAPPING:
                    # The way to access the value from this fields is
                    # overridden in ADDITIONAL_MAPPING
                    continue

                value = field.get(field.interface(obj))
                if not value:
                    # set a value anyway to keep the dimensions of all
                    value = ''
                    # make sure we do no more transforms
                    field = None

                if IRichTextValue.providedBy(value):
                    value = transform_richtext(value, mimetype=richtext_format)

                if IRelationList.providedBy(field):
                    rel_val = []
                    for relation in value:
                        rel_val.append(get_url_for_relation(relation))
                    value = pretty_join(rel_val)

                if IRelationChoice.providedBy(field):
                    value = get_url_for_relation(value)

                if INamed.providedBy(value):
                    value = get_blob_url(value, brain, blob_format, fieldname)

                if IDatetime.providedBy(field) or IDate.providedBy(field):
                    value = api.portal.get_localized_time(
                        value, long_format=True)

                if safe_callable(value):
                    value = value()

                if isinstance(value, list) or isinstance(value, tuple):
                    value = pretty_join(value)

                item_dict[fieldname] = value

            # Update the data with additional info or overridden getters
            item_dict.update(self.additional_data(obj, blacklist))

            results.append(item_dict)
        return results
Ejemplo n.º 27
0
 def file_size(self):
     """file_size."""
     if INamed.providedBy(self.context.file):
         return byteDisplay(self.context.file.getSize())
     return "0 KB"