def handle_comment(message): response = send_from_comment(message) response_text = text.make_response_text(message, response) # check if subreddit is untracked or silent. If so, PM the users. if response["subreddit_status"] in ["silent", "hostile"]: message_recipient = str(message.author) if response["status"] < 100: subject = "Your Tip Was Successful" else: subject = "You Tip Did Not Go Through" message_text = response_text + text.COMMENT_FOOTER sql = "INSERT INTO messages (username, subject, message) VALUES (%s, %s, %s)" val = (message_recipient, subject, message_text) MYCURSOR.execute(sql, val) MYDB.commit() else: message.reply(response_text + text.COMMENT_FOOTER)
def handle_comment(message): response = send_from_comment(message) response_text = text.make_response_text(message, response) # check if subreddit is untracked or silent. If so, PM the users. if response["subreddit_status"] in ["silent", "untracked", "hostile"]: message_recipient = str(message.author) if response["status"] < 100: subject = text.SUBJECTS["success"] else: subject = text.SUBJECTS["failure"] message_text = response_text + text.COMMENT_FOOTER msg = Message(username=message_recipient, subject=subject, message=message_text) msg.save() else: message.reply(response_text + text.COMMENT_FOOTER)
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 test_handle_send_from_comment_and_text(handle_send_from_comment_mocks): """ 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 """ # sender has no account message = RedditMessage("t4_5", "DNE", "", f"{TIP_COMMANDS[0]} 0.01") response = send_from_comment(message) assert response == { "status": 100, "username": "******", "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "subreddit_status": "full", } assert ( text.make_response_text(message, response) == "You don't have an account yet. Please PM me with `create` in the body to make an account." ) # no amount specified message = RedditMessage("t4_5", "rich", "", f"{TIP_COMMANDS[0]}") response = send_from_comment(message) assert response == { "status": 110, "username": "******", "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "subreddit_status": "full", } assert (text.make_response_text( message, response ) == "You must specify an amount and a user, e.g. `send 1 nano_tipper`.") # could not parse the amount message = RedditMessage("t4_5", "rich", "", f"{TIP_COMMANDS[0]} 0.0sdf1") response = send_from_comment(message) assert response == { "status": 120, "username": "******", "amount": "0.0sdf1", "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "subreddit_status": "full", } assert ( text.make_response_text(message, response) == "I could not read the amount or the currency code. Is '0.0sdf1' a number? This could also mean the currency converter is down." ) # send below program limit message = RedditMessage("t4_5", "rich", "", f"{TIP_COMMANDS[0]} 0.00001") response = send_from_comment(message) assert response == { "amount": 10000000000000000000000000, "status": 130, "username": "******", "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "subreddit_status": "full", } assert (text.make_response_text( message, response) == "Program minimum is 0.0001 Nano.") # send to an Excluded redditor (i.e. a currency code) message = RedditMessage("t4_5", "rich", "", f"{TIP_COMMANDS[0]} 0.01 USD") response = send_from_comment(message) assert response == { "status": 140, "username": "******", "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "subreddit_status": "full", } assert ( text.make_response_text(message, response) == "It wasn't clear if you were trying to perform a currency conversion or " "not. If so, be sure there is no space between the amount and currency. " "Example: '!ntip 0.5USD'") # subreddit is not tracked message = RedditMessage("t4_5", "rich", "", f"/u/{TIP_BOT_USERNAME} 0.01", subreddit="not_tracked_sub") response = send_from_comment(message) assert response == { "status": 150, "amount": 10000000000000000000000000000, "subreddit_minimum": 1, "username": "******", "subreddit": "not_tracked_sub", "subreddit_status": "untracked", } assert (text.make_response_text( message, response) == "Your tip is below the minimum for an unfamiliar sub.") # send greater than sender balance message = RedditMessage("t4_5", "poor", "", f"{TIP_COMMANDS[0]} 0.01", subreddit="friendly_sub") response = send_from_comment(message) assert response == { "amount": 10000000000000000000000000000, "status": 160, "username": "******", "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "subreddit_status": "full", } assert (text.make_response_text( message, response) == "You have insufficient funds. Please check your balance.") # user is opted out message = RedditMessage( "t4_5", "rich", "", f"{TIP_COMMANDS[0]} 0.01", subreddit="friendly_sub", parent_author="out", ) response = send_from_comment(message) assert response == { "amount": 10000000000000000000000000000, "status": 190, "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "username": "******", "recipient": "out", "subreddit_status": "full", } assert (text.make_response_text( message, response) == "Sorry, the user has opted-out of using Nano Tipper.") # send less than recipient minimum message = RedditMessage( "t4_5", "rich", "", f"{TIP_COMMANDS[0]} 0.01", subreddit="friendly_sub", parent_author="high_min", ) response = send_from_comment(message) assert response == { "amount": 10000000000000000000000000000, "minimum": 100000000000000000000000000000000, "status": 180, "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "subreddit_status": "full", "username": "******", "recipient": "high_min", } assert ( text.make_response_text(message, response) == "Sorry, the user has set a tip minimum of 100.0. Your tip of 0.01 is below this amount." ) # send to new user message = RedditMessage( "t4_5", "rich", "", f"{TIP_COMMANDS[0]} 0.01", subreddit="friendly_sub", parent_author="dne", ) response = send_from_comment(message) assert response == { "amount": 10000000000000000000000000000, "status": 20, "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "subreddit_status": "full", "username": "******", "hash": "success!", "recipient": "dne", } assert ( text.make_response_text(message, response) == "Creating a new account for /u/dne and sending ```0.01 Nano```. [Transac" "tion on Nano Crawler](https://nanocrawler.cc/explorer/block/success!)" ) # check text for minimal message.subreddit = "minimal_sub" response = send_from_comment(message) assert ( text.make_response_text(message, response) == "^(Made a new account and )^[sent](https://nanocrawler.cc/explorer/block" "/success!) ^0.01 ^Nano ^to ^(/u/dne) ^- [^(Nano Tipper)](https://githu" "b.com/danhitchcock/nano_tipper_z)") # send to user message = RedditMessage( "t4_5", "rich", "", f"{TIP_COMMANDS[0]} 0.01", subreddit="friendly_sub", parent_author="poor", ) response = send_from_comment(message) assert response == { "amount": 10000000000000000000000000000, "status": 10, "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "username": "******", "hash": "success!", "recipient": "poor", "subreddit_status": "full", } assert ( text.make_response_text(message, response) == "Sent ```0.01 Nano``` to /u/poor -- [Transaction on Nano Crawler](https" "://nanocrawler.cc/explorer/block/success!)") # minimal text for new user message.subreddit = "minimal_sub" response = send_from_comment(message) assert ( text.make_response_text(message, response) == "^[Sent](https://nanocrawler.cc/explorer/block/success!) ^0.01 ^Nano " "^to ^(/u/poor) ^- [^(Nano Tipper)](https://github.com/danhitchcock/nan" "o_tipper_z)") # send at end of message message = RedditMessage( "t4_5", "rich", "", f"something something {TIP_COMMANDS[0]} 0.01", subreddit="friendly_sub", parent_author="poor", ) response = send_from_comment(message) assert response == { "amount": 10000000000000000000000000000, "status": 10, "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "username": "******", "hash": "success!", "recipient": "poor", "subreddit_status": "full", } assert ( text.make_response_text(message, response) == "Sent ```0.01 Nano``` to /u/poor -- [Transaction on Nano Crawler](https" "://nanocrawler.cc/explorer/block/success!)") # send by username mention message = RedditMessage( "t4_5", "rich", "", f"/u/{TIP_BOT_USERNAME} 0.01", subreddit="friendly_sub", parent_author="poor", ) response = send_from_comment(message) assert response == { "amount": 10000000000000000000000000000, "status": 10, "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "username": "******", "hash": "success!", "recipient": "poor", "subreddit_status": "full", } assert ( text.make_response_text(message, response) == "Sent ```0.01 Nano``` to /u/poor -- [Transaction on Nano Crawler](https" "://nanocrawler.cc/explorer/block/success!)") # send at end of by username mention message = RedditMessage( "t4_5", "rich", "", f"something something /u/{TIP_BOT_USERNAME} 0.01", subreddit="friendly_sub", parent_author="poor", ) response = send_from_comment(message) assert response == { "amount": 10000000000000000000000000000, "status": 10, "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "username": "******", "hash": "success!", "recipient": "poor", "subreddit_status": "full", } assert ( text.make_response_text(message, response) == "Sent ```0.01 Nano``` to /u/poor -- [Transaction on Nano Crawler](https" "://nanocrawler.cc/explorer/block/success!)") # no amount specified message = RedditMessage("t4_5", "rich", "", f"{DONATE_COMMANDS[0]} 1", subreddit="friendly_sub") response = send_from_comment(message) assert response == { "status": 110, "username": "******", "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "subreddit_status": "full", } assert (text.make_response_text( message, response ) == "You must specify an amount and a user, e.g. `send 1 nano_tipper`.") # send to non-existent nanocenter project message = RedditMessage( "t4_5", "rich", "", f"{DONATE_COMMANDS[0]} 0.01 project_does_not_exist", subreddit="friendly_sub", ) response = send_from_comment(message) assert response == { "amount": 10000000000000000000000000000, "recipient": "project_does_not_exist", "status": 210, "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "username": "******", "subreddit_status": "full", } assert (text.make_response_text(message, response) == "No Nanocenter project named project_does_not_exist was found.") # nanocenter project does exist message = RedditMessage( "t4_5", "rich", "", f"{DONATE_COMMANDS[0]} 0.01 project_exists", subreddit="friendly_sub", ) response = send_from_comment(message) assert response == { "amount": 10000000000000000000000000000, "hash": "success!", "status": 40, "subreddit": "friendly_sub", "subreddit_minimum": 0.001, "username": "******", "recipient": "project_exists", "subreddit_status": "full", } assert ( text.make_response_text(message, response) == "Donated ```0.01 Nano``` to Nanocenter Project project_exists -- [Tran" "saction on Nano Crawler](https://nanocrawler.cc/explorer/block/success!)" )
def test_handle_send_from_PM(handle_send_from_message_mocks): """ 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 190 - user has opted out 200 - No Nanocenter Project specified 210 - Nanocenter Project does not exist """ # sender has no account message = RedditMessage("t4_5", "DNE", "", "send 0.01 poor") response = handle_send(message) assert response == {"status": 100, "username": "******"} assert ( text.make_response_text(message, response) == "You don't have an account yet. Please PM me with `create` in the body to make an account." ) # no recipient specified message = RedditMessage("t4_5", "rich", "", "send 0.01") response = handle_send(message) assert response == {"status": 110, "username": "******"} assert (text.make_response_text( message, response ) == "You must specify an amount and a user, e.g. `send 1 nano_tipper`.") # no amount or recipient specified message = RedditMessage("t4_5", "rich", "", "send") response = handle_send(message) assert response == {"status": 110, "username": "******"} assert (text.make_response_text( message, response ) == "You must specify an amount and a user, e.g. `send 1 nano_tipper`.") # could not parse the amount message = RedditMessage("t4_5", "rich", "", "send 0.0sdf1 poor") response = handle_send(message) assert response == { "amount": "0.0sdf1", "status": 120, "username": "******", } assert ( text.make_response_text(message, response) == "I could not read the amount or the currency code. Is '0.0sdf1' a number? This could also mean the currency converter is down." ) # send below sender balance message = RedditMessage("t4_5", "poor", "", "send 0.01 rich") response = handle_send(message) assert response == { "amount": 10000000000000000000000000000, "status": 160, "username": "******", } assert (text.make_response_text( message, response) == "You have insufficient funds. Please check your balance.") # send send to opted out user message = RedditMessage("t4_5", "rich", "", "send 0.01 out") response = handle_send(message) assert response == { "amount": 10000000000000000000000000000, "status": 190, "username": "******", "recipient": "out", } assert (text.make_response_text( message, response) == "Sorry, the user has opted-out of using Nano Tipper.") # send to an Excluded redditor (i.e. a currency code) message = RedditMessage("t4_5", "rich", "", "send 0.01 USD rich") response = handle_send(message) assert response == { "status": 140, "username": "******", } assert ( text.make_response_text(message, response) == "It wasn't clear if you were trying to perform a currency conversion o" "r not. If so, be sure there is no space between the amount and currency. " "Example: '!ntip 0.5USD'") # send below user minimum message = RedditMessage("t4_5", "rich", "", "send 0.01 high_min") response = handle_send(message) assert response == { "amount": 10000000000000000000000000000, "minimum": 100000000000000000000000000000000, "recipient": "high_min", "status": 180, "username": "******", } assert (text.make_response_text( message, response ) == "Sorry, the user has set a tip minimum of 100.0. Your tip of 0.01 is " "below this amount.") # send below program limit message = RedditMessage("t4_5", "rich", "", "send 0.00001 high_min") response = handle_send(message) assert response == { "amount": 10000000000000000000000000, "status": 130, "username": "******", } assert (text.make_response_text( message, response) == "Program minimum is 0.0001 Nano.") # send to invalid address/not a redditor message = RedditMessage("t4_5", "rich", "", "send 0.01 nano_invalid") response = handle_send(message) assert response == { "amount": 10000000000000000000000000000, "recipient": "nano_invalid", "status": 170, "username": "******", } assert (text.make_response_text(message, response) == "'nano_invalid' is neither a redditor nor a valid address.") # send to valid account message = RedditMessage("t4_5", "rich", "", "send 0.01 poor") response = handle_send(message) assert response == { "amount": 10000000000000000000000000000, "recipient": "poor", "status": 10, "username": "******", "hash": "success!", } assert ( text.make_response_text(message, response) == "Sent ```0.01 Nano``` to /u/poor -- [Transaction on Nano Crawler](https:" "//nanocrawler.cc/explorer/block/success!)") # send to new account message = RedditMessage("t4_5", "rich", "", "send 0.01 DNE") response = handle_send(message) assert response == { "amount": 10000000000000000000000000000, "recipient": "dne", "status": 20, "username": "******", "hash": "success!", } assert ( text.make_response_text(message, response) == "Creating a new account for /u/dne and sending ```0.01 Nano```. [Transac" "tion on Nano Crawler](https://nanocrawler.cc/explorer/block/success!)" ) # send to valid address message = RedditMessage("t4_5", "rich", "", "send 0.01 nano_valid") response = handle_send(message) assert response == { "amount": 10000000000000000000000000000, "recipient": "nano_valid", "status": 30, "username": "******", "hash": "success!", } assert ( text.make_response_text(message, response) == "Sent ```0.01 Nano``` to address nano_valid -- [Transaction on Nano Cra" "wler](https://nanocrawler.cc/explorer/block/success!)")
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)