コード例 #1
0
ファイル: ipn.py プロジェクト: whatcouldgowrong/reddit
    def process_response(self):
        data = request.POST

        transaction_id = 'RG%s' % data['transaction_id']
        pennies = int(data['pennies'])
        months = int(data['months'])
        status = 'succeeded'

        goldtype = data['goldtype']
        buyer = Account._by_name(data['buyer'])

        if goldtype == 'gift':
            gift_kw = {
                'recipient': Account._by_name(data['recipient']),
                'giftmessage': _force_utf8(data.get('giftmessage', None)),
                'signed': data.get('signed') == 'True',
            }
        else:
            gift_kw = {}

        webhook = Webhook(transaction_id=transaction_id,
                          pennies=pennies,
                          months=months,
                          goldtype=goldtype,
                          buyer=buyer,
                          **gift_kw)
        return status, webhook
コード例 #2
0
ファイル: ipn.py プロジェクト: jakesyl/reddit
    def process_response(self):
        data = request.POST

        transaction_id = 'RG%s' % data['transaction_id']
        pennies = int(data['pennies'])
        months = int(data['months'])
        status = 'succeeded'

        goldtype = data['goldtype']
        buyer = Account._by_name(data['buyer'])

        if goldtype == 'gift':
            gift_kw = {
                'recipient': Account._by_name(data['recipient']),
                'giftmessage': _force_utf8(data.get('giftmessage', None)),
                'signed': data.get('signed') == 'True',
            }
        else:
            gift_kw = {}

        webhook = Webhook(
            transaction_id=transaction_id,
            pennies=pennies,
            months=months,
            goldtype=goldtype,
            buyer=buyer,
            **gift_kw)
        return status, webhook
コード例 #3
0
ファイル: test_vverifypassword.py プロジェクト: xxl007/reddit
    def setUpClass(cls):
        cls._backup_user = c.user
        cls._backup_loggedin = c.user_is_loggedin

        # Create a dummy account for testing with; won't touch the database
        # as long as we don't `._commit()`
        name = "unit_tester_%s" % uuid.uuid4().hex
        cls._password = uuid.uuid4().hex
        try:
            Account._by_name(name)
            raise AccountExists
        except NotFound:
            cls._account = Account(name=name,
                                   password=bcrypt_password(cls._password))
コード例 #4
0
    def setUpClass(cls):
        cls._backup_user = c.user
        cls._backup_loggedin = c.user_is_loggedin

        # Create a dummy account for testing with; won't touch the database
        # as long as we don't `._commit()`
        name = "unit_tester_%s" % uuid.uuid4().hex
        cls._password = uuid.uuid4().hex
        try:
            Account._by_name(name)
            raise AccountExists
        except NotFound:
            cls._account = Account(
                name=name,
                password=bcrypt_password(cls._password)
            )
コード例 #5
0
ファイル: submit_link.py プロジェクト: saisai/postcards
def submit_link(user, subreddit, title, url, thumb_url):
    account = Account._by_name(user)
    subreddit = Subreddit._by_name(subreddit)
    ip = '127.0.0.1'

    # submit the link
    link = Link._submit(
        is_self=False,
        title=title,
        content=url,
        author=account,
        sr=subreddit,
        ip=ip,
        spam=False,
    )

    try:
        # force the thumbnail before scraper_q gets in the mix
        image_data = urllib.urlopen(thumb_url).read()
        force_thumbnail(link, image_data)
    except:
        pass

    # various backend processing things
    queries.new_link(link)
    link.update_search_index()

    # wait for the amqp worker to finish up
    worker.join()

    print link.make_permalink_slow()
コード例 #6
0
ファイル: api.py プロジェクト: eerock/reddit
    def process_response(self, res):
        from r2.models import Account

        fullname = res.merchantcustomerid.contents[0]
        name = res.description.contents[0]
        customer_id = int(res.customerprofileid.contents[0])
        acct = Account._by_name(name)

        # make sure we are updating the correct account!
        if acct.name == name:
            CustomerID.set(acct, customer_id)
        else:
            raise AuthorizeNetException, "account name doesn't match authorize.net account"

        # parse the ship-to list, and make sure the Account is up todate
        ship_to = []
        for profile in res.findAll("shiptolist"):
            a = Address.fromXML(profile)
            ShippingAddress.add(acct, a.customerAddressId)
            ship_to.append(a)

        # parse the payment profiles, and ditto
        profiles = []
        for profile in res.findAll("paymentprofiles"):
            a = Address.fromXML(profile)
            cc = CreditCard.fromXML(profile.payment)
            payprof = PaymentProfile(a, cc, int(a.customerPaymentProfileId))
            PayID.add(acct, a.customerPaymentProfileId)
            profiles.append(payprof)

        return acct, Profile(acct, profiles, ship_to)
コード例 #7
0
ファイル: ipn.py プロジェクト: new-day-international/reddit
    def process_response(self):
        data = request.POST

        transaction_id = "RG%s" % data["transaction_id"]
        pennies = int(data["pennies"])
        months = int(data["months"])
        status = "succeeded"

        buyer_name = data["buyer"]
        goldtype = data["goldtype"]

        buyer = Account._by_name(buyer_name)

        blob = {"goldtype": goldtype, "account_id": buyer._id, "account_name": buyer.name, "status": "initialized"}

        if goldtype == "gift":
            blob["recipient"] = data["recipient"]
            giftmessage = data.get("giftmessage", None)
            blob["giftmessage"] = _force_utf8(giftmessage)
            signed = data.get("signed")
            blob["signed"] = True if signed == "True" else False

        passthrough = generate_blob(blob)

        return status, passthrough, transaction_id, pennies, months
コード例 #8
0
ファイル: ipn.py プロジェクト: siadat/reddit
    def process_response(self):
        data = request.POST

        transaction_id = 'RG%s' % data['transaction_id']
        pennies = int(data['pennies'])
        months = int(data['months'])
        status = 'succeeded'

        buyer_name = data['buyer']
        goldtype = data['goldtype']

        buyer = Account._by_name(buyer_name)

        blob = {
            'goldtype': goldtype,
            'account_id': buyer._id,
            'account_name': buyer.name,
            'status': 'initialized',
        }

        if goldtype == 'gift':
            blob['recipient'] = data['recipient']
            giftmessage = data.get('giftmessage', None)
            blob['giftmessage'] = _force_utf8(giftmessage)
            signed = data.get('signed')
            blob['signed'] = True if signed == 'True' else False

        passthrough = generate_blob(blob)

        return status, passthrough, transaction_id, pennies, months
コード例 #9
0
ファイル: http.py プロジェクト: yangman-c/reddit
    def get_authenticated_account(self):
        from r2.models import Account, NotFound, register

        try:
            authorization = request.environ.get("HTTP_AUTHORIZATION")
            username, password = parse_http_basic(authorization)
        except RequirementException:
            return None

        try:
            account = Account._by_name(username)
        except NotFound:
            if g.auth_trust_http_authorization:
                # note: we're explicitly allowing automatic re-registration of
                # _deleted accounts and login of _banned accounts here because
                # we're trusting you know what you're doing in an SSO situation
                account = register(username, password, request.ip)
            else:
                return None

        # if we're to trust the authorization headers, don't check passwords
        if g.auth_trust_http_authorization:
            return account

        # not all systems support bcrypt in the standard crypt
        if account.password.startswith("$2a$"):
            expected_hash = bcrypt.hashpw(password, account.password)
        else:
            expected_hash = crypt.crypt(password, account.password)

        if not constant_time_compare(expected_hash, account.password):
            return None
        return account
コード例 #10
0
ファイル: api.py プロジェクト: DanHoerst/reddit
    def process_response(self, res):
        from r2.models import Account
        fullname = res.merchantcustomerid.contents[0]
        name = res.description.contents[0]
        customer_id = int(res.customerprofileid.contents[0])
        acct = Account._by_name(name)

        # make sure we are updating the correct account!
        if acct.name == name:
            CustomerID.set(acct, customer_id)
        else:
            raise AuthorizeNetException, \
                  "account name doesn't match authorize.net account"

        # parse the ship-to list, and make sure the Account is up todate
        ship_to = []
        for profile in res.findAll("shiptolist"):
            a = Address.fromXML(profile)
            ShippingAddress.add(acct, a.customerAddressId)
            ship_to.append(a)

        # parse the payment profiles, and ditto
        profiles = []
        for profile in res.findAll("paymentprofiles"):
            a = Address.fromXML(profile)
            cc = CreditCard.fromXML(profile.payment)
            payprof = PaymentProfile(a, cc, int(a.customerPaymentProfileId))
            PayID.add(acct, a.customerPaymentProfileId)
            profiles.append(payprof)

        return acct, Profile(acct, profiles, ship_to)
コード例 #11
0
def create_account(full_name):
    name = full_name.replace(' ', '_')
    retry = 2 # First retry will by name2
    username = name
    while True:
        # Create a new account
        try:
            if dryrun:
                try:
                    account = Account._by_name(username)
                    if account:
                        raise AccountExists
                except NotFound:
                    account = FakeAccount()
                    account.name = username
            else:
                account = register(username, generate_password(), None)
                account.ob_account_name = full_name
                account._commit()
        except AccountExists:
            # This username is taken, generate another, but first limit the retries
            if retry > MAX_RETRIES:
                raise StandardError("Unable to create account for '%s' after %d attempts" % (full_name, retry - 1))
        else:
            return account
        username = "******" % (name, retry)
        retry += 1
コード例 #12
0
ファイル: ipn.py プロジェクト: rolmos/reddit
    def process_response(self):
        data = request.POST

        transaction_id = 'RG%s' % data['transaction_id']
        pennies = int(data['pennies'])
        months = int(data['months'])
        status = 'succeeded'

        buyer_name = data['buyer']
        goldtype = data['goldtype']

        buyer = Account._by_name(buyer_name)

        blob = {
            'goldtype': goldtype,
            'account_id': buyer._id,
            'account_name': buyer.name,
            'status': 'initialized',
        }

        if goldtype == 'gift':
            blob['recipient'] = data['recipient']
            giftmessage = data.get('giftmessage', None)
            blob['giftmessage'] = _force_utf8(giftmessage)
            signed = data.get('signed')
            blob['signed'] = True if signed == 'True' else False

        passthrough = generate_blob(blob)

        return status, passthrough, transaction_id, pennies, months
コード例 #13
0
ファイル: gold.py プロジェクト: Shilohtd/reddit
    def _gift_using_creddits(self, recipient, months=1, thing_fullname=None, proxying_for=None):
        with creddits_lock(c.user):
            if not c.user.employee and c.user.gold_creddits < months:
                err = RedditError("INSUFFICIENT_CREDDITS")
                self.on_validation_error(err)

            note = None
            buyer = c.user
            if c.user.name.lower() in g.live_config["proxy_gilding_accounts"]:
                note = "proxy-%s" % c.user.name
                if proxying_for:
                    try:
                        buyer = Account._by_name(proxying_for)
                    except NotFound:
                        pass

            send_gift(
                buyer=buyer,
                recipient=recipient,
                months=months,
                days=months * 31,
                signed=False,
                giftmessage=None,
                thing_fullname=thing_fullname,
                note=note,
            )

            if not c.user.employee:
                c.user.gold_creddits -= months
                c.user._commit()
コード例 #14
0
ファイル: gold.py プロジェクト: vivekbarsagadey/reddit
    def _gift_using_creddits(self, recipient, months=1, thing_fullname=None,
            proxying_for=None):
        with creddits_lock(c.user):
            if not c.user.employee and c.user.gold_creddits < months:
                err = RedditError("INSUFFICIENT_CREDDITS")
                self.on_validation_error(err)

            note = None
            buyer = c.user
            if c.user.name.lower() in g.live_config["proxy_gilding_accounts"]:
                note = "proxy-%s" % c.user.name
                if proxying_for:
                    try:
                        buyer = Account._by_name(proxying_for)
                    except NotFound:
                        pass

            send_gift(
                buyer=buyer,
                recipient=recipient,
                months=months,
                days=months * 31,
                signed=False,
                giftmessage=None,
                thing_fullname=thing_fullname,
                note=note,
            )

            if not c.user.employee:
                c.user.gold_creddits -= months
                c.user._commit()
コード例 #15
0
ファイル: scraper.py プロジェクト: kevinrose/diggit
def submit_all():
    from r2.models import Subdigg, Account, Link, NotFound
    from r2.lib.media import set_media
    from r2.lib.db import queries
    sr = Subdigg._by_name('testmedia')
    author = Account._by_name('testmedia')
    links = []
    for url in test_urls:
        try:
            # delete any existing version of the link
            l = Link._by_url(url, sr)
            print "Deleting %s" % l
            l._deleted = True
            l._commit()
        except NotFound:
            pass

        l = Link._submit(url, url, author, sr, '0.0.0.0')

        try:
            set_media(l)
        except Exception, e:
            print e

        if g.write_query_queue:
            queries.new_link(l)

        links.append(l)
コード例 #16
0
def job_send_meetup_email_to_user(meetup_id, username):
    meetup = Meetup._byID(meetup_id, data=True)
    try:
      user = Account._by_name(username)
      notify.email_user_about_meetup(user, meetup)
    except NotFound:
      # Users can get deleted so ignore if not found
      pass
コード例 #17
0
def monitor_mentions(comment):
    if not isinstance(comment, Comment):
        return

    if comment._spam or comment._deleted:
        return

    sender = comment.author_slow
    if getattr(sender, "butler_ignore", False):
        # this is an account that generates false notifications, e.g.
        # LinkFixer
        return

    subreddit = comment.subreddit_slow
    usernames = list(
        extract_user_mentions(comment.body, num=g.butler_max_mentions + 1))
    inbox_class = Inbox.rel(Account, Comment)

    # If more than our allowed number of mentions were passed, don't highlight
    # any of them.
    if len(usernames) > g.butler_max_mentions:
        return

    # Subreddit.can_view stupidly requires this.
    c.user_is_loggedin = True

    for username in usernames:
        try:
            account = Account._by_name(username)
        except NotFound:
            continue

        # most people are aware of when they mention themselves.
        if account == sender:
            continue

        # bail out if that user has the feature turned off
        if not account.pref_monitor_mentions:
            continue

        # don't notify users of things they can't see
        if not subreddit.can_view(account):
            continue

        # don't notify users when a person they've blocked mentions them
        if account.is_enemy(sender):
            continue

        # ensure this comment isn't already in the user's inbox already
        rels = inbox_class._fast_query(
            account,
            comment,
            ("inbox", "selfreply", "mention"),
        )
        if filter(None, rels.values()):
            continue

        notify_mention(account, comment)
コード例 #18
0
def enflair(subreddit_name, account_name, flair_text, flair_class):
    sr = Subreddit._by_name(subreddit_name)
    account = Account._by_name(account_name)

    sr.add_flair(account)

    setattr(account, "flair_%d_text" % sr._id, flair_text)
    setattr(account, "flair_%d_css_class" % sr._id, flair_class)
    account._commit()
コード例 #19
0
def ensure_account(name):
    """Look up or register an account and return it."""
    try:
        account = Account._by_name(name)
        print ">> found /u/{}".format(name)
        return account
    except NotFound:
        print ">> registering /u/{}".format(name)
        return register(name, "password", "127.0.0.1")
コード例 #20
0
ファイル: butler.py プロジェクト: Robert77168/reddit
def monitor_mentions(comment):
    if not isinstance(comment, Comment):
        return

    if comment._spam or comment._deleted:
        return

    sender = comment.author_slow
    if getattr(sender, "butler_ignore", False):
        # this is an account that generates false notifications, e.g.
        # LinkFixer
        return

    subreddit = comment.subreddit_slow
    usernames = list(extract_user_mentions(comment.body, num=g.butler_max_mentions + 1))
    inbox_class = Inbox.rel(Account, Comment)

    # If more than our allowed number of mentions were passed, don't highlight
    # any of them.
    if len(usernames) > g.butler_max_mentions:
        return

    # Subreddit.can_view stupidly requires this.
    c.user_is_loggedin = True

    for username in usernames:
        try:
            account = Account._by_name(username)
        except NotFound:
            continue

        # most people are aware of when they mention themselves.
        if account == sender:
            continue

        # bail out if that user has the feature turned off
        if not account.pref_monitor_mentions:
            continue

        # don't notify users of things they can't see
        if not subreddit.can_view(account):
            continue

        # don't notify users when a person they've blocked mentions them
        if account.is_enemy(sender):
            continue

        # ensure this comment isn't already in the user's inbox already
        rels = inbox_class._fast_query(
            account,
            comment,
            ("inbox", "selfreply", "mention"),
        )
        if filter(None, rels.values()):
            continue

        notify_mention(account, comment)
コード例 #21
0
def ensure_account(name):
    """Look up or register an account and return it."""
    try:
        account = Account._by_name(name)
        print ">> found /u/{}".format(name)
        return account
    except NotFound:
        print ">> registering /u/{}".format(name)
        return register(name, "password", "127.0.0.1")
コード例 #22
0
ファイル: enflair.py プロジェクト: chromakode/postcards
def enflair(subreddit_name, account_name, flair_text, flair_class):
    sr = Subreddit._by_name(subreddit_name)
    account = Account._by_name(account_name)

    sr.add_flair(account)

    setattr(account, "flair_%d_text" % sr._id, flair_text)
    setattr(account, "flair_%d_css_class" % sr._id, flair_class)
    account._commit()
コード例 #23
0
 def _(username):
     try:
         account = Account._by_name(username)
         if notify_accounts is not None:
             notify_accounts.add(account)
         return True
     except NotFound:
         account = None
         return False
コード例 #24
0
def fix_about_post():
    user = Account._by_name('Eliezer_Yudkowsky')
    l = Link._byID(1, data=True)
    # l = Link._byID(int('1i', 36))
    if l.url.lower() == 'self':
        l.url = l.make_permalink_slow()
        l.is_self = True
        l._commit()
        l.set_url_cache()
    v = Vote.vote(user, l, True, l.ip, False)
コード例 #25
0
ファイル: post_tools.py プロジェクト: AndrewHay/lesswrong
def fix_about_post():
    user = Account._by_name('Eliezer_Yudkowsky')
    l = Link._byID(1, data=True)
    # l = Link._byID(int('1i', 36))
    if l.url.lower() == 'self':
        l.url = l.make_permalink_slow()
        l.is_self = True
        l._commit()
        l.set_url_cache()
    v = Vote.vote(user, l, True, l.ip, False)
コード例 #26
0
ファイル: ipn.py プロジェクト: tolgaek/reddit
    def POST_spendcreddits(self, form, jquery, months, passthrough):
        if months is None or months < 1:
            form.set_html(".status", _("nice try."))
            return

        days = months * 31

        if not passthrough:
            raise ValueError("/spendcreddits got no passthrough?")

        blob_key, payment_blob = get_blob(passthrough)
        if payment_blob["goldtype"] != "gift":
            raise ValueError("/spendcreddits payment_blob %s has goldtype %s" % (passthrough, payment_blob["goldtype"]))

        signed = payment_blob["signed"]
        giftmessage = _force_unicode(payment_blob["giftmessage"])
        recipient_name = payment_blob["recipient"]

        if payment_blob["account_id"] != c.user._id:
            fmt = "/spendcreddits payment_blob %s has userid %d " + "but c.user._id is %d"
            raise ValueError(fmt % passthrough, payment_blob["account_id"], c.user._id)

        try:
            recipient = Account._by_name(recipient_name)
        except NotFound:
            raise ValueError("Invalid username %s in spendcreddits, buyer = %s" % (recipient_name, c.user.name))

        if recipient._deleted:
            form.set_html(".status", _("that user has deleted their account"))
            return

        if not c.user.employee:
            if months > c.user.gold_creddits:
                raise ValueError("%s is trying to sneak around the creddit check" % c.user.name)

            c.user.gold_creddits -= months
            c.user.gold_creddit_escrow += months
            c.user._commit()

        comment_id = payment_blob.get("comment")
        comment = send_gift(c.user, recipient, months, days, signed, giftmessage, comment_id)

        if not c.user.employee:
            c.user.gold_creddit_escrow -= months
            c.user._commit()

        payment_blob["status"] = "processed"
        g.hardcache.set(blob_key, payment_blob, 86400 * 30)

        form.set_html(".status", _("the gold has been delivered!"))
        form.find("button").hide()

        if comment:
            gilding_message = make_comment_gold_message(comment, user_gilded=True)
            jquery.gild_comment(comment_id, gilding_message, comment.gildings)
コード例 #27
0
ファイル: models.py プロジェクト: wting/reddit-plugin-robin
def populate(start=0, num_users=16384):
    from r2.models.account import Account, register, AccountExists
    from reddit_robin.matchmaker import add_to_waitinglist

    for i in xrange(start, num_users):
        name = "test%s" % i
        try:
            a = register(name, "123456", registration_ip="127.0.0.1")
        except AccountExists:
            a = Account._by_name(name)
        print "added %s" % a
        add_to_waitinglist(a)
コード例 #28
0
def enflair(subreddit_name, account_name, flair_text, flair_class):
    sr = Subreddit._by_name(subreddit_name)

    try:
        account = Account._by_name(account_name)
    except NotFound:
        return

    sr.add_flair(account)

    setattr(account, "flair_%d_text" % sr._id, flair_text)
    setattr(account, "flair_%d_css_class" % sr._id, flair_class)
    account._commit()
コード例 #29
0
ファイル: enflair.py プロジェクト: MelissaCole/postcards
def enflair(subreddit_name, account_name, flair_text, flair_class):
    sr = Subreddit._by_name(subreddit_name)

    try:
        account = Account._by_name(account_name)
    except NotFound:
        return

    sr.add_flair(account)

    setattr(account, "flair_%d_text" % sr._id, flair_text)
    setattr(account, "flair_%d_css_class" % sr._id, flair_class)
    account._commit()
コード例 #30
0
    def get_reports(cls, wrapped, max_user_reasons=20):
        """Get two lists of mod and user reports on the item."""
        if (wrapped.reported > 0 and
                (wrapped.can_ban or
                 getattr(wrapped, "promoted", None) and c.user_is_sponsor)):
            from r2.models import SRMember

            reports = cls.for_thing(wrapped.lookups[0])

            q = SRMember._simple_query(
                ["_thing2_id", "_date"],
                SRMember.c._thing1_id == wrapped.sr_id,
                SRMember.c._name == "moderator",
            )
            mod_dates = {rel._thing2_id: rel._date for rel in q}

            if g.automoderator_account:
                automoderator = Account._by_name(g.automoderator_account)
            else:
                automoderator = None

            mod_reports = []
            user_reports = []

            for report in reports:
                # always include AutoModerator reports
                if automoderator and report._thing1_id == automoderator._id:
                    mod_reports.append(report)
                # include in mod reports if made after the user became a mod
                elif (report._thing1_id in mod_dates and
                        report._date >= mod_dates[report._thing1_id]):
                    mod_reports.append(report)
                else:
                    user_reports.append(report)

            # mod reports return as tuples with (reason, name)
            mods = Account._byID([report._thing1_id
                                  for report in mod_reports],
                                 data=True, return_dict=True)
            mod_reports = [(getattr(report, "reason", None),
                            mods[report._thing1_id].name)
                            for report in mod_reports]

            # user reports return as tuples with (reason, count)
            user_reports = Counter([getattr(report, "reason", None)
                                    for report in user_reports])
            user_reports = user_reports.most_common(max_user_reasons)

            return mod_reports, user_reports
        else:
            return [], []
コード例 #31
0
ファイル: ipn.py プロジェクト: shuapeng/reddit
def validate_blob(custom):
    """Validate payment_blob and return a dict with everything looked up."""
    ret = {}

    if not custom:
        raise GoldException('no custom')

    payment_blob = g.hardcache.get('payment_blob-%s' % str(custom))
    if not payment_blob:
        raise GoldException('no payment_blob')

    if 'account_id' in payment_blob and 'account_name' in payment_blob:
        try:
            buyer = Account._byID(payment_blob['account_id'], data=True)
            ret['buyer'] = buyer
        except NotFound:
            raise GoldException('bad account_id')

        if not buyer.name.lower() == payment_blob['account_name'].lower():
            raise GoldException('buyer mismatch')
    elif 'email' in payment_blob:
        ret['email'] = payment_blob['email']
    else:
        raise GoldException('no account_id or email')

    goldtype = payment_blob['goldtype']
    ret['goldtype'] = goldtype

    if goldtype == 'gift':
        recipient_name = payment_blob.get('recipient', None)
        if not recipient_name:
            raise GoldException('gift missing recpient')
        try:
            recipient = Account._by_name(recipient_name)
            ret['recipient'] = recipient
        except NotFound:
            raise GoldException('bad recipient')
        thing_fullname = payment_blob.get('thing', None)
        if thing_fullname:
            try:
                ret['thing'] = Thing._by_fullname(thing_fullname)
            except NotFound:
                raise GoldException('bad thing')
        ret['signed'] = payment_blob.get('signed', False)
        giftmessage = payment_blob.get('giftmessage')
        giftmessage = _force_unicode(giftmessage) if giftmessage else None
        ret['giftmessage'] = giftmessage
    elif goldtype not in ('onetime', 'autorenew', 'creddits', 'code'):
        raise GoldException('bad goldtype')

    return ret
コード例 #32
0
ファイル: ipn.py プロジェクト: dinxx/reddit
def validate_blob(custom):
    """Validate payment_blob and return a dict with everything looked up."""
    ret = {}

    if not custom:
        raise GoldException('no custom')

    payment_blob = g.hardcache.get('payment_blob-%s' % str(custom))
    if not payment_blob:
        raise GoldException('no payment_blob')

    if 'account_id' in payment_blob and 'account_name' in payment_blob:
        try:
            buyer = Account._byID(payment_blob['account_id'], data=True)
            ret['buyer'] = buyer
        except NotFound:
            raise GoldException('bad account_id')

        if not buyer.name.lower() == payment_blob['account_name'].lower():
            raise GoldException('buyer mismatch')
    elif 'email' in payment_blob:
        ret['email'] = payment_blob['email']
    else:
        raise GoldException('no account_id or email')

    goldtype = payment_blob['goldtype']
    ret['goldtype'] = goldtype

    if goldtype == 'gift':
        recipient_name = payment_blob.get('recipient', None)
        if not recipient_name:
            raise GoldException('gift missing recpient')
        try:
            recipient = Account._by_name(recipient_name)
            ret['recipient'] = recipient
        except NotFound:
            raise GoldException('bad recipient')
        thing_fullname = payment_blob.get('thing', None)
        if thing_fullname:
            try:
                ret['thing'] = Thing._by_fullname(thing_fullname)
            except NotFound:
                raise GoldException('bad thing')
        ret['signed'] = payment_blob.get('signed', False)
        giftmessage = payment_blob.get('giftmessage')
        giftmessage = _force_unicode(giftmessage) if giftmessage else None
        ret['giftmessage'] = giftmessage
    elif goldtype not in ('onetime', 'autorenew', 'creddits', 'code'):
        raise GoldException('bad goldtype')

    return ret
コード例 #33
0
ファイル: sr_rss.py プロジェクト: constantAmateur/sciteit
def run():
    #rss = get_sr_rss()
    #names = rss.keys()
    #Build tree order, this will be from root to leaves.
    order=build_sr_tree(Subsciteit._by_name(g.default_sr)._id)
    #Populate RSS in the other order...
    order.reverse()
    for sr_id in order:
        sr = Subsciteit._byID(sr_id)
	if sr.rss_source:
	    #ac=Account._byID(srob.moderators[0])
	    ac=Account._by_name(g.system_user)
            print "Populating %s as %s using feed |%s|" % (sr.name,ac.name,sr.rss_source)
            submit_rss_links(sr.name,sr.rss_source,user=ac._id)
コード例 #34
0
ファイル: ipn.py プロジェクト: tolgaek/reddit
def validate_blob(custom):
    """Validate payment_blob and return a dict with everything looked up."""
    ret = {}

    if not custom:
        raise GoldException("no custom")

    payment_blob = g.hardcache.get("payment_blob-%s" % str(custom))
    if not payment_blob:
        raise GoldException("no payment_blob")

    if not ("account_id" in payment_blob and "account_name" in payment_blob):
        raise GoldException("no account_id")

    try:
        buyer = Account._byID(payment_blob["account_id"], data=True)
        ret["buyer"] = buyer
    except NotFound:
        raise GoldException("bad account_id")

    if not buyer.name.lower() == payment_blob["account_name"].lower():
        raise GoldException("buyer mismatch")

    goldtype = payment_blob["goldtype"]
    ret["goldtype"] = goldtype

    if goldtype == "gift":
        recipient_name = payment_blob.get("recipient", None)
        if not recipient_name:
            raise GoldException("gift missing recpient")
        try:
            recipient = Account._by_name(recipient_name)
            ret["recipient"] = recipient
        except NotFound:
            raise GoldException("bad recipient")
        comment_fullname = payment_blob.get("comment", None)
        if comment_fullname:
            try:
                ret["comment"] = Comment._by_fullname(comment_fullname)
            except NotFound:
                raise GoldException("bad comment")
        ret["signed"] = payment_blob.get("signed", False)
        giftmessage = payment_blob.get("giftmessage")
        giftmessage = _force_unicode(giftmessage) if giftmessage else None
        ret["giftmessage"] = giftmessage
    elif goldtype not in ("onetime", "autorenew", "creddits"):
        raise GoldException("bad goldtype")

    return ret
コード例 #35
0
def send_claim_message(username, postcard_url):
    # this is ripped off from the gold-record.py code in reddit-private
    timestamp = int(time.time())
    now = datetime.datetime.now(g.tz)
    transaction_id = "M%d" % timestamp
    secret = "p_%d%s" % (timestamp, randstr(5))
    create_unclaimed_gold(transaction_id, "", "manual-unclaimed",
                          0, REWARD, secret, now, None)

    claim_url = "http://www.reddit.com/thanks/" + secret
    user = Account._by_name(username)
    message = TEMPLATE % dict(postcard_url=postcard_url,
                              claim_url=claim_url,
                              gold_support_email=g.goldthanks_email)
    send_system_message(user, "we got that postcard you sent us!", message)
コード例 #36
0
ファイル: ipn.py プロジェクト: tolgaek/reddit
    def process_response(self):
        data = request.POST

        transaction_id = "RG%s" % data["transaction_id"]
        pennies = int(data["pennies"])
        months = int(data["months"])
        status = "succeeded"

        goldtype = data["goldtype"]
        buyer = Account._by_name(data["buyer"])

        if goldtype == "gift":
            gift_kw = {
                "recipient": Account._by_name(data["recipient"]),
                "giftmessage": _force_utf8(data.get("giftmessage", None)),
                "signed": data.get("signed") == "True",
            }
        else:
            gift_kw = {}

        webhook = Webhook(
            transaction_id=transaction_id, pennies=pennies, months=months, goldtype=goldtype, buyer=buyer, **gift_kw
        )
        return status, webhook
コード例 #37
0
def update_user(user):
    if isinstance(user, str):
        user = Account._by_name(user)
    elif isinstance(user, int):
        user = Account._byID(user)

    results = [get_inbox_messages(user),
               get_inbox_comments(user),
               get_sent(user),
               get_liked(user),
               get_disliked(user),
               get_saved(user),
               get_hidden(user),
               get_submitted(user, 'new', 'all'),
               get_comments(user, 'new', 'all')]
    add_queries(results)
コード例 #38
0
ファイル: queries.py プロジェクト: Craigus/lesswrong
def update_user(user):
    if isinstance(user, str):
        user = Account._by_name(user)
    elif isinstance(user, int):
        user = Account._byID(user)

    results = [get_inbox_messages(user),
               get_inbox_comments(user),
               get_sent(user),
               get_liked(user),
               get_disliked(user),
               get_saved(user),
               get_hidden(user),
               get_submitted(user, 'new', 'all'),
               get_comments(user, 'new', 'all')]
    add_queries(results)
コード例 #39
0
ファイル: queries.py プロジェクト: huasanyelao/reddit
def update_user(user):
    if isinstance(user, str):
        user = Account._by_name(user)
    elif isinstance(user, int):
        user = Account._byID(user)

    results = [
        get_inbox_messages(user),
        get_inbox_comments(user),
        get_inbox_selfreply(user),
        get_sent(user),
        get_liked(user),
        get_disliked(user),
        get_submitted(user, "new", "all"),
        get_comments(user, "new", "all"),
    ]
    for q in results:
        q.update()
コード例 #40
0
ファイル: submit_link.py プロジェクト: chromakode/postcards
def submit_link(user, subreddit, title, url, thumb_url):
    account = Account._by_name(user)
    subreddit = Subreddit._by_name(subreddit)
    ip = '127.0.0.1'

    # submit the link
    link = Link._submit(title, url, account, subreddit, ip, spam=False)

    # force the thumbnail before scraper_q gets in the mix
    image_data = urllib.urlopen(thumb_url).read()
    force_thumbnail(link, image_data)

    # various backend processing things
    queries.queue_vote(account, link, True, ip)
    queries.new_link(link)
    queries.changed(link)

    print link.make_permalink_slow()
コード例 #41
0
def set_prefs(user, prefs):
    for k, v in prefs.iteritems():
        if k == 'pref_beta' and v and not getattr(user, 'pref_beta', False):
            # If a user newly opted into beta, we want to subscribe them
            # to the beta subreddit.
            try:
                sr = Subreddit._by_name(g.beta_sr)
                if not sr.is_subscriber(user):
                    sr.add_subscriber(user)
            except NotFound:
                g.log.warning("Could not find beta subreddit '%s'. It may "
                              "need to be created." % g.beta_sr)

        # CUSTOM: refuse empty IRC nick
        elif k == 'pref_chat_user' and v is None:
            continue
        # CUSTOM: Nick change: force generate new chat client credentials, avoids user having to change their
        # nick in the chat client. Forces new chat client session and account.
        elif k == 'pref_chat_user' and v != user.pref_chat_user:
            setattr(user, 'pref_chat_client_user', None)
            setattr(user, 'pref_chat_client_password', None)

            # CUSTOM: "update caches" (from account.py, for delete user case). Clears comment cache (sidebar block is not cached/always updates)
            # TODO - Post cache does not clear, chat posts are wonky on IRC nick change. only known way is reddit-flush. asking for too much liveness?
            blah = Account._by_name(user.name,
                                    allow_deleted=True,
                                    _update=True)
        elif k == 'pref_chat_client_user' and v is None:
            continue
        elif k == 'pref_chat_client_password' and v is None:
            continue

        # CUSTOM: mass unsubscribe
        # TODO: create Subreddit.unsubscribe_multiple(cls, user, sr_ids)
        elif k == 'pref_subscriptions_unsubscribe' and v == 'subs_reset_subscriptions':
            subscriber_srs = Subreddit.user_subreddits(user,
                                                       ids=False,
                                                       limit=None)
            for sub in subscriber_srs:
                sub.remove_subscriber(user)
            continue

        setattr(user, k, v)
コード例 #42
0
def submit_link(user, subreddit, title, url, thumb_url):
    account = Account._by_name(user)
    subreddit = Subreddit._by_name(subreddit)
    ip = '127.0.0.1'

    # submit the link
    link = Link._submit(title, url, account, subreddit, ip, spam=False)

    # force the thumbnail before scraper_q gets in the mix
    image_data = urllib.urlopen(thumb_url).read()
    force_thumbnail(link, image_data)

    # various backend processing things
    queries.queue_vote(account, link, UPVOTE, ip)
    queries.new_link(link)
    link.update_search_index()

    # wait for the amqp worker to finish up
    worker.join()

    print link.make_permalink_slow()
コード例 #43
0
ファイル: submit_link.py プロジェクト: MelissaCole/postcards
def submit_link(user, subreddit, title, url, thumb_url):
    account = Account._by_name(user)
    subreddit = Subreddit._by_name(subreddit)
    ip = '127.0.0.1'

    # submit the link
    link = Link._submit(title, url, account, subreddit, ip, spam=False)

    # force the thumbnail before scraper_q gets in the mix
    image_data = urllib.urlopen(thumb_url).read()
    force_thumbnail(link, image_data)

    # various backend processing things
    queries.queue_vote(account, link, UPVOTE, ip)
    queries.new_link(link)
    link.update_search_index()

    # wait for the amqp worker to finish up
    worker.join()

    print link.make_permalink_slow()
コード例 #44
0
ファイル: ipn.py プロジェクト: AD42/reddit
def reverse_gold_purchase(transaction_id):
    transaction = retrieve_gold_transaction(transaction_id)

    if not transaction:
        raise GoldException('gold_table %s not found' % transaction_id)

    buyer = Account._byID(int(transaction.account_id), data=True)
    recipient = None
    days = transaction.days
    months = days / 31

    secret = transaction.secret
    if '{' in secret:
        secret.strip('{}') # I goofed
        pieces = secret.split(',')
    else:
        pieces = secret.split('-')
    goldtype = pieces[0]
    if goldtype == 'gift':
        recipient_name, secret = pieces[1:]
        recipient = Account._by_name(recipient_name)

    gold_recipient = recipient or buyer
    with gold_lock(gold_recipient):
        gold_recipient._sync_latest()

        if goldtype in ('onetime', 'autorenew'):
            subtract_gold_days(buyer, days)

        elif goldtype == 'creddits':
            subtract_gold_creddits(buyer, months)

        elif goldtype == 'gift':
            subtract_gold_days(recipient, days)
            subject = 'your gifted gold has been reversed'
            message = 'sorry, but the payment was reversed'
            send_system_message(recipient, subject, message)
    update_gold_transaction(transaction_id, 'reversed')
コード例 #45
0
ファイル: ipn.py プロジェクト: siadat/reddit
def reverse_gold_purchase(transaction_id):
    transaction = retrieve_gold_transaction(transaction_id)

    if not transaction:
        raise GoldException('gold_table %s not found' % transaction_id)

    buyer = Account._byID(int(transaction.account_id), data=True)
    recipient = None
    days = transaction.days
    months = days / 31

    secret = transaction.secret
    if '{' in secret:
        secret.strip('{}') # I goofed
        pieces = secret.split(',')
    else:
        pieces = secret.split('-')
    goldtype = pieces[0]
    if goldtype == 'gift':
        recipient_name, secret = pieces[1:]
        recipient = Account._by_name(recipient_name)

    gold_recipient = recipient or buyer
    with gold_lock(gold_recipient):
        gold_recipient._sync_latest()

        if goldtype in ('onetime', 'autorenew'):
            subtract_gold_days(buyer, days)

        elif goldtype == 'creddits':
            subtract_gold_creddits(buyer, months)

        elif goldtype == 'gift':
            subtract_gold_days(recipient, days)
            subject = 'your gifted gold has been reversed'
            message = 'sorry, but the payment was reversed'
            send_system_message(recipient, subject, message)
    update_gold_transaction(transaction_id, 'reversed')
コード例 #46
0
def http_basic():
    """Authenticate the user based on their HTTP "Authorization" header."""
    import crypt

    try:
        authorization = request.environ.get("HTTP_AUTHORIZATION")
        username, password = parse_http_basic(authorization)
    except RequirementException:
        return None

    try:
        account = Account._by_name(username)
    except NotFound:
        return None

    # not all systems support bcrypt in the standard crypt
    if account.password.startswith("$2a$"):
        expected_hash = bcrypt.hashpw(password, account.password)
    else:
        expected_hash = crypt.crypt(password, account.password)

    if not constant_time_compare(expected_hash, account.password):
        return None
    return account
コード例 #47
0
    def POST_edit_promo(self, form, jquery, username, l, title, url, selftext,
                        kind, disable_comments, sendreplies, media_url,
                        media_autoplay, media_override, gifts_embed_url,
                        media_url_type, domain_override, is_managed):

        should_ratelimit = False
        if not c.user_is_sponsor:
            should_ratelimit = True

        if not should_ratelimit:
            c.errors.remove((errors.RATELIMIT, 'ratelimit'))

        # check for user override
        if not l and c.user_is_sponsor and username:
            try:
                user = Account._by_name(username)
            except NotFound:
                c.errors.add(errors.USER_DOESNT_EXIST, field="username")
                form.set_error(errors.USER_DOESNT_EXIST, "username")
                return

            if not user.email:
                c.errors.add(errors.NO_EMAIL_FOR_USER, field="username")
                form.set_error(errors.NO_EMAIL_FOR_USER, "username")
                return

            if not user.email_verified:
                c.errors.add(errors.NO_VERIFIED_EMAIL, field="username")
                form.set_error(errors.NO_VERIFIED_EMAIL, "username")
                return
        else:
            user = c.user

        # check for shame banned domains
        if form.has_errors("url", errors.DOMAIN_BANNED):
            g.stats.simple_event('spam.shame.link')
            return

        # demangle URL in canonical way
        if url:
            if isinstance(url, (unicode, str)):
                form.set_inputs(url=url)
            elif isinstance(url, tuple) or isinstance(url[0], Link):
                # there's already one or more links with this URL, but
                # we're allowing mutliple submissions, so we really just
                # want the URL
                url = url[0].url

        if kind == 'link':
            if form.has_errors('url', errors.NO_URL, errors.BAD_URL):
                return

        # users can change the disable_comments on promoted links
        if ((not l or not promote.is_promoted(l))
                and (form.has_errors('title', errors.NO_TEXT, errors.TOO_LONG)
                     or jquery.has_errors('ratelimit', errors.RATELIMIT))):
            return

        if kind == 'self' and form.has_errors('text', errors.TOO_LONG):
            return

        if not l:
            # creating a new promoted link
            l = promote.new_promotion(title, url if kind == 'link' else 'self',
                                      selftext if kind == 'self' else '', user,
                                      request.ip)
            l.domain_override = domain_override or None
            if c.user_is_sponsor:
                l.managed_promo = is_managed
            l._commit()
            form.redirect(promote.promo_edit_url(l))

        elif not promote.is_promo(l):
            return

        # changing link type is not allowed
        if ((l.is_self and kind == 'link')
                or (not l.is_self and kind == 'self')):
            c.errors.add(errors.NO_CHANGE_KIND, field="kind")
            form.set_error(errors.NO_CHANGE_KIND, "kind")
            return

        changed = False
        # live items can only be changed by a sponsor, and also
        # pay the cost of de-approving the link
        if not promote.is_promoted(l) or c.user_is_sponsor:
            if title and title != l.title:
                l.title = title
                changed = not c.user_is_sponsor

            if kind == 'link' and url and url != l.url:
                l.url = url
                changed = not c.user_is_sponsor

        # only trips if the title and url are changed by a non-sponsor
        if changed:
            promote.unapprove_promotion(l)

        # selftext can be changed at any time
        if kind == 'self':
            l.selftext = selftext

        # comment disabling and sendreplies is free to be changed any time.
        l.disable_comments = disable_comments
        l.sendreplies = sendreplies

        if c.user_is_sponsor:
            if (form.has_errors("media_url", errors.BAD_URL)
                    or form.has_errors("gifts_embed_url", errors.BAD_URL)):
                return

        scraper_embed = media_url_type == "scrape"
        media_url = media_url or None
        gifts_embed_url = gifts_embed_url or None

        if c.user_is_sponsor and scraper_embed and media_url != l.media_url:
            if media_url:
                media = _scrape_media(media_url,
                                      autoplay=media_autoplay,
                                      save_thumbnail=False,
                                      use_cache=True)

                if media:
                    l.set_media_object(media.media_object)
                    l.set_secure_media_object(media.secure_media_object)
                    l.media_url = media_url
                    l.gifts_embed_url = None
                    l.media_autoplay = media_autoplay
                else:
                    c.errors.add(errors.SCRAPER_ERROR, field="media_url")
                    form.set_error(errors.SCRAPER_ERROR, "media_url")
                    return
            else:
                l.set_media_object(None)
                l.set_secure_media_object(None)
                l.media_url = None
                l.gifts_embed_url = None
                l.media_autoplay = False

        if (c.user_is_sponsor and not scraper_embed
                and gifts_embed_url != l.gifts_embed_url):
            if gifts_embed_url:
                parsed = UrlParser(gifts_embed_url)
                if not is_subdomain(parsed.hostname, "redditgifts.com"):
                    c.errors.add(errors.BAD_URL, field="gifts_embed_url")
                    form.set_error(errors.BAD_URL, "gifts_embed_url")
                    return

                iframe = """
                    <iframe class="redditgifts-embed"
                            src="%(embed_url)s"
                            width="710" height="500" scrolling="no"
                            frameborder="0" allowfullscreen>
                    </iframe>
                """ % {
                    'embed_url': websafe(gifts_embed_url)
                }
                media_object = {
                    'oembed': {
                        'description': 'redditgifts embed',
                        'height': 500,
                        'html': iframe,
                        'provider_name': 'redditgifts',
                        'provider_url': 'http://www.redditgifts.com/',
                        'title': 'redditgifts secret santa 2014',
                        'type': 'rich',
                        'width': 710
                    },
                    'type': 'redditgifts'
                }
                l.set_media_object(media_object)
                l.set_secure_media_object(media_object)
                l.media_url = None
                l.gifts_embed_url = gifts_embed_url
                l.media_autoplay = False
            else:
                l.set_media_object(None)
                l.set_secure_media_object(None)
                l.media_url = None
                l.gifts_embed_url = None
                l.media_autoplay = False

        if c.user_is_sponsor:
            l.media_override = media_override
            l.domain_override = domain_override or None
            l.managed_promo = is_managed

        l._commit()
        form.redirect(promote.promo_edit_url(l))
コード例 #48
0
def create_about_post():
    user = Account._by_name('Eliezer_Yudkowsky')
    sr = Subreddit._by_name('admin')
    link = Link._submit('About LessWrong', 'TBC', user, sr, '::1', [])
コード例 #49
0
ファイル: mailgun.py プロジェクト: zeantsoi/reddit
    def POST_zendeskreply(self):
        request_body = request.POST
        recipient = request_body["recipient"]
        sender_email = request_body["sender"]
        from_ = request_body["from"]
        subject = request_body["subject"]
        body_plain = request_body["body-plain"]
        stripped_text = request_body["stripped-text"]
        stripped_signature = request_body["stripped-signature"]
        timestamp = request_body["timestamp"]
        token = request_body["token"]
        signature = request_body["signature"]
        email_id = request_body["Message-Id"]

        if not validate_mailgun_webhook(timestamp, token, signature):
            # per Mailgun docs send a 406 so the message won't be retried
            abort(406, "invalid signature")

        message_id36 = parse_and_validate_reply_to_address(recipient)

        if not message_id36:
            # per Mailgun docs send a 406 so the message won't be retried
            abort(406, "invalid message")

        parent = Message._byID36(message_id36, data=True)
        to = Account._byID(parent.author_id, data=True)
        sr = Subreddit._byID(parent.sr_id, data=True)
        body = self.get_snipped_body(stripped_text, stripped_signature)

        try:
            markdown_souptest(body)
        except SoupError:
            g.log.warning("bad markdown in modmail email: %s", body)
            abort(406, "invalid body")

        if parent.get_muted_user_in_conversation():
            queue_blocked_muted_email(sr, parent, sender_email, email_id)
            return

        # keep the subject consistent
        message_subject = parent.subject
        if not message_subject.startswith("re: "):
            message_subject = "re: " + message_subject

        # from_ is like '"NAME (GROUP)" <*****@*****.**>'
        match = re.search("\"(?P<name>\w+) [\w ()]*\"", from_)
        from_sr = True
        author = Account.system_user()

        if match and match.group(
                "name") in g.live_config['modmail_account_map']:
            zendesk_name = match.group("name")
            moderator_name = g.live_config['modmail_account_map'][zendesk_name]
            moderator = Account._by_name(moderator_name)
            if sr.is_moderator_with_perms(moderator, "mail"):
                author = moderator
                from_sr = False

        message, inbox_rel = Message._new(
            author=author,
            to=to,
            subject=message_subject,
            body=body,
            ip='0.0.0.0',
            parent=parent,
            sr=sr,
            from_sr=from_sr,
            can_send_email=False,
            sent_via_email=True,
            email_id=email_id,
        )
        message._commit()
        queries.new_message(message, inbox_rel)
        g.stats.simple_event("mailgun.incoming.success")
        g.stats.simple_event("modmail_email.incoming_email")
コード例 #50
0
from r2.models.admintools import send_system_message
from r2.models.gold import (
    gold_goal_on,
    gold_revenue_multi,
    GoldRevenueGoalByDate,
    TIMEZONE,
)
from r2.models.wiki import WikiPage
from r2.lib.comment_tree import get_comment_tree
from r2.lib.db import tdb_cassandra

from reddit_gold.server_naming import gold_buyers_on


SERVERNAME_SR = Subreddit._by_name(g.gold_servername_sr)
SYSTEM_ACCOUNT = Account._by_name(g.system_user)


def get_recent_name_submissions():
    link_fullnames = list(queries.get_links(SERVERNAME_SR, "new", "all"))
    links = chain.from_iterable(Thing._by_fullname(chunk, return_dict=False)
                                for chunk in in_chunks(link_fullnames))

    for link in links:
        if link._deleted or link._spam:
            continue

        # OH GOD WHAT HAVE YOU POSTED IN MY LOVELY AUTOMATED SUBREDDIT!?
        if (not hasattr(link, "revenue_date") or
            not hasattr(link, "revenue_bucket") or
            not hasattr(link, "server_names")):
コード例 #51
0
def complimentary(username, value=True):
    a = Account._by_name(username, True)
    a.complimentary_promos = value
    a._commit()
コード例 #52
0
ファイル: ipn.py プロジェクト: siadat/reddit
    def finish(self, parameters, txn_id,
               payer_email, paying_id, subscr_id,
               custom, pennies, months, days):

        blob_key, payment_blob = get_blob(custom)

        buyer_id = payment_blob.get('account_id', None)
        if not buyer_id:
            dump_parameters(parameters)
            raise ValueError("No buyer_id in IPN/GC with custom='%s'" % custom)
        try:
            buyer = Account._byID(buyer_id)
        except NotFound:
            dump_parameters(parameters)
            raise ValueError("Invalid buyer_id %d in IPN/GC with custom='%s'"
                             % (buyer_id, custom))

        if subscr_id:
            buyer.gold_subscr_id = subscr_id

        instagift = False
        if payment_blob['goldtype'] in ('autorenew', 'onetime'):
            admintools.engolden(buyer, days)

            subject = _("thanks for buying reddit gold!")

            if g.lounge_reddit:
                lounge_url = "/r/" + g.lounge_reddit
                message = strings.lounge_msg % dict(link=lounge_url)
            else:
                message = ":)"
        elif payment_blob['goldtype'] == 'creddits':
            buyer._incr("gold_creddits", months)
            buyer._commit()
            subject = _("thanks for buying creddits!")
            message = _("To spend them, visit [/gold](/gold) or your favorite person's userpage.")
        elif payment_blob['goldtype'] == 'gift':
            recipient_name = payment_blob.get('recipient', None)
            try:
                recipient = Account._by_name(recipient_name)
            except NotFound:
                dump_parameters(parameters)
                raise ValueError("Invalid recipient_name %s in IPN/GC with custom='%s'"
                                 % (recipient_name, custom))
            signed = payment_blob.get("signed", False)
            giftmessage = _force_unicode(payment_blob.get("giftmessage", ""))
            comment_id = payment_blob.get("comment")
            send_gift(buyer, recipient, months, days, signed, giftmessage, comment_id)
            instagift = True
            subject = _("thanks for giving reddit gold!")
            message = _("Your gift to %s has been delivered." % recipient.name)
        else:
            dump_parameters(parameters)
            raise ValueError("Got status '%s' in IPN/GC" % payment_blob['status'])

        # Reuse the old "secret" column as a place to record the goldtype
        # and "custom", just in case we need to debug it later or something
        secret = payment_blob['goldtype'] + "-" + custom

        if instagift:
            status="instagift"
        else:
            status="processed"

        create_claimed_gold(txn_id, payer_email, paying_id, pennies, days,
                            secret, buyer_id, c.start_time,
                            subscr_id, status=status)

        send_system_message(buyer, subject, message)

        payment_blob["status"] = "processed"
        g.hardcache.set(blob_key, payment_blob, 86400 * 30)