Exemplo n.º 1
0
    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...")
Exemplo n.º 2
0
    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...")
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
 def update_config(self, option, value):
     try:
         self.botserver.set_config_option(option, value)
     except InvalidConsoleCommand as e:
         log.error(e)
Exemplo n.º 5
0
    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))