Attonement for massacring this library (wip)
This commit is contained in:
parent
959a9c5ad3
commit
e6ad257479
4 changed files with 64 additions and 97 deletions
|
@ -24,27 +24,18 @@ PchumLog = logging.getLogger('pchumLogger')
|
||||||
import logging
|
import logging
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
#import re
|
|
||||||
#import string
|
|
||||||
import time
|
import time
|
||||||
#import threading
|
|
||||||
import os
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
import ostools
|
import ostools
|
||||||
import ssl
|
import ssl
|
||||||
|
import json
|
||||||
_datadir = ostools.getDataDir()
|
_datadir = ostools.getDataDir()
|
||||||
|
|
||||||
from oyoyo.parse import *
|
from oyoyo.parse import *
|
||||||
from oyoyo import helpers
|
from oyoyo import helpers
|
||||||
from oyoyo.cmdhandler import CommandError
|
from oyoyo.cmdhandler import CommandError
|
||||||
|
|
||||||
# Python < 3 compatibility
|
|
||||||
if sys.version_info < (3,):
|
|
||||||
class bytes(object):
|
|
||||||
def __new__(self, b='', encoding='utf8'):
|
|
||||||
return str(b)
|
|
||||||
|
|
||||||
|
|
||||||
class IRCClientError(Exception):
|
class IRCClientError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -92,26 +83,17 @@ class IRCClient:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# This should be moved to profiles
|
# This should be moved to profiles
|
||||||
import json
|
|
||||||
|
|
||||||
try:
|
with open(_datadir + "server.json", "r") as server_file:
|
||||||
with open(_datadir + "server.json", "r") as server_file:
|
read_file = server_file.read()
|
||||||
read_file = server_file.read()
|
server_file.close()
|
||||||
server_file.close()
|
server_obj = json.loads(read_file)
|
||||||
server_obj = json.loads(read_file)
|
TLS = server_obj['TLS']
|
||||||
TLS = server_obj['TLS']
|
#print("TLS-status is: " + str(TLS))
|
||||||
#print("TLS-status is: " + str(TLS))
|
if TLS == False:
|
||||||
if TLS == False:
|
#print("false")
|
||||||
#print("false")
|
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
else:
|
||||||
else:
|
|
||||||
self.context = ssl.create_default_context()
|
|
||||||
self.context.check_hostname = False
|
|
||||||
self.context.verify_mode = ssl.CERT_NONE
|
|
||||||
self.bare_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
self.socket = self.context.wrap_socket(self.bare_socket)
|
|
||||||
except:
|
|
||||||
logging.exception('')
|
|
||||||
self.context = ssl.create_default_context()
|
self.context = ssl.create_default_context()
|
||||||
self.context.check_hostname = False
|
self.context.check_hostname = False
|
||||||
self.context.verify_mode = ssl.CERT_NONE
|
self.context.verify_mode = ssl.CERT_NONE
|
||||||
|
@ -160,10 +142,11 @@ class IRCClient:
|
||||||
% repr([(type(arg), arg) for arg in args]))
|
% repr([(type(arg), arg) for arg in args]))
|
||||||
|
|
||||||
msg = bytes(" ", "UTF-8").join(bargs)
|
msg = bytes(" ", "UTF-8").join(bargs)
|
||||||
logging.info('---> send "%s"' % msg)
|
PchumLog.info('---> send "%s"' % msg)
|
||||||
try:
|
try:
|
||||||
self.socket.send(msg + bytes("\r\n", "UTF-8"))
|
self.socket.sendall(msg + bytes("\r\n", "UTF-8"))
|
||||||
except socket.error as se:
|
except socket.error as se:
|
||||||
|
PchumLog.debug("socket.error %s" % se)
|
||||||
try: # a little dance of compatibility to get the errno
|
try: # a little dance of compatibility to get the errno
|
||||||
errno = se.errno
|
errno = se.errno
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -177,7 +160,7 @@ class IRCClient:
|
||||||
""" initiates the connection to the server set in self.host:self.port
|
""" initiates the connection to the server set in self.host:self.port
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logging.info('connecting to %s:%s' % (self.host, self.port))
|
PchumLog.info('connecting to %s:%s' % (self.host, self.port))
|
||||||
self.socket.connect(("%s" % self.host, self.port))
|
self.socket.connect(("%s" % self.host, self.port))
|
||||||
if not self.blocking:
|
if not self.blocking:
|
||||||
self.socket.setblocking(0)
|
self.socket.setblocking(0)
|
||||||
|
@ -196,15 +179,16 @@ class IRCClient:
|
||||||
while not self._end:
|
while not self._end:
|
||||||
try:
|
try:
|
||||||
buffer += self.socket.recv(1024)
|
buffer += self.socket.recv(1024)
|
||||||
|
#raise socket.timeout
|
||||||
except socket.timeout as e:
|
except socket.timeout as e:
|
||||||
if self._end:
|
if self._end:
|
||||||
break
|
break
|
||||||
logging.debug("timeout in client.py")
|
PchumLog.debug("timeout in client.py")
|
||||||
raise e
|
raise e
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
if self._end:
|
if self._end:
|
||||||
break
|
break
|
||||||
logging.debug("error %s" % e)
|
PchumLog.debug("error %s" % e)
|
||||||
try: # a little dance of compatibility to get the errno
|
try: # a little dance of compatibility to get the errno
|
||||||
errno = e.errno
|
errno = e.errno
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -228,48 +212,43 @@ class IRCClient:
|
||||||
prefix, command, args = parse_raw_irc_command(el)
|
prefix, command, args = parse_raw_irc_command(el)
|
||||||
try:
|
try:
|
||||||
self.command_handler.run(command, prefix, *args)
|
self.command_handler.run(command, prefix, *args)
|
||||||
except CommandError:
|
except CommandError as e:
|
||||||
# error will have already been loggingged by the handler
|
PchumLog.debug("CommandError %s" % e)
|
||||||
pass
|
|
||||||
|
|
||||||
yield True
|
yield True
|
||||||
except socket.timeout as se:
|
except socket.timeout as se:
|
||||||
logging.debug("passing timeout")
|
PchumLog.debug("passing timeout")
|
||||||
raise se
|
raise se
|
||||||
except socket.error as se:
|
except socket.error as se:
|
||||||
logging.debug("problem: %s" % (se))
|
PchumLog.debug("problem: %s" % (se))
|
||||||
if self.socket:
|
if self.socket:
|
||||||
logging.info('error: closing socket')
|
PchumLog.info('error: closing socket')
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
raise se
|
raise se
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.debug("other exception: %s" % e)
|
PchumLog.debug("other exception: %s" % e)
|
||||||
raise e
|
raise e
|
||||||
else:
|
else:
|
||||||
logging.debug("ending while, end is %s" % self._end)
|
PchumLog.debug("ending while, end is %s" % self._end)
|
||||||
if self.socket:
|
if self.socket:
|
||||||
logging.info('finished: closing socket')
|
PchumLog.info('finished: closing socket')
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
yield False
|
yield False
|
||||||
def close(self):
|
def close(self):
|
||||||
# with extreme prejudice
|
# with extreme prejudice
|
||||||
if self.socket:
|
if self.socket:
|
||||||
logging.info('shutdown socket')
|
PchumLog.info('shutdown socket')
|
||||||
#print("shutdown socket")
|
#print("shutdown socket")
|
||||||
self._end = True
|
self._end = True
|
||||||
self.socket.shutdown(socket.SHUT_WR)
|
self.socket.shutdown(socket.SHUT_WR)
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
|
|
||||||
def simple_send(self, message):
|
def simple_send(self, message):
|
||||||
self.socket.send(bytes(message, "UTF-8"))
|
self.socket.sendall(bytes(message, "UTF-8"))
|
||||||
|
|
||||||
def quit(self, msg):
|
def quit(self, msg):
|
||||||
# I am going mad :)
|
PchumLog.info("QUIT")
|
||||||
# Why does this only work 33% of the time </3
|
self.socket.sendall(bytes(msg + "\n", "UTF-8"))
|
||||||
|
|
||||||
# Somehow, kinda fixed :')
|
|
||||||
logging.info("QUIT")
|
|
||||||
self.socket.send(bytes(msg + "\n", "UTF-8"))
|
|
||||||
|
|
||||||
class IRCApp:
|
class IRCApp:
|
||||||
""" This class manages several IRCClient instances without the use of threads.
|
""" This class manages several IRCClient instances without the use of threads.
|
||||||
|
@ -296,7 +275,7 @@ class IRCApp:
|
||||||
|
|
||||||
warning: if you add a client that has blocking set to true,
|
warning: if you add a client that has blocking set to true,
|
||||||
timers will no longer function properly """
|
timers will no longer function properly """
|
||||||
logging.info('added client %s (ar=%s)' % (client, autoreconnect))
|
PchumLog.info('added client %s (ar=%s)' % (client, autoreconnect))
|
||||||
self._clients[client] = self._ClientDesc(autoreconnect=autoreconnect)
|
self._clients[client] = self._ClientDesc(autoreconnect=autoreconnect)
|
||||||
|
|
||||||
def addTimer(self, seconds, cb):
|
def addTimer(self, seconds, cb):
|
||||||
|
@ -305,7 +284,7 @@ class IRCApp:
|
||||||
( the only advantage to these timers is they dont use threads )
|
( the only advantage to these timers is they dont use threads )
|
||||||
"""
|
"""
|
||||||
assert callable(cb)
|
assert callable(cb)
|
||||||
logging.info('added timer to call %s in %ss' % (cb, seconds))
|
PchumLog.info('added timer to call %s in %ss' % (cb, seconds))
|
||||||
self._timers.append((time.time() + seconds, cb))
|
self._timers.append((time.time() + seconds, cb))
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
@ -322,8 +301,8 @@ class IRCApp:
|
||||||
try:
|
try:
|
||||||
next(clientdesc.con)
|
next(clientdesc.con)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error('client error %s' % e)
|
PchumLog.error('client error %s' % e)
|
||||||
logging.error(traceback.format_exc())
|
PchumLog.error(traceback.format_exc())
|
||||||
if clientdesc.autoreconnect:
|
if clientdesc.autoreconnect:
|
||||||
clientdesc.con = None
|
clientdesc.con = None
|
||||||
if isinstance(clientdesc.autoreconnect, (int, float)):
|
if isinstance(clientdesc.autoreconnect, (int, float)):
|
||||||
|
@ -335,7 +314,7 @@ class IRCApp:
|
||||||
found_one_alive = True
|
found_one_alive = True
|
||||||
|
|
||||||
if not found_one_alive:
|
if not found_one_alive:
|
||||||
logging.info('nothing left alive... quiting')
|
PchumLog.info('nothing left alive... quiting')
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
now = time.time()
|
now = time.time()
|
||||||
|
@ -343,7 +322,7 @@ class IRCApp:
|
||||||
self._timers = []
|
self._timers = []
|
||||||
for target_time, cb in timers:
|
for target_time, cb in timers:
|
||||||
if now > target_time:
|
if now > target_time:
|
||||||
logging.info('calling timer cb %s' % cb)
|
PchumLog.info('calling timer cb %s' % cb)
|
||||||
cb()
|
cb()
|
||||||
else:
|
else:
|
||||||
self._timers.append((target_time, cb))
|
self._timers.append((target_time, cb))
|
||||||
|
|
|
@ -28,13 +28,6 @@ import traceback
|
||||||
from oyoyo import helpers
|
from oyoyo import helpers
|
||||||
from oyoyo.parse import parse_nick
|
from oyoyo.parse import parse_nick
|
||||||
|
|
||||||
# Python < 3 compatibility
|
|
||||||
if sys.version_info < (3,):
|
|
||||||
class bytes(object):
|
|
||||||
def __new__(self, b='', encoding='utf8'):
|
|
||||||
return str(b)
|
|
||||||
|
|
||||||
|
|
||||||
def protected(func):
|
def protected(func):
|
||||||
""" decorator to protect functions from being called """
|
""" decorator to protect functions from being called """
|
||||||
func.protected = True
|
func.protected = True
|
||||||
|
@ -62,6 +55,7 @@ class CommandHandler(object):
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
def get(self, in_command_parts):
|
def get(self, in_command_parts):
|
||||||
|
PchumLog.debug("in_command_parts: %s" % in_command_parts)
|
||||||
""" finds a command
|
""" finds a command
|
||||||
commands may be dotted. each command part is checked that it does
|
commands may be dotted. each command part is checked that it does
|
||||||
not start with and underscore and does not have an attribute
|
not start with and underscore and does not have an attribute
|
||||||
|
@ -97,7 +91,10 @@ class CommandHandler(object):
|
||||||
@protected
|
@protected
|
||||||
def run(self, command, *args):
|
def run(self, command, *args):
|
||||||
""" finds and runs a command """
|
""" finds and runs a command """
|
||||||
logging.debug("processCommand %s(%s)" % (command, args))
|
arguments_str = ''
|
||||||
|
for x in args:
|
||||||
|
arguments_str += str(x) + ' '
|
||||||
|
PchumLog.debug("processCommand %s(%s)" % (command, arguments_str.strip()))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
f = self.get(command)
|
f = self.get(command)
|
||||||
|
@ -105,30 +102,30 @@ class CommandHandler(object):
|
||||||
self.__unhandled__(command, *args)
|
self.__unhandled__(command, *args)
|
||||||
return
|
return
|
||||||
|
|
||||||
logging.debug('f %s' % f)
|
PchumLog.debug('f %s' % f)
|
||||||
#logging.info(*args)
|
#logging.info(*args)
|
||||||
|
|
||||||
# Because more than 5 arguments can be passed by channelmodeis
|
# Because more than 5 arguments can be passed by channelmodeis
|
||||||
try:
|
#try:
|
||||||
#if str(command) == 'channelmodeis':
|
#if str(command) == 'channelmodeis':
|
||||||
# This might be stupid :)
|
# This might be stupid :)
|
||||||
# Update: This was very stupid
|
# Update: This was very stupid
|
||||||
#f(*args[0:4])
|
#f(*args[0:4])
|
||||||
#else:
|
#else:
|
||||||
f(*args)
|
f(*args)
|
||||||
except Exception as e:
|
#except Exception as e:
|
||||||
#logging.error('command raised '+ command + str())
|
# #logging.error('command raised '+ command + str())
|
||||||
logging.error('command args: ' + str([*args]))
|
# PchumLog.error('command args: ' + str([*args]))
|
||||||
logging.error('command raised %s' % e)
|
# PchumLog.error('command raised %s' % e)
|
||||||
logging.error(traceback.format_exc())
|
# PchumLog.error(traceback.format_exc())
|
||||||
raise CommandError(command)
|
# raise CommandError(command)
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
def __unhandled__(self, cmd, *args):
|
def __unhandled__(self, cmd, *args):
|
||||||
"""The default handler for commands. Override this method to
|
"""The default handler for commands. Override this method to
|
||||||
apply custom behavior (example, printing) unhandled commands.
|
apply custom behavior (example, printing) unhandled commands.
|
||||||
"""
|
"""
|
||||||
logging.debug('unhandled command %s(%s)' % (cmd, args))
|
PchumLog.debug('unhandled command %s(%s)' % (cmd, args))
|
||||||
|
|
||||||
|
|
||||||
class DefaultCommandHandler(CommandHandler):
|
class DefaultCommandHandler(CommandHandler):
|
||||||
|
@ -155,7 +152,7 @@ class DefaultBotCommandHandler(CommandHandler):
|
||||||
|
|
||||||
def help(self, sender, dest, arg=None):
|
def help(self, sender, dest, arg=None):
|
||||||
"""list all available commands or get help on a specific command"""
|
"""list all available commands or get help on a specific command"""
|
||||||
logging.info('help sender=%s dest=%s arg=%s' % (sender, dest, arg))
|
PchumLog.info('help sender=%s dest=%s arg=%s' % (sender, dest, arg))
|
||||||
if not arg:
|
if not arg:
|
||||||
commands = self.getVisibleCommands()
|
commands = self.getVisibleCommands()
|
||||||
commands.sort()
|
commands.sort()
|
||||||
|
|
|
@ -15,18 +15,16 @@
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
# THE SOFTWARE.
|
# THE SOFTWARE.
|
||||||
|
|
||||||
import logging
|
import logging, logging.config
|
||||||
|
import ostools
|
||||||
|
_datadir = ostools.getDataDir()
|
||||||
|
logging.config.fileConfig(_datadir + "logging.ini")
|
||||||
|
PchumLog = logging.getLogger('pchumLogger')
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from oyoyo.ircevents import *
|
from oyoyo.ircevents import *
|
||||||
|
|
||||||
# Python < 3 compatibility
|
|
||||||
if sys.version_info < (3,):
|
|
||||||
class bytes(object):
|
|
||||||
def __new__(self, b='', encoding='utf8'):
|
|
||||||
return str(b)
|
|
||||||
|
|
||||||
|
|
||||||
def parse_raw_irc_command(element):
|
def parse_raw_irc_command(element):
|
||||||
"""
|
"""
|
||||||
This function parses a raw irc command and returns a tuple
|
This function parses a raw irc command and returns a tuple
|
||||||
|
@ -46,14 +44,12 @@ def parse_raw_irc_command(element):
|
||||||
|
|
||||||
<crlf> ::= CR LF
|
<crlf> ::= CR LF
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
element = element.decode("utf-8")
|
element = element.decode("utf-8")
|
||||||
except:
|
except UnicodeDecodeError as e:
|
||||||
try:
|
PchumLog.debug("utf-8 error %s" % e)
|
||||||
element = element.decode("latin-1")
|
element = element.decode("latin-1", 'replace')
|
||||||
except:
|
|
||||||
# This shouldn't happen, but if it does:
|
|
||||||
element = ""
|
|
||||||
|
|
||||||
parts = element.strip().split(" ")
|
parts = element.strip().split(" ")
|
||||||
if parts[0].startswith(':'):
|
if parts[0].startswith(':'):
|
||||||
|
@ -69,7 +65,7 @@ def parse_raw_irc_command(element):
|
||||||
try:
|
try:
|
||||||
command = numeric_events[command]
|
command = numeric_events[command]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logging.info('unknown numeric event %s' % command)
|
PchumLog.info('unknown numeric event %s' % command)
|
||||||
command = command.lower()
|
command = command.lower()
|
||||||
|
|
||||||
if args[0].startswith(':'):
|
if args[0].startswith(':'):
|
||||||
|
|
7
pesterchum.py
Normal file → Executable file
7
pesterchum.py
Normal file → Executable file
|
@ -185,15 +185,10 @@ PchumLog = logging.getLogger('pchumLogger')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import console
|
import console
|
||||||
|
_CONSOLE = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
_CONSOLE = False
|
_CONSOLE = False
|
||||||
logging.warning("Console file not shipped; skipping.")
|
logging.warning("Console file not shipped; skipping.")
|
||||||
except Exception as err:
|
|
||||||
_CONSOLE = False
|
|
||||||
# Consider erroring?
|
|
||||||
logging.error("Failed to load console!", exc_info=err)
|
|
||||||
else:
|
|
||||||
_CONSOLE = True
|
|
||||||
|
|
||||||
if _datadir:
|
if _datadir:
|
||||||
if not os.path.exists(_datadir):
|
if not os.path.exists(_datadir):
|
||||||
|
|
Loading…
Reference in a new issue