def uncaught_exception(exctype, value, tb): delta = datetime.utcnow() - GlobalVars.startup_utc_date log_exception(exctype, value, tb) if delta.total_seconds() < 180 and exctype not in \ {KeyboardInterrupt, SystemExit, requests.ConnectionError, WebSocketConnectionClosedException}: exit_mode("early_exception") else: exit_mode("restart")
def prepare_git_for_operation(blacklist_file_name): try: git.checkout('master') git.remote.update() git.reset('--hard', 'origin/master') except GitError as e: if GlobalVars.on_windows: return False, "Not doing this, we're on Windows." log_exception(*sys.exc_info()) return False, "`git pull` has failed. This shouldn't happen. Details have been logged." if GlobalVars.on_windows: remote_ref = git.rev_parse("refs/remotes/origin/master").strip() local_ref = git.rev_parse("master").strip() else: remote_ref = git("rev-parse", "refs/remotes/origin/master").strip() local_ref = git("rev-parse", "master").strip() if local_ref != remote_ref: local_log = git.log(r"--pretty=`[%h]` *%cn*: %s", "-1", str(local_ref)).strip() remote_log = git.log(r"--pretty=`[%h]` *%cn*: %s", "-1", str(remote_ref)).strip() return False, "HEAD isn't at tip of origin's master branch (local {}, remote {})".format( local_log, remote_log) return True, None
def add_to_blacklist(cls, blacklist='', item_to_blacklist='', username='', chat_profile_link='', code_permissions=False, metasmoke_down=False): if git.config("--get", "user.name", _ok_code=[0, 1]) == "": return (False, 'Tell someone to run `git config user.name "SmokeDetector"`') if git.config("--get", "user.email", _ok_code=[0, 1]) == "": return (False, 'Tell someone to run `git config user.email "*****@*****.**"`') if blacklist == "": return (False, 'GitManager: blacklist is not defined. Blame a developer.') if item_to_blacklist == "": return (False, 'GitManager: item_to_blacklist is not defined. Blame a developer.') # item_to_blacklist = item_to_blacklist.replace("\\s", " ") if blacklist == "website": blacklist_type = Blacklist.WEBSITES ms_search_option = "&body_is_regex=1&body=" elif blacklist == "keyword": blacklist_type = Blacklist.KEYWORDS ms_search_option = "&body_is_regex=1&body=" elif blacklist == "username": blacklist_type = Blacklist.USERNAMES ms_search_option = "&username_is_regex=1&username="******"number": blacklist_type = Blacklist.NUMBERS ms_search_option = "&body=" elif blacklist == "watch_keyword": blacklist_type = Blacklist.WATCHED_KEYWORDS ms_search_option = "&body_is_regex=1&body=" elif blacklist == "watch_number": blacklist_type = Blacklist.WATCHED_NUMBERS ms_search_option = "&body=" else: return (False, 'GitManager: blacklist is not recognized. Blame a developer.') blacklister = Blacklist(blacklist_type) blacklist_file_name = blacklist_type[0] try: cls.gitmanager_lock.acquire() status, message = cls.prepare_git_for_operation(blacklist_file_name) if not status: return (False, message) now = str(int(time.time())) if blacklist_type in {Blacklist.WATCHED_KEYWORDS, Blacklist.WATCHED_NUMBERS}: op = 'watch' item = item_to_blacklist item_to_blacklist = "\t".join([now, username, item]) else: op = 'blacklist' item = item_to_blacklist exists, line = blacklister.exists(item_to_blacklist) if exists: return (False, 'Already {}ed on line {} of {}'.format(op, line, blacklist_file_name)) watch_removed = False if blacklist_type not in {Blacklist.WATCHED_KEYWORDS, Blacklist.WATCHED_NUMBERS}: for watcher_type in {Blacklist.WATCHED_KEYWORDS, Blacklist.WATCHED_NUMBERS}: watcher = Blacklist(watcher_type) if watcher.exists(item_to_blacklist): watch_removed = True watcher.remove(item_to_blacklist) blacklister.add(item_to_blacklist) branch = "auto-blacklist-{0}".format(now) git.checkout("-b", branch) git.reset("HEAD") git.add(blacklist_file_name) if watch_removed: git.add('watched_keywords.txt', 'watched_numbers.txt') git.commit("--author='SmokeDetector <*****@*****.**>'", "-m", "Auto {0} of `{1}` by {2}".format(op, item, username)) if code_permissions: git.checkout("master") git.merge(branch) git.push("origin", "master") git.branch('-D', branch) # Delete the branch in the local git tree since we're done with it. else: git.push("origin", branch) git.checkout("master") if GlobalVars.github_username is None or GlobalVars.github_password is None: return (False, "Tell someone to set a GH password") payload = {"title": "{0}: {1} {2}".format(username, op.title(), item), "body": "[{0}]({1}) requests the {2} of the {3} `{4}`. See the MS search [here]" "(https://metasmoke.erwaysoftware.com/search?utf8=%E2%9C%93{5}{6}) and the " "Stack Exchange search [here](https://stackexchange.com/search?q=%22{7}%22).\n" "<!-- METASMOKE-BLACKLIST-{8} {4} -->".format( username, chat_profile_link, op, blacklist, # 0 1 2 3 item, ms_search_option, # 4 5 quote_plus(item), # 6 quote_plus(item.replace("\\W", " ").replace("\\.", ".")), # 7 blacklist.upper()), # 8 "head": branch, "base": "master"} response = GitHubManager.create_pull_request(payload) log('debug', response) try: git.checkout("deploy") # Return to deploy, pending the accept of the PR in Master. git.branch('-D', branch) # Delete the branch in the local git tree since we're done with it. url, pr_num = response["html_url"], response["number"] if metasmoke_down: return (True, "MS is not reachable, so I can't see if you have code privileges, but I've " "[created PR#{1} for you]({0}).".format( url, pr_num)) else: return (True, "You don't have code privileges, but I've [created PR#{1} for you]({0}).".format( url, pr_num)) except KeyError: git.checkout("deploy") # Return to deploy try: # Delete the branch in the local git tree, we'll create it again if the # command is run again. This way, we keep things a little more clean in # the local git tree git.branch('-D', branch) except GitError: # It's OK if the branch doesn't get deleted, so long as we switch back to # deploy, which we do in the finally block... pass # Error capture/checking for any "invalid" GH reply without an 'html_url' item, # which will throw a KeyError. if "bad credentials" in str(response['message']).lower(): # Capture the case when GH credentials are bad or invalid return (False, "Something is wrong with the GH credentials, tell someone to check them.") else: # Capture any other invalid response cases. return (False, "A bad or invalid reply was received from GH, the message was: %s" % response['message']) except Exception as err: log_exception(*sys.exc_info()) return (False, "Git functions failed for unspecified reasons, details may be in error log.") finally: # Always return to `deploy` branch when done with anything. git.checkout("deploy") cls.gitmanager_lock.release() if op == 'blacklist': return (True, "Blacklisted `{0}`".format(item)) elif op == 'watch': return (True, "Added `{0}` to watchlist".format(item))
def remove_from_blacklist(cls, item, username, blacklist_type="", code_privileged=False, metasmoke_down=False): if not code_privileged: if metasmoke_down: return False, "MS is offline, and I can't determine if you are a code admin or not. " \ "If you are a code admin, then wait for MS to be back up before running this command." else: return False, "Ask a code admin to run that for you. Use `!!/whois code_admin` to find out who's here." try: cls.gitmanager_lock.acquire() git.checkout("master") if blacklist_type == "watch": blacklists = [Blacklist.WATCHED_KEYWORDS, Blacklist.WATCHED_NUMBERS] list_type = "watchlist" elif blacklist_type == "blacklist": blacklists = [Blacklist.KEYWORDS, Blacklist.WEBSITES, Blacklist.USERNAMES, Blacklist.NUMBERS] list_type = "blacklist" else: return False, "`blacklist_type` not set, blame a developer." for blacklist in blacklists: file_name = blacklist[0] manager = Blacklist(blacklist) exists, _line = manager.exists(item) if exists: break if not exists: return False, 'No such item `{}` in {}.'.format(item, list_type) status, message = cls.prepare_git_for_operation(file_name) if not status: return False, message branch = 'auto-un{}-{}'.format(blacklist_type, time.time()) git.checkout('-b', branch) git.reset('HEAD') manager.remove(item) git.add(file_name) git.commit("--author='SmokeDetector <*****@*****.**>'", '-m', 'Auto un{} of `{}` by {}'.format(blacklist_type, item, username)) git.checkout('master') git.merge(branch) git.push('origin', 'master') try: git.branch('-D', branch) except GitError: # It's OK if the branch doesn't get deleted, so long as we switch back to # deploy, which we do in the finally block... pass except Exception as e: log('error', '{}: {}'.format(type(e).__name__, e)) log_exception(*sys.exc_info()) return False, 'Git operations failed for unspecified reasons.' finally: git.checkout('deploy') cls.gitmanager_lock.release() # With no exception raised, list_type should be set return True, 'Removed `{}` from {}'.format(item, list_type)
def remove_from_blacklist(cls, item, username, blacklist_type="", code_privileged=False, metasmoke_down=False): if not code_privileged: if metasmoke_down: return False, "MS is offline, and I can't determine if you are a blacklist manager or not. " \ "If you are a blacklist manager, then wait for MS to be back up before running " \ "this command." else: return False, "Ask a blacklist manager to run that for you. Use `!!/whois blacklister` to find " \ "out who's here." try: cls.gitmanager_lock.acquire() git.checkout("master") if blacklist_type == "watch": blacklists = [ Blacklist.WATCHED_KEYWORDS, Blacklist.WATCHED_NUMBERS ] list_type = "watchlist" elif blacklist_type == "blacklist": blacklists = [ Blacklist.KEYWORDS, Blacklist.WEBSITES, Blacklist.USERNAMES, Blacklist.NUMBERS ] list_type = "blacklist" else: return False, "`blacklist_type` not set, blame a developer." for blacklist in blacklists: file_name = blacklist[0] manager = Blacklist(blacklist) exists, _line = manager.exists(item) if exists: break if not exists: return False, 'No such item `{}` in {}.'.format( item, list_type) status, message = cls.prepare_git_for_operation(file_name) if not status: return False, message branch = 'auto-un{}-{}'.format(blacklist_type, time.time()) git.checkout('-b', branch) git.reset('HEAD') manager.remove(item) git.add(file_name) git( "-c", "user.name=" + GlobalVars.git_name, "-c", "user.email=" + GlobalVars.git_email, "commit", "--author={} <{}>".format(GlobalVars.git_name, GlobalVars.git_email), '-m', 'Auto un{} of `{}` by {}'.format(blacklist_type, item, username)) git.checkout('master') git.merge(branch) origin_or_auth = cls.get_origin_or_auth() git.push(origin_or_auth, 'master') try: git.branch('-D', branch) except GitError: # It's OK if the branch doesn't get deleted, so long as we switch back to # deploy, which we do in the finally block... pass except Exception as e: log('error', '{}: {}'.format(type(e).__name__, e)) log_exception(*sys.exc_info()) return False, 'Git operations failed for unspecified reasons.' finally: git.checkout('deploy') cls.gitmanager_lock.release() # With no exception raised, list_type should be set return True, 'Removed `{}` from {}'.format(item, list_type)
target=GlobalVars.bodyfetcher.add_to_queue, args=(a, True if is_spam else None)) t.start() except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() now = datetime.utcnow() delta = now - GlobalVars.startup_utc_date seconds = delta.total_seconds() tr = traceback.format_exc() exception_only = ''.join(traceback.format_exception_only(type(e), e))\ .strip() n = os.linesep logged_msg = str(now) + " UTC" + n + exception_only + n + tr + n + n log('error', logged_msg) log_exception(exc_type, exc_obj, exc_tb) if seconds < 180 and exc_type not in { websocket.WebSocketConnectionClosedException, requests.ConnectionError }: # noinspection PyProtectedMember exit_mode("early_exception") ws = init_se_websocket_or_reboot(MAX_SE_WEBSOCKET_RETRIES, tell_debug_room_on_error=True) chatcommunicate.tell_rooms_with( "debug", "Recovered from `" + exception_only + "`") while GlobalVars.no_se_activity_scan: # Sleep for longer than the automatic restart time.sleep(30000)
def add_to_blacklist(cls, blacklist='', item_to_blacklist='', username='', chat_profile_link='', code_permissions=False, metasmoke_down=False): if blacklist == "": return (False, 'GitManager: blacklist is not defined. Blame a developer.') if item_to_blacklist == "": return ( False, 'GitManager: item_to_blacklist is not defined. Blame a developer.' ) # item_to_blacklist = item_to_blacklist.replace("\\s", " ") if blacklist == "website": blacklist_type = Blacklist.WEBSITES ms_search_option = "&body_is_regex=1&body=" elif blacklist == "keyword": blacklist_type = Blacklist.KEYWORDS ms_search_option = "&body_is_regex=1&body=" elif blacklist == "username": blacklist_type = Blacklist.USERNAMES ms_search_option = "&username_is_regex=1&username="******"number": blacklist_type = Blacklist.NUMBERS ms_search_option = "&body=" elif blacklist == "watch_keyword": blacklist_type = Blacklist.WATCHED_KEYWORDS ms_search_option = "&body_is_regex=1&body=" elif blacklist == "watch_number": blacklist_type = Blacklist.WATCHED_NUMBERS ms_search_option = "&body=" else: return ( False, 'GitManager: blacklist is not recognized. Blame a developer.') blacklister = Blacklist(blacklist_type) blacklist_file_name = blacklist_type[0] try: cls.gitmanager_lock.acquire() status, message = cls.prepare_git_for_operation( blacklist_file_name) if not status: return (False, message) now = str(int(time.time())) if blacklist_type in { Blacklist.WATCHED_KEYWORDS, Blacklist.WATCHED_NUMBERS }: op = 'watch' item = item_to_blacklist item_to_blacklist = "\t".join([now, username, item]) else: op = 'blacklist' item = item_to_blacklist exists, line = blacklister.exists(item_to_blacklist) if exists: return (False, 'Already {}ed on line {} of {}'.format( op, line, blacklist_file_name)) watch_removed = False if blacklist_type not in { Blacklist.WATCHED_KEYWORDS, Blacklist.WATCHED_NUMBERS }: for watcher_type in { Blacklist.WATCHED_KEYWORDS, Blacklist.WATCHED_NUMBERS }: watcher = Blacklist(watcher_type) if watcher.exists(item_to_blacklist): watch_removed = True watcher.remove(item_to_blacklist) blacklister.add(item_to_blacklist) branch = "auto-blacklist-{0}".format(now) git.checkout("-b", branch) git.reset("HEAD") git.add(blacklist_file_name) if watch_removed: git.add('watched_keywords.txt', 'watched_numbers.txt') git( "-c", "user.name=" + GlobalVars.git_name, "-c", "user.email=" + GlobalVars.git_email, "commit", "--author={} <{}>".format(GlobalVars.git_name, GlobalVars.git_email), "-m", "Auto {0} of `{1}` by {2}".format(op, item, username)) origin_or_auth = cls.get_origin_or_auth() if code_permissions: git.checkout("master") git.merge(branch) git.push(origin_or_auth, "master") git.branch( '-D', branch ) # Delete the branch in the local git tree since we're done with it. else: git.push(origin_or_auth, branch) git.checkout("master") if ((GlobalVars.github_username is None or GlobalVars.github_password is None) and (GlobalVars.github_access_token is None)): return (False, "Tell someone to set a GH token") payload = { "title": "{0}: {1} {2}".format(username, op.title(), item), "body": "[{0}]({1}) requests the {2} of the {3} `{4}`. See the MS search [here]" "(https://metasmoke.erwaysoftware.com/search?utf8=%E2%9C%93{5}{6}) and the " "Stack Exchange search [in text](https://stackexchange.com/search?q=%22{7}%22)" ", [in URLs](https://stackexchange.com/search?q=url%3A%22{7}%22)" ", and [in code](https://stackexchange.com/search?q=code%3A%22{7}%22)" ".\n" "<!-- METASMOKE-BLACKLIST-{8} {4} -->".format( username, chat_profile_link, op, blacklist, # 0 1 2 3 item, ms_search_option, # 4 5 quote_plus(_anchor(item, blacklist_type)), # 6 quote_plus( item.replace("\\W", " ").replace("\\.", ".")), # 7 blacklist.upper()), # 8 "head": branch, "base": "master" } response = GitHubManager.create_pull_request(payload) log('debug', response) try: git.checkout( "deploy" ) # Return to deploy, pending the accept of the PR in Master. git.branch( '-D', branch ) # Delete the branch in the local git tree since we're done with it. url, pr_num = response["html_url"], response["number"] if metasmoke_down: return ( True, "MS is not reachable, so I can't see if you have blacklist manager privileges, but " "I've [created PR#{1} for you]({0}).{2}".format( url, pr_num, GitHubManager.still_using_usernames_nudge)) else: return (True, "You don't have blacklist manager privileges, " "but I've [created PR#{1} for you]({0}).{2}". format( url, pr_num, GitHubManager.still_using_usernames_nudge)) except KeyError: git.checkout("deploy") # Return to deploy try: # Delete the branch in the local git tree, we'll create it again if the # command is run again. This way, we keep things a little more clean in # the local git tree git.branch('-D', branch) except GitError: # It's OK if the branch doesn't get deleted, so long as we switch back to # deploy, which we do in the finally block... pass # Error capture/checking for any "invalid" GH reply without an 'html_url' item, # which will throw a KeyError. if "bad credentials" in str(response['message']).lower(): # Capture the case when GH credentials are bad or invalid return ( False, "Something is wrong with the GH credentials, tell someone to check them." ) else: # Capture any other invalid response cases. return ( False, "A bad or invalid reply was received from GH, the message was: %s" % response['message']) except Exception as err: log_exception(*sys.exc_info()) return ( False, "Git functions failed for unspecified reasons, details may be in error log." ) finally: # Always return to `deploy` branch when done with anything. git.checkout("deploy") cls.gitmanager_lock.release() if op == 'blacklist': return (True, "Blacklisted `{0}`".format(item)) elif op == 'watch': return (True, "Added `{0}` to watchlist".format(item))
if GlobalVars.flovis is not None: data = json.loads(json.loads(a)['data']) GlobalVars.flovis.stage('received', data['siteBaseHostAddress'], data['id'], json.loads(a)) is_spam, reason, why = check_if_spam_json(a) t = Thread(name="bodyfetcher post enqueing", target=GlobalVars.bodyfetcher.add_to_queue, args=(a, True if is_spam else None)) t.start() except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() now = datetime.utcnow() delta = now - GlobalVars.startup_utc_date seconds = delta.total_seconds() tr = traceback.format_exc() exception_only = ''.join(traceback.format_exception_only(type(e), e))\ .strip() n = os.linesep logged_msg = str(now) + " UTC" + n + exception_only + n + tr + n + n log('error', logged_msg) log_exception(exc_type, exc_obj, exc_tb) if seconds < 180 and exc_type not in {websocket.WebSocketConnectionClosedException, requests.ConnectionError}: # noinspection PyProtectedMember exit_mode("early_exception") ws = websocket.create_connection("ws://qa.sockets.stackexchange.com/") ws.send("155-questions-active") chatcommunicate.tell_rooms_with("debug", "Recovered from `" + exception_only + "`")
"user-level installed. Skipping TLD names update. \n" if "/home/" in strerror and ".local/lib/python" in strerror and "/site-packages/tld/" in strerror: err_msg = "WARNING: Cannot read/write to user-space `tld` installation, check permissions on the " \ "path. Skipping TLD names update. \n" else: err_msg = strerror elif "certificate verify failed" in strerror.lower(): # Ran into this error in testing on Windows, best to throw a warn if we get this... err_msg = "WARNING: Cannot verify SSL connection for TLD names update; skipping TLD names update." else: err_msg = strerror log_exception(type(ioerr), ioerr, err_msg, True, level="warning") if "ChatExchangeU" in os.environ: log('debug', "ChatExchange username loaded from environment") username = os.environ["ChatExchangeU"] elif GlobalVars.chatexchange_u: log('debug', "ChatExchange username loaded from config") username = GlobalVars.chatexchange_u else: log( 'error', "No ChatExchange username provided. Set it in config or provide it via environment variable" ) exit_mode("shutdown") if "ChatExchangeP" in os.environ:
def on_message(message, client): global shutdown if not isinstance(message, chatexchange.events.MessagePosted): # Ignore non-message_posted events. return is_shiro = (message.user.id == my_user.id) is_super_user = (is_shiro or message.user.id == 200996 or message.user.is_moderator) is_trusted_user = (is_super_user or message.user.id in TRUSTED_USER_IDS) #print("") #print(">> (%s / %s) %s" % (message.user.name, repr(message.user.id), message.content)) try: pat = re.compile("\s*<b>(.*)</b>\s*", re.IGNORECASE) m = re.match(pat, message.content) if m is not None: guess = m.groups()[0].strip().lower() if guess in passphrases: show_board() else: guessed.append(guess) if is_shiro and message.content.strip().startswith("<b>RED</b>:"): pin_red(message.message) if is_shiro and message.content.strip().startswith("<b>BLUE</b>:"): pin_blue(message.message) if is_trusted_user and message.content.lower().strip() == "!teams": show_teams() if is_trusted_user and message.content.lower().strip() == "!board": show_board() if is_trusted_user and message.content.lower().strip() == "!undo": guessed.pop() if is_trusted_user and message.content.lower().strip() == "!flipcoin": flip_coin() if is_trusted_user and message.content.lower().strip() == "!blame": blame() if is_trusted_user and message.content.lower().strip() == "!recall": recall() if is_trusted_user and message.content.lower().startswith("!join"): add_user(message.content, message.user.name) elif message.content.lower().strip() == "!join": add_user(message.content, message.user.name) if is_trusted_user and message.content.lower().startswith("!leave"): remove_user(message.content, message.user.name) elif message.content.lower().strip() == "!leave": remove_user(message.content, message.user.name) if is_trusted_user and message.content.lower().startswith("!newgame"): new_game(message.content) if is_super_user and message.content.lower().startswith("!whitelist"): add_whitelist(message.content) if is_trusted_user and message.content.lower().strip( ) == "!finalboard": show_final() if is_super_user and message.content.lower().startswith("!imagehost"): change_host(message.content) if is_trusted_user and message.content.lower().startswith("!seed"): try: new_seed = message.content[6:] init(new_seed) show_board() except: pass if is_super_user and message.content.lower().strip() == "!shutdown": shutdown = True if is_super_user and message.content.lower().strip() == "!ping": ping() if message.content.lower().strip() == "!help": info() if is_trusted_user and message.content.lower().strip() == "!pingable": add_pinglist(message.content, message.user.name.replace(" ", "")) elif is_super_user and message.content.lower().startswith("!pingable"): add_pinglist(message.content) if is_trusted_user and message.content.lower().strip( ) == "!notpingable": remove_pinglist(message.content, message.user.name.replace(" ", "")) elif is_super_user and message.content.lower().startswith( "!notpingable"): remove_pinglist(message.content) if is_trusted_user and message.content.lower().startswith("!pinglist"): pinglist() except: log_exception(*sys.exc_info())
def on_message(message, client): global shutdown, whose_turn, num_guesses, red, blue if not isinstance(message, chatexchange.events.MessagePosted): # Ignore non-message_posted events. return is_shiro = (message.user.id == my_user.id) is_super_user = (is_shiro or message.user.id == 200996 or message.user.is_moderator) is_trusted_user = (is_super_user or message.user.id in TRUSTED_USER_IDS) #print("") #print(">> (%s / %s) %s" % (message.user.name, repr(message.user.id), message.content)) try: clue_pattern = re.compile( r"(?:Red|Blue): <b>.+(?:</b>)?\s*\((\d+|unlimited|\u221e)\)(?:</b>)?", re.IGNORECASE) #Strange things happening with this pattern clue_match = re.match(clue_pattern, message.content) if not is_shiro and clue_match is not None and ( (whose_turn == "SMRed" and message.user.name == red[0]) or (whose_turn == "SMBlue" and message.user.name == blue[0])): clue = clue_match.groups()[0].strip().lower() #print("Matched clue: %s" % (clue)) if clue.isdigit() and int(clue) > 0: num_guesses = int(clue) + 1 else: num_guesses = 100 toggle_turn() #print("num guesses: %s" % (num_guesses)) pat = re.compile(r"\s*<b>(.*)</b>\s*", re.IGNORECASE) guess_match = re.match(pat, message.content) if not is_shiro and guess_match is not None and ( (whose_turn == "Red" and message.user.name in red[1:]) or (whose_turn == "Blue" and message.user.name in blue[1:])): guess = guess_match.groups()[0].strip().lower() if guess in passphrases: show_board() toggle_turn() else: process_guess(guess.upper()) if is_shiro and message.content.strip().startswith("<b>RED</b>:"): pin_red(message.message) if is_shiro and message.content.strip().startswith("<b>BLUE</b>:"): pin_blue(message.message) if is_trusted_user and message.content.lower().strip() == "!teams": show_teams() if is_trusted_user and message.content.lower().strip() == "!board": show_board() if is_trusted_user and message.content.lower().strip() == "!flipcoin": flip_coin() if is_trusted_user and message.content.lower().strip() == "!blame": blame() if is_trusted_user and message.content.lower().strip() == "!recall": recall() if is_trusted_user and message.content.lower().startswith("!join"): add_user(message.content, message.user.name) elif message.content.lower().strip() == "!join": add_user(message.content, message.user.name) if is_trusted_user and message.content.lower().startswith("!leave"): remove_user(message.content, message.user.name) elif message.content.lower().strip() == "!leave": remove_user(message.content, message.user.name) if is_trusted_user and message.content.lower().startswith("!newgame"): new_game(message.content) if is_super_user and message.content.lower().startswith("!whitelist"): add_whitelist(message.content) if is_trusted_user and message.content.lower().strip( ) == "!finalboard": show_final() if is_super_user and message.content.lower().startswith("!imagehost"): change_host(message.content) if is_trusted_user and message.content.lower().startswith("!seed"): try: new_seed = message.content[6:] init(new_seed) show_board() except: pass if is_super_user and message.content.lower().strip() == "!shutdown": shutdown = True if is_super_user and message.content.lower().strip() == "!ping": ping() if message.content.lower().strip() == "!help": info() if is_trusted_user and message.content.lower().strip() == "!pingable": add_pinglist(message.content, message.user.name.replace(" ", "")) elif is_super_user and message.content.lower().startswith("!pingable"): add_pinglist(message.content) if is_trusted_user and message.content.lower().strip( ) == "!notpingable": remove_pinglist(message.content, message.user.name.replace(" ", "")) elif is_super_user and message.content.lower().startswith( "!notpingable"): remove_pinglist(message.content) if is_trusted_user and message.content.lower().startswith("!pinglist"): pinglist() if is_trusted_user and (message.content.lower().startswith("!who") or message.content.lower().strip() == "!guesses"): #print(whose_turn) if whose_turn == "Red" or whose_turn == "Blue": room.send_message( "%s currently has %s guesses remaining." % (whose_turn, num_guesses if num_guesses < 25 else "unlimited")) elif whose_turn[:2] == "SM": room.send_message( "We are currently waiting for a clue from the %s spymaster." % (whose_turn[2:])) except: log_exception(*sys.exc_info())