From 805a9a4b79e37e7a314df773ee6d65a8dbffe780 Mon Sep 17 00:00:00 2001 From: Joshua Uziel Date: Thu, 17 Mar 2016 16:17:42 -0700 Subject: [PATCH] Onboarding: Featured subreddits API endpoint Endpoint for retrieving subreddits to make new users aware of without actually subscribing them while doing the onboarding process. The list of featured subreddits will be managed separately from the default ones. For testing purposes, we add a subreddit to show up via the inject_test_data script. --- r2/r2/config/routing.py | 3 +- r2/r2/controllers/listingcontroller.py | 10 +++++++ r2/r2/lib/menus.py | 1 + r2/r2/lib/pages/pages.py | 2 ++ r2/r2/models/subreddit.py | 38 +++++++++++++++++++++++--- scripts/inject_test_data.py | 2 ++ 6 files changed, 51 insertions(+), 5 deletions(-) diff --git a/r2/r2/config/routing.py b/r2/r2/config/routing.py index 311eda370..ea9b12a6c 100644 --- a/r2/r2/config/routing.py +++ b/r2/r2/config/routing.py @@ -102,7 +102,8 @@ def make_map(config): mc('/subreddits/login', controller='forms', action='login') mc('/subreddits/:where', controller='reddits', action='listing', where='popular', conditions={'function':not_in_sr}, - requirements=dict(where="popular|new|banned|employee|gold|default|quarantine")) + requirements=dict(where="popular|new|banned|employee|gold|default|" + "quarantine|featured")) # If no subreddit is specified, might as well show a list of 'em. mc('/r', controller='redirect', action='redirect', dest='/subreddits') diff --git a/r2/r2/controllers/listingcontroller.py b/r2/r2/controllers/listingcontroller.py index 1c2d33b0a..00f1ea845 100644 --- a/r2/r2/controllers/listingcontroller.py +++ b/r2/r2/controllers/listingcontroller.py @@ -1453,6 +1453,11 @@ class RedditsController(ListingController): def keep_fn(self): base_keep_fn = ListingController.keep_fn(self) def keep(item): + if self.where == 'featured': + if item.type not in ('public', 'restricted'): + return False + if not item.discoverable: + return False return base_keep_fn(item) and (c.over18 or not item.over_18) return keep @@ -1510,6 +1515,11 @@ class RedditsController(ListingController): sr._fullname for sr in Subreddit.default_subreddits(ids=False) ] + elif self.where == 'featured': + return [ + sr._fullname + for sr in Subreddit.featured_subreddits() + ] else: reddits = Subreddit._query( write_cache = True, read_cache = True, diff --git a/r2/r2/lib/menus.py b/r2/r2/lib/menus.py index 5e2901d42..e100826c0 100644 --- a/r2/r2/lib/menus.py +++ b/r2/r2/lib/menus.py @@ -153,6 +153,7 @@ menu = MenuHandler(hot = _('hot'), create = _("create"), mine = _("my subreddits"), quarantine = _("quarantine"), + featured = _("featured"), i18n = _("help translate"), errors = _("errors"), diff --git a/r2/r2/lib/pages/pages.py b/r2/r2/lib/pages/pages.py index 45977059e..e846a41eb 100644 --- a/r2/r2/lib/pages/pages.py +++ b/r2/r2/lib/pages/pages.py @@ -2245,6 +2245,8 @@ class SubredditsPage(Reddit): buttons.append(NamedButton("gold")) if c.user_is_admin: buttons.append(NamedButton("quarantine")) + if c.user_is_admin: + buttons.append(NamedButton("featured")) if c.user_is_loggedin: #add the aliases to "my reddits" stays highlighted buttons.append(NamedButton("mine", diff --git a/r2/r2/models/subreddit.py b/r2/r2/models/subreddit.py index 3a742b4f2..bdc77ba8e 100644 --- a/r2/r2/models/subreddit.py +++ b/r2/r2/models/subreddit.py @@ -1056,6 +1056,17 @@ class Subreddit(Thing, Printable, BaseSite): else: return srs + @classmethod + def featured_subreddits(cls): + """Return the curated list of subreddits shown during onboarding.""" + location = get_user_location() + srids = LocalizedFeaturedSubreddits.get_featured(location) + + srs = Subreddit._byID(srids, data=True, return_dict=False, stale=True) + srs = filter(lambda sr: sr.discoverable, srs) + + return srs + @classmethod @memoize('random_reddits', time = 1800) def random_reddits_cached(cls, user_name, sr_ids, limit): @@ -1971,9 +1982,9 @@ class TooManySubredditsError(Exception): pass -class LocalizedDefaultSubreddits(tdb_cassandra.View): +class BaseLocalizedSubreddits(tdb_cassandra.View): """Mapping of location to subreddit ids""" - _use_db = True + _use_db = False _compare_with = tdb_cassandra.ASCII_TYPE _read_consistency_level = tdb_cassandra.CL.QUORUM _write_consistency_level = tdb_cassandra.CL.QUORUM @@ -1982,7 +1993,6 @@ class LocalizedDefaultSubreddits(tdb_cassandra.View): "default_validation_class": tdb_cassandra.ASCII_TYPE, } GLOBAL = "GLOBAL" - CACHE_PREFIX = "localized_defaults" @classmethod def _rowkey(cls, location): @@ -2046,7 +2056,7 @@ class LocalizedDefaultSubreddits(tdb_cassandra.View): return cls.get_srids(cls.GLOBAL) @classmethod - def get_defaults(cls, location): + def get_localized_srs(cls, location): location_key = cls._rowkey(location) if location else None global_key = cls._rowkey(cls.GLOBAL) keys = filter(None, [location_key, global_key]) @@ -2060,6 +2070,26 @@ class LocalizedDefaultSubreddits(tdb_cassandra.View): return ids_by_location[global_key] +class LocalizedDefaultSubreddits(BaseLocalizedSubreddits): + _use_db = True + _type_prefix = "LocalizedDefaultSubreddits" + CACHE_PREFIX = "localized_defaults" + + @classmethod + def get_defaults(cls, location): + return cls.get_localized_srs(location) + + +class LocalizedFeaturedSubreddits(BaseLocalizedSubreddits): + _use_db = True + _type_prefix = "LocalizedFeaturedSubreddits" + CACHE_PREFIX = "localized_featured" + + @classmethod + def get_featured(cls, location): + return cls.get_localized_srs(location) + + class LabeledMulti(tdb_cassandra.Thing, MultiReddit): """Thing with special columns that hold Subreddit ids and properties.""" _use_db = True diff --git a/scripts/inject_test_data.py b/scripts/inject_test_data.py index 14d651842..db5f96e57 100644 --- a/scripts/inject_test_data.py +++ b/scripts/inject_test_data.py @@ -42,6 +42,7 @@ from r2.models import ( Comment, Link, LocalizedDefaultSubreddits, + LocalizedFeaturedSubreddits, NotFound, register, Subreddit, @@ -356,3 +357,4 @@ def inject_test_data(num_links=25, num_comments=25, num_votes=5): srs = [Subreddit._by_name(n) for n in ("pics", "videos", "askhistorians")] LocalizedDefaultSubreddits.set_global_srs(srs) + LocalizedFeaturedSubreddits.set_global_srs([Subreddit._by_name('pics')])