Port to Python3

This commit is contained in:
Alexei Sorokin 2016-07-28 21:25:38 +03:00
parent 2c85e34daf
commit 6d59e02735
3 changed files with 76 additions and 69 deletions

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys import sys
@ -9,7 +9,10 @@ from ircbot import SingleServerIRCBot
from ircbot import Channel from ircbot import Channel
from irclib import nm_to_n from irclib import nm_to_n
from threading import Thread from threading import Thread
from ConfigParser import SafeConfigParser if sys.version_info >= (3, 0):
from configparser import SafeConfigParser
else:
from ConfigParser import SafeConfigParser
class IRCBot(SingleServerIRCBot): class IRCBot(SingleServerIRCBot):
@ -43,7 +46,7 @@ class IRCBot(SingleServerIRCBot):
c.nick(self.nickname) c.nick(self.nickname)
def on_welcome(self, c, e): def on_welcome(self, c, e):
print 'Connected to IRC' print('Connected to IRC')
c.join(self.channel) c.join(self.channel)
def on_pubmsg(self, c, e): def on_pubmsg(self, c, e):
@ -56,7 +59,7 @@ class IRCBot(SingleServerIRCBot):
buffer = 460 buffer = 460
for i in range(0, len(m), buffer): for i in range(0, len(m), buffer):
inter.irc(m[i:i + buffer].encode('latin-1', 'replace')) inter.irc(m[i:i + buffer])
elif str(e.arguments()[0]) == '.help': elif str(e.arguments()[0]) == '.help':
m = 'The only command I know is \'.users\'. Also, my owner is ' \ m = 'The only command I know is \'.users\'. Also, my owner is ' \
@ -64,7 +67,7 @@ class IRCBot(SingleServerIRCBot):
buffer = 460 buffer = 460
for i in range(0, len(m), buffer): for i in range(0, len(m), buffer):
inter.irc(m[i:i + buffer].encode('latin-1', 'replace')) inter.irc(m[i:i + buffer])
else: else:
message = '[' + from_nick + '] ' + ''.join(e.arguments()) message = '[' + from_nick + '] ' + ''.join(e.arguments())
@ -127,12 +130,10 @@ class XMPPBot(sleekxmpp.ClientXMPP):
buffer = 460 buffer = 460
for i in range(0, len(text), buffer): for i in range(0, len(text), buffer):
inter.irc(text[i:i + buffer].encode('latin-1', inter.irc(text[i:i + buffer])
'replace'))
except Exception as e: except Exception as e:
print e print(e)
pass
def xmpp_presence(self, event): def xmpp_presence(self, event):
try: try:
@ -145,17 +146,16 @@ class XMPPBot(sleekxmpp.ClientXMPP):
else: else:
if nick not in self.chanmuc.muc_users(): if nick not in self.chanmuc.muc_users():
self.chanmuc.muc_add_user(nick.decode()) self.chanmuc.muc_add_user(nick)
except Exception as e: except Exception as e:
print e print(e)
pass
def start(self): def start(self):
self.jabber.register_plugin('xep_0045') # XMPP MUC. self.jabber.register_plugin('xep_0045') # XMPP MUC.
self.jabber.register_plugin('xep_0199') # XMPP Ping. self.jabber.register_plugin('xep_0199') # XMPP Ping.
if self.jabber.connect(): if self.jabber.connect():
# sys.stderr.write('connected with %s\n'%con) # sys.stderr.write('connected with %s\n'%con)
print 'Connected to XMPP' print('Connected to XMPP')
self.register_handlers() self.register_handlers()
self.jabber.process(block=True) self.jabber.process(block=True)
else: else:
@ -239,4 +239,4 @@ if __name__ == '__main__':
z.join() z.join()
w.join() w.join()
except (KeyboardInterrupt, SystemExit): except (KeyboardInterrupt, SystemExit):
print 'Exit' print('Exit')

View File

@ -25,7 +25,10 @@ write simpler bots.
""" """
import sys import sys
from UserDict import UserDict if sys.version_info >= (3, 0):
from collections import UserDict
else:
from UserDict import UserDict
from irclib import SimpleIRCClient from irclib import SimpleIRCClient
from irclib import nm_to_n, irc_lower, all_events from irclib import nm_to_n, irc_lower, all_events
@ -160,7 +163,7 @@ class SingleServerIRCBot(SimpleIRCClient):
"""[Internal]""" """[Internal]"""
before = nm_to_n(e.source()) before = nm_to_n(e.source())
after = e.target() after = e.target()
for ch in self.channels.values(): for ch in list(self.channels.values()):
if ch.has_user(before): if ch.has_user(before):
ch.change_nick(before, after) ch.change_nick(before, after)
@ -177,7 +180,7 @@ class SingleServerIRCBot(SimpleIRCClient):
def _on_quit(self, c, e): def _on_quit(self, c, e):
"""[Internal]""" """[Internal]"""
nick = nm_to_n(e.source()) nick = nm_to_n(e.source())
for ch in self.channels.values(): for ch in list(self.channels.values()):
if ch.has_user(nick): if ch.has_user(nick):
ch.remove_user(nick) ch.remove_user(nick)
@ -284,7 +287,7 @@ class IRCDict:
def __iter__(self): def __iter__(self):
return iter(self.data) return iter(self.data)
def __contains__(self, key): def __contains__(self, key):
return self.has_key(key) return key in self
def clear(self): def clear(self):
self.data.clear() self.data.clear()
self.canon_keys.clear() self.canon_keys.clear()
@ -294,15 +297,15 @@ class IRCDict:
import copy import copy
return copy.copy(self) return copy.copy(self)
def keys(self): def keys(self):
return self.data.keys() return list(self.data.keys())
def items(self): def items(self):
return self.data.items() return list(self.data.items())
def values(self): def values(self):
return self.data.values() return list(self.data.values())
def has_key(self, key): def has_key(self, key):
return irc_lower(key) in self.canon_keys return irc_lower(key) in self.canon_keys
def update(self, dict): def update(self, dict):
for k, v in dict.items(): for k, v in list(dict.items()):
self.data[k] = v self.data[k] = v
def get(self, key, failobj=None): def get(self, key, failobj=None):
return self.data.get(key, failobj) return self.data.get(key, failobj)
@ -322,16 +325,16 @@ class Channel:
def users(self): def users(self):
"""Returns an unsorted list of the channel's users.""" """Returns an unsorted list of the channel's users."""
return self.userdict.keys() return list(self.userdict.keys())
def opers(self): def opers(self):
"""Returns an unsorted list of the channel's operators.""" """Returns an unsorted list of the channel's operators."""
return self.operdict.keys() return list(self.operdict.keys())
def voiced(self): def voiced(self):
"""Returns an unsorted list of the persons that have voice """Returns an unsorted list of the persons that have voice
mode set in the channel.""" mode set in the channel."""
return self.voiceddict.keys() return list(self.voiceddict.keys())
def has_user(self, nick): def has_user(self, nick):
"""Check whether the channel has a user.""" """Check whether the channel has a user."""

View File

@ -207,8 +207,8 @@ class IRC:
incoming data, if there are any. If that seems boring, look incoming data, if there are any. If that seems boring, look
at the process_forever method. at the process_forever method.
""" """
sockets = map(lambda x: x._get_socket(), self.connections) sockets = [x._get_socket() for x in self.connections]
sockets = filter(lambda x: x != None, sockets) sockets = [x for x in sockets if x != None]
if sockets: if sockets:
(i, o, e) = select.select(sockets, [], [], timeout) (i, o, e) = select.select(sockets, [], [], timeout)
self.process_data(i) self.process_data(i)
@ -344,7 +344,7 @@ class Connection:
self.irclibobj = irclibobj self.irclibobj = irclibobj
def _get_socket(): def _get_socket():
raise IRCError, "Not overridden" raise IRCError("Not overridden")
############################## ##############################
### Convenience wrappers. ### Convenience wrappers.
@ -408,7 +408,7 @@ class ServerConnection(Connection):
if self.connected: if self.connected:
self.disconnect("Changing servers") self.disconnect("Changing servers")
self.previous_buffer = "" self.previous_buffer = u""
self.handlers = {} self.handlers = {}
self.real_server_name = "" self.real_server_name = ""
self.real_nickname = nickname self.real_nickname = nickname
@ -425,10 +425,10 @@ class ServerConnection(Connection):
try: try:
self.socket.bind((self.localaddress, self.localport)) self.socket.bind((self.localaddress, self.localport))
self.socket.connect((self.server, self.port)) self.socket.connect((self.server, self.port))
except socket.error, x: except socket.error as x:
self.socket.close() self.socket.close()
self.socket = None self.socket = None
raise ServerConnectionError, "Couldn't connect to socket: %s" % x raise ServerConnectionError("Couldn't connect to socket: %s" % x)
self.connected = 1 self.connected = 1
if self.irclibobj.fn_to_add_socket: if self.irclibobj.fn_to_add_socket:
self.irclibobj.fn_to_add_socket(self.socket) self.irclibobj.fn_to_add_socket(self.socket)
@ -480,7 +480,7 @@ class ServerConnection(Connection):
try: try:
new_data = self.socket.recv(2**14) new_data = self.socket.recv(2**14)
except socket.error, x: except socket.error as x:
# The server hung up. # The server hung up.
self.disconnect("Connection reset by peer") self.disconnect("Connection reset by peer")
return return
@ -489,7 +489,7 @@ class ServerConnection(Connection):
self.disconnect("Connection reset by peer") self.disconnect("Connection reset by peer")
return return
lines = _linesep_regexp.split(self.previous_buffer + new_data) lines = _linesep_regexp.split(self.previous_buffer + new_data.decode("latin-1", "replace"))
# Save the last, unfinished line. # Save the last, unfinished line.
self.previous_buffer = lines[-1] self.previous_buffer = lines[-1]
@ -497,7 +497,7 @@ class ServerConnection(Connection):
for line in lines: for line in lines:
if DEBUG: if DEBUG:
print "FROM SERVER:", line print("FROM SERVER: %s\n" % line)
if not line: if not line:
continue continue
@ -551,7 +551,7 @@ class ServerConnection(Connection):
command = "privnotice" command = "privnotice"
for m in messages: for m in messages:
if type(m) is types.TupleType: if type(m) is tuple:
if command in ["privmsg", "pubmsg"]: if command in ["privmsg", "pubmsg"]:
command = "ctcp" command = "ctcp"
else: else:
@ -559,15 +559,15 @@ class ServerConnection(Connection):
m = list(m) m = list(m)
if DEBUG: if DEBUG:
print "command: %s, source: %s, target: %s, arguments: %s" % ( print("command: %s, source: %s, target: %s, arguments: %s" % (
command, prefix, target, m) command, prefix, target, m))
self._handle_event(Event(command, prefix, target, m)) self._handle_event(Event(command, prefix, target, m))
if command == "ctcp" and m[0] == "ACTION": if command == "ctcp" and m[0] == "ACTION":
self._handle_event(Event("action", prefix, target, m[1:])) self._handle_event(Event("action", prefix, target, m[1:]))
else: else:
if DEBUG: if DEBUG:
print "command: %s, source: %s, target: %s, arguments: %s" % ( print("command: %s, source: %s, target: %s, arguments: %s" % (
command, prefix, target, [m]) command, prefix, target, [m]))
self._handle_event(Event(command, prefix, target, [m])) self._handle_event(Event(command, prefix, target, [m]))
else: else:
target = None target = None
@ -585,8 +585,8 @@ class ServerConnection(Connection):
command = "umode" command = "umode"
if DEBUG: if DEBUG:
print "command: %s, source: %s, target: %s, arguments: %s" % ( print("command: %s, source: %s, target: %s, arguments: %s" % (
command, prefix, target, arguments) command, prefix, target, arguments))
self._handle_event(Event(command, prefix, target, arguments)) self._handle_event(Event(command, prefix, target, arguments))
def _handle_event(self, event): def _handle_event(self, event):
@ -650,7 +650,7 @@ class ServerConnection(Connection):
try: try:
self.socket.close() self.socket.close()
except socket.error, x: except socket.error as x:
pass pass
self.socket = None self.socket = None
self._handle_event(Event("disconnect", self.server, "", [message])) self._handle_event(Event("disconnect", self.server, "", [message]))
@ -733,7 +733,7 @@ class ServerConnection(Connection):
def part(self, channels, message=""): def part(self, channels, message=""):
"""Send a PART command.""" """Send a PART command."""
if type(channels) == types.StringType: if type(channels) == bytes:
self.send_raw("PART " + channels + (message and (" " + message))) self.send_raw("PART " + channels + (message and (" " + message)))
else: else:
self.send_raw("PART " + ",".join(channels) + (message and (" " + message))) self.send_raw("PART " + ",".join(channels) + (message and (" " + message)))
@ -778,12 +778,12 @@ class ServerConnection(Connection):
The string will be padded with appropriate CR LF. The string will be padded with appropriate CR LF.
""" """
if self.socket is None: if self.socket is None:
raise ServerNotConnectedError, "Not connected." raise ServerNotConnectedError("Not connected.")
try: try:
self.socket.send(string + "\r\n") self.socket.send(string.encode("latin-1", "replace") + b"\r\n")
if DEBUG: if DEBUG:
print "TO SERVER:", string print("TO SERVER: %s\n" % string)
except socket.error, x: except socket.error as x:
# Ouch! # Ouch!
self.disconnect("Connection reset by peer.") self.disconnect("Connection reset by peer.")
@ -876,14 +876,14 @@ class DCCConnection(Connection):
self.peeraddress = socket.gethostbyname(address) self.peeraddress = socket.gethostbyname(address)
self.peerport = port self.peerport = port
self.socket = None self.socket = None
self.previous_buffer = "" self.previous_buffer = u""
self.handlers = {} self.handlers = {}
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.passive = 0 self.passive = 0
try: try:
self.socket.connect((self.peeraddress, self.peerport)) self.socket.connect((self.peeraddress, self.peerport))
except socket.error, x: except socket.error as x:
raise DCCConnectionError, "Couldn't connect to socket: %s" % x raise DCCConnectionError("Couldn't connect to socket: %s" % x)
self.connected = 1 self.connected = 1
if self.irclibobj.fn_to_add_socket: if self.irclibobj.fn_to_add_socket:
self.irclibobj.fn_to_add_socket(self.socket) self.irclibobj.fn_to_add_socket(self.socket)
@ -899,7 +899,7 @@ class DCCConnection(Connection):
peer, the peer address and port are available as peer, the peer address and port are available as
self.peeraddress and self.peerport. self.peeraddress and self.peerport.
""" """
self.previous_buffer = "" self.previous_buffer = u""
self.handlers = {} self.handlers = {}
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.passive = 1 self.passive = 1
@ -907,8 +907,8 @@ class DCCConnection(Connection):
self.socket.bind((socket.gethostbyname(socket.gethostname()), 0)) self.socket.bind((socket.gethostbyname(socket.gethostname()), 0))
self.localaddress, self.localport = self.socket.getsockname() self.localaddress, self.localport = self.socket.getsockname()
self.socket.listen(10) self.socket.listen(10)
except socket.error, x: except socket.error as x:
raise DCCConnectionError, "Couldn't bind socket: %s" % x raise DCCConnectionError("Couldn't bind socket: %s" % x)
return self return self
def disconnect(self, message=""): def disconnect(self, message=""):
@ -924,7 +924,7 @@ class DCCConnection(Connection):
self.connected = 0 self.connected = 0
try: try:
self.socket.close() self.socket.close()
except socket.error, x: except socket.error as x:
pass pass
self.socket = None self.socket = None
self.irclibobj._handle_event( self.irclibobj._handle_event(
@ -941,8 +941,8 @@ class DCCConnection(Connection):
self.socket = conn self.socket = conn
self.connected = 1 self.connected = 1
if DEBUG: if DEBUG:
print "DCC connection from %s:%d" % ( print("DCC connection from %s:%d" % (
self.peeraddress, self.peerport) self.peeraddress, self.peerport))
self.irclibobj._handle_event( self.irclibobj._handle_event(
self, self,
Event("dcc_connect", self.peeraddress, None, None)) Event("dcc_connect", self.peeraddress, None, None))
@ -950,7 +950,7 @@ class DCCConnection(Connection):
try: try:
new_data = self.socket.recv(2**14) new_data = self.socket.recv(2**14)
except socket.error, x: except socket.error as x:
# The server hung up. # The server hung up.
self.disconnect("Connection reset by peer") self.disconnect("Connection reset by peer")
return return
@ -979,11 +979,11 @@ class DCCConnection(Connection):
target = None target = None
for chunk in chunks: for chunk in chunks:
if DEBUG: if DEBUG:
print "FROM PEER:", chunk print("FROM PEER: %s\n" % chunk)
arguments = [chunk] arguments = [chunk]
if DEBUG: if DEBUG:
print "command: %s, source: %s, target: %s, arguments: %s" % ( print("command: %s, source: %s, target: %s, arguments: %s" % (
command, prefix, target, arguments) command, prefix, target, arguments))
self.irclibobj._handle_event( self.irclibobj._handle_event(
self, self,
Event(command, prefix, target, arguments)) Event(command, prefix, target, arguments))
@ -1003,8 +1003,8 @@ class DCCConnection(Connection):
if self.dcctype == "chat": if self.dcctype == "chat":
self.socket.send("\n") self.socket.send("\n")
if DEBUG: if DEBUG:
print "TO PEER: %s\n" % string print("TO PEER: %s\n" % string)
except socket.error, x: except socket.error as x:
# Ouch! # Ouch!
self.disconnect("Connection reset by peer.") self.disconnect("Connection reset by peer.")
@ -1173,7 +1173,11 @@ def mask_matches(nick, mask):
_special = "-[]\\`^{}" _special = "-[]\\`^{}"
nick_characters = string.ascii_letters + string.digits + _special nick_characters = string.ascii_letters + string.digits + _special
_ircstring_translation = string.maketrans(string.ascii_uppercase + "[]\\^", if sys.version_info >= (3, 0):
_ircstring_translation = bytes.maketrans((string.ascii_uppercase + "[]\\^").encode("latin-1"),
(string.ascii_lowercase + "{}|~").encode("latin-1"))
else:
_ircstring_translation = string.maketrans(string.ascii_uppercase + "[]\\^",
string.ascii_lowercase + "{}|~") string.ascii_lowercase + "{}|~")
def irc_lower(s): def irc_lower(s):
@ -1249,16 +1253,16 @@ def ip_numstr_to_quad(num):
"""Convert an IP number as an integer given in ASCII """Convert an IP number as an integer given in ASCII
representation (e.g. '3232235521') to an IP address string representation (e.g. '3232235521') to an IP address string
(e.g. '192.168.0.1').""" (e.g. '192.168.0.1')."""
n = long(num) n = int(num)
p = map(str, map(int, [n >> 24 & 0xFF, n >> 16 & 0xFF, p = list(map(str, list(map(int, [n >> 24 & 0xFF, n >> 16 & 0xFF,
n >> 8 & 0xFF, n & 0xFF])) n >> 8 & 0xFF, n & 0xFF]))))
return ".".join(p) return ".".join(p)
def ip_quad_to_numstr(quad): def ip_quad_to_numstr(quad):
"""Convert an IP address string (e.g. '192.168.0.1') to an IP """Convert an IP address string (e.g. '192.168.0.1') to an IP
number as an integer given in ASCII representation number as an integer given in ASCII representation
(e.g. '3232235521').""" (e.g. '3232235521')."""
p = map(long, quad.split(".")) p = list(map(int, quad.split(".")))
s = str((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]) s = str((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3])
if s[-1] == "L": if s[-1] == "L":
s = s[:-1] s = s[:-1]
@ -1547,4 +1551,4 @@ protocol_events = [
"pong", "pong",
] ]
all_events = generated_events + protocol_events + numeric_events.values() all_events = generated_events + protocol_events + list(numeric_events.values())