Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix p5 compatibility #7

Merged
merged 11 commits into from
May 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,3 @@ output.xml
include/
lib/
pip-selfcheck.json
buildout.cfg
13 changes: 6 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@ sudo: false
cache:
pip: true
directories:
- $HOME/buildout-cache
- eggs
env:
# - PLONE_VERSION=4.3.x
- PLONE_VERSION=5.0.x
before_install:
- mkdir -p $HOME/buildout-cache/{eggs,downloads}
- virtualenv .
- bin/pip install --upgrade pip setuptools zc.buildout
- PLONE_VERSION=5.1.x
install:
- sed -ie "s#plone-x.x.x.cfg#plone-$PLONE_VERSION.cfg#" travis.cfg
- bin/buildout -N -t 3 -c travis.cfg
- virtualenv -p `which python` .
- bin/pip install -r requirements.txt
- sed -ie "s#test-5.1.x#test-$PLONE_VERSION#" buildout.cfg
- bin/buildout -N -t 5
script:
- bin/code-analysis
- bin/test
Expand Down
33 changes: 9 additions & 24 deletions base.cfg → buildout.cfg
Original file line number Diff line number Diff line change
@@ -1,34 +1,19 @@
[buildout]
extends=
https://raw.github.com/collective/buildout.plonetest/master/test-5.1.x.cfg
versions.cfg

extensions = mr.developer
parts =
instance
test

package-name = collective.limitfilesizepanel
package-extras = [test]

parts +=
coverage
test-coverage
code-analysis
dependencychecker

develop = .
sources-dir = extras
auto-checkout =

[instance]
recipe = plone.recipe.zope2instance
user = admin:admin
http-address = 8080
eggs =
Plone
Pillow
plone.app.debugtoolbar
collective.limitfilesizepanel[test]

[test]
recipe = zc.recipe.testrunner
eggs = ${instance:eggs}
initialization =
os.environ['TZ'] = 'UTC'
defaults = ['-s', 'collective.limitfilesizepanel', '--auto-color', '--auto-progress']

[coverage]
recipe = zc.recipe.egg
eggs = coverage
Expand Down
11 changes: 11 additions & 0 deletions collective/limitfilesizepanel/browser/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:plone="http://namespaces.plone.org/plone"
xmlns:zcml="http://namespaces.zope.org/zcml"
i18n_domain="collective.limitfilesizepanel">


Expand All @@ -14,6 +15,7 @@
name="limitfilesize-settings"
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
class=".controlpanel.LimitFileSizeControlPanel"
layer="collective.limitfilesizepanel.interfaces.ILimitFileSizePanelLayer"
permission="collective.limitfilesizepanel.LimitFileSizePanel"
/>

Expand All @@ -25,4 +27,13 @@
layer="collective.limitfilesizepanel.interfaces.ILimitFileSizePanelLayer"
allowed_interface=".limitfilesizepanel_view.IHelpersView"
/>

<browser:page
zcml:condition="have plone-5"
name="fileUpload"
for="Products.CMFCore.interfaces._content.IFolderish"
class=".tinymce_upload_p5.FileUpload"
layer="collective.limitfilesizepanel.interfaces.ILimitFileSizePanelLayer"
permission="collective.limitfilesizepanel.LimitFileSizePanel"
/>
</configure>
71 changes: 49 additions & 22 deletions collective/limitfilesizepanel/browser/limitfilesizepanel_view.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
# -*- coding: utf-8 -*-
from AccessControl import getSecurityManager
from Acquisition import aq_base
from collective.limitfilesizepanel import messageFactory as _
from collective.limitfilesizepanel.interfaces import ILimitFileSizePanel
from plone import api
from plone.api.exc import InvalidParameterError
from Products.Five.browser import BrowserView
from zope.interface import implements
from Products.validation.i18n import safe_unicode
from zope.i18n import translate
from zope.interface import implementer
from zope.interface import Interface
from ZPublisher.HTTPRequest import FileUpload

try:
from plone.namedfile.interfaces import INamedBlobImageField
from plone.namedfile.interfaces import INamedBlobFileField
Expand All @@ -24,6 +27,9 @@ def checkSize(uploadfile, maxsize):
def canBypassValidation():
"""Check if the user has bypass permission"""

def newDataOnly():
""" Return if the validation is only for new data """

def get_maxsize(validator, field, **kwargs):
"""
This is the method called from AT validator
Expand All @@ -42,11 +48,18 @@ def get_maxsize_tiny(metatypes):
"""


@implementer(IHelpersView)
class View(BrowserView):
'''
"""
Helper view for file uploads
'''
implements(IHelpersView)
"""

def newDataOnly(self):
"""
"""
return api.portal.get_registry_record(
'new_data_only',
interface=ILimitFileSizePanel)

def check_size_dx(self, uploadfile, maxsize):
""" check the size of given file """
Expand All @@ -56,28 +69,32 @@ def check_size_dx(self, uploadfile, maxsize):
}
if self.canBypassValidation():
return result

new_data_only = api.portal.get_registry_record(
'new_data_only',
interface=ILimitFileSizePanel)

if new_data_only and self.context != api.portal.get():
# we are in edit, and we don't want validate uploaded files.
return result

size = float(uploadfile.getSize())
if (isinstance(uploadfile, FileUpload) or hasattr(aq_base(uploadfile), 'tell')): # NOQA
uploadfile.seek(0, 2) # eof
size = float(uploadfile.tell())
uploadfile.seek(0)
else:
size = float(uploadfile.getSize())
sizeMB = (size / (1024 * 1024))
result['sizeMB'] = sizeMB

if sizeMB > maxsize:
result['valid'] = False
msg = _(
'validation_error',
default=u'Validation failed. Uploaded data is too large:'
u' ${size}MB (max ${max}MB)',
mapping={
'size': safe_unicode('{0:.1f}'.format(sizeMB)),
'max': safe_unicode('{0:.1f}'.format(maxsize))
})
result['error'] = translate(msg, context=self.request)
return result

def check_size(self, uploadfile, maxsize):
""" check the size of given file """
result = {
'maxsize': maxsize,
'valid': True
'valid': True,
}

if self.canBypassValidation():
Expand Down Expand Up @@ -108,14 +125,24 @@ def check_size(self, uploadfile, maxsize):

if sizeMB > maxsize:
result['valid'] = False
msg = _(
'validation_error',
default=u'Validation failed. Uploaded data is too large:'
u' ${size}MB (max ${max}MB)',
mapping={
'size': safe_unicode('{0:.1f}'.format(sizeMB)),
'max': safe_unicode('{0:.1f}'.format(maxsize))
})
result['error'] = translate(msg, context=self.request)
return result

def canBypassValidation(self):
"""Check if the user has bypass permission"""

sm = getSecurityManager()
return sm.checkPermission(
"collective.limitfilesizepanel: Bypass limit size", self.context)
return api.user.has_permission(
'collective.limitfilesizepanel: Bypass limit size',
obj=self.context
)

def _get_type_maxsize(self, field, context):
"""Get portal_type/fieldname pair configuration in the registry"""
Expand Down Expand Up @@ -201,9 +228,9 @@ def get_maxsize(self, validator, **kwargs):
# get original max size
if 'maxsize' in kwargs:
maxsize = kwargs.get('maxsize')
elif hasattr(aq_base(instance), 'getMaxSizeFor'):
elif hasattr(aq_base(instance), 'getMaxSizeFor'): # noqa
maxsize = instance.getMaxSizeFor(field.getName())
elif hasattr(field, 'maxsize'):
elif hasattr(field, 'maxsize'): # noqa
maxsize = field.maxsize
else:
# set to given default value (default defaults to 0)
Expand Down
42 changes: 42 additions & 0 deletions collective/limitfilesizepanel/browser/tinymce_upload_p5.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
from plone import api
from plone.app.content.browser.file import FileUploadView as BaseFileUploadView

import mimetypes


class FileUpload(BaseFileUploadView):
"""
add filesize validation to tinymce file upload view
"""

def __call__(self):
filedata = self.request.form.get('file', None)
if not filedata:
return super(FileUpload, self).__call__()
filename = filedata.filename
content_type = mimetypes.guess_type(filename)[0] or ''
ctr = api.portal.get_tool(name='content_type_registry')
portal_type = ctr.findTypeName(
filename.lower(), content_type, '') or 'File'

helper_view = api.content.get_view(
name='lfsp_helpers_view',
context=self.context,
request=self.context.REQUEST,)

if helper_view.newDataOnly() and '/edit' in self.request.get('HTTP_REFERER'): # noqa
return super(FileUpload, self).__call__()
maxsize = helper_view.get_maxsize_tiny((portal_type,))
if not maxsize:
return super(FileUpload, self).__call__()

size_check = helper_view.check_size_dx(
maxsize=maxsize,
uploadfile=filedata
)
if size_check and not size_check.get('valid', False):
response = self.request.RESPONSE
response.setStatus(403)
return size_check.get('error', '')
return super(FileUpload, self).__call__()
3 changes: 2 additions & 1 deletion collective/limitfilesizepanel/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@
/>

<configure zcml:condition="installed plone.dexterity">
<adapter factory=".dx_validators.DXFileSizeValidator" />
<adapter factory=".dx_validators.FileSizeValidator" />
<adapter factory=".dx_validators.ImageFileSizeValidator" />
</configure>

</configure>
40 changes: 22 additions & 18 deletions collective/limitfilesizepanel/dx_validators.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
# -*- coding: utf-8 -*-
from Products.validation.i18n import safe_unicode
from plone.namedfile.interfaces import INamedBlobImageField
from plone.namedfile.interfaces import INamedBlobFileField
from collective.limitfilesizepanel import messageFactory as _
from zope.interface import Invalid
from z3c.form import validator
from plone import api
from plone.api.exc import InvalidParameterError
from zope.i18n import translate
from plone.dexterity.browser.edit import DefaultEditForm


class DXFileSizeValidator(validator.FileUploadValidator):
Expand All @@ -18,7 +16,10 @@ class DXFileSizeValidator(validator.FileUploadValidator):
def validate(self, value):
super(DXFileSizeValidator, self).validate(value)
if not value:
return
return True

if isinstance(self.view, DefaultEditForm):
return True
try:
helper_view = api.content.get_view(
name='lfsp_helpers_view',
Expand All @@ -27,10 +28,13 @@ def validate(self, value):
)
except InvalidParameterError:
#  the view is enabled only when the product is installed
return
if helper_view.canBypassValidation():
return True
maxsize = helper_view.get_maxsize_dx(self, self.field)
if helper_view.newDataOnly() and isinstance(self.view, DefaultEditForm): # noqa
return True
maxsize = helper_view.get_maxsize_dx(
validator=self,
field=self.field
)
if not maxsize:
return True

Expand All @@ -39,20 +43,20 @@ def validate(self, value):
uploadfile=value)

if size_check and not size_check.get('valid', False):
msg = _(
'validation_error',
default=u"Validation failed. Uploaded data is too large:"
u" ${size}MB (max ${max}MB)",
mapping={
'size': safe_unicode("%.1f" % size_check.get('sizeMB')),
'max': safe_unicode("%.1f" % size_check.get('maxsize'))
})
raise Invalid(translate(msg, context=self.context.REQUEST))
raise Invalid(size_check.get('error', ''))
return True


validator.WidgetValidatorDiscriminators(DXFileSizeValidator,
class ImageFileSizeValidator(DXFileSizeValidator):
""" """


class FileSizeValidator(DXFileSizeValidator):
""" """


validator.WidgetValidatorDiscriminators(ImageFileSizeValidator,
field=INamedBlobImageField)

validator.WidgetValidatorDiscriminators(DXFileSizeValidator,
validator.WidgetValidatorDiscriminators(FileSizeValidator,
field=INamedBlobFileField)
4 changes: 2 additions & 2 deletions collective/limitfilesizepanel/overrides.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
<adapter
for="Products.CMFPlone.interfaces.siteroot.IPloneSiteRoot"
provides="Products.TinyMCE.adapters.interfaces.Upload.IUpload"
factory=".tinymce_upload.Upload"
factory=".tinymce_upload_p4.Upload"
/>

<adapter
for="plone.folder.interfaces.IOrderableFolder"
provides="Products.TinyMCE.adapters.interfaces.Upload.IUpload"
factory=".tinymce_upload.Upload"
factory=".tinymce_upload_p4.Upload"
/>
</configure>
Loading