diff --git a/r2/r2/lib/db/queries.py b/r2/r2/lib/db/queries.py index 14b83dfb2..f144f0fb6 100755 --- a/r2/r2/lib/db/queries.py +++ b/r2/r2/lib/db/queries.py @@ -20,7 +20,7 @@ # Inc. All Rights Reserved. ############################################################################### -from r2.models import Account, Link, Comment, Trial, Vote, SaveHide +from r2.models import Account, Link, Comment, Trial, Vote, SaveHide, Report from r2.models import Message, Inbox, Subreddit, ModContribSR, ModeratorInbox, MultiReddit from r2.lib.db.thing import Thing, Merge from r2.lib.db.operators import asc, desc, timeago @@ -640,6 +640,31 @@ def get_unread_inbox(user): get_unread_messages(user), get_unread_selfreply(user)) +def _user_reported_query(user_id, thing_cls): + rel_cls = Report.rel(Account, thing_cls) + return rel_query(rel_cls, user_id, ('-1', '0', '1')) + # -1: rejected report + # 0: unactioned report + # 1: accepted report + +@cached_userrel_query +def get_user_reported_links(user_id): + return _user_reported_query(user_id, Link) + +@cached_userrel_query +def get_user_reported_comments(user_id): + return _user_reported_query(user_id, Comment) + +@cached_userrel_query +def get_user_reported_messages(user_id): + return _user_reported_query(user_id, Message) + +@merged_cached_query +def get_user_reported(user_id): + return [get_user_reported_links(user_id), + get_user_reported_comments(user_id), + get_user_reported_messages(user_id)] + def add_queries(queries, insert_items=None, delete_items=None, foreground=False): """Adds multiple queries to the query queue. If insert_items or delete_items is specified, the query may not need to be @@ -931,6 +956,13 @@ def _by_author(things, authors=True): else: return ret +def _by_thing1_id(rels): + ret = {} + for rel in tup(rels): + ret.setdefault(rel._thing1_id, []).append(rel) + return ret + + def was_spam_filtered(thing): if (thing._spam and not thing._deleted and getattr(thing, 'verdict', None) != 'mod-removed'): @@ -1103,14 +1135,21 @@ def unban(things, insert=True): changed(things) -def new_report(thing): +def new_report(thing, report_rel): + reporter_id = report_rel._thing1_id + with CachedQueryMutator() as m: if isinstance(thing, Link): m.insert(get_reported_links(thing.sr_id), [thing]) + m.insert(get_user_reported_links(reporter_id), [report_rel]) elif isinstance(thing, Comment): m.insert(get_reported_comments(thing.sr_id), [thing]) + m.insert(get_user_reported_comments(reporter_id), [report_rel]) + elif isinstance(thing, Message): + m.insert(get_user_reported_messages(reporter_id), [report_rel]) -def clear_reports(things): + +def clear_reports(things, rels): query_cache_deletes = [] by_srid = _by_srid(things, srs=False) @@ -1124,6 +1163,25 @@ def clear_reports(things): if comments: query_cache_deletes.append([get_reported_comments(sr_id), comments]) + # delete from user_reported if the report was correct + rels = [r for r in rels if r._name == '1'] + if rels: + link_rels = [r for r in rels if r._type2 == Link] + comment_rels = [r for r in rels if r._type2 == Comment] + message_rels = [r for r in rels if r._type2 == Message] + + rels_to_query = ((link_rels, get_user_reported_links), + (comment_rels, get_user_reported_comments), + (message_rels, get_user_reported_messages)) + + for thing_rels, query in rels_to_query: + if not thing_rels: + continue + + by_thing1_id = _by_thing1_id(thing_rels) + for reporter_id, reporter_rels in by_thing1_id.iteritems(): + query_cache_deletes.append([query(reporter_id), reporter_rels]) + with CachedQueryMutator() as m: for q, deletes in query_cache_deletes: m.delete(q, deletes) diff --git a/r2/r2/models/admintools.py b/r2/r2/models/admintools.py index c0664992e..f160b2222 100644 --- a/r2/r2/models/admintools.py +++ b/r2/r2/models/admintools.py @@ -39,9 +39,7 @@ class AdminTools(object): all_things = tup(things) new_things = [x for x in all_things if not x._spam] - # No need to accept reports on things with _spam=True, - # since nobody can report them in the first place. - Report.accept(new_things, True) + Report.accept(all_things, True) for t in all_things: if getattr(t, "promoted", None) is not None: diff --git a/r2/r2/models/report.py b/r2/r2/models/report.py index 89077488c..1d1f1d9b5 100644 --- a/r2/r2/models/report.py +++ b/r2/r2/models/report.py @@ -71,7 +71,7 @@ class Report(MultiRelation('report', author._incr('reported') # update the reports queue if it exists - queries.new_report(thing) + queries.new_report(thing, r) # if the thing is already marked as spam, accept the report if thing._spam: @@ -101,11 +101,12 @@ class Report(MultiRelation('report', for thing_cls, cls_things in things_by_cls.iteritems(): # look up all of the reports for each thing rel_cls = cls.rel(Account, thing_cls) - rels = rel_cls._query(rel_cls.c._thing2_id == [ x._id for x in cls_things ], - rel_cls.c._name == '0') + thing_ids = [t._id for t in cls_things] + rels = rel_cls._query(rel_cls.c._thing2_id == thing_ids) for r in rels: - r._name = '1' if correct else '-1' - r._commit() + if r._name == '0': + r._name = '1' if correct else '-1' + r._commit() for thing in cls_things: if thing.reported > 0: @@ -113,6 +114,5 @@ class Report(MultiRelation('report', thing._commit() to_clear.append(thing) - if to_clear: - queries.clear_reports(to_clear) + queries.clear_reports(to_clear, rels)