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()
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()
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.")
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)
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()
async def wig_enable(self, msg: Message, id: int): id = int(id) wig: Wigs = session.query(Wigs).filter(Wigs.id == id).first() successful = session.query(Wigs).filter(Wigs.id == id).update( {Wigs.enabled: True}) if successful: await msg.reply(f"{bot.msg_prefix}{wig.wig_name} enabled.")
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}")
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)
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.")
def get_topic(raw=False): result = session.query(Settings).filter( Settings.key == "topic").one_or_none() topic = result.value if result is not None else '""' if raw: # Returns a dictionary val = json.loads(topic) return val # Beyond this point returns a string try: topic = json.loads(topic) # Check that a topic is set if topic.get("topic", False): # Build the topic topic_text = topic["topic"] topic_text = f"{topic_text}Goal: {topic['goal']} " if topic.get( "goal", False) else topic_text topic_text = f"{topic_text}Currently: {topic['step']} " if topic.get( "step", False) else topic_text topic_text = f"{topic_text}Notes/Info: {topic['link']}" if topic.get( "link", False) else topic_text # Return the topic in string format. return topic_text else: return "No current topic." except json.decoder.JSONDecodeError: # Stored value was not a json string # Return an empty dictionary to indicate no topic currently set. return "No current topic."
async def shoutout(self, msg: Message, *args): if len(args) == 0 and self.last_raid: # Shotout to last raided user shoutout_to = self.last_raid elif len(args) == 0: shoutout_to = None else: shoutout_to = args[0] # If we a user isn't defined to shoutout to, quit if shoutout_to is None: return # Read the message from the settings table message = session.query(Settings.value).filter(Settings.key == "shoutout_msg").one_or_none() # Default message if none has been set. if message is None: message = "Hey Everyone! Check out the awesome {channel}. Give them a follow!" else: message = message[0] message = message.format(channel=shoutout_to) await msg.reply(f"{bot.msg_prefix}{message}")
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)
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.")
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.")
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()
async def wig_list(self, msg: Message, *args): wigs: Wigs = session.query(Wigs).all() wig_list = [ f"{'🔕' if not wig.enabled else '🔔'}({wig.id}){wig.wig_name}" for wig in wigs ] for w in wig_list: await msg.reply(f"{bot.msg_prefix} {w}")
async def on_channel_joined(self, channel: Channel): while True: if not bot.live: if not self.not_live_updated: # Reset the session if the stream is not live self.lost_count["session"] = 0 # Update the session key if it hasn't been updated since going offline session.query(Settings).filter( Settings.key == "lost_count").update( {"value": json.dumps(self.lost_count)}) self.not_live_updated = True else: # Reset keeping track if the session count has been updated since going offline self.not_live_updated = False await sleep(60)
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.")
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.")
def __init__(self): super().__init__() print("LostMod loaded") result = session.query(Settings).filter( Settings.key == "lost_count").one_or_none() self.lost_count = json.loads(result.value) if result is not None else { "session": 0, "total": 0 } self.not_live_updated = False
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.")
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.")
def __init__(self): super().__init__() # Load the ignore list from the database on startup self.ignore_list_patterns = dict() query = session.query(IgnoreList).filter( IgnoreList.enabled == True).all() # noqa E712 for each in query: self.ignore_list_patterns[each.id] = each.pattern # Check and set the status of the bot on startup. AddOhmsBot.live = self.check_live_status() print(f"Stream online: {AddOhmsBot.live}")
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") return category
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)
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
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.")
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.")
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.")
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.")