Esempio n. 1
0
def return_tips():
    tips_to_return_call = ("SELECT tip_bot.tip_list.dm_id, tip_bot.tip_list.sender_id, "
                           "tip_bot.users.account, tip_bot.tip_list.amount "
                           "FROM tip_bot.tip_list "
                           "INNER JOIN tip_bot.users "
                           "ON tip_bot.tip_list.receiver_id = tip_bot.users.user_id "
                           "WHERE DATE(tip_bot.tip_list.timestamp) < DATE_SUB(now(), interval 30 day) "
                           "AND tip_bot.users.register = 0 "
                           "AND tip_bot.tip_list.processed = 2;")
    tip_list = get_db_data(tips_to_return_call)

    for tip in tip_list:
        transaction_id = tip[0]
        sender_id = tip[1]
        receiver_account = tip[2]
        amount = Decimal(tip[3])

        logging.info("{}: Returning tip {}".format(datetime.now(), transaction_id))

        sender_account_call = "SELECT account FROM users WHERE user_id = {}".format(sender_id)
        sender_account_info = get_db_data(sender_account_call)
        sender_account = sender_account_info[0][0]
        send_amount = int(amount * 1000000000000000000000000000000)

        receive_pending(receiver_account)

        work = get_pow(receiver_account)
        try:
            if work == '':
                send_hash = rpc.send(wallet="{}".format(WALLET), source="{}".format(receiver_account),
                                     destination="{}".format(sender_account), amount=send_amount)
            else:
                send_hash = rpc.send(wallet="{}".format(WALLET), source="{}".format(receiver_account),
                                     destination="{}".format(sender_account), amount=send_amount, work=work)
            logging.info("{}: Tip returned under hash: {}".format(str(datetime.now()), send_hash))
        except nano.rpc.RPCException as e:
            logging.info("{}: Insufficient balance to return.  Descriptive error: {}".format(datetime.now(), e))
            insufficient_balance_call = ("UPDATE tip_bot.tip_list "
                                         "SET processed = 6 "
                                         "WHERE dm_id = %s;")
            insufficient_balance_values = [transaction_id,]
            set_db_data(insufficient_balance_call, insufficient_balance_values)
            continue
        except Exception as f:
            logging.info("{}: Unexpected error: {}".format(datetime.now(), f))
            continue

        update_tip_call = ("UPDATE tip_bot.tip_list "
                           "SET processed = 9 "
                           "WHERE dm_id = %s;")
        update_tip_values = [transaction_id,]
        try:
            set_db_data(update_tip_call, update_tip_values)
        except Exception as e:
            logging.info("{}: Error updating tip to returned: {}".format(datetime.now(), e))

    send_returned_notice_to_receivers()
    send_returned_notice_to_senders()
Esempio n. 2
0
def return_unused_balance():
    get_inactive_users = (
        "SELECT user_id, system, account "
        " FROM tip_bot.return_address "
        " WHERE last_action < DATE_SUB(now(), interval 60 day) "
        "     AND account IS NOT NULL;")
    inactive_users = get_db_data(get_inactive_users)
    logging.info("{}: Returning inactive balances for user list: {}".format(
        datetime.now(), inactive_users))

    for user in inactive_users:
        get_tip_account = ("SELECT account FROM users "
                           "WHERE user_id = {} AND system = '{}'".format(
                               user[0], user[1]))
        tip_account_data = get_db_data(get_tip_account)
        tip_account = tip_account_data[0][0]
        print("Returning unused balance for user {} system {} account {} to ")
        # check for any unreceived tips
        receive_pending(tip_account)
        # get balance of tip account
        balance_data = {'action': 'account_balance', 'account': tip_account}
        json_request = json.dumps(balance_data)
        r = requests.post('{}'.format(NODE_IP), data=json_request)
        rx = r.json()
        balance_raw = rx['balance']
        balance = Decimal(balance_raw) / CONVERT_MULTIPLIER[CURRENCY]
        # send from tip account to return account
        if Decimal(balance) > 0:
            try:
                donation_amount, send_amount = calculate_donation_amount(
                    Decimal(balance), user[0], user[1])
                work = get_pow(tip_account)
                donation_hash = rpc.send(wallet=WALLET,
                                         source=tip_account,
                                         destination=BOT_ACCOUNT,
                                         work=work,
                                         amount=donation_amount)
                work = get_pow(tip_account)
                inactive_hash = rpc.send(wallet=WALLET,
                                         source=tip_account,
                                         destination=user[2],
                                         work=work,
                                         amount=send_amount)
            except Exception as e:
                logging.info("{}: ERROR: {}".format(datetime.now, e))
            logging.info(
                "{}: Inactive user {} on {} had their funds returned to their recovery address {} under hash {}"
                .format(datetime.now(), user[0], user[1], user[2],
                        inactive_hash))
            logging.info(
                "{}: Inactive user {} on {} donated under hash {}".format(
                    datetime.now(), user[0], user[1], user[2], donation_hash))
        else:
            logging.info("{}: Balance for user {} on {} was 0".format(
                datetime.now(), user[0], user[1]))
Esempio n. 3
0
def validate_sender(message):
    """
    Validate that the sender has an account with the tip bot, and has enough NANO to cover the tip.
    """
    logging.info("{}: validating sender".format(datetime.now()))
    logging.info("sender id: {}".format(message['sender_id']))
    logging.info("system: {}".format(message['system']))
    db_call = "SELECT account, register FROM users where user_id = {} AND system = '{}'".format(
        message['sender_id'], message['system'])
    sender_account_info = get_db_data(db_call)

    if not sender_account_info:
        no_account_text = (
            "You do not have an account with the bot.  Please send a DM to me with !register to set up "
            "an account.")
        send_reply(message, no_account_text)

        logging.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 = {} AND system = '{}'".format(
            message['sender_id'], message['system'])
        set_db_data(db_call)

    receive_pending(message['sender_account'])
    message['sender_balance_raw'] = rpc.account_balance(
        account='{}'.format(message['sender_account']))
    message['sender_balance'] = message['sender_balance_raw'][
        'balance'] / 1000000000000000000000000000000

    return message
Esempio n. 4
0
def balance_process(message):
    import modules.db as db
    import modules.currency as currency
    import modules.social as social
    """
    When the user sends a DM containing !balance, reply with the balance of the account linked with their Twitter ID
    """
    logging.info("{}: In balance process".format(datetime.datetime.utcnow()))
    try:
        user = db.User.select().where(db.User.user_id == int(message['sender_id'])).get()
        message['sender_account'] = user.account
        sender_register = user.register

        if sender_register == 0:
            db.User.update(register=1).where(
                (db.User.user_id == int(message['sender_id'])) &
                (db.User.register == 0)).execute()

        currency.receive_pending(message['sender_account'])
        balance_return = rpc.account_balance(
            account="{}".format(message['sender_account']))
        message['sender_balance_raw'] = balance_return['balance']
        message['sender_balance'] = BananoConversions.raw_to_banano(balance_return['balance'])

        balance_text = "Your balance is {} BAN.".format(
            message['sender_balance'])
        social.send_dm(message['sender_id'], balance_text)
        logging.info("{}: Balance Message Sent!".format(datetime.datetime.utcnow()))
    except db.User.DoesNotExist:
        logging.info(
            "{}: User tried to check balance without an account".format(
                datetime.datetime.utcnow()))
        balance_message = (
            "There is no account linked to your username.  Please respond with .register to "
            "create an account.")
        social.send_dm(message['sender_id'], balance_message)
Esempio n. 5
0
def validate_sender(message):
    import modules.db as db
    import modules.currency as currency
    """
    Validate that the sender has an account with the tip bot, and has enough NANO to cover the tip.
    """
    logging.info("{}: validating sender".format(datetime.datetime.utcnow()))
    logging.info("sender id: {}".format(message['sender_id']))
    try:
        user = db.User.select().where(
            db.User.user_id == int(message['sender_id'])).get()
        message['sender_account'] = user.account
        message['sender_register'] = user.register

        if message['sender_register'] != 1:
            db.User.update(register=1).where(
                (db.User.user_id == int(message['sender_id']))
                & (db.User.register == 0)).execute()

        currency.receive_pending(message['sender_account'])
        message['sender_balance_raw'] = rpc.account_balance(
            account='{}'.format(message['sender_account']))
        message['sender_balance'] = BananoConversions.raw_to_banano(
            message['sender_balance_raw']['balance'])

        return message
    except db.User.DoesNotExist:
        no_account_text = (
            "You do not have an account with the bot.  Please send a DM to me with .register to set up "
            "an account.")
        send_reply(message, no_account_text)

        logging.info("{}: User tried to send a tip without an account.".format(
            datetime.datetime.utcnow()))
        message['sender_account'] = None
        return message
Esempio n. 6
0
def withdraw_process(message):
    import modules.db as db
    import modules.currency as currency
    import modules.social as social
    """
    When the user sends !withdraw, send their entire balance to the provided account.  If there is no provided account
    reply with an error.
    """
    logging.info('{}: in withdraw process.'.format(datetime.datetime.utcnow()))
    # check if there is a 2nd argument
    if 3 >= len(message['dm_array']) >= 2:
        # if there is, retrieve the sender's account and wallet
        try:
            user = db.User.select().where(db.User.user_id == int(message['sender_id'])).get()
            sender_account = user.account
            currency.receive_pending(sender_account)
            balance_return = rpc.account_balance(
                account='{}'.format(sender_account))

            if len(message['dm_array']) == 2:
                receiver_account = message['dm_array'][1].lower()
            else:
                receiver_account = message['dm_array'][2].lower()

            if rpc.validate_account_number(receiver_account) == 0:
                invalid_account_text = (
                    "The account address you provided is invalid.  Please double check and "
                    "resend your request.")
                social.send_dm(message['sender_id'], invalid_account_text)
                logging.info(
                    "{}: The BAN account address is invalid: {}".format(
                        datetime.datetime.utcnow(), receiver_account))
            elif balance_return['balance'] == 0:
                no_balance_text = (
                    "You have 0 balance in your account.  Please deposit to your address {} to "
                    "send more tips!".format(sender_account))
                social.send_dm(message['sender_id'], no_balance_text)
                logging.info(
                    "{}: The user tried to withdraw with 0 balance".format(
                        datetime.datetime.utcnow()))
            else:
                if len(message['dm_array']) == 3:
                    try:
                        withdraw_amount = Decimal(message['dm_array'][1])
                    except Exception as e:
                        logging.info("{}: withdraw no number ERROR: {}".format(
                            datetime.datetime.utcnow(), e))
                        invalid_amount_text = (
                            "You did not send a number to withdraw.  Please resend with the format"
                            ".withdraw <account> or !withdraw <amount> <account>"
                        )
                        social.send_dm(message['sender_id'],
                                       invalid_amount_text)
                        return
                    withdraw_amount_raw = BananoConversions.banano_to_raw(withdraw_amount)
                    if Decimal(withdraw_amount_raw) > Decimal(
                            balance_return['balance']):
                        not_enough_balance_text = (
                            "You do not have that much BAN in your account.  To withdraw your "
                            "full amount, send .withdraw <account>")
                        social.send_dm(message['sender_id'],
                                       not_enough_balance_text)
                        return
                else:
                    withdraw_amount_raw = balance_return['balance']
                    withdraw_amount = BananoConversions.raw_to_banano(balance_return[
                        'balance'])
                # send the total balance to the provided account
                work = currency.get_pow(sender_account)
                if work == '':
                    logging.info("{}: processed without work".format(
                        datetime.datetime.utcnow()))
                    send_hash = rpc.send(
                        wallet="{}".format(WALLET),
                        source="{}".format(sender_account),
                        destination="{}".format(receiver_account),
                        amount=withdraw_amount_raw)
                else:
                    logging.info("{}: processed with work: {}".format(
                        datetime.datetime.utcnow(), work))
                    send_hash = rpc.send(
                        wallet="{}".format(WALLET),
                        source="{}".format(sender_account),
                        destination="{}".format(receiver_account),
                        amount=withdraw_amount_raw,
                        work=work)
                logging.info("{}: send_hash = {}".format(
                    datetime.datetime.utcnow(), send_hash))
                # respond that the withdraw has been processed
                withdraw_text = ("You have successfully withdrawn {} BANANO!".
                                 format(withdraw_amount))
                social.send_dm(message['sender_id'], withdraw_text)
                logging.info("{}: Withdraw processed.  Hash: {}".format(
                    datetime.datetime.utcnow(), send_hash))
        except db.User.DoesNotExist:
            withdraw_no_account_text = "You do not have an account.  Respond with .register to set one up."
            social.send_dm(message['sender_id'], withdraw_no_account_text)
            logging.info("{}: User tried to withdraw with no account".format(
                datetime.datetime.utcnow()))
    else:
        incorrect_withdraw_text = (
            "I didn't understand your withdraw request.  Please resend with .withdraw "
            "<optional:amount> <account>.  Example, .withdraw 1 ban_1meme1... would "
            "withdraw 1 BANANO to account ban_1meme1...  Also, .withdraw "
            "ban_1meme1... would withdraw your entire balance to account "
            "ban_1meme1...")
        social.send_dm(message['sender_id'], incorrect_withdraw_text)
        logging.info("{}: User sent a withdraw with invalid syntax.".format(
            datetime.datetime.utcnow()))
Esempio n. 7
0
def return_tips():
    tips_to_return_call = ("SELECT tip_list.dm_id, tip_list.sender_id, "
                           "users.account, tip_list.amount, tip_list.system "
                           "FROM tip_list "
                           "INNER JOIN users "
                           "ON tip_list.receiver_id = users.user_id AND tip_list.system = users.system "
                           "WHERE DATE(tip_list.timestamp) < DATE_SUB(now(), interval 30 day) "
                           "AND users.register = 0 "
                           "AND tip_list.processed = 2;")
    tip_list = get_db_data(tips_to_return_call)

    for tip in tip_list:
        transaction_id = tip[0]
        sender_id = tip[1]
        receiver_account = tip[2]
        amount = Decimal(str(tip[3]))
        system = tip[4]

        logging.info("{}: Returning tip {}".format(datetime.now(), transaction_id))

        sender_account_call = "SELECT account FROM users WHERE user_id = {} AND system = '{}'".format(sender_id, system)
        sender_account_info = get_db_data(sender_account_call)
        sender_account = sender_account_info[0][0]

        donation_amount, send_amount = calculate_donation_amount(amount, sender_id, system)
        logging.info("donation amount: {}".format(donation_amount))
        logging.info("send_amount: {} - {}".format(amount, send_amount))

        receive_pending(receiver_account)

        work = get_pow(receiver_account)
        try:
            if work == '':
                send_hash = rpc.send(wallet="{}".format(WALLET), source="{}".format(receiver_account),
                                     destination="{}".format(sender_account), amount=send_amount)
                if donation_amount > 0:
                    donation_hash = rpc.send(wallet="{}".format(WALLET), source="{}".format(receiver_account),
                                             destination="{}".format(BOT_ACCOUNT), amount=donation_amount)
                    logging.info("{}: Donation sent from account {} under hash: {}".format(datetime.now(), receiver_account,
                                                                                           donation_hash))
            else:
                send_hash = rpc.send(wallet="{}".format(WALLET), source="{}".format(receiver_account),
                                     destination="{}".format(sender_account), amount=send_amount, work=work)
                if donation_amount > 0:
                    donation_work = get_pow(receiver_account)
                    donation_hash = rpc.send(wallet="{}".format(WALLET), source="{}".format(receiver_account),
                                             destination="{}".format(BOT_ACCOUNT), amount=donation_amount, work=donation_work)
                    logging.info("{}: Donation sent from account {} under hash: {}".format(datetime.now(), receiver_account,
                                                                                           donation_hash))

            logging.info("{}: Tip returned under hash: {}".format(str(datetime.now()), send_hash))
        except nano.rpc.RPCException as e:
            logging.info("{}: Insufficient balance to return {} raw and {} donation from account {}.  Descriptive error: {}".format(datetime.now(),
                                                                                                                                    send_amount,
                                                                                                                                    donation_amount,
                                                                                                                                    receiver_account,
                                                                                                                                    e))
            insufficient_balance_check = rpc.account_balance(receiver_account)
            logging.info("Current balance: {}".format(insufficient_balance_check))
            insufficient_balance_call = ("UPDATE tip_list "
                                         "SET processed = 6 "
                                         "WHERE dm_id = %s;")
            insufficient_balance_values = [transaction_id,]
            set_db_data(insufficient_balance_call, insufficient_balance_values)
            continue
        except Exception as f:
            logging.info("{}: Unexpected error: {}".format(datetime.now(), f))
            continue

        update_tip_call = ("UPDATE tip_list "
                           "SET processed = 9 "
                           "WHERE dm_id = %s;")
        update_tip_values = [transaction_id,]
        try:
            set_db_data(update_tip_call, update_tip_values)
        except Exception as e:
            logging.info("{}: Error updating tip to returned: {}".format(datetime.now(), e))

    send_returned_notice_to_receivers()
    send_returned_notice_to_senders()
Esempio n. 8
0
def return_tips():
    tips_to_return_call = (
        "SELECT tip_list.dm_id, tip_list.amount, users.account, tip_list.sender_id, tip_list.system "
        "FROM tip_bot.tip_list "
        "INNER JOIN users ON tip_list.receiver_id = users.user_id AND tip_list.system = users.system "
        "WHERE processed = 6;")
    tip_list = get_db_data(tips_to_return_call)

    for tip in tip_list:
        transaction_id = tip[0]
        sender_id = tip[3]
        receiver_account = tip[2]
        amount = Decimal(str(tip[1]))
        system = tip[4]

        logging.info("{}: Returning tip {}".format(datetime.now(),
                                                   transaction_id))

        donation_amount, send_amount = calculate_donation_amount(
            amount, sender_id, system)
        logging.info("donation amount: {}".format(donation_amount))
        logging.info("send_amount: {} - {}".format(amount, send_amount))

        receive_pending(receiver_account)

        work = get_pow(receiver_account)
        try:
            if work == '':
                if donation_amount > 0:
                    donation_hash = rpc.send(
                        wallet="{}".format(WALLET),
                        source="{}".format(receiver_account),
                        destination="{}".format(BOT_ACCOUNT),
                        amount=donation_amount)
                    logging.info(
                        "{}: Donation sent from account {} under hash: {}".
                        format(datetime.now(), receiver_account,
                               donation_hash))
            else:
                if donation_amount > 0:
                    donation_hash = rpc.send(
                        wallet="{}".format(WALLET),
                        source="{}".format(receiver_account),
                        destination="{}".format(BOT_ACCOUNT),
                        amount="{}".format(donation_amount),
                        work=work)
                    logging.info(
                        "{}: Donation sent from account {} under hash: {}".
                        format(datetime.now(), receiver_account,
                               donation_hash))

        except nano.rpc.RPCException as e:
            logging.info(
                "{}: Insufficient balance to return {} raw and {} donation from account {}.  Descriptive error: {}"
                .format(datetime.now(), send_amount, donation_amount,
                        receiver_account, e))
            insufficient_balance_check = rpc.account_balance(receiver_account)
            logging.info(
                "Current balance: {}".format(insufficient_balance_check))
            if int(insufficient_balance_check['balance']) == 0:
                insufficient_balance_call = ("UPDATE tip_list "
                                             "SET processed = 9 "
                                             "WHERE dm_id = %s;")
            else:
                insufficient_balance_call = ("UPDATE tip_list "
                                             "SET processed = 6 "
                                             "WHERE dm_id = %s;")

            insufficient_balance_values = [
                transaction_id,
            ]
            set_db_data(insufficient_balance_call, insufficient_balance_values)
            continue
        except Exception as f:
            logging.info("{}: Unexpected error: {}".format(datetime.now(), f))
            continue

        update_tip_call = ("UPDATE tip_list "
                           "SET processed = 9 "
                           "WHERE dm_id = %s;")
        update_tip_values = [
            transaction_id,
        ]
        try:
            set_db_data(update_tip_call, update_tip_values)
        except Exception as e:
            logging.info("{}: Error updating tip to returned: {}".format(
                datetime.now(), e))