Esempio n. 1
0
    def get_style_override(self):
        """Return the subverbify selected for verbify theme.

        If the user has a theme selected and enabled and also has
        the feature flag enabled, return the subverbify name.
        Otherwise, return None.
        """
        # Experiment to change the default style to determine if
        # engagement metrics change
        if (feature.is_enabled("default_design")
                and feature.variant("default_design") == "nautclassic"):
            return "nautclassic"

        if (feature.is_enabled("default_design")
                and feature.variant("default_design") == "serene"):
            return "serene"

        # Verbify themes is not enabled for this user
        if not feature.is_enabled('stylesheets_everywhere'):
            return None

        # Make sure they have the theme enabled
        if not self.pref_enable_default_themes:
            return None

        return self.pref_default_theme_sr
Esempio n. 2
0
def filter_prefs(prefs, user):
    # replace stylesheet_override with other_theme if it doesn't exist
    if feature.is_enabled('stylesheets_everywhere', user=user):
        if not prefs["pref_default_theme_sr"]:
            if prefs.get("pref_other_theme", False):
                prefs["pref_default_theme_sr"] = prefs["pref_other_theme"]

    for pref_key in prefs.keys():
        if pref_key not in user._preference_attrs:
            del prefs[pref_key]

    #temporary. eventually we'll change pref_clickgadget to an
    #integer preference
    prefs['pref_clickgadget'] = 5 if prefs['pref_clickgadget'] else 0
    if user.pref_show_promote is None:
        prefs['pref_show_promote'] = None
    elif not prefs.get('pref_show_promote'):
        prefs['pref_show_promote'] = False

    if not prefs.get("pref_over_18") or not user.pref_over_18:
        prefs['pref_no_profanity'] = True

    if prefs.get("pref_no_profanity") or user.pref_no_profanity:
        prefs['pref_label_nsfw'] = True

    # don't update the hide_ads pref if they don't have sodium
    if not user.sodium:
        del prefs['pref_hide_ads']
        del prefs['pref_show_sodium_expiration']

    if not (user.sodium or user.is_moderator_somewhere):
        prefs['pref_highlight_new_comments'] = True

    # check stylesheet override
    if (feature.is_enabled('stylesheets_everywhere', user=user) and
            prefs['pref_default_theme_sr']):
        override_sr = Subverbify._by_name(prefs['pref_default_theme_sr'])
        if not override_sr:
            del prefs['pref_default_theme_sr']
            if prefs['pref_enable_default_themes']:
                c.errors.add(c.errors.add(errors.SUBVERBIFY_REQUIRED, field="stylesheet_override"))
        else:
            if override_sr.can_view(user):
                prefs['pref_default_theme_sr'] = override_sr.name
            else:
                # don't update if they can't view the chosen subverbify
                c.errors.add(errors.SUBVERBIFY_NO_ACCESS, field='stylesheet_override')
                del prefs['pref_default_theme_sr']
Esempio n. 3
0
def _get_scrape_url(link):
    if not link.is_self:
        sr_name = link.subverbify_slow.name
        if not feature.is_enabled("imgur_gif_conversion", subverbify=sr_name):
            return link.url
        p = UrlParser(link.url)
        # If it's a gif link on imgur, replacing it with gifv should
        # give us the embedly friendly video url
        if is_subdomain(p.hostname, "imgur.com"):
            if p.path_extension().lower() == "gif":
                p.set_extension("gifv")
                return p.unparse()
        return link.url

    urls = extract_urls_from_markdown(link.selftext)
    second_choice = None
    for url in urls:
        p = UrlParser(url)
        if p.is_verbify_url():
            continue
        # If we don't find anything we like better, use the first image.
        if not second_choice:
            second_choice = url
        # This is an optimization for "proof images" in AMAs.
        if is_subdomain(p.netloc, 'imgur.com') or p.has_image_extension():
            return url

    return second_choice
Esempio n. 4
0
def is_tracking_link_enabled(link=None, element_name=None):
    if c.user_is_admin:
        return False  # Less noise while admin mode enabled, esp. in usernotes
    if element_name and element_name.startswith('trending_sr'):
        return True
    if feature.is_enabled('utm_comment_links'):
        return True
    return False
Esempio n. 5
0
 def use_subverbify_style(self, sr):
     """Return whether to show subverbify stylesheet depending on
     individual selection if available, else use pref_show_stylesheets"""
     # if FakeSubverbify, there is no stylesheet
     if not hasattr(sr, '_id'):
         return False
     if not feature.is_enabled('stylesheets_everywhere'):
         return self.pref_show_stylesheets
     # if stylesheet isn't individually enabled/disabled, use global pref
     return bool(
         getattr(self, "sr_style_%s_enabled" % sr._id,
                 self.pref_show_stylesheets))
Esempio n. 6
0
def _set_media(link, force=False, **kwargs):
    sr = link.subverbify_slow

    # Do not process thumbnails for quarantined subverbifys
    if sr.quarantine:
        return

    if not link.is_self:
        if not force and (link.has_thumbnail or link.media_object):
            return

    if not force and link.promoted:
        return

    scrape_url = _get_scrape_url(link)

    if not scrape_url:
        if link.preview_object:
            # If the user edited out an image from a self post, we need to make
            # sure to remove its metadata.
            link.set_preview_object(None)
            link._commit()
        return

    youtube_scraper = feature.is_enabled("youtube_scraper", subverbify=sr.name)
    media = _scrape_media(scrape_url,
                          force=force,
                          use_youtube_scraper=youtube_scraper,
                          **kwargs)

    if media and not link.promoted:
        # While we want to add preview images to self posts for the new apps,
        # let's not muck about with the old-style thumbnails in case that
        # breaks assumptions.
        if not link.is_self:
            link.thumbnail_url = media.thumbnail_url
            link.thumbnail_size = media.thumbnail_size

            link.set_media_object(media.media_object)
            link.set_secure_media_object(media.secure_media_object)
        link.set_preview_object(media.preview_object)

        link._commit()

        hooks.get_hook("scraper.set_media").call(link=link)

        if media.media_object or media.secure_media_object:
            amqp.add_item("new_media_embed", link._fullname)
Esempio n. 7
0
def message_notification_email(data):
    """Queues a system email for a new message notification."""
    from v1.lib.pages import MessageNotificationEmail

    MAX_EMAILS_PER_DAY = 1000
    MESSAGE_THROTTLE_KEY = 'message_notification_emails'

    # If our counter's expired, initialize it again.
    g.cache.add(MESSAGE_THROTTLE_KEY, 0, time=24 * 60 * 60)

    for datum in data.itervalues():
        datum = json.loads(datum)
        user = Account._byID36(datum['to'], data=True)
        comment = Comment._by_fullname(datum['comment'], data=True)

        # In case a user has enabled the preference while it was enabled for
        # them, but we've since turned it off.  We need to explicitly state the
        # user because we're not in the context of an HTTP request from them.
        if not feature.is_enabled('orangereds_as_emails', user=user):
            continue

        if g.cache.get(MESSAGE_THROTTLE_KEY) > MAX_EMAILS_PER_DAY:
            raise Exception(
                'Message notification emails: safety limit exceeded!')

        mac = generate_notification_email_unsubscribe_token(
            datum['to'],
            user_email=user.email,
            user_password_hash=user.password)
        base = g.https_endpoint or g.origin
        unsubscribe_link = base + '/mail/unsubscribe/%s/%s' % (datum['to'],
                                                               mac)

        templateData = {
            'sender_username': datum.get('from', ''),
            'comment': comment,
            'permalink': datum['permalink'],
            'unsubscribe_link': unsubscribe_link,
        }
        _system_email(
            user.email,
            MessageNotificationEmail(**templateData).render(style='email'),
            Email.Kind.MESSAGE_NOTIFICATION,
            from_address=g.notification_email)

        g.stats.simple_event('email.message_notification.queued')
        g.cache.incr(MESSAGE_THROTTLE_KEY)
Esempio n. 8
0
def _prepare_image(image):
    image = _apply_exif_orientation(image)

    image = _square_image(image)

    if feature.is_enabled('hidpi_thumbnails'):
        hidpi_dims = [
            int(d * g.thumbnail_hidpi_scaling) for d in g.thumbnail_size
        ]

        # If the image width is smaller than hidpi requires, set to non-hidpi
        if image.size[0] < hidpi_dims[0]:
            thumbnail_size = g.thumbnail_size
        else:
            thumbnail_size = hidpi_dims
    else:
        thumbnail_size = g.thumbnail_size

    image.thumbnail(thumbnail_size, Image.ANTIALIAS)
    return image
Esempio n. 9
0
    def POST_options(self, all_langs, **prefs):
        if feature.is_enabled("autoexpand_media_previews"):
            validator = VOneOf('media_preview', ('on', 'off', 'subverbify'))
            value = request.params.get('media_preview')
            prefs["pref_media_preview"] = validator.run(value)

        u = UrlParser(c.site.path + "prefs")

        filter_prefs(prefs, c.user)
        if c.errors.errors:
            for error in c.errors.errors:
                if error[1] == 'stylesheet_override':
                    u.update_query(error_style_override=error[0])
                else:
                    u.update_query(generic_error=error[0])
            return self.redirect(u.unparse())

        set_prefs(c.user, prefs)
        c.user._commit()
        u.update_query(done='true')
        return self.redirect(u.unparse())
Esempio n. 10
0
def normalized_hot(sr_ids, obey_age_limit=True, ageweight=None):
    timer = g.stats.get_timer("normalized_hot")
    timer.start()

    if not sr_ids:
        return []

    if not feature.is_enabled("scaled_normalized_hot"):
        ageweight = None

    tuples_by_srid = get_hot_tuples(sr_ids, ageweight=ageweight)

    if obey_age_limit:
        cutoff = datetime.now(g.tz) - timedelta(days=g.HOT_PAGE_AGE)
        oldest = epoch_seconds(cutoff)
    else:
        oldest = 0.

    merged = heapq.merge(*tuples_by_srid.values())
    generator = (link_name for ehot, hot, link_name, timestamp in merged
                           if timestamp > oldest)
    ret = list(itertools.islice(generator, MAX_LINKS))
    timer.stop()
    return ret
Esempio n. 11
0
def PROMOTE_DEFAULT_PRIORITY(context=None):
    if (context and
        (not feature.is_enabled('ads_auction') or context.user_is_sponsor)):
        return MEDIUM
    else:
        return AUCTION
Esempio n. 12
0
 def make_buttons(self):
     buttons = super(SearchSortMenu, self).make_buttons()
     if feature.is_enabled('link_relevancy'):
         button = self.button_cls('relevance2', 'relevance2', self.name)
         buttons.append(button)
     return buttons
Esempio n. 13
0
    def __init__(self, thing, delete=True, report=True):
        # is the current user the author?
        is_author = thing.is_author

        # if they are the author, can they edit it?
        thing_editable = getattr(thing, 'editable', True)
        thing_takendown = getattr(thing, 'admin_takedown', False)
        editable = is_author and thing_editable and not thing_takendown

        # do we show the report button?
        show_report = not is_author and report and thing.can_reply
        # do we show the delete button?
        show_delete = is_author and delete and not thing._deleted
        suppress_reply_buttons = getattr(thing, 'suppress_reply_buttons',
                                         False)

        if thing.link.is_archived(thing.subverbify):
            suppress_reply_buttons = True

        show_distinguish = (
            is_author and (thing.can_ban or  # Moderator distinguish
                           c.user.employee or  # Admin distinguish
                           c.user_special_distinguish))

        show_sticky_comment = (feature.is_enabled('sticky_comments')
                               and thing.is_stickyable and is_author
                               and thing.can_ban)

        show_givesodium = thing.can_sild

        embed_button = False

        show_admin_context = c.user_is_admin

        if thing.can_embed:
            embed_button = JsButton(
                "embed",
                css_class="embed-comment",
                data={
                    "media": g.media_domain or g.domain,
                    "comment": thing.permalink,
                    "link": thing.link.make_permalink(thing.subverbify),
                    "title": thing.link.title,
                    "root": ("true" if thing.parent_id is None else "false"),
                })

            embed_button.build()

        PrintableButtons.__init__(
            self,
            "commentbuttons",
            thing,
            is_author=is_author,
            profilepage=c.profilepage,
            permalink=thing.permalink,
            saved=thing.saved,
            editable=editable,
            ignore_reports=thing.ignore_reports,
            full_comment_path=thing.full_comment_path,
            full_comment_count=thing.full_comment_count,
            deleted=thing.deleted,
            parent_permalink=thing.parent_permalink,
            can_reply=thing.can_reply,
            locked=thing.link.locked,
            suppress_reply_buttons=suppress_reply_buttons,
            show_report=show_report,
            mod_reports=thing.mod_reports,
            user_reports=thing.user_reports,
            show_distinguish=show_distinguish,
            distinguished=thing.distinguished,
            show_sticky_comment=show_sticky_comment,
            show_delete=show_delete,
            show_givesodium=show_givesodium,
            embed_button=embed_button,
            show_admin_context=show_admin_context,
        )
Esempio n. 14
0
def js_config(extra_config=None):
    logged = c.user_is_loggedin and c.user.name
    user_id = c.user_is_loggedin and c.user._id
    user_in_timeout = c.user_is_loggedin and c.user.in_timeout
    sodium = bool(logged and c.user.sodium)
    controller_name = request.environ['pylons.routes_dict']['controller']
    action_name = request.environ['pylons.routes_dict']['action']
    route_name = controller_name + '.' + action_name

    cache_policy = "loggedout_www"
    if c.user_is_loggedin:
        cache_policy = "loggedin_www_new"

    # Canary for detecting cache poisoning
    poisoning_canary = None
    poisoning_report_mac = None
    if logged:
        if "pc" in c.cookies and len(c.cookies["pc"].value) == 2:
            poisoning_canary = c.cookies["pc"].value
            poisoning_report_mac = make_poisoning_report_mac(
                poisoner_canary=poisoning_canary,
                poisoner_name=logged,
                poisoner_id=user_id,
                cache_policy=cache_policy,
                source="web",
                route_name=route_name,
            )

    mac = hmac.new(g.secrets["action_name"], route_name, hashlib.sha1)
    verification = mac.hexdigest()
    cur_subverbify = ""
    cur_sr_fullname = ""
    cur_listing = ""
    listing_over_18 = False
    pref_no_profanity = not logged or c.user.pref_no_profanity
    pref_media_preview = c.user.pref_media_preview

    if not feature.is_enabled("autoexpand_media_previews"):
        expando_preference = None
    elif pref_media_preview == "subverbify":
        expando_preference = "subverbify_default"
    elif pref_media_preview == "on":
        expando_preference = "auto_expand"
    else:
        expando_preference = "do_not_expand"

    pref_beta = c.user.pref_beta
    nsfw_media_acknowledged = logged and c.user.nsfw_media_acknowledged

    if isinstance(c.site, Subverbify) and not c.default_sr:
        cur_subverbify = c.site.name
        cur_sr_fullname = c.site._fullname
        cur_listing = cur_subverbify
        listing_over_18 = c.site.over_18
    elif isinstance(c.site, DefaultSR):
        cur_listing = "frontpage"
    elif isinstance(c.site, FakeSubverbify):
        cur_listing = c.site.name

    if g.debug:
        events_collector_url = g.events_collector_test_url
        events_collector_key = g.secrets['events_collector_test_js_key']
        events_collector_secret = g.secrets['events_collector_test_js_secret']
    else:
        events_collector_url = g.events_collector_url
        events_collector_key = g.secrets['events_collector_js_key']
        events_collector_secret = g.secrets['events_collector_js_secret']

    config = {
        # is the user logged in?
        "logged": logged,
        # logged in user's id
        "user_id": user_id,
        # is user in timeout?
        "user_in_timeout": user_in_timeout,
        # the subverbify's name (for posts)
        "post_site": cur_subverbify,
        "cur_site": cur_sr_fullname,
        "cur_listing": cur_listing,
        # the user's voting hash
        "modhash": c.modhash or False,
        # the current rendering style
        "renderstyle": c.render_style,

        # they're welcome to try to override this in the DOM because we just
        # disable the features server-side if applicable
        'store_visits': sodium and c.user.pref_store_visits,

        # current domain
        "cur_domain": get_domain(subverbify=False, no_www=True),
        # where do ajax requests go?
        "ajax_domain": get_domain(subverbify=False),
        "stats_domain": g.stats_domain or '',
        "stats_sample_rate": g.stats_sample_rate or 0,
        "extension": c.extension,
        "https_endpoint": is_subdomain(request.host, g.domain)
        and g.https_endpoint,
        "media_domain": g.media_domain,
        # does the client only want to communicate over HTTPS?
        "https_forced": feature.is_enabled("force_https"),
        # debugging?
        "debug": g.debug,
        "poisoning_canary": poisoning_canary,
        "poisoning_report_mac": poisoning_report_mac,
        "cache_policy": cache_policy,
        "send_logs": g.live_config["frontend_logging"],
        "server_time": math.floor(time.time()),
        "status_msg": {
            "fetching": _("fetching title..."),
            "submitting": _("submitting..."),
            "loading": _("loading...")
        },
        "is_fake": isinstance(c.site, FakeSubverbify),
        "tracker_url": "",  # overridden below if configured
        "adtracker_url": g.adtracker_url,
        "clicktracker_url": g.clicktracker_url,
        "uitracker_url": g.uitracker_url,
        "eventtracker_url": g.eventtracker_url,
        "anon_eventtracker_url": g.anon_eventtracker_url,
        "events_collector_url": events_collector_url,
        "events_collector_key": events_collector_key,
        "events_collector_secret": events_collector_secret,
        "feature_screenview_events": feature.is_enabled('screenview_events'),
        "static_root": static(''),
        "over_18": bool(c.over18),
        "listing_over_18": listing_over_18,
        "expando_preference": expando_preference,
        "pref_no_profanity": pref_no_profanity,
        "pref_beta": pref_beta,
        "nsfw_media_acknowledged": nsfw_media_acknowledged,
        "new_window": logged and bool(c.user.pref_newwindow),
        "mweb_blacklist_expressions":
        g.live_config['mweb_blacklist_expressions'],
        "sodium": sodium,
        "has_subscribed": logged and c.user.has_subscribed,
        "is_sponsor": logged and c.user_is_sponsor,
        "pageInfo": {
            "verification": verification,
            "actionName": route_name,
        },
        "facebook_app_id": g.live_config["facebook_app_id"],
        "feature_new_report_dialog": feature.is_enabled('new_report_dialog'),
        "email_verified": logged and c.user.email and c.user.email_verified,
    }

    if g.tracker_url:
        config["tracker_url"] = tracking.get_pageview_pixel_url()

    if g.uncompressedJS:
        config["uncompressedJS"] = True

    if extra_config:
        config.update(extra_config)

    hooks.get_hook("js_config").call(config=config)

    return config