SearchableText was broken.

This commit is contained in:
Gaetan Delannay 2010-11-30 17:41:18 +01:00
parent 52816ec343
commit e62e00d367
8 changed files with 58 additions and 13 deletions

View file

@ -3,7 +3,7 @@
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
import os, os.path, sys, zipfile, appy import os, os.path, sys, zipfile, appy
from appy.bin.clean import Cleaner from appy.bin.clean import Cleaner
from appy.shared.utils import FolderDeleter, copyFolder from appy.shared.utils import FolderDeleter, copyFolder, cleanFolder
from optparse import OptionParser from optparse import OptionParser
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -104,6 +104,8 @@ class EggifyScript:
def eggify(self): def eggify(self):
'''Let's wrap a nice Python module into an ugly egg.''' '''Let's wrap a nice Python module into an ugly egg.'''
j = os.path.join j = os.path.join
# First, clean the Python module
cleanFolder(self.pythonModule, verbose=False)
# Create the egg folder # Create the egg folder
eggFullName = j(self.eggFolder, self.eggName) eggFullName = j(self.eggFolder, self.eggName)
if os.path.exists(eggFullName): if os.path.exists(eggFullName):

View file

@ -700,6 +700,28 @@ class Type:
if self.isEmptyValue(value): return '' if self.isEmptyValue(value): return ''
return value return value
def getIndexValue(self, obj, forSearch=False):
'''This method returns a version for this field value on p_obj that is
ready for indexing purposes. Needs to be overridden by some child
classes.
If p_forSearch is True, it will return a "string" version of the
index value suitable for a global search.'''
value = self.getValue(obj)
if forSearch and (value != None):
if isinstance(value, unicode):
res = value.encode('utf-8')
elif type(value) in sequenceTypes:
res = []
for v in value:
if isinstance(v, unicode): res.append(v.encode('utf-8'))
else: res.append(str(v))
res = ' '.join(res)
else:
res = str(value)
return res
return value
def getRequestValue(self, request): def getRequestValue(self, request):
'''Gets the string (or list of strings if multi-valued) '''Gets the string (or list of strings if multi-valued)
representation of this field as found in the p_request.''' representation of this field as found in the p_request.'''
@ -1065,11 +1087,16 @@ class String(Type):
else: return value else: return value
if isinstance(value, basestring) and self.isMultiValued(): if isinstance(value, basestring) and self.isMultiValued():
value = [value] value = [value]
# Some backward compatibilities with Archetypes.
elif value.__class__.__name__ == 'BaseUnit': elif value.__class__.__name__ == 'BaseUnit':
try: try:
value = unicode(value) value = unicode(value)
except UnicodeDecodeError: except UnicodeDecodeError:
value = str(value) value = str(value)
elif isinstance(value, tuple):
# When Appy storage was based on Archetype, multivalued string
# fields stored values as tuples of unicode strings.
value = list(value)
return value return value
def getFormattedValue(self, obj, value): def getFormattedValue(self, obj, value):
@ -1369,8 +1396,8 @@ class File(Type):
- mimeType is the MIME type of the file. - mimeType is the MIME type of the file.
''' '''
if value: if value:
ZFileUpload = self.o.getProductConfig().FileUpload ZFileUpload = obj.o.getProductConfig().FileUpload
OFSImageFile = self.o.getProductConfig().File OFSImageFile = obj.o.getProductConfig().File
if isinstance(value, ZFileUpload): if isinstance(value, ZFileUpload):
# The file content comes from a HTTP POST. # The file content comes from a HTTP POST.
# Retrieve the existing value, or create one if None # Retrieve the existing value, or create one if None

View file

@ -361,7 +361,8 @@ class ClassDescriptor(appy.gen.descriptors.ClassDescriptor):
m += '\n' + ' '*spaces + 'def get%s%s(self):\n' % (n[0].upper(), n[1:]) m += '\n' + ' '*spaces + 'def get%s%s(self):\n' % (n[0].upper(), n[1:])
spaces += TABS spaces += TABS
m += ' '*spaces + "'''Gets indexable value of field \"%s\".'''\n" % n m += ' '*spaces + "'''Gets indexable value of field \"%s\".'''\n" % n
m += ' '*spaces + 'return self.getAppyType("%s").getValue(self)\n' % n m += ' '*spaces + 'return self.getAppyType("%s").getIndexValue(' \
'self)\n' % n
self.methods = m self.methods = m
class ToolClassDescriptor(ClassDescriptor): class ToolClassDescriptor(ClassDescriptor):

View file

@ -667,14 +667,14 @@ class Generator(AbstractGenerator):
if classDescr.isFolder(): if classDescr.isFolder():
baseClass = 'OrderedBaseFolder' baseClass = 'OrderedBaseFolder'
baseSchema = 'OrderedBaseFolderSchema' baseSchema = 'OrderedBaseFolderSchema'
parents = [baseClass, 'BaseMixin'] parents = ['BaseMixin', baseClass]
imports = [] imports = []
implements = [baseClass] implements = [baseClass]
for baseClass in classDescr.klass.__bases__: for baseClass in classDescr.klass.__bases__:
if self.determineAppyType(baseClass) == 'class': if self.determineAppyType(baseClass) == 'class':
bcName = getClassName(baseClass) bcName = getClassName(baseClass)
parents.remove('BaseMixin') parents.remove('BaseMixin')
parents.append(bcName) parents.insert(0, bcName)
implements.append(bcName) implements.append(bcName)
imports.append('from %s import %s' % (bcName, bcName)) imports.append('from %s import %s' % (bcName, bcName))
baseSchema = '%s.schema' % bcName baseSchema = '%s.schema' % bcName

View file

@ -56,9 +56,17 @@ class PloneInstaller:
{s_indexName:s_indexType}. Here are some examples of index types: {s_indexName:s_indexType}. Here are some examples of index types:
"FieldIndex", "ZCTextIndex", "DateIndex".''' "FieldIndex", "ZCTextIndex", "DateIndex".'''
catalog = ploneSite.portal_catalog catalog = ploneSite.portal_catalog
indexNames = catalog.indexes() zopeCatalog = catalog._catalog
for indexName, indexType in indexInfo.iteritems(): for indexName, indexType in indexInfo.iteritems():
if indexName not in indexNames: # If this index already exists but with a different type, remove it.
if (indexName in zopeCatalog.indexes):
oldType = zopeCatalog.indexes[indexName].__class__.__name__
if oldType != indexType:
catalog.delIndex(indexName)
logger.info('Existing index "%s" of type "%s" was removed:'\
' we need to recreate it with type "%s".' % \
(indexName, oldType, indexType))
if indexName not in zopeCatalog.indexes:
# We need to create this index # We need to create this index
if indexType != 'ZCTextIndex': if indexType != 'ZCTextIndex':
catalog.addIndex(indexName, indexType) catalog.addIndex(indexName, indexType)
@ -68,8 +76,6 @@ class PloneInstaller:
catalog.reindexIndex(indexName, ploneSite.REQUEST) catalog.reindexIndex(indexName, ploneSite.REQUEST)
logger.info('Created index "%s" of type "%s"...' % \ logger.info('Created index "%s" of type "%s"...' % \
(indexName, indexType)) (indexName, indexType))
# TODO: if the index already exists but has not the same type, we
# re-create it with the same type and we reindex it.
actionsToHide = { actionsToHide = {
'portal_actions': ('sitemap', 'accessibility', 'change_state','sendto'), 'portal_actions': ('sitemap', 'accessibility', 'change_state','sendto'),

View file

@ -793,7 +793,7 @@ class BaseMixin:
transition on an object.''' transition on an object.'''
rq = self.REQUEST rq = self.REQUEST
self.portal_workflow.doActionFor(self, rq['workflow_action'], self.portal_workflow.doActionFor(self, rq['workflow_action'],
comment = rq.get('comment', '')) comment = rq.get('comment', ''))
self.reindexObject() self.reindexObject()
# Where to redirect the user back ? # Where to redirect the user back ?
# TODO (?): remove the "phase" param for redirecting the user to the # TODO (?): remove the "phase" param for redirecting the user to the
@ -1040,4 +1040,13 @@ class BaseMixin:
response.setHeader('Cachecontrol', 'no-cache') response.setHeader('Cachecontrol', 'no-cache')
response.setHeader('Expires', 'Thu, 11 Dec 1975 12:05:05 GMT') response.setHeader('Expires', 'Thu, 11 Dec 1975 12:05:05 GMT')
return theFile.index_html(self.REQUEST, self.REQUEST.RESPONSE) return theFile.index_html(self.REQUEST, self.REQUEST.RESPONSE)
def SearchableText(self):
'''This method concatenates the content of every field with
searchable=True for indexing purposes.'''
res = []
for field in self.getAllAppyTypes():
if not field.searchable: continue
res.append(field.getIndexValue(self, forSearch=True))
return res
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View file

@ -11,7 +11,7 @@ schema = Schema((<!fields!>
),) ),)
fullSchema = OrderedBaseFolderSchema.copy() + schema.copy() fullSchema = OrderedBaseFolderSchema.copy() + schema.copy()
class <!toolName!>(UniqueObject, OrderedBaseFolder, ToolMixin): class <!toolName!>(ToolMixin, UniqueObject, OrderedBaseFolder):
'''Tool for <!applicationName!>.''' '''Tool for <!applicationName!>.'''
security = ClassSecurityInfo() security = ClassSecurityInfo()
__implements__ = (getattr(UniqueObject,'__implements__',()),) + (getattr(OrderedBaseFolder,'__implements__',()),) __implements__ = (getattr(UniqueObject,'__implements__',()),) + (getattr(OrderedBaseFolder,'__implements__',()),)

View file

@ -9,7 +9,7 @@ schema = Schema((<!fields!>
),) ),)
fullSchema = BaseSchema.copy() + schema.copy() fullSchema = BaseSchema.copy() + schema.copy()
class <!applicationName!>User(BaseContent, BaseMixin): class <!applicationName!>User(BaseMixin, BaseContent):
'''User mixin.''' '''User mixin.'''
security = ClassSecurityInfo() security = ClassSecurityInfo()
__implements__ = (getattr(BaseContent,'__implements__',()),) __implements__ = (getattr(BaseContent,'__implements__',()),)