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()
def check_telegram_member(chat_id, chat_name, member_id, member_name): check_user_call = ( "SELECT member_id, member_name FROM telegram_chat_members " "WHERE chat_id = {} and member_name = '{}'".format( chat_id, member_name)) user_check_data = get_db_data(check_user_call) logging.info("checking if user exists") if not user_check_data: logging.info("{}: User {}-{} not found in DB, inserting".format( datetime.now(), chat_id, member_name)) new_chat_member_call = ( "INSERT INTO telegram_chat_members (chat_id, chat_name, member_id, member_name) " "VALUES ({}, '{}', {}, '{}')".format(chat_id, chat_name, member_id, member_name)) set_db_data(new_chat_member_call) return
def mark_notified(user_type): """ Set the DB to show that the receivers were identified. """ if user_type == 'receivers': processed_num = 9 else: processed_num = 8 notified_users_call = ("SELECT dm_id " "FROM tip_bot.tip_list " "WHERE processed = {}".format(processed_num)) notified_users = get_db_data(notified_users_call) for id in notified_users: notified_send_call = ("UPDATE tip_bot.tip_list " "SET processed = %s " "WHERE dm_id = %s") notified_send_values = [(processed_num - 1), id[0]] set_db_data(notified_send_call, notified_send_values)
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
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()
def on_message(client, userdata, msg): try: r = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB, password=REDIS_PW) topic = msg.topic topic = topic.split('/') if topic[0] == 'work': work_type = topic[1] message = msg.payload.decode().split(',') work_hash = message[0] work_difficulty = message[1] mapping = { 'work_type': work_type, 'work_difficulty': work_difficulty, 'timestamp': str(datetime.now()) } r.hmset(work_hash, mapping) logger.info( "{}: work topic received: Work type = {}, hash: {}, difficulty: {}" .format(datetime.now(), work_type, work_hash, work_difficulty)) elif topic[0] == 'result': message = msg.payload.decode().split(',') work_hash = message[0] work_value = message[1] work_client = message[2] hmreturn = r.hmget(work_hash, ['work_type', 'timestamp', 'work_difficulty']) work_type = hmreturn[0].decode() request_time = datetime.strptime(hmreturn[1].decode(), '%Y-%m-%d %H:%M:%S.%f') work_difficulty = hmreturn[2].decode() if work_difficulty != 'ffffffc000000000': # Add work multiplier logic for V19 work_multiplier = get_work_mult() # work_multiplier = "1" else: work_multiplier = "1" time_diff_micro = (datetime.now() - request_time).microseconds time_difference = round(time_diff_micro * (10**-6), 4) client_sql = "INSERT IGNORE INTO dpow_mqtt.clients SET client_id = %s" request_sql = ( "INSERT IGNORE INTO requests " "(hash, client, work_type, work_value, work_difficulty, multiplier, response_length) " "VALUES (%s, %s, %s, %s, %s, %s, %s)") db.set_db_data(client_sql, [ work_client, ]) db.set_db_data(request_sql, [ work_hash, work_client, work_type, work_value, work_difficulty, work_multiplier, time_difference ]) elif topic[0] == 'statistics': stats = json.loads(msg.payload.decode()) logger.info("Stats call received: {}".format(stats)) try: db.set_services(stats['services']['public']) private_call = ( "INSERT INTO services" " (service_name, service_ondemand, service_precache, private_count)" " VALUES ('private', %s, %s, %s)" " ON DUPLICATE KEY UPDATE service_ondemand = VALUES(service_ondemand)," " service_precache = VALUES(service_precache)," " private_count = VALUES(private_count)") private_stats = stats['services']['private'] db.set_db_data(private_call, [ private_stats['ondemand'], private_stats['precache'], private_stats['count'] ]) except Exception as e: logger.info( "Error logger.infoing public services: {}".format(e)) logger.info(stats) elif topic[0] == 'client': try: result = json.loads(msg.payload.decode()) address = topic[1] precache = result['precache'] ondemand = result['ondemand'] client_call = ( "INSERT INTO clients" " (client_id, precache, ondemand)" " VALUES (%s, %s, %s)" " ON DUPLICATE KEY UPDATE precache = VALUES(precache)," " ondemand = VALUES(ondemand);") db.set_db_data(client_call, [address, precache, ondemand]) except Exception as e: logger.info("error logging client info: {}".format(e)) logger.info(msg.payload) else: try: logger.info("UNEXPECTED MESSAGE") logger.info("TOPIC: {}".format(topic[0].upper())) logger.info("message: {}".format(msg.payload)) except Exception as e: logger.info("exception: {}".format(e)) except Exception as e: logger.info("Error: {}".format(e))
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))