def linecount(self, message: core.BotMessage) -> None: """Gets a user's linecount Args: message (message: core.BotMessage) -> None: the Message object that invoked the command """ if len(message.arguments) < 3: return message.respond( f"Usage: ``{config.commandCharacter}linecount <user>, <room>, [optional number of days]``." ) userID = psclient.toID(message.arguments[1]) roomID = psclient.toID(message.arguments[2]) try: days = int(message.arguments[3]) except (IndexError, ValueError): days = 30 room = message.connection.getRoom(roomID) if not message.connection.rustChatlogger: return message.respond("There is currently no chatlogger loaded.") if not room: return message.respond(f"Invalid room: {roomID}") if not message.sender.can("searchlog", room): return message.respond("Permission denied.") message.respondHTMLPatched( message.connection.rustChatlogger.linecount_html( roomID, userID, days))
def topusers(self, message: core.BotMessage) -> None: """Gets the top users of a room Args: message (message: core.BotMessage) -> None: the Message object that invoked the command """ if len(message.arguments) < 2: return message.respond( f"Usage: ``{config.commandCharacter}topusers <room>, [optional number of days]``." ) roomID = psclient.toID(message.arguments[1]) try: days = int(message.arguments[2]) except (IndexError, ValueError): days = 30 room = message.connection.getRoom(roomID) if not message.connection.rustChatlogger: return message.respond("There is currently no chatlogger loaded.") if not room: return message.respond(f"Invalid room: {roomID}") if not message.sender.can("searchlog", room): return message.respond("Permission denied.") message.respond("Please wait; fetching userstats...") return message.respondHTMLPatched( message.connection.rustChatlogger.topusers_html(roomID, days, 30))
def listRepeats(self, message: core.BotMessage) -> None: """listrepeats: lists repeats Arguments: message {Message} -- the Message object that invoked the command """ room = message.room if not room: if len(message.arguments) != 2: return message.respond( "You must specify a room when using this command in PMs.") room = message.connection.getRoom(message.arguments[1]) if not room: return message.respond( f"I'm not in the room '{message.arguments[1]}'.") if not message.sender.can('searchlog', room): return message.respond("Permission denied.") repeats = data.get("repeats") if not (repeats and room.id in repeats and repeats[room.id]): return message.respond( f"There are no repeats for the room '{room.id}'") htmlBuf = f"<details><summary>Repeats for the room <strong>{room.id}</strong></summary><ul>" for repeat in repeats[room.id]: htmlBuf += f"<li>Repeated every {list(repeat.values())[0]} minutes: \"{list(repeat.keys())[0]}\"</li>" htmlBuf += "</ul></details>" print(htmlBuf) return message.respondHTMLPatched(htmlBuf)
def showSampleTeams(self, message: core.BotMessage) -> None: """Displays sample teams Arguments: message {Message} -- the Message object that invoked the command """ if message.room and not message.sender.can('broadcast', message.room): return formatid = psclient.toID(','.join(message.arguments[1:]) if len(message.arguments) > 1 else '') if not formatid or formatid not in htmlboxes: return message.respond( f"You must specify a format that I have sample teams for: {', '.join(list(htmlboxes.keys()))}" ) return message.respondHTMLPatched(generateHTML(htmlboxes[formatid]))
def audio(self, message: core.BotMessage) -> None: """audio: displays audio in the room Arguments: message {Message} -- the Message object that invoked the command """ if len(message.arguments) < 2: return message.respond(f"Usage: ``{ config.commandCharacter}audio <URL to audio file>``.") url = ','.join(message.arguments[1:]).strip() if not isAudioURL(url): return message.respond( "You must specify a valid URL beginning with ``http://`` or ``https://``; the URL must refer to an audio file." ) return message.respondHTMLPatched(f'<audio controls src="{url}"></audio>')
def logsearch(self, message: core.BotMessage) -> None: """Searches logs Args: message (message: core.BotMessage) -> None: the Message object that invoked the command """ if len(message.arguments) < 2: return message.respond( f"Usage: ``{config.commandCharacter}logsearch <room>, [optional user], [optional keyword]``." ) if not message.connection.rustChatlogger: return message.respond("There is currently no chatlogger loaded.") roomID = psclient.toID(message.arguments[1]).lower() userID = psclient.toID(message.arguments[2]).lower() if len( message.arguments) > 2 else None keywords = message.arguments[3:] if len( message.arguments) > 3 else None room = message.connection.getRoom(roomID) if not room: return message.respond(f"Invalid room: {roomID}") if not message.sender.can("searchlog", room): return message.respond("Permission denied.") message.respond( f"Fetching the {MAX_MESSAGES} most recent messages in the room {roomID}" + (f" sent by the user '{userID}'" if userID else "") + (f" containing all of the following keywords: {', '.join(keywords)}" if keywords else "") + ".") return message.respondHTMLPatched( message.connection.rustChatlogger.html_search( roomID, userID or None, None, # `oldest` param in Rust keywords or None, MAX_MESSAGES))
def superhero(self, message: core.BotMessage) -> None: """Gets information on a superhero from the Superhero API Arguments: message {Message} -- the Message object that invoked the command """ if message.room and not message.sender.can('broadcast', message.room): return superheroIDDictionary = data.get( "superheroIDDictionary") or _initializeData() superhero = psclient.toID(config.separator.join(message.arguments[1:])) if superhero not in superheroIDDictionary: return message.respond( f"{superhero} isn't a superhero that can be looked up with the API." ) superheroID = superheroIDDictionary[superhero] APIResponse = requests.get( f"https://superheroapi.com/api/{config.superheroAPIKey}/{superheroID}" ).json() if APIResponse['response'] != 'success': return message.respond( f"The API request for {superhero} (ID: {superheroID}) failed with response {APIResponse['response']}." ) # Aliases and relatives can be lists aliases = APIResponse['biography']['aliases'] relatives = APIResponse['connections']['relatives'] aliases = aliases if isinstance(aliases, str) else ", ".join(aliases) relatives = relatives if isinstance(relatives, str) else ", ".join(relatives) message.respond(f"!show {APIResponse['image']['url']}") html = f""" <details><summary>{APIResponse['name']}</summary><details><summary>Stats</summary> <b>Intelligence:</b> {APIResponse['powerstats']['intelligence']}<br> <b>Strength:</b> {APIResponse['powerstats']['strength']}<br> <b>Speed:</b> {APIResponse['powerstats']['speed']}<br> <b>Durability:</b> {APIResponse['powerstats']['durability']}<br> <b>Power:</b> {APIResponse['powerstats']['power']}<br> <b>Combat:</b> {APIResponse['powerstats']['combat']}<br> </details><details><summary>Biography</summary> <b>Full Name:</b> {APIResponse['biography']['full-name']}<br> <b>Alter Egos:</b> {APIResponse['biography']['alter-egos']}<br> <b>Aliases:</b> {aliases}<br> <b>Birthplace:</b> {APIResponse['biography']['place-of-birth']}<br> <b>Debut:</b> {APIResponse['biography']['first-appearance']}<br> <b>Publisher:</b> {APIResponse['biography']['publisher']}<br> <b>Alignment:</b> {APIResponse['biography']['alignment']}<br> </details><details><summary>Appearance</summary> <b>Gender:</b> {APIResponse['appearance']['gender']}<br> <b>Race:</b> {APIResponse['appearance']['race']}<br> <b>Height:</b> {APIResponse['appearance']['height'][1]}<br> <b>Weight:</b> {APIResponse['appearance']['weight'][1]}<br> <b>Eye Color:</b> {APIResponse['appearance']['eye-color']}<br> <b>Hair Color:</b> {APIResponse['appearance']['hair-color']}<br> </details><details><summary>Work</summary> <b>Occupation:</b> {APIResponse['work']['occupation']}<br> <b>Base:</b> {APIResponse['work']['base']}<br> </details><details><summary>Connections</summary> <b>Group Affiliation:</b> {APIResponse['connections']['group-affiliation']}<br> <b>Relatives:</b> {relatives}<br> </details></details> """ return message.respondHTMLPatched(html)