diff --git a/r2/r2/controllers/reddit_base.py b/r2/r2/controllers/reddit_base.py index acf5edbeb..387eed3ce 100644 --- a/r2/r2/controllers/reddit_base.py +++ b/r2/r2/controllers/reddit_base.py @@ -78,6 +78,7 @@ from r2.lib.validator import ( ) from r2.models import ( All, + AllMinus, check_request, DefaultSR, DomainSR, @@ -338,6 +339,16 @@ def set_subreddit(): else: sr_ids = [sr._id for sr in srs] c.site = MultiReddit(sr_ids, sr_name) + elif '-' in sr_name: + sr_names = sr_name.split('-') + if not sr_names[0].lower() == All.name.lower(): + abort(404) + srs = Subreddit._by_name(sr_names[1:], stale=can_stale).values() + srs = [sr for sr in srs if not isinstance(sr, FakeSubreddit)] + if not srs: + c.site = All + else: + c.site = AllMinus(srs) else: try: c.site = Subreddit._by_name(sr_name, stale=can_stale) diff --git a/r2/r2/models/subreddit.py b/r2/r2/models/subreddit.py index c4e8178f1..c662c8b80 100644 --- a/r2/r2/models/subreddit.py +++ b/r2/r2/models/subreddit.py @@ -973,6 +973,29 @@ class AllSR(FakeSubreddit): return None +class AllMinus(AllSR): + name = 'minus' + + def __init__(self, srs): + AllSR.__init__(self) + self.srs = srs + self.sr_ids = [sr._id for sr in srs] + + @property + def title(self): + return 'all minus ' + ' '.join(sr.name for sr in self.srs) + + @property + def path(self): + return '/r/all-' + '-'.join(sr.name for sr in self.srs) + + def get_links(self, sort, time): + from r2.models import Link + from r2.lib.db.operators import not_ + q = AllSR.get_links(self, sort, time) + q._filter(not_(Link.c.sr_id.in_(self.sr_ids))) + return q + class _DefaultSR(FakeSubreddit): #notice the space before reddit.com name = ' reddit.com'