def show_tells(self, nick): try: conn = sqlite3.connect(self.db_file) c = conn.cursor() result = c.execute("SELECT sender, message, timestamp, unix_timestamp FROM tell WHERE " "lower(recipient) = ?", [nick.lower()]).fetchall() for msg in result: self.message(nick, None, "$(bold){}$(clear) left you a message: {} - Sent on {} ({} ago)" .format(msg[0], msg[1], msg[2], duration.timesincetimestamp(int(msg[3]))), True) if msg[0] == "$(lime)TellModule": # We don't want this kind of recursion. continue if nick.lower() != msg[0].lower(): udata = self.getUserData(msg[0]) # Let the sender know message has been sent if they're online. if udata: self.message(msg[0], None, "Delivered message '{}' to {} sent on {}." .format(msg[1], nick, msg[2])) else: # Manually add a new entry to the database to let the user know their message was delivered. sender = "$(lime)TellModule" rcvmsg = ("Your message '{}' to {} has been delivered (Sent by you on: {})." .format(msg[1], nick, msg[2])) timestamp = time.strftime("%Y-%m-%d %H:%M:%S %Z") unix_timestamp = int(time.time()) c.execute("INSERT INTO tell (sender, recipient, message, timestamp, unix_timestamp) " "VALUES (?, ?, ?, ?, ?)", [sender, msg[0], rcvmsg, timestamp, unix_timestamp]) self.hastells[msg[0].lower()] = True c.execute("DELETE FROM tell WHERE lower(recipient) = ?", [nick.lower()]) self.hastells[nick.lower()] = False conn.commit() conn.close() except sqlite3.Error as e: self.error("show_tells({}) error: {}".format(nick, str(e))) return False return True
def get_seen(self, nickname): if not self.validator.nickname(nickname): self.warning("seen: Tried to get seen data from invalid nickname {}".format(nickname)) return False nickname = nickname.lower() response = "" try: conn = sqlite3.connect(self.db_file) c = conn.cursor() result = c.execute("SELECT * FROM seen WHERE lower(nick) = ?", [nickname]).fetchone() if len(result) > 4: response = ("{} ({}) was last seen on {} ({} ago) {}" .format(result[0], result[1], result[2], duration.timesincetimestamp(int(result[3])), result[4])) conn.close() except sqlite3.Error as e: self.error("get_seen({}) error: {}".format(nickname, str(e))) return response
def parse_weather(self, json): """ So once we actually *have* our result, we want to make a nice (set of) strings from it. This function looks in the json that is available and retrieves: the forecast, possible alerts, and location data. """ if json and "location" in json and "forecast" in json: retlist = [] fctxt = json["forecast"]["txt_forecast"] # Check if it has a state to later append it extras = "" if "state" in json["location"]: if json["location"]["state"]: extras = json["location"]["state"] + ", " # Check if there are any alerts alerts = False if "alerts" in json and len(json["alerts"]): alerts = True if alerts: # If there are alerts, we don't put it on the results line, but give it 1 or 2 separate line(s). retlist.append("Results for {}, {}{}, {}.".format(json["location"]["city"], extras, json["location"]["country_name"], json["location"]["country"])) # Figure out alert data. alerts = json["alerts"][0] type = alerts["type"] desc = alerts["description"] signif = alerts["significance"] timedata = "" starts = int(alerts["date_epoch"]) ends = int(alerts["expires_epoch"]) if int(time.time()) < starts: timedata = ("starts in {}".format(duration.timesincetimestamp(starts))) elif int(time.time()) < ends: timedata = ("{} remaining before alert ends".format(duration.timebeforetimestamp(ends))) else: timedata = ("ended {} ago".format(duration.timesincetimestamp(ends))) message = alerts["message"].replace("\n", " ").replace(" ", " ").strip(" .") if len(message) > 50: message = message[:50] + ".." retlist.append("$(red){} Type Alert!$(clear) - {} ({}, significance: {}): {}" .format(type, desc, timedata, signif, message)) else: # If there aren't alerts, add it on to the main line. retlist.append("Results for {}, {}{}, {} - No weather alerts in the area." .format(json["location"]["city"], extras, json["location"]["country_name"], json["location"]["country"])) itters = 0 unit_type = "fcttext" if self.module_data["use_imperial"] else "fcttext_metric" if "forecastday" in fctxt: for fcday in fctxt["forecastday"]: if self.module_data["forecasts_ignore_night"] and fcday["title"].endswith("Night"): continue itters += 1 retlist.append("Forecast for {}: {}".format(fcday["title"], fcday[unit_type])) if itters >= self.module_data["forecasts_max"]: break if retlist: return retlist return "No results found" if "error" in json["response"]: return ("Could not parse forecast (Error: {} - {})" .format(json["response"]["error"]["type"], json["response"]["error"]["description"])) return "Could not parse forecast"
def lastfm_nowplaying(self, target, nick, account): api_url = "http://ws.audioscrobbler.com/2.0/?format=json" api_key = self.api_key["lastfm"] payload = { "format": "json", "user": account, "api_key": api_key, "method": "user.getrecenttracks", "limit": 1 } json = "" try: r = requests.get(api_url, params=payload) r.raise_for_status() json = r.json() except Exception as e: self.warning("Could not retrieve LastFM np information for {}: {}".format(account, str(e))) self.message(target, nick, "Could not retrieve information: {}".format(str(e))) acct = "" lfmstr = "" if "message" in json: return self.message(target, nick, json["message"]) if "@attr" in json: acct = json["@attr"]["user"] else: acct = account if "recenttracks" in json and "track" in json["recenttracks"]: if not len(json["recenttracks"]["track"]): return self.message(target, nick, "{} has not listened to any tracks recently.".format(acct)) json = json["recenttracks"]["track"] if type(json) == dict: # Not currently playing. artist = json["artist"]["#text"] song = json["name"] album = json["album"]["#text"] if album != song and album != artist: album = "from the album '$(bold){}$(bold)'".format(album) else: album = "" timeago = duration.timesincetimestamp(int(json["date"]["uts"])) lfmstr = ("$(bold){}$(bold) last listened to '$(bold){}$(bold)' by " "'$(bold){}$(bold)' {} ({} ago)" .format(acct, song, artist, album, timeago)).rstrip() + "." elif type(json) == list: # Currently playing json = json[0] artist = json["artist"]["#text"] song = json["name"] album = json["album"]["#text"] if album and album != song and album != artist: album = "from the album '$(bold){}$(bold)'".format(album) else: album = "" lfmstr = ("$(bold){}$(bold) is listening to '$(bold){}$(bold)' by " "'$(bold){}$(bold)' {}" .format(acct, song, artist, album)).rstrip() + "." else: lfmstr = "Could not determine {}'s last played song.".format(acct) if lfmstr: return self.message(target, nick, lfmstr, True) else: return self.message(target, nick, "Unable to fetch last.fm information from {}.".format(acct))
def on_command(self, target, nick, command, commandtext, mod, admin): if target.startswith("#"): if command == "fdsettings": purdur = duration.timesincetimestamp(self.last_purge) expdur = duration.timesincetimestamp(time.time() - self.expiry) return self.notice(nick, ("Max Warns: {}, Interval: {}, Messages Per Interval: {}, Expiry: {} ({}), " "Last Purge: {} ago".format(self.getWarnMaxCount(), self.module_data["message_interval"], self.module_data["message_max_per_interval"], expdur, self.expiry, purdur))) if command == "fdinfo": if not self.isOp(nick, target) and not mod: return self.notice(nick, "Sorry, you need to be an OP to use this command.") if target not in self.module_data["channels"]: return self.notice(nick, "You need to use this command in a flood detecting channel.") if not commandtext: return self.notice(nick, "Usage: fdinfo <nick>") if commandtext.lower() not in self.flood_detect[target]: return self.message(target, nick, "No data found on user.") self.logreport("fdinfo on {} requested by {} in {}.".format(commandtext, nick, target)) return self.notice(nick, str(self.flood_detect[target][commandtext.lower()])) if command == "fdpurge": if not self.isOp(nick, target) and not mod: return self.notice(nick, "Sorry, you need to be an OP to use this command.") if target not in self.module_data["channels"]: return self.notice(nick, "You need to use this command in a flood detecting channel.") self.logreport("fdpurge on {} requested by {} in {}.".format(commandtext, nick, target)) self.flood_detect[target] = {} return self.notice(nick, "Data purged for channel.") if command == "fdpurgenick": if not self.isOp(nick, target) and not mod: return self.notice(nick, "Sorry, you need to be an OP to use this command.") if target not in self.module_data["channels"]: return self.notice(nick, "You need to use this command in a flood detecting channel.") if not commandtext: return self.notice(nick, "Usage: fdpurgenick <nick>") if target not in self.flood_detect: self.createDict(target, commandtext) self.logreport("fdpurgenick on {} requested by {} in {}.".format(commandtext, nick, target)) self.flood_detect[target][nick.lower()] = {"messages": [], "warnings": 0} return self.notice(nick, "Data purged for nick '{}' on '{}'.".format(commandtext, target)) if mod: if command == "fdchans": if self.module_data["channels"]: return self.message(target, nick, "I am checking for flooding in: {}" .format(self.module_data["channels"])) if command == "fddisable": if target in self.module_data["channels"]: newchannels = self.module_data["channels"].replace(target, "").replace(",,", ",").rstrip(",") self.module_data["channels"] = newchannels self.channels = self.module_data["channels"].replace(" ", "").split(",") self.logreport("Disabled Flood Detection in {} (requested by {})".format(target, nick)) return self.message(target, nick, "Flood Detection disabled for {}.".format(target)) return self.message(target, nick, "Flood Detection not enabled in channel.") if command == "fdenable": if target not in self.module_data["channels"]: self.module_data["channels"] += "," + target self.channels = self.module_data["channels"].replace(" ", "").split(",") self.logreport("Enabled Flood Detection in {} (requested by {})".format(target, nick)) return self.message(target, nick, "Flood Detection enabled for {}.".format(target)) return self.message(target, nick, "Flood Detection already enabled in channel.") return False