Update to python 3
This commit is contained in:
parent
ffc9d7ca0d
commit
919cc0f505
18
bot.py
18
bot.py
|
@ -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__':
|
||||
|
|
|
@ -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
|
||||
|
|
28
core/irc.py
28
core/irc.py
|
@ -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
|
||||
|
|
14
core/main.py
14
core/main.py
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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$")
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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'))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]])
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue