def get_recommendations(srs, count=10, source=SRC_MULTIREDDITS, to_omit=None, match_set=True, over18=False): """Return subreddits recommended if you like the given subreddits. Args: - srs is one Subreddit object or a list of Subreddits - count is total number of results to return - source is a prefix telling which set of recommendations to use - to_omit is a single or list of subreddit id36s that should not be be included. (Useful for omitting recs that were already rejected.) - match_set=True will return recs that are similar to each other, useful for matching the "theme" of the original set - over18 content is filtered unless over18=True or one of the original srs is over18 """ srs = tup(srs) to_omit = tup(to_omit) if to_omit else [] # fetch more recs than requested because some might get filtered out rec_id36s = SRRecommendation.for_srs([sr._id36 for sr in srs], to_omit, count * 2, source, match_set=match_set) # always check for private subreddits at runtime since type might change rec_srs = Subreddit._byID36(rec_id36s, return_dict=False) filtered = [sr for sr in rec_srs if is_visible(sr)] # don't recommend adult srs unless one of the originals was over_18 if not over18 and not any(sr.over_18 for sr in srs): filtered = [sr for sr in filtered if not sr.over_18] return filtered[:count]
def get_recommendations(srs, count=10, source=SRC_MULTIREDDITS, to_omit=None): """Return subreddits recommended if you like the given subreddits. Args: - srs is one Subreddit object or a list of Subreddits - count is total number of results to return - source is a prefix telling which set of recommendations to use - to_omit is one Subreddit object or a list of Subreddits that should not be included. (Useful for omitting recs that were already rejected.) """ srs = tup(srs) to_omit = tup(to_omit) if to_omit else [] # fetch more recs than requested because some might get filtered out rec_id36s = SRRecommendation.for_srs([sr._id36 for sr in srs], [o._id36 for o in to_omit], count * 2, source) # always check for private subreddits at runtime since type might change rec_srs = Subreddit._byID36(rec_id36s, return_dict=False) filtered = [sr for sr in rec_srs if sr.type != 'private'] # don't recommend adult srs unless one of the originals was over_18 if not any(sr.over_18 for sr in srs): filtered = [sr for sr in filtered if not sr.over_18] return filtered[:count]
def get_recommendations(srs, count=10, source=SRC_MULTIREDDITS, to_omit=None): """Return subreddits recommended if you like the given subreddits. Args: - srs is one Subreddit object or a list of Subreddits - count is total number of results to return - source is a prefix telling which set of recommendations to use - to_omit is one Subreddit object or a list of Subreddits that should not be included. (Useful for omitting recs that were already rejected.) """ srs = tup(srs) to_omit = tup(to_omit) if to_omit else [] # fetch more recs than requested because some might get filtered out rec_id36s = SRRecommendation.for_srs([sr._id36 for sr in srs], [o._id36 for o in to_omit], count * 2, source) # always check for private subreddits at runtime since type might change rec_srs = Subreddit._byID36(rec_id36s, return_dict=False) filtered = [sr for sr in rec_srs if sr.type != "private"] # don't recommend adult srs unless one of the originals was over_18 if not any(sr.over_18 for sr in srs): filtered = [sr for sr in filtered if not sr.over_18] return filtered[:count]
def process_message(msg): msg_dict = json.loads(msg.body) if msg_dict["event"] == "new_message": message_id36 = msg_dict["message_id36"] message = Message._byID36(message_id36, data=True) send_modmail_email(message) elif msg_dict["event"] == "blocked_muted": subreddit_id36 = msg_dict["subreddit_id36"] sr = Subreddit._byID36(subreddit_id36, data=True) parent_id36 = msg_dict["parent_id36"] parent = Message._byID36(parent_id36, data=True) sender_email = msg_dict["sender_email"] incoming_email_id = msg_dict["incoming_email_id"] send_blocked_muted_email(sr, parent, sender_email, incoming_email_id)
def get_recommendations(srs): """ Return the subreddits recommended if you like the given subreddit """ # for now, but keep the API open for multireddits later assert len(srs) == 1 and srs[0].__class__ == Subreddit sr = srs[0] recs = _get_recommendations(sr._id36) if not recs: return [] srs = Subreddit._byID36(recs, return_dict=True, data=True) return srs
def fetch_recommendations(source, to_omit): # fetch more recs than requested because some might get filtered out rec_id36s = SRRecommendation.for_srs([sr._id36 for sr in srs], to_omit, count * 2, source, match_set=match_set) # always check for private subreddits at runtime since type might change rec_srs = Subreddit._byID36(rec_id36s, return_dict=False) filtered = [sr for sr in rec_srs if is_visible(sr)] if filter_over18: filtered = [sr for sr in filtered if not sr.over_18] return filtered
def get_recommended_content(prefs, src, settings): """Get a mix of content from subreddits recommended for someone with the given preferences (likes and dislikes.) Returns a list of ExploreItems. """ # numbers chosen empirically to give enough results for explore page num_liked = 10 # how many liked srs to use when generating the recs num_recs = 20 # how many recommended srs to ask for num_discovery = 2 # how many discovery-related subreddits to mix in num_rising = 4 # how many rising links to mix in num_items = 20 # total items to return rising_items = discovery_items = comment_items = hot_items = [] # make a list of srs that shouldn't be recommended default_srid36s = [to36(srid) for srid in Subreddit.default_subreddits()] omit_srid36s = list(prefs.likes.union(prefs.dislikes, prefs.recent_views, default_srid36s)) # pick random subset of the user's liked srs liked_srid36s = random_sample(prefs.likes, num_liked) if settings.personalized else [] # pick random subset of discovery srs candidates = set(get_discovery_srid36s()).difference(prefs.dislikes) discovery_srid36s = random_sample(candidates, num_discovery) # multiget subreddits to_fetch = liked_srid36s + discovery_srid36s srs = Subreddit._byID36(to_fetch) liked_srs = [srs[sr_id36] for sr_id36 in liked_srid36s] discovery_srs = [srs[sr_id36] for sr_id36 in discovery_srid36s] if settings.personalized: # generate recs from srs we know the user likes recommended_srs = get_recommendations(liked_srs, count=num_recs, to_omit=omit_srid36s, source=src, match_set=False, over18=settings.nsfw) random.shuffle(recommended_srs) # split list of recommended srs in half midpoint = len(recommended_srs) / 2 srs_slice1 = recommended_srs[:midpoint] srs_slice2 = recommended_srs[midpoint:] # get hot links plus top comments from one half comment_items = get_comment_items(srs_slice1, src) # just get hot links from the other half hot_items = get_hot_items(srs_slice2, TYPE_HOT, src) if settings.discovery: # get links from subreddits dedicated to discovery discovery_items = get_hot_items(discovery_srs, TYPE_DISCOVERY, 'disc') if settings.rising: # grab some (non-personalized) rising items omit_sr_ids = set(int(id36, 36) for id36 in omit_srid36s) rising_items = get_rising_items(omit_sr_ids, count=num_rising) # combine all items and randomize order to get a mix of types all_recs = list(chain(rising_items, comment_items, discovery_items, hot_items)) random.shuffle(all_recs) # make sure subreddits aren't repeated seen_srs = set() recs = [] for r in all_recs: if not settings.nsfw and r.is_over18(): continue if not is_visible(r.sr): # could happen in rising items continue if r.sr._id not in seen_srs: recs.append(r) seen_srs.add(r.sr._id) if len(recs) >= num_items: break return recs
def add_props(cls, user, wrapped): from r2.lib.db.thing import Thing from r2.lib.menus import QueryButton from r2.lib.pages import WrappedUser from r2.models import ( Account, Link, ModSR, MultiReddit, Subreddit, ) target_names = {item.target_fullname for item in wrapped if hasattr(item, "target_fullname")} targets = Thing._by_fullname(target_names, data=True) # get moderators moderators = Account._byID36({item.mod_id36 for item in wrapped}, data=True) # get authors for targets that are Links or Comments target_author_names = {target.author_id for target in targets.values() if hasattr(target, "author_id")} target_authors = Account._byID(target_author_names, data=True) # get parent links for targets that are Comments parent_link_names = {target.link_id for target in targets.values() if hasattr(target, "link_id")} parent_links = Link._byID(parent_link_names, data=True) # get subreddits srs = Subreddit._byID36({item.sr_id36 for item in wrapped}, data=True) for item in wrapped: item.moderator = moderators[item.mod_id36] item.subreddit = srs[item.sr_id36] item.text = cls._text.get(item.action, '') item.target = None item.target_author = None if hasattr(item, "target_fullname") and item.target_fullname: item.target = targets[item.target_fullname] if hasattr(item.target, "author_id"): author_name = item.target.author_id item.target_author = target_authors[author_name] if hasattr(item.target, "link_id"): parent_link_name = item.target.link_id item.parent_link = parent_links[parent_link_name] if isinstance(item.target, Account): item.target_author = item.target if c.render_style == "html": request_path = request.path # make wrapped users for targets that are accounts user_targets = filter(lambda target: isinstance(target, Account), targets.values()) wrapped_user_targets = {user._fullname: WrappedUser(user) for user in user_targets} for item in wrapped: if isinstance(item.target, Account): user_name = item.target._fullname item.wrapped_user_target = wrapped_user_targets[user_name] css_class = 'modactions %s' % item.action action_button = QueryButton( '', item.action, query_param='type', css_class=css_class) action_button.build(base_path=request_path) item.action_button = action_button mod_button = QueryButton( item.moderator.name, item.moderator.name, query_param='mod') mod_button.build(base_path=request_path) item.mod_button = mod_button if isinstance(c.site, ModSR) or isinstance(c.site, MultiReddit): rgb = item.subreddit.get_rgb() item.bgcolor = 'rgb(%s,%s,%s)' % rgb item.is_multi = True else: item.bgcolor = "rgb(255,255,255)" item.is_multi = False
def add_props(cls, user, wrapped): from r2.lib.db.thing import Thing from r2.lib.menus import QueryButton from r2.lib.pages import WrappedUser from r2.models import ( Account, Link, ModSR, MultiReddit, Subreddit, ) target_names = { item.target_fullname for item in wrapped if hasattr(item, "target_fullname") } targets = Thing._by_fullname(target_names, data=True) # get moderators moderators = Account._byID36({item.mod_id36 for item in wrapped}, data=True) # get authors for targets that are Links or Comments target_author_names = { target.author_id for target in targets.values() if hasattr(target, "author_id") } target_authors = Account._byID(target_author_names, data=True) # get parent links for targets that are Comments parent_link_names = { target.link_id for target in targets.values() if hasattr(target, "link_id") } parent_links = Link._byID(parent_link_names, data=True) # get subreddits srs = Subreddit._byID36({item.sr_id36 for item in wrapped}, data=True) for item in wrapped: item.moderator = moderators[item.mod_id36] item.subreddit = srs[item.sr_id36] item.text = cls._text.get(item.action, '') item.details = item.get_extra_text() item.target = None item.target_author = None if hasattr(item, "target_fullname") and item.target_fullname: item.target = targets[item.target_fullname] if hasattr(item.target, "author_id"): author_name = item.target.author_id item.target_author = target_authors[author_name] if hasattr(item.target, "link_id"): parent_link_name = item.target.link_id item.parent_link = parent_links[parent_link_name] if isinstance(item.target, Account): item.target_author = item.target if c.render_style == "html": request_path = request.path # make wrapped users for targets that are accounts user_targets = filter(lambda target: isinstance(target, Account), targets.values()) wrapped_user_targets = { user._fullname: WrappedUser(user) for user in user_targets } for item in wrapped: if isinstance(item.target, Account): user_name = item.target._fullname item.wrapped_user_target = wrapped_user_targets[user_name] css_class = 'modactions %s' % item.action action_button = QueryButton('', item.action, query_param='type', css_class=css_class) action_button.build(base_path=request_path) item.action_button = action_button mod_button = QueryButton(item.moderator.name, item.moderator.name, query_param='mod') mod_button.build(base_path=request_path) item.mod_button = mod_button if isinstance(c.site, ModSR) or isinstance( c.site, MultiReddit): item.bgcolor = 'rgb(%s,%s,%s)' % cls.get_rgb(item) item.is_multi = True else: item.bgcolor = "rgb(255,255,255)" item.is_multi = False