Exemple #1
0
    def transform(match):
        groups = match.groupdict()
        if 'iso' in groups:
            iso = groups['iso']
        elif 'sym' in groups:
            iso = money.CURRENCY_SYMBOLS[groups['sym']]
        else:
            iso = 'USD'

        exp = money.ISO_CODES_TO_EXP[iso]
        new_amount_regex = (r'\A[0-9,]+\Z' if exp == 0 else
                            r'\A[0-9,]+(?:\.[0-9]{' + str(exp) + r'})?\Z')
        if not re.match(new_amount_regex, groups['amt']):
            return None

        # We manipulate the number as a string as it avoids floating point
        # rounding issues
        groups['amt'] = groups['amt'].replace(',', '')
        if '.' in groups['amt']:
            return money.Money(int(groups['amt'].replace('.', '')), iso)
        return money.Money(int(groups['amt'] + ''.join(['0'] * exp)), iso)
Exemple #2
0
 def test_iso(self):
     self.assertEqual(PARSER.parse('$loan EUR 15'),
                      [money.Money(1500, 'EUR'), None])
Exemple #3
0
 def test_symbol(self):
     self.assertEqual(PARSER.parse('$loan 15$'),
                      [money.Money(1500, 'USD'), None])
Exemple #4
0
    def handle_comment(self, itgs, comment, rpiden, rpversion):
        start_at = time.time()
        token_vals = PARSER.parse(comment['body'])
        borrower_username = comment['link_author']
        lender_username = comment['author']
        amount = token_vals[0]
        store_currency = token_vals[1] or amount.currency

        if amount.currency == store_currency:
            store_amount = amount
            rate = 1
        else:
            rate = convert.convert(itgs, amount.currency, store_currency)
            store_amount = money.Money(int(amount.minor * rate),
                                       store_currency)

        if store_currency == 'USD':
            usd_amount = store_amount
            usd_rate = 1
        else:
            # Where possible we want the source to be consistent rather than
            # the target as it allows us to reuse requests
            usd_rate = 1 / convert.convert(itgs, 'USD', store_currency)
            usd_amount = money.Money(int(store_amount.minor * usd_rate),
                                     'USD',
                                     exp=2,
                                     symbol='$',
                                     symbol_on_left=True)

        users = Table('users')
        currencies = Table('currencies')
        moneys = Table('moneys')
        loans = Table('loans')
        loan_creation_infos = Table('loan_creation_infos')
        (lender_user_id, ) = query_helper.find_or_create_or_find(
            itgs, (Query.from_(users).select(
                users.id).where(users.username == Parameter('%s')).get_sql(),
                   (lender_username.lower(), )),
            (Query.into(users).columns(users.username).insert(
                Parameter('%s')).returning(users.id).get_sql(),
             (lender_username.lower(), )))
        (borrower_user_id, ) = query_helper.find_or_create_or_find(
            itgs, (Query.from_(users).select(
                users.id).where(users.username == Parameter('%s')).get_sql(),
                   (borrower_username.lower(), )),
            (Query.into(users).columns(users.username).insert(
                Parameter('%s')).returning(users.id).get_sql(),
             (borrower_username.lower(), )))
        (db_store_currency_id, db_currency_symbol,
         db_currency_sym_on_left) = query_helper.find_or_create_or_find(
             itgs, (Query.from_(currencies).select(
                 currencies.id, currencies.symbol,
                 currencies.symbol_on_left).where(
                     currencies.code == Parameter('%s')).get_sql(),
                    (store_currency, )),
             (Query.into(currencies).columns(
                 currencies.code, currencies.symbol, currencies.symbol_on_left,
                 currencies.exponent).insert(
                     *[Parameter('%s') for _ in range(4)]).returning(
                         currencies.id, currencies.symbol,
                         currencies.symbol_on_left).get_sql(),
              (store_currency, ' ' + store_currency, False,
               money.ISO_CODES_TO_EXP[store_currency])))
        itgs.write_cursor.execute(
            Query.into(moneys).columns(
                moneys.currency_id, moneys.amount,
                moneys.amount_usd_cents).insert(
                    *[Parameter('%s')
                      for _ in range(3)]).returning(moneys.id).get_sql(),
            (db_store_currency_id, store_amount.minor, usd_amount.minor))
        (principal_id, ) = itgs.write_cursor.fetchone()
        itgs.write_cursor.execute(
            Query.into(moneys).columns(
                moneys.currency_id, moneys.amount,
                moneys.amount_usd_cents).insert(
                    *[Parameter('%s')
                      for _ in range(3)]).returning(moneys.id).get_sql(),
            (db_store_currency_id, 0, 0))
        (principal_repayment_id, ) = itgs.write_cursor.fetchone()
        itgs.write_cursor.execute(
            Query.into(loans).columns(
                loans.lender_id, loans.borrower_id, loans.principal_id,
                loans.principal_repayment_id, loans.created_at,
                loans.repaid_at, loans.unpaid_at,
                loans.deleted_at).insert(*[Parameter('%s')
                                           for _ in range(8)]).returning(
                                               loans.id).get_sql(),
            (lender_user_id, borrower_user_id, principal_id,
             principal_repayment_id,
             datetime.fromtimestamp(comment['created_utc']), None, None, None))
        (loan_id, ) = itgs.write_cursor.fetchone()

        itgs.write_cursor.execute(
            Query.into(loan_creation_infos).columns(
                loan_creation_infos.loan_id, loan_creation_infos.type,
                loan_creation_infos.parent_fullname,
                loan_creation_infos.comment_fullname,
                loan_creation_infos.mod_user_id).insert(
                    *[Parameter('%s') for _ in range(5)]).get_sql(),
            (loan_id, 0, comment['link_fullname'], comment['fullname'], None))
        itgs.write_conn.commit()

        store_amount.symbol = db_currency_symbol
        store_amount.symbol_on_left = db_currency_sym_on_left

        permalink = (
            'https://www.reddit.com/comments/{}/redditloans/{}'.format(
                comment['link_fullname'][3:], comment['fullname'][3:]))

        itgs.logger.print(Level.INFO,
                          '/u/{} just lent /u/{} {} - permalink: {}',
                          lender_username, borrower_username, store_amount,
                          permalink)

        itgs.channel.exchange_declare('events', 'topic')
        itgs.channel.basic_publish(
            'events', 'loans.create',
            json.dumps({
                'loan_id': loan_id,
                'comment': {
                    'link_fullname': comment['link_fullname'],
                    'fullname': comment['fullname'],
                    'subreddit': comment['subreddit']
                },
                'lender': {
                    'id': lender_user_id,
                    'username': lender_username
                },
                'borrower': {
                    'id': borrower_user_id,
                    'username': borrower_username
                },
                'amount': {
                    'minor': store_amount.minor,
                    'currency': store_amount.currency,
                    'exp': store_amount.exp,
                    'symbol': store_amount.symbol,
                    'symbol_on_left': store_amount.symbol_on_left
                },
                'permalink': permalink
            }))

        processing_time = time.time() - start_at
        formatted_response = get_response(
            itgs,
            'successful_loan',
            lender_username=lender_username,
            borrower_username=borrower_username,
            principal=str(store_amount),
            principal_explicit=repr(store_amount),
            loan_id=loan_id,
            processing_time=processing_time)

        utils.reddit_proxy.send_request(itgs, rpiden, rpversion,
                                        'post_comment', {
                                            'parent': comment['fullname'],
                                            'text': formatted_response
                                        })
Exemple #5
0
 def test_user_link_noncanonical_expanded(self):
     self.assertEqual(
         PARSER.parse('$paid [/u/johndoe](https://reddit.com/user/johndoe) 1'),
         ['johndoe', money.Money(100, 'USD')]
     )
Exemple #6
0
 def test_user_link_http(self):
     self.assertEqual(
         PARSER.parse('$paid [u/johndoe](http://www.reddit.com/u/johndoe) 1'),
         ['johndoe', money.Money(100, 'USD')]
     )
Exemple #7
0
 def test_escaped(self):
     self.assertEqual(
         PARSER.parse('$paid\\_with\\_id 1 2'),
         [1, money.Money(200, 'USD')]
     )
Exemple #8
0
 def test_comma_and_period(self):
     self.assertEqual(PARSER.parse('$loan $1,000.00'),
                      [money.Money(100000, 'USD'), None])
Exemple #9
0
 def test_user_missing_leading_slash(self):
     self.assertEqual(
         PARSER.parse('$paid u/johndoe 1'),
         ['johndoe', money.Money(100, 'USD')]
     )
Exemple #10
0
 def test_underscores_and_hyphens_allowed_username(self):
     self.assertEqual(
         PARSER.parse('$paid u/Foo_The-Bar $37'),
         ['Foo_The-Bar', money.Money(3700, 'USD')]
     )
Exemple #11
0
 def test_hyphenated_username(self):
     self.assertEqual(
         PARSER.parse('$paid u/Do-Re-Me $250'),
         ['Do-Re-Me', money.Money(25000, 'USD')]
     )
Exemple #12
0
 def test_simple(self):
     self.assertEqual(
         PARSER.parse('$paid /u/johndoe 15'),
         ['johndoe', money.Money(1500, 'USD')]
     )
Exemple #13
0
 def test_user_link_noncanonical_no_leading_slash(self):
     self.assertEqual(
         PARSER.parse('$paid [u/johndoe](https://reddit.com/u/johndoe) 1'),
         ['johndoe', money.Money(100, 'USD')]
     )
Exemple #14
0
 def test_cents(self):
     self.assertEqual(PARSER.parse('$loan 1.23'),
                      [money.Money(123, 'USD'), None])
Exemple #15
0
 def test_user_hyphen_link_expanded(self):
     self.assertEqual(
         PARSER.parse('$paid [/u/john-doe](https://www.reddit.com/user/john-doe) 1'),
         ['john-doe', money.Money(100, 'USD')]
     )
Exemple #16
0
 def test_cents_iso(self):
     self.assertEqual(PARSER.parse('$loan 1.23 CAD'),
                      [money.Money(123, 'CAD'), None])
Exemple #17
0
 def test_user_link_expanded_trailing_slash(self):
     self.assertEqual(
         PARSER.parse('$paid [/u/johndoe](https://www.reddit.com/user/johndoe/) 1'),
         ['johndoe', money.Money(100, 'USD')]
     )
Exemple #18
0
 def test_convert(self):
     self.assertEqual(PARSER.parse('$loan 1.23 CAD AS JPY'),
                      [money.Money(123, 'CAD'), 'JPY'])
Exemple #19
0
 def test_simple(self):
     self.assertEqual(
         PARSER.parse('$paid_with_id 1 2'),
         [1, money.Money(200, 'USD')]
     )