Пример #1
0
    def get_stats(self):
        dayago = self.now - 86400

        channel_message_counts = {}
        user_message_counts = {}
        for channel in self.slacker.channels_by_name:
            if ignore_channel(self.config, channel):
                self.logger.debug(
                    "Not checking stats for channel: #%s because it's in ignore_channels",
                    channel)
                continue

            cid = self.slacker.get_channelid(channel)
            cur_messages = self.slacker.get_messages_in_time_range(
                dayago, cid, self.now)

            channel_message_counts[channel] = len(cur_messages)

            for message in cur_messages:
                if message.get('user'):
                    user_name = self.slacker.users_by_id[message['user']]
                    if not self.config.stats_ignore_users or not user_name in self.config.stats_ignore_users:
                        if user_message_counts.get(user_name):
                            user_message_counts[
                                user_name] = user_message_counts[user_name] + 1
                        else:
                            user_message_counts[user_name] = 1

        return channel_message_counts, user_message_counts
Пример #2
0
    def warn_all(self, days, force_warn=False):
        """Warn all channels which are `days` idle; if `force_warn`, will warn even if we already have."""
        if not self.config.activated:
            self.logger.info(
                "Note, destalinator is not activated and is in a dry-run mode. For help, see the "
                "documentation on the DESTALINATOR_ACTIVATED environment variable."
            )
        self.action(
            "Warning all channels stale for more than {} days".format(days))

        stale = []
        for channel in sorted(self.slacker.channels_by_name.keys()):
            if ignore_channel(self.config, channel):
                self.logger.debug(
                    "Not warning #%s because it's in ignore_channels", channel)
                continue
            if self.stale(channel, days):
                if self.warn(channel, days, force_warn):
                    stale.append(channel)
            self.flush_channel_cache(channel)

        if stale and self.config.general_message_channel:
            self.logger.debug("Notifying #%s of warned channels",
                              self.config.general_message_channel)
            self.warn_in_general(stale)
Пример #3
0
    def stale(self, channel_name, days):
        """
        Return True if channel represented by `channel_name` is stale.
        Definition of stale is: no messages in the last `days` which are not from config.ignore_users.
        """
        if not self.channel_minimum_age(channel_name, days):
            return False

        if ignore_channel(self.config, channel_name):
            return False

        if self.slacker.channel_has_only_restricted_members(channel_name):
            return False

        messages = self.get_messages(channel_name, days)

        # return True (stale) if none of the messages match the criteria below
        return not any(
            # the message is not from an ignored user
            x.get("user") not in self.config.ignore_users \
            and x.get("username") not in self.config.ignore_users \
            and (
                # the message must have text that doesn't include ignored words
                (x.get("text") and b":dolphin:" not in x.get("text").encode('utf-8', 'ignore')) \
                or x.get("attachments")  # or the message must have attachments
            )
            for x in messages
        )
Пример #4
0
    def get_interesting_messages(self):
        """
        returns [[message, [listofchannelstoannounce]]
        """
        dayago = self.now - 86400

        messages = []
        for channel in self.slacker.channels_by_name:
            if ignore_channel(self.config, channel):
                self.logger.debug("Not checking flags for channel: #%s because it's in ignore_channels", channel)
                continue

            cid = self.slacker.get_channelid(channel)
            cur_messages = self.slacker.get_messages_in_time_range(dayago, cid, self.now)
            for message in cur_messages:
                announce = self.message_destination(message)
                if announce:
                    messages.append([message, announce])

        return messages
Пример #5
0
    def warn(self, channel_name, days, force_warn=False):
        """
        Send warning text to channel_name, if it has not been sent already in the last `days`.
        Using `force_warn=True` will warn even if a previous warning exists.
        Return True if we actually warned, otherwise False.
        """
        # Might not need to do this since we now do this in `stale`
        if self.slacker.channel_has_only_restricted_members(channel_name):
            self.logger.debug(
                "Would have warned #%s but it contains only restricted users",
                channel_name)
            return False

        # Might not need to do this since we now do this in `stale`
        if ignore_channel(self.config, channel_name):
            self.logger.debug(
                "Not warning #%s because it's in ignore_channels",
                channel_name)
            return False

        messages = self.get_messages(channel_name, days)
        texts = [x.get("text").strip() for x in messages if x.get("text")]
        if (not force_warn and
            (self.add_slack_channel_markup(self.warning_text) in texts or any(
                any(
                    a.get('fallback') == 'channel_warning'
                    for a in m.get('attachments', [])) for m in messages))):
            self.logger.debug(
                "Not warning #%s because we found a prior warning",
                channel_name)
            return False

        if self.config.activated:
            self.post_marked_up_message(channel_name,
                                        self.warning_text,
                                        message_type='channel_warning')
            self.action("Warned #{}".format(channel_name))

        return True
Пример #6
0
    def archive(self, channel_name):
        """Archive the given channel name, returning the Slack API response as a JSON string."""
        # Might not need to do this since we now do this in `stale`
        if ignore_channel(self.config, channel_name):
            self.logger.debug(
                "Not archiving #%s because it's in ignore_channels",
                channel_name)
            return

        if self.config.activated:
            self.logger.debug("Announcing channel closure in #%s",
                              channel_name)
            self.post_marked_up_message(channel_name,
                                        self.closure_text,
                                        message_type='channel_archive')

            members = self.slacker.get_channel_member_names(channel_name)
            say = "Members at archiving are {}".format(", ".join(
                sorted(members)))
            self.logger.debug("Telling channel #%s: %s", channel_name, say)
            self.post_marked_up_message(channel_name,
                                        say,
                                        message_type='channel_archive_members')

            self.action("Archiving channel #{}".format(channel_name))
            payload = self.slacker.archive(channel_name)
            if payload['ok']:
                self.logger.debug("Slack API response to archive: %s",
                                  json.dumps(payload, indent=4))
                self.logger.info("Archived %s", channel_name)
            else:
                error = payload.get(
                    'error', '!! No error found in payload %s !!' % payload)
                self.logger.error(
                    "Failed to archive %s: %s. See https://api.slack.com/methods/channels.archive for more context.",
                    channel_name, error)

            return payload