def index_object(self, documentId, obj, threshold=None):
        """Index an object:
        - 'documentId' is the integer ID of the document
        - 'obj' is the object to be indexed
        - ignore threshold
        """
        if self._since_field is None:
            return 0

        since = getattr(obj, self._since_field, None)
        if safe_callable(since):
            since = since()
        since = self._convertDateTime(since)

        until = getattr(obj, self._until_field, None)
        if safe_callable(until):
            until = until()
        until = self._convertDateTime(until)

        datum = (since, until)

        old_datum = self._unindex.get(documentId, None)
        if datum == old_datum:  # No change?  bail out!
            return 0

        self._increment_counter()

        if old_datum is not None:
            old_since, old_until = old_datum
            self._removeForwardIndexEntry(old_since, old_until, documentId)

        self._insertForwardIndexEntry(since, until, documentId)
        self._unindex[documentId] = datum

        return 1
예제 #2
0
    def get_value(self, object):
        try:
            fields = self.index._indexed_attrs
        except:
            fields  = [ self.index._fieldname ]

        all_texts = []
        for attr in fields:
            text = getattr(object, attr, None)
            if text is None:
                continue
            if safe_callable(text):
                text = text()
            if text is None:
                continue
            if text:
                if isinstance(text, (list, tuple, )):
                    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)
        if all_texts:
            return '\n'.join(all_texts)
예제 #3
0
    def index_object(self, documentId, obj, threshold=None):
        """Wrapper for  index_doc()  handling indexing of multiple attributes.

        Enter the document with the specified documentId in the index
        under the terms extracted from the indexed text attributes,
        each of which should yield either a string or a list of
        strings (Unicode or otherwise) to be passed to index_doc().
        """
        # TODO we currently ignore subtransaction threshold

        # needed for backward compatibility
        fields = getattr(self, '_indexed_attrs', [self._fieldname])

        all_texts = []
        for attr in fields:
            text = getattr(obj, attr, None)
            if text is None:
                continue
            if safe_callable(text):
                text = text()
            if text is not None:
                if isinstance(text, (list, tuple, set)):
                    all_texts.extend(text)
                else:
                    all_texts.append(text)

        # Check that we're sending only strings
        all_texts = [t for t in all_texts if isinstance(t, basestring)]
        if all_texts:
            return self.index.index_doc(documentId, all_texts)
        return 0
예제 #4
0
    def index_object(self, docid, obj ,threshold=100):
        """ hook for (Z)Catalog """

        f = getattr(obj, self.id, None)
        if f is not None:
            if safe_callable(f):
                try:
                    path = f()
                except AttributeError:
                    return 0
            else:
                path = f

            if not isinstance(path, (StringType, TupleType)):
                raise TypeError('path value must be string or tuple of strings')
        else:
            try:
                path = obj.getPhysicalPath()
            except AttributeError:
                return 0

        if isinstance(path, (ListType, TupleType)):
            path = '/'+ '/'.join(path[1:])
        comps = filter(None, path.split('/'))

        if not self._unindex.has_key(docid):
            self._length.change(1)

        for i in range(len(comps)):
            self.insertEntry(comps[i], docid, i)
        self._unindex[docid] = path
        return 1
 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:
             text = getattr(obj, attr, None)
             if text is None:
                 continue
             if safe_callable(text):
                 try: text = text(lang=lang)
                 except: text = text()
             if text is None:
                 continue
             if text:
                 if isinstance(text, (list, tuple, )):
                     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)
         if all_texts:
             self._v_lang = lang
             res += self.index.index_doc(documentId, all_texts)
     self._v_lang = None
     return res > 0
예제 #6
0
    def get_value(self, object):
        if self.index._since_field is None:
            return

        since = getattr(object, self.index._since_field, None)
        if safe_callable(since):
            since = since()

        until = getattr(object, self.index._until_field, None)
        if safe_callable(until):
            until = until()
        if not since or not until:
            return

        return {
            '%s1' % self.index.id: since.ISO8601(),
            '%s2' % self.index.id: until.ISO8601()}
예제 #7
0
파일: CatalogTool.py 프로젝트: goschtl/zope
 def cmf_uid(self):
     """
     Return the CMFUid UID of the object while making sure
     it is not accidentally acquired.
     """
     cmf_uid = getattr(aq_base(self.__ob), 'cmf_uid', '')
     if safe_callable(cmf_uid):
         return cmf_uid()
     return cmf_uid
예제 #8
0
    def index_object(self, docid, obj, threshold=100):
        """ hook for (Z)Catalog """

        # PathIndex first checks for an attribute matching its id and
        # falls back to getPhysicalPath only when failing to get one.
        # If self.indexed_attrs is not None, it's value overrides this behavior

        attrs = self.indexed_attrs
        index = attrs is None and self.id or attrs[0]

        path = getattr(obj, index, None)
        if path is not None:
            if safe_callable(path):
                path = path()

            if not isinstance(path, (str, tuple)):
                raise TypeError('path value must be string or tuple '
                                'of strings: (%r, %s)' % (index, repr(path)))
        else:
            try:
                path = obj.getPhysicalPath()
            except AttributeError:
                return 0

        if isinstance(path, (list, tuple)):
            path = '/' + '/'.join(path[1:])
        comps = filter(None, path.split('/'))

        # Make sure we reindex properly when path change
        old_path = self._unindex.get(docid, _marker)
        if old_path is not _marker:
            if old_path != path:
                self.unindex_object(docid, _old=old_path)
                # unindex reduces length, we need to counter that
                self._length.change(1)
        else:
            # We only get a new entry if the value wasn't there before.
            # If it already existed the length is unchanged
            self._length.change(1)

        for i, comp in enumerate(comps):
            self.insertEntry(comp, docid, i)

        # Add terminator
        self.insertEntry(None, docid, len(comps) - 1)

        # Add full-path indexes, to optimize certain edge cases
        parent_path = '/' + '/'.join(comps[:-1])
        parents = self._index_parents.get(parent_path, _marker)
        if parents is _marker:
            self._index_parents[parent_path] = parents = IITreeSet()
        parents.insert(docid)
        self._index_items[path] = docid

        self._unindex[docid] = path
        return 1
예제 #9
0
 def _get_object_paths(self, obj, attr):
     try:
         paths = getattr(obj, attr, ())
     except AttributeError:
         return _marker
     if safe_callable(paths):
         paths = paths()
     if isinstance(paths, basestring):
         return (paths,)
     else:
         return paths
예제 #10
0
 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,
     # we'll do so.
     try:
         datum = getattr(obj, attr)
         if safe_callable(datum):
             datum = datum()
     except (AttributeError, TypeError):
         datum = _marker
     return datum
    def index_object(self, docid, obj ,threshold=100):
        """ hook for (Z)Catalog """

        # PathIndex first checks for an attribute matching its id and
        # falls back to getPhysicalPath only when failing to get one.
        # The presence of 'indexed_attrs' overrides this behavior and
        # causes indexing of the custom attribute.

        attrs = getattr(self, 'indexed_attrs', None)
        if attrs:
            index = attrs[0]
        else:
            index = self.id

        f = getattr(obj, index, None)
        if f is not None:
            if safe_callable(f):
                try:
                    path = f()
                except AttributeError:
                    return 0
            else:
                path = f

            if not isinstance(path, (str, tuple)):
                raise TypeError('path value must be string or tuple '
                                'of strings: (%r, %s)' % (index, repr(path)))
        else:
            try:
                path = obj.getPhysicalPath()
            except AttributeError:
                return 0

        if isinstance(path, (list, tuple)):
            path = '/'+ '/'.join(path[1:])
        comps = filter(None, path.split('/'))
        parent_path = '/' + '/'.join(comps[:-1])

        # Make sure we reindex properly when path change
        if self._unindex.has_key(docid) and self._unindex.get(docid) != path:
            self.unindex_object(docid)

        if not self._unindex.has_key(docid):
            self._length.change(1)

        for i in range(len(comps)):
            self.insertEntry(comps[i], docid, i)

        # Add terminator
        self.insertEntry(None, docid, len(comps)-1, parent_path, path)

        self._unindex[docid] = path
        return 1
예제 #12
0
    def catalog_object(self, obj, uid=None, idxs=[],
                       update_metadata=1, pghandler=None):
        mode = self.mode
        if mode in (DISABLE_MODE, DUAL_MODE):
            result = self.patched.catalog_object(
                obj, uid, idxs, update_metadata, pghandler)
            if mode == DISABLE_MODE:
                return result
        wrapped_object = None
        if not IIndexableObject.providedBy(obj):
            # This is the CMF 2.2 compatible approach, which should be used
            # going forward
            wrapper = queryMultiAdapter((obj, self.catalogtool), IIndexableObject)
            if wrapper is not None:
                wrapped_object = wrapper
            else:
                wrapped_object = obj
        else:
            wrapped_object = obj
        conn = self.conn
        catalog = self.catalog
        if idxs == []:
            idxs = catalog.indexes.keys()
        index_data = {}
        for index_name in idxs:
            index = getIndex(catalog, index_name)
            if index is not None:
                value = index.get_value(wrapped_object)
                if value in (None, 'None'):
                    # yes, we'll index null data...
                    value = None
                index_data[index_name] = value
        if update_metadata:
            metadata = {}
            for meta_name in catalog.names:
                attr = getattr(wrapped_object, meta_name, MV)
                if (attr is not MV and safe_callable(attr)):
                    attr = attr()
                metadata[meta_name] = attr
            # XXX Also, always index path so we can use it with the brain
            # to make urls
            metadata['_path'] = wrapped_object.getPhysicalPath()
            index_data['_metadata'] = dumps(metadata)

        uid = getUID(obj)
        try:
            doc = conn.get(self.catalogsid, self.catalogtype, uid)
            self.registerInTransaction(uid, td.Actions.modify, doc)
        except NotFoundException:
            self.registerInTransaction(uid, td.Actions.add)
        conn.index(index_data, self.catalogsid, self.catalogtype, uid)
        if self.registry.auto_flush:
            conn.refresh()
 def index_object( self, documentId, obj, threshold=None ):
     if self._since_field is None:
         return 0
     
     since_attr = getattr(obj, self._since_field, None)
     until_attr = getattr(obj, self._until_field, None)
     if not since_attr and not until_attr:
         return 0
     for lang in self.languages:
         self._v_lang = lang
         if safe_callable(since_attr):
             since = since_attr()
             try: since = since_attr(lang=lang)
             except: pass
         else:
             since = since_attr
         since = self._convertDateTime( since )
         if safe_callable( until_attr ):
             until = until_attr()
             try: until = until_attr(lang=lang)
             except: pass
         else:
             until = until_attr
         until = self._convertDateTime( until )
 
         datum = ( since, until )
 
         old_datum = self._unindex.get( documentId, None )
         if datum == old_datum: # No change?  bail out!
             return 0
 
         if old_datum is not None:
             old_since, old_until = old_datum
             self._removeForwardIndexEntry( old_since, old_until, documentId )
 
         self._insertForwardIndexEntry( since, until, documentId )
         self._unindex[ documentId ] = datum
     self._v_lang = None
     return 1
    def _get_generic_searchable_text(self, obj):
        # Get searchable text from any object.

        catalog = getToolByName(self, 'portal_catalog')
        wrapper = queryMultiAdapter((obj, catalog), IIndexableObject)
        if wrapper is None:
            return
        text = getattr(wrapper, 'SearchableText', None)
        if text is None:
            return
        if safe_callable(text):
            text = text()
        return text
예제 #15
0
    def index_object(self, documentId, obj, threshold=None):
        """index an object, normalizing the indexed value to an integer

           o Normalized value has granularity of one minute.

           o Objects which have 'None' as indexed value are *omitted*,
             by design.
        """
        returnStatus = 0
        date_attr = getattr( obj, self.id, None )
        if not date_attr:
            return returnStatus
        for lang in self.languages:
            self._v_lang = lang
            try:
                if safe_callable( date_attr ):
                    date = date_attr()
                    try: date = date(lang=lang)
                    except: pass
                else:
                    date = date_attr
                ConvertedDate = self._convert( value=date, default=_marker )
            except AttributeError:
                ConvertedDate = _marker
    
            oldConvertedDate = self._unindex.get( documentId, _marker )
    
            if ConvertedDate != oldConvertedDate:
                if oldConvertedDate is not _marker:
                    self.removeForwardIndexEntry(oldConvertedDate, documentId)
                    if ConvertedDate is _marker:
                        try:
                            del self._unindex[documentId]
                        except ConflictError:
                            raise
                        except:
                            LOG.error("Should not happen: ConvertedDate was there,"
                                      " now it's not, for document with id %s" %
                                      documentId)
    
                if ConvertedDate is not _marker:
                    self.insertForwardIndexEntry( ConvertedDate, documentId )
                    self._unindex[documentId] = ConvertedDate
                    
                returnStatus = 1
        self._v_lang = None
        return returnStatus
예제 #16
0
 def _get_object_keywords(self, obj, attr):
     newKeywords = getattr(obj, attr, ())
     if safe_callable(newKeywords):
         newKeywords = newKeywords()
     if (isinstance(newKeywords, StringType)
         or isinstance(newKeywords, UnicodeType)): #Python 2.1 compat isinstance
         return (newKeywords,)
     else:
         unique = {}
         try:
             for k in newKeywords:
                 unique[k] = None
         except TypeError:
             # Not a sequence
             return (newKeywords,)
         else:
             return unique.keys()
예제 #17
0
    def addSearchableTextField(self, icc):
        st = self.context.SearchableText
        if safe_callable(st):
            st = st()
        text = self._c(st)
        icc.addContent('SearchableText', text, self.language)

        f = self.context.getFile()
        if not f:
            return

        body = str(f)
        if body:
            mt = f.getContentType()
            if mt == 'text/plain':
                icc.addContent('SearchableText', self._c(body), self.language)
            else:
                icc.addBinary('SearchableText', body, mt, None, self.language)
예제 #18
0
 def _get_object_keywords(self, obj, attr):
     newKeywords = getattr(obj, attr, ())
     if safe_callable(newKeywords):
         try:
             newKeywords = newKeywords()
         except (AttributeError, TypeError):
             return ()
     if not newKeywords:
         return ()
     elif isinstance(newKeywords, basestring):
         return (newKeywords, )
     else:
         unique = {}
         try:
             for k in newKeywords:
                 unique[k] = None
         except TypeError:
             # Not a sequence
             return (newKeywords, )
         else:
             return unique.keys()
예제 #19
0
 def _get_object_keywords(self, obj, attr):
     newKeywords = getattr(obj, attr, ())
     if safe_callable(newKeywords):
         try:
             newKeywords = newKeywords()
         except (AttributeError, TypeError):
             return ()
     if not newKeywords:
         return ()
     elif isinstance(newKeywords, basestring):
         return (newKeywords,)
     else:
         unique = {}
         try:
             for k in newKeywords:
                 unique[k] = None
         except TypeError:
             # Not a sequence
             return (newKeywords,)
         else:
             return unique.keys()
예제 #20
0
    def get_value(self, object):
        attrs = self.index.indexed_attrs
        index = attrs is None and self.index.id or attrs[0]

        path = getattr(object, index, None)
        if path is not None:
            if safe_callable(path):
                path = path()

            if not isinstance(path, (str, tuple)):
                raise TypeError('path value must be string or tuple '
                                'of strings: (%r, %s)' % (index, repr(path)))
        else:
            try:
                path = object.getPhysicalPath()
            except AttributeError:
                return
        return {
            'path': '/'.join(path),
            'depth': len(path) - 1
        }
예제 #21
0
    def get_value(self, object):
        attrs = self.index.indexed_attrs
        index = attrs is None and self.index.id or attrs[0]

        path = getattr(object, index, None)
        if path is not None:
            if safe_callable(path):
                path = path()

            if not isinstance(path, (str, tuple)):
                raise TypeError('path value must be string or tuple '
                                'of strings: (%r, %s)' % (index, repr(path)))
        else:
            try:
                path = object.getPhysicalPath()
            except AttributeError:
                return
        return {
            'path': '/'.join(path),
            'depth': len(path) - 1
        }
예제 #22
0
 def mpi_index_object(self, docId, obj, threshold=None):
     f = getattr(obj, self.id, None)
     if f is not None:
         if safe_callable(f):
             try:
                 paths = f()
             except AttributeError:
                 return 0
         else:
             paths = f
     else:
         try:
             paths = obj.getPhysicalPath()
         except AttributeError:
             return 0
     if paths:
         paths = _recursivePathSplit(paths)
         if not _isSequenceOfSequences(paths):
             paths = [paths]
         vals.append((self.id, paths, None))
         return 1
     return 0
예제 #23
0
 def mpi_index_object(self, docId, obj, threshold=None):
     f = getattr(obj, self.id, None)
     if f is not None:
         if safe_callable(f):
             try:
                 paths = f()
             except AttributeError:
                 return 0
         else:
             paths = f
     else:
         try:
             paths = obj.getPhysicalPath()
         except AttributeError:
             return 0
     if paths:
         paths = _recursivePathSplit(paths)
         if not _isSequenceOfSequences(paths):
             paths = [paths]
         vals.append((self.id, paths, None))
         return 1
     return 0
예제 #24
0
    def index_object(self, docid, obj, threshold=100):
        """ See IPluggableIndex.
        """
        f = getattr(obj, self.id, None)

        if f is not None:
            if safe_callable(f):
                try:
                    path = f()
                except AttributeError:
                    return 0
            else:
                path = f

            if not isinstance(path, (str, tuple)):
                raise TypeError(
                    'path value must be string or tuple of strings')
        else:
            try:
                path = obj.getPhysicalPath()
            except AttributeError:
                return 0

        if isinstance(path, (list, tuple)):
            path = '/' + '/'.join(path[1:])

        comps = filter(None, path.split('/'))

        old_value = self._unindex.get(docid, None)
        if old_value == path:
            return 0

        if old_value is None:
            self._length.change(1)

        for i in range(len(comps)):
            self.insertEntry(comps[i], docid, i)
        self._unindex[docid] = path
        return 1
예제 #25
0
    def index_object(self, docid, obj, threshold=100):
        """ hook for (Z)Catalog """

        f = getattr(obj, self.id, None)
        if f is not None:
            if safe_callable(f):
                try:
                    paths = f()
                except AttributeError:
                    return 0
            else:
                paths = f
        else:
            try:
                paths = obj.getPhysicalPath()
            except AttributeError:
                return 0

        if not paths: return 0
        paths = _recursivePathSplit(paths)
        if not _isSequenceOfSequences(paths):
            paths = [paths]

        if docid in self._unindex:
            if isinstance(self._unindex[docid], set):
                self._unindex[docid] = OOSet(self._unindex[docid])

            unin = set(self._unindex[docid])
            paths_set = {'/'.join(x) for x in paths}

            for oldpath in unin - paths_set:
                self.unindex_paths(docid, (oldpath, ))
        else:
            self._unindex[docid] = OOSet()
            self._length.change(1)

        self.index_paths(docid, paths)

        return 1
예제 #26
0
    def index_object(self, docid, obj, threshold=100):
        """ See IPluggableIndex.
        """
        f = getattr(obj, self.id, None)

        if f is not None:
            if safe_callable(f):
                try:
                    path = f()
                except AttributeError:
                    return 0
            else:
                path = f

            if not isinstance(path, (str, tuple)):
                raise TypeError(
                    'path value must be string or tuple of strings')
        else:
            try:
                path = obj.getPhysicalPath()
            except AttributeError:
                return 0

        if isinstance(path, (list, tuple)):
            path = '/' + '/'.join(path[1:])

        comps = filter(None, path.split('/'))

        old_value = self._unindex.get(docid, None)
        if old_value == path:
            return 0

        if old_value is None:
            self._length.change(1)

        for i in range(len(comps)):
            self.insertEntry(comps[i], docid, i)
        self._unindex[docid] = path
        return 1
예제 #27
0
    def index_object(self, docid, obj, threshold=100):
        """ hook for (Z)Catalog """

        f = getattr(obj, self.id, None)
        if f is not None:
            if safe_callable(f):
                try:
                    paths = f()
                except AttributeError:
                    return 0
            else:
                paths = f
        else:
            try:
                paths = obj.getPhysicalPath()
            except AttributeError:
                return 0

        if not paths: return 0
        paths = _recursivePathSplit(paths)
        if not _isSequenceOfSequences(paths):
            paths = [paths]

        if docid in self._unindex:
            if isinstance(self._unindex[docid], set):
                self._unindex[docid] = OOSet(self._unindex[docid])

            unin = set(self._unindex[docid])
            paths_set = {'/'.join(x) for x in paths}

            for oldpath in unin - paths_set:
                self.unindex_paths(docid, (oldpath,))
        else:
            self._unindex[docid] = OOSet()
            self._length.change(1)

        self.index_paths(docid, paths)

        return 1
    def index_object(self, docid, obj, threshold=100):
        """ hook for (Z)Catalog """

        f = getattr(obj, self.id, None)
        if f is not None:
            if safe_callable(f):
                try:
                    paths = f()
                except AttributeError:
                    return 0
            else:
                paths = f
        else:
            try:
                paths = obj.getPhysicalPath()
            except AttributeError:
                return 0

        if not paths: return 0
        paths = _recursivePathSplit(paths)
        if not _isSequenceOfSequences(paths):
            paths = [paths]

        if docid in self._unindex:
            unin = self._unindex[docid]
            # Migrate old versions of the index to use OOSet
            if isinstance(unin, set):
                unin = self._unindex[docid] = OOSet(unin)
            for oldpath in list(unin):
                if list(oldpath.split('/')) not in paths:
                    self.unindex_paths(docid, (oldpath,))
        else:
            self._unindex[docid] = OOSet()
            self._length.change(1)

        self.index_paths(docid, paths)

        return 1
예제 #29
0
    def index_object(self, docid, obj, threshold=100):
        """ hook for (Z)Catalog """

        f = getattr(obj, self.id, None)
        if f is not None:
            if safe_callable(f):
                try:
                    paths = f()
                except AttributeError:
                    return 0
            else:
                paths = f
        else:
            try:
                paths = obj.getPhysicalPath()
            except AttributeError:
                return 0

        if not paths: return 0
        paths = _recursivePathSplit(paths)
        if not _isSequenceOfSequences(paths):
            paths = [paths]

        if docid in self._unindex:
            unin = self._unindex[docid]
            # Migrate old versions of the index to use OOSet
            if isinstance(unin, set):
                unin = self._unindex[docid] = OOSet(unin)
            for oldpath in list(unin):
                if list(oldpath.split('/')) not in paths:
                    self.unindex_paths(docid, (oldpath, ))
        else:
            self._unindex[docid] = OOSet()
            self._length.change(1)

        self.index_paths(docid, paths)

        return 1
예제 #30
0
    def __call__(self):
        wrapped = IndexableObjectWrapper(self.context, self.catalog)
        text = getattr(wrapped, 'SearchableText')
        if safe_callable(text):
            text = text()

        # Archetypes object: remove id and title
        if IBaseObject.providedBy(self.context):
            for fieldname in ['id', 'title']:
                field = self.context.Schema().getField(fieldname)
                if field is None:
                    continue

                method = field.getIndexAccessor(self.context)
                value = method()
                text = text.replace(value, '', 1)
        # other content (e.g. dexterity): remove title
        elif IContentish.providedBy(self.context):
            text = text.replace(self.context.Title(), '', 1)

        # Strip html tags
        text = re.sub('<[^<]+?>', '', text)

        return text
예제 #31
0
 def addSearchableTextField(self, icc):
     st = self.context.SearchableText
     if safe_callable(st):
         st = st()
     text = self._c(st)
     icc.addContent('SearchableText', text, self.language)
예제 #32
0
    def index_object(self, documentId, obj, threshold=None):
        """index an object, normalizing the indexed value to an integer

           o Normalized value has granularity of one minute.

           o Objects which have 'None' as indexed value are *omitted*,
             by design.

           o Repeat by recurdef - a RFC2445 reccurence definition string

        """
        returnStatus = 0

        try:
            date_attr = getattr(obj, self.id)
            if safe_callable(date_attr):
                date_attr = date_attr()
        except AttributeError:
            return returnStatus

        recurdef = getattr(obj, self.attr_recurdef, None)
        if safe_callable(recurdef):
            recurdef = recurdef()

        if not recurdef:
            dates = [pydt(date_attr)]
        else:
            until = getattr(obj, self.attr_until, None)
            if safe_callable(until):
                until = until()

            dates = recurrence_sequence_ical(date_attr,
                                             recrule=recurdef,
                                             until=until)

        newvalues = IISet(map(dt2int, dates))
        oldvalues = self._unindex.get(documentId, _marker)
        if oldvalues is not _marker:
            oldvalues = IISet(oldvalues)

        if oldvalues is not _marker and newvalues is not _marker\
            and not difference(newvalues, oldvalues)\
            and not difference(oldvalues, newvalues):
            # difference is calculated relative to first argument, so we have to
            # use it twice here
            return returnStatus

        if oldvalues is not _marker:
            for oldvalue in oldvalues:
                self.removeForwardIndexEntry(oldvalue, documentId)
            if newvalues is _marker:
                try:
                    del self._unindex[documentId]
                except ConflictError:
                    raise
                except:
                    LOG.error("Should not happen: oldvalues was there,"
                              " now it's not, for document with id %s" %
                              documentId)

        if newvalues is not _marker:
            inserted = False
            for value in newvalues:
                self.insertForwardIndexEntry(value, documentId)
                inserted = True
            if inserted:
                # store tuple values in reverse index entries for sorting
                self._unindex[documentId] = tuple(newvalues)
                returnStatus = 1

        return returnStatus
    def index_object(self, documentId, obj, threshold=None):
        """ Index an object:
        'documentId' is the integer id of the document

        'obj' is the object to be indexed

        'threshold' is the number of words to process between
        commiting subtransactions.  If 'None' subtransactions are
        disabled. """

        # sniff the object for our 'id', the 'document source' of the
        # index is this attribute.  If it smells callable, call it.
        try:
            source = getattr(obj, self.id)
            if safe_callable(source):
                source = source()

            if not isinstance(source, UnicodeType):
                source = str(source)

        except (AttributeError, TypeError):
            return 0

        # sniff the object for 'id'+'_encoding'

        try:
            encoding = getattr(obj, self.id+'_encoding')
            if safe_callable(encoding ):
                encoding = str(encoding())
            else:
                encoding = str(encoding)
        except (AttributeError, TypeError):
            encoding = 'latin1'

        lexicon = self.getLexicon()

        splitter = lexicon.Splitter

        wordScores = OIBTree()
        last = None

        # Run through the words and score them

        for word in list(splitter(source,encoding=encoding)):
            if word[0] == '\"':
                last = self._subindex(word[1:-1], wordScores, last, splitter)
            else:
                if word==last: continue
                last=word
                wordScores[word]=wordScores.get(word,0)+1

        # Convert scores to use wids:
        widScores=IIBucket()
        getWid=lexicon.getWordId
        for word, score in wordScores.items():
            widScores[getWid(word)]=score

        del wordScores

        currentWids=IISet(self._unindex.get(documentId, []))

        # Get rid of document words that are no longer indexed
        self.unindex_objectWids(documentId, difference(currentWids, widScores))

        # Now index the words. Note that the new xIBTrees are clever
        # enough to do nothing when there isn't a change. Woo hoo.
        insert=self.insertForwardIndexEntry
        for wid, score in widScores.items():
            insert(wid, documentId, score)

        # Save the unindexing info if it's changed:
        wids=widScores.keys()
        if wids != currentWids.keys():
            self._unindex[documentId]=wids

        return len(wids)
예제 #34
0
 def addSearchableTextField(self, icc):
     st = self.context.SearchableText
     if safe_callable(st):
         st = st()
     text = self._c(st)
     icc.addContent('SearchableText', text, self.language)
예제 #35
0
파일: index.py 프로젝트: CGTIC/Plone_SP
    def index_object( self, documentId, obj, threshold=None ):
        """index an object, normalizing the indexed value to an integer

           o Normalized value has granularity of one minute.

           o Objects which have 'None' as indexed value are *omitted*,
             by design.

           o Repeat by recurdef - a RFC2445 reccurence definition string

        """
        returnStatus = 0

        try:
            date_attr = getattr( obj, self.id )
            if safe_callable( date_attr ):
                date_attr = date_attr()
        except AttributeError:
            return returnStatus

        recurdef = getattr(obj, self.attr_recurdef, None)
        if safe_callable(recurdef):
            recurdef = recurdef()

        if not recurdef:
            dates = [pydt(date_attr)]
        else:
            until = getattr(obj, self.attr_until, None)
            if safe_callable(until):
                until = until()

            dates = recurrence_sequence_ical(date_attr, recrule=recurdef, until=until)

        newvalues = IISet(map(dt2int, dates))
        oldvalues = self._unindex.get( documentId, _marker )
        if oldvalues is not _marker:
            oldvalues = IISet(oldvalues)

        if oldvalues is not _marker and newvalues is not _marker\
            and not difference(newvalues, oldvalues)\
            and not difference(oldvalues, newvalues):
            # difference is calculated relative to first argument, so we have to
            # use it twice here
            return returnStatus

        if oldvalues is not _marker:
            for oldvalue in oldvalues:
                self.removeForwardIndexEntry(oldvalue, documentId)
            if newvalues is _marker:
                try:
                    del self._unindex[documentId]
                except ConflictError:
                    raise
                except:
                    LOG.error("Should not happen: oldvalues was there,"
                                 " now it's not, for document with id %s" %
                                   documentId)

        if newvalues is not _marker:
            inserted = False
            for value in newvalues:
                self.insertForwardIndexEntry( value, documentId )
                inserted = True
            if inserted:
                # store tuple values in reverse index entries for sorting
                self._unindex[documentId] = tuple(newvalues)
                returnStatus = 1

        return returnStatus
예제 #36
0
    def index_object(self, documentId, obj, threshold=None):
        """ Index an object:
        'documentId' is the integer id of the document

        'obj' is the object to be indexed

        'threshold' is the number of words to process between
        commiting subtransactions.  If 'None' subtransactions are
        disabled. """

        # sniff the object for our 'id', the 'document source' of the
        # index is this attribute.  If it smells callable, call it.
        try:
            source = getattr(obj, self.id)
            if safe_callable(source):
                source = source()

            if not isinstance(source, UnicodeType):
                source = str(source)

        except (AttributeError, TypeError):
            return 0

        # sniff the object for 'id'+'_encoding'

        try:
            encoding = getattr(obj, self.id + '_encoding')
            if safe_callable(encoding):
                encoding = str(encoding())
            else:
                encoding = str(encoding)
        except (AttributeError, TypeError):
            encoding = 'latin1'

        lexicon = self.getLexicon()

        splitter = lexicon.Splitter

        wordScores = OIBTree()
        last = None

        # Run through the words and score them

        for word in list(splitter(source, encoding=encoding)):
            if word[0] == '\"':
                last = self._subindex(word[1:-1], wordScores, last, splitter)
            else:
                if word == last: continue
                last = word
                wordScores[word] = wordScores.get(word, 0) + 1

        # Convert scores to use wids:
        widScores = IIBucket()
        getWid = lexicon.getWordId
        for word, score in wordScores.items():
            widScores[getWid(word)] = score

        del wordScores

        currentWids = IISet(self._unindex.get(documentId, []))

        # Get rid of document words that are no longer indexed
        self.unindex_objectWids(documentId, difference(currentWids, widScores))

        # Now index the words. Note that the new xIBTrees are clever
        # enough to do nothing when there isn't a change. Woo hoo.
        insert = self.insertForwardIndexEntry
        for wid, score in widScores.items():
            insert(wid, documentId, score)

        # Save the unindexing info if it's changed:
        wids = widScores.keys()
        if wids != currentWids.keys():
            self._unindex[documentId] = wids

        return len(wids)