def _parseWeather(json):
    if "current_observation" not in json:
        return "No weather for this location could be found at this moment. Try again later."

    cond = json["current_observation"]
    tempC = cond["temp_c"]
    tempF = cond["temp_f"]
    feelslikeC = cond["feelslike_c"]
    feelslikeF = cond["feelslike_f"]
    description = cond["weather"]
    humidity = cond["relative_humidity"]
    winddir = cond["wind_dir"]
    windspeedMiles = cond["wind_mph"]
    windspeedMs = round(cond["wind_kph"] / 3.6, 1)
    stationID = cond["station_id"]
    feelslikeStr = ""
    if abs(float(tempC) - float(feelslikeC)) > 3.0:
        feelslikeStr = "(feels like {}°C / {}°F) ".format(
            feelslikeC, feelslikeF)

    if len(cond["estimated"]) > 0:
        latestUpdateStr = cond["estimated"]["description"]
    else:
        latestUpdate = (timestamp(now()) - int(cond["observation_epoch"])) / 60
        latestUpdateStr = "Latest Update: {}".format("{} minute(s) ago".format(latestUpdate) if latestUpdate > 0 \
                                                         else "just now")

    return "Temp: {}°C / {}°F {}| Weather: {} | Humidity: {} | Wind Speed: {} m/s / {} mph | " \
            "Wind Direction: {} | Station ID: {} | {}.".format(tempC, tempF, feelslikeStr, description, humidity,
                                                               windspeedMs,  windspeedMiles, winddir, stationID,
                                                               latestUpdateStr)
Beispiel #2
0
 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
Beispiel #3
0
 def checkEvents(self):
     for network in self.subscriptions:
         if network not in self.events:
             continue
         try:
             server = [x for x in self.bot.servers.itervalues() if x.supportHelper.network == network][0].name
         except IndexError:  # We're not currently connected to this network
             continue
         sources = [x for x in self.subscriptions[network] if x in self.bot.servers[server].channels or x in
                    self.bot.servers[server].users]
         if len(sources) == 0:
             continue  # Only fire events if there's a channel or user to fire them at
         events = []
         for i in range(0, len(self.events[network])):
             event = self.events[network][i]
             if event["date"] < now() and event["fired"] == False:
                 events.append(event)
                 self.events[network][i]["fired"] = True
         if len(events) == 0:
             continue
         self.bot.storage["events"] = self.events
         for source in sources:
             for event in events:
                 m = "{}'s event {!r} is happening right now!".format(event["user"], event["event"])
                 self.replyPRIVMSG(server, source, m)
Beispiel #4
0
 def __init__(self, configFile):
     self.config = Config(configFile)
     self.connectionFactory = HeufyBotFactory(self)
     self.log = None
     self.moduleHandler = ModuleHandler(self)
     self.servers = {}
     self.storage = None
     self.storageSync = None
     self.startTime = now()
Beispiel #5
0
 def __init__(self, configFile):
     self.config = Config(configFile)
     self.connectionFactory = HeufyBotFactory(self)
     self.log = None
     self.moduleHandler = ModuleHandler(self)
     self.servers = {}
     self.storage = None
     self.storageSync = None
     self.startTime = now()
Beispiel #6
0
    def handleCTCP(self, server, source, user, message):
        if not self.bot.moduleHandler.useModuleOnServer(self.name, server):
            return

        if message.upper() == "PING" or message.upper().startswith("PING "):
            self.sendCTCPReply(server, user.nick, "PING", message[5:])
        elif message.upper() == "VERSION":
            self.sendCTCPReply(server, user.nick, "VERSION", "PyHeufyBot v{} / {}".format(__version__, platform()))
        elif message.upper() == "TIME":
            self.sendCTCPReply(server, user.nick, "TIME", strftimeWithTimezone(now()))
        elif message.upper() == "SOURCE":
            self.sendCTCPReply(server, user.nick, "SOURCE", "https://github.com/Heufneutje/PyHeufyBot/")
Beispiel #7
0
 def _handleTOPIC(self, nick, ident, host, params):
     if params[0] not in self.connection.channels:
         self._logWarning("Received TOPIC message for unknown channel {}.".format(params[0]))
         return
     channel = self.connection.channels[params[0]]
     if nick not in self.connection.users:
         # A user that's not in the channel can change the topic so let's make a temporary user.
         user = IRCUser(nick, ident, host)
     else:
         user = self.connection.users[nick]
     oldTopic = channel.topic
     channel.topic = params[1]
     channel.topicSetter = user.fullUserPrefix()
     channel.topicTimestamp = timeutils.timestamp(timeutils.now())
     self.moduleHandler.runGenericAction("changetopic", self.connection.name, channel, user, oldTopic, params[1])
Beispiel #8
0
    def handleCTCP(self, server, source, user, message):
        if not self.bot.moduleHandler.useModuleOnServer(self.name, server):
            return

        if message.upper() == "PING" or message.upper().startswith("PING "):
            self.sendCTCPReply(server, user.nick, "PING", message[5:])
        elif message.upper() == "VERSION":
            self.sendCTCPReply(
                server, user.nick, "VERSION",
                "PyHeufyBot v{} / {}".format(__version__, platform()))
        elif message.upper() == "TIME":
            self.sendCTCPReply(server, user.nick, "TIME",
                               strftimeWithTimezone(now()))
        elif message.upper() == "SOURCE":
            self.sendCTCPReply(server, user.nick, "SOURCE",
                               "https://github.com/Heufneutje/PyHeufyBot/")
 def _getTime(self, lat, lon):
     currentTime = timestamp(now())
     params = {
         "location": "{},{}".format(lat, lon),
         "timestamp": currentTime
     }
     result = self.bot.moduleHandler.runActionUntilValue("fetch-url", self.timeBaseURL, params)
     if not result:
         return "No time for this location could be found at this moment. Try again later."
     timeJSON = result.json()
     if timeJSON["status"] != "OK":
         if "error_message" in timeJSON:
             return timeJSON["error_message"]
         else:
             return "An unknown error occurred while requesting the time."
     resultDate = datetime.fromtimestamp(currentTime + int(timeJSON["dstOffset"]) + int(timeJSON["rawOffset"]))
     properDay = self._getProperDay(resultDate.day)
     formattedTime = resultDate.strftime("%H:%M (%I:%M %p) on %A, " + properDay + " of %B, %Y")
     return "Timezone: {} | Local time is {}".format(timeJSON["timeZoneName"], formattedTime)
Beispiel #10
0
 def _handleTOPIC(self, nick, ident, host, params):
     if params[0] not in self.connection.channels:
         self._logWarning(
             "Received TOPIC message for unknown channel {}.".format(
                 params[0]))
         return
     channel = self.connection.channels[params[0]]
     if nick not in self.connection.users:
         # A user that's not in the channel can change the topic so let's make a temporary user.
         user = IRCUser(nick, ident, host)
     else:
         user = self.connection.users[nick]
     oldTopic = channel.topic
     channel.topic = params[1]
     channel.topicSetter = user.fullUserPrefix()
     channel.topicTimestamp = timeutils.timestamp(timeutils.now())
     self.moduleHandler.runGenericAction("changetopic",
                                         self.connection.name, channel,
                                         user, oldTopic, params[1])
Beispiel #11
0
 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
Beispiel #12
0
 def execute(self, server, source, command, params, data):
     start = strftimeWithTimezone(self.bot.startTime)
     delta = timeDeltaString(now(), self.bot.startTime)
     self.replyPRIVMSG(server, source, "I have been up since {} ({}).".format(start, delta))
Beispiel #13
0
 def _parseTell(self, nick, tell):
     return "{}: {} < From {} ({} ago).".format(nick, tell["body"], tell["from"], timeDeltaString(now(), tell["date"]))
Beispiel #14
0
 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]))
Beispiel #15
0
 def _parseTell(self, nick, tell):
     return "{}: {} < From {} ({} ago).".format(
         nick, tell["body"], tell["from"],
         timeDeltaString(now(), tell["date"]))
Beispiel #16
0
 def execute(self, server, source, command, params, data):
     start = strftimeWithTimezone(self.bot.startTime)
     delta = timeDeltaString(now(), self.bot.startTime)
     self.replyPRIVMSG(server, source,
                       "I have been up since {} ({}).".format(start, delta))
Beispiel #17
0
 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)
Beispiel #18
0
 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]))