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 init_savelink_config(): """Initialize the Save handler configuration""" try: with open("./config/config_savelink.json") as f: conf = json.load(f) return conf, True except (IOError, FileNotFoundError) as e: log.info("Save handler configuration couldn't be loaded: %s.", e) return None, False
def init_solvetracker_config(): """Initialize the SolveTracker configuration or disable SolveTracker support if config file doesn't exist.""" try: with open("./config/config_solvetracker.json") as f: return json.load(f), True except (IOError, FileNotFoundError) as e: log.info( "Solvetracker configuration couldn't be loaded: %s. Deactivating SolveTracker...", e) return None, False
def init_bot_data(self): """ Fetches the bot user information such as bot_name, bot_id and bot_at. """ log.debug("Resolving bot user in slack") self.bot_name = self.slack_wrapper.username self.bot_id = self.slack_wrapper.user_id self.bot_at = "<@{}>".format(self.bot_id) log.debug("Found bot user %s (%s)", self.bot_name, self.bot_id) self.running = True # Might even pass the bot server for handlers? log.info("Initializing handlers...") handler_factory.initialize(self.slack_wrapper, self)
def set_config_option(self, option, value): """Set configuration option.""" self.lock() try: if option in self.config: self.config[option] = value log.info("Updated configuration: %s => %s", option, value) with open("./config/config.json", "w") as f: json.dump(self.config, f) else: raise InvalidConsoleCommand( "The specified configuration option doesn't exist: {}". format(option)) finally: self.release()
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 quit(self): """Inform the application that it is quitting.""" log.info("Shutting down") self.running = False
def start_services(self): for service in enabled_services: log.info("[Services] Enabling {}".format(service.__name__)) s = service(self, self.slack_wrapper) self.service_stack.append(s) s.start()
#!/usr/bin/env python3 from util.loghandler import log from server.botserver import BotServer if __name__ == "__main__": log.info("Initializing threads...") server = BotServer() server.start() # Server should be up and running. Quit when server shuts down server.join() log.info("Server has shut down. Quit")
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))
def register(handler_name, handler): log.info("Registering new handler: %s (%s)", handler_name, handler.__class__.__name__) handlers[handler_name] = handler handler.handler_name = handler_name