[Product-Developers] Re: Catalog search problems

Swank, Craig Craig_Swank at nrel.gov
Fri Mar 7 15:36:24 UTC 2008


This query took place in a view class of my product.  I was also trying it
in a Clouseau prompt, but I think there is something wrong with that in a
buildout.

I just got my view working again, but unfortunately I don't understand why
yet.  I guess I couldn't hurt to paste the code from both versions in case
someone is able to spot the problem easily.  I'm sure I made a boneheaded
mistake, but I still say my catalog query should have worked.

Here is the current version that works:

from zope.interface import implements, Interface

from DateTime import DateTime

import datetime
from dateutil.relativedelta import relativedelta

from Products.Five.browser import BrowserView
from Products.CMFCore.utils import getToolByName
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile

from nrel.ftir import ftirMessageFactory as _


class IFtirRecordList(Interface):
    """
    FtirRecordList view interface
    """

    def test():
        """ test method"""


class FtirRecordList(BrowserView):
    """
    FtirRecordList browser view
    """
    implements(IFtirRecordList)
    
    __call__ = ViewPageTemplateFile('ftirrecordlist.pt')

    def __init__(self, context, request):
        
        print 'ftir view init'
        self.context = context
        self.request = request
        self.customer = None
        self.startDateIn = DateTime() #using zope DateTime here because that
is how it is stored in the content
        self.startDateCredited = DateTime() #using zope DateTime here
because that is how it is stored in the content
        self.submitQuery()
        #self.options = self.getOptions()

    @property
    def portal_catalog(self):
        return getToolByName(self.context, 'portal_catalog')

    @property
    def portal(self):
        return getToolByName(self.context, 'portal_url').getPortalObject()

    def test(self):
        """
        test method
        """
        dummy = _(u'a dummy string')

        return {'dummy': dummy}
        
    def getOptions(self):
        """
        This method populates the option boxes with
        unique values from the fields of the objects in the database.
        """
        options = {'customer':[],
                   'organization':[],
                   'sample_number':[],
                   'Title':[],
                   'sample_description':[],
                   'instrument':[],
                   'comments':[],
                   'storage_location':[],
                   'file_number':[],
                   'collaborators':[],
                   'notebook':[]
                   }
        
        self.startDateIn = DateTime() #using zope DateTime here because that
is how it is stored in the content
        self.startDateCredited = DateTime() #using zope DateTime here
because that is how it is stored in the content
        
        for brain in self.brains:
            date_in = getattr(brain, 'date_in')
            date_credited = getattr(brain, 'date_credited')
            if date_in.lessThan(self.startDateIn):
                self.startDateIn = date_in
            if date_credited.lessThan(self.startDateCredited):
                self.startDateCredited = date_credited
            for key, value in options.iteritems():
                data = getattr(brain, key)
                if not data in value:
                    value.append(data)
                   
                   
        options['date_in'] = self.makeDates(self.startDateIn)
        options['date_credited'] = self.makeDates(self.startDateCredited)
        
        self.options = options
        
    def makeDates(self, startDate):
        """
        Takes the startDate and makes a list of strings that represent
        every month from the startDate until today.  This list is used
        in the page template option boxes for the date searches
        """
        print startDate.month()
        today = datetime.datetime.now()
        today = datetime.date(today.year, today.month, today.day)
        startDate = datetime.date(startDate.year(), startDate.month(),
startDate.day()) #using python datetime so dateutil.relativedelta can be
used
        delta = relativedelta(months=+1)
        returnList = []
        while startDate <= today:
            returnList.append('%i/%i' % (startDate.month, startDate.year))
            startDate = startDate + delta
        return returnList
        
    def makeZopeDate(self, dateField):
        """
        Takes a string of the form '1/2005' and returns a zope Date object
        that can be used in a catalog search
        """
        
        date = self.request.get(dateField)
        
        
        if date == '' or date is None or date == 'start' or date == 'end':
            return None
        month, year = date.split('/')
        month = int(month)
        year = int(year)
        
        return DateTime(year, month, 1)
        
        
    def submitQuery(self):
        fields = {'customer' : self.request.get('customer'),
                  'organization' : self.request.get('organization'),
                  'sample_number' : self.request.get('sample_number'),
                  'Title' : self.request.get('title'),
                  'sample_description' :
self.request.get('sample_description'),
                  'instrument' : self.request.get('instrument'),
                  'comments' : self.request.get('comments'),
                  'storage_location' : self.request.get('storage_location'),
                  'file_number' : self.request.get('file_number'),
                  'colaborators' : self.request.get('colaborators'),
                  'notebook' : self.request.get('notebook'),
                  }
        
        query = {'path':{'query':'/'.join(self.context.getPhysicalPath()),
                         'depth' : 1 },
                 'portal_type': 'FtirRecord'}
        
        for key, value in fields.iteritems():
            if value is not None and value != '':
                query[key] = value
        
        date_in_start = self.makeZopeDate('date_in_start')
        date_in_end = self.makeZopeDate('date_in_end')
        if date_in_start is not None and date_in_end is None:
            query['date_in'] = {'query':[date_in_start, DateTime()],
'range':'minmax'}
        elif date_in_start is not None and date_in_end is not None:
            query['date_in'] = {'query':[date_in_start, date_in_end],
'range':'minmax'}
        elif date_in_start is None and date_in_end is not None:
            query['date_in'] = {'query':[self.startDateIn, date_in_end],
'range':'minmax'}
        
        date_credited_start = self.makeZopeDate('date_credited_start')
        date_credited_end = self.makeZopeDate('date_credited_end')
        if date_credited_start is not None and date_credited_end is None:
            query['date_credited'] = {'query':[date_credited_start,
DateTime()], 'range':'minmax'}
        elif date_credited_start is not None and date_credited_end is not
None:
            query['date_credited'] = {'query':[date_credited_start,
date_credited_end], 'range':'minmax'}
        elif date_credited_start is None and date_credited_end is not None:
            query['date_credited'] = {'query':[self.startDateCredited,
date_credited_end], 'range':'minmax'}

        self.brains = self.portal_catalog.searchResults(query)
        self.getOptions()




And here is the previous version that doesn't work




from zope.interface import implements, Interface

from DateTime import DateTime

import datetime
from dateutil.relativedelta import relativedelta

from Products.Five.browser import BrowserView
from Products.CMFCore.utils import getToolByName
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile

from nrel.ftir import ftirMessageFactory as _


class IFtirRecordList(Interface):
    """
    FtirRecordList view interface
    """

    def test():
        """ test method"""


class FtirRecordList(BrowserView):
    """
    FtirRecordList browser view
    """
    implements(IFtirRecordList)
    
    __call__ = ViewPageTemplateFile('ftirrecordlist.pt')

    def __init__(self, context, request):
        print 'ftir view init'
        self.context = context
        self.request = request
        self.customer = None
        self.brains = self.portal_catalog( {'portal_type':'FtirRecord'})
        self.options = self.getOptions()

    @property
    def portal_catalog(self):
        return getToolByName(self.context, 'portal_catalog')

    @property
    def portal(self):
        return getToolByName(self.context, 'portal_url').getPortalObject()

    def test(self):
        """
        test method
        """
        dummy = _(u'a dummy string')

        return {'dummy': dummy}
        
    def getOptions(self):
        """
        This method is called by the page template in order to populate the
option boxes with
        unique values from the fields of the objects in the database.
        """
        
        query = {'path':{'query':'/'.join(self.context.getPhysicalPath()),
                         'depth' : 1 },
                 'portal_type': 'FtirRecord'}
        brains = self.portal_catalog.searchResults(query)
        print 'brains', brains
        
        options = {'customer':[],
                   'organization':[],
                   'sample_number':[],
                   'Title':[],
                   'sample_description':[],
                   'instrument':[],
                   'comments':[],
                   'storage_location':[],
                   'file_number':[],
                   'collaborators':[],
                   'notebook':[]
                   }
        
        self.startDateIn = DateTime() #using zope DateTime here because that
is how it is stored in the content
        self.startDateCredited = DateTime()
        
        for brain in brains:
            date_in = getattr(brain, 'date_in')
            date_credited = getattr(brain, 'date_credited')
            if date_in.lessThan(self.startDateIn):
                self.startDateIn = date_in
            if date_credited.lessThan(self.startDateCredited):
                self.startDateCredited = date_credited
            for key, value in options.iteritems():
                data = getattr(brain, key)
                if not data in value:
                    value.append(data)
                   
                   
        options['date_in'] = self.makeDates(self.startDateIn)
        options['date_credited'] = self.makeDates(self.startDateCredited)
        
        return options
        
    def makeDates(self, startDate):
        """
        Takes the startDate and makes a list of strings that represent
        every month from the startDate until today.  This list is used
        in the page template option boxes for the date searches
        """
        print startDate.month()
        today = datetime.datetime.now()
        today = datetime.date(today.year, today.month, today.day)
        startDate = datetime.date(startDate.year(), startDate.month(),
startDate.day()) #using python datetime
                 #so dateutil.relativedelta can be used

        delta = relativedelta(months=+1)
        returnList = []
        while startDate <= today:
            returnList.append('%i/%i' % (startDate.month, startDate.year))
            startDate = startDate + delta
        return returnList
        
    def makeZopeDate(self, dateField):
        """
        Takes a string of the form '1/2005' and returns a zope Date object
        that can be used in a catalog search
        """
        
        date = self.request.get(dateField)
        
        
        if date == '' or date is None or date == 'start' or date == 'end':
            return None
        month, year = date.split('/')
        month = int(month)
        year = int(year)
        
        return DateTime(year, month, 1)
        
        
    def submitQuery(self):
        fields = {'customer' : self.request.get('customer'),
                  'organization' : self.request.get('organization'),
                  'sample_number' : self.request.get('sample_number'),
                  'Title' : self.request.get('title'),
                  'sample_description' :
self.request.get('sample_description'),
                  'instrument' : self.request.get('instrument'),
                  'comments' : self.request.get('comments'),
                  'storage_location' : self.request.get('storage_location'),
                  'file_number' : self.request.get('file_number'),
                  'colaborators' : self.request.get('colaborators'),
                  'notebook' : self.request.get('notebook'),
                  }
                  
        query = {'path':{'query':'/'.join(self.context.getPhysicalPath()),
                         'depth' : 1 },
                 'portal_type': 'FtirRecord'}
                   
        for key, value in fields.iteritems():
            if value is not None:
                query[key] = value
                
        date_in_start = self.makeZopeDate('date_in_start')
        date_in_end = self.makeZopeDate('date_in_end')
        if date_in_start is not None and date_in_end is None:
            query['date_in'] = {'query':[date_in_start, DateTime()],
'range':'minmax'}
        elif date_in_start is not None and date_in_end is not None:
            query['date_in'] = {'query':[date_in_start, date_in_end],
'range':'minmax'}
        elif date_in_start is None and date_in_end is not None:
            query['date_in'] = {'query':[self.startDateIn, date_in_end],
'range':'minmax'}
            
        date_credited_start = self.makeZopeDate('date_credited_start')
        date_credited_end = self.makeZopeDate('date_credited_end')
        if date_credited_start is not None and date_credited_end is None:
            query['date_credited'] = {'query':[date_credited_start,
DateTime()], 'range':'minmax'}
        elif date_credited_start is not None and date_credited_end is not
None:
            query['date_credited'] = {'query':[date_credited_start,
date_credited_end], 'range':'minmax'}
        elif date_credited_start is None and date_credited_end is not None:
            query['date_credited'] = {'query':[self.startDateCredited,
date_credited_end], 'range':'minmax'}

        
        self.brains = self.portal_catalog.searchResults(query)


On 3/6/08 3:23 PM, "Maurits van Rees" <m.van.rees at zestsoftware.nl> wrote:

> Swank, Craig, on 2008-03-06:
>> Thanks for the reply, Andreas.  Yes, I have tried reindexing, clearing and
>> rebuilding, you name it.  It is almost as if the catalog search is being
>> done on another catalog, but I don't have another catalog.
> 
> You say you query the catalog like this:
> 
> brains = portal_catalog(portal_type="Folder")
> 
> Where do you do that?  Is that in a zopectl debug session?  Because I
> have seen different results while querying the catalog in a zopectl
> debug session ('bin/instance debug' in a normal buildout) than when in
> file system code or a pdb session.





More information about the Product-Developers mailing list