Exemple #1
0
def _use_adserver_reporting(thing):
    if not feature.is_enabled("adserver_reporting"):
        return False

    if not g.adserver_reporting_cutoff:
        return False

    try:
        cutoff = parse_date(g.adserver_reporting_cutoff)
    except ValueError:
        return False

    if isinstance(thing, PromoCampaign):
        link = Link._byID(thing.link_id)
    else:
        link = thing

    campaigns = list(PromoCampaign._by_link(link._id))

    # No campaigns, so nothing to report. Show the new
    # view anyway.
    if not campaigns:
        return True

    end_date = max(campaign.end_date for campaign in campaigns)
    end_date = end_date.replace(tzinfo=g.tz)
    cutoff = cutoff.replace(tzinfo=g.tz)

    if end_date < cutoff:
        return False

    return not feature.is_enabled("legacy_ad_reporting")
Exemple #2
0
 def hidden_options(cls):
     sorts = ["random"]
     if not feature.is_enabled("qa_sort"):
         sorts.append("qa")
     if feature.is_enabled("remove_hot_comments"):
         sorts.append("hot")
     return sorts
Exemple #3
0
def _use_adserver_reporting(thing):
    if not feature.is_enabled("adserver_reporting"):
        return False

    if not g.adserver_reporting_cutoff:
        return False

    try:
        cutoff = parse_date(g.adserver_reporting_cutoff)
    except ValueError:
        return False

    if isinstance(thing, PromoCampaign):
        link = Link._byID(thing.link_id)
    else:
        link = thing

    campaigns = list(PromoCampaign._by_link(link._id))

    # No campaigns, so nothing to report. Show the new
    # view anyway.
    if not campaigns:
        return True

    end_date = max(campaign.end_date for campaign in campaigns)
    end_date = end_date.replace(tzinfo=g.tz)
    cutoff = cutoff.replace(tzinfo=g.tz)

    if end_date < cutoff:
        return False

    return not feature.is_enabled("legacy_ad_reporting")
Exemple #4
0
 def hidden_options(cls):
     sorts = ['random']
     if not feature.is_enabled('qa_sort'):
         sorts.append('qa')
     if feature.is_enabled('remove_hot_comments'):
         sorts.append('hot')
     return sorts
Exemple #5
0
 def hidden_options(cls):
     sorts = ['random']
     if not feature.is_enabled('qa_sort'):
         sorts.append('qa')
     if feature.is_enabled('remove_hot_comments'):
         sorts.append('hot')
     return sorts
Exemple #6
0
    def get_style_override(self):
        """Return the subreddit selected for reddit theme.

        If the user has a theme selected and enabled and also has
        the feature flag enabled, return the subreddit 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"

        # Reddit 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
Exemple #7
0
    def get_style_override(self):
        """Return the subreddit selected for reddit theme.

        If the user has a theme selected and enabled and also has
        the feature flag enabled, return the subreddit 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"

        # Reddit 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
    def raw_data(self, thing):
        d = ThingJsonTemplate.raw_data(self, thing)

        if c.permalink_page:
            d["upvote_ratio"] = thing.upvote_ratio

        if feature.is_enabled('default_sort'):
            d['suggested_sort'] = thing.sort_if_suggested()

        preview_object = getattr(thing, 'preview_object', None)
        if feature.is_enabled('link_preview') and preview_object:
            source_width = preview_object['width']
            source_height = preview_object['height']
            source_ratio = float(source_height) / source_width

            def generate_image_links(censor_nsfw=False):
                # Determine which previews would be feasible with our given dims
                preview_resolutions = []
                for w in self.PREVIEW_RESOLUTIONS:
                    if w > source_width:
                        continue

                    url = g.image_resizing_provider.resize_image(
                        preview_object, w, censor_nsfw, self.PREVIEW_MAX_RATIO)
                    h = int(w * source_ratio)
                    preview_resolutions.append({
                        "url": url,
                        "width": w,
                        "height": h,
                    })

                d['post_hint'] = thing.post_hint
                url = g.image_resizing_provider.resize_image(
                    preview_object, censor_nsfw=censor_nsfw)

                return {
                    "source": {
                        "url": url,
                        "width": source_width,
                        "height": source_height,
                    },
                    "resolutions": preview_resolutions,
                }

            d['preview'] = {}
            images = generate_image_links()
            images['id'] = preview_object['uid']
            images['variants'] = {}
            if thing.nsfw:
                images['variants']['nsfw'] = generate_image_links(censor_nsfw=True)
            d['preview']['images'] = [images]

        return d
Exemple #9
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 gold
    if not user.gold:
        del prefs['pref_hide_ads']
        del prefs['pref_show_gold_expiration']

    # SAIDIT: degolding
    # if not (user.gold 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 = Subreddit._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.SUBREDDIT_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 subreddit
                c.errors.add(errors.SUBREDDIT_NO_ACCESS,
                             field='stylesheet_override')
                del prefs['pref_default_theme_sr']
Exemple #10
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 gold
    if not user.gold:
        del prefs['pref_hide_ads']
        del prefs['pref_show_gold_expiration']

    if not (user.gold 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 = Subreddit._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.SUBREDDIT_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 subreddit
                c.errors.add(errors.SUBREDDIT_NO_ACCESS, field='stylesheet_override')
                del prefs['pref_default_theme_sr']
Exemple #11
0
    def __init__(self, style, thing,
                 show_delete = False, show_report = True,
                 show_distinguish = False, show_marknsfw = False,
                 show_unmarknsfw = False, is_link=False,
                 show_flair=False, show_rescrape=False,
                 show_givegold=False, **kw):
        show_ignore = thing.show_reports
        approval_checkmark = getattr(thing, "approval_checkmark", None)
        show_approve = (thing.show_spam or show_ignore or
                        (is_link and approval_checkmark is None)) and not thing._deleted

        show_new_post_sharing = feature.is_enabled('improved_sharing')

        Styled.__init__(self, style = style,
                        thing = thing,
                        fullname = thing._fullname,
                        can_ban = thing.can_ban,
                        show_spam = thing.show_spam,
                        show_reports = thing.show_reports,
                        show_ignore = show_ignore,
                        approval_checkmark = approval_checkmark,
                        show_delete = show_delete,
                        show_approve = show_approve,
                        show_report = show_report,
                        show_distinguish = show_distinguish,
                        show_marknsfw = show_marknsfw,
                        show_unmarknsfw = show_unmarknsfw,
                        show_flair = show_flair,
                        show_rescrape=show_rescrape,
                        show_givegold=show_givegold,
                        show_new_post_sharing=show_new_post_sharing,
                        **kw)
Exemple #12
0
    def GET_happening_now(self):
        """ Get some basic information about the currently featured live thread.

            Returns an empty 204 response for api requests if no thread is currently featured.

            See also: [/api/live/*thread*/about](#GET_api_live_{thread}_about).
        """

        if not is_api() or not feature.is_enabled('live_happening_now'):
            self.abort404()

        event_id = NamedGlobals.get(HAPPENING_NOW_KEY, None)
        if not event_id:
            response.status_code = 204
            return

        try:
            event = LiveUpdateEvent._byID(event_id)
        except NotFound:
            response.status_code = 204
            return
        else:
            c.liveupdate_event = event
            content = Wrapped(event)
            return pages.LiveUpdateEventPage(content).render()
def adzerk_endpoint(endpoint):
    url = "%s/%s" % (URL_BASE, endpoint)

    if feature.is_enabled("adzerk_reporting_2"):
        url = url + "?datasource=1"

    return url
Exemple #14
0
 def GET_nominations(self, responder):
     if not feature.is_enabled('reddit_donate'):
         return self.abort404()
     nominated_org_ids = DonationNominationsByAccount.get_for(c.user)
     orgs = DonationOrganization.byEIN(nominated_org_ids)
     wrapped = inject_nomination_status(orgs, assume_nominated=True)
     return wrapped
Exemple #15
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 ageweight and feature.is_enabled("scaled_normalized_hot"):
        tuples_by_srid = get_hot_tuples(sr_ids, ageweight=ageweight)
    else:
        tuples_by_srid = sgm(g.cache, sr_ids, miss_fn=get_hot_tuples,
                             prefix='normalized_hot', time=g.page_cache_time)

    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
Exemple #16
0
    def keep_item(self, item):
        # doesn't use the default keep_item because we want to keep
        # things that were voted on, even if they've chosen to hide
        # them in normal listings
        user = c.user if c.user_is_loggedin else None

        if item._spam or item._deleted:
            return False
        # If checking (wrapped) links, filter out banned subreddits
        elif hasattr(item, "subreddit") and item.subreddit.spammy():
            return False
        elif hasattr(item, "subreddit") and not c.user_is_admin and not item.subreddit.is_exposed(user):
            return False
        elif self.skip_deleted_authors and getattr(item, "author", None) and item.author._deleted:
            return False
        elif isinstance(item.lookups[0], Subreddit) and not item.is_exposed(user):
            return False

        # show NSFW to API and RSS users unless obey_over18=true
        is_api_or_rss = c.render_style in API_TYPES or c.render_style in RSS_TYPES
        if is_api_or_rss:
            include_over18 = not c.obey_over18 or c.over18
        elif feature.is_enabled("safe_search"):
            include_over18 = c.over18
        else:
            include_over18 = True

        is_nsfw = item.over_18 or (hasattr(item, "subreddit") and item.subreddit.over_18)
        if is_nsfw and not include_over18:
            return False

        return True
 def GET_nominations(self, responder):
     if not feature.is_enabled('reddit_donate'):
         return self.abort404()
     nominated_org_ids = DonationNominationsByAccount.get_for(c.user)
     orgs = DonationOrganization.byEIN(nominated_org_ids)
     wrapped = inject_nomination_status(orgs, assume_nominated=True)
     return wrapped
Exemple #18
0
def register(name, password, registration_ip):
    # get a lock for registering an Account with this name to prevent
    # simultaneous operations from creating multiple Accounts with the same name
    with g.make_lock("account_register", "register_%s" % name.lower()):
        try:
            account = Account._by_name(name)
            raise AccountExists
        except NotFound:
            account = Account(
                name=name,
                password=bcrypt_password(password),
                # new accounts keep the profanity filter settings until opting out
                pref_no_profanity=True,
                registration_ip=registration_ip,
            )

            account._commit()

            if can_auto_optin_email(request, c):
                if feature.is_enabled("orangereds_as_emails", user=account):
                    account.pref_email_messages = True
                    account._commit()

            # update Account._by_name to pick up this new name->Account
            Account._by_name(name, _update=True)
            Account._by_name(name, allow_deleted=True, _update=True)

            return account
Exemple #19
0
def register(name, password, registration_ip):
    # get a lock for registering an Account with this name to prevent
    # simultaneous operations from creating multiple Accounts with the same name
    with g.make_lock("account_register", "register_%s" % name.lower()):
        try:
            account = Account._by_name(name)
            raise AccountExists
        except NotFound:
            account = Account(
                name=name,
                password=bcrypt_password(password),
                # new accounts keep the profanity filter settings until opting out
                pref_no_profanity=True,
                registration_ip=registration_ip,
            )

            account._commit()

            if can_auto_optin_email(request, c):              
                if feature.is_enabled('orangereds_as_emails', user=account):
                    account.pref_email_messages = True
                    account._commit()

            # update Account._by_name to pick up this new name->Account
            Account._by_name(name, _update=True)
            Account._by_name(name, allow_deleted=True, _update=True)

            return account
Exemple #20
0
    def keep_item(self, item):
        # doesn't use the default keep_item because we want to keep
        # things that were voted on, even if they've chosen to hide
        # them in normal listings
        if item._spam or item._deleted:
            return False
        # If checking (wrapped) links, filter out banned subreddits
        elif hasattr(item, 'subreddit') and item.subreddit.spammy():
            return False
        elif (self.skip_deleted_authors and getattr(item, "author", None)
              and item.author._deleted):
            return False

        # show NSFW to API and RSS users unless obey_over18=true
        is_api_or_rss = (c.render_style in API_TYPES
                         or c.render_style in RSS_TYPES)
        if is_api_or_rss:
            include_over18 = not c.obey_over18 or c.over18
        elif feature.is_enabled('safe_search'):
            include_over18 = c.over18
        else:
            include_over18 = True

        is_nsfw = (item.over_18
                   or (hasattr(item, 'subreddit') and item.subreddit.over_18))
        if is_nsfw and not include_over18:
            return False

        return True
Exemple #21
0
def _get_scrape_url(link):
    if not link.is_self:
        sr_name = link.subreddit_slow.name
        if not feature.is_enabled("imgur_gif_conversion", subreddit=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_reddit_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
Exemple #22
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 ageweight and feature.is_enabled("scaled_normalized_hot"):
        tuples_by_srid = get_hot_tuples(sr_ids, ageweight=ageweight)
    else:
        tuples_by_srid = sgm(g.cache,
                             sr_ids,
                             miss_fn=get_hot_tuples,
                             prefix='normalized_hot',
                             time=g.page_cache_time)

    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
Exemple #23
0
    def __init__(self, thing, campaign, before, after):
        self.thing = thing
        self.campaign = campaign
        self.before = before
        self.after = after
        self.prev = None
        self.next = None
        self.has_live_campaign = False
        self.has_early_campaign = False
        self.detail_name = ('campaign %s' %
                            campaign._id36 if campaign else 'all campaigns')
        self.has_adserver_reporting = feature.is_enabled("adserver_reporting")
        self.use_adserver_reporting = _use_adserver_reporting(thing)
        self.has_spent = self.use_adserver_reporting

        editable = c.user_is_sponsor or c.user._id == thing.author_id
        if self.use_adserver_reporting:
            # can't get this info from adserver
            self.traffic_last_modified = False
        else:
            self.traffic_last_modified = traffic.get_traffic_last_modified()
            self.traffic_lag = (datetime.datetime.utcnow() -
                                self.traffic_last_modified)

        self.interval = self.get_interval(thing)
        self.period = datetime.timedelta(
            days=30 if self.interval == "day" else 7)

        self.make_table(campaign or thing)
        self.make_campaign_table()
        Templated.__init__(self)
Exemple #24
0
    def __init__(self, thing, campaign, before, after):
        self.thing = thing
        self.campaign = campaign
        self.before = before
        self.after = after
        self.prev = None
        self.next = None
        self.has_live_campaign = False
        self.has_early_campaign = False
        self.detail_name = ('campaign %s' % campaign._id36 if campaign
                                                           else 'all campaigns')
        self.has_adserver_reporting = feature.is_enabled("adserver_reporting")
        self.use_adserver_reporting = _use_adserver_reporting(thing)
        self.has_spent = self.use_adserver_reporting


        editable = c.user_is_sponsor or c.user._id == thing.author_id
        if self.use_adserver_reporting:
            # can't get this info from adserver
            self.traffic_last_modified = False
        else:
            self.traffic_last_modified = traffic.get_traffic_last_modified()
            self.traffic_lag = (datetime.datetime.utcnow() -
                                self.traffic_last_modified)

        self.interval = self.get_interval(thing)
        self.period = datetime.timedelta(days=30 if self.interval == "day" else 7)

        self.make_table(campaign or thing)
        self.make_campaign_table()
        Templated.__init__(self)
Exemple #25
0
    def listing(self, next_suggestions=None):
        self.things, prev, next, bcount, acount = self.get_items()

        self.next_suggestions = next_suggestions
        self._max_num = max(acount, bcount)
        self.after = None
        self.before = None

        if self.nextprev and self.prev_link and prev and bcount > 1:
            p = self.params.copy()
            p.update({"after": None, "before": prev._fullname, "count": bcount})
            self.before = prev._fullname
            self.prev = request.path + utils.query_string(p)
            p_first = self.params.copy()
            p_first.update({"after": None, "before": None, "count": None})
            self.first = request.path + utils.query_string(p_first)
        if self.nextprev and self.next_link and next:
            p = self.params.copy()
            p.update({"after": next._fullname, "before": None, "count": acount})
            self.after = next._fullname
            self.next = request.path + utils.query_string(p)

        for count, thing in enumerate(self.things):
            thing.rowstyle_cls = getattr(thing, "rowstyle_cls", "")
            thing.rowstyle_cls += " " + ("even" if (count % 2) else "odd")
            thing.rowstyle = CachedVariable("rowstyle")

        survey_action = c.cookies.get("survey_action")
        if feature.is_enabled("show_survey") and not survey_action and g.live_config["survey_info"]:
            self.survey = ast.literal_eval(g.live_config["survey_info"])
            self.show_survey = True

        # TODO: need name for template -- must be better way
        return Wrapped(self)
Exemple #26
0
    def keep_item(self, item):
        # doesn't use the default keep_item because we want to keep
        # things that were voted on, even if they've chosen to hide
        # them in normal listings
        if item._spam or item._deleted:
            return False
        # If checking (wrapped) links, filter out banned subreddits
        elif hasattr(item, 'subreddit') and item.subreddit.spammy():
            return False
        elif (self.skip_deleted_authors and
              getattr(item, "author", None) and item.author._deleted):
            return False

        # show NSFW to API and RSS users unless obey_over18=true
        is_api_or_rss = (c.render_style in API_TYPES
                         or c.render_style in RSS_TYPES)
        if is_api_or_rss:
            include_over18 = not c.obey_over18 or c.over18
        elif feature.is_enabled('safe_search'):
            include_over18 = c.over18
        else:
            include_over18 = True

        is_nsfw = (item.over_18 or
            (hasattr(item, 'subreddit') and item.subreddit.over_18))
        if is_nsfw and not include_over18:
            return False

        return True
Exemple #27
0
    def GET_happening_now(self):
        """ Get some basic information about the currently featured live thread.

            Returns an empty 204 response for api requests if no thread is currently featured.

            See also: [/api/live/*thread*/about](#GET_api_live_{thread}_about).
        """

        if not is_api() or not feature.is_enabled('live_happening_now'):
            self.abort404()

        event_id = NamedGlobals.get(HAPPENING_NOW_KEY, None)
        if not event_id:
            response.status_code = 204
            return

        try:
            event = LiveUpdateEvent._byID(event_id)
        except NotFound:
            response.status_code = 204
            return
        else:
            c.liveupdate_event = event
            content = Wrapped(event)
            return pages.LiveUpdateEventPage(content).render()
Exemple #28
0
def _get_scrape_url(link):
    if not link.is_self:
        sr_name = link.subreddit_slow.name
        if not feature.is_enabled("imgur_gif_conversion", subreddit=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_reddit_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
Exemple #29
0
 def hidden_options(cls):
     if feature.is_enabled('qa_sort'):
         return ('random', )
     else:
         return (
             'random',
             'qa',
         )
Exemple #30
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
Exemple #31
0
    def __init__(self, thing, delete=False, report=True):
        was_comment = getattr(thing, 'was_comment', False)
        permalink = thing.permalink
        # don't allow replying to self unless it's modmail
        valid_recipient = (thing.author_id != c.user._id or thing.sr_id)

        can_reply = (c.user_is_loggedin and getattr(thing, "repliable", True)
                     and valid_recipient)
        can_block = True
        can_mute = False

        if not was_comment:
            first_message = thing
            if getattr(thing, 'first_message', False):
                first_message = Message._byID(thing.first_message, data=True)

            if thing.sr_id:
                sr = thing.subreddit_slow
                if feature.is_enabled('modmail_muting', subreddit=sr.name):
                    if (sr.is_muted(first_message.author_slow) or
                        (first_message.to_id
                         and sr.is_muted(first_message.recipient_slow))):
                        can_reply = False

                    if (not sr.is_moderator(thing.author_slow)
                            and sr.is_moderator_with_perms(
                                c.user, 'access', 'mail')):
                        can_mute = True

        if not was_comment and thing.display_author:
            can_block = False

        if was_comment:
            link = thing.link_slow
            if link.archived or link.locked:
                can_reply = False

        # Allow comment-reply messages to have links to the full thread.
        if was_comment:
            self.full_comment_path = thing.link_permalink
            self.full_comment_count = thing.full_comment_count

        PrintableButtons.__init__(
            self,
            "messagebuttons",
            thing,
            profilepage=c.profilepage,
            permalink=permalink,
            was_comment=was_comment,
            unread=thing.new,
            user_is_recipient=thing.user_is_recipient,
            can_reply=can_reply,
            parent_id=getattr(thing, "parent_id", None),
            show_report=True,
            show_delete=False,
            can_block=can_block,
            can_mute=can_mute,
        )
Exemple #32
0
    def raw_data(self, thing):
        data = ThingJsonTemplate.raw_data(self, thing)

        # XXX remove this when feature is enabled and use _data_attrs instead
        if feature.is_enabled('mobile_settings'):
            for attr in ('community_rules', 'key_color', 'related_subreddits'):
                data[attr] = self.thing_attr(thing.site, attr)

        return data
Exemple #33
0
    def raw_data(self, thing):
        data = ThingJsonTemplate.raw_data(self, thing)

        # XXX remove this when feature is enabled and use _data_attrs instead
        if feature.is_enabled('mobile_settings'):
            for attr in ('community_rules', 'key_color', 'related_subreddits'):
                data[attr] = self.thing_attr(thing.site, attr)

        return data
Exemple #34
0
    def __init__(self, thing, delete = False, report = True):
        was_comment = getattr(thing, 'was_comment', False)
        permalink = thing.permalink
        # don't allow replying to self unless it's modmail
        valid_recipient = (thing.author_id != c.user._id or
                           thing.sr_id)

        can_reply = (c.user_is_loggedin and
                     getattr(thing, "repliable", True) and
                     valid_recipient)
        can_block = True
        can_mute = False

        if not was_comment:
            first_message = thing
            if getattr(thing, 'first_message', False):
                first_message = Message._byID(thing.first_message, data=True)

            if thing.sr_id:
                sr = thing.subreddit_slow
                if feature.is_enabled('modmail_muting', subreddit=sr.name):
                    if (sr.is_muted(first_message.author_slow) or
                            (first_message.to_id and
                                sr.is_muted(first_message.recipient_slow))):
                        can_reply = False

                    if (not sr.is_moderator(thing.author_slow) and
                            sr.is_moderator_with_perms(c.user, 'access', 'mail')):
                        can_mute = True

        if not was_comment and thing.display_author:
            can_block = False

        if was_comment:
            link = thing.link_slow
            if link.archived or link.locked:
                can_reply = False

        # Allow comment-reply messages to have links to the full thread.
        if was_comment:
            self.full_comment_path = thing.link_permalink
            self.full_comment_count = thing.full_comment_count

        PrintableButtons.__init__(self, "messagebuttons", thing,
                                  profilepage = c.profilepage,
                                  permalink = permalink,
                                  was_comment = was_comment,
                                  unread = thing.new,
                                  user_is_recipient = thing.user_is_recipient,
                                  can_reply = can_reply,
                                  parent_id = getattr(thing, "parent_id", None),
                                  show_report = True,
                                  show_delete = False,
                                  can_block = can_block,
                                  can_mute = can_mute,
                                 )
Exemple #35
0
    def raw_data(self, thing):
        d = ThingJsonTemplate.raw_data(self, thing)

        if c.permalink_page:
            d["upvote_ratio"] = thing.upvote_ratio

        if feature.is_enabled('default_sort'):
            d['suggested_sort'] = thing.sort_if_suggested()

        return d
def add_home_sidebox():
    if not feature.is_enabled('place_on_homepage'):
        return None

    return SideBox(
        title="PLACE",
        css_class="place_sidebox",
        link="/r/place",
        target="_blank",
    )
Exemple #37
0
 def use_subreddit_style(self, sr):
     """Return whether to show subreddit stylesheet depending on
     individual selection if available, else use pref_show_stylesheets"""
     # if FakeSubreddit, 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))
Exemple #38
0
    def update_sr_activity(self, sr):
        if not self._spam:
            AccountsActiveBySR.touch(self, sr)

            if c.activity_service and feature.is_enabled("activity_service_write"):
                try:
                    c.activity_service.record_activity(
                        sr._fullname, self._fullname)
                except Thrift.TException as exc:
                    g.log.warning("failed to update activity: %s", exc)
Exemple #39
0
def add_home_sidebox():
    if not feature.is_enabled('robin_on_homepage'):
        return None

    return SideBox(
        title="robin",
        css_class="robin_sidebox",
        link="/robin",
        target="_blank",
    )
Exemple #40
0
    def raw_data(self, thing):
        d = ThingJsonTemplate.raw_data(self, thing)

        if c.permalink_page:
            d["upvote_ratio"] = thing.upvote_ratio

        if feature.is_enabled('default_sort'):
            d['suggested_sort'] = thing.sort_if_suggested()

        return d
Exemple #41
0
def handle_login(controller,
                 form,
                 responder,
                 user,
                 rem=None,
                 signature=None,
                 **kwargs):
    def _event(error):
        g.events.login_event('login_attempt',
                             error_msg=error,
                             user_name=request.urlvars.get('url_user'),
                             remember_me=rem,
                             signature=signature,
                             request=request,
                             context=c)

    if signature and not signature.is_valid():
        _event(error="SIGNATURE")
        abort(403)

    if feature.is_enabled('login_disabled'):
        _event(error="DISABLED")
        abort(403)

    hook_error = hooks.get_hook("account.login").call_until_return(
        responder=responder,
        request=request,
        context=c,
    )
    # if any of the hooks returned an error, abort the login.  The
    # set_error in this case also needs to exist in the hook.
    if hook_error:
        _event(error=hook_error)
        return

    exempt_ua = (request.user_agent and any(
        ua in request.user_agent
        for ua in g.config.get('exempt_login_user_agents', ())))
    if (errors.LOGGED_IN, None) in c.errors:
        if user == c.user or exempt_ua:
            # Allow funky clients to re-login as the current user.
            c.errors.remove((errors.LOGGED_IN, None))
        else:
            _event(error='LOGGED_IN')
            abort(reddit_http_error(409, errors.LOGGED_IN))

    if responder.has_errors("ratelimit", errors.RATELIMIT):
        _event(error='RATELIMIT')

    elif responder.has_errors("passwd", errors.WRONG_PASSWORD):
        _event(error='WRONG_PASSWORD')

    else:
        controller._login(responder, user, rem)
        _event(error=None)
Exemple #42
0
    def GET_search(self, responder, prefix):
        """Get organizations by display-name prefix."""

        if not feature.is_enabled('reddit_donate'):
            return self.abort404()

        if responder.has_errors("prefix", errors.TOO_LONG, errors.TOO_SHORT):
            return

        organizations = DonationOrganizationsByPrefix.byPrefix(prefix)
        return inject_nomination_status(organizations)
Exemple #43
0
    def update_sr_activity(self, sr):
        if not self._spam:
            AccountsActiveBySR.touch(self, sr)

            if c.activity_service and feature.is_enabled(
                    "activity_service_write"):
                try:
                    c.activity_service.record_activity(sr._fullname,
                                                       self._fullname)
                except Thrift.TException as exc:
                    g.log.warning("failed to update activity: %s", exc)
Exemple #44
0
 def use_subreddit_style(self, sr):
     """Return whether to show subreddit stylesheet depending on
     individual selection if available, else use pref_show_stylesheets"""
     # if FakeSubreddit, 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))
    def POST_unnominate(self, form, jquery, organization):
        if not feature.is_enabled('reddit_donate'):
            return self.abort404()

        if form.has_errors("organization", errors.DONATE_UNKNOWN_ORGANIZATION):
            return

        DonationNominationsByAccount.unnominate(
            c.user,
            organization,
        )
Exemple #46
0
    def POST_unnominate(self, form, jquery, organization):
        if not feature.is_enabled('reddit_donate'):
            return self.abort404()

        if form.has_errors("organization", errors.DONATE_UNKNOWN_ORGANIZATION):
            return

        DonationNominationsByAccount.unnominate(
            c.user,
            organization,
        )
    def GET_search(self, responder, prefix):
        """Get organizations by display-name prefix."""

        if not feature.is_enabled('reddit_donate'):
            return self.abort404()

        if responder.has_errors("prefix", errors.TOO_LONG, errors.TOO_SHORT):
            return

        organizations = DonationOrganizationsByPrefix.byPrefix(prefix)
        return inject_nomination_status(organizations)
Exemple #48
0
    def timeout_expiration(self):
        """Find the expiration date of the user's temp-timeout as a datetime
        object.

        Returns None if no temp-timeout found.
        """
        if not feature.is_enabled('timeouts'):
            return None
        if not self.in_timeout:
            return None

        return TempTimeout.search(self.name).get(self.name)
    def GET_organization(self, responder, organization):
        """Look up a single org by EIN."""

        if not feature.is_enabled('reddit_donate'):
            return self.abort404()

        if responder.has_errors("organization",
                                errors.DONATE_UNKNOWN_ORGANIZATION):
            return

        wrapped = inject_nomination_status([organization])
        return wrapped[0]
Exemple #50
0
    def timeout_expiration(self):
        """Find the expiration date of the user's temp-timeout as a datetime
        object.

        Returns None if no temp-timeout found.
        """
        if not feature.is_enabled('timeouts'):
            return None
        if not self.in_timeout:
            return None

        return TempTimeout.search(self.name).get(self.name)
Exemple #51
0
    def GET_organization(self, responder, organization):
        """Look up a single org by EIN."""

        if not feature.is_enabled('reddit_donate'):
            return self.abort404()

        if responder.has_errors("organization",
                                errors.DONATE_UNKNOWN_ORGANIZATION):
            return

        wrapped = inject_nomination_status([organization])
        return wrapped[0]
Exemple #52
0
 def GET_over18(self):
     if feature.is_enabled('better_interstitials'):
         return InterstitialPage(
             _("over 18?"),
             content=Over18Interstitial(),
         ).render()
     else:
         return BoringPage(_("over 18?"),
                           content=Over18(),
                           show_sidebar=False,
                           show_newsletterbar=False,
                           show_welcomebar=False,
                           robots='noindex,nofollow').render()
Exemple #53
0
def notify_user_added(rel_type, author, user, target):
    msgs = user_added_messages.get(rel_type)
    if not msgs:
        return

    srname = target.path.rstrip("/")
    d = {
        "url": srname,
        "title": "%s: %s" % (srname, target.title),
        "author": "/u/" + author.name,
        "user": "******" + user.name,
    }

    if "pm" in msgs and author != user:
        subject = msgs["pm"]["subject"] % d
        msg = msgs["pm"]["msg"] % d

        if rel_type in ("moderator_invite", "contributor"):
            # send the message from the subreddit
            item, inbox_rel = Message._new(
                author, user, subject, msg, request.ip, sr=target, from_sr=True,
                can_send_email=False, is_auto_modmail=True)
        else:
            item, inbox_rel = Message._new(
                author, user, subject, msg, request.ip, can_send_email=False)

        queries.new_message(item, inbox_rel, update_modmail=False)

    if "modmail" in msgs:
        subject = msgs["modmail"]["subject"] % d
        msg = msgs["modmail"]["msg"] % d

        if rel_type == "moderator_invite":
            # Don't send the separate moderator invite message from the
            # system user to new modmail, since the one sent to the invitee
            # will already show up in there.
            # TODO: when new modmail is fully deployed, the "modmail" dict
            # should be completely removed from the moderator_invite section
            # of user_added_messages, and this check removed.
            if feature.is_enabled('new_modmail', subreddit=target.name):
                return

            modmail_author = Account.system_user()
        else:
            modmail_author = author

        item, inbox_rel = Message._new(modmail_author, target, subject, msg,
                                       request.ip, sr=target,
                                       is_auto_modmail=True)
        queries.new_message(item, inbox_rel)
Exemple #54
0
    def POST_snoovatar(self, form, jquery, public, snoo_color,
                       unvalidated_components):
        if not feature.is_enabled('snoovatars'):
            return

        if form.has_errors(
                "components",
                errors.NO_TEXT,
                errors.TOO_LONG,
                errors.BAD_STRING,
        ):
            return
        if form.has_errors("snoo_color", errors.BAD_CSS_COLOR):
            return

        try:
            tailors = g.plugins["gold"].tailors_data
            validated = {}

            for tailor in tailors:
                tailor_name = tailor["name"]

                component = unvalidated_components.get(tailor_name)

                # if the tailor requires a selection, ensure there is one
                if not tailor["allow_clear"]:
                    require(component)

                # ensure this dressing exists
                dressing = component.get("dressingName")
                if dressing:
                    for d in tailor["dressings"]:
                        if dressing == d["name"]:
                            break
                    else:
                        raise RequirementException

                validated[tailor_name] = component
        except RequirementException:
            c.errors.add(errors.INVALID_SNOOVATAR, field="components")
            form.has_errors("components", errors.INVALID_SNOOVATAR)
            return

        SnoovatarsByAccount.save(
            user=c.user,
            name="snoo",
            public=public,
            snoo_color=snoo_color,
            components=validated,
        )
Exemple #55
0
    def raw_data(self, thing):
        data = ThingJsonTemplate.raw_data(self, thing)

        # XXX remove this when feature is enabled and use _data_attrs instead
        if feature.is_enabled('mobile_settings'):
            for attr in ('community_rules', 'key_color', 'related_subreddits'):
                data[attr] = self.thing_attr(thing, attr)

        permissions = getattr(thing, 'mod_permissions', None)
        if permissions:
            permissions = [perm for perm, has in permissions.iteritems() if has]
            data['mod_permissions'] = permissions

        return data
Exemple #56
0
    def raw_data(self, thing):
        data = ThingJsonTemplate.raw_data(self, thing)

        # XXX remove this when feature is enabled and use _data_attrs instead
        if feature.is_enabled('mobile_settings'):
            for attr in ('community_rules', 'key_color', 'related_subreddits'):
                data[attr] = self.thing_attr(thing, attr)

        permissions = getattr(thing, 'mod_permissions', None)
        if permissions:
            permissions = [perm for perm, has in permissions.iteritems() if has]
            data['mod_permissions'] = permissions

        return data
Exemple #57
0
def _set_media(link, force=False, **kwargs):
    sr = link.subreddit_slow

    # Do not process thumbnails for quarantined subreddits
    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", subreddit=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)
Exemple #58
0
def _prepare_image(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