def _processTells(self, server, source, nick): if networkName(self.bot, server) not in self.tells: return chanTells = [] pmTells = [] for tell in self.tells[networkName(self.bot, server)][:]: if not any( fnmatch(nick.lower(), r) for r in tell["to"].split("/")): continue if now() < tell["datetoreceive"]: continue if tell["source"][0] in self.bot.servers[ server].supportHelper.chanTypes and len(chanTells) < 3: if tell["source"] == source: chanTells.append(tell) self.tells[networkName(self.bot, server)].remove(tell) elif tell["source"][0] not in self.bot.servers[ server].supportHelper.chanTypes: pmTells.append(tell) self.tells[networkName(self.bot, server)].remove(tell) for tell in chanTells: self.replyPRIVMSG(server, source, self._parseTell(nick, tell)) for tell in pmTells: self.replyPRIVMSG(server, nick, self._parseTell(nick, tell)) if len(chanTells) > 0 or len(pmTells) > 0: self.bot.storage["tells"] = self.tells
def execute(self, server, source, command, params, data): if command == "setpron": if len(params) < 1: self.replyPRIVMSG(server, source, "Your pronouns are ...blank?") return if networkName(self.bot, server) not in self.pronstore: self.pronstore[networkName(self.bot, server)] = {} self.pronstore[networkName(self.bot, server)][data["user"].nick.lower()] = " ".join(params) self.bot.storage["pronouns"] = self.pronstore # actually unsure why this is needed self.replyPRIVMSG(server, source, "Your pronouns have been noted.") elif command == "rmpron": if data["user"].nick.lower() not in self.pronstore[networkName(self.bot, server)]: self.replyPRIVMSG(server, source, "I don't even know your pronouns!") else: del self.pronstore[networkName(self.bot, server)][data["user"].nick.lower()] self.bot.storage["pronouns"] = self.pronstore self.replyPRIVMSG(server, source, "Your pronouns have been removed.") elif command == "pronouns": if len(params) < 1: lookup = data["user"].nick.lower() else: lookup = params[0] userpron = self.lookUpPronouns(server, source, lookup, True) if userpron["success"]: self.replyPRIVMSG(server, source, "{} uses <{}> pronouns".format(lookup, userpron["pronouns"]))
def execute(self, server, source, command, params, data): if not self.lastfmKey: self.replyPRIVMSG(server, source, "No LastFM API key was found.") return if networkName(self.bot, server) not in self.links: self.links[networkName(self.bot, server)] = {} if command == "np": if len(params) == 0: name = data["user"].nick.lower() else: name = params[0].lower() if name in self.links[networkName(self.bot, server)]: name = self.links[networkName(self.bot, server)][name] url = "http://ws.audioscrobbler.com/2.0/" params = { "method": "user.getrecenttracks", "limit": "1", "format": "json", "user": name, "api_key": self.lastfmKey } result = self.bot.moduleHandler.runActionUntilValue( "fetch-url", url, params) if not result: m = "An error occurred while retrieving data from LastFM." else: j = result.json() if "error" in j and j["error"] == 6: m = "No user with the name {!r} could be found on LastFM.".format( name) elif len(j["recenttracks"]["track"]) == 0: m = "No recently played music was found for user {!r}".format( name) else: track = j["recenttracks"]["track"][0] artist = track["artist"]["#text"].encode("utf-8", "ignore") songTitle = track["name"].encode("utf-8", "ignore") longLink = track["url"] link = self.bot.moduleHandler.runActionUntilValue( "shorten-url", longLink) if not link: link = longLink m = "{!r} by {} | {}".format(songTitle, artist, link) self.replyPRIVMSG(server, source, m) elif command == "nplink": if len(params) == 0: m = "You must provide a LastFM name to link to your nickname." else: self.links[networkName( self.bot, server)][data["user"].nick.lower()] = params[0].lower() self.bot.storage["lastfm-links"] = self.links m = "The nickname {!r} is now linked to LastFM name {!r}".format( data["user"].nick, params[0]) self.replyPRIVMSG(server, source, m)
def applyIgnores(self, data): if not self.bot.moduleHandler.useModuleOnServer( self.name, data["server"]): return if networkName(self.bot, data["server"]) not in self.ignores: return for ignoredHost in self.ignores[networkName(self.bot, data["server"])]: if fnmatch(data["user"].fullUserPrefix().lower(), ignoredHost.lower()): data.clear() break
def execute(self, server, source, command, params, data): if not self.lastfmKey: self.replyPRIVMSG(server, source, "No LastFM API key was found.") return if networkName(self.bot, server) not in self.links: self.links[networkName(self.bot, server)] = {} if command == "np": if len(params) == 0: name = data["user"].nick.lower() else: name = params[0].lower() if name in self.links[networkName(self.bot, server)]: name = self.links[networkName(self.bot, server)][name] url = "http://ws.audioscrobbler.com/2.0/" params = { "method": "user.getrecenttracks", "limit": "1", "format": "json", "user": name, "api_key": self.lastfmKey } result = self.bot.moduleHandler.runActionUntilValue("fetch-url", url, params) if not result: m = "An error occurred while retrieving data from LastFM." else: j = result.json() if "error" in j and j["error"] == 6: m = "No user with the name {!r} could be found on LastFM.".format(name) elif len(j["recenttracks"]["track"]) == 0: m = "No recently played music was found for user {!r}".format(name) else: track = j["recenttracks"]["track"][0] artist = track["artist"]["#text"].encode("utf-8", "ignore") songTitle = track["name"].encode("utf-8", "ignore") longLink = track["url"] link = self.bot.moduleHandler.runActionUntilValue("shorten-url", longLink) if not link: link = longLink m = "{!r} by {} | {}".format(songTitle, artist, link) self.replyPRIVMSG(server, source, m) elif command == "nplink": if len(params) == 0: m = "You must provide a LastFM name to link to your nickname." else: self.links[networkName(self.bot, server)][data["user"].nick.lower()] = params[0].lower() self.bot.storage["lastfm-links"] = self.links m = "The nickname {!r} is now linked to LastFM name {!r}".format(data["user"].nick, params[0]) self.replyPRIVMSG(server, source, m)
def _handleSubscription(self, server, source, subAction): if subAction: if source not in self.subscriptions[networkName(self.bot, server)]: self.subscriptions[networkName(self.bot, server)].append(source) self.bot.storage["event-subs"] = self.subscriptions m = "{} is now subscribed to event announcements.".format(source) else: m = "{} is already subscribed to event announcements!".format(source) else: if source in self.subscriptions[networkName(self.bot, server)]: self.subscriptions[networkName(self.bot, server)].remove(source) self.bot.storage["event-subs"] = self.subscriptions m = "{} is now unsubscribed from event announcements.".format(source) else: m = "{} is not subscribed to event announcements!".format(source) self.replyPRIVMSG(server, source, m)
def lookUpPronouns(self, server, source, user, displayErrors): if not self.bot.moduleHandler.useModuleOnServer(self.name, server): return if networkName(self.bot, server) in self.pronstore and user.lower() in self.pronstore[networkName(self.bot, server)]: return { "success": True, "pronouns": self.pronstore[networkName(self.bot, server)][user.lower()] } if displayErrors: error = "User's pronouns have not been specified. Your pronouns can be set with the \"setpron\" command, " \ "{}".format(user) self.replyPRIVMSG(server, source, error) return { "success": False }
def lookUpLocation(self, server, source, user, displayErrors): if not self.bot.moduleHandler.useModuleOnServer(self.name, server): return if networkName(self.bot, server) in self.locations and user.lower( ) in self.locations[networkName(self.bot, server)]: return { "success": True, "place": self.locations[networkName(self.bot, server)][user.lower()] } if displayErrors: error = "Your location is not registered. Register your location by using the \"addloc\" command or " \ "provide a location." self.replyPRIVMSG(server, source, error) return {"success": False}
def lookUpLocation(self, server, source, user, displayErrors): if not self.bot.moduleHandler.useModuleOnServer(self.name, server): return if networkName(self.bot, server) in self.locations and user.lower() in self.locations[networkName(self.bot, server)]: return { "success": True, "place": self.locations[networkName(self.bot, server)][user.lower()] } if displayErrors: error = "Your location is not registered. Register your location by using the \"addloc\" command or " \ "provide a location." self.replyPRIVMSG(server, source, error) return { "success": False }
def execute(self, server, source, command, params, data): self.commandUsed = True if "channel" not in data: self.replyPRIVMSG(server, source, "Word counters can only be used in channels.") return if len(params) < 1: self.replyPRIVMSG(server, source, "You didn't specify a word.") return network = networkName(self.bot, server) if network not in self.wordCounters: self.wordCounters[network] = {} if source not in self.wordCounters[network]: self.wordCounters[network][source] = {} word = params[0].lower() if command == "addwordcount": if word in self.wordCounters[network][source]: self.replyPRIVMSG( server, source, "A counter for {!r} already exists.".format(word)) else: self.wordCounters[network][source][word] = {} self.bot.storage["wordcounts"] = self.wordCounters self.replyPRIVMSG( server, source, "A counter for {!r} has been added.".format(word)) elif command == "remwordcount": if word in self.wordCounters[network][source]: del self.wordCounters[network][source][word] self.bot.storage["wordcounts"] = self.wordCounters self.replyPRIVMSG( server, source, "The counter for {!r} has been removed.".format(word)) else: self.replyPRIVMSG( server, source, "A counter for {!r} does not exist.".format(word)) elif command == "wordcount": self.commandUsed = True if word not in self.wordCounters[network][source]: self.replyPRIVMSG( server, source, "A counter for {!r} does not exist.".format(word)) return total = sum(self.wordCounters[network][source][word].itervalues()) result = "The word {!r} has been said {} times.".format( word, total) if result > 0: top = max(self.wordCounters[network][source][word].iteritems(), key=operator.itemgetter(1)) result = "{} The top contributor is {} with {} times.".format( result, top[0], top[1]) self.replyPRIVMSG(server, source, result)
def execute(self, server, source, command, params, data): if networkName(self.bot, server) not in self.ignores: self.ignores[networkName(self.bot, server)] = [] if len(params) == 0: if len(self.ignores[networkName(self.bot, server)]) == 0: self.replyPRIVMSG(server, source, "There are no users that are ignored.") else: ignoredUsers = ", ".join(self.ignores[networkName( self.bot, server)]) self.replyPRIVMSG(server, source, "Ignoring users: {}.".format(ignoredUsers)) return success = [] fail = [] if command == "ignore": for ignore in params: if ignore.lower() in self.ignores[networkName( self.bot, server)]: fail.append(ignore) else: self.ignores[networkName(self.bot, server)].append(ignore.lower()) success.append(ignore) if len(success) > 0: self.bot.storage["ignore_list"] = self.ignores self.replyPRIVMSG( server, source, "Now ignoring: {}.".format(", ".join(success))) if len(fail) > 0: self.replyPRIVMSG( server, source, "Already ignored: {}.".format(", ".join(fail))) elif command == "unignore": for ignore in params: if ignore.lower() in self.ignores[networkName( self.bot, server)]: self.ignores[networkName(self.bot, server)].remove(ignore.lower()) success.append(ignore) else: fail.append(ignore) if len(success) > 0: self.bot.storage["ignore_list"] = self.ignores self.replyPRIVMSG( server, source, "No longer ignoring: {}.".format(", ".join(success))) if len(fail) > 0: self.replyPRIVMSG(server, source, "Not ignored: {}.".format(", ".join(fail)))
def _getQuote(self, server, source, searchString, searchNickname, index): if len(self.ooclog[networkName(self.bot, server)][source]) == 0: return "No quotes in the log." regex = re.compile(searchString, re.IGNORECASE) matches = [] if searchNickname: for x in self.ooclog[networkName(self.bot, server)][source]: if x[21] == "*": match = re.search(regex, x[:x.find(" ", 23)]) else: match = re.search(regex, x[x.find("<") + 1:x.find(">")]) if match: matches.append(x) else: for x in self.ooclog[networkName(self.bot, server)][source]: if re.search(regex, x[x.find(">") + 1:]): matches.append(x) if len(matches) == 0: return "No matches for {!r} found.".format(searchString) if index < 0 or index > len(matches) - 1: index = random.randint(0, len(matches) - 1) return "Quote #{}/{}: {}".format(index + 1, len(matches), matches[index])
def _processTells(self, server, source, nick): if networkName(self.bot, server) not in self.tells: return chanTells = [] pmTells = [] for tell in self.tells[networkName(self.bot, server)][:]: if not any(fnmatch(nick.lower(), r) for r in tell["to"].split("/")): continue if now() < tell["datetoreceive"]: continue if tell["source"][0] in self.bot.servers[server].supportHelper.chanTypes and len(chanTells) < 3: if tell["source"] == source: chanTells.append(tell) self.tells[networkName(self.bot, server)].remove(tell) elif tell["source"][0] not in self.bot.servers[server].supportHelper.chanTypes: pmTells.append(tell) self.tells[networkName(self.bot, server)].remove(tell) for tell in chanTells: self.replyPRIVMSG(server, source, self._parseTell(nick, tell)) for tell in pmTells: self.replyPRIVMSG(server, nick, self._parseTell(nick, tell)) if len(chanTells) > 0 or len(pmTells) > 0: self.bot.storage["tells"] = self.tells
def _postList(self, server, source, searchString, searchNickname): if len(self.ooclog[networkName(self.bot, server)][source]) == 0: return "No quotes in the log." regex = re.compile(searchString, re.IGNORECASE) matches = [] if searchNickname: for x in self.ooclog[networkName(self.bot, server)][source]: if x[21] == "*": match = re.search(regex, x[:x.find(" ", 23)]) else: match = re.search(regex, x[x.find("<") + 1:x.find(">")]) if match: matches.append(x) else: for x in self.ooclog[networkName(self.bot, server)][source]: if re.search(regex, x[x.find(">") + 1:]): matches.append(x) if len(matches) == 0: return "No matches for {!r} found.".format(searchString) result = self.bot.moduleHandler.runActionUntilValue("post-paste", "OoC Log", "\n".join(matches), 10) if not result: return "An error occurred. The PasteEE API seems to be down right now." return "List posted: {}".format(result)
def execute(self, server, source, command, params, data): self.commandUsed = True if "channel" not in data: self.replyPRIVMSG(server, source, "Word counters can only be used in channels.") return if len(params) < 1: self.replyPRIVMSG(server, source, "You didn't specify a word.") return network = networkName(self.bot, server) if network not in self.wordCounters: self.wordCounters[network] = {} if source not in self.wordCounters[network]: self.wordCounters[network][source] = {} word = params[0].lower() if command == "addwordcount": if word in self.wordCounters[network][source]: self.replyPRIVMSG(server, source, "A counter for {!r} already exists.".format(word)) else: self.wordCounters[network][source][word] = {} self.bot.storage["wordcounts"] = self.wordCounters self.replyPRIVMSG(server, source, "A counter for {!r} has been added.".format(word)) elif command == "remwordcount": if word in self.wordCounters[network][source]: del self.wordCounters[network][source][word] self.bot.storage["wordcounts"] = self.wordCounters self.replyPRIVMSG(server, source, "The counter for {!r} has been removed.".format(word)) else: self.replyPRIVMSG(server, source, "A counter for {!r} does not exist.".format(word)) elif command == "wordcount": self.commandUsed = True if word not in self.wordCounters[network][source]: self.replyPRIVMSG(server, source, "A counter for {!r} does not exist.".format(word)) return total = sum(self.wordCounters[network][source][word].itervalues()) result = "The word {!r} has been said {} times.".format(word, total) if result > 0: top = max(self.wordCounters[network][source][word].iteritems(), key=operator.itemgetter(1)) result = "{} The top contributor is {} with {} times.".format(result, top[0], top[1]) self.replyPRIVMSG(server, source, result)
def execute(self, server, source, command, params, data): if command == "addloc": if len(params) < 1: self.replyPRIVMSG(server, source, "What do you want to do with your location?") return if networkName(self.bot, server) not in self.locations: self.locations[networkName(self.bot, server)] = {} self.locations[networkName(self.bot, server)][data["user"].nick.lower()] = " ".join(params) self.bot.storage["userlocations"] = self.locations self.bot.moduleHandler.runGenericAction("userlocation-updated", data["user"].nick, " ".join(params)) self.replyPRIVMSG(server, source, "Your location has been updated.") elif command == "remloc": if data["user"].nick.lower() not in self.locations[networkName(self.bot, server)]: self.replyPRIVMSG(server, source, "Your location is not registered!") else: del self.locations[networkName(self.bot, server)][data["user"].nick.lower()] self.bot.storage["userlocations"] = self.locations self.bot.moduleHandler.runGenericAction("userlocation-deleted", data["user"].nick) self.replyPRIVMSG(server, source, "Your location has been removed.") elif command == "locimport": if len(params) < 1: self.replyPRIVMSG(server, source, "Import locations from where?") return if not os.path.isfile(params[0]): self.replyPRIVMSG(server, source, "Import file doesn't exist.") return with open(params[0]) as importFile: try: j = json.load(importFile) except ValueError as e: self.replyPRIVMSG(server, source, "An error occurred while reading the import file: {0}.".format(e)) return if networkName(self.bot, server) not in self.locations: self.locations[networkName(self.bot, server)] = {} skipped = 0 for nick, location in j.iteritems(): if nick in self.locations[networkName(self.bot, server)]: skipped += 1 continue self.locations[networkName(self.bot, server)][nick] = location self.bot.storage["userlocations"] = self.locations if skipped == 0: msg = "Imported {} location(s).".format(len(j)) else: msg = "Imported {} location(s). Skipped {} location(s) because of a nickname conflict." \ .format(len(j) - skipped, skipped) self.replyPRIVMSG(server, source, msg) elif command == "locexport": if len(params) < 1: self.replyPRIVMSG(server, source, "Export locations to where?") return with open(params[0], "w") as exportFile: if networkName(self.bot, server) not in self.locations: self.replyPRIVMSG(server, source, "No locations to export.") return locations = self.locations[networkName(self.bot, server)] json.dump(locations, exportFile, sort_keys=True, indent=4) self.replyPRIVMSG(server, source, "Exported {} location(s).".format(len(locations)))
def execute(self, server, source, command, params, data): if command == "addloc": if len(params) < 1: self.replyPRIVMSG( server, source, "What do you want to do with your location?") return if networkName(self.bot, server) not in self.locations: self.locations[networkName(self.bot, server)] = {} self.locations[networkName( self.bot, server)][data["user"].nick.lower()] = " ".join(params) self.bot.storage["userlocations"] = self.locations self.bot.moduleHandler.runGenericAction("userlocation-updated", data["user"].nick, " ".join(params)) self.replyPRIVMSG(server, source, "Your location has been updated.") elif command == "remloc": if data["user"].nick.lower() not in self.locations[networkName( self.bot, server)]: self.replyPRIVMSG(server, source, "Your location is not registered!") else: del self.locations[networkName( self.bot, server)][data["user"].nick.lower()] self.bot.storage["userlocations"] = self.locations self.bot.moduleHandler.runGenericAction( "userlocation-deleted", data["user"].nick) self.replyPRIVMSG(server, source, "Your location has been removed.") elif command == "locimport": if len(params) < 1: self.replyPRIVMSG(server, source, "Import locations from where?") return if not os.path.isfile(params[0]): self.replyPRIVMSG(server, source, "Import file doesn't exist.") return with open(params[0]) as importFile: try: j = json.load(importFile) except ValueError as e: self.replyPRIVMSG( server, source, "An error occurred while reading the import file: {0}." .format(e)) return if networkName(self.bot, server) not in self.locations: self.locations[networkName(self.bot, server)] = {} skipped = 0 for nick, location in j.iteritems(): if nick in self.locations[networkName(self.bot, server)]: skipped += 1 continue self.locations[networkName(self.bot, server)][nick] = location self.bot.storage["userlocations"] = self.locations if skipped == 0: msg = "Imported {} location(s).".format(len(j)) else: msg = "Imported {} location(s). Skipped {} location(s) because of a nickname conflict." \ .format(len(j) - skipped, skipped) self.replyPRIVMSG(server, source, msg) elif command == "locexport": if len(params) < 1: self.replyPRIVMSG(server, source, "Export locations to where?") return with open(params[0], "w") as exportFile: if networkName(self.bot, server) not in self.locations: self.replyPRIVMSG(server, source, "No locations to export.") return locations = self.locations[networkName(self.bot, server)] json.dump(locations, exportFile, sort_keys=True, indent=4) self.replyPRIVMSG( server, source, "Exported {} location(s).".format(len(locations)))
def countMessage(self, server, channel, user, body): self._countWords(networkName(self.bot, server), channel.name, user.nick, body)
def countAction(self, server, source, user, body): if body.upper().startswith("ACTION") and isinstance(source, IRCChannel): self._countWords(networkName(self.bot, server), source.name, user.nick, body)
def execute(self, server, source, command, params, data): if command == "tell" or command == "tellafter": if len(params) == 0 or len(params) == 1: self.replyPRIVMSG(server, source, "Tell who?") return elif len(params) == 1 and command == "tellafter": self.replyPRIVMSG(server, source, "Tell it when?") return elif len(params ) == 1 or len(params) == 2 and command == "tellafter": self.replyPRIVMSG(server, source, "Tell {} what?".format(params[0])) return sentTells = [] if command == "tellafter": try: date = datetime.strptime(params[1], "%Y-%m-%d") except ValueError: date = now() + durationToTimedelta(params[1]) else: date = now() for recep in params[0].split("&"): if recep.lower() == self.bot.servers[server].nick.lower(): self.replyPRIVMSG( server, source, "Thanks for telling me that, {}.".format( data["user"].nick)) continue message = { "to": recep.lower(), "body": " ".join(params[1:]) if command == "tell" else " ".join(params[2:]), "date": now(), "datetoreceive": date, "from": data["user"].nick, "source": source if source[0] in self.bot.servers[server].supportHelper.chanTypes else "PM" } if networkName(self.bot, server) not in self.tells: self.tells[networkName(self.bot, server)] = [] self.tells[networkName(self.bot, server)].append(message) sentTells.append(recep.replace("/", " or ")) if len(sentTells) > 0: if command == "tellafter": m = "Okay, I'll tell {} that when they speak after {}.".format( "&".join(sentTells), strftimeWithTimezone(date)) else: m = "Okay, I'll tell {} that next time they speak.".format( "&".join(sentTells)) self.replyPRIVMSG(server, source, m) self.bot.storage["tells"] = self.tells elif command == "stells": if networkName(self.bot, server) not in self.tells: return tells = [] for tell in self.tells[networkName(self.bot, server)]: if tell["from"].lower() == data["user"].nick.lower(): tells.append(self._parseSentTell(tell)) if len(tells) > 0: for tell in tells: self.replyNOTICE(server, data["user"].nick, tell) else: self.replyNOTICE( server, data["user"].nick, "No undelivered messages sent by you were found.") elif command == "rtell": if len(params) == 0: self.replyPRIVMSG(server, source, "Remove what?") return if networkName(self.bot, server) not in self.tells: self.replyNOTICE( server, data["user"].nick, "No tells matching {!r} were found.".format(params[0])) return tells = [ x for x in self.tells[networkName(self.bot, server)] if x["from"].lower() == data["user"].nick.lower() ] for tell in tells: if re.search(" ".join(params), tell["body"], re.IGNORECASE): self.tells[networkName(self.bot, server)].remove(tell) self.bot.storage["tells"] = self.tells m = "Message {!r} was removed from the message database.".format( self._parseSentTell(tell)) self.replyNOTICE(server, data["user"].nick, m) break else: self.replyNOTICE( server, data["user"].nick, "No tells matching {!r} were found.".format(params[0]))
def _removeQuote(self, server, source, quote): self.ooclog[networkName(self.bot, server)][source].remove(quote) self.bot.storage["ooclog"] = self.ooclog self.replyPRIVMSG(server, source, "Quote '{}' was removed from the log!".format(quote))
def execute(self, server, source, command, params, data): if command == "tell" or command == "tellafter": if len(params) == 0 or len(params) == 1: self.replyPRIVMSG(server, source, "Tell who?") return elif len(params) == 1 and command == "tellafter": self.replyPRIVMSG(server, source, "Tell it when?") return elif len(params) == 1 or len(params) == 2 and command == "tellafter": self.replyPRIVMSG(server, source, "Tell {} what?".format(params[0])) return sentTells = [] if command == "tellafter": try: date = datetime.strptime(params[1], "%Y-%m-%d") except ValueError: date = now() + durationToTimedelta(params[1]) else: date = now() for recep in params[0].split("&"): if recep.lower() == self.bot.servers[server].nick.lower(): self.replyPRIVMSG(server, source, "Thanks for telling me that, {}.".format(data["user"].nick)) continue message = { "to": recep.lower(), "body": " ".join(params[1:]) if command == "tell" else " ".join(params[2:]), "date": now(), "datetoreceive": date, "from": data["user"].nick, "source": source if source[0] in self.bot.servers[server].supportHelper.chanTypes else "PM" } if networkName(self.bot, server) not in self.tells: self.tells[networkName(self.bot, server)] = [] self.tells[networkName(self.bot, server)].append(message) sentTells.append(recep.replace("/", " or ")) if len(sentTells) > 0: if command == "tellafter": m = "Okay, I'll tell {} that when they speak after {}.".format("&".join(sentTells), strftimeWithTimezone(date)) else: m = "Okay, I'll tell {} that next time they speak.".format("&".join(sentTells)) self.replyPRIVMSG(server, source, m) self.bot.storage["tells"] = self.tells elif command == "stells": if networkName(self.bot, server) not in self.tells: return tells = [] for tell in self.tells[networkName(self.bot, server)]: if tell["from"].lower() == data["user"].nick.lower(): tells.append(self._parseSentTell(tell)) if len(tells) > 0: for tell in tells: self.replyNOTICE(server, data["user"].nick, tell) else: self.replyNOTICE(server, data["user"].nick, "No undelivered messages sent by you were found.") elif command == "rtell": if len(params) == 0: self.replyPRIVMSG(server, source, "Remove what?") return if networkName(self.bot, server) not in self.tells: self.replyNOTICE(server, data["user"].nick, "No tells matching {!r} were found.".format(params[0])) return tells = [x for x in self.tells[networkName(self.bot, server)] if x["from"].lower() == data[ "user"].nick.lower()] for tell in tells: if re.search(" ".join(params), tell["body"], re.IGNORECASE): self.tells[networkName(self.bot, server)].remove(tell) self.bot.storage["tells"] = self.tells m = "Message {!r} was removed from the message database.".format(self._parseSentTell(tell)) self.replyNOTICE(server, data["user"].nick, m) break else: self.replyNOTICE(server, data["user"].nick, "No tells matching {!r} were found.".format(params[0]))
def countAction(self, server, source, user, body): if body.upper().startswith("ACTION") and isinstance( source, IRCChannel): self._countWords(networkName(self.bot, server), source.name, user.nick, body)
def _removeQuote(self, server, source, quote): self.ooclog[networkName(self.bot, server)][source].remove(quote) self.bot.storage["ooclog"] = self.ooclog self.replyPRIVMSG(server, source, "Quote {!r} was removed from the log!".format(quote))
def execute(self, server, source, command, params, data): if networkName(self.bot, server) not in self.events: self.events[networkName(self.bot, server)] = [] if command == "event": if len(params) == 0: self.replyPRIVMSG(server, source, "Add what event?") return try: date = datetime.strptime(" ".join(params[0:2]), "%Y-%m-%d %H:%M") eventOffset = 2 if len(params) < 3: self.replyPRIVMSG(server, source, "Add what event?") return except ValueError: try: date = datetime.strptime(params[0], "%Y-%m-%d") eventOffset = 1 if len(params) < 2: self.replyPRIVMSG(server, source, "Add what event?") return except ValueError: e = "The date format you specified is invalid. The format is yyyy-MM-dd or yyyy-MM-dd HH:mm." self.replyPRIVMSG(server, source, e) return event = { "event": " ".join(params[eventOffset:]), "date": date, "user": data["user"].nick, "fired": True if date < now() else False } self.events[networkName(self.bot, server)].append(event) self.bot.storage["events"] = self.events m = "Event {!r} on date {} was added to the events database!".format(event["event"], strftimeWithTimezone(date)) self.replyPRIVMSG(server, source, m) elif command == "timetill": if len(params) == 0: self.replyPRIVMSG(server, source, "You didn't specify an event") return events = [x for x in self.events[networkName(self.bot, server)] if x["date"] > now()] events.sort(key=lambda item: item["date"]) for event in events: if re.search(" ".join(params), event["event"], re.IGNORECASE): m = "{}'s event {!r} will occur in {}.".format(event["user"], event["event"], timeDeltaString( event["date"], now())) self.replyPRIVMSG(server, source, m) break else: m = "No events matching {!r} were found in the events database.".format(" ".join(params)) self.replyPRIVMSG(server, source, m) elif command == "timesince": if len(params) == 0: self.replyPRIVMSG(server, source, "You didn't specify an event") return events = [x for x in self.events[networkName(self.bot, server)] if x["date"] < now()] events.sort(key=lambda item: item["date"], reverse=True) for event in events: if re.search(" ".join(params), event["event"], re.IGNORECASE): m = "{}'s event {!r} occurred {} ago.".format(event["user"], event["event"], timeDeltaString( now(), event["date"])) self.replyPRIVMSG(server, source, m) break else: m = "No events matching {!r} were found in the events database.".format(" ".join(params)) self.replyPRIVMSG(server, source, m) elif command == "dateof": if len(params) == 0: self.replyPRIVMSG(server, source, "You didn't specify an event") return events = [x for x in self.events[networkName(self.bot, server)] if x["date"] > now()] events.sort(key=lambda item: item["date"]) for event in events: if re.search(" ".join(params), event["event"], re.IGNORECASE): m = "{}'s event {!r} will occur on {}.".format(event["user"], event["event"], strftimeWithTimezone(event["date"])) self.replyPRIVMSG(server, source, m) break else: events = [x for x in self.events[networkName(self.bot, server)] if x["date"] < now()] events.sort(key=lambda item: item["date"], reverse=True) for event in events: if re.search(" ".join(params), event["event"], re.IGNORECASE): m = "{}'s event {!r} occurred on {}.".format(event["user"], event["event"], strftimeWithTimezone(event["date"])) self.replyPRIVMSG(server, source, m) break else: m = "No events matching {!r} were found in the events database.".format(" ".join(params)) self.replyPRIVMSG(server, source, m) elif command == "events": if len(params) == 0 or not isNumber(params[0]): days = 7 else: days = int(params[0]) if int(params[0]) < 365 else 365 events = [x for x in self.events[networkName(self.bot, server)] if x["date"] > now() and x[ "date"] <= now() + timedelta(days)] dayString = "" if days == 1 else "s" if len(events) > 0: events.sort(key=lambda item: item["date"]) eventNames = [x["event"] for x in events] m = "Events occurring in the next {} day{}: {}.".format(days, dayString, ", ".join(eventNames)) else: m = "No events are occurring in the next {} day{}.".format(days, dayString) self.replyPRIVMSG(server, source, m) elif command == "revent": if len(params) == 0: self.replyPRIVMSG(server, source, "You didn't specify an event") return events = [x for x in self.events[networkName(self.bot, server)] if x["date"] > now()] events.sort(key=lambda item: item["date"]) for event in events: if re.search(" ".join(params), event["event"], re.IGNORECASE): self.events[networkName(self.bot, server)].remove(event) self.bot.storage["events"] = self.events m = "{}'s event {!r} with date {} has been removed from the events database.".format( event["user"], event["event"], strftimeWithTimezone(event["date"])) self.replyPRIVMSG(server, source, m) break else: events = [x for x in self.events[networkName(self.bot, server)] if x["date"] < now() and x[ "user"].lower() == data["user"].nick.lower()] events.sort(key=lambda item: item["date"], reverse=True) for event in events: if re.search(" ".join(params), event["event"], re.IGNORECASE): self.events[networkName(self.bot, server)].remove(event) self.bot.storage["events"] = self.events m = "{}'s event {!r} with date {} has been removed from the events database.".format( event["user"], event["event"], strftimeWithTimezone(event["date"])) self.replyPRIVMSG(server, source, m) break else: m = "No events matching {!r} by you were found in the events database.".format(" ".join(params)) self.replyPRIVMSG(server, source, m) elif command == "subevent" or command == "unsubevent": if networkName(self.bot, server) not in self.subscriptions: self.subscriptions[networkName(self.bot, server)] = [] src = source if "channel" in data else data["user"].nick subAction = command == "subevent" self._handleSubscription(server, src, subAction)
def execute(self, server, source, command, params, data): if networkName(self.bot, server) not in self.ooclog: self.ooclog[networkName(self.bot, server)] = {} if source not in self.ooclog[networkName(self.bot, server)]: self.ooclog[networkName(self.bot, server)][source] = [] if command == "oocadd": if len(params) == 0: self.replyPRIVMSG(server, source, "Add what?") return if "channel" not in data: self.replyPRIVMSG(server, source, "You can only add quotes from a channel.") return regex = re.compile(re.escape(" ".join(params)), re.IGNORECASE) if len(self.messageBuffer) == 0: self.replyPRIVMSG(server, source, "Sorry, there are no lines in my message buffer.") return matches = filter(regex.search, self.messageBuffer[self.bot.servers[server]][data["channel"]]) if len(matches) == 0: self.replyPRIVMSG(server, source, "Sorry, that didn't match anything in my message buffer.") elif len(matches) > 1: self.replyPRIVMSG(server, source, "Sorry, that matches too many lines in my message buffer.") else: todayDate = time.strftime("[%Y-%m-%d] [%H:%M]") quote = "{} {}".format(todayDate, matches[0]) if quote.lower() in [x.lower() for x in self.ooclog[networkName(self.bot, server)][source]]: self.replyPRIVMSG(server, source, "That quote is already in the log!") else: self.ooclog[networkName(self.bot, server)][source].append(quote) self.bot.storage["ooclog"] = self.ooclog self.replyPRIVMSG(server, source, "Quote '{}' was added to the log!".format(quote)) elif command == "oocremove": if len(params) == 0: self.replyPRIVMSG(server, source, "Remove what?") return regex = re.compile(" ".join(params), re.IGNORECASE) matches = filter(regex.search, self.ooclog[networkName(self.bot, server)][source]) if len(matches) == 0: self.replyPRIVMSG(server, source, "That quote is not in the log.") elif len(matches) > 1: self.replyPRIVMSG(server, source, "Unable to remove quote, {} matches found.".format(len(matches))) else: self._removeQuote(server, source, matches[0]) elif command == "oocremoveid": if len(params) == 0 or not isNumber(params[0]): self.replyPRIVMSG(server, source, "You didn't specify a valid ID.") else: index = int(params[0]) - 1 quotes = self.ooclog[networkName(self.bot, server)][source] if index < len(quotes): self._removeQuote(server, source, quotes[index]) else: self.replyPRIVMSG(server, source, "That quote is not in the log.") elif command == "oocrandom": self.replyPRIVMSG(server, source, self._getQuote(server, source, "", False, -1)) elif command == "oocsearchnick" or command == "oocsearch": searchNick = command == "oocsearchnick" if len(params) == 0: quote = self._getQuote(server, source, data["user"].nick, searchNick, -1) elif len(params) == 1: quote = self._getQuote(server, source, params[0], searchNick, -1) elif isNumber(params[len(params) - 1]): quote = self._getQuote(server, source, " ".join(params[:len(params) - 1]), searchNick, int(params[len(params) - 1]) - 1) else: quote = self._getQuote(server, source, " ".join(params), searchNick, -1) self.replyPRIVMSG(server, source, quote) elif command == "oocid": if len(params) == 0 or not isNumber(params[0]): quote = "You didn't specify a valid ID." else: quote = self._getQuote(server, source, "", False, int(params[0]) - 1) self.replyPRIVMSG(server, source, quote) elif command == "ooclist": if len(params) > 0: subsubcommand = params.pop(0).lower() if subsubcommand == "searchnick": result = self._postList(server, source, " ".join(params), True) elif subsubcommand == "search": result = self._postList(server, source, " ".join(params), False) else: result = self._postList(server, source, "", False) else: result = self._postList(server, source, "", False) self.replyPRIVMSG(server, source, result)
def execute(self, server, source, command, params, data): if networkName(self.bot, server) not in self.ooclog: self.ooclog[networkName(self.bot, server)] = {} if source not in self.ooclog[networkName(self.bot, server)]: self.ooclog[networkName(self.bot, server)][source] = [] if command == "oocadd": if len(params) == 0: self.replyPRIVMSG(server, source, "Add what?") return if "channel" not in data: self.replyPRIVMSG(server, source, "You can only add quotes from a channel.") return regex = re.compile(re.escape(" ".join(params)), re.IGNORECASE) if len(self.messageBuffer) == 0: self.replyPRIVMSG( server, source, "Sorry, there are no lines in my message buffer.") return matches = filter( regex.search, self.messageBuffer[self.bot.servers[server]][data["channel"]]) if len(matches) == 0: self.replyPRIVMSG( server, source, "Sorry, that didn't match anything in my message buffer.") elif len(matches) > 1: self.replyPRIVMSG( server, source, "Sorry, that matches too many lines in my message buffer.") else: todayDate = time.strftime("[%Y-%m-%d] [%H:%M]") quote = "{} {}".format(todayDate, matches[0]) if quote.lower() in [ x.lower() for x in self.ooclog[networkName( self.bot, server)][source] ]: self.replyPRIVMSG(server, source, "That quote is already in the log!") else: self.ooclog[networkName(self.bot, server)][source].append(quote) self.bot.storage["ooclog"] = self.ooclog self.replyPRIVMSG( server, source, "Quote {!r} was added to the log!".format(quote)) elif command == "oocremove": if len(params) == 0: self.replyPRIVMSG(server, source, "Remove what?") return regex = re.compile(" ".join(params), re.IGNORECASE) matches = filter( regex.search, self.ooclog[networkName(self.bot, server)][source]) if len(matches) == 0: self.replyPRIVMSG(server, source, "That quote is not in the log.") elif len(matches) > 1: self.replyPRIVMSG( server, source, "Unable to remove quote, {} matches found.".format( len(matches))) else: self._removeQuote(server, source, matches[0]) elif command == "oocremoveid": if len(params) == 0 or not isNumber(params[0]): self.replyPRIVMSG(server, source, "You didn't specify a valid ID.") else: index = int(params[0]) - 1 quotes = self.ooclog[networkName(self.bot, server)][source] if index < len(quotes): self._removeQuote(server, source, quotes[index]) else: self.replyPRIVMSG(server, source, "That quote is not in the log.") elif command == "oocrandom": self.replyPRIVMSG(server, source, self._getQuote(server, source, "", False, -1)) elif command == "oocsearchnick" or command == "oocsearch": searchNick = command == "oocsearchnick" if len(params) == 0: quote = self._getQuote(server, source, data["user"].nick, searchNick, -1) elif len(params) == 1: quote = self._getQuote(server, source, params[0], searchNick, -1) elif isNumber(params[len(params) - 1]): quote = self._getQuote(server, source, " ".join(params[:len(params) - 1]), searchNick, int(params[len(params) - 1]) - 1) else: quote = self._getQuote(server, source, " ".join(params), searchNick, -1) self.replyPRIVMSG(server, source, quote) elif command == "oocid": if len(params) == 0 or not isNumber(params[0]): quote = "You didn't specify a valid ID." else: quote = self._getQuote(server, source, "", False, int(params[0]) - 1) self.replyPRIVMSG(server, source, quote) elif command == "ooclist": if len(params) > 0: subsubcommand = params.pop(0).lower() if subsubcommand == "searchnick": result = self._postList(server, source, " ".join(params), True) elif subsubcommand == "search": result = self._postList(server, source, " ".join(params), False) else: result = self._postList(server, source, "", False) else: result = self._postList(server, source, "", False) self.replyPRIVMSG(server, source, result)