Search API: enforce obey_over18

Do not include nsfw results for api and rss requests when obey_over18=true.
This commit is contained in:
Florence Yeun
2015-03-30 15:26:02 -07:00
parent 268a629713
commit fe2fc34ca4
3 changed files with 64 additions and 20 deletions

View File

@@ -36,7 +36,7 @@ from r2 import config
from r2.models import *
from r2.models.recommend import ExploreSettings
from r2.config import feature
from r2.config.extensions import is_api
from r2.config.extensions import is_api, API_TYPES, RSS_TYPES
from r2.lib import hooks, recommender, embeds, pages
from r2.lib.pages import *
from r2.lib.pages.things import hot_links_by_url_listing
@@ -905,7 +905,15 @@ class FrontController(RedditController):
@api_doc(api_section.subreddits, uri='/subreddits/search', supports_rss=True)
def GET_search_reddits(self, query, reverse, after, count, num):
"""Search subreddits by title and description."""
q = SubredditSearchQuery(query)
# show NSFW to API and RSS users unless obey_over18=true
is_api_or_rss = (c.render_style in API_TYPES
or c.render_style in RSS_TYPES)
if is_api_or_rss and c.obey_over18 and not c.over18:
include_over18 = False
else:
include_over18 = True
q = SubredditSearchQuery(query, include_over18=include_over18)
results, etime, spane = self._search(q, num=num, reverse=reverse,
after=after, count=count,
@@ -946,10 +954,19 @@ class FrontController(RedditController):
if not syntax:
syntax = SearchQuery.default_syntax
# show NSFW to API and RSS users unless obey_over18=true
is_api_or_rss = (c.render_style in API_TYPES
or c.render_style in RSS_TYPES)
if is_api_or_rss and c.obey_over18 and not c.over18:
include_over18 = False
else:
include_over18 = True
try:
cleanup_message = None
try:
q = SearchQuery(query, site, sort,
q = SearchQuery(query, site, sort=sort,
include_over18=include_over18,
recent=recent, syntax=syntax)
results, etime, spane = self._search(q, num=num, after=after,
reverse=reverse,
@@ -962,7 +979,9 @@ class FrontController(RedditController):
cleaned = re.sub("[^\w\s]+", " ", query)
cleaned = cleaned.lower().strip()
q = SearchQuery(cleaned, site, sort, recent=recent)
q = SearchQuery(cleaned, site, sort=sort,
include_over18=include_over18,
recent=recent)
results, etime, spane = self._search(q, num=num,
after=after,
reverse=reverse,

View File

@@ -802,7 +802,7 @@ def _encode_query(query, bq, faceting, size, start, rank, return_fields):
params = {}
if bq:
params["bq"] = bq
else:
if query:
params["q"] = query
params["results-type"] = "json"
params["size"] = size
@@ -832,7 +832,7 @@ class CloudSearchQuery(object):
lucene_parser = None
def __init__(self, query, sr=None, sort=None, syntax=None, raw_sort=None,
faceting=None, recent=None):
faceting=None, recent=None, include_over18=True):
if syntax is None:
syntax = self.default_syntax
elif syntax not in self.known_syntaxes:
@@ -848,6 +848,7 @@ class CloudSearchQuery(object):
self.sort = self.sorts[sort]
self._recent = recent
self.recent = self.recents[recent]
self.include_over18 = include_over18
self.faceting = faceting
self.bq = u''
self.results = None
@@ -874,15 +875,25 @@ class CloudSearchQuery(object):
self.bq = self.customize_query(bq)
elif self.syntax == "plain":
q = self.query.encode('utf-8')
self.bq = self.customize_query()
if g.sqlprinting:
g.log.info("%s", self)
return self._run_cached(q, self.bq.encode('utf-8'), self.sort,
self.faceting, start=start, num=num,
_update=_update)
def customize_query(self, bq):
def customize_query(self, bq=u''):
return bq
@classmethod
def create_boolean_query(cls, queries):
'''Return an AND clause combining all queries'''
if len(queries) > 1:
return '(and ' + ' '.join(queries) + ')'
elif queries:
return queries[0]
return u''
def __repr__(self):
'''Return a string representation of this query'''
result = ["<", self.__class__.__name__, "> query:",
@@ -984,25 +995,20 @@ class LinkSearchQuery(CloudSearchQuery):
known_syntaxes = ("cloudsearch", "lucene", "plain")
default_syntax = "lucene"
def customize_query(self, bq):
queries = [bq]
def customize_query(self, bq=u''):
queries = []
if bq:
queries = [bq]
subreddit_query = self._get_sr_restriction(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)
@classmethod
def create_boolean_query(cls, queries):
'''Return an AND clause combining all queries'''
if len(queries) > 1:
bq = '(and ' + ' '.join(queries) + ')'
else:
bq = queries[0]
return bq
@staticmethod
def _restrict_recent(recent):
now = datetime.now(g.tz)
@@ -1058,3 +1064,11 @@ class SubredditSearchQuery(CloudSearchQuery):
known_syntaxes = ("plain",)
default_syntax = "plain"
def customize_query(self, bq=u''):
queries = []
if bq:
queries = [bq]
if not self.include_over18:
queries.append('over18:0')
return self.create_boolean_query(queries)

View File

@@ -31,6 +31,7 @@ import time
from pylons import c, g, request
from pylons.i18n import _
from r2.config.extensions import API_TYPES, RSS_TYPES
from r2.lib.comment_tree import (
conversation,
link_comments_and_sort,
@@ -687,8 +688,18 @@ class SearchBuilder(IDBuilder):
elif (self.skip_deleted_authors and
getattr(item, "author", None) and item.author._deleted):
return False
else:
return True
# show NSFW to API and RSS users unless obey_over18=true
is_api_or_rss = (c.render_style in API_TYPES
or c.render_style in RSS_TYPES)
if is_api_or_rss and c.obey_over18 and not c.over18:
is_nsfw = (item.over_18 or
(hasattr(item, 'subreddit') and item.subreddit.over_18))
if is_nsfw:
return False
# currently showing NSFW content by default in search
return True
class WikiRevisionBuilder(QueryBuilder):
show_extended = True