Ejemplo n.º 1
0
def validate_sender(message):
    """
    Validate that the sender has an account with the tip bot, and has enough Coin to cover the tip.
    """
    logger.info("{}: validating sender".format(datetime.now()))
    logger.info("sender id: {}".format(message['sender_id']))
    logger.info("from_app: {}".format(message['from_app']))
    db_call = "SELECT account, register FROM users where user_id = {} AND users.from_app = '{}'".format(
        message['sender_id'], message['from_app'])
    sender_account_info = modules.db.get_db_data(db_call)

    if not sender_account_info:
        send_reply(message, translations.no_account_text[message['language']])

        logger.info("{}: User tried to send a tip without an account.".format(
            datetime.now()))
        message['sender_account'] = None
        return message

    message['sender_account'] = sender_account_info[0][0]
    message['sender_register'] = sender_account_info[0][1]

    if message['sender_register'] != 1:
        db_call = "UPDATE users SET register = 1 WHERE user_id = %s AND users.from_app = %s"
        db_values = [message['sender_id'], message['from_app']]
        modules.db.set_db_data(db_call, db_values)

    message['sender_balance_raw'] = rpc.get_account_balance(
        message['sender_account'])
    message['sender_balance'] = message['sender_balance_raw']['balance']

    return message
Ejemplo n.º 2
0
def get_twitter_account(screen_name):
    try:
        user = api.get_user(screen_name)

        if user is not None:
            account_call = (
                "SELECT account, address FROM users "
                "WHERE user_id = '{}' AND users.from_app = 'twitter';".format(
                    user.id_str))
            account_return = modules.db.get_db_data(account_call)
            balance_return = rpc.get_account_balance(account_return[0][0])
            account_dict = {
                'user_id': user.id_str,
                'address': account_return[0][1],
                'balance': str(balance_return['balance']),
                'pending': str(balance_return['pending'])
            }
            response = Response(json.dumps(account_dict))
            response.headers['Access-Control-Allow-Credentials'] = True
            response.headers['Access-Control-Allow-Origin'] = '*'
            response.headers['Content-Type'] = 'application/json'
            return response, HTTPStatus.OK
        else:
            logger.info('{}: No user found.'.format(datetime.now()))
            account_dict = {
                'user_id': None,
                'address': None,
                'balance': None,
                'pending': None
            }
            response = Response(json.dumps(account_dict))
            response.headers['Access-Control-Allow-Credentials'] = True
            response.headers['Access-Control-Allow-Origin'] = '*'
            response.headers['Content-Type'] = 'application/json'
            return response, HTTPStatus.OK
    except Exception as e:
        logger.info('{}: ERROR in get_twitter_account(webhooks.py): {}'.format(
            datetime.now(), e))
        account_dict = {
            'user_id': None,
            'address': None,
            'balance': None,
            'pending': None
        }
        response = Response(json.dumps(account_dict))
        response.headers['Access-Control-Allow-Credentials'] = True
        response.headers['Access-Control-Allow-Origin'] = '*'
        response.headers['Content-Type'] = 'application/json'
        return response, HTTPStatus.OK
def balance_process(message):
    """
    When the user sends a DM containing !balance, reply with the balance of the account linked with their Twitter ID
    """
    logger.info("{}: In balance process".format(datetime.now()))
    balance_call = ("SELECT account, register FROM users WHERE user_id = {} "
                    "AND users.from_app = '{}'".format(message['sender_id'],
                                                       message['from_app']))
    data = modules.db.get_db_data(balance_call)
    if not data:
        logger.info(
            "{}: User tried to check balance without an account".format(
                datetime.now()))
        modules.social.send_dm(message['sender_id'],
                               translations.no_account_text['language'],
                               message['from_app'])
    else:
        message['sender_account'] = data[0][0]
        sender_register = data[0][1]

        if sender_register == 0:
            set_register_call = "UPDATE users SET register = 1 WHERE user_id = %s AND users.from_app = %s AND register = 0"
            set_register_values = [message['sender_id'], message['from_app']]
            modules.db.set_db_data(set_register_call, set_register_values)
        new_pid = os.fork()
        if new_pid == 0:
            os._exit(0)
        else:
            balance_return = rpc.get_account_balance(message['sender_account'])
            message['sender_balance'] = balance_return['balance']
            message['sender_pending'] = balance_return['pending']

            modules.social.send_dm(
                message['sender_id'],
                translations.balance_text[message['language']].format(
                    message['sender_balance'], CURRENCY_SYMBOL,
                    message['sender_pending'], CURRENCY_SYMBOL),
                message['from_app'])
            logger.info("{}: Balance Message Sent!".format(datetime.now()))
            return ''
Ejemplo n.º 4
0
def refresh_balance(account):
    try:
        account_call = ("SELECT account FROM users "
                        "WHERE address = '{}' AND users.from_app = 'twitter';".
                        format(account))
        account_return = modules.db.get_db_data(account_call)
        balance_return = rpc.get_account_balance(account_return[0][0])

        balance_dict = {
            'balance': balance_return[0],
            'pending': balance_return[1]
        }
        response = Response(json.dumps(balance_dict))
        response.headers['Access-Control-Allow-Credentials'] = True
        response.headers['Access-Control-Allow-Origin'] = '*'
        response.headers['Content-Type'] = 'application/json'

        return response, HTTPStatus.OK
    except Exception as e:
        logger.info("{}: ERROR in refresh_balance (webhooks.py): {}".format(
            datetime.now, e))
        return e, HTTPStatus.BAD_REQUEST
def donate_process(message):
    """
    When the user sends !donate, send the provided amount from the user's account to the tip bot's donation wallet.
    If the user has no balance or account, reply with an error.
    """
    logger.info("{}: in donate_process.".format(datetime.now()))

    if len(message['dm_array']) >= 2:
        sender_account_call = (
            "SELECT account FROM users where user_id = {} and users.from_app = '{}'"
            .format(message['sender_id'], message['from_app']))
        donate_data = modules.db.get_db_data(sender_account_call)
        sender_account = donate_data[0][0]
        send_amount = message['dm_array'][1]

        balance_return = rpc.get_account_balance(sender_account)
        balance = balance_return['balance']
        receiver_account = BOT_ACCOUNT

        try:
            logger.info("{}: The user is donating {} Coin".format(
                datetime.now(), Decimal(send_amount)))
        except Exception as e:
            logger.info("{}: ERROR IN CONVERTING DONATION AMOUNT: {}".format(
                datetime.now(), e))
            modules.social.send_dm(
                message['sender_id'],
                translations.wrong_donate_text[message['language']],
                message['from_app'])
            return ''
        logger.info("balance: {} - send_amount: {}".format(
            Decimal(balance), Decimal(send_amount)))
        # We need to reduce the send_amount for a proper comparison - Decimal will not store exact amounts
        # (e.g. 0.0003 = 0.00029999999999452123)
        if Decimal(balance) < (Decimal(send_amount) - Decimal(0.00001)):
            modules.social.send_dm(
                message['sender_id'],
                translations.large_donate_text[message['language']].format(
                    balance, CURRENCY_NAME,
                    Decimal(send_amount)), message['from_app'])
            logger.info(
                "{}: User tried to donate more than their balance.".format(
                    datetime.now()))

        elif Decimal(send_amount) < Decimal(MIN_TIP):
            modules.social.send_dm(
                message['sender_id'], translations.small_donate_text[
                    message['language']].format(MIN_TIP), message['from_app'])
            logger.info(
                "{}: User tried to donate less than the min tip".format(
                    datetime.now()))
            return ''
        else:
            # If the send amount > balance, send the whole balance.  If not, send the send amount.
            # This is to take into account for Decimal value conversions.
            if Decimal(send_amount) > Decimal(balance):
                send_amount_raw = Decimal(balance)
            else:
                send_amount_raw = Decimal(send_amount)
            logger.info(
                ('{}; send_amount_raw: {}'.format(datetime.now(),
                                                  int(send_amount_raw))))

            rpc.move(sender_account, receiver_account, send_amount_raw)
            modules.social.send_dm(
                message['sender_id'],
                translations.donate_text[message['language']].format(
                    send_amount, CURRENCY_SYMBOL), message['from_app'])
            logger.info("{}: {} coin donation processed.  ".format(
                datetime.now(), Decimal(send_amount)))

    else:
        modules.social.send_dm(
            message['sender_id'],
            translations.incorrect_donate_text[message['language']],
            message['from_app'])
        logger.info("{}: User sent a donation with invalid syntax".format(
            datetime.now()))
def withdraw_process(message):
    """
    When the user sends !withdraw, send their entire balance to the provided account.  If there is no provided account
    reply with an error.
    """
    logger.info('{}: in withdraw process.'.format(datetime.now()))
    # check if there is a 2nd argument
    if 3 >= len(message['dm_array']) >= 2:
        # if there is, retrieve the sender's account and wallet
        withdraw_account_call = (
            "SELECT account, address, register FROM users WHERE user_id = {} AND users.from_app = '{}'"
            .format(message['sender_id'], message['from_app']))
        withdraw_data = modules.db.get_db_data(withdraw_account_call)

        if not withdraw_data:

            modules.social.send_dm(
                message['sender_id'],
                translations.no_account_text[message['language']],
                message['from_app'])
            logger.info("{}: User tried to withdraw with no account".format(
                datetime.now()))

        else:
            sender_account = withdraw_data[0][0]
            sender_address = withdraw_data[0][1]
            sender_register = withdraw_data[0][2]

            if sender_register == 0:
                set_register_call = (
                    "UPDATE users SET register = 1 WHERE user_id = %s AND users.from_app = %s AND register = 0"
                )
                set_register_values = [
                    message['sender_id'], message['from_app']
                ]
                modules.db.set_db_data(set_register_call, set_register_values)

            balance_return = rpc.get_account_balance(sender_account)

            if len(message['dm_array']) == 2:
                receiver_address = message['dm_array'][1]
            else:
                receiver_address = message['dm_array'][2]

            if rpc.validate_address(receiver_address) is False:
                modules.social.send_dm(
                    message['sender_id'],
                    translations.invalid_account_text[message['language']],
                    message['from_app'])
                logger.info("{}: The address is invalid: {}".format(
                    datetime.now(), receiver_address))

            elif balance_return['balance'] == 0:
                modules.social.send_dm(
                    message['sender_id'], translations.no_balance_text[
                        message['language']].format(sender_address),
                    message['from_app'])
                logger.info(
                    "{}: The user tried to withdraw with 0 balance".format(
                        datetime.now()))

            else:
                if len(message['dm_array']) == 3:
                    try:
                        withdraw_amount = Decimal(message['dm_array'][1])
                    except Exception as e:
                        logger.info("{}: withdraw no number ERROR: {}".format(
                            datetime.now(), e))
                        modules.social.send_dm(
                            message['sender_id'],
                            translations.invalid_amount_text[
                                message['language']], message['from_app'])
                        return
                    withdraw_amount_raw = int(withdraw_amount)
                    if Decimal(withdraw_amount_raw) > Decimal(
                            balance_return['balance']):
                        modules.social.send_dm(
                            message['sender_id'],
                            translations.not_enough_balance_text[
                                message['language']].format(CURRENCY_SYMBOL),
                            message['from_app'])
                        return
                else:
                    withdraw_amount_raw = balance_return['balance']
                    withdraw_amount = balance_return['balance']

                # XXX - Send balance to account
                #
                send_hash = rpc.send_from(sender_account, receiver_address,
                                          withdraw_amount_raw)

                logger.info("{}: send_hash = {}".format(
                    datetime.now(), send_hash))
                # respond that the withdraw has been processed
                modules.social.send_dm(
                    message['sender_id'],
                    translations.withdraw_text[message['language']].format(
                        withdraw_amount, CURRENCY_SYMBOL, EXPLORER,
                        send_hash), message['from_app'])
                logger.info("{}: Withdraw processed.  Hash: {}".format(
                    datetime.now(), send_hash))
    else:
        modules.social.send_dm(
            message['sender_id'],
            translations.incorrect_withdraw_text[message['language']].format(
                BOT_ACCOUNT, CURRENCY), message['from_app'])
        logger.info("{}: User sent a withdraw with invalid syntax.".format(
            datetime.now()))