Exemplo n.º 1
0
    async def announce_start(self, msg, *args):
        self.enable = True
        print("Enabling announcements.")
        await channels[self.chan].send_message(f"{bot.msg_prefix}Announcements, announcements, ANNOUNCEMENTS!")
        session.query(Settings).filter(Settings.key == "announcement_enabled").update({"value": True})

        session.commit()
Exemplo n.º 2
0
    async def announce_del(self, msg, *args):

        try:
            id = args[0]
            id = int(id)
        except IndexError:
            print("Invalid Announcement delete value not provided")
            return
        except ValueError:
            print("Invalid Announcement delete ID passed, must be an integer")
            return
        except Exception as e:
            print(e)
            return

        announcement = self.get_announcement(id)

        if announcement is None:
            print("Invalid Announcement delete ID, 0 rows deleted.")
        else:
            session.delete(announcement)
            print(f"Announcement id {announcement.id} deleted.")
            await msg.reply(f"{bot.msg_prefix}Announcement {id=} deleted.")

        count = session.query(Announcements).filter(Announcements.category == announcement.id).count()
        if count == 0 and announcement.id != 1:
            await msg.reply(f"{bot.msg_prefix}Resetting category to Default")
            session.query(Settings).filter(Settings.key == self.current_category_setting).update({Settings.value: 1})

        session.commit()
Exemplo n.º 3
0
    async def announce_time(self, msg, time: int = None):
        try:
            # Make sure we receive a positive number
            if int(time) < 1:
                raise ValueError

            self.delay = int(time)

            updated = session.query(Settings).filter(Settings.key == "announcement_delay").update({"value": self.delay})

            if not updated:
                # Insert if it wasn't updated, because it didn't exist.
                insert = Settings(key="announcement_delay", value=self.delay)
                session.add(insert)

            session.commit()

            self.restart_task()
            await msg.reply(f"{bot.msg_prefix}New announce time is {time} seconds")
        except ValueError:
            await msg.reply(f"{bot.msg_prefix}Invalid time, please use an integer in seconds")
        except TypeError:
            await msg.reply(f"{bot.msg_prefix} Current announce time is {self.delay} seconds.")
        except Exception as e:
            print(type(e), e)
Exemplo n.º 4
0
    async def announce_disable(self, msg, *args):
        "Disables posting an announcement by ID"
        try:
            index = int(args[0])

        except IndexError:
            await msg.reply(f"{bot.msg_prefix} Try again with an ID")
            return

        except ValueError:
            if args[0] == "last":
                result = session.query(Announcements.id).order_by(Announcements.last_sent.desc()).first()
                index = result.id
                print(f"Disabling ID {index}")
            else:
                await msg.reply(f"{bot.msg_prefix} Try again with an ID Number")
                return

        except Exception as e:
            print(type(e), e)
            return

        successful = session.query(Announcements).filter(Announcements.id == index).update({"enabled": False})
        if successful:
            result = session.query(Announcements).filter(Announcements.id == index).one_or_none()
            print(f"Disabled announcement ID {index}")
            await msg.reply(f"{bot.msg_prefix}Disabled announcement ID {index}: {str(result.text)}")

            session.commit()

        else:
            print(f"Announcement ID {index} not found.")
            await msg.reply(f"{bot.msg_prefix}Announcement ID {index} not found.")
Exemplo n.º 5
0
    async def announce_enable(self, msg, *args):
        "Disables posting an announcement by ID"
        try:
            index = int(args[0])

        except IndexError:
            await msg.reply(f"{bot.msg_prefix} Try again with an ID")
            return

        except ValueError:
            await msg.reply(f"{bot.msg_prefix} Try again with an ID Number")
            return

        except Exception as e:
            print(type(e), e)
            return

        successful = session.query(Announcements).filter(Announcements.id == index).update({"enabled": True})
        if successful:
            print(f"Enabled announcement ID {index}")
            await msg.reply(f"{bot.msg_prefix}Enabled announcement ID {index}")
            session.commit()

        else:
            print(f"Announcement ID {index} not found.")
            await msg.reply(f"{bot.msg_prefix}Announcement ID {index} not found.")
Exemplo n.º 6
0
    async def announce_category_del(self, msg, category_id: int):
        """Check if any messages are still assigned to this category, and refuse to delete if so"""

        category_id = int(category_id)

        # Quick fail if trying to delete default
        if category_id == 1:
            await msg.reply(f"{bot.msg_prefix}Default category will not be deleted.")
            return

        # Grab the category
        category = self.get_announcements_category(category_id)
        if category is None:
            await msg.reply(f"{bot.msg_prefix} Category id {category_id} does not exist.")
            return

        # Check to see if there are announcements still assigned to this category
        announcement_count = session.query(Announcements).filter(Announcements.category == category_id).count()
        if announcement_count > 0:
            await msg.reply(f"{bot.msg_prefix}{category.name} is not an empty category, aborting. 🚨🚨")
            return

        session.delete(category)
        session.commit()
        await msg.reply(f"{bot.msg_prefix}{category.name} ({category.id}) has been deleted.")
Exemplo n.º 7
0
    async def ignore_add(self, msg: Message, pattern: str):

        # Check if the regex is valid, return error if not.
        try:
            re.compile(pattern)
        except re.error:
            await msg.reply(f"{bot.msg_prefix}Invalid regex pattern.")
            return

        # Will not support a space in the pattern, but that doesn't matter because usernames can't have spaces
        query = session.query(IgnoreList).filter(
            IgnoreList.pattern == pattern).one_or_none()
        if query is None:
            # Pattern didn't exist, so add it.
            insert = IgnoreList(pattern=pattern)
            session.add(insert)
            session.commit()
            session.refresh(insert)
            await msg.reply(
                f"{bot.msg_prefix}I will now ignore links from {pattern}")
            bot.ignore_list_patterns[insert.id] = pattern

        else:
            await msg.reply(
                f"{bot.msg_prefix}That pattern is already in the database.")
Exemplo n.º 8
0
    async def timer_loop(self):
        while True:
            # Try except to prevent loop from accidentally crashing, no known reasons to crash.
            try:
                now = datetime.now(tz=self.timezone)
                self.next_run = now + timedelta(seconds=self.delay)
                await sleep(self.delay)
                # This is done so the loop will continue to run and not exit out because the loop has ended
                # if done as a while enabled
                if self.enable and (self.channel_active or self.sleep_override):
                    # Grab the currently enabled announcement category
                    cat = session.query(Settings).filter(Settings.key == self.current_category_setting).first()
                    category = self.get_announcements_category(cat.value) if not None else 1

                    if self.announcement_count >= self.announce_topic_frequency:
                        # Send the topic instead of the announcement
                        topic = get_topic()
                        message_text = "Topic: " + topic
                        self.announcement_count = 0
                    else:
                        result = (  # Read the next announcement from the database
                            session.query(Announcements)
                            .filter(Announcements.enabled == True)  # noqa E712 SQLAlchemy doesn't work with `is True`
                            .filter(Announcements.category == category.id)
                            .order_by(Announcements.last_sent)
                            .first()
                        )

                        # Make sure there are entries in the dictioary
                        if result is None:
                            # Use continue instead of return so more can be added once the bot is run
                            continue

                        message_text = result.text
                        self.announcement_count += 1

                        # Update the last time sent of the message
                        session.query(Announcements).filter(Announcements.id == result.id).update(
                            {"last_sent": datetime.now(), "times_sent": result.times_sent + 1}
                        )

                        session.commit()

                    # Send the message
                    await channels[self.chan].send_message(bot.msg_prefix + message_text)

                    # Since we sent a message, going to clear the announcements_sleeping flag
                    self.announcements_sleeping = False

                    # Assuming the channel isn't active until proven otherwise
                    self.channel_active = False

                elif not self.channel_active:
                    if not self.announcements_sleeping:
                        await channels[self.chan].send_message(bot.msg_prefix + "It's so quiet in here...")
                        self.announcements_sleeping = True

            except Exception as e:
                print(e)
Exemplo n.º 9
0
    async def announce_stop(self, msg, *args):
        self.enable = False
        print("Disabling announcements.")
        await channels[self.chan].send_message(f"{bot.msg_prefix}Disabling announcements")

        session.query(Settings).filter(Settings.key == "announcement_enabled").update({"value": False})

        session.commit()
Exemplo n.º 10
0
    async def on_channel_joined(self, channel: Channel) -> None:
        """Bot joined a channel"""
        # Call user joind for all users currently in th channel
        for user_name in channel.chatters.all_viewers:
            await self.on_user_join(user_name, channel, commit=False)

        # Waited to commit so only one database commit was done on the server join
        session.commit()
Exemplo n.º 11
0
    async def wig_del(self, msg: Message, id: int):
        """Delete a wig by ID"""
        id = int(id)

        wig: Wigs = session.query(Wigs).filter(Wigs.id == id).first()
        if wig is not None:
            session.delete(wig)
            session.commit()
            await msg.reply(f"{bot.msg_prefix}{wig.wig_name} deleted.")
Exemplo n.º 12
0
    async def wig_time(self, msg: Message, time: int):
        """Set how long the poll should run for"""
        time = int(time)

        session.query(Settings.value).filter(
            Settings.key == "WigPollTime").update({Settings.value: time})
        session.commit()

        await msg.reply(f"{bot.msg_prefix}Time updated to {time}")
Exemplo n.º 13
0
    async def wig_add(self, msg: Message, *args):
        """Adds a new wig to the database"""
        wig_name = " ".join(map(str, args))

        new_wig = Wigs(wig_name=wig_name, enabled=1)
        session.add(new_wig)
        session.commit()

        session.refresh(new_wig)
        await msg.reply(f"{bot.msg_prefix}New wig added as id {new_wig.id}.")
Exemplo n.º 14
0
 async def allow_user(self, msg: Message, user: str):
     query = (
         session.query(LinksToDiscordIgnoreList).filter(LinksToDiscordIgnoreList.username == user.lower()).one_or_none()
     )
     if query:
         session.delete(query)
         session.commit()
         await msg.reply(f"{bot.msg_prefix}I will now allow links from {user}")
     else:
         await msg.reply(f"{bot.msg_prefix}{user} wasn't on my ignore list.")
Exemplo n.º 15
0
 async def ignore_disable(self, msg: Message, id: int):
     id = int(id)  # Library may not actually convert to an integer
     query = session.query(IgnoreList).filter(IgnoreList.id == id).update(
         {IgnoreList.enabled: False})
     session.commit()
     if query:
         await msg.reply(f"{bot.msg_prefix}ID:{id} disabled.")
         if id in bot.ignore_list_patterns.keys():
             del bot.ignore_list_patterns[id]
     else:
         await msg.reply(f"{bot.msg_prefix}Invalid ID.")
Exemplo n.º 16
0
def save_topic(topic: dict):
    topic_json = json.dumps(topic)

    rows_affected = session.query(Settings).filter(
        Settings.key == "topic").update({"value": topic_json})

    if not rows_affected:
        ins = Settings(key="topic", value=topic_json)
        session.add(ins)

    session.commit()

    return True
Exemplo n.º 17
0
    async def ignore_del(self, msg: Message, id: int):
        id = int(id)  # Library may not actually convert to an integer

        query = session.query(IgnoreList).filter(
            IgnoreList.id == id).one_or_none()
        if query:
            session.delete(query)
            session.commit()
            await msg.reply(
                f"{bot.msg_prefix}I will no longer ignore {query.pattern}")
            del bot.ignore_list_patterns[id]
        else:
            await msg.reply(f"{bot.msg_prefix}ID:{id} doesn't exist.")
Exemplo n.º 18
0
    async def shoutout_msg(self, msg: Message, *args):

        message = ""
        for word in args:
            message += f"{word} "

        successful = session.query(Settings.value).filter(Settings.key == "shoutout_msg").update({"value": message})
        if not successful:
            insert = Settings(key="shoutout_msg", value=message)
            session.add(insert)

        session.commit()

        await msg.reply(f"{bot.msg_prefix} Message updated.")
Exemplo n.º 19
0
    async def set_topic(self, msg, *args):

        topic = ""
        for arg in args:
            topic += f"{arg} "

        rows_affected = session.query(Settings).filter(Settings.key == "topic").update({"value": topic})

        if not rows_affected:
            ins = Settings(key="topic", value=topic)
            session.add(ins)

        session.commit()

        await msg.reply(f"{bot.msg_prefix}Topic set.")
Exemplo n.º 20
0
    async def announce_category_add(self, msg, *args):
        """Add a category"""

        cat_name = " ".join(map(str, args))
        exists = session.query(AnnouncementCategories).filter(AnnouncementCategories.name == cat_name).count()
        if exists:
            await msg.reply(f"{bot.msg_prefix}Duplicate category name")
            return

        # Insert the new category into the database
        new_announcement = AnnouncementCategories(name=cat_name)
        session.add(new_announcement)
        session.commit()

        # Refresh to pull the ID inserted as
        session.refresh(new_announcement)
        await msg.reply(f"{bot.msg_prefix}{new_announcement.name} added as id {new_announcement.id}")
Exemplo n.º 21
0
    def set_cooldown(self, feed: str, cooldown: int) -> None:
        """
        Sets the MQTT cooldown
        Updates or inserts the value into the database
        Exception handling should be done in the calling function
        """
        q = session.query(Settings.id).filter(Settings.key == f"mqtt_cooldown_{feed}").one_or_none()
        if q is None:
            # Value wasn't in the database, lets insert it.
            insert = Settings(key=f"mqtt_cooldown_{feed}", value=cooldown)
            session.add(insert)
            self.mqtt_cooldown[feed] = cooldown
        else:
            session.query(Settings).filter(Settings.key == f"mqtt_cooldown_{feed}").update({"value": cooldown})
            self.mqtt_cooldown[feed] = cooldown

        session.commit()
Exemplo n.º 22
0
    async def on_pubsub_bits(self, raw: PubSubData, data) -> None:
        """Send MQTT push when a us4er redeems bits"""
        """
        print(raw.message_dict)
        {'data':
            {'user_name': 'tisboyo', 'channel_name': 'baldengineer',
            'user_id': '461713054', 'channel_id': '125957551', 'time': '2020-09-20T02:48:34.819702158Z',
            'chat_message': 'cheer1', 'bits_used': 1, 'total_bits_used': 2,
            'is_anonymous': False, 'context': 'cheer', 'badge_entitlement': None},
        'version': '1.0',
        'message_type': 'bits_event',
        'message_id': '5a2da2f4-a6b5-5d23-b7cc-839a3ea5140c'
        }
        """
        # bits = await load_data("bits")
        # bits[datetime.now().isoformat()] = raw.message_dict
        # await save_data("bits", bits)

        user_id = raw.message_dict["data"]["user_id"]
        server_id = raw.message_dict["data"]["channel_id"]
        bits_used = raw.message_dict["data"]["bits_used"]

        rows_affected = (session.query(Users).filter(
            Users.user_id == user_id, Users.channel == server_id).update({
                "cheers":
                Users.cheers + bits_used,
                "last_message":
                datetime.now()
            }))

        # If the user doesn't exist, insert them
        if not rows_affected:
            user_object = Users(
                user_id=user_id,
                channel=server_id,
                user=raw.message_dict["data"]["user_name"],
                message_count=1,
                cheers=bits_used,
            )
            session.add(user_object)

        session.commit()
Exemplo n.º 23
0
    async def announce_add(self, msg, *args):

        message = ""

        # Build the message
        for arg in args:
            message += f"{arg} "

        print(f"Adding to announce: {message}", end="")

        announcement_object = Announcements(text=message)

        session.add(announcement_object)
        session.commit()
        session.refresh(announcement_object)
        id = announcement_object.id

        print(f"...done, {id=}")

        await msg.reply(f"{bot.msg_prefix}Added announce {id=}")
Exemplo n.º 24
0
    async def on_user_join(self, user_name: str, channel: Channel, commit: bool = True) -> None:
        """User has joined the channel"""

        # get_user_info is cached by the bot, so only one actual request per user is sent to the api
        user_id = await get_user_id(user_name)
        channel_id = await get_user_id(channel.name)

        # Don't overwrite if the user is already here, happens if they join twice
        if (user_name, user_id) not in self.user_joined.keys():
            in_database = session.query(Users).filter(Users.user_id == user_id, Users.channel == channel_id).one_or_none()

            # If the user isn't in the database insert them so we can find them later
            if not in_database:
                user_object = Users(user_id=user_id, channel=channel_id, user=user_name)
                session.add(user_object)
                if commit:
                    session.commit()

            self.user_joined[(user_name, user_id)] = datetime.now()
            print(f"{datetime.now().isoformat()}: {user_name} has joined #{channel.name}, in database: {bool(in_database)}")
Exemplo n.º 25
0
    async def user_exit(self, users: Union[str, frozenset], channel: Channel):

        now = datetime.now()

        # If only a single user is passed, convert it to a frozenset as if a list of users was passed
        if isinstance(users, str):
            users = frozenset([users])

        for user_name in users:
            # Build a tuple to compare
            user = (user_name, await get_user_id(user_name))

            # Check to make sure the user is still in the user_joined to prevent errors
            if user in self.user_joined.keys():
                # Calculate the time in the channel for this session
                joined: datetime = self.user_joined[user]
                parted = now
                time_this_session = parted - joined

                _, user_id = user
                channel_id = int(await get_user_id(channel.name))

                # Update the database
                # Adding time objects is not possible with sqlite, so using an integer to track seconds
                rows_affected = (
                    session.query(Users)
                    .filter(Users.user_id == user_id, Users.channel == channel_id)
                    .update({"time_in_channel": Users.time_in_channel + time_this_session.seconds})
                )

                if not rows_affected:
                    user_object = Users(
                        user_id=user_id, channel=channel_id, user=user_name, time_in_channel=time_this_session.seconds
                    )
                    session.add(user_object)

                # Remove the user from the user_joined key, since they have exited the channel
                del self.user_joined[user]

        # Commit the changes
        session.commit()
Exemplo n.º 26
0
    async def on_raw_message(self, msg: Message) -> None:
        """Increment the user message counter"""

        # Make sure the user actually sent a message,and it's not a whisper.
        if not msg.is_user_message or msg.is_whisper:
            return

        user_id = msg.tags.user_id
        server_id = msg.tags.room_id

        rows_affected = (session.query(Users).filter(
            Users.user_id == user_id, Users.channel == server_id).update({
                "message_count":
                Users.message_count + 1,
                "last_message":
                datetime.now()
            }))

        # If the user doesn't exist, insert them
        if not rows_affected:
            user_object = Users(user_id=user_id,
                                channel=server_id,
                                user=msg.author,
                                message_count=1)
            session.add(user_object)

            # Added for #155
            # If we have had a raid in the last 60 seconds, don't send anything for the new users,
            # even thought they got inserted into the database.
            if (self.last_raid + timedelta(seconds=60)) < datetime.now():
                if not bot.user_ignored(msg.author):
                    await bot.MQTT.send(
                        first_time_chatter_topic,
                        dumps({
                            "author": msg.author,
                            "timestamp": str(datetime.now())
                        }))
                    print(f"New user {msg.author} sent to MQTT.")

        session.commit()
Exemplo n.º 27
0
    async def on_raw_message(self, msg: Message) -> None:
        """Increment the user message counter"""

        # Make sure the user actually sent a message,and it's not a whisper.
        if not msg.is_user_message or msg.is_whisper:
            return

        user_id = msg.tags.user_id
        server_id = msg.tags.room_id

        rows_affected = (
            session.query(Users)
            .filter(Users.user_id == user_id, Users.channel == server_id)
            .update({"message_count": Users.message_count + 1, "last_message": datetime.now()})
        )

        # If the user doesn't exist, insert them
        if not rows_affected:
            user_object = Users(user_id=user_id, channel=server_id, user=msg.author, message_count=1)
            session.add(user_object)

        session.commit()
Exemplo n.º 28
0
    async def lost(self, msg: Message, *args):
        # Check if user is on ignore list
        if bot.user_ignored(str(msg.author)):
            return

        # Increase both counts
        self.lost_count["session"] += 1
        self.lost_count["total"] += 1

        rows_affected = (session.query(Settings).filter(
            Settings.key == "lost_count").update(
                {"value": json.dumps(self.lost_count)}))

        if not rows_affected:
            ins = Settings(key="lost_count", value=json.dumps(self.lost_count))
            session.add(ins)

        session.commit()

        await msg.reply(
            f"@baldengineer has lost {self.lost_count['session']} things so far today, {self.lost_count['total']} total."
        )
Exemplo n.º 29
0
class AutoMessageStarterMod(Mod):
    name = "automsg"
    task_name = "automessage"

    def __init__(self):
        query = session.query(Settings.value).filter(Settings.key == "announcement_delay").one_or_none()
        self.delay = int(query[0]) if query is not None else 900
        self.chan = cfg.channels[0]
        self.next_run = datetime.min
        self.timezone = pytz.timezone("America/Chicago")
        self.channel_active = False
        self.announcements_sleeping = True
        self.sleep_override = False
        self.current_category_setting = "announcement_category"

        self.enable = session.query(Settings.value).filter(Settings.key == "announcement_enabled").one_or_none()
        if self.enable is None:
            insert = Settings(key="announcement_enabled", value=True)
            session.add(insert)

    @property
    def delay(self):
        return self.__delay

    @delay.setter
    def delay(self, time: int):
        self.__delay = int(time)
        print(f"Announcement message delay is {self.delay} seconds")

    async def timer_loop(self):
        while True:
            # Try except to prevent loop from accidentally crashing, no known reasons to crash.
            try:
                now = datetime.now(tz=self.timezone)
                self.next_run = now + timedelta(seconds=self.delay)
                await sleep(self.delay)
                # This is done so the loop will continue to run and not exit out because the loop has ended
                # if done as a while enabled
                if self.enable and (self.channel_active or self.sleep_override):
                    # Grab the currently enabled announcement category
                    cat = session.query(Settings).filter(Settings.key == self.current_category_setting).first()
                    category = self.get_announcements_category(cat.value) if not None else 1

                    result = (  # Read the next announcement from the database
                        session.query(Announcements)
                        .filter(Announcements.enabled == True)  # noqa E712 SQLAlchemy doesn't work with `is True`
                        .filter(Announcements.category == category.id)
                        .order_by(Announcements.last_sent)
                        .first()
                    )

                    # Make sure there are entries in the dictioary
                    if result is None:
                        # Use continue instead of return so more can be added once the bot is run
                        continue

                    # Send the message
                    await channels[self.chan].send_message(bot.msg_prefix + result.text)

                    # Update the last time sent of the message
                    session.query(Announcements).filter(Announcements.id == result.id).update(
                        {"last_sent": datetime.now(), "times_sent": result.times_sent + 1}
                    )

                    session.commit()

                    # Since we sent a message, going to clear the announcements_sleeping flag
                    self.announcements_sleeping = False

                    # Assuming the channel isn't active until proven otherwise
                    self.channel_active = False

                elif not self.channel_active:
                    if not self.announcements_sleeping:
                        await channels[self.chan].send_message(bot.msg_prefix + "It's so quiet in here...")
                        self.announcements_sleeping = True

            except Exception as e:
                print(e)

    async def on_raw_message(self, msg: Message):
        """
        Tracks the last time a message was sent,
        and if it was by the bot, consider the channel inactive.
        """
        if msg.is_user_message:
            self.channel_active = True
            self.announcements_sleeping = False

    @ModCommand(name, "announce", permission="admin")
    async def announce(self, msg, *args):
        # Announce parent command
        pass

    @SubCommand(announce, "nosleep", permission="admin")
    async def announce_nosleep(self, msg, *args):
        self.sleep_override = not self.sleep_override
        status = "disabled" if self.sleep_override else "enabled"
        await msg.reply(f"{bot.msg_prefix}Announce auto-sleep status is now {status}.")

    @SubCommand(announce, "start", permission="admin")
    async def announce_start(self, msg, *args):
        self.enable = True
        print("Enabling announcements.")
        await channels[self.chan].send_message(f"{bot.msg_prefix}Announcements, announcements, ANNOUNCEMENTS!")
        session.query(Settings).filter(Settings.key == "announcement_enabled").update({"value": True})

        session.commit()

    @SubCommand(announce, "stop", permission="admin")
    async def announce_stop(self, msg, *args):
        self.enable = False
        print("Disabling announcements.")
        await channels[self.chan].send_message(f"{bot.msg_prefix}Disabling announcements")

        session.query(Settings).filter(Settings.key == "announcement_enabled").update({"value": False})

        session.commit()

    @SubCommand(announce, "time", permission="admin")
    async def announce_time(self, msg, time: int = None):
        try:
            # Make sure we receive a positive number
            if int(time) < 1:
                raise ValueError

            self.delay = int(time)

            updated = session.query(Settings).filter(Settings.key == "announcement_delay").update({"value": self.delay})

            if not updated:
                # Insert if it wasn't updated, because it didn't exist.
                insert = Settings(key="announcement_delay", value=self.delay)
                session.add(insert)

            session.commit()

            self.restart_task()
            await msg.reply(f"{bot.msg_prefix}New announce time is {time} seconds")
        except ValueError:
            await msg.reply(f"{bot.msg_prefix}Invalid time, please use an integer in seconds")
        except TypeError:
            await msg.reply(f"{bot.msg_prefix} Current announce time is {self.delay} seconds.")
        except Exception as e:
            print(type(e), e)

    @SubCommand(announce, "list", permission="admin")
    async def announce_list(self, msg, *args):
        result = (
            session.query(Announcements, AnnouncementCategories)
            .order_by(Announcements.id)
            .join(AnnouncementCategories)
            .all()
        )
        print("Announcements".center(80, "*"))
        print("          Times")
        print(" ID : EN : Sent : Category : Text")
        for announcement, category in result:
            en = "Y" if announcement.enabled else "N"
            print(f"{announcement.id:3} :  {en} : {announcement.times_sent:4} : {category.name[:8]:8} : {announcement.text}")
        print(f" https://{getenv('WEB_HOSTNAME')}/announcements ".center(80, "*"))
        await msg.reply(f"{bot.msg_prefix}Announcements listed in console.")

    @SubCommand(announce, "del", permission="admin")
    async def announce_del(self, msg, *args):

        try:
            id = args[0]
            id = int(id)
        except IndexError:
            print("Invalid Announcement delete value not provided")
            return
        except ValueError:
            print("Invalid Announcement delete ID passed, must be an integer")
            return
        except Exception as e:
            print(e)
            return

        announcement = self.get_announcement(id)

        if announcement is None:
            print("Invalid Announcement delete ID, 0 rows deleted.")
        else:
            session.delete(announcement)
            print(f"Announcement id {announcement.id} deleted.")
            await msg.reply(f"{bot.msg_prefix}Announcement {id=} deleted.")

        count = session.query(Announcements).filter(Announcements.category == announcement.id).count()
        if count == 0 and announcement.id != 1:
            await msg.reply(f"{bot.msg_prefix}Resetting category to Default")
            session.query(Settings).filter(Settings.key == self.current_category_setting).update({Settings.value: 1})

        session.commit()

    @SubCommand(announce, "add", permission="admin")
    async def announce_add(self, msg, *args):

        message = ""

        # Build the message
        for arg in args:
            message += f"{arg} "

        print(f"Adding to announce: {message}", end="")

        announcement_object = Announcements(text=message)

        session.add(announcement_object)
        session.commit()
        session.refresh(announcement_object)
        id = announcement_object.id

        print(f"...done, {id=}")

        await msg.reply(f"{bot.msg_prefix}Added announce {id=}")

    @SubCommand(announce, "disable", permission="admin")
    async def announce_disable(self, msg, *args):
        "Disables posting an announcement by ID"
        try:
            index = int(args[0])

        except IndexError:
            await msg.reply(f"{bot.msg_prefix} Try again with an ID")
            return

        except ValueError:
            if args[0] == "last":
                result = session.query(Announcements.id).order_by(Announcements.last_sent.desc()).first()
                index = result.id
                print(f"Disabling ID {index}")
            else:
                await msg.reply(f"{bot.msg_prefix} Try again with an ID Number")
                return

        except Exception as e:
            print(type(e), e)
            return

        successful = session.query(Announcements).filter(Announcements.id == index).update({"enabled": False})
        if successful:
            result = session.query(Announcements).filter(Announcements.id == index).one_or_none()
            print(f"Disabled announcement ID {index}")
            await msg.reply(f"{bot.msg_prefix}Disabled announcement ID {index}: {str(result.text)}")

            session.commit()

        else:
            print(f"Announcement ID {index} not found.")
            await msg.reply(f"{bot.msg_prefix}Announcement ID {index} not found.")

    @SubCommand(announce, "enable", permission="admin")
    async def announce_enable(self, msg, *args):
        "Disables posting an announcement by ID"
        try:
            index = int(args[0])

        except IndexError:
            await msg.reply(f"{bot.msg_prefix} Try again with an ID")
            return

        except ValueError:
            await msg.reply(f"{bot.msg_prefix} Try again with an ID Number")
            return

        except Exception as e:
            print(type(e), e)
            return

        successful = session.query(Announcements).filter(Announcements.id == index).update({"enabled": True})
        if successful:
            print(f"Enabled announcement ID {index}")
            await msg.reply(f"{bot.msg_prefix}Enabled announcement ID {index}")
            session.commit()

        else:
            print(f"Announcement ID {index} not found.")
            await msg.reply(f"{bot.msg_prefix}Announcement ID {index} not found.")

    @SubCommand(announce, "status", permission="admin")
    async def announce_status(self, msg, *args):
        """Sends the current status of the announcements"""

        status = "Enabled" if self.enable else "Disabled"
        next_run_seconds = self.next_run - datetime.now(self.timezone)
        enabled = session.query(Announcements).filter(Announcements.enabled == True).count()  # noqa E712
        total_count = session.query(Announcements).count()
        # Scalar returns the first element of the first result or None
        cat_id = int(session.query(Settings.value).filter(Settings.key == self.current_category_setting).scalar())
        category_name = session.query(AnnouncementCategories.name).filter(AnnouncementCategories.id == cat_id).scalar()
        announcements_in_cat = session.query(Announcements).filter(Announcements.category == cat_id).count()

        replies = [
            f"{bot.msg_prefix}Current status is {status}",
            f"{bot.msg_prefix}Current delay is {self.delay} seconds. ",
            f"{bot.msg_prefix}Next send time will be {self.next_run.strftime('%H:%M:%S')} which is in {str(next_run_seconds)[:-7]}.",  # noqa E501
            f"{bot.msg_prefix}{enabled}/{total_count} of all announcements enabled.",
            f"{bot.msg_prefix}Current category is {category_name}, with {announcements_in_cat} announcements",
        ]

        for reply in replies:
            await msg.reply(reply)

    @SubCommand(announce, "category", permission="admin")
    async def announce_category(self, msg, *args):
        """Base command for category management"""
        pass

    @SubCommand(announce_category, "add", permission="admin")
    async def announce_category_add(self, msg, *args):
        """Add a category"""

        cat_name = " ".join(map(str, args))
        exists = session.query(AnnouncementCategories).filter(AnnouncementCategories.name == cat_name).count()
        if exists:
            await msg.reply(f"{bot.msg_prefix}Duplicate category name")
            return

        # Insert the new category into the database
        new_announcement = AnnouncementCategories(name=cat_name)
        session.add(new_announcement)
        session.commit()

        # Refresh to pull the ID inserted as
        session.refresh(new_announcement)
        await msg.reply(f"{bot.msg_prefix}{new_announcement.name} added as id {new_announcement.id}")

    @SubCommand(announce_category, "del", permission="admin")
    async def announce_category_del(self, msg, category_id: int):
        """Check if any messages are still assigned to this category, and refuse to delete if so"""

        category_id = int(category_id)

        # Quick fail if trying to delete default
        if category_id == 1:
            await msg.reply(f"{bot.msg_prefix}Default category will not be deleted.")
            return

        # Grab the category
        category = self.get_announcements_category(category_id)
        if category is None:
            await msg.reply(f"{bot.msg_prefix} Category id {category_id} does not exist.")
            return

        # Check to see if there are announcements still assigned to this category
        announcement_count = session.query(Announcements).filter(Announcements.category == category_id).count()
        if announcement_count > 0:
            await msg.reply(f"{bot.msg_prefix}{category.name} is not an empty category, aborting. 🚨🚨")
            return

        session.delete(category)
        session.commit()
        await msg.reply(f"{bot.msg_prefix}{category.name} ({category.id}) has been deleted.")

    @SubCommand(announce_category, "list", permission="admin")
    async def announce_category_list(self, msg, *args):
        """List the available categories"""
        result = session.query(AnnouncementCategories).order_by(AnnouncementCategories.id).all()

        print("Announcement Categories".center(80, "*"))
        print(" ID : Category")
        for category in result:
            print(f"{category.id:3} : {category.name}")

        print(f" https://{getenv('WEB_HOSTNAME')}/announcements ".center(80, "*"))
        await msg.reply(f"{bot.msg_prefix}Categories listed in console.")

    @SubCommand(announce_category, "assign", permission="admin")
    async def announce_category_assign(self, msg, announcement_id: int, category_id: int):
        """
        Assign a category to an Announcement
        Usage: !announce category assign message_id category_id
        """

        # Cast the ID's to ints
        announcement_id = int(announcement_id)
        category_id = int(category_id)

        # Check to make sure the announcement category exists
        # Keep inside parens, otherwise this assigns True to category on a good category
        # instead of the category itself
        if (category := self.get_announcements_category(category_id)) is None:
            await msg.reply(f"{bot.msg_prefix}Invalid category id")
            return

        # Check to make sure the announcement itself exists
        if not session.query(Announcements).filter(Announcements.id == announcement_id).count():
            await msg.reply(f"{bot.msg_prefix}Invalid announcement id")
            return

        # Update the announcement
        result = (
            session.query(Announcements)
            .filter(Announcements.id == announcement_id)
            .update({Announcements.category: category_id})
        )

        session.commit()

        # Send response of results
        if result:
            await msg.reply(f"{bot.msg_prefix}Announcement id {announcement_id} updated to category {category.name}")
        else:
            await msg.reply(f"{bot.msg_prefix}Unable to update.")
Exemplo n.º 30
0
        if (category := self.get_announcements_category(category_id)) is None:
            await msg.reply(f"{bot.msg_prefix}Invalid category id.")
            return

        # TODO Change to just an update, and do a alembic revision to insert a default after #79 is complete.
        updated = (
            session.query(Settings)
            .filter(Settings.key == self.current_category_setting)
            .update({Settings.value: category_id})
        )

        if not updated:  # Insert the key
            insert = Settings(key=self.current_category_setting, value=category_id)
            session.add(insert)

        session.commit()

        await msg.reply(f"{bot.msg_prefix}Active announcement category is now {category.name}")

    def get_announcements_category(self, category_id: int) -> AnnouncementCategories or None:
        """
        Returns an AnnouncementCategories object or None
        Use: if (category := self.get_announcements_category(category_id)) is None:
        """
        category_id = int(category_id)
        category = session.query(AnnouncementCategories).filter(AnnouncementCategories.id == category_id).first()
        # Have to check if a valid category was returned
        # to prevent a NoneType error if an invalid one is found
        if category is None:
            category = AnnouncementCategories(id=1, name="Default")