def __call__(self):
     form = self.request.form
     if "form.button.save" in form:
         if "tags" in form:
             tags = form["tags"].split(";")
             uids = form.get("UID", [])
             brains = self.portal_catalog(UID=uids)
             for brain in brains:
                 ob = brain.getObject()
                 otags = list(ob.Subject())
                 ob.setSubject(set(otags + tags))
                 ob.indexObject()
             status = _(u"documents tagged")
             IStatusMessage(self.request).addStatusMessage(status, type="info")
         else:
             status = _(u"No value to tag supplied")
             IStatusMessage(self.request).addStatusMessage(status, type="error")
     return self.template()
 def actionUpdate(self, action, data):
     min_score = data['min_score']
     same_query = data['same_query']
     max_results = data['max_results']
     max_related = data['max_related']
     basequery = self.context.buildQuery()
     if basequery is None:
         return LazyCat([[]])
     baseresults = self.portal_catalog.searchResults(basequery)
     uids = [brain.UID for brain in baseresults]
     service = SimService()
     for brain in baseresults:
         if len(brain.getRawRelatedItems) >= max_related:
             continue
         response = service.query(brain.UID, min_score=min_score)
         if response['status'] == 'OK':
             simserveritems = response['response']
             suids =[s[0] for s in simserveritems
                         if brain.UID != s[0]]
             if same_query:
                 suids =[s for s in suids if s in uids]
             if suids:
                 related = brain.getRawRelatedItems
                 if len(related) < max_results:
                     new_related = related +[s for s in suids
                                     if s not in related]
                 else:
                     continue
                 if len(new_related[:max_results]) > len(related):
                     ob = brain.getObject()
                     ob.setRelatedItems(new_related[:max_results])
                     logger.info('set %i new relations to "%s"' %
                         (len(new_related[:max_results]) - len(related),
                          brain.Title))
         elif response['status'] == 'NOTFOUND':
             logger.info('document "%s" not in index' % brain.Title)
         else:
             IStatusMessage(self.request).addStatusMessage(
                     response['response'], type='error')
     status = _(u'related items set')
     IStatusMessage(self.request).addStatusMessage(status, type='info')
     self.request.response.redirect(self.next_url)
    def queryCatalog(self, *args, **kw):
        """Invoke the catalog using our criteria to augment any passed
        in query before calling the catalog.
        """
        basequery = self.buildQuery()
        if basequery is None:
            return LazyCat([[]])
        portal_catalog = getToolByName(self, 'portal_catalog')
        baseresults = portal_catalog.searchResults(basequery)
        uids = [brain.UID for brain in baseresults]
        service = SimService()
        min_score = self.getMin_score()
        response = service.query(documents=uids, min_score=min_score, max_results=200)
        if response['status']=='OK':
            indexed_documents = response['response'].keys()
            similar_documents = []
            for values in response['response'].itervalues():
                similar_documents +=[k[0] for k in values]
            unique_docs = list(set(similar_documents))
            doc_count={}
            for doc in unique_docs:
                count = similar_documents.count(doc)
                docs = doc_count.get(count, [])
                docs.append(doc)
                doc_count[count] = docs
            min_similar = self.getMin_similar()
            for k, v in doc_count.iteritems():
                if (k*100)/len(indexed_documents) < min_similar:
                    for doc in v:
                        if doc in unique_docs:
                            unique_docs.remove(doc)
            query={}
            citerions_to_apply = self.getCiterions_to_apply()
            if citerions_to_apply:
                status =''
                if self.hasSortCriterion() and self.getExclude_orig():
                    if len(citerions_to_apply)+1 == len(self.listCriteria()):
                        status = _('You excluded all items')
                elif self.getExclude_orig():
                    if len(citerions_to_apply)== len(self.listCriteria()):
                        status = _('You excluded all items')
                if status:
                    i = zope.security.management.getInteraction()
                    for p in i.participations:
                        if zope.publisher.interfaces.IRequest.providedBy(p):
                            request = p
                            break
                    #IStatusMessage(request).addStatusMessage(
                    #                status, type='error')
                criteria = self.listCriteria()
                for criterion in criteria:
                    for key, value in criterion.getCriteriaItems():
                        if key in citerions_to_apply:
                            query[key]=value
            if self.getExclude_orig():
                for doc in indexed_documents:
                    if doc in unique_docs:
                        unique_docs.remove(doc)
            else:
                if not citerions_to_apply:
                    unique_docs += uids

            if self.hasSortCriterion():
                criterion = self.getSortCriterion()
                sort_order = None
                sort_on = criterion.getCriteriaItems()[0][1]
                if len(criterion.getCriteriaItems())==2:
                    sort_order = criterion.getCriteriaItems()[1][1]
                    query['sort_on'] = sort_on
                    query['sort_order'] = sort_order
                    query['UID'] = unique_docs
                return portal_catalog(**query)
            else:
                sim_relevance = {}
                for values in response['response'].itervalues():
                    for v in values:
                        rel = sim_relevance.get(v[0],0)
                        rel += v[1]
                        sim_relevance[v[0]] = rel
                by_relevance = sorted(sim_relevance.items(),
                        key=itemgetter(1), reverse=True)
                query['UID'] = unique_docs
                brains= portal_catalog(**query)
                uid_brains ={}
                for brain in brains:
                    uid_brains[brain.UID] = brain
                result = []
                for r in by_relevance:
                    if r[0] in uid_brains:
                        result.append(uid_brains[r[0]])
                return result
from Products.statusmessages.interfaces import IStatusMessage

from collective.simserver.related.config import PROJECTNAME

from collective.simserver.core.utils import SimService
from collective.simserver.related import simserverMessageFactory as _
from collective.simserver.related.interfaces import ISimserverCollection

SimserverTopicSchema = topic.ATTopicSchema.copy() + atapi.Schema((

    atapi.FloatField(
        'min_score',
        required = True,
        default = 0.7,
        widget=atapi.DecimalWidget(
            label=_(u"Minimal score"),
            description=_(u"Minimal score of related items"),
            visible={'edit': 'visible', 'view': 'invisible'},
        ),
        validators=('isDecimal'),
    ),

    atapi.IntegerField(
        'min_similar',
        required = True,
        default = 30,
        widget = atapi.IntegerWidget(
            label = u'related to % items',
            description=_(u"The content must be similar to at least this percentage of basevalues"),
            visible={'edit': 'visible', 'view': 'visible'},
        ),
 def actionCancel(self, action, data):
     status = _(u'canceled')
     IStatusMessage(self.request).addStatusMessage(status, type='info')
     self.request.response.redirect(self.next_url)