2014-12-01 17:13:58 +00:00
|
|
|
"""Various network tools (w3m, w3c validator, curl, traceurl, ...)"""
|
|
|
|
|
2015-10-12 04:28:52 +00:00
|
|
|
# PYTHON STUFFS #######################################################
|
|
|
|
|
2015-06-24 23:55:29 +00:00
|
|
|
import logging
|
2015-09-07 17:07:43 +00:00
|
|
|
import re
|
2015-06-24 23:55:29 +00:00
|
|
|
|
2015-10-30 20:57:45 +00:00
|
|
|
from nemubot.exception import IMException
|
2015-01-03 19:34:44 +00:00
|
|
|
from nemubot.hooks import hook
|
2014-12-01 17:13:58 +00:00
|
|
|
|
|
|
|
from more import Response
|
|
|
|
|
|
|
|
from . import isup
|
|
|
|
from . import page
|
|
|
|
from . import w3c
|
2014-12-04 20:51:28 +00:00
|
|
|
from . import watchWebsite
|
2014-12-01 17:13:58 +00:00
|
|
|
from . import whois
|
|
|
|
|
2015-10-12 04:28:52 +00:00
|
|
|
logger = logging.getLogger("nemubot.module.networking")
|
|
|
|
|
|
|
|
|
|
|
|
# LOADING #############################################################
|
|
|
|
|
2014-12-01 17:13:58 +00:00
|
|
|
def load(context):
|
2014-12-04 20:51:28 +00:00
|
|
|
for mod in [isup, page, w3c, watchWebsite, whois]:
|
2015-02-11 17:12:39 +00:00
|
|
|
mod.add_event = context.add_event
|
|
|
|
mod.del_event = context.del_event
|
|
|
|
mod.save = context.save
|
2014-12-01 17:13:58 +00:00
|
|
|
mod.print = print
|
2015-02-11 17:12:39 +00:00
|
|
|
mod.send_response = context.send_response
|
|
|
|
page.load(context.config, context.add_hook)
|
|
|
|
watchWebsite.load(context.data)
|
2015-06-03 20:07:06 +00:00
|
|
|
try:
|
|
|
|
whois.load(context.config, context.add_hook)
|
|
|
|
except ImportError:
|
|
|
|
logger.exception("Unable to load netwhois module")
|
2014-12-01 17:13:58 +00:00
|
|
|
|
|
|
|
|
2015-10-12 04:28:52 +00:00
|
|
|
# MODULE INTERFACE ####################################################
|
2014-12-01 17:13:58 +00:00
|
|
|
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("title",
|
2015-10-12 04:28:52 +00:00
|
|
|
help="Retrieve webpage's title",
|
|
|
|
help_usage={"URL": "Display the title of the given URL"})
|
2015-09-07 17:07:43 +00:00
|
|
|
def cmd_title(msg):
|
|
|
|
if not len(msg.args):
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("Indicate the URL to visit.")
|
2015-09-07 17:07:43 +00:00
|
|
|
|
|
|
|
url = " ".join(msg.args)
|
|
|
|
res = re.search("<title>(.*?)</title>", page.fetch(" ".join(msg.args)), re.DOTALL)
|
|
|
|
|
|
|
|
if res is None:
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("The page %s has no title" % url)
|
2015-09-07 17:07:43 +00:00
|
|
|
else:
|
|
|
|
return Response("%s: %s" % (url, res.group(1).replace("\n", " ")), channel=msg.channel)
|
|
|
|
|
|
|
|
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("curly",
|
2015-10-12 04:28:52 +00:00
|
|
|
help="Retrieve webpage's headers",
|
|
|
|
help_usage={"URL": "Display HTTP headers of the given URL"})
|
2014-12-01 17:13:58 +00:00
|
|
|
def cmd_curly(msg):
|
2015-07-10 21:09:54 +00:00
|
|
|
if not len(msg.args):
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("Indicate the URL to visit.")
|
2014-12-01 17:13:58 +00:00
|
|
|
|
2015-07-10 21:09:54 +00:00
|
|
|
url = " ".join(msg.args)
|
2014-12-01 17:13:58 +00:00
|
|
|
version, status, reason, headers = page.headers(url)
|
|
|
|
|
|
|
|
return Response("Entêtes de la page %s : HTTP/%s, statut : %d %s ; headers : %s" % (url, version, status, reason, ", ".join(["\x03\x02" + h + "\x03\x02: " + v for h, v in headers])), channel=msg.channel)
|
|
|
|
|
|
|
|
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("curl",
|
2015-10-12 04:28:52 +00:00
|
|
|
help="Retrieve webpage's body",
|
|
|
|
help_usage={"URL": "Display raw HTTP body of the given URL"})
|
2014-12-01 17:13:58 +00:00
|
|
|
def cmd_curl(msg):
|
2015-07-10 21:09:54 +00:00
|
|
|
if not len(msg.args):
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("Indicate the URL to visit.")
|
2014-12-01 17:13:58 +00:00
|
|
|
|
|
|
|
res = Response(channel=msg.channel)
|
2015-07-10 21:09:54 +00:00
|
|
|
for m in page.fetch(" ".join(msg.args)).split("\n"):
|
2014-12-01 17:13:58 +00:00
|
|
|
res.append_message(m)
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("w3m",
|
2015-10-12 04:28:52 +00:00
|
|
|
help="Retrieve and format webpage's content",
|
|
|
|
help_usage={"URL": "Display and format HTTP content of the given URL"})
|
2014-12-01 17:13:58 +00:00
|
|
|
def cmd_w3m(msg):
|
2015-10-12 04:28:52 +00:00
|
|
|
if not len(msg.args):
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("Indicate the URL to visit.")
|
2015-10-12 04:28:52 +00:00
|
|
|
res = Response(channel=msg.channel)
|
|
|
|
for line in page.render(" ".join(msg.args)).split("\n"):
|
|
|
|
res.append_message(line)
|
|
|
|
return res
|
2014-12-01 17:13:58 +00:00
|
|
|
|
|
|
|
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("traceurl",
|
2015-10-12 04:28:52 +00:00
|
|
|
help="Follow redirections of a given URL and display each step",
|
|
|
|
help_usage={"URL": "Display redirections steps for the given URL"})
|
2014-12-01 17:13:58 +00:00
|
|
|
def cmd_traceurl(msg):
|
2015-10-12 04:28:52 +00:00
|
|
|
if not len(msg.args):
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("Indicate an URL to trace!")
|
2014-12-01 17:13:58 +00:00
|
|
|
|
2015-10-12 04:28:52 +00:00
|
|
|
res = list()
|
|
|
|
for url in msg.args[:4]:
|
|
|
|
try:
|
|
|
|
trace = page.traceURL(url)
|
|
|
|
res.append(Response(trace, channel=msg.channel, title="TraceURL"))
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
return res
|
|
|
|
|
2014-12-01 17:13:58 +00:00
|
|
|
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("isup",
|
2015-10-12 04:28:52 +00:00
|
|
|
help="Check if a website is up",
|
|
|
|
help_usage={"DOMAIN": "Check if a DOMAIN is up"})
|
2014-12-01 17:13:58 +00:00
|
|
|
def cmd_isup(msg):
|
2015-10-12 04:28:52 +00:00
|
|
|
if not len(msg.args):
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("Indicate an domain name to check!")
|
2015-10-12 04:28:52 +00:00
|
|
|
|
|
|
|
res = list()
|
|
|
|
for url in msg.args[:4]:
|
|
|
|
rep = isup.isup(url)
|
|
|
|
if rep:
|
|
|
|
res.append(Response("%s is up (response time: %ss)" % (url, rep), channel=msg.channel))
|
|
|
|
else:
|
|
|
|
res.append(Response("%s is down" % (url), channel=msg.channel))
|
|
|
|
return res
|
2014-12-01 17:13:58 +00:00
|
|
|
|
|
|
|
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("w3c",
|
2015-10-12 04:28:52 +00:00
|
|
|
help="Perform a w3c HTML validator check",
|
|
|
|
help_usage={"URL": "Do W3C HTML validation on the given URL"})
|
2014-12-01 17:13:58 +00:00
|
|
|
def cmd_w3c(msg):
|
2015-07-10 21:09:54 +00:00
|
|
|
if not len(msg.args):
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("Indicate an URL to validate!")
|
2014-12-01 17:13:58 +00:00
|
|
|
|
2015-07-10 21:09:54 +00:00
|
|
|
headers, validator = w3c.validator(msg.args[0])
|
2014-12-01 17:13:58 +00:00
|
|
|
|
|
|
|
res = Response(channel=msg.channel, nomore="No more error")
|
|
|
|
|
|
|
|
res.append_message("%s: status: %s, %s warning(s), %s error(s)" % (validator["url"], headers["X-W3C-Validator-Status"], headers["X-W3C-Validator-Warnings"], headers["X-W3C-Validator-Errors"]))
|
|
|
|
|
|
|
|
for m in validator["messages"]:
|
|
|
|
if "lastLine" not in m:
|
|
|
|
res.append_message("%s%s: %s" % (m["type"][0].upper(), m["type"][1:], m["message"]))
|
|
|
|
else:
|
|
|
|
res.append_message("%s%s on line %s, col %s: %s" % (m["type"][0].upper(), m["type"][1:], m["lastLine"], m["lastColumn"], m["message"]))
|
|
|
|
|
|
|
|
return res
|
2014-12-04 20:51:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("watch", data="diff",
|
2015-10-12 04:28:52 +00:00
|
|
|
help="Alert on webpage change",
|
|
|
|
help_usage={"URL": "Watch the given URL and alert when it changes"})
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("updown", data="updown",
|
2015-10-12 04:28:52 +00:00
|
|
|
help="Alert on server availability change",
|
|
|
|
help_usage={"URL": "Watch the given domain and alert when it availability status changes"})
|
2014-12-04 20:51:28 +00:00
|
|
|
def cmd_watch(msg, diffType="diff"):
|
2015-07-10 21:09:54 +00:00
|
|
|
if not len(msg.args):
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("indicate an URL to watch!")
|
2014-12-04 20:51:28 +00:00
|
|
|
|
2015-07-10 21:09:54 +00:00
|
|
|
return watchWebsite.add_site(msg.args[0], msg.frm, msg.channel, msg.server, diffType)
|
2014-12-04 20:51:28 +00:00
|
|
|
|
|
|
|
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("listwatch",
|
2015-10-12 04:28:52 +00:00
|
|
|
help="List URL watched for the channel",
|
|
|
|
help_usage={None: "List URL watched for the channel"})
|
2015-07-20 22:21:32 +00:00
|
|
|
def cmd_listwatch(msg):
|
|
|
|
wl = watchWebsite.watchedon(msg.channel)
|
|
|
|
if len(wl):
|
|
|
|
return Response(wl, channel=msg.channel, title="URL watched on this channel")
|
|
|
|
else:
|
|
|
|
return Response("No URL are currently watched. Use !watch URL to watch one.", channel=msg.channel)
|
|
|
|
|
|
|
|
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("unwatch",
|
2015-10-12 04:28:52 +00:00
|
|
|
help="Unwatch a previously watched URL",
|
|
|
|
help_usage={"URL": "Unwatch the given URL"})
|
2014-12-04 20:51:28 +00:00
|
|
|
def cmd_unwatch(msg):
|
2015-07-10 21:09:54 +00:00
|
|
|
if not len(msg.args):
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("which URL should I stop watching?")
|
2014-12-04 20:51:28 +00:00
|
|
|
|
2015-10-12 04:28:52 +00:00
|
|
|
for arg in msg.args:
|
|
|
|
return watchWebsite.del_site(arg, msg.frm, msg.channel, msg.frm_owner)
|