Commit 79e5b5fc authored by Ivan Tyagov's avatar Ivan Tyagov

Add pre_converted_only argument on format REQUEST arguments.

If pre_converted_only is True system will return desired conversion only if it's already cached.
Extend testDms to cover it.
parent 63b88e67
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Generic method to handle conversion failures ans still return something to use \n
to explain what when wrong, etc.\n
"""\n
VALID_IMAGE_FORMAT_LIST = (\'jpg\', \'jpeg\', \'png\', \'gif\', \'pnm\', \'ppm\', \'tiff\')\n
\n
# some good defaults\n
mimetype = "text/plain"\n
data = "Conversion failure"\n
\n
if format in VALID_IMAGE_FORMAT_LIST:\n
# default image is an OFSImage so even if conversion engine is down \n
# we are still able to deliver it\n
default_image = getattr(context, "default_conversion_failure_image", None)\n
if default_image is not None:\n
mimetype = default_image.getContentType()\n
data = default_image.index_html(context.REQUEST, context.REQUEST.RESPONSE)\n
\n
return mimetype, data\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>format=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Document_getFailsafeConversion</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Image" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Cacheable__manager_id</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts18922384.14</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
<value> <string>default_conversion_failure_image</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>image/png</string> </value>
</item>
<item>
<key> <string>data</string> </key>
<value> <string encoding="base64">iVBORw0KGgoAAAANSUhEUgAAAPAAAAC0CAYAAACqnKHoAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A
/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sKEgcTF+P+EykAAAAdaVRYdENv
bW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAACNxJREFUeNrt2llIlG0fx/Gf2t4Yxii5
RDRlmRKRbQcxeFIk2UEFFdVZBy1GoZlDBxVhUZS02J5kexEdRAQFBVkaeVY5ErRHREJhktpCi+b/
OXkVdUabxffRnr4fmAPvub3mmmvu79yzRZiZCcAfKZIlAAgYAAEDIGCAgAEQMAACBkDAAAEDIGAA
BAwQMAACBkDAAAgYIGAABAyAgAEQMEDAAAgYAAEDBAyAgAEQMAACBggYAAEDIGAABAwQMAACBkDA
AAEDIGAABAyAgAECBkDAAAgYIGAABAyAgAEQMEDAAAgYAAEDIGCAgAEQMAACBggYAAEDIGAABAwQ
MAACBkDAAAgYIGAABAyAgAECBkDAAAgYAAEDBAyAgAEQMAACBgj4TxQREaGIiAiOgF6y9uE+HsH8
/3/psY/sLQ+mx+MhNCDYfszMejpgSerbt68ePXqklJQUv9f38DTxLx0HoT7Owfz/f+mY6jUvoRsb
G5WTk8ORDPyJAc+ePVs3b97U1atXf7uvmenYsWPKyMhQXFyc4uLilJGRoePHjwf8rNrV+7DGxkbl
5ubK5XJpypQpOnv2rCTp8+fPysvL0+jRozVy5Ejt3LnT79j37t3T/PnzlZiYqNjYWM2cOVMPHz70
u29NTY0WL16s+Ph4paamasOGDWpqaur0rcONGzeUlZUll8ul6OhoTZ48WQUFBfrx40dA9zuQudXW
1mrAgAHq06eP3r9/7zPG169fFRMTo2HDhqmxsTHo+xzo26JgxmzR1NSkDRs2KDU1VQkJCVq6dKlq
a2sDWptw17ZHWA+TZJLsyZMn1qdPH3O5XPbt2zef61s0NzdbZmZm6/aOl6ysLGtubg74dv1tW7ly
Zbsxo6KizOv12oIFC3xu7/r1652O3fbSv39/e/z4cbv9GhoabMSIET77rl692u/8Vq1a1en9Tk9P
tx8/fgR8v383t8WLF5sk27t3r88YJSUlJsny8/ODHvd3ax/KXNvu23btWi4ul8s+f/7c5W11x9r2
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</string> </value>
</item>
<item>
<key> <string>height</string> </key>
<value> <int>180</int> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>size</string> </key>
<value> <int>2437</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Default Image returned if conversion failed</string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>240</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
1254 1255
\ No newline at end of file \ No newline at end of file
...@@ -67,10 +67,31 @@ class DocumentMixin: ...@@ -67,10 +67,31 @@ class DocumentMixin:
# to bypass such check one should use _convert directly # to bypass such check one should use _convert directly
del transaction_variable[LOCK_PERMISSION_KEY] del transaction_variable[LOCK_PERMISSION_KEY]
self._checkConversionFormatPermission(format, lock_checking=True, **kw) self._checkConversionFormatPermission(format, lock_checking=True, **kw)
result = self._convert(format, **kw)
pre_converted_only = kw.pop('pre_converted_only', False)
if pre_converted_only:
# we will use ONLY cache to return converted content
# if respective document is not in cache we will return a good default content
try:
kw['format'] = format
result = self.getConversion(**kw)
except KeyError:
# respective document is not cached yet and we should return a failure safe content instead
result = self.getFailsafeConversion(**kw)
else:
# generate conversion on the fly or get it from cache (if already stored)
result = self._convert(format, **kw)
if LOCK_PERMISSION_KEY in transaction_variable: if LOCK_PERMISSION_KEY in transaction_variable:
del transaction_variable[LOCK_PERMISSION_KEY] del transaction_variable[LOCK_PERMISSION_KEY]
return result return result
def getFailsafeConversion(self, **kw):
"""
Return a failure resistent conversion of a document
"""
method = self._getTypeBasedMethod('getFailsafeConversion',
fallback_script_id='Document_getFailsafeConversion')
return method(**kw)
def _convert(self, format, **kw): def _convert(self, format, **kw):
"""Private method which make the transformation. """Private method which make the transformation.
......
...@@ -41,7 +41,7 @@ class DownloadableMixin: ...@@ -41,7 +41,7 @@ class DownloadableMixin:
### Content processing methods ### Content processing methods
security.declareProtected(Permissions.View, 'index_html') security.declareProtected(Permissions.View, 'index_html')
@fill_args_from_request('display', 'quality', 'resolution', 'frame') @fill_args_from_request('display', 'quality', 'resolution', 'frame', 'pre_converted_only')
def index_html(self, REQUEST, RESPONSE, format=_MARKER, **kw): def index_html(self, REQUEST, RESPONSE, format=_MARKER, **kw):
""" """
We follow here the standard Zope API for files and images We follow here the standard Zope API for files and images
......
...@@ -93,9 +93,13 @@ def makeFileUpload(name, as_name=None): ...@@ -93,9 +93,13 @@ def makeFileUpload(name, as_name=None):
class TestDocumentMixin(ERP5TypeTestCase): class TestDocumentMixin(ERP5TypeTestCase):
bussiness_template_list = ['erp5_core_proxy_field_legacy', bussiness_template_list = ['erp5_core_proxy_field_legacy',
'erp5_full_text_myisam_catalog','erp5_base', 'erp5_jquery',
'erp5_ingestion', 'erp5_ingestion_mysql_innodb_catalog', 'erp5_full_text_myisam_catalog',
'erp5_web', 'erp5_dms'] 'erp5_base',
'erp5_ingestion_mysql_innodb_catalog',
'erp5_ingestion',
'erp5_web',
'erp5_dms']
def setUpOnce(self): def setUpOnce(self):
# set a dummy localizer (because normally it is cookie based) # set a dummy localizer (because normally it is cookie based)
...@@ -131,8 +135,8 @@ class TestDocumentMixin(ERP5TypeTestCase): ...@@ -131,8 +135,8 @@ class TestDocumentMixin(ERP5TypeTestCase):
preference_list = self.portal.portal_preferences.contentValues( preference_list = self.portal.portal_preferences.contentValues(
portal_type=portal_type) portal_type=portal_type)
if not preference_list: if not preference_list:
preference = self.portal.portal_preferences.newContent( preference = self.portal.portal_preferences.newContent(title="Default System Preference",
portal_type=portal_type) portal_type=portal_type)
else: else:
preference = preference_list[0] preference = preference_list[0]
if self.portal.portal_workflow.isTransitionPossible(preference, 'enable'): if self.portal.portal_workflow.isTransitionPossible(preference, 'enable'):
...@@ -2131,6 +2135,42 @@ return 1 ...@@ -2131,6 +2135,42 @@ return 1
# if PDF size is larger than A4 format system should deny conversion # if PDF size is larger than A4 format system should deny conversion
self.assertRaises(Unauthorized, pdf.convert, format='jpeg') self.assertRaises(Unauthorized, pdf.convert, format='jpeg')
def test_preConversionOnly(self):
"""
Test usage of pre_converted_only argument - i.e. return a conversion only form cache otherwise
return a default (i.e. indicating a conversion failures)
"""
doc = self.portal.document_module.newContent(portal_type='Presentation')
upload_file = makeFileUpload('TEST-en-003.odp')
doc.edit(file=upload_file)
doc.publish()
self.stepTic()
default_conversion_failure_image_size, default_conversion_failure_image_file_size = \
self.getURLSizeList('%s/default_conversion_failure_image' %self.portal.absolute_url())
doc_url = '%s/%s' %(self.portal.absolute_url(), doc.getPath())
converted_image_size_70, converted_file_size_70 = self.getURLSizeList(doc_url, \
**{'format':'png', 'quality':70.0})
self.assertTrue(doc.hasConversion(**{'format': 'png', 'quality': 70.0}))
# try with new quality and pre_converted_only now a default image
# with content "No image available" should be returned
failure_image_size, failure_file_size = self.getURLSizeList(doc_url, \
**{'format':'png', 'quality':80.0, 'pre_converted_only':1})
self.assertSameSet(failure_image_size, default_conversion_failure_image_size)
converted_image_size_80, converted_file_size_80 = self.getURLSizeList(doc_url, \
**{'format':'png', 'quality':80.0})
self.assertSameSet(converted_image_size_80, converted_image_size_70)
self.assertTrue(doc.hasConversion(**{'format': 'png', 'quality': 80.0}))
# as conversion is cached we should get it
converted_image_size_80n, converted_file_size_80n = self.getURLSizeList(doc_url,
**{'format':'png', 'quality':80.0, 'pre_converted_only':1})
self.assertSameSet(converted_image_size_80n, converted_image_size_70)
def test_getSearchText(self): def test_getSearchText(self):
""" """
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment