added commands help and forecast
implemented usage of bot-nick as cmdprefix changed min time for waiting between channel privmsgs to 0.1sec changed the way pircbot.query() chooses between NOTICE or PRIVMSG some minor fixes and commenting
This commit is contained in:
parent
421c206719
commit
f7289a1ac4
2 changed files with 104 additions and 21 deletions
|
@ -47,7 +47,8 @@ Modes = +iB
|
|||
[Permissions]
|
||||
# List of users (hostmasks as regex) and the commands they are allowed to execute.
|
||||
# * can be used instead of commands to allow every command. You should append a trailing comma.
|
||||
# All command names should be lowercase.
|
||||
# All command names should be lowercase. Add "help" as a command if you want the user
|
||||
# to see all aviable commands in the help message (is automatically included with "*").
|
||||
yournickname\!yourusername@.* = *,
|
||||
\!@some other user = join, part, invite
|
||||
.*\!murderer@(localhost|127(\.0){2}\.1) = die,
|
||||
|
|
122
main.py
122
main.py
|
@ -28,7 +28,7 @@
|
|||
|
||||
import sys, string, socket, re, signal, json, logging
|
||||
from random import choice
|
||||
from time import sleep, time
|
||||
from time import sleep, time, strftime, localtime
|
||||
from select import poll, POLLIN, POLLPRI, POLLOUT,\
|
||||
POLLERR, POLLHUP, POLLNVAL
|
||||
from threading import Thread, Event
|
||||
|
@ -59,6 +59,9 @@ class pircbot():
|
|||
forecast_cfg = {"Active": "0"},
|
||||
logger = logging.getLogger(logging.basicConfig())
|
||||
):
|
||||
self.log = logger
|
||||
|
||||
|
||||
self.nicknames = nicknames
|
||||
self.ident = ident
|
||||
self.realname = realname
|
||||
|
@ -71,6 +74,9 @@ class pircbot():
|
|||
self.query_type = query_type.upper()
|
||||
self.cmdprefix = command_prefix
|
||||
self.msg_wait_time = float(msg_wait_time)
|
||||
if self.msg_wait_time < 0.1:
|
||||
self.log.info("msg_wait_time ist zu klein, nutze 0.1 Sekunden")
|
||||
self.msg_wait_time = 0.1
|
||||
self.parser_wait_time = float(parser_wait_time)
|
||||
|
||||
self.users = users
|
||||
|
@ -78,10 +84,8 @@ class pircbot():
|
|||
self.duckduckgo_cfg = duckduckgo_cfg
|
||||
self.forecast_cfg = forecast_cfg
|
||||
|
||||
self.log = logger
|
||||
|
||||
|
||||
self.user = {}
|
||||
self.user = {"mask":"", "nick":"", "ident":"", "host":""}
|
||||
|
||||
self.socket = None
|
||||
self.recvbuffer = bytearray(1024)
|
||||
|
@ -210,11 +214,15 @@ class pircbot():
|
|||
if command == "PING":
|
||||
self.send("PONG %s" % params[0])
|
||||
# PRIVMSG and NOTICE
|
||||
elif command == "PRIVMSG" or command == "NOTICE":
|
||||
if params[1][0] == self.cmdprefix:
|
||||
args = []
|
||||
for v in params[1][1:].split(" "):
|
||||
if v!="": args.append(v)
|
||||
elif command == "PRIVMSG" or command == "NOTICE" and self.ready:
|
||||
args = []
|
||||
for v in params[1].split(" "):
|
||||
if v!="": args.append(v)
|
||||
if len(args)>1 and args[0][0:len(self.user["nick"])] == self.user["nick"]:
|
||||
args.pop(0)
|
||||
args[0] = "".join((self.cmdprefix, args[0]))
|
||||
if args[0][0] == self.cmdprefix:
|
||||
args[0] = args[0][1:]
|
||||
rp = self.on_command(command, prefix, origin, params[0], args[0].lower(), args[1:])
|
||||
if rp not in (None, ""):
|
||||
self.reply(origin, params[0], rp, command)
|
||||
|
@ -326,8 +334,11 @@ class pircbot():
|
|||
self.send("".join(("PRIVMSG ", channel, " :", msg)))
|
||||
|
||||
# replies to user by NOTICE or PRIVMSG
|
||||
def query(self, nick, msg, in_query_type):
|
||||
self.send("".join((self.query_type if self.query_type!="" else in_query_type, " ", nick, " :", msg)))
|
||||
def query(self, nick, msg, in_query_type="", force_query_type=""):
|
||||
self.send("".join((force_query_type if force_query_type!="" else
|
||||
(self.query_type if self.query_type!="" else
|
||||
(in_query_type if in_query_type!="" else
|
||||
"PRIVMSG")), " ", nick, " :", msg)))
|
||||
|
||||
def nick(self, nick):
|
||||
self.exec_on_ready("".join(('self.send("JOIN %s" % "', channel, '")')))
|
||||
|
@ -359,14 +370,43 @@ class pircbot():
|
|||
Params contains a list of originally space separated parameters.
|
||||
"""
|
||||
numparams = len(params)
|
||||
# hello
|
||||
if command == "hello":
|
||||
### INTERNAL ###
|
||||
# help [me]
|
||||
if command == "help":
|
||||
if numparams == 1 and params[0].startswith("me"):
|
||||
rply = "\
|
||||
Nope, you're on your own."
|
||||
else:
|
||||
rply = "\
|
||||
Command Prefix is \"%s\" or \"%s\"\n\
|
||||
\n\
|
||||
Commands:\n\
|
||||
hello [<...>]\n\
|
||||
say <text>\n\
|
||||
choose <choice1>, <choice2>[, <choice3>[, ...]] -- Let the bot decide!\n\
|
||||
DuckDuckGo, ddg <query> -- Ask the DuckDuckGo Instant Answer API\n\
|
||||
Forecast, fc <query> -- Query Forecast.io\n\
|
||||
" % (
|
||||
self.cmdprefix,
|
||||
self.user["nick"]
|
||||
)
|
||||
if self.check_privileges(origin["mask"], command):
|
||||
rply += " \n\
|
||||
~ For the aristocrats ~\n\
|
||||
join <channel>\n\
|
||||
part <channel>\n\
|
||||
mode ±<modes>\n\
|
||||
die [<quitmsg>]"
|
||||
for line in rply.splitlines(): self.query(origin["nick"], line[20:], force_query_type="PRIVMSG")
|
||||
|
||||
# hello [<...>]
|
||||
elif command == "hello":
|
||||
greeting = "".join(("Hi " + origin["nick"] +"!"))
|
||||
return greeting
|
||||
# say
|
||||
# say <text>
|
||||
elif command == "say":
|
||||
return " ".join(params)
|
||||
# choose
|
||||
# choose <choice1>, <choice2>[, <choice3>[, ...]]
|
||||
elif command == "choose":
|
||||
choices = " ".join(params).split(", ")# if numparams>1 else params.split(", ")
|
||||
if choices[0] == "":
|
||||
|
@ -376,6 +416,7 @@ class pircbot():
|
|||
else:
|
||||
return choice(choices)
|
||||
|
||||
### EXTERNAL ###
|
||||
# DuckDuckGo, ddg <query>
|
||||
elif command in ("duckduckgo", "ddg") and self.duckduckgo_cfg["Active"] == "1":
|
||||
if numparams==0:
|
||||
|
@ -393,7 +434,7 @@ class pircbot():
|
|||
)
|
||||
rj = json.loads(str(rp.readall(), "utf-8"))
|
||||
empty_field_counter = 0
|
||||
for elem in [rj for rj in used_fields]:
|
||||
for elem in [v for v in used_fields if v in rj]:
|
||||
if rj[elem] not in ("", []):
|
||||
self.reply(origin, source, "%s: %s" % (elem, rj[elem]), in_query_type)
|
||||
else:
|
||||
|
@ -404,14 +445,55 @@ class pircbot():
|
|||
return "(Results from DuckDuckGo <https://duckduckgo.com>)"
|
||||
else:
|
||||
return "Error while querying DuckDuckGo, got HTTP-Status %i" % rp.getcode()
|
||||
# Forecast, fc, weather
|
||||
elif command in ("weather", "forecast", "fc") and self.forecast_cfg["Active"] == "1":
|
||||
# Forecast, fc <query>
|
||||
elif command in ("forecast", "fc") and self.forecast_cfg["Active"] == "1":
|
||||
if numparams==2:
|
||||
|
||||
return "(Powered by Forecast <http://forecast.io/>)"
|
||||
try: rp = urlopen("https://api.forecast.io/forecast/%s/%s?units=si&exclude=minutely,hourly,daily"
|
||||
% (self.forecast_cfg["ApiKey"], quote_plus(",".join(params))))
|
||||
except Exception as e:
|
||||
self.log.error("Error while querying Forecast.io: %s" % e)
|
||||
return "Error while querying Forecast.io: %s" % e
|
||||
if rp.getcode() == 200:
|
||||
rj = json.loads(str(rp.readall(), "utf-8"))
|
||||
self.reply(origin, source,
|
||||
strftime("CURRENTLY (%d.%m.%Y %H:%M:%S)", localtime(rj["currently"]["time"])), in_query_type)
|
||||
self.reply(origin, source,
|
||||
"Summary: %s" % rj["currently"]["summary"], in_query_type)
|
||||
self.reply(origin, source,
|
||||
"Temperature: %s °C" % rj["currently"]["temperature"], in_query_type)
|
||||
self.reply(origin, source,
|
||||
"Apparent Temperature: %s °C" % rj["currently"]["apparentTemperature"], in_query_type)
|
||||
self.reply(origin, source,
|
||||
"Dew Point: %s °C" % rj["currently"]["dewPoint"], in_query_type)
|
||||
self.reply(origin, source,
|
||||
"Wind Speed: %s m/s" % rj["currently"]["windSpeed"], in_query_type)
|
||||
self.reply(origin, source,
|
||||
"Cloud Cover: %s %%" % rj["currently"]["cloudCover"], in_query_type)
|
||||
self.reply(origin, source,
|
||||
"Precipitation Probability: %s %%" % (rj["currently"]["precipProbability"]*100), in_query_type)
|
||||
if "precipIntensity" in rj["currently"]: self.reply(origin, source,
|
||||
"Precipitation Intensity: %s mm/h" % rj["currently"]["precipIntensity"], in_query_type)
|
||||
if "precipType" in rj["currently"]: self.reply(origin, source,
|
||||
"Precipitation Type: %s" % rj["currently"]["precipType"], in_query_type)
|
||||
self.reply(origin, source,
|
||||
"Visibility: %s km" % rj["currently"]["visibility"], in_query_type)
|
||||
self.reply(origin, source,
|
||||
"Humidity: %s %%" % (rj["currently"]["humidity"]*100), in_query_type)
|
||||
self.reply(origin, source,
|
||||
"Pressure: %s hPa" % rj["currently"]["pressure"], in_query_type)
|
||||
self.reply(origin, source,
|
||||
"Ozone: %s DU" % rj["currently"]["ozone"], in_query_type)
|
||||
if "nearestStormDistance" in rj["currently"]: self.reply(origin, source,
|
||||
"Nearest Storm Distance: %s km" % rj["currently"]["nearestStormDistance"], in_query_type)
|
||||
self.reply(origin, source,
|
||||
"Sources: %s" % ", ".join(rj["flags"]["sources"]), in_query_type)
|
||||
return "(Powered by Forecast <http://forecast.io/>)"
|
||||
else:
|
||||
return "Error while querying Forecast.io, got HTTP-Status %i" % rp.getcode()
|
||||
else:
|
||||
return "Usage: %s <lat> <lon>" % command
|
||||
|
||||
### IRC ###
|
||||
# join <channel>
|
||||
elif command == "join":
|
||||
if numparams>0:
|
||||
|
|
Loading…
Reference in a new issue