Ejemplo n.º 1
0
 def fields(self, thing):
     '''Return fields relevant to a Link search index'''
     account = self.accounts[thing.author_id]
     sr = self.srs[thing.sr_id]
     return LinkFields(thing, account, sr).fields()
Ejemplo n.º 2
0
class LinkSearchQuery(CloudSearchQuery):
    search_api = g.CLOUDSEARCH_SEARCH_API
    sorts = {
        'relevance': '-relevance',
        'relevance2': '-relevance2',
        'hot': '-hot2',
        'top': '-top',
        'new': '-timestamp',
        'comments': '-num_comments',
    }
    recents = {
        'hour': timedelta(hours=1),
        'day': timedelta(days=1),
        'week': timedelta(days=7),
        'month': timedelta(days=31),
        'year': timedelta(days=366),
        'all': None,
        None: None,
    }
    schema = l2cs.make_schema(LinkFields.lucene_fieldnames())
    lucene_parser = l2cs.make_parser(
        int_fields=LinkFields.lucene_fieldnames(type_=int),
        yesno_fields=LinkFields.lucene_fieldnames(type_="yesno"),
        schema=schema)
    known_syntaxes = g.search_syntaxes
    default_syntax = "lucene"

    def customize_query(self, bq=u''):
        queries = []
        if bq:
            queries = [bq]
        if self.sr:
            subreddit_query = self._restrict_sr(self.sr)
            if subreddit_query:
                queries.append(subreddit_query)
        if self.recent:
            recent_query = self._restrict_recent(self.recent)
            queries.append(recent_query)
        if not self.include_over18:
            queries.append('over18:0')
        return self.create_boolean_query(queries)

    @staticmethod
    def _restrict_recent(recent):
        now = datetime.now(g.tz)
        since = epoch_seconds(now - recent)
        return 'timestamp:%i..' % since

    @staticmethod
    def _restrict_sr(sr):
        '''Return a cloudsearch appropriate query string that restricts
        results to only contain results from sr
        
        '''
        if isinstance(sr, MultiReddit):
            if not sr.sr_ids:
                raise InvalidQuery
            srs = ["sr_id:%s" % sr_id for sr_id in sr.sr_ids]
            return "(or %s)" % ' '.join(srs)
        elif isinstance(sr, DomainSR):
            return "site:'\"%s\"'" % sr.domain
        elif isinstance(sr, FriendsSR):
            if not c.user_is_loggedin or not c.user.friends:
                raise InvalidQuery
            # The query limit is roughly 8k bytes. Limit to 200 friends to
            # avoid getting too close to that limit
            friend_ids = c.user.friends[:200]
            friends = [
                "author_fullname:'%s'" %
                Account._fullname_from_id36(r2utils.to36(id_))
                for id_ in friend_ids
            ]
            return "(or %s)" % ' '.join(friends)
        elif isinstance(sr, AllMinus):
            if not sr.exclude_sr_ids:
                raise InvalidQuery
            exclude_srs = ["sr_id:%s" % sr_id for sr_id in sr.exclude_sr_ids]
            return "(not (or %s))" % ' '.join(exclude_srs)
        elif not isinstance(sr, FakeSubreddit):
            return "sr_id:%s" % sr._id

        return None