Use UTF-8 in IRC

This commit is contained in:
Alexei Sorokin 2016-07-29 16:19:05 +03:00
parent 6d59e02735
commit 3d22bbe87d
2 changed files with 31 additions and 7 deletions

View File

@ -45,7 +45,8 @@ class SingleServerIRCBot(SimpleIRCClient):
have operator or voice modes. The "database" is kept in the have operator or voice modes. The "database" is kept in the
self.channels attribute, which is an IRCDict of Channels. self.channels attribute, which is an IRCDict of Channels.
""" """
def __init__(self, server_list, nickname, realname, reconnection_interval=60): def __init__(self, server_list, nickname, realname,
reconnection_interval=60, encoding="utf-8"):
"""Constructor for SingleServerIRCBot objects. """Constructor for SingleServerIRCBot objects.
Arguments: Arguments:
@ -61,6 +62,8 @@ class SingleServerIRCBot(SimpleIRCClient):
reconnection_interval -- How long the bot should wait reconnection_interval -- How long the bot should wait
before trying to reconnect. before trying to reconnect.
encoding -- An encoding to use.
dcc_connections -- A list of initiated/accepted DCC dcc_connections -- A list of initiated/accepted DCC
connections. connections.
""" """
@ -74,6 +77,7 @@ class SingleServerIRCBot(SimpleIRCClient):
self._nickname = nickname self._nickname = nickname
self._realname = realname self._realname = realname
self._encoding = encoding
for i in ["disconnect", "join", "kick", "mode", for i in ["disconnect", "join", "kick", "mode",
"namreply", "nick", "part", "quit"]: "namreply", "nick", "part", "quit"]:
self.connection.add_global_handler(i, self.connection.add_global_handler(i,
@ -96,7 +100,8 @@ class SingleServerIRCBot(SimpleIRCClient):
self.server_list[0][1], self.server_list[0][1],
self._nickname, self._nickname,
password, password,
ircname=self._realname) ircname=self._realname,
encoding=self._encoding)
except ServerConnectionError: except ServerConnectionError:
pass pass

View File

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (C) 1999--2002 Joel Rosdahl # Copyright (C) 1999--2002 Joel Rosdahl
# #
# This library is free software; you can redistribute it and/or # This library is free software; you can redistribute it and/or
@ -380,7 +382,7 @@ class ServerConnection(Connection):
self.socket = None self.socket = None
def connect(self, server, port, nickname, password=None, username=None, def connect(self, server, port, nickname, password=None, username=None,
ircname=None, localaddress="", localport=0): ircname=None, localaddress="", localport=0, encoding="utf-8"):
"""Connect/reconnect to a server. """Connect/reconnect to a server.
Arguments: Arguments:
@ -401,6 +403,8 @@ class ServerConnection(Connection):
localport -- Bind the connection to a specific local port. localport -- Bind the connection to a specific local port.
encoding -- The encoding to use.
This function can be called to reconnect a closed connection. This function can be called to reconnect a closed connection.
Returns the ServerConnection object. Returns the ServerConnection object.
@ -418,6 +422,7 @@ class ServerConnection(Connection):
self.username = username or nickname self.username = username or nickname
self.ircname = ircname or nickname self.ircname = ircname or nickname
self.password = password self.password = password
self.encoding = encoding
self.localaddress = localaddress self.localaddress = localaddress
self.localport = localport self.localport = localport
self.localhost = socket.gethostname() self.localhost = socket.gethostname()
@ -489,7 +494,12 @@ 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.decode("latin-1", "replace")) try:
new_data = new_data.decode(self.encoding, "strict")
except (UnicodeDecodeError, UnicodeEncodeError):
new_data = new_data.decode("latin-1", "replace")
lines = _linesep_regexp.split(self.previous_buffer + new_data)
# Save the last, unfinished line. # Save the last, unfinished line.
self.previous_buffer = lines[-1] self.previous_buffer = lines[-1]
@ -777,10 +787,17 @@ class ServerConnection(Connection):
The string will be padded with appropriate CR LF. The string will be padded with appropriate CR LF.
""" """
if isinstance(string, bytes):
data = string
else:
try:
data = string.encode(self.encoding, "strict")
except (UnicodeEncodeError, UnicodeDecodeError):
data = string.encode("latin-1", "replace")
if self.socket is None: if self.socket is None:
raise ServerNotConnectedError("Not connected.") raise ServerNotConnectedError("Not connected.")
try: try:
self.socket.send(string.encode("latin-1", "replace") + b"\r\n") self.socket.send(data + b"\r\n")
if DEBUG: if DEBUG:
print("TO SERVER: %s\n" % string) print("TO SERVER: %s\n" % string)
except socket.error as x: except socket.error as x:
@ -1046,7 +1063,7 @@ class SimpleIRCClient:
self.dcc_connections.remove(c) self.dcc_connections.remove(c)
def connect(self, server, port, nickname, password=None, username=None, def connect(self, server, port, nickname, password=None, username=None,
ircname=None, localaddress="", localport=0): ircname=None, localaddress="", localport=0, encoding="utf-8"):
"""Connect/reconnect to a server. """Connect/reconnect to a server.
Arguments: Arguments:
@ -1067,11 +1084,13 @@ class SimpleIRCClient:
localport -- Bind the connection to a specific local port. localport -- Bind the connection to a specific local port.
encoding -- The encoding to use.
This function can be called to reconnect a closed connection. This function can be called to reconnect a closed connection.
""" """
self.connection.connect(server, port, nickname, self.connection.connect(server, port, nickname,
password, username, ircname, password, username, ircname,
localaddress, localport) localaddress, localport, encoding)
def dcc_connect(self, address, port, dcctype="chat"): def dcc_connect(self, address, port, dcctype="chat"):
"""Connect to a DCC peer. """Connect to a DCC peer.