Update to python 3

This commit is contained in:
Christine Dodrill 2015-11-15 08:36:35 -08:00
parent ffc9d7ca0d
commit 919cc0f505
17 changed files with 100 additions and 100 deletions

18
bot.py
View File

@ -1,7 +1,7 @@
#!/usr/bin/env python
import os
import Queue
import queue
import sys
import traceback
import time
@ -21,7 +21,7 @@ def main():
sys.path += ['lib']
os.chdir(sys.path[0] or '.') # do stuff relative to the install directory
print 'Loading plugins'
print('Loading plugins')
# bootstrap the reloader
eval(compile(open(os.path.join('core', 'reload.py'), 'U').read(),
@ -29,30 +29,30 @@ def main():
globals())
reload(init=True)
print 'Connecting to IRC'
print('Connecting to IRC')
try:
config()
if not hasattr(bot, 'config'):
exit()
except Exception, e:
print 'ERROR: malformed config file:', e
except Exception as e:
print('ERROR: malformed config file:', e)
traceback.print_exc()
sys.exit()
print 'Running main loop'
print('Running main loop')
while True:
reload() # these functions only do things
config() # if changes have occured
for conn in bot.conns.itervalues():
for conn in bot.conns.values():
try:
out = conn.out.get_nowait()
main(conn, out)
except Queue.Empty:
except queue.Empty:
pass
while all(conn.out.empty() for conn in bot.conns.itervalues()):
while all(conn.out.empty() for conn in bot.conns.values()):
time.sleep(.1)
if __name__ == '__main__':

View File

@ -46,7 +46,7 @@ def config():
try:
bot.config = json.load(open('config'))
bot._config_mtime = config_mtime
for name, conf in bot.config['connections'].iteritems():
for name, conf in bot.config['connections'].items():
if name in bot.conns:
bot.conns[name].set_conf(conf)
else:
@ -54,8 +54,8 @@ def config():
bot.conns[name] = SSLIRC(conf)
else:
bot.conns[name] = IRC(conf)
except ValueError, e:
print 'ERROR: malformed config!', e
except ValueError as e:
print('ERROR: malformed config!', e)
bot._config_mtime = 0

View File

@ -1,8 +1,8 @@
import re
import socket
import time
import thread
import Queue
import _thread
import queue
from ssl import wrap_socket, CERT_NONE, CERT_REQUIRED, SSLError
@ -20,7 +20,7 @@ def censor(text):
text = text.replace('\n', '').replace('\r', '')
replacement = '[censored]'
if 'censored_strings' in bot.config:
words = map(re.escape, bot.config['censored_strings'])
words = list(map(re.escape, bot.config['censored_strings']))
regex = re.compile('(%s)' % "|".join(words))
text = regex.sub(replacement, text)
return text
@ -33,8 +33,8 @@ class crlf_tcp(object):
def __init__(self, host, port, timeout=300):
self.ibuffer = ""
self.obuffer = ""
self.oqueue = Queue.Queue() # lines to be sent out
self.iqueue = Queue.Queue() # lines that were received
self.oqueue = queue.Queue() # lines to be sent out
self.iqueue = queue.Queue() # lines that were received
self.socket = self.create_socket()
self.host = host
self.port = port
@ -45,8 +45,8 @@ class crlf_tcp(object):
def run(self):
self.socket.connect((self.host, self.port))
thread.start_new_thread(self.recv_loop, ())
thread.start_new_thread(self.send_loop, ())
_thread.start_new_thread(self.recv_loop, ())
_thread.start_new_thread(self.send_loop, ())
def recv_from_socket(self, nbytes):
return self.socket.recv(nbytes)
@ -87,7 +87,7 @@ class crlf_tcp(object):
def send_loop(self):
while True:
line = self.oqueue.get().splitlines()[0][:500]
print ">>> %r" % line
print(">>> %r" % line)
self.obuffer += line.encode('utf-8', 'replace') + '\r\n'
while self.obuffer:
sent = self.socket.send(self.obuffer)
@ -133,12 +133,12 @@ class IRC(object):
def __init__(self, conf):
self.set_conf(conf)
self.out = Queue.Queue() # responses from the server are placed here
self.out = queue.Queue() # responses from the server are placed here
# format: [rawline, prefix, command, params,
# nick, user, host, paramlist, msg]
self.connect()
thread.start_new_thread(self.parse_loop, ())
_thread.start_new_thread(self.parse_loop, ())
def set_conf(self, conf):
self.conf = conf
@ -150,7 +150,7 @@ class IRC(object):
def connect(self):
self.conn = self.create_connection()
thread.start_new_thread(self.conn.run, ())
_thread.start_new_thread(self.conn.run, ())
self.cmd("NICK", [self.nick])
self.cmd("USER",
[self.conf.get('user', 'h'), "3", "*", self.conf.get('realname',
@ -203,18 +203,18 @@ class FakeIRC(IRC):
def __init__(self, conf):
self.set_conf(conf)
self.out = Queue.Queue() # responses from the server are placed here
self.out = queue.Queue() # responses from the server are placed here
self.f = open(fn, 'rb')
thread.start_new_thread(self.parse_loop, ())
_thread.start_new_thread(self.parse_loop, ())
def parse_loop(self):
while True:
msg = decode(self.f.readline()[9:])
if msg == '':
print "!!!!DONE READING FILE!!!!"
print("!!!!DONE READING FILE!!!!")
return
if msg.startswith(":"): # has a prefix

View File

@ -1,9 +1,9 @@
import fuckit
import thread
import _thread
import traceback
thread.stack_size(1024 * 512) # reduce vm size
_thread.stack_size(1024 * 512) # reduce vm size
class Input(dict):
@ -81,14 +81,14 @@ def run(func, input):
else:
out = func(input.inp)
if out is not None:
input.reply(unicode(out))
input.reply(str(out))
def do_sieve(sieve, bot, input, func, type, args):
try:
return sieve(bot, input, func, type, args)
except Exception:
print 'sieve error',
print('sieve error', end=' ')
traceback.print_exc()
return None
@ -100,7 +100,7 @@ class Handler(object):
def __init__(self, func):
self.func = func
self.input_queue = Queue.Queue()
thread.start_new_thread(self.start, ())
_thread.start_new_thread(self.start, ())
def start(self):
uses_db = 'db' in self.func._args
@ -151,14 +151,14 @@ def dispatch(input, kind, func, args, autohelp=False):
if func._thread:
bot.threads[func].put(input)
else:
thread.start_new_thread(run, (func, input))
_thread.start_new_thread(run, (func, input))
def match_command(command):
commands = list(bot.commands)
# do some fuzzy matching
prefix = filter(lambda x: x.startswith(command), commands)
prefix = [x for x in commands if x.startswith(command)]
if len(prefix) == 1:
return prefix[0]
elif prefix and command not in prefix:

View File

@ -14,7 +14,7 @@ if 'lastfiles' not in globals():
def make_signature(f):
return f.func_code.co_filename, f.func_name, f.func_code.co_firstlineno
return f.__code__.co_filename, f.__name__, f.__code__.co_firstlineno
def format_plug(plug, kind='', lpad=0, width=40):
@ -63,14 +63,14 @@ def reload(init=False):
fileset = set(glob.glob(os.path.join('plugins', '*.py')))
# remove deleted/moved plugins
for name, data in bot.plugs.iteritems():
for name, data in bot.plugs.items():
bot.plugs[name] = [x for x in data if x[0]._filename in fileset]
for filename in list(mtimes):
if filename not in fileset and filename not in core_fileset:
mtimes.pop(filename)
for func, handler in list(bot.threads.iteritems()):
for func, handler in list(bot.threads.items()):
if func._filename not in fileset:
handler.stop()
del bot.threads[func]
@ -92,16 +92,16 @@ def reload(init=False):
continue
# remove plugins already loaded from this filename
for name, data in bot.plugs.iteritems():
for name, data in bot.plugs.items():
bot.plugs[name] = [x for x in data
if x[0]._filename != filename]
for func, handler in list(bot.threads.iteritems()):
for func, handler in list(bot.threads.items()):
if func._filename == filename:
handler.stop()
del bot.threads[func]
for obj in namespace.itervalues():
for obj in namespace.values():
if hasattr(obj, '_hook'): # check for magic
if obj._thread:
bot.threads[obj] = Handler(obj)
@ -110,21 +110,21 @@ def reload(init=False):
bot.plugs[type] += [data]
if not init:
print '### new plugin (type: %s) loaded:' % \
type, format_plug(data)
print('### new plugin (type: %s) loaded:' % \
type, format_plug(data))
if changed:
bot.commands = {}
for plug in bot.plugs['command']:
name = plug[1]['name'].lower()
if not re.match(r'^\w+$', name):
print '### ERROR: invalid command name "%s" (%s)' % (name,
format_plug(plug))
print('### ERROR: invalid command name "%s" (%s)' % (name,
format_plug(plug)))
continue
if name in bot.commands:
print "### ERROR: command '%s' already registered (%s, %s)" % \
print("### ERROR: command '%s' already registered (%s, %s)" % \
(name, format_plug(bot.commands[name]),
format_plug(plug))
format_plug(plug)))
continue
bot.commands[name] = plug
@ -134,28 +134,28 @@ def reload(init=False):
bot.events[event].append((func, args))
if init:
print ' plugin listing:'
print(' plugin listing:')
if bot.commands:
# hack to make commands with multiple aliases
# print nicely
print ' command:'
print(' command:')
commands = collections.defaultdict(list)
for name, (func, args) in bot.commands.iteritems():
for name, (func, args) in bot.commands.items():
commands[make_signature(func)].append(name)
for sig, names in sorted(commands.iteritems()):
for sig, names in sorted(commands.items()):
names.sort(key=lambda x: (-len(x), x)) # long names first
out = ' ' * 6 + '%s:%s:%s' % sig
out += ' ' * (50 - len(out)) + ', '.join(names)
print out
print(out)
for kind, plugs in sorted(bot.plugs.iteritems()):
for kind, plugs in sorted(bot.plugs.items()):
if kind == 'command':
continue
print ' %s:' % kind
print(' %s:' % kind)
for plug in plugs:
print format_plug(plug, kind=kind, lpad=6)
print
print(format_plug(plug, kind=kind, lpad=6))
print()

View File

@ -6,7 +6,7 @@ import json
quotes = []
with open("./plugins/data/bobross.json", "r") as fin:
print fin
print(fin)
quotes = json.load(fin)
@hook.regex("^[Bb]ob [Rr]oss fact$")

View File

@ -10,7 +10,7 @@ def help(inp, bot=None, pm=None):
funcs = {}
disabled = bot.config.get('disabled_plugins', [])
disabled_comm = bot.config.get('disabled_commands', [])
for command, (func, args) in bot.commands.iteritems():
for command, (func, args) in bot.commands.items():
fn = re.match(r'^plugins.(.+).py$', func._filename)
if fn.group(1).lower() not in disabled:
if command not in disabled_comm:
@ -21,7 +21,7 @@ def help(inp, bot=None, pm=None):
else:
funcs[func] = command
commands = dict((value, key) for key, value in funcs.iteritems())
commands = dict((value, key) for key, value in funcs.items())
if not inp:
pm('available commands: ' + ' '.join(sorted(commands)))

View File

@ -100,4 +100,4 @@ def log(paraml, input=None, bot=None):
fd = get_log_fd(bot.persist_dir, input.server, input.chan)
fd.write(timestamp + ' ' + beau + '\n')
print timestamp, input.chan, beau.encode('utf8', 'ignore')
print(timestamp, input.chan, beau.encode('utf8', 'ignore'))

View File

@ -7,7 +7,7 @@ import ponyapi
def get_time(ep):
now = datetime.datetime(2006, 1, 1)
now = now.now()
then = now.fromtimestamp(int(ep[u"air_date"]))
then = now.fromtimestamp(int(ep["air_date"]))
td = then-now
return now, then, td
@ -21,15 +21,15 @@ def when(inp, say=None):
seasonep = ""
if inp == "discord":
return "%s will air on %s" % (ep[u"name"], DDate(then))
return "%s will air on %s" % (ep["name"], DDate(then))
if ep[u"is_movie"]:
if ep["is_movie"]:
seasonep = "(a movie)"
else:
seasonep = "(season %d episode %d)" % (ep[u"season"], ep[u"episode"])
seasonep = "(season %d episode %d)" % (ep["season"], ep["episode"])
reply = "%s %s will air on %s in %d days!" % (
ep[u"name"], seasonep, then.strftime("%a, %d %b %Y %H:%M:%S"),
ep["name"], seasonep, then.strftime("%a, %d %b %Y %H:%M:%S"),
td.days)
return reply
@ -41,9 +41,9 @@ def randomep(inp):
seasonep = ""
if ep[u"is_movie"]:
if ep["is_movie"]:
seasonep = "(a movie)"
else:
seasonep = "(season %d episode %d)" % (ep[u"season"], ep[u"episode"])
seasonep = "(season %d episode %d)" % (ep["season"], ep["episode"])
return "%s %s" % (ep[u"name"], seasonep)
return "%s %s" % (ep["name"], seasonep)

View File

@ -28,11 +28,11 @@ def sieve_suite(bot, input, func, kind, args):
if acl is None:
continue
if 'deny-except' in acl:
allowed_channels = map(unicode.lower, acl['deny-except'])
allowed_channels = list(map(str.lower, acl['deny-except']))
if input.chan.lower() not in allowed_channels:
return None
if 'allow-except' in acl:
denied_channels = map(unicode.lower, acl['allow-except'])
denied_channels = list(map(str.lower, acl['allow-except']))
if input.chan.lower() in denied_channels:
return None
if 'whitelist' in acl:

View File

@ -5,5 +5,5 @@ from util import hook, http
def tinyurl(match):
try:
return http.open(match.group()).url.strip()
except http.URLError, e:
except http.URLError as e:
pass

View File

@ -8,7 +8,7 @@ prefix = split_len(names, 3)
suffix = split_len(endings, 3)
def ipv4tourbit(ip):
ip = map(lambda x: int(x), ip.split("."))
ip = [int(x) for x in ip.split(".")]
return "~%s%s-%s%s" % (prefix[ip[0]], suffix[ip[1]], prefix[ip[2]], suffix[ip[3]])

View File

@ -29,7 +29,7 @@ def get_history(db, chan, url):
def nicklist(nicks):
nicks = sorted(dict(nicks), key=unicode.lower)
nicks = sorted(dict(nicks), key=str.lower)
if len(nicks) <= 2:
return ' and '.join(nicks)
else:

View File

@ -8,7 +8,7 @@ def _hook_add(func, add, name=''):
func._hook.append(add)
if not hasattr(func, '_filename'):
func._filename = func.func_code.co_filename
func._filename = func.__code__.co_filename
if not hasattr(func, '_args'):
argspec = inspect.getargspec(func)
@ -39,7 +39,7 @@ def _hook_add(func, add, name=''):
def sieve(func):
if func.func_code.co_argcount != 5:
if func.__code__.co_argcount != 5:
raise ValueError(
'sieves must take 5 arguments: (bot, input, func, type, args)')
_hook_add(func, ['sieve', (func,)])
@ -50,7 +50,7 @@ def command(arg=None, **kwargs):
args = {}
def command_wrapper(func):
args.setdefault('name', func.func_name)
args.setdefault('name', func.__name__)
_hook_add(func, ['command', (func, args)], 'command')
return func
@ -67,7 +67,7 @@ def event(arg=None, **kwargs):
args = kwargs
def event_wrapper(func):
args['name'] = func.func_name
args['name'] = func.__name__
args.setdefault('events', ['*'])
_hook_add(func, ['event', (func, args)], 'event')
return func
@ -96,7 +96,7 @@ def regex(regex, flags=0, **kwargs):
args = kwargs
def regex_wrapper(func):
args['name'] = func.func_name
args['name'] = func.__name__
args['regex'] = regex
args['re'] = re.compile(regex, flags)
_hook_add(func, ['regex', (func, args)], 'regex')

View File

@ -1,18 +1,18 @@
# convenience wrapper for urllib2 & friends
import binascii
import cookielib
import http.cookiejar
import hmac
import json
import random
import string
import time
import urllib
import urllib2
import urlparse
import urllib.request, urllib.parse, urllib.error
import urllib.request, urllib.error, urllib.parse
import urllib.parse
from hashlib import sha1
from urllib import quote, unquote, quote_plus as _quote_plus
from urllib2 import HTTPError, URLError
from urllib.parse import quote, unquote, quote_plus as _quote_plus
from urllib.error import HTTPError, URLError
from lxml import etree, html
@ -23,7 +23,7 @@ ua_firefox = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) ' \
'Gecko/20070725 Firefox/2.0.0.6'
ua_internetexplorer = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
jar = cookielib.CookieJar()
jar = http.cookiejar.CookieJar()
def get(*args, **kwargs):
@ -51,13 +51,13 @@ def open(url, query_params=None, post_data=None,
url = prepare_url(url, query_params)
request = urllib2.Request(url, post_data)
request = urllib.request.Request(url, post_data)
if get_method is not None:
request.get_method = lambda: get_method
if headers is not None:
for header_key, header_value in headers.iteritems():
for header_key, header_value in headers.items():
request.add_header(header_key, header_value)
if 'User-Agent' not in request.headers:
@ -78,28 +78,28 @@ def open(url, query_params=None, post_data=None,
request.add_header('Authorization', header)
if cookies:
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(jar))
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar))
else:
opener = urllib2.build_opener()
opener = urllib.request.build_opener()
return opener.open(request)
def prepare_url(url, queries):
if queries:
scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
scheme, netloc, path, query, fragment = urllib.parse.urlsplit(url)
query = dict(urlparse.parse_qsl(query))
query = dict(urllib.parse.parse_qsl(query))
query.update(queries)
query = urllib.urlencode(dict((to_utf8(key), to_utf8(value))
for key, value in query.iteritems()))
query = urllib.parse.urlencode(dict((to_utf8(key), to_utf8(value))
for key, value in query.items()))
url = urlparse.urlunsplit((scheme, netloc, path, query, fragment))
url = urllib.parse.urlunsplit((scheme, netloc, path, query, fragment))
return url
def to_utf8(s):
if isinstance(s, unicode):
if isinstance(s, str):
return s.encode('utf8', 'ignore')
else:
return str(s)

View File

@ -69,7 +69,7 @@ def timesince(d, now=None):
since = delta.days * 24 * 60 * 60 + delta.seconds
if since <= 0:
# d is in the future compared to now, stop processing.
return u'0 ' + 'minutes'
return '0 ' + 'minutes'
for i, (seconds, name) in enumerate(chunks):
count = since // seconds
if count != 0:

View File

@ -25,8 +25,8 @@ __license__ = "Python"
import re
import unicodedata
import urlparse
from urllib import quote, unquote
import urllib.parse
from urllib.parse import quote, unquote
default_port = {
'http': 80,
@ -50,7 +50,7 @@ normalizers = ( Normalizer( re.compile(r'(?:https?://)?(?:[a-zA-Z0-9\-]+\.)?(?:a
def normalize(url):
"""Normalize a URL."""
scheme, auth, path, query, fragment = urlparse.urlsplit(url.strip())
scheme, auth, path, query, fragment = urllib.parse.urlsplit(url.strip())
userinfo, host, port = re.search('([^@]*@)?([^:]*):?(.*)', auth).groups()
# Always provide the URI scheme in lowercase characters.
@ -73,7 +73,7 @@ def normalize(url):
# Always use uppercase A-through-F characters when percent-encoding.
# All portions of the URI must be utf-8 encoded NFC from Unicode strings
def clean(string):
string = unicode(unquote(string), 'utf-8', 'replace')
string = str(unquote(string), 'utf-8', 'replace')
return unicodedata.normalize('NFC', string).encode('utf-8')
path = quote(clean(path), "~:/?#[]@!$&'()*+,;=")
fragment = quote(clean(fragment), "~")
@ -112,7 +112,7 @@ def normalize(url):
# For schemes that define a port, use an empty port if the default is
# desired
if port and scheme in default_port.keys():
if port and scheme in list(default_port.keys()):
if port.isdigit():
port = str(int(port))
if int(port) == default_port[scheme]:
@ -124,7 +124,7 @@ def normalize(url):
auth += ":" + port
if url.endswith("#") and query == "" and fragment == "":
path += "#"
normal_url = urlparse.urlunsplit((scheme, auth, path, query,
normal_url = urllib.parse.urlunsplit((scheme, auth, path, query,
fragment)).replace("http:///", "http://")
for norm in normalizers:
m = norm.regex.match(normal_url)