def handle_balance(message): username = str(message.author) message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created add_history_record( username=str(message.author), comment_or_message="message", reddit_time=message_time, action="balance", comment_id=message.name, comment_text=str(message.body)[:255], ) try: acct = Account.get(username=username) results = check_balance(acct.address) response = text.BALANCE % ( acct.address, from_raw(results), acct.address, ) return response except Account.DoesNotExist: return text.NOT_OPEN
def handle_balance(message): username = str(message.author) message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created add_history_record( username=str(message.author), comment_or_message="message", reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), action="balance", comment_id=message.name, comment_text=str(message.body)[:255], ) sql = "SELECT address FROM accounts WHERE username=%s" val = (username, ) MYCURSOR.execute(sql, val) result = MYCURSOR.fetchall() if len(result) > 0: results = check_balance(result[0][0]) response = text.BALANCE % ( result[0][0], from_raw(results[0]), from_raw(results[1]), result[0][0], ) return response return text.NOT_OPEN
def handle_balance(message): username = str(message.author) message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created add_history_record( username=str(message.author), comment_or_message="message", reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), action="balance", comment_id=message.name, comment_text=str(message.body)[:255], ) sql = "SELECT address FROM accounts WHERE username=%s" val = (username, ) MYCURSOR.execute(sql, val) result = MYCURSOR.fetchall() if len(result) > 0: results = check_balance(result[0][0]) response = ( "At address %s:\n\nAvailable: %s Nano\n\nUnpocketed: %s Nano\n\nNano " "will be pocketed automatically unless the transaction is below " "0.0001 Nano." "\n\nhttps://nanocrawler.cc/explorer/account/%s" % (result[0][0], results[0] / 10**30, results[1] / 10**30, result[0][0])) return response return "You do not have an open account yet"
def handle_projects(message): """ Handles creation and updates of crowdfunding (NanoCenter) projects """ parsed_text = parse_text(str(message.body)) response = text.CROWD_FUNDING["projects"] if (str(message.author).lower() in DONATION_ADMINS + TIPBOT_OWNER) and len(parsed_text) > 2: sql = "INSERT INTO projects (project, address) VALUES(%s, %s) ON DUPLICATE KEY UPDATE address=%s" val = (parsed_text[1], parsed_text[2], parsed_text[2]) MYCURSOR.execute(sql, val) MYDB.commit() add_history_record( username=str(message.author), action="project", comment_text=str(message.body)[:255], comment_or_message="message", comment_id=message.name, ) sql = "SELECT project, address FROM projects" MYCURSOR.execute(sql) results = MYCURSOR.fetchall() for result in results: response += "%s %s \n" % (result[0], result[1]) return response
def handle_create(message): message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created add_history_record( username=str(message.author), comment_or_message="message", reddit_time=message_time, action="create", comment_id=message.name, comment_text=str(message.body)[:255], ) username = str(message.author) try: acct = Account.get(username=username) response = text.ALREADY_EXISTS % (acct.address, acct.address) except Account.DoesNotExist: address = tipper_functions.add_new_account(username)['address'] if address is None: response = text.ACCOUNT_MAKE_ERROR_ERROR else: response = WELCOME_CREATE % (address, address) # reddit.redditor(message_recipient).message(subject, message_text) return response
def handle_silence(message): message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created username = str(message.author) add_history_record( username=str(message.author), action="silence", comment_or_message="message", comment_id=message.name, reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), ) parsed_text = parse_text(str(message.body)) if len(parsed_text) < 2: response = text.SILENCE["parse_error"] return response if parsed_text[1] == "yes": sql = "UPDATE accounts SET silence = TRUE WHERE username = %s " val = (username, ) MYCURSOR.execute(sql, val) response = text.SILENCE["yes"] elif parsed_text[1] == "no": sql = "UPDATE accounts SET silence = FALSE WHERE username = %s" val = (username, ) MYCURSOR.execute(sql, val) response = text.SILENCE["no"] else: response = text.SILENCE["yes_no"] MYDB.commit() return response
def handle_silence(message): message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created username = str(message.author) add_history_record( username=str(message.author), action="silence", comment_or_message="message", comment_id=message.name, reddit_time=message_time, ) parsed_text = parse_text(str(message.body)) if len(parsed_text) < 2: response = text.SILENCE["parse_error"] return response if parsed_text[1] == "yes": Account.update(silence=True).where( Account.username == username).execute() response = text.SILENCE["yes"] elif parsed_text[1] == "no": Account.update(silence=False).where( Account.username == username).execute() response = text.SILENCE["no"] else: response = text.SILENCE["yes_no"] return response
def handle_create(message): message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created add_history_record( username=str(message.author), comment_or_message="message", reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), action="create", comment_id=message.name, comment_text=str(message.body)[:255], ) username = str(message.author) sql = "SELECT address FROM accounts WHERE username=%s" val = (username, ) MYCURSOR.execute(sql, val) result = MYCURSOR.fetchall() if len(result) is 0: address = tipper_functions.add_new_account(username)["address"] response = WELCOME_CREATE % (address, address) message_recipient = TIP_BOT_USERNAME subject = "send" message_text = "send 0.001 %s" % username sql = "INSERT INTO messages (username, subject, message) VALUES (%s, %s, %s)" val = (message_recipient, subject, message_text) MYCURSOR.execute(sql, val) MYDB.commit() # reddit.redditor(message_recipient).message(subject, message_text) else: response = text.ALREADY_EXISTS % (result[0][0], result[0][0]) return response
def handle_opt_in(message): add_history_record( username=str(message.author), action="opt-in", comment_or_message="message", comment_id=message.name, reddit_time=datetime.utcfromtimestamp(message.created_utc), ) Account.update(opt_in=True).where( Account.username == str(message.author)).execute() response = text.OPT_IN return response
def handle_help(message): message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created add_history_record( username=str(message.author), action="help", comment_or_message="message", comment_id=message.name, reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), ) response = HELP return response
def handle_opt_in(message): add_history_record( username=str(message.author), action="opt-in", comment_or_message="message", comment_id=message.name, reddit_time=datetime.utcfromtimestamp( message.created_utc).strftime("%Y-%m-%d %H:%M:%S"), ) sql = "UPDATE accounts SET opt_in = TRUE WHERE username = %s" MYCURSOR.execute(sql, (str(message.author), )) MYDB.commit() response = text.OPT_IN return response
def handle_opt_in(message): add_history_record( username=str(message.author), action="opt-in", comment_or_message="message", comment_id=message.name, reddit_time=datetime.utcfromtimestamp( message.created_utc).strftime("%Y-%m-%d %H:%M:%S"), ) sql = "UPDATE accounts SET opt_in = TRUE WHERE username = %s" MYCURSOR.execute(sql, (str(message.author), )) MYDB.commit() response = ( "Welcome back! You have opted back in. Your account will be restored with the same address, " "though any Nano you had may have already been returned or donated already." ) return response
def handle_receive(message): """ :param message: :return: """ message_time = datetime.utcfromtimestamp(message.created_utc) username = str(message.author) # find any accounts associated with the redditor sql = "SELECT address, private_key FROM accounts WHERE username=%s" val = (username, ) MYCURSOR.execute(sql, val) result = MYCURSOR.fetchall() if len(result) > 0: address = result[0][0] open_or_receive(address, result[0][1]) balance = check_balance(address) add_history_record( username=username, action="receive", reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), address=address, comment_id=message.name, comment_or_message="message", ) response = ( "At address %s, you currently have %s Nano available, and %s Nano " "unpocketed. If you have any unpocketed, create a new " "message containing the word " "'receive'\n\nhttps://nanocrawler.cc/explorer/account/%s" % (address, balance[0] / 10**30, balance[1] / 10**30, address)) return response else: add_history_record( username=username, action="receive", reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), comment_id=message.name, comment_or_message="message", ) response = ( "You do not currently have an account open. To create one, " "respond with the text 'create' in the message body.") return response
def handle_opt_out(message): add_history_record( username=str(message.author), action="opt-out", comment_or_message="message", comment_id=message.name, reddit_time=datetime.utcfromtimestamp( message.created_utc).strftime("%Y-%m-%d %H:%M:%S"), ) sql = "UPDATE accounts SET opt_in = FALSE WHERE username = %s" MYCURSOR.execute(sql, (str(message.author), )) MYDB.commit() response = ( "You have opted-out and I promise not to bother you anymore.\n\nReturnable Nano will be returned " "to the tippers, and the remaining balance will be donated to the tipbot fund.\n\nIf this was in " "error, please respond immediately with the text `opt-in`.") return response
def handle_receive(message): """ :param message: :return: """ message_time = datetime.utcfromtimestamp(message.created_utc) username = str(message.author) # find any accounts associated with the redditor sql = "SELECT address, private_key FROM accounts WHERE username=%s" val = (username, ) MYCURSOR.execute(sql, val) result = MYCURSOR.fetchall() if len(result) > 0: address = result[0][0] open_or_receive(address, result[0][1]) balance = check_balance(address) add_history_record( username=username, action="receive", reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), address=address, comment_id=message.name, comment_or_message="message", ) response = text.RECEIVE["balance"] % ( address, from_raw(balance[0]), from_raw(balance[1]), address, ) return response else: add_history_record( username=username, action="receive", reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), comment_id=message.name, comment_or_message="message", ) response = text.NOT_OPEN return response
def handle_silence(message): message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created username = str(message.author) add_history_record( username=str(message.author), action="silence", comment_or_message="message", comment_id=message.name, reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), ) parsed_text = parse_text(str(message.body)) if len(parsed_text) < 2: response = ("I couldn't parse your command. I was expecting 'silence " "<yes/no>'. Be sure to check your spacing.") return response if parsed_text[1] == "yes": sql = "UPDATE accounts SET silence = TRUE WHERE username = %s " val = (username, ) MYCURSOR.execute(sql, val) response = ("Silence set to 'yes'. You will no longer receive tip " "notifications or be tagged by the bot.") elif parsed_text[1] == "no": sql = "UPDATE accounts SET silence = FALSE WHERE username = %s" val = (username, ) MYCURSOR.execute(sql, val) response = ( "Silence set to 'no'. You will receive tip notifications and be " "tagged by the bot in replies.") else: response = ( "I did not see 'no' or 'yes' after 'silence'. If you did type " "that, check your spacing.") MYDB.commit() return response
def handle_convert(message): """ Returns the Nano amount of a currency. """ parsed_text = parse_text(str(message.body)) add_history_record( username=str(message.author), action="convert", comment_or_message="message", comment_id=message.name, reddit_time=datetime.utcfromtimestamp( message.created_utc).strftime("%Y-%m-%d %H:%M:%S"), ) if len(parsed_text) < 2: return text.CONVERT["no_amount_specified"] try: amount = parse_raw_amount(parsed_text) except TipError: return text.SEND_TEXT[120] % parsed_text[1] return text.CONVERT["success"] % (parsed_text[1], from_raw(amount))
def handle_create(message): message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created add_history_record( username=str(message.author), comment_or_message="message", reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), action="create", comment_id=message.name, comment_text=str(message.body)[:255], ) username = str(message.author) sql = "SELECT address FROM accounts WHERE username=%s" val = (username, ) MYCURSOR.execute(sql, val) result = MYCURSOR.fetchall() if len(result) is 0: address = tipper_functions.add_new_account(username) response = WELCOME_CREATE % (address, address) message_recipient = TIP_BOT_USERNAME subject = "send" message_text = "send 0.001 %s" % username sql = "INSERT INTO messages (username, subject, message) VALUES (%s, %s, %s)" val = (message_recipient, subject, message_text) MYCURSOR.execute(sql, val) MYDB.commit() # reddit.redditor(message_recipient).message(subject, message_text) else: response = ( "It looks like you already have an account. In any case it is now " "**active**. Your Nano address is %s." "\n\nhttps://nanocrawler.cc/explorer/account/%s" % (result[0][0], result[0][0])) return response
def handle_send(message): """ Extracts send command information from a PM command :param message: :return: """ parsed_text = parse_text(str(message.body)) username = str(message.author) message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created entry_id = add_history_record( username=username, action="send", comment_or_message="message", comment_id=message.name, reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), comment_text=str(message.body)[:255], ) response = {"username": username} # check that there are enough fields (i.e. a username) if len(parsed_text) <= 2: update_history_notes(entry_id, "no recipient or amount specified") response["status"] = 110 return response # check that it wasn't a mistyped currency code or something if parsed_text[2] in EXCLUDED_REDDITORS: response["status"] = 140 return response # pull sender account info sender_info = tipper_functions.account_info(response["username"]) if not sender_info: update_history_notes(entry_id, "user does not exist") response["status"] = 100 return response # parse the amount try: response["amount"] = parse_raw_amount(parsed_text, response["username"]) except TipError as err: response["status"] = 120 response["amount"] = parsed_text[1] update_history_notes(entry_id, err.sql_text) return response # check if it's above the program minimum if response["amount"] < nano_to_raw(PROGRAM_MINIMUM): update_history_notes(entry_id, "amount below program limit") response["status"] = 130 return response # check the user's balance if response["amount"] > sender_info["balance"]: update_history_notes(entry_id, "insufficient funds") response["status"] = 160 return response recipient_text = parsed_text[2] # catch invalid redditor AND address try: recipient_info = parse_recipient_username(recipient_text) except TipError as err: update_history_notes(entry_id, err.sql_text) response["recipient"] = recipient_text response["status"] = 170 return response # if we have a username, pull their info if "username" in recipient_info.keys(): response["recipient"] = recipient_info["username"] recipient_name = recipient_info["username"] recipient_info = tipper_functions.account_info(recipient_name) response["status"] = 10 if recipient_info is None: recipient_info = tipper_functions.add_new_account( response["recipient"]) response["status"] = 20 elif not recipient_info["opt_in"]: response["status"] = 190 return response # check if it's an address else: # otherwise, just use the address. Everything is None except address recipient_info["minimum"] = 0 response["recipient"] = recipient_info["address"] response["status"] = 30 # check the send amount is above the user minimum, if a username is provided # if it was just an address, this would be -1 if response["amount"] < recipient_info["minimum"]: update_history_notes(entry_id, "below user minimum") response["status"] = 180 response["minimum"] = recipient_info["minimum"] return response response["hash"] = send( sender_info["address"], sender_info["private_key"], response["amount"], recipient_info["address"], )["hash"] # if it was an address, just send to the address if "username" not in recipient_info.keys(): sql = ( "UPDATE history SET notes = %s, address = %s, username = %s, recipient_username = %s, " "recipient_address = %s, amount = %s, return_status = %s WHERE id = %s" ) val = ( "send to address", sender_info["address"], sender_info["username"], None, recipient_info["address"], str(response["amount"]), "cleared", entry_id, ) tipper_functions.exec_sql(sql, val) LOGGER.info( f"Sending Nano: {sender_info['address']} {sender_info['private_key']} {response['amount']} {recipient_info['address']}" ) return response # Update the sql and send the PMs sql = ( "UPDATE history SET notes = %s, address = %s, username = %s, recipient_username = %s, " "recipient_address = %s, amount = %s, hash = %s, return_status = %s WHERE id = %s" ) val = ( "sent to user", sender_info["address"], sender_info["username"], recipient_info["username"], recipient_info["address"], str(response["amount"]), response["hash"], "cleared", entry_id, ) tipper_functions.exec_sql(sql, val) LOGGER.info( f"Sending Nano: {sender_info['address']} {sender_info['private_key']} {response['amount']} {recipient_info['address']} {recipient_info['username']}" ) if response["status"] == 20: subject = "Congrats on receiving your first Nano Tip!" message_text = (WELCOME_TIP % ( response["amount"] / 10**30, recipient_info["address"], recipient_info["address"], ) + COMMENT_FOOTER) send_pm(recipient_info["username"], subject, message_text) return response else: if not recipient_info["silence"]: receiving_new_balance = check_balance(recipient_info["address"]) subject = "You just received a new Nano tip!" message_text = (NEW_TIP % ( response["amount"] / 10**30, recipient_info["address"], receiving_new_balance[0] / 10**30, receiving_new_balance[1] / 10**30, response["hash"], ) + COMMENT_FOOTER) send_pm(recipient_info["username"], subject, message_text) return response
def handle_minimum(message): message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created # user may select a minimum tip amount to avoid spamming. Tipbot minimum is 0.001 username = str(message.author) # find any accounts associated with the redditor parsed_text = parse_text(str(message.body)) # there should be at least 2 words, a minimum and an amount. if len(parsed_text) < 2: response = ("I couldn't parse your command. I was expecting 'minimum " "<amount>'. Be sure to check your spacing.") return response # check that the minimum is a number if parsed_text[1].lower() == "nan" or ("inf" in parsed_text[1].lower()): response = ("'%s' didn't look like a number to me. If it is blank, " "there might be extra spaces in the command.") return response try: amount = float(parsed_text[1]) except: response = ("'%s' didn't look like a number to me. If it is blank, " "there might be extra spaces in the command.") return response # check that it's greater than 0.01 if nano_to_raw(amount) < nano_to_raw(PROGRAM_MINIMUM): response = ( "Did not update. The amount you specified is below the program minimum " "of %s Nano." % PROGRAM_MINIMUM) return response # check if the user is in the database sql = "SELECT address FROM accounts WHERE username=%s" val = (username, ) MYCURSOR.execute(sql, val) result = MYCURSOR.fetchall() if len(result) > 0: # open_or_receive(result[0][0], result[0][1]) # balance = check_balance(result[0][0]) add_history_record( username=username, action="minimum", amount=nano_to_raw(amount), address=result[0][0], comment_or_message="message", comment_id=message.name, reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), comment_text=str(message.body)[:255], ) sql = "UPDATE accounts SET minimum = %s WHERE username = %s" val = (str(nano_to_raw(amount)), username) MYCURSOR.execute(sql, val) MYDB.commit() response = "Updating tip minimum to %s" % amount return response else: add_history_record( username=username, action="minimum", reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), amount=nano_to_raw(amount), comment_id=message.name, comment_text=str(message.body)[:255], ) response = ( "You do not currently have an account open. To create one, " "respond with the text 'create' in the message body.") return response
def handle_message(message): response = "not activated" parsed_text = parse_text(str(message.body)) command = parsed_text[0].lower() # only activate if it's not an opt-out command if command != "opt-out": activate(message.author) # normal commands if command in ["help", "!help"]: LOGGER.info("Helping") subject = "Nano Tipper - Help" response = handle_help(message) elif command in ["balance", "address"]: LOGGER.info("balance") subject = "Nano Tipper - Account Balance" response = handle_balance(message) elif command == "minimum": LOGGER.info("Setting Minimum") subject = "Nano Tipper - Tip Minimum" response = handle_minimum(message) elif command in ["percentage", "percent"]: LOGGER.info("Setting Percentage") subject = "Nano Tipper - Returned Tip Percentage for Donation" response = handle_percentage(message) elif command in ["create", "register"]: LOGGER.info("Creating") subject = "Nano Tipper - Create" response = handle_create(message) elif command in ["send", "withdraw"]: subject = "Nano Tipper - Send" LOGGER.info("send via PM") response = handle_send(message) response = text.make_response_text(message, response) elif command == "history": LOGGER.info("history") subject = "Nano Tipper - History" response = handle_history(message) elif command == "silence": LOGGER.info("silencing") subject = "Nano Tipper - Silence" response = handle_silence(message) elif command == "subreddit": LOGGER.info("subredditing") subject = "Nano Tipper - Subreddit" response = handle_subreddit(message) elif command == "opt-out": LOGGER.info("opting out") response = handle_opt_out(message) subject = "Nano Tipper - Opt Out" elif command == "opt-in": LOGGER.info("opting in") subject = "Nano Tipper - Opt In" response = handle_opt_in(message) # nanocenter donation commands elif command in ("project", "projects"): if (str(message.author).lower() in DONATION_ADMINS + TIPBOT_OWNER) and len(parsed_text) > 2: sql = "INSERT INTO projects (project, address) VALUES(%s, %s) ON DUPLICATE KEY UPDATE address=%s" val = (parsed_text[1], parsed_text[2], parsed_text[2]) MYCURSOR.execute(sql, val) MYDB.commit() add_history_record( username=str(message.author), action="project", comment_text=str(message.body)[:255], comment_or_message="message", comment_id=message.name, ) response = "Current NanoCenter Donation Projects: \n\n" subject = "Nanocenter Projects" sql = "SELECT project, address FROM projects" MYCURSOR.execute(sql) results = MYCURSOR.fetchall() for result in results: response += "%s %s \n" % (result[0], result[1]) elif command == "delete_project": if ((str(message.author) == TIPBOT_OWNER) or (str(message.author).lower() == "rockmsockmjesus")) and len(parsed_text) > 1: sql = "DELETE FROM projects WHERE project=%s" val = (parsed_text[1], ) MYCURSOR.execute(sql, val) MYDB.commit() response = "Current NanoCenter Donation Projects: \n\n" subject = "Nanocenter Projects" sql = "SELECT project, address FROM projects" MYCURSOR.execute(sql) results = MYCURSOR.fetchall() for result in results: response += "%s %s \n" % (result[0], result[1]) # a few administrative tasks elif command in ["restart", "stop", "disable", "deactivate"]: if str(message.author).lower() in [ TIPBOT_OWNER, "rockmsockmjesus", ]: # "joohansson"]: add_history_record( username=str(message.author), action="restart", comment_text=str(message.body)[:255], comment_or_message="message", comment_id=message.name, ) sys.exit() elif command == "test_welcome_tipped": subject = "Nano Tipper - Welcome By Tip" response = WELCOME_TIP % ( 0.01, "xrb_3jy9954gncxbhuieujc3pg5t1h36e7tyqfapw1y6zukn9y1g6dj5xr7r6pij", "xrb_3jy9954gncxbhuieujc3pg5t1h36e7tyqfapw1y6zukn9y1g6dj5xr7r6pij", ) elif command == "test_welcome_create": subject = "Nano Tipper - Create" response = WELCOME_CREATE % ( "xrb_3jy9954gncxbhuieujc3pg5t1h36e7tyqfapw1y6zukn9y1g6dj5xr7r6pij", "xrb_3jy9954gncxbhuieujc3pg5t1h36e7tyqfapw1y6zukn9y1g6dj5xr7r6pij", ) else: add_history_record( username=str(message.author), comment_text=str(message.body)[:255], comment_or_message="message", comment_id=message.name, ) return None message_recipient = str(message.author) message_text = response + COMMENT_FOOTER send_pm(message_recipient, subject, message_text, bypass_opt_out=True)
def handle_history(message): message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created username = str(message.author) parsed_text = parse_text(str(message.body)) num_records = 10 # if there are more than 2 words, one of the words is a number for the number of records if len(parsed_text) >= 2: if parsed_text[1].lower() == "nan" or ("inf" in parsed_text[1].lower()): response = ( "'%s' didn't look like a number to me. If it is blank, " "there might be extra spaces in the command.") return response try: num_records = int(parsed_text[1]) except: response = ( "'%s' didn't look like a number to me. If it is blank, " "there might be extra spaces in the command.") return response # check that it's greater than 50 if num_records > 50: num_records = 50 # check if the user is in the database sql = "SELECT address FROM accounts WHERE username=%s" val = (username, ) MYCURSOR.execute(sql, val) result = MYCURSOR.fetchall() if len(result) > 0: # open_or_receive(result[0][0], result[0][1]) # balance = check_balance(result[0][0]) add_history_record( username=username, action="history", amount=num_records, address=result[0][0], comment_or_message="message", comment_id=message.name, reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), comment_text=str(message.body)[:255], ) response = "Here are your last %s historical records:\n\n" % num_records sql = ( "SELECT reddit_time, action, amount, comment_id, notes, recipient_" "username, recipient_address FROM history WHERE username=%s ORDER BY " "id DESC limit %s") val = (username, num_records) MYCURSOR.execute(sql, val) results = MYCURSOR.fetchall() for result in results: try: amount = result[2] if (result[1] == "send") and amount: amount = int(result[2]) / 10**30 if (result[4] == "sent to registered redditor" or result[4] == "new user created"): response += ( "%s: %s | %s Nano to %s | reddit object: %s | %s\n\n" % ( result[0], result[1], amount, result[5], result[3], result[4], )) elif (result[4] == "sent to registered address" or result[4] == "sent to unregistered address"): response += ( "%s: %s | %s Nano to %s | reddit object: %s | %s\n\n" % ( result[0], result[1], amount, result[6], result[3], result[4], )) elif result[1] == "send": response += "%s: %s | reddit object: %s | %s\n\n" % ( result[0], result[1], result[3], result[4], ) elif (result[1] == "minimum") and amount: amount = int(result[2]) / 10**30 response += "%s: %s | %s | %s | %s\n\n" % ( result[0], result[1], amount, result[3], result[4], ) else: response += "%s: %s | %s | %s | %s\n\n" % ( result[0], result[1], amount, result[3], result[4], ) except: response += ( "Unparsed Record: Nothing is wrong, I just didn't " "parse this record properly.\n\n") return response else: add_history_record( username=username, action="history", reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), amount=num_records, comment_id=message.name, comment_text=str(message.body)[:255], ) response = ( "You do not currently have an account open. To create one, " "respond with the text 'create' in the message body.") return response
def handle_history(message): message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created username = str(message.author) parsed_text = parse_text(str(message.body)) num_records = 10 # if there are more than 2 words, one of the words is a number for the number of records if len(parsed_text) >= 2: if parsed_text[1].lower() == "nan" or ("inf" in parsed_text[1].lower()): response = text.NAN return response try: num_records = int(parsed_text[1]) except: response = text.NAN return response # check that it's greater than 50 if num_records > 50: num_records = 50 # check if the user is in the database try: acct = Account.get(username=username) # open_or_receive(result[0][0], result[0][1]) # balance = check_balance(result[0][0]) add_history_record( username=username, action="history", amount=num_records, address=acct.address, comment_or_message="message", comment_id=message.name, reddit_time=message_time, comment_text=str(message.body)[:255], ) response = "Here are your last %s historical records:\n\n" % num_records history = History.select( History.reddit_time, History.action, History.amount, History.comment_id, History.notes, History.recipient_username, History.recipient_address).where( History.username == username).order_by(History.id.desc()) for result in history: try: amount = result.amount if (result.action == "send") and amount: amount = from_raw(int(result.amount)) if (result.notes == "sent to registered redditor" or result.notes == "new user created"): response += ( "%s: %s | %s Banano to %s | reddit object: %s | %s\n\n" % ( result.reddit_time.strftime( "%Y-%m-%d %H:%M:%S"), result.action, amount, result.recipient_username, result.comment_id, result.notes, )) elif (result.notes == "sent to registered address" or result.notes == "sent to unregistered address"): response += ( "%s: %s | %s Banano to %s | reddit object: %s | %s\n\n" % ( result.reddit_time.strftime( "%Y-%m-%d %H:%M:%S"), result.action, amount, result.recipient_address, result.comment_id, result.notes, )) elif result.action == "send": response += "%s: %s | reddit object: %s | %s\n\n" % ( result.reddit_time.strftime("%Y-%m-%d %H:%M:%S"), result.action, result.comment_id, result.notes, ) else: response += "%s: %s | %s | %s | %s\n\n" % ( result.reddit_time.strftime("%Y-%m-%d %H:%M:%S"), result.action, amount, result.comment_id, result.notes, ) except: response += ( "Unparsed Record: Nothing is wrong, I just didn't " "parse this record properly.\n\n") return response except Account.DoesNotExist: add_history_record( username=username, action="history", reddit_time=message_time, amount=num_records, comment_id=message.name, comment_text=str(message.body)[:255], ) response = text.NOT_OPEN return response
def handle_percentage(message): message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created # user may select a minimum tip amount to avoid spamming. Tipbot minimum is 0.001 username = str(message.author) # find any accounts associated with the redditor parsed_text = parse_text(str(message.body)) # there should be at least 2 words, a minimum and an amount. if len(parsed_text) < 2: response = "I couldn't parse your command. I was expecting 'percentage <amount>'. Be sure to check your spacing." return response # check that the minimum is a number if parsed_text[1].lower() == "nan" or ("inf" in parsed_text[1].lower()): response = "'%s' didn't look like a number to me. If it is blank, there might be extra spaces in the command." return response try: amount = float(parsed_text[1]) except: response = "'%s' didn't look like a number to me. If it is blank, there might be extra spaces in the command." return response # check that it's greater than 0.01 if round(amount, 2) < 0: response = "Did not update. Your percentage cannot be negative." return response if round(amount, 2) > 100: response = "Did not update. Your percentage must be 100 or lower." return response # check if the user is in the database sql = "SELECT address FROM accounts WHERE username=%s" val = (username, ) MYCURSOR.execute(sql, val) result = MYCURSOR.fetchall() if len(result) > 0: # open_or_receive(result[0][0], result[0][1]) # balance = check_balance(result[0][0]) add_history_record( username=username, action="percentage", amount=round(amount, 2), address=result[0][0], comment_or_message="message", comment_id=message.name, reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), comment_text=str(message.body)[:255], ) sql = "UPDATE accounts SET percentage = %s WHERE username = %s" val = (round(amount, 2), username) MYCURSOR.execute(sql, val) MYDB.commit() response = "Updating donation percentage to %s" % round(amount, 2) return response else: add_history_record( username=username, action="percentage", reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), amount=round(amount, 2), comment_id=message.name, comment_text=str(message.body)[:255], ) response = ( "You do not currently have an account open. To create one, " "respond with the text 'create' in the message body.") return response
def send_from_comment(message): """ Error codes: Success 10 - sent to existing user 20 - sent to new user 30 - sent to address 40 - donated to nanocenter project Tip not sent 100 - sender account does not exist 110 - Amount and/or recipient not specified 120 - could not parse send amount 130 - below program minimum 140 - currency code issue 150 - below 1 nano for untracked sub 160 - insufficient funds 170 - invalid address / recipient 180 - below recipient minimum 200 - No Nanocenter Project specified 210 - Nanocenter Project does not exist Extracts send command information from a PM command :param message: :return: response string """ parsed_text = parse_text(str(message.body)) response = {"username": str(message.author)} message_time = datetime.datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created entry_id = add_history_record( username=response["username"], action="send", comment_or_message="comment", comment_id=message.name, reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), comment_text=str(message.body)[:255], ) # check if it's a donate command at the end if parsed_text[-3] in DONATE_COMMANDS: parsed_text = parsed_text[-3:] # don't do anything if the first word is a tip command or username elif (parsed_text[0] in [ f"/u/{TIP_BOT_USERNAME}", f"u/{TIP_BOT_USERNAME}" ]) or (parsed_text[0] in TIP_COMMANDS): pass # if the second to last is a username or tip command, redifine parsed text elif (parsed_text[-2] in [ f"/u/{TIP_BOT_USERNAME}", f"u/{TIP_BOT_USERNAME}" ]) or (parsed_text[-2] in TIP_COMMANDS): parsed_text = parsed_text[-2:] # before we can do anything, check the subreddit status for generating the response # check if amount is above subreddit minimum. response["subreddit"] = str(message.subreddit).lower() sql = "SELECT status FROM subreddits WHERE subreddit=%s" val = (response["subreddit"], ) results = tipper_functions.query_sql(sql, val) if len(results) == 0: response["subreddit_minimum"] = 1 results = [["untracked"]] elif results[0][0] in ["full", "friendly", "minimal", "silent"]: response["subreddit_minimum"] = 0 else: response["subreddit_minimum"] = 1 response["subreddit_status"] = results[0][0] # check that it wasn't a mistyped currency code or something if parsed_text[2] in EXCLUDED_REDDITORS: response["status"] = 140 return response if parsed_text[0] in TIP_COMMANDS and len(parsed_text) <= 1: update_history_notes(entry_id, "no recipient or amount specified") response["status"] = 110 return response if parsed_text[0] in DONATE_COMMANDS and len(parsed_text) <= 2: response["status"] = 110 update_history_notes(entry_id, "no recipient or amount specified") return response # pull sender account info sender_info = tipper_functions.account_info(response["username"]) if not sender_info: update_history_notes(entry_id, "user does not exist") response["status"] = 100 return response # parse the amount try: response["amount"] = parse_raw_amount(parsed_text, response["username"]) except TipError as err: response["status"] = 120 response["amount"] = parsed_text[1] update_history_notes(entry_id, err.sql_text) return response # check if it's above the program minimum if response["amount"] < nano_to_raw(PROGRAM_MINIMUM): update_history_notes(entry_id, "amount below program limit") response["status"] = 130 return response # check the user's balance if response["amount"] > sender_info["balance"]: update_history_notes(entry_id, "insufficient funds") response["status"] = 160 return response if response["amount"] < nano_to_raw(response["subreddit_minimum"]): update_history_notes(entry_id, "amount below subreddit minimum") response["status"] = 150 return response # if it's a normal send, pull the account author # we will distinguish users from donations by the presence of a private key if parsed_text[0] in (TIP_COMMANDS + [f"/u/{TIP_BOT_USERNAME}", f"u/{TIP_BOT_USERNAME}"]): response["status"] = 10 response["recipient"] = str(message.parent().author) recipient_info = tipper_functions.account_info(response["recipient"]) if not recipient_info: response["status"] = 20 recipient_info = tipper_functions.add_new_account( response["recipient"]) elif recipient_info["silence"]: response["status"] = 11 elif not recipient_info["opt_in"]: response["status"] = 190 return response elif parsed_text[0] in DONATE_COMMANDS: response["recipient"] = parsed_text[2] results = tipper_functions.query_sql( "FROM projects SELECT address WHERE project = %s", (parsed_text[2], )) if len(results) <= 0: response["status"] = 210 return response recipient_info = { "username": parsed_text[2], "address": results[0][0], "minimum": -1, } response["status"] = 40 else: response["status"] = 999 return response # check the send amount is above the user minimum, if a username is provided # if it was just an address, this would be -1 if response["amount"] < recipient_info["minimum"]: update_history_notes(entry_id, "below user minimum") response["status"] = 180 response["minimum"] = recipient_info["minimum"] return response # send the nanos!! response["hash"] = send( sender_info["address"], sender_info["private_key"], response["amount"], recipient_info["address"], )["hash"] # Update the sql and send the PMs sql = ( "UPDATE history SET notes = %s, address = %s, username = %s, recipient_username = %s, " "recipient_address = %s, amount = %s, hash = %s, return_status = %s WHERE id = %s" ) val = ( "sent to user", sender_info["address"], sender_info["username"], recipient_info["username"], recipient_info["address"], str(response["amount"]), response["hash"], "cleared", entry_id, ) tipper_functions.exec_sql(sql, val) LOGGER.info( f"Sending Nano: {sender_info['address']} {sender_info['private_key']} {response['amount']} {recipient_info['address']} {recipient_info['username']}" ) # Update the sql and send the PMs if needed # if there is no private key, it's a donation. No PMs to send if "private_key" not in recipient_info.keys(): sql = "UPDATE history SET notes = %s, address = %s, username = %s, recipient_address = %s, amount = %s WHERE id = %s" val = ( "sent to nanocenter address", sender_info["address"], sender_info["username"], recipient_info["address"], str(response["amount"]), entry_id, ) tipper_functions.exec_sql(sql, val) response["status"] = 40 return response # update the sql database and send sql = ( "UPDATE history SET notes = %s, address = %s, username = %s, recipient_username = %s, " "recipient_address = %s, amount = %s, return_status = %s WHERE id = %s" ) val = ( "sent to user", sender_info["address"], sender_info["username"], recipient_info["username"], recipient_info["address"], str(response["amount"]), "cleared", entry_id, ) tipper_functions.exec_sql(sql, val) if response["status"] == 20: subject = "Congrats on receiving your first Nano Tip!" message_text = (text.WELCOME_TIP % ( response["amount"] / 10**30, recipient_info["address"], recipient_info["address"], ) + text.COMMENT_FOOTER) send_pm(recipient_info["username"], subject, message_text) return response else: if not recipient_info["silence"]: receiving_new_balance = check_balance(recipient_info["address"]) subject = "You just received a new Nano tip!" message_text = (text.NEW_TIP % ( response["amount"] / 10**30, recipient_info["address"], receiving_new_balance[0] / 10**30, receiving_new_balance[1] / 10**30, response["hash"], ) + text.COMMENT_FOOTER) send_pm(recipient_info["username"], subject, message_text) return response
def handle_message(message): response = "not activated" parsed_text = parse_text(str(message.body)) command = parsed_text[0].lower() # only activate if it's not an opt-out command if command != "opt-out": activate(message.author) # normal commands if command in ["help", "!help"]: LOGGER.info("Helping") subject = text.SUBJECTS["help"] response = handle_help(message) elif command in ["balance", "address"]: LOGGER.info("balance") subject = text.SUBJECTS["balance"] response = handle_balance(message) elif command in ["create", "register"]: LOGGER.info("Creating") subject = text.SUBJECTS["create"] response = handle_create(message) elif command in ["send", "withdraw"]: subject = text.SUBJECTS["send"] LOGGER.info("send via PM") response = handle_send(message) response = text.make_response_text(message, response) elif command == "history": LOGGER.info("history") subject = text.SUBJECTS["history"] response = handle_history(message) elif command == "silence": LOGGER.info("silencing") subject = text.SUBJECTS["silence"] response = handle_silence(message) elif command == "subreddit": LOGGER.info("subredditing") subject = text.SUBJECTS["subreddit"] response = handle_subreddit(message) elif command == "opt-out": LOGGER.info("opting out") response = handle_opt_out(message) subject = text.SUBJECTS["opt-out"] elif command == "opt-in": LOGGER.info("opting in") subject = text.SUBJECTS["opt-in"] response = handle_opt_in(message) # a few administrative tasks elif command in ["restart", "stop", "disable", "deactivate"]: if str(message.author).lower() in [ TIPBOT_OWNER, ]: # "joohansson"]: add_history_record( username=str(message.author), action="restart", comment_text=str(message.body)[:255], comment_or_message="message", comment_id=message.name, ) sys.exit() else: add_history_record( username=str(message.author), comment_text=str(message.body)[:255], comment_or_message="message", comment_id=message.name, ) return None message_recipient = str(message.author) message_text = response + COMMENT_FOOTER send_pm(message_recipient, subject, message_text, bypass_opt_out=True)
def handle_send(message): """ Extracts send command information from a PM command :param message: :return: """ parsed_text = parse_text(str(message.body)) username = str(message.author) message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created entry_id = add_history_record( username=username, action="send", comment_or_message="message", comment_id=message.name, reddit_time=message_time, comment_text=str(message.body)[:255], ) response = {"username": username} # check that there are enough fields (i.e. a username) if len(parsed_text) <= 2: update_history_notes(entry_id, "no recipient or amount specified") response["status"] = 110 return response # pull sender account info sender_info = tipper_functions.account_info(response["username"]) if not sender_info: update_history_notes(entry_id, "user does not exist") response["status"] = 100 return response # parse the amount try: response["amount"] = parse_raw_amount(parsed_text, response["username"]) except TipError as err: response["status"] = 120 response["amount"] = parsed_text[1] update_history_notes(entry_id, err.sql_text) return response # check if it's above the program minimum if response["amount"] < to_raw(PROGRAM_MINIMUM): update_history_notes(entry_id, "amount below program limit") response["status"] = 130 return response # check the user's balance if response["amount"] > sender_info["balance"]: update_history_notes(entry_id, "insufficient funds") response["status"] = 160 return response recipient_text = parsed_text[2] # catch invalid redditor AND address try: recipient_info = parse_recipient_username(recipient_text) except TipError as err: update_history_notes(entry_id, err.sql_text) response["recipient"] = recipient_text response["status"] = 170 return response # if we have a username, pull their info if "username" in recipient_info.keys(): response["recipient"] = recipient_info["username"] recipient_name = recipient_info["username"] recipient_info = tipper_functions.account_info(recipient_name) response["status"] = 10 if recipient_info is None: recipient_info = tipper_functions.add_new_account( response["recipient"]) if recipient_info is None: return text.TIP_CREATE_ACCT_ERROR response["status"] = 20 elif not recipient_info["opt_in"]: response["status"] = 190 return response # check if it's an address else: # otherwise, just use the address. Everything is None except address response["recipient"] = recipient_info["address"] response["status"] = 30 if sender_info["address"] == recipient_info["address"]: # Don't allow sends to yourself response["status"] = 200 return response response["hash"] = send( sender_info["address"], response["amount"], recipient_info["address"], )["block"] # if it was an address, just send to the address if "username" not in recipient_info.keys(): History.update( notes="send to address", address=sender_info["address"], username=sender_info["username"], recipient_username=None, recipient_address=recipient_info["address"], amount=str(response["amount"]), return_status="cleared").where(History.id == entry_id).execute() LOGGER.info( f"Sending Banano: {sender_info['address']} {sender_info['private_key']} {response['amount']} {recipient_info['address']}" ) return response # Update the sql and send the PMs History.update( notes="send to address", address=sender_info["address"], username=sender_info["username"], recipient_username=recipient_info["username"], recipient_address=recipient_info["address"], amount=str(response["amount"]), return_status="cleared").where(History.id == entry_id).execute() LOGGER.info( f"Sending Banano: {sender_info['address']} {sender_info['private_key']} {response['amount']} {recipient_info['address']} {recipient_info['username']}" ) if response["status"] == 20: subject = text.SUBJECTS["first_tip"] message_text = (WELCOME_TIP % ( NumberUtil.format_float(from_raw(response["amount"])), recipient_info["address"], recipient_info["address"], ) + COMMENT_FOOTER) send_pm(recipient_info["username"], subject, message_text) return response else: if not recipient_info["silence"]: receiving_new_balance = check_balance(recipient_info["address"]) subject = text.SUBJECTS["new_tip"] message_text = (NEW_TIP % ( NumberUtil.format_float(from_raw(response["amount"])), recipient_info["address"], from_raw(receiving_new_balance), response["hash"], ) + COMMENT_FOOTER) send_pm(recipient_info["username"], subject, message_text) return response
def send_from_comment(message): """ Error codes: Success 10 - sent to existing user 20 - sent to new user 30 - sent to address 40 - donated to nanocenter project Tip not sent 100 - sender account does not exist 110 - Amount and/or recipient not specified 120 - could not parse send amount 130 - below program minimum 150 - below 1 nano for untracked sub 160 - insufficient funds 170 - invalid address / recipient 180 - below recipient minimum 200 - No Nanocenter Project specified 210 - Nanocenter Project does not exist Extracts send command information from a PM command :param message: :return: response string """ parsed_text = parse_text(str(message.body)) response = {"username": str(message.author)} message_time = datetime.datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created entry_id = add_history_record( username=response["username"], action="send", comment_or_message="comment", comment_id=message.name, reddit_time=message_time, comment_text=str(message.body)[:255], ) # don't do anything if the first word is a tip command or username if (parsed_text[0] in [f"/u/{TIP_BOT_USERNAME}", f"u/{TIP_BOT_USERNAME}" ]) or (parsed_text[0] in TIP_COMMANDS): pass # if the second to last is a username or tip command, redifine parsed text elif (parsed_text[-2] in [ f"/u/{TIP_BOT_USERNAME}", f"u/{TIP_BOT_USERNAME}" ]) or (parsed_text[-2] in TIP_COMMANDS): parsed_text = parsed_text[-2:] # before we can do anything, check the subreddit status for generating the response response["subreddit"] = str(message.subreddit).lower() try: sr = Subreddit.select(Subreddit.status, Subreddit.minimum).where( Subreddit.subreddit == response["subreddit"]).get() response["subreddit_status"] = sr.status response["subreddit_minimum"] = sr.minimum except Subreddit.DoesNotExist: response["subreddit_status"] = "untracked" response["subreddit_minimum"] = "1" if parsed_text[0] in TIP_COMMANDS and len(parsed_text) <= 1: update_history_notes(entry_id, "no recipient or amount specified") response["status"] = 110 return response # pull sender account info sender_info = tipper_functions.account_info(response["username"]) if not sender_info: update_history_notes(entry_id, "user does not exist") response["status"] = 100 return response # parse the amount try: response["amount"] = parse_raw_amount(parsed_text, response["username"]) except TipError as err: response["status"] = 120 response["amount"] = parsed_text[1] update_history_notes(entry_id, err.sql_text) return response # check if it's above the program minimum if response["amount"] < to_raw(PROGRAM_MINIMUM): update_history_notes(entry_id, "amount below program limit") response["status"] = 130 return response # check the user's balance if response["amount"] > sender_info["balance"]: update_history_notes(entry_id, "insufficient funds") response["status"] = 160 return response # check that it's above the subreddit minimum if response["amount"] < to_raw(response["subreddit_minimum"]): update_history_notes(entry_id, "amount below subreddit minimum") response["status"] = 150 return response # if it's a normal send, pull the account author # we will distinguish users from donations by the presence of a private key if parsed_text[0] in (TIP_COMMANDS + [f"/u/{TIP_BOT_USERNAME}", f"u/{TIP_BOT_USERNAME}"]): response["status"] = 10 response["recipient"] = str(message.parent().author) recipient_info = tipper_functions.account_info(response["recipient"]) if not recipient_info: response["status"] = 20 recipient_info = tipper_functions.add_new_account( response["recipient"]) if recipient_info is None: return text.TIP_CREATE_ACCT_ERROR elif recipient_info["silence"]: response["status"] = 11 elif not recipient_info["opt_in"]: response["status"] = 190 return response else: response["status"] = 999 return response if sender_info["address"] == recipient_info["address"]: # Don't allow sends to yourself response["status"] = 200 return response # send the bans!! response["hash"] = send( sender_info["address"], response["amount"], recipient_info["address"], )["block"] # Update the sql and send the PMs History.update( notes="sent to user", address=sender_info["address"], username=sender_info["username"], recipient_username=recipient_info["username"], recipient_address=recipient_info["address"], amount=str(response["amount"]), hash=response["hash"], return_status="cleared").where(History.id == entry_id).execute() LOGGER.info( f"Sending Banano: {sender_info['address']} {sender_info['private_key']} {response['amount']} {recipient_info['address']} {recipient_info['username']}" ) if response["status"] == 20: subject = text.SUBJECTS["first_tip"] message_text = (text.WELCOME_TIP % ( NumberUtil.format_float(from_raw(response["amount"])), recipient_info["address"], recipient_info["address"], ) + text.COMMENT_FOOTER) send_pm(recipient_info["username"], subject, message_text) return response else: if not recipient_info["silence"]: receiving_new_balance = check_balance(recipient_info["address"]) subject = text.SUBJECTS["new_tip"] message_text = (text.NEW_TIP % ( NumberUtil.format_float(from_raw(response["amount"])), recipient_info["address"], from_raw(receiving_new_balance), response["hash"], ) + text.COMMENT_FOOTER) send_pm(recipient_info["username"], subject, message_text) return response
def handle_minimum(message): message_time = datetime.utcfromtimestamp( message.created_utc) # time the reddit message was created # user may select a minimum tip amount to avoid spamming. Tipbot minimum is 0.001 username = str(message.author) # find any accounts associated with the redditor parsed_text = parse_text(str(message.body)) # there should be at least 2 words, a minimum and an amount. if len(parsed_text) < 2: response = text.MINIMUM["parse_error"] return response # check that the minimum is a number if parsed_text[1].lower() == "nan" or ("inf" in parsed_text[1].lower()): response = text.NAN return response try: amount = float(parsed_text[1]) except: response = text.NAN % parsed_text[1] return response # check that it's greater than 0.01 if to_raw(amount) < to_raw(PROGRAM_MINIMUM): response = text.MINIMUM["below_program"] % PROGRAM_MINIMUM return response # check if the user is in the database sql = "SELECT address FROM accounts WHERE username=%s" val = (username, ) MYCURSOR.execute(sql, val) result = MYCURSOR.fetchall() if len(result) > 0: # open_or_receive(result[0][0], result[0][1]) # balance = check_balance(result[0][0]) add_history_record( username=username, action="minimum", amount=to_raw(amount), address=result[0][0], comment_or_message="message", comment_id=message.name, reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), comment_text=str(message.body)[:255], ) sql = "UPDATE accounts SET minimum = %s WHERE username = %s" val = (str(to_raw(amount)), username) MYCURSOR.execute(sql, val) MYDB.commit() response = text.MINIMUM["set_min"] % amount return response else: add_history_record( username=username, action="minimum", reddit_time=message_time.strftime("%Y-%m-%d %H:%M:%S"), amount=to_raw(amount), comment_id=message.name, comment_text=str(message.body)[:255], ) response = text.NOT_OPEN return response