class About(Plugin): needs_static_build = True config = { ConfigValue.str: [ 'advertising_links_sr', 'wiki_page_selfserve_advertisers', 'wiki_page_selfserve_content', 'wiki_page_selfserve_blurbs', 'wiki_page_selfserve_quotes', 'wiki_page_selfserve_help', 'wiki_page_team_members', ], } js = { 'about': Module( 'about.js', 'lib/modernizr.custom.3d+shadow.js', 'lib/iso8601.js', 'slideshow.js', 'timeline.js', 'grid.js', 'about.js', 'about-main.js', 'about-team.js', 'about-postcards.js', prefix='about/', ), 'advertising': Module( 'advertising.js', 'advertising.js', prefix='advertising/', ), } def add_routes(self, mc): mc('/about/postcards', controller='about', action='postcards', conditions={'function': not_in_sr}) # handle wildcard from postcard pushState URLs. mc('/about/postcards/*etc', controller='about', action='postcards', conditions={'function': not_in_sr}) mc('/ad_inq', controller='redirect', action='redirect', dest='/advertising') mc('/advertising', controller='about', action='advertising', conditions={'function': not_in_sr}) def load_controllers(self): from about import AboutController
class AdzerkPromo(Plugin): needs_static_build = True config = { ConfigValue.int: [ 'adzerk_site_id', 'adzerk_advertiser_id', 'adzerk_priority_id', 'adzerk_channel_id', 'adzerk_publisher_id', 'adzerk_network_id', 'adzerk_ad_type', ], } js = { 'reddit-init': Module('reddit-init.js', 'adzerkspotlight.js', ) } def load_controllers(self): import r2.lib.promote from reddit_adzerkpromo import adzerkpromo r2.lib.promote.get_single_promo = adzerkpromo.get_adzerk_promo adzerkpromo.hooks.register_all()
class About(Plugin): config = { ConfigValue.int: ['about_images_count', 'about_images_min_score'] } js = { 'less': Module('lib/less-1.3.0.min.js', prefix='about/', should_compile=False), 'about': Module( 'about.js', 'lib/modernizr.custom.3d+shadow.js', 'lib/underscore-1.3.3.js', 'lib/backbone-0.9.2.js', 'lib/iso8601.js', 'about-utils.js', 'slideshow.js', 'timeline.js', 'grid.js', 'about.js', 'about-main.js', 'about-team.js', 'about-postcards.js', prefix='about/', ) } def add_routes(self, mc): mc('/about/:action', controller='about', conditions={'function': not_in_sr}) def load_controllers(self): def load(name): with open(path.join(path.dirname(__file__), 'data', name)) as f: data = json.load(f) return data from about import AboutController, parse_date_text self.timeline_data = load('timeline.json') for idx, event in enumerate(self.timeline_data): self.timeline_data[idx]['date'] = parse_date_text(event['date']) self.sites_data = load('sites.json') self.team_data = load('team.json') self.colors_data = load('colors.json')
class About(Plugin): needs_static_build = True config = { ConfigValue.int: [ 'about_images_count', 'about_images_min_score', ], ConfigValue.str: [ 'advertising_links_sr', 'wiki_page_selfserve_advertisers', 'wiki_page_selfserve_content', 'wiki_page_selfserve_blurbs', 'wiki_page_selfserve_quotes', 'wiki_page_selfserve_help', 'wiki_page_team_members', ], } js = { 'about': Module('about.js', 'lib/modernizr.custom.3d+shadow.js', 'lib/iso8601.js', 'slideshow.js', 'timeline.js', 'grid.js', 'about.js', 'about-main.js', 'about-team.js', 'about-postcards.js', prefix='about/', ) } def add_routes(self, mc): # handle wildcard after /about/:action/ for postcard pushState URLs. for route in ('/about/:action', '/about/:action/*etc'): mc(route, controller='about', conditions={'function':not_in_sr}, requirements={'action':'team|postcards|alien'}) mc('/ad_inq', controller='redirect', action='redirect', dest='/advertising') mc('/advertising', controller='about', action='advertising', conditions={'function':not_in_sr}) def load_controllers(self): def load(name): with open(path.join(path.dirname(__file__), 'data', name)) as f: data = json.load(f) return data from about import AboutController, parse_date_text self.timeline_data = load('timeline.json') for idx, event in enumerate(self.timeline_data): self.timeline_data[idx]['date'] = parse_date_text(event['date']) self.sites_data = load('sites.json') self.colors_data = load('colors.json')
class Adzerk(Plugin): needs_static_build = True config = { ConfigValue.int: [ 'az_selfserve_site_id', 'az_selfserve_advertiser_id', 'az_selfserve_channel_id', 'az_selfserve_publisher_id', 'az_selfserve_network_id', 'az_selfserve_ad_type', 'az_selfserve_num_request', ], ConfigValue.dict(ConfigValue.str, ConfigValue.int): [ 'az_selfserve_priorities', ], } js = { 'reddit-init': Module( 'reddit-init.js', 'adzerk/adzerk.js', ) } def add_routes(self, mc): mc('/api/request_promo/', controller='adzerkapi', action='request_promo') def declare_queues(self, queues): from r2.config.queues import MessageQueue queues.declare({ "adzerk_q": MessageQueue(bind_to_self=True), }) def load_controllers(self): # replace the standard Ads view with an Adzerk specific one. import r2.lib.pages.pages from adzerkads import Ads as AdzerkAds r2.lib.pages.pages.Ads = AdzerkAds # replace standard adserver with Adzerk. from adzerkpromote import AdzerkApiController from adzerkpromote import hooks as adzerkpromote_hooks adzerkpromote_hooks.register_all()
class BetaMode(Plugin): needs_static_build = True config = { ConfigValue.str: [ 'beta_domain', 'beta_name', 'beta_title', 'beta_feedback_url', ], ConfigValue.bool: [ 'beta_require_admin', 'beta_require_gold', ], ConfigValue.tuple: [ 'beta_allowed_users', ], ConfigValue.messages: [ 'beta_description_md', ] } js = { 'reddit': Module( 'reddit.js', 'betamode.js', ) } def add_routes(self, mc): mc('/beta/about/:name', controller='betamode', action='beta', conditions={'function': not_in_sr}) mc('/beta/disable', controller='betamode', action='disable', conditions={'function': not_in_sr}) def load_controllers(self): from reddit_betamode import betamode betamode.hooks.register_all()
class Meatspace(Plugin): needs_static_build = True js = { "meatspace-qrcode": Module( "meatspace-qrcode.js", "lib/jquery.qrcode.min.js", "meatspace-qrcode.js", ), } errors = { "MEETUP_NOT_WITH_SELF": N_("you can't connect with yourself"), "MEETUP_INVALID_CODE": N_("that is not the correct code"), } def add_routes(self, mc): mc("/meetup/:codename/:action", controller="qrcode", action="portal", conditions={"function": not_in_sr}) mc("/api/meetup_connect", controller="qrcode", action="connect", conditions={"function": not_in_sr}) # shortdomain stuff is handled in haproxy, but haproxy can only prefix # paths that come through during rewrite. we'll handle it from there. mc("/meetup/:codename/or/:user/:code", controller="qrcode", action="connect_shortlink", conditions={"function": not_in_sr}) def load_controllers(self): from reddit_meatspace.qrcode import QrCodeController
class TheButton(Plugin): needs_static_build = True config = { ConfigValue.tuple: [ "thebutton_caches", ], } live_config = { ConfigValue.int: [ "thebutton_srid", ], ConfigValue.bool: [ "thebutton_is_active", ], ConfigValue.str: [ "thebutton_nopress_flair_class", "thebutton_nopress_flair_text", "thebutton_cantpress_flair_class", "thebutton_cantpress_flair_text", ], } js = { "reddit": Module( "reddit.js", "websocket.js", "thebutton.js", ) } def on_load(self, g): from r2.lib.cache import CMemcache, MemcacheChain, LocalCache, SelfEmptyingCache thebutton_memcaches = CMemcache( 'thebutton', g.thebutton_caches, min_compress_len=1400, num_clients=g.num_mc_clients, ) localcache_cls = (SelfEmptyingCache if g.running_as_script else LocalCache) g.thebuttoncache = MemcacheChain(( localcache_cls(), thebutton_memcaches, )) g.cache_chains.update(thebutton=g.thebuttoncache) def add_routes(self, mc): mc( "/api/press_button", controller="buttonapi", action="press_button", ) def load_controllers(self): from r2.lib.pages import Reddit from reddit_thebutton.controllers import ( ButtonApiController, ) Reddit.extra_stylesheets.append('thebutton.less') from reddit_thebutton.hooks import hooks hooks.register_all() def declare_queues(self, queues): from r2.config.queues import MessageQueue queues.declare({ "buttonflair_q": MessageQueue(), }) queues.buttonflair_q << ( "new_comment", "new_link", )
class Adzerk(Plugin): needs_static_build = True config = { ConfigValue.str: [ 'adzerk_engine_domain', ], ConfigValue.int: [ 'az_selfserve_salesperson_id', 'az_selfserve_network_id', 'az_reporting_timeout', ], ConfigValue.float: [ 'display_ad_skip_probability', ], ConfigValue.tuple: [ 'display_ad_skip_keywords', ], ConfigValue.dict(ConfigValue.str, ConfigValue.int): [ 'az_selfserve_priorities', 'az_selfserve_site_ids', ], ConfigValue.tuple_of(ConfigValue.int): [ 'adserver_campaign_ids', ], } js = { 'reddit-init': Module('reddit-init.js', 'adzerk/adzerk.js', ), 'display': Module('display.js', 'adzerk/display.js', ), 'companion': Module('companion.js', 'adzerk/companion.js', ), 'ad-dependencies': Module('ad-dependencies.js', 'adzerk/jquery.js', ), } def add_routes(self, mc): mc('/api/request_promo/', controller='adzerkapi', action='request_promo') mc('/ads/display/300x250/', controller='adserving', action='ad_300_250') mc('/ads/display/300x250-companion/', controller='adserving', action='ad_300_250_companion') def declare_queues(self, queues): from r2.config.queues import MessageQueue queues.declare({ "adzerk_q": MessageQueue(bind_to_self=True), "adzerk_reporting_q": MessageQueue(bind_to_self=True), }) def load_controllers(self): # replace the standard Ads view with an Adzerk specific one. import r2.lib.pages.pages from adzerkads import Ads as AdzerkAds r2.lib.pages.pages.Ads = AdzerkAds # replace standard adserver with Adzerk. from adzerkpromote import AdzerkApiController from adzerkpromote import hooks as adzerkpromote_hooks from adzerkads import AdServingController adzerkpromote_hooks.register_all()
class Gold(Plugin): needs_static_build = True config = { ConfigValue.str: [ "gold_hostname_file", "gold_servername_sr", "wiki_page_gold_features", ], } js = { 'gold-lib': Module( 'gold-lib.js', 'paper-core.js', prefix='lib/', ), "snoovatar": LocalizedModule( "snoovatar.js", "snoovatar.js", DataSource( wrap="r.snoovatar.initTailors({content})", data=json.load( pkg_resources.resource_stream( __name__, "data/tailors.json", )), ), prefix="snoovatar/", ), } errors = { "BAD_CSS_COLOR": N_("invalid color"), "INVALID_SNOOVATAR": N_("unknown or missing dressings"), } def add_routes(self, mc): mc('/gold/about', controller='gold', action='about') mc('/about/gold', controller='redirect', action='redirect', dest='/gold/about') mc('/gold/partners', controller='gold', action='partners') mc('/user/:username/snoo', controller='gold', action='snoovatar') mc("/api/gold/snoovatar", controller='goldapi', action='snoovatar') def load_controllers(self): from reddit_gold.controllers import GoldController, GoldApiController from reddit_gold.server_naming import hooks hooks.register_all() self.tailors_data = json.load( pkg_resources.resource_stream( __name__, "data/tailors.json", ))
class Place(Plugin): needs_static_build = True js = { "place-base": Module( "place-base.js", # core & external dependencies "websocket.js", "place/modules.js", "place/utils.js", # 'exit node' modules, no internal dependencies "place/activity.js", "place/api.js", "place/audio.js", "place/camera.js", "place/camerabutton.js", "place/canvasse.js", "place/coordinates.js", "place/hand.js", "place/inspector.js", "place/keyboard.js", "place/mollyguard.js", "place/mutebutton.js", "place/notificationbutton.js", "place/notifications.js", "place/palette.js", "place/zoombutton.js", "place/timer.js", # 'internal node' modules, only dependant on 'exit nodes' "place/client.js", "place/cursor.js", "place/world.js", # 'entrance node' modules, only dependant on 'internal' or 'exit' nodes "place/camerabuttonevents.js", "place/cameraevents.js", "place/canvasevents.js", "place/mutebuttonevents.js", "place/notificationbuttonevents.js", "place/paletteevents.js", "place/websocketevents.js", "place/zoombuttonevents.js", ), # Optionally included admin-only modules "place-admin": Module( "place-admin.js", "place/admin/api.js", "place/admin/slider.js", "place/admin/selector.js", ), "place-init": Module( "place-init.js", # entry point "place/init.js", ), } config = { # TODO: your static configuratation options go here, e.g.: # ConfigValue.int: [ # "place_blargs", # ], } live_config = { # TODO: your live configuratation options go here, e.g.: # ConfigValue.int: [ # "place_realtime_blargs", # ], } errors = { # TODO: your API errors go here, e.g.: # "PLACE_NOT_COOL": N_("not cool"), } def add_routes(self, mc): mc("/place", controller="place", action="canvasse", conditions={"function": not_in_sr}, is_embed=False) mc("/place/embed", controller="place", action="canvasse", conditions={"function": not_in_sr}, is_embed=True) mc("/api/place/time", controller="place", action="time_to_wait", conditions={"function": not_in_sr}) mc("/api/place/board-bitmap", controller="loggedoutplace", action="board_bitmap", conditions={"function": not_in_sr}) mc("/api/place/:action", controller="place", conditions={"function": not_in_sr}) def load_controllers(self): from r2.lib.pages import Reddit from reddit_place.controllers import ( controller_hooks, PlaceController, ) controller_hooks.register_all() Reddit.extra_stylesheets.append('place_global.less') def declare_queues(self, queues): # TODO: add any queues / bindings you need here, e.g.: # # queues.some_queue_defined_elsewhere << "routing_key" # # or # # from r2.config.queues import MessageQueue # queues.declare({ # "some_q": MessageQueue(), # }) pass
class FreeToPlay(Plugin): needs_static_build = True config = { ConfigValue.tuple: [ "f2pcaches", ], ConfigValue.dict(str, str): [ "team_subreddits", "steam_promo_items", ], } js = { 'reddit': Module('reddit.js', 'lib/iso8601.js', 'f2p/scrollupdater.js', 'f2p/f2p.js', 'f2p/utils.js', 'f2p/items.js', TemplateFileSource('f2p/panel.html'), TemplateFileSource('f2p/login-message.html'), TemplateFileSource('f2p/item.html'), TemplateFileSource('f2p/item-bubble.html'), TemplateFileSource('f2p/scores.html'), TemplateFileSource('f2p/target-overlay.html'), ) } live_config = { ConfigValue.float: [ 'drop_cooldown_mu', 'drop_cooldown_sigma', ], ConfigValue.dict(str, int): [ 'f2p_rarity_weights', ], } def declare_queues(self, queues): # imported here so we don't depend on pyx files at import time # which allows "make" to work in a clean clone of the repos from r2.config.queues import MessageQueue queues.declare({ "steam_q": MessageQueue(bind_to_self=True), }) def on_load(self, g): from r2.lib.cache import CMemcache, MemcacheChain, LocalCache # TODO: use SelfEmptyingCache for localcache if we use this in jobs f2p_memcaches = CMemcache( 'f2p', g.f2pcaches, num_clients=g.num_mc_clients, ) g.f2pcache = MemcacheChain(( LocalCache(), f2p_memcaches, )) g.cache_chains.update(f2p=g.f2pcache) compendium = pkg_resources.resource_stream(__name__, "data/compendium.json") g.f2pitems = json.load(compendium) for kind, data in g.f2pitems.iteritems(): data["kind"] = kind def add_routes(self, mc): mc('/f2p/gamelog', controller='gamelog', action='listing') mc('/api/f2p/:action', controller='freetoplayapi') mc('/f2p/steam/:action', controller='steam', action='start') def load_controllers(self): from r2.lib.pages import Reddit Reddit.extra_stylesheets.append('f2p.less') from reddit_f2p import f2p f2p.hooks.register_all() f2p.monkeypatch() from reddit_f2p.steam import SteamController from reddit_f2p.gamelog import GameLogController
class Robin(Plugin): needs_static_build = True js = { "robin": LocalizedModule("robin.js", "lib/page-visibility.js", "lib/tinycon.js", "websocket.js", TemplateFileSource("robin/robinmessage.html"), TemplateFileSource("robin/robinroomparticipant.html"), "errors.js", "models/validators.js", "robin/models.js", "robin/views.js", "robin/notifications.js", "robin/favicon.js", "robin/init.js", ), "robin-join": Module("robin-join.js", "robin/join.js", ), } live_config = { ConfigValue.int: [ "robin_ratelimit_window", ], ConfigValue.dict(ConfigValue.int, ConfigValue.float): [ "robin_ratelimit_avg_per_sec", ], } def declare_queues(self, queues): from r2.config.queues import MessageQueue queues.declare({ "robin_presence_q": MessageQueue(), "robin_waitinglist_q": MessageQueue(bind_to_self=True), "robin_subreddit_maker_q": MessageQueue(bind_to_self=True), }) queues.robin_presence_q << ( "websocket.connect", "websocket.disconnect", ) def add_routes(self, mc): mc("/robin", controller="robin", action="chat", conditions={"function": not_in_sr}) mc("/robin/all", controller="robin", action="all", conditions={"function": not_in_sr}) mc("/robin/admin", controller="robin", action="admin", conditions={"function": not_in_sr}) mc("/robin/join", controller="robin", action="join", conditions={"function": not_in_sr}) mc("/robin/:room_id", controller="robin", action="force_room", conditions={"function": not_in_sr}) mc("/robin/user/:user", controller="robin", action="user_room", conditions={"function": not_in_sr}) mc("/api/robin/:room_id/:action", controller="robin", conditions={"function": not_in_sr}) mc("/api/join_room", controller="robin", action="join_room", conditions={"function": not_in_sr}) mc("/api/room_assignment", controller="robin", action="room_assignment", conditions={"function": not_in_sr}) mc("/api/admin_prompt", controller="robin", action="admin_prompt", conditions={"function": not_in_sr}) mc("/api/admin_reap", controller="robin", action="admin_reap", conditions={"function": not_in_sr}) mc("/api/admin_broadcast", controller="robin", action="admin_broadcast", conditions={"function": not_in_sr}) def load_controllers(self): from r2.lib.pages import Reddit from reddit_robin.controllers import ( RobinController, ) Reddit.extra_stylesheets.append('robin_global.less') from reddit_robin.hooks import hooks hooks.register_all()