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)
def test_iso(self): self.assertEqual(PARSER.parse('$loan EUR 15'), [money.Money(1500, 'EUR'), None])
def test_symbol(self): self.assertEqual(PARSER.parse('$loan 15$'), [money.Money(1500, 'USD'), None])
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 })
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')] )
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')] )
def test_escaped(self): self.assertEqual( PARSER.parse('$paid\\_with\\_id 1 2'), [1, money.Money(200, 'USD')] )
def test_comma_and_period(self): self.assertEqual(PARSER.parse('$loan $1,000.00'), [money.Money(100000, 'USD'), None])
def test_user_missing_leading_slash(self): self.assertEqual( PARSER.parse('$paid u/johndoe 1'), ['johndoe', money.Money(100, 'USD')] )
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')] )
def test_hyphenated_username(self): self.assertEqual( PARSER.parse('$paid u/Do-Re-Me $250'), ['Do-Re-Me', money.Money(25000, 'USD')] )
def test_simple(self): self.assertEqual( PARSER.parse('$paid /u/johndoe 15'), ['johndoe', money.Money(1500, 'USD')] )
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')] )
def test_cents(self): self.assertEqual(PARSER.parse('$loan 1.23'), [money.Money(123, 'USD'), None])
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')] )
def test_cents_iso(self): self.assertEqual(PARSER.parse('$loan 1.23 CAD'), [money.Money(123, 'CAD'), None])
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')] )
def test_convert(self): self.assertEqual(PARSER.parse('$loan 1.23 CAD AS JPY'), [money.Money(123, 'CAD'), 'JPY'])
def test_simple(self): self.assertEqual( PARSER.parse('$paid_with_id 1 2'), [1, money.Money(200, 'USD')] )