示例#1
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)
示例#2
0
    def get_details(cls, thing, voters=None):
        from v1.models import Comment, Link
        if isinstance(thing, Link):
            details_cls = VoteDetailsByLink
        elif isinstance(thing, Comment):
            details_cls = VoteDetailsByComment
        else:
            raise ValueError

        voter_id36s = None
        if voters:
            voter_id36s = [voter._id36 for voter in voters]

        try:
            row = details_cls._byID(thing._id36, properties=voter_id36s)
            raw_details = row._values()
        except tdb_cassandra.NotFound:
            return []

        try:
            row = VoterIPByThing._byID(thing._fullname, properties=voter_id36s)
            ips = row._values()
        except tdb_cassandra.NotFound:
            ips = {}

        details = []
        for voter_id36, json_data in raw_details.iteritems():
            data = json.loads(json_data)
            data = cls.convert_old_details(data)

            user = Account._byID36(voter_id36, data=True)
            direction = Vote.deserialize_direction(data.pop("direction"))
            date = datetime.utcfromtimestamp(data.pop("date"))
            effects = data.pop("effects")
            data["ip"] = ips.get(voter_id36)

            vote = Vote(user, thing, direction, date, data, effects,
                get_previous_vote=False)
            details.append(vote)
        details.sort(key=lambda d: d.date)

        return details
示例#3
0
def generate_notification_email_unsubscribe_token(user_id36,
                                                  user_email=None,
                                                  user_password_hash=None):
    """Generate a token used for one-click unsubscribe links for notification
    emails.

    user_id36: A base36-encoded user id.
    user_email: The user's email.  Looked up if not provided.
    user_password_hash: The hash of the user's password.  Looked up if not
                        provided.
    """
    import hashlib
    import hmac

    if (not user_email) or (not user_password_hash):
        user = Account._byID36(user_id36, data=True)
        if not user_email:
            user_email = user.email
        if not user_password_hash:
            user_password_hash = user.password

    return hmac.new(g.secrets['email_notifications'],
                    user_id36 + user_email + user_password_hash,
                    hashlib.sha256).hexdigest()
示例#4
0
    def add_props(cls, user, wrapped):
        from v1.lib.db.thing import Thing
        from v1.lib.menus import QueryButton
        from v1.lib.pages import WrappedUser
        from v1.models import (
            Account,
            Link,
            ModSR,
            MultiVerbify,
            Subverbify,
        )

        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 subverbifys
        srs = Subverbify._byID36({item.sr_id36 for item in wrapped}, data=True)

        for item in wrapped:
            item.moderator = moderators[item.mod_id36]
            item.subverbify = 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, MultiVerbify):
                    rgb = item.subverbify.get_rgb()
                    item.bgcolor = 'rgb(%s,%s,%s)' % rgb
                    item.is_multi = True
                else:
                    item.bgcolor = "rgb(255,255,255)"
                    item.is_multi = False