From 2836356f12bfa299dea1a92eb11a66c4215faaf2 Mon Sep 17 00:00:00 2001 From: James Vega Date: Wed, 2 Feb 2005 05:29:31 +0000 Subject: [PATCH] Add the Internet plugin in the new plugin format. Also move Fun.hexip to the Internet plugin. --- plugins/Internet/README.txt | 1 + plugins/Internet/__init__.py | 60 ++++++++++++ plugins/Internet/config.py | 48 ++++++++++ plugins/Internet/plugin.py | 173 +++++++++++++++++++++++++++++++++++ plugins/Internet/test.py | 49 ++++++++++ setup.py | 1 + 6 files changed, 332 insertions(+) create mode 100644 plugins/Internet/README.txt create mode 100644 plugins/Internet/__init__.py create mode 100644 plugins/Internet/config.py create mode 100644 plugins/Internet/plugin.py create mode 100644 plugins/Internet/test.py diff --git a/plugins/Internet/README.txt b/plugins/Internet/README.txt new file mode 100644 index 000000000..d60b47a97 --- /dev/null +++ b/plugins/Internet/README.txt @@ -0,0 +1 @@ +Insert a description of your plugin here, with any notes, etc. about using it. diff --git a/plugins/Internet/__init__.py b/plugins/Internet/__init__.py new file mode 100644 index 000000000..f9e52e2e7 --- /dev/null +++ b/plugins/Internet/__init__.py @@ -0,0 +1,60 @@ +### +# Copyright (c) 2003-2005, Jeremiah Fincher +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions, and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions, and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author of this software nor the name of +# contributors to this software may be used to endorse or promote products +# derived from this software without specific prior written consent. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +### + +""" +Provides some internet-related commands. +""" + +import supybot +import supybot.world as world + +# Use this for the version of this plugin. You may wish to put a CVS keyword +# in here if you're keeping the plugin in CVS or some similar system. +__version__ = "%%VERSION%%" + +__author__ = supybot.authors.jemfinch + +# This is a dictionary mapping supybot.Author instances to lists of +# contributions. +__contributors__ = {supybot.authors.jamessan:'whois'} + +import config +import plugin +reload(plugin) # In case we're being reloaded. +# Add more reloads here if you add third-party modules and want them to be +# reloaded when this plugin is reloaded. Don't forget to import them as well! + +if world.testing: + import test + +Class = plugin.Class +configure = config.configure + + +# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: diff --git a/plugins/Internet/config.py b/plugins/Internet/config.py new file mode 100644 index 000000000..09498e07b --- /dev/null +++ b/plugins/Internet/config.py @@ -0,0 +1,48 @@ +### +# Copyright (c) 2003-2005, Jeremiah Fincher +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions, and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions, and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author of this software nor the name of +# contributors to this software may be used to endorse or promote products +# derived from this software without specific prior written consent. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +### + +import supybot.conf as conf +import supybot.registry as registry + +def configure(advanced): + # This will be called by supybot to configure this module. advanced is + # a bool that specifies whether the user identified himself as an advanced + # user or not. You should effect your configuration by manipulating the + # registry as appropriate. + from supybot.questions import expect, anything, something, yn + conf.registerPlugin('Internet', True) + + +Internet = conf.registerPlugin('Internet') +# This is where your configuration variables (if any) should go. For example: +# conf.registerGlobalValue(Internet, 'someConfigVariableName', +# registry.Boolean(False, """Help for someConfigVariableName.""")) + + +# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78 diff --git a/plugins/Internet/plugin.py b/plugins/Internet/plugin.py new file mode 100644 index 000000000..9fe0f5db2 --- /dev/null +++ b/plugins/Internet/plugin.py @@ -0,0 +1,173 @@ +### +# Copyright (c) 2003-2005, Jeremiah Fincher +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions, and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions, and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author of this software nor the name of +# contributors to this software may be used to endorse or promote products +# derived from this software without specific prior written consent. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +### + +import socket +import telnetlib + +import supybot.utils as utils +from supybot.commands import * +from supybot.utils.iter import any +import supybot.callbacks as callbacks + + +class Internet(callbacks.Privmsg): + """Add the help for "@help Internet" here.""" + threaded = True + def dns(self, irc, msg, args, host): + """ + + Returns the ip of or the reverse DNS hostname of . + """ + if utils.net.isIP(host): + hostname = socket.getfqdn(host) + if hostname == host: + irc.reply('Host not found.') + else: + irc.reply(hostname) + else: + try: + ip = socket.gethostbyname(host) + if ip == '64.94.110.11': # Verisign sucks! + irc.reply('Host not found.') + else: + irc.reply(ip) + except socket.error: + irc.reply('Host not found.') + dns = wrap(dns, ['something']) + + _tlds = set(['com', 'net', 'edu']) + _domain = ['Domain Name', 'Server Name', 'domain'] + _registrar = ['Sponsoring Registrar', 'Registrar', 'source'] + _updated = ['Last Updated On', 'Domain Last Updated Date', 'Updated Date', + 'Last Modified', 'changed'] + _created = ['Created On', 'Domain Registration Date', 'Creation Date'] + _expires = ['Expiration Date', 'Domain Expiration Date'] + _status = ['Status', 'Domain Status', 'status'] + def whois(self, irc, msg, args, domain): + """ + + Returns WHOIS information on the registration of . + """ + usertld = domain.split('.')[-1] + if '.' not in domain: + irc.error(' must be in .com, .net, .edu, or .org.') + return + elif len(domain.split('.')) != 2: + irc.error(' must be a domain, not a hostname.') + return + if usertld in self._tlds: + server = 'rs.internic.net' + search = '=%s' % domain + else: + server = '%s.whois-servers.net' % usertld + search = domain + try: + t = telnetlib.Telnet(server, 43) + except socket.error, e: + irc.error(str(e)) + return + t.write(search) + t.write('\n') + s = t.read_all() + server = registrar = updated = created = expires = status = '' + for line in s.splitlines(): + line = line.strip() + if not line or ':' not in line: + continue + if not server and any(line.startswith, self._domain): + server = ':'.join(line.split(':')[1:]).strip().lower() + # Let's add this check so that we don't respond with info for + # a different domain. E.g., doing a whois for microsoft.com + # and replying with the info for microsoft.com.wanadoodoo.com + if server != domain: + server = '' + continue + if not server: + continue + if not registrar and any(line.startswith, self._registrar): + registrar = ':'.join(line.split(':')[1:]).strip() + elif not updated and any(line.startswith, self._updated): + s = ':'.join(line.split(':')[1:]).strip() + updated = 'updated %s' % s + elif not created and any(line.startswith, self._created): + s = ':'.join(line.split(':')[1:]).strip() + created = 'registered %s' % s + elif not expires and any(line.startswith, self._expires): + s = ':'.join(line.split(':')[1:]).strip() + expires = 'expires %s' % s + elif not status and any(line.startswith, self._status): + status = ':'.join(line.split(':')[1:]).strip().lower() + if not status: + status = 'unknown' + try: + t = telnetlib.Telnet('whois.pir.org', 43) + except socket.error, e: + irc.error(str(e)) + return + t.write('registrar ') + t.write(registrar.split('(')[0].strip()) + t.write('\n') + s = t.read_all() + url = '' + for line in s.splitlines(): + line = line.strip() + if not line: + continue + if line.startswith('Email'): + url = ' ' % line.split('@')[-1] + elif line.startswith('Registrar Organization:'): + url = ' ' % line.split(':')[1].strip() + elif line == 'Not a valid ID pattern': + url = '' + if server and status: + info = filter(None, [status, created, updated, expires]) + s = format('%s%s is %L.', server, url, info) + irc.reply(s) + else: + irc.error('I couldn\'t find such a domain.') + whois = wrap(whois, ['lowered']) + + def hexip(self, irc, msg, args, ip): + """ + + Returns the hexadecimal IP for that IP. + """ + quads = ip.split('.') + ret = "" + for quad in quads: + i = int(quad) + ret += '%02x' % i + irc.reply(ret.upper()) + hexip = wrap(hexip, ['ip']) + + +Class = Internet + + +# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: diff --git a/plugins/Internet/test.py b/plugins/Internet/test.py new file mode 100644 index 000000000..1ffe9e901 --- /dev/null +++ b/plugins/Internet/test.py @@ -0,0 +1,49 @@ +### +# Copyright (c) 2003-2005, Jeremiah Fincher +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions, and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions, and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author of this software nor the name of +# contributors to this software may be used to endorse or promote products +# derived from this software without specific prior written consent. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +### + +from supybot.test import * + +class InternetTestCase(PluginTestCase): + plugins = ('Internet',) + if network: + def testDns(self): + self.assertNotError('dns slashdot.org') + self.assertResponse('dns alsdkjfaslkdfjaslkdfj.com', + 'Host not found.') + + def testWhois(self): + self.assertNotError('internet whois ohio-state.edu') + self.assertError('internet whois www.ohio-state.edu') + self.assertNotError('internet whois kuro5hin.org') + self.assertError('internet whois www.kuro5hin.org') + self.assertNotError('internet whois microsoft.com') + self.assertNotError('internet whois inria.fr') + + +# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: diff --git a/setup.py b/setup.py index 242e00f39..5761bf5bf 100644 --- a/setup.py +++ b/setup.py @@ -41,6 +41,7 @@ plugins = [ 'Games', 'Google', 'Herald', + 'Internet', 'Later', 'Math', 'Network',