Пример #1
0
class Bot:
    """Bot object each group will have that handle checking for commands and processing them"""
    def __init__(self,
                 group,
                 yt_key=None,
                 delim="$",
                 refresh_group_interval=600):
        """
        :param group: the group this object will read messages from
        :param yt_key: youtube api key. need it to use yt_search but not needed for other commands
        :param delim: the first character that will let the bot know it is a command. default is "$"
        """
        self.group = group
        self.delim = delim
        self.ult = Utilities(yt_key)
        self.tags = Tags(group.name, group.id, group.members)
        self.valid_commands = ["avatar", "git", "yt", "tag", "help"]
        Timer(refresh_group_interval, self.reload_group).start()

    def get_message(self):
        """
        :return: returns the latest message from a group. if there is an error, return None
        """
        try:
            return self.group.messages.list()[0]
        except Exception as err:
            Utilities.log(
                "Exception: {self.group.name}: bot.get_message: {err}")
            return None

    def reload_tags(self):
        """
        :return: reloads the tags in the Tag object
        """
        self.tags.reload_tags()

    def reload_group(self, stop=Event()):
        """
        :param stop: threading Event. not set by default so this method would be called every 10 minutes
        :return: updates the group name, group id, and group members of a group every 10 minutes
        """
        self.group.refresh_from_server()
        self.tags.update_members(self.group.members)
        self.tags.update_group_id(self.group.id)
        self.tags.update_group_name(self.group.name)
        self.tags.save_tags()

        if not stop.is_set():
            Timer(600, self.reload_group).start()

    def save_tags(self):
        """
        :return: writes the tags to a file for the group
        """
        self.tags.save_tags()

    def find_owner_name(self, user_id):
        """
        :param user_id: user_id of a member in the group
        :return: returns the nickname associated with the user_id
        """
        return list(filter(lambda x: x.user_id == user_id,
                           self.group.members))[0]

    def find_avatar(self, message, mentions):
        """
        :param message: the avatar command. checks to see if it's a help call or actual usage
        :param mentions: list of attachments with the message. uses it to check for mentions
        :return: avatar url of person mentioned or an error message saying to mention the user
        """
        if message[2] == "help":
            return "Usage: avatar [person]"
        else:
            mentions = list(filter(lambda x: x.type == "mentions", mentions))
            if len(mentions) == 1:
                user_id = mentions[0].user_ids[0]
                return self.find_owner_name(user_id).image_url
            return "Please mention the one person you want the avatar of"

    def send_message(self, message):
        """
        :param message: message that will be sent to the group
        :return: message should post in the group
        """
        try:
            if isinstance(message, list):
                for res in message:
                    self.group.post(res)
            else:
                self.group.post(message)
        except Exception as err:
            Utilities.log(
                f"Exception: {self.group.name}: bot.send_message: {err}")

    def process_message(self, message):
        """
        :param message: checks if the message is a valid comand and execute command it is associated with
        :return: results of the command executed
        """
        if message is not None:
            try:
                message_text = message.text.lower()
                delim = message_text[:len(self.delim)]
                message_text = message_text[len(self.delim):]
                message_text = message_text.split(" ")
                command = message_text[0]

                if delim == self.delim and command in self.valid_commands:
                    user_id = message.user_id
                    owner = self.find_owner_name(user_id)
                    Utilities.log(
                        f"{self.group.name}: Processing from {owner}: {message_text}, Command: {command}"
                    )
                    result = None
                    if command == "help":
                        result = self.ult.post_help()
                    if command == "avatar":
                        result = self.find_avatar(message_text,
                                                  message.attachments)
                    if command == "git":
                        result = self.ult.git()
                    if command == "yt":
                        query = ' '.join(message_text[1:])
                        result = self.ult.yt_search(query)
                    if command == "tag":
                        result = self.tags.parse_commands(
                            message_text, user_id, message.attachments)

                    if result is not None:
                        Utilities.log(
                            f"{self.group.name}: posting \"{result}\"")
                        self.send_message(result)
            except Exception as err:
                if isinstance(err, googleapiclient.errors.HttpError):
                    self.send_message(str(err))
                if message.text is None:
                    pass
                else:
                    Utilities.log(
                        f"{self.group.name}: bot.process_message: {err}")