Skip to content
This repository has been archived by the owner on May 25, 2023. It is now read-only.

Various improvements #11

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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
10 changes: 7 additions & 3 deletions docs/HISTORY.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ Changelog
1.1b12 (unreleased)
-------------------

- Nothing changed yet.

- Required fields are not dependent from language fallback anymore [sebasgo]
- Reset language after scaling images [pgrunewald]
- Make indices resilient [sebasgo]
- Fix Image Bobo traversing for fullscreen view [sebasgo]
- Allow language fallback for brains [pgrunewald]
- Fix lazy initialization with respect to plone.protect [sebasgo]

1.1b11 (2017-01-09)
-------------------
Expand All @@ -16,7 +20,7 @@ Changelog
1.1b10 (2014-12-05)
-------------------

* Renamed protected TAL keyword 'translate' to 'multilanguage'
* Renamed protected TAL keyword 'translate' to 'multilanguage' [pgrunewald]


1.1b9 (2014-06-24)
Expand Down
7 changes: 0 additions & 7 deletions raptus/multilanguagefields/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,6 @@ def __init__(self, name=None, **kwargs):
def _set_required(self, value):
self._required = value
def _get_required(self):
context = getSite()
if self.haveLanguageFallback(context):
current = self._v_lang
if current is None:
current = self._getCurrentLanguage(context)
default = self.getDefaultLang(context)
return default == current and getattr(self, '_required', False)
return getattr(self, '_required', False)
required = property(fget=_get_required,
fset=_set_required)
Expand Down
32 changes: 24 additions & 8 deletions raptus/multilanguagefields/indexes/UnIndex.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,28 @@
from Products.PluginIndexes.common import safe_callable
from Products.PluginIndexes.common.UnIndex import UnIndex, _marker

try:
from plone.protect.utils import safeWrite
except ImportError:
def safeWrite(obj, request=None):
pass


class MultilanguageUnIndex(UnIndex):
"""Multilanguage aware forward and reverse index.
"""

_v_lang = None
_d_length = PersistentDict()
_d_index = PersistentDict()
_d_unindex = PersistentDict()

def _getCurrentLanguage(self):
return getToolByName(getSite(), 'portal_languages').getPreferredLanguage()

try:
return getToolByName(getSite(), 'portal_languages').getPreferredLanguage()
except AttributeError:
return 'en'

def _get_lang_length(self, lang):
if not self._d_length.has_key(lang):
self._d_length[lang] = BTrees.Length.Length()
Expand All @@ -53,10 +63,13 @@ def _del_length(self):
_length = property(fget=_get_length,
fset=_set_length,
fdel=_del_length)

def _get_lang_index(self, lang):
if not self._d_index.has_key(lang):
self._d_index[lang] = OOBTree()
safeWrite(self)
safeWrite(self._d_index)
safeWrite(self._d_index[lang])
return self._d_index[lang]

def _set_index(self, value):
Expand All @@ -78,10 +91,13 @@ def _del_index(self):
_index = property(fget=_get_index,
fset=_set_index,
fdel=_del_index)

def _get_lang_unindex(self, lang):
if not self._d_unindex.has_key(lang):
self._d_unindex[lang] = IOBTree()
safeWrite(self)
safeWrite(self._d_unindex)
safeWrite(self._d_unindex[lang])
return self._d_unindex[lang]

def _set_unindex(self, value):
Expand All @@ -103,7 +119,7 @@ def _del_unindex(self):
_unindex = property(fget=_get_unindex,
fset=_set_unindex,
fdel=_del_unindex)

def clear(self):
self._v_lang = None
self._d_length = PersistentDict()
Expand Down Expand Up @@ -136,7 +152,7 @@ def unindex_object(self, documentId):
UnIndex.unindex_object(self, documentId)
finally:
self._v_lang = None

def _get_object_datum(self, obj, attr):
# self.id is the name of the index, which is also the name of the
# attribute we're interested in. If the attribute is callable,
Expand Down
22 changes: 18 additions & 4 deletions raptus/multilanguagefields/indexes/ZCTextIndex.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
from Products.PluginIndexes.common import safe_callable
from Products.CMFCore.utils import getToolByName

try:
from plone.protect.utils import safeWrite
except ImportError:
def safeWrite(obj, request=None):
pass


class MultilanguageZCTextIndex(ZCTextIndex):
"""Multilanguage Persistent text index.
"""
Expand All @@ -24,18 +31,23 @@ class MultilanguageZCTextIndex(ZCTextIndex):
_v_lang = None

def _getCurrentLanguage(self):
return getToolByName(getSite(), 'portal_languages').getPreferredLanguage()
try:
return getToolByName(getSite(), 'portal_languages').getPreferredLanguage()
except AttributeError:
return 'en'

@property
def languages(self):
ltool = getToolByName(getSite(), 'portal_languages', None)
if ltool is None:
return []
return ltool.getSupportedLanguages()

def _get_lang_index(self, lang):
if not hasattr(self, '_index_%s' % lang):
setattr(self, '_index_%s' % lang, self._index_factory(aq_base(self.getLexicon())))
safeWrite(self)
safeWrite(self, getattr(self, '_index_%s' % lang))
return getattr(self, '_index_%s' % lang)

def _set_index(self, value):
Expand Down Expand Up @@ -71,6 +83,8 @@ def getLexicon(self):
raise TypeError('Object "%s" is not a ZCTextIndex Lexicon'
% repr(lexicon))
self._v_lexicon = lexicon
safeWrite(self)
safeWrite(lexicon)
return lexicon

## Pluggable Index APIs ##
Expand All @@ -79,7 +93,7 @@ def index_object(self, documentId, obj, threshold=None):
try: fields = self._indexed_attrs
except: fields = [ self._fieldname ]
res = 0

for lang in self.languages:
all_texts = []
for attr in fields:
Expand All @@ -96,7 +110,7 @@ def index_object(self, documentId, obj, threshold=None):
all_texts.extend(text)
else:
all_texts.append(text)

# Check that we're sending only strings
all_texts = filter(lambda text: isinstance(text, basestring), \
all_texts)
Expand Down
9 changes: 7 additions & 2 deletions raptus/multilanguagefields/patches/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
# CatalogBrain monkey patch
def __new_init__(self, data):
ndata = []
lang = getToolByName(getSite(), 'portal_languages').getPreferredLanguage()
portal_languages = getToolByName(getSite(), 'portal_languages')
lang = portal_languages.getPreferredLanguage()
default_lang = portal_languages.getDefaultLanguage() if portal_languages.allow_content_language_fallback else 'en'
try:
encoding = getToolByName(self, "portal_properties").site_properties.default_charset
except AttributeError:
Expand All @@ -34,7 +36,10 @@ def __new_init__(self, data):
try:
value = json.loads(v)
value = value['___multilanguage___']
v = value.get(lang, '')
if portal_languages.allow_content_language_fallback:
v = value.get(lang, value.get(default_lang, ''))
else:
v = value.get(lang, '')
if isinstance(v, basestring):
v = v.encode(encoding)
except:
Expand Down
14 changes: 11 additions & 3 deletions raptus/multilanguagefields/patches/imaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,19 @@ def publishTraverse(self, request, name):
ImageTraverser.publishTraverse = publishTraverse
LOG.info("plone.app.imaging.traverse.ImageTraverser.publishTraverse patched")

def scale(self, fieldname=None, scale=None, **parameters):
def scale(self, fieldname=None, scale=None, height=None, width=None, **parameters):
field = self.context.getField(fieldname)

if IMultilanguageField.providedBy(field):
if not '___' in fieldname: # no language explicitly wished. So unset language preference.
field.resetLanguage()
fieldname = '%s___%s___' % (fieldname, field._v_lang or field._getCurrentLanguage(self.context))

image = self.__old_scale(fieldname, scale, height, width, **parameters)

if IMultilanguageField.providedBy(field):
fieldname = '%s___%s___' % (fieldname, field._v_lang or field._getCurrentLanguage(getSite()))
return self.__old_scale(fieldname, scale, **parameters)
field.resetLanguage()
return image
from plone.app.imaging.scaling import ImageScaling
ImageScaling.__old_scale = ImageScaling.scale
ImageScaling.scale = scale
Expand Down
48 changes: 24 additions & 24 deletions raptus/multilanguagefields/patches/traverse.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
from raptus.multilanguagefields import LOG
from raptus.multilanguagefields.interfaces import IMultilanguageField
from Products.Archetypes.BaseObject import BaseObject

def __bobo_traverse__(self, REQUEST, name):
"""Transparent access to multilanguage image scales for
content types holding an multilanguage ImageField named
'image'
""" helper to access multilanguage image scales the old way during
`unrestrictedTraverse` calls

NO BLOBS
the method to be patched is '__bobo_traverse__'
"""
if name.startswith('image_') or name == 'image':
field = self.getField('image')
if not IMultilanguageField.providedBy(field):
field = self.getField(name.split('_')[0])
if not IMultilanguageField.providedBy(field) or not hasattr(REQUEST, 'get'):
return BaseObject.__bobo_traverse__(self, REQUEST, name)
last = REQUEST.get('ACTUAL_URL', '').endswith(name)
fieldname, scale = name, None
Expand All @@ -25,31 +25,32 @@ def __bobo_traverse__(self, REQUEST, name):
if '_' in name:
fieldname, scale = name.split('_', 1)
if last and REQUEST.get('HTTP_USER_AGENT', False):
_scale = scale
if _scale is not None:
_scale = '_'+str(_scale)
else:
_scale = ''
REQUEST.RESPONSE.redirect(self.absolute_url()+'/'+fieldname+'___'+field._getCurrentLanguage(self)+'___'+_scale)
# begin own code
if scale in field.getAvailableSizes(self):
# end own code
_scale = scale
if _scale is not None:
_scale = '_'+str(_scale)
else:
_scale = ''
REQUEST.RESPONSE.redirect(self.absolute_url()+'/'+fieldname+'___'+field._getCurrentLanguage(self)+'___'+_scale)
lang = field._getCurrentLanguage(self)
lang_before = field._v_lang
try:
field.setLanguage(lang)
handler = IImageScaleHandler(field, None)
image = None
if scale:
if scale in field.getAvailableSizes(self):
image = field.getScale(self, scale=scale)
else:
image = field.getScale(self)
if handler is not None:
try:
image = handler.getScale(self, scale)
except AttributeError: # no image available, do not raise as there might be one available as a fallback
pass
if not image: # language fallback
defaultLang = field.getDefaultLang(self)
if defaultLang and not defaultLang == lang:
field.setLanguage(defaultLang)
if scale:
if scale in field.getAvailableSizes(self):
image = field.getScale(self, scale=scale)
else:
image = field.getScale(self)
if handler is not None:
image = handler.getScale(self, scale)
if image is not None:
if last and REQUEST.get('HTTP_USER_AGENT', False):
_scale = scale
Expand All @@ -60,8 +61,7 @@ def __bobo_traverse__(self, REQUEST, name):
REQUEST.RESPONSE.redirect(self.absolute_url()+'/'+fieldname+'___'+defaultLang+'___'+_scale)
finally:
field.setLanguage(lang_before)
if image is not None and not isinstance(image, basestring):
# image might be None or '' for empty images
if image is not None:
return image
return BaseObject.__bobo_traverse__(self, REQUEST, name)

Expand Down