import sets
import logging
from Products.QueueCatalog.CatalogEventQueue import CatalogEventQueue, EVENT_TYPES, ADDED_EVENTS
from Products.QueueCatalog.CatalogEventQueue import ADDED, CHANGED, CHANGED_ADDED, REMOVED
from Products.QueueCatalog.CatalogEventQueue import SAFE_POLICY, ALTERNATIVE_POLICY
from Products.QueueCatalog.QueueCatalog import cataloged
from ZODB.POSException import ConflictError
from ZEO.Exceptions import ClientDisconnected
logger = logging.getLogger('event.QueueCatalog')

def _process_queue(self, queue, limit):
    """Process a single queue"""
    catalog = self.getZCatalog()

    if self.getProcessAllIndexes():
        #idxs = None
        idxs = catalog.indexes()
    else:
        cat_indexes = sets.Set(catalog.indexes())
        immediate_indexes = sets.Set(self._immediate_indexes)
        if not immediate_indexes or immediate_indexes==cat_indexes:
            idxs = catalog.indexes() # do all of 'em
        else:
            idxs = list(cat_indexes - immediate_indexes)
    events = queue.process(limit)
    count = 0

    for uid, (t, event) in events.items():
        if event is REMOVED:
            try:
                if cataloged(catalog, uid):
                    catalog.uncatalog_object(uid)
            except (ConflictError, ClientDisconnected):
                logger.error('conflict-error uncataloging object', exc_info=True)
            except:
                logger.error('error uncataloging object', exc_info=True)
        else:
            # add or change
            if event is CHANGED and not cataloged(catalog, uid):
                continue
            # Note that the uid may be relative to the catalog.
            obj = catalog.unrestrictedTraverse(uid, None)
            if obj is not None:
                immediate_metadata = self.getImmediateMetadataUpdate()
                try:
                    catalog.catalog_object(
                        obj, uid, idxs=idxs,
                        update_metadata=not immediate_metadata)
                except (ConflictError, ClientDisconnected):
                    logger.error('conflict-error uncataloging object', exc_info=True)
                    #raise
                except:
                    logger.error('error cataloging object', exc_info=True)

        count = count + 1

    return count
from Products.QueueCatalog.QueueCatalog import QueueCatalog 
QueueCatalog._process_queue = _process_queue
