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]
|
[Permissions]
|
||||||
# List of users (hostmasks as regex) and the commands they are allowed to execute.
|
# 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.
|
# * 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@.* = *,
|
yournickname\!yourusername@.* = *,
|
||||||
\!@some other user = join, part, invite
|
\!@some other user = join, part, invite
|
||||||
.*\!murderer@(localhost|127(\.0){2}\.1) = die,
|
.*\!murderer@(localhost|127(\.0){2}\.1) = die,
|
||||||
|
|
116
main.py
116
main.py
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
import sys, string, socket, re, signal, json, logging
|
import sys, string, socket, re, signal, json, logging
|
||||||
from random import choice
|
from random import choice
|
||||||
from time import sleep, time
|
from time import sleep, time, strftime, localtime
|
||||||
from select import poll, POLLIN, POLLPRI, POLLOUT,\
|
from select import poll, POLLIN, POLLPRI, POLLOUT,\
|
||||||
POLLERR, POLLHUP, POLLNVAL
|
POLLERR, POLLHUP, POLLNVAL
|
||||||
from threading import Thread, Event
|
from threading import Thread, Event
|
||||||
|
@ -59,6 +59,9 @@ class pircbot():
|
||||||
forecast_cfg = {"Active": "0"},
|
forecast_cfg = {"Active": "0"},
|
||||||
logger = logging.getLogger(logging.basicConfig())
|
logger = logging.getLogger(logging.basicConfig())
|
||||||
):
|
):
|
||||||
|
self.log = logger
|
||||||
|
|
||||||
|
|
||||||
self.nicknames = nicknames
|
self.nicknames = nicknames
|
||||||
self.ident = ident
|
self.ident = ident
|
||||||
self.realname = realname
|
self.realname = realname
|
||||||
|
@ -71,6 +74,9 @@ class pircbot():
|
||||||
self.query_type = query_type.upper()
|
self.query_type = query_type.upper()
|
||||||
self.cmdprefix = command_prefix
|
self.cmdprefix = command_prefix
|
||||||
self.msg_wait_time = float(msg_wait_time)
|
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.parser_wait_time = float(parser_wait_time)
|
||||||
|
|
||||||
self.users = users
|
self.users = users
|
||||||
|
@ -78,10 +84,8 @@ class pircbot():
|
||||||
self.duckduckgo_cfg = duckduckgo_cfg
|
self.duckduckgo_cfg = duckduckgo_cfg
|
||||||
self.forecast_cfg = forecast_cfg
|
self.forecast_cfg = forecast_cfg
|
||||||
|
|
||||||
self.log = logger
|
|
||||||
|
|
||||||
|
self.user = {"mask":"", "nick":"", "ident":"", "host":""}
|
||||||
self.user = {}
|
|
||||||
|
|
||||||
self.socket = None
|
self.socket = None
|
||||||
self.recvbuffer = bytearray(1024)
|
self.recvbuffer = bytearray(1024)
|
||||||
|
@ -210,11 +214,15 @@ class pircbot():
|
||||||
if command == "PING":
|
if command == "PING":
|
||||||
self.send("PONG %s" % params[0])
|
self.send("PONG %s" % params[0])
|
||||||
# PRIVMSG and NOTICE
|
# PRIVMSG and NOTICE
|
||||||
elif command == "PRIVMSG" or command == "NOTICE":
|
elif command == "PRIVMSG" or command == "NOTICE" and self.ready:
|
||||||
if params[1][0] == self.cmdprefix:
|
|
||||||
args = []
|
args = []
|
||||||
for v in params[1][1:].split(" "):
|
for v in params[1].split(" "):
|
||||||
if v!="": args.append(v)
|
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:])
|
rp = self.on_command(command, prefix, origin, params[0], args[0].lower(), args[1:])
|
||||||
if rp not in (None, ""):
|
if rp not in (None, ""):
|
||||||
self.reply(origin, params[0], rp, command)
|
self.reply(origin, params[0], rp, command)
|
||||||
|
@ -326,8 +334,11 @@ class pircbot():
|
||||||
self.send("".join(("PRIVMSG ", channel, " :", msg)))
|
self.send("".join(("PRIVMSG ", channel, " :", msg)))
|
||||||
|
|
||||||
# replies to user by NOTICE or PRIVMSG
|
# replies to user by NOTICE or PRIVMSG
|
||||||
def query(self, nick, msg, in_query_type):
|
def query(self, nick, msg, in_query_type="", force_query_type=""):
|
||||||
self.send("".join((self.query_type if self.query_type!="" else in_query_type, " ", nick, " :", msg)))
|
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):
|
def nick(self, nick):
|
||||||
self.exec_on_ready("".join(('self.send("JOIN %s" % "', channel, '")')))
|
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.
|
Params contains a list of originally space separated parameters.
|
||||||
"""
|
"""
|
||||||
numparams = len(params)
|
numparams = len(params)
|
||||||
# hello
|
### INTERNAL ###
|
||||||
if command == "hello":
|
# 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"] +"!"))
|
greeting = "".join(("Hi " + origin["nick"] +"!"))
|
||||||
return greeting
|
return greeting
|
||||||
# say
|
# say <text>
|
||||||
elif command == "say":
|
elif command == "say":
|
||||||
return " ".join(params)
|
return " ".join(params)
|
||||||
# choose
|
# choose <choice1>, <choice2>[, <choice3>[, ...]]
|
||||||
elif command == "choose":
|
elif command == "choose":
|
||||||
choices = " ".join(params).split(", ")# if numparams>1 else params.split(", ")
|
choices = " ".join(params).split(", ")# if numparams>1 else params.split(", ")
|
||||||
if choices[0] == "":
|
if choices[0] == "":
|
||||||
|
@ -376,6 +416,7 @@ class pircbot():
|
||||||
else:
|
else:
|
||||||
return choice(choices)
|
return choice(choices)
|
||||||
|
|
||||||
|
### EXTERNAL ###
|
||||||
# DuckDuckGo, ddg <query>
|
# DuckDuckGo, ddg <query>
|
||||||
elif command in ("duckduckgo", "ddg") and self.duckduckgo_cfg["Active"] == "1":
|
elif command in ("duckduckgo", "ddg") and self.duckduckgo_cfg["Active"] == "1":
|
||||||
if numparams==0:
|
if numparams==0:
|
||||||
|
@ -393,7 +434,7 @@ class pircbot():
|
||||||
)
|
)
|
||||||
rj = json.loads(str(rp.readall(), "utf-8"))
|
rj = json.loads(str(rp.readall(), "utf-8"))
|
||||||
empty_field_counter = 0
|
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 ("", []):
|
if rj[elem] not in ("", []):
|
||||||
self.reply(origin, source, "%s: %s" % (elem, rj[elem]), in_query_type)
|
self.reply(origin, source, "%s: %s" % (elem, rj[elem]), in_query_type)
|
||||||
else:
|
else:
|
||||||
|
@ -404,14 +445,55 @@ class pircbot():
|
||||||
return "(Results from DuckDuckGo <https://duckduckgo.com>)"
|
return "(Results from DuckDuckGo <https://duckduckgo.com>)"
|
||||||
else:
|
else:
|
||||||
return "Error while querying DuckDuckGo, got HTTP-Status %i" % rp.getcode()
|
return "Error while querying DuckDuckGo, got HTTP-Status %i" % rp.getcode()
|
||||||
# Forecast, fc, weather
|
# Forecast, fc <query>
|
||||||
elif command in ("weather", "forecast", "fc") and self.forecast_cfg["Active"] == "1":
|
elif command in ("forecast", "fc") and self.forecast_cfg["Active"] == "1":
|
||||||
if numparams==2:
|
if numparams==2:
|
||||||
|
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/>)"
|
return "(Powered by Forecast <http://forecast.io/>)"
|
||||||
|
else:
|
||||||
|
return "Error while querying Forecast.io, got HTTP-Status %i" % rp.getcode()
|
||||||
else:
|
else:
|
||||||
return "Usage: %s <lat> <lon>" % command
|
return "Usage: %s <lat> <lon>" % command
|
||||||
|
|
||||||
|
### IRC ###
|
||||||
# join <channel>
|
# join <channel>
|
||||||
elif command == "join":
|
elif command == "join":
|
||||||
if numparams>0:
|
if numparams>0:
|
||||||
|
|
Loading…
Reference in a new issue