def run(self): log.info("Starting server thread...") self.running = True self.load_config() self.slack_wrapper = SlackWrapper(self.get_config_option("api_key")) self.start_services() while self.running: try: if self.slack_wrapper.connected: log.info("Connection successful...") self.load_bot_data() read_websocket_delay = 1 # 1 second delay between reading from firehose # Might even pass the bot server for handlers? log.info("Initializing handlers...") handler_factory.initialize(self.slack_wrapper, self) # Main loop log.info("Bot is running...") while self.running: message = self.slack_wrapper.read() if message: reaction, channel, ts, reaction_user = self.parse_slack_reaction( message) if reaction: log.debug("Received reaction : {} ({})".format( reaction, channel)) handler_factory.process_reaction( self.slack_wrapper, reaction, ts, channel, reaction_user) command, channel, user = self.parse_slack_message( message) if command: log.debug( "Received bot command : {} ({})".format( command, channel)) handler_factory.process( self.slack_wrapper, command, channel, user) time.sleep(read_websocket_delay) else: log.error( "Connection failed. Invalid slack token or bot id?") self.running = False except websocket._exceptions.WebSocketConnectionClosedException: log.exception("Web socket error. Executing reconnect...") except SlackConnectionError: # Try to reconnect if slackclient auto_reconnect didn't work out. Keep an eye on the logfiles, # and remove the superfluous exception handling if auto_reconnect works. log.exception( "Slack connection error. Trying manual reconnect in 5 seconds..." ) time.sleep(5) self.stop_services() log.info("Shutdown complete...")
def run(self): log.info("Starting server thread...") self.running = True while self.running: try: self.load_config() self.slack_wrapper = SlackWrapper( self.get_config_option("api_key")) if self.slack_wrapper.connected: log.info("Connection successful...") self.init_bot_data() # Main loop log.info("Bot is running...") while self.running: message = self.slack_wrapper.read() if message: self.handle_message(message) time.sleep(self.read_websocket_delay) else: log.error( "Connection failed. Invalid slack token or bot id?") self.running = False except websocket._exceptions.WebSocketConnectionClosedException: log.exception("Web socket error. Executing reconnect...") except SlackConnectionError: # Try to reconnect if slackclient auto_reconnect didn't work out. Keep an eye on the logfiles, # and remove the superfluous exception handling if auto_reconnect works. log.exception( "Slack connection error. Trying manual reconnect in 5 seconds..." ) time.sleep(5) except: log.exception("Unhandled error. Try reconnect...") time.sleep(5) log.info("Shutdown complete...")
def execute(cls, slack_wrapper, args, timestamp, channel_id, user_id, user_is_admin): """Execute the save command.""" if not LINKSAVE_SUPPORT: raise InvalidCommand( "Save Link failed: Link saver not configured.") if args[0] not in CATEGORIES: raise InvalidCommand("Save Link failed: Invalid Category.") if LINKSAVE_CONFIG["allowed_users"] and user_id not in LINKSAVE_CONFIG[ "allowed_users"]: raise InvalidCommand( "Save Link failed: User not allowed to save links") message = slack_wrapper.get_message(channel_id, timestamp)["messages"][0]["text"] profile_details = slack_wrapper.get_member(user_id)["user"]["profile"] # http://www.noah.org/wiki/RegEx_Python#URL_regex_pattern url_regex = "http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+" url = re.search(url_regex, message) if not url: slack_wrapper.post_message( channel_id, "Save Link failed: Unable to extract URL", timestamp) return try: url_data = unfurl(url.group()) except requests.exceptions.Timeout as e: slack_wrapper.post_message(channel_id, "Save Link failed: Request timed out", timestamp) log.error(e) return data = { "options[staticman-token]": LINKSAVE_CONFIG["staticman-token"], "fields[title]": url_data["title"], "fields[link]": url.group(), "fields[excerpt]": url_data["desc"], "fields[category]": args[0], "fields[header][overlay_image]": url_data["img"], "fields[user]": profile_details["display_name"] or profile_details["real_name"] } resp = requests.post( "https://mystaticmanapp.herokuapp.com/v2/entry/{git_repo}/{git_branch}/links" .format_map(LINKSAVE_CONFIG), data=data).json() if resp["success"]: slack_wrapper.post_message(channel_id, "Link saved successfully", timestamp) else: slack_wrapper.post_message(channel_id, "Error saving the link", timestamp) log.error(resp)
def update_config(self, option, value): try: self.botserver.set_config_option(option, value) except InvalidConsoleCommand as e: log.error(e)
def run(self): position_found = None old_position = -1 position_changed = False points_found = -1 add_id = 0 lookup_add = "" while position_found is None and add_id < 100: quote_page = 'https://ctftime.org/stats/{}'.format(lookup_add) # This useragent needs to be randomish otherwise we get 403'd page = requests.get(quote_page, headers={'User-Agent': "Otters inc."}) soup = BeautifulSoup(page.text, 'html.parser') data = [] table = soup.find('table', attrs={'class': 'table table-striped'}) rows = table.find_all('tr') for row in rows: cols = row.find_all('td') cols = [ele.text.strip() for ele in cols] data.append([ele for ele in cols if ele]) if os.path.isfile(self.position_filename): with open(self.position_filename, 'r') as f: old_position = int(f.read().replace('\n', '')) for l in data: if len(l) > 1 and l[1] == self.team_name: position_found = int(l[0]) points_found = float(l[2]) if position_found is not None: break add_id += 1 lookup_add = "2019?page={}".format(add_id) if position_found is None: log.error("Cannot find position in first 100 pages!") return if old_position != position_found: position_changed = True with open(self.position_filename, "w") as f: f.write(str(position_found)) ts = datetime.datetime.fromtimestamp( time.time()).strftime('%Y-%m-%d %H:%M:%S') if not position_changed: log.info("{} : Nothing changed, staying quiet".format(ts)) return message = u"*------- 🚨 CTFTIME ALERT 🚨 -------*\n\n@channel\n" \ "*We moved from position {} to {} in the world! 🌍🌍🌍🌍🌍" \ "*\n\n*We have {} points*\n\n" \ "https://ctftime.org/stats/{}".format(old_position, position_found, points_found, lookup_add) self.slack_wrapper.post_message(self.post_channel_id, message) log.info("{} : sent update".format(ts))