Use a logger

This commit is contained in:
nemunaire 2014-08-14 12:49:38 +02:00
parent 3839455f42
commit d0b1336d07
14 changed files with 118 additions and 77 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
*# *#
*~ *~
*.log
TAGS TAGS
*.py[cod] *.py[cod]
__pycache__ __pycache__

37
bot.py
View File

@ -18,6 +18,7 @@
from datetime import datetime from datetime import datetime
from datetime import timedelta from datetime import timedelta
import logging
from queue import Queue from queue import Queue
import threading import threading
import time import time
@ -31,6 +32,8 @@ from server.IRC import IRCServer
from server.DCC import DCC from server.DCC import DCC
import response import response
logger = logging.getLogger(__name__)
ID_letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ID_letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
class Bot: class Bot:
@ -38,6 +41,7 @@ class Bot:
# Bot general informations # Bot general informations
self.version = 3.4 self.version = 3.4
self.version_txt = "3.4-dev" self.version_txt = "3.4-dev"
logger.info("Initiate nemubot v%s" % self.version_txt)
# Save various informations # Save various informations
self.ip = ip self.ip = ip
@ -87,6 +91,7 @@ class Bot:
msg.sender, "USERINFO %s" % self.realname) msg.sender, "USERINFO %s" % self.realname)
self.ctcp_capabilities["VERSION"] = lambda srv, msg: _ctcp_response( self.ctcp_capabilities["VERSION"] = lambda srv, msg: _ctcp_response(
msg.sender, "VERSION nemubot v%s" % self.version_txt) msg.sender, "VERSION nemubot v%s" % self.version_txt)
logger.debug("CTCP capabilities setup: %s" % ", ".join(self.ctcp_capabilities))
def _ctcp_clientinfo(self, srv, msg): def _ctcp_clientinfo(self, srv, msg):
"""Response to CLIENTINFO CTCP message""" """Response to CLIENTINFO CTCP message"""
@ -101,7 +106,7 @@ class Bot:
srv.dcc_clients[conn.sender] = conn srv.dcc_clients[conn.sender] = conn
conn.send_dcc("Hello %s!" % conn.nick) conn.send_dcc("Hello %s!" % conn.nick)
else: else:
print ("DCC: unable to connect to %s:%s" % (ip, msg.cmds[4])) logger.error("DCC: unable to connect to %s:%s" % (ip, msg.cmds[4]))
def add_event(self, evt, eid=None, module_src=None): def add_event(self, evt, eid=None, module_src=None):
@ -132,10 +137,12 @@ class Bot:
if module_src is not None: if module_src is not None:
module_src.REGISTERED_EVENTS.append(evt.id) module_src.REGISTERED_EVENTS.append(evt.id)
logger.info("New event registered: %s -> %s" % (evt.id, evt))
return evt.id return evt.id
def del_event(self, id, module_src=None): def del_event(self, id, module_src=None):
"""Find and remove an event from list""" """Find and remove an event from list"""
logger.info("Removing event: %s from %s" % (id, module_src))
if len(self.events) > 0 and id == self.events[0].id: if len(self.events) > 0 and id == self.events[0].id:
self.events.remove(self.events[0]) self.events.remove(self.events[0])
self.update_timer() self.update_timer()
@ -158,8 +165,8 @@ class Bot:
if self.event_timer is not None: if self.event_timer is not None:
self.event_timer.cancel() self.event_timer.cancel()
if len(self.events) > 0: if len(self.events) > 0:
#print ("Update timer, next in", self.events[0].time_left.seconds, logger.debug("Update timer: next event in %d seconds" %
# "seconds") self.events[0].time_left.seconds)
if datetime.now() + timedelta(seconds=5) >= self.events[0].current: if datetime.now() + timedelta(seconds=5) >= self.events[0].current:
while datetime.now() < self.events[0].current: while datetime.now() < self.events[0].current:
time.sleep(0.6) time.sleep(0.6)
@ -168,8 +175,8 @@ class Bot:
self.event_timer = threading.Timer( self.event_timer = threading.Timer(
self.events[0].time_left.seconds + 1, self.end_timer) self.events[0].time_left.seconds + 1, self.end_timer)
self.event_timer.start() self.event_timer.start()
#else: else:
# print ("Update timer: no timer left") logger.debug("Update timer: no timer left")
def end_timer(self): def end_timer(self):
"""Function called at the end of the timer""" """Function called at the end of the timer"""
@ -225,7 +232,7 @@ class Bot:
return False return False
def unload_module(self, name, verb=False): def unload_module(self, name):
"""Unload a module""" """Unload a module"""
if name in self.modules: if name in self.modules:
self.modules[name].print_debug("Unloading module %s" % name) self.modules[name].print_debug("Unloading module %s" % name)
@ -240,7 +247,7 @@ class Bot:
self.del_event(e) self.del_event(e)
# Remove from the dict # Remove from the dict
del self.modules[name] del self.modules[name]
print(" Module `%s' successfully unloaded." % name) logger.info("Module `%s' successfully unloaded." % name)
return True return True
return False return False
@ -274,18 +281,18 @@ class Bot:
if self.network[bot].srv == srv: if self.network[bot].srv == srv:
self.network[bot].send_cmd(cmd, data) self.network[bot].send_cmd(cmd, data)
def quit(self, verb=False): def quit(self):
"""Save and unload modules and disconnect servers""" """Save and unload modules and disconnect servers"""
if self.event_timer is not None: if self.event_timer is not None:
if verb: print ("Stop the event timer...") logger.info("Stop the event timer...")
self.event_timer.cancel() self.event_timer.cancel()
if verb: print ("Save and unload all modules...") logger.info("Save and unload all modules...")
k = list(self.modules.keys()) k = list(self.modules.keys())
for mod in k: for mod in k:
self.unload_module(mod, verb) self.unload_module(mod)
if verb: print ("Close all servers connection...") logger.info("Close all servers connection...")
k = list(self.servers.keys()) k = list(self.servers.keys())
for srv in k: for srv in k:
self.servers[srv].disconnect() self.servers[srv].disconnect()
@ -436,13 +443,13 @@ class Bot:
return srv.moremessages[msg.channel] return srv.moremessages[msg.channel]
elif msg.cmds[0] == "dcc": elif msg.cmds[0] == "dcc":
print("dcctest for", msg.sender) logger.debug("dcctest for " + msg.sender)
srv.send_dcc("Hello %s!" % msg.nick, msg.sender) srv.send_dcc("Hello %s!" % msg.nick, msg.sender)
elif msg.cmds[0] == "pvdcctest": elif msg.cmds[0] == "pvdcctest":
print("dcctest") logger.debug("dcctest")
return Response(msg.sender, message="Test DCC") return Response(msg.sender, message="Test DCC")
elif msg.cmds[0] == "dccsendtest": elif msg.cmds[0] == "dccsendtest":
print("dccsendtest") logger.debug("dccsendtest")
conn = DCC(srv, msg.sender) conn = DCC(srv, msg.sender)
conn.send_file("bot_sample.xml") conn.send_file("bot_sample.xml")

View File

@ -41,7 +41,7 @@ class Channel:
def join(self, nick, level = 0): def join(self, nick, level = 0):
"""Someone join the channel""" """Someone join the channel"""
#print ("%s arrive sur %s" % (nick, self.name)) logger.debug("%s join %s" % (nick, self.name))
self.people[nick] = level self.people[nick] = level
def chtopic(self, newtopic): def chtopic(self, newtopic):
@ -52,7 +52,7 @@ class Channel:
def nick(self, oldnick, newnick): def nick(self, oldnick, newnick):
"""Someone change his nick""" """Someone change his nick"""
if oldnick in self.people: if oldnick in self.people:
#print ("%s change de nom pour %s sur %s" % (oldnick, newnick, self.name)) logger.debug("%s switch nick to %s on %s" % (oldnick, newnick, self.name))
lvl = self.people[oldnick] lvl = self.people[oldnick]
del self.people[oldnick] del self.people[oldnick]
self.people[newnick] = lvl self.people[newnick] = lvl
@ -60,7 +60,7 @@ class Channel:
def part(self, nick): def part(self, nick):
"""Someone leave the channel""" """Someone leave the channel"""
if nick in self.people: if nick in self.people:
#print ("%s vient de quitter %s" % (nick, self.name)) logger.debug("%s has left %s" % (nick, self.name))
del self.people[nick] del self.people[nick]
def mode(self, msg): def mode(self, msg):

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import queue import queue
import re import re
import threading import threading
@ -28,6 +29,8 @@ from message import Message
import response import response
import server import server
logger = logging.getLogger(__name__)
class MessageConsumer: class MessageConsumer:
"""Store a message before treating""" """Store a message before treating"""
def __init__(self, srv, raw, time, prvt, data): def __init__(self, srv, raw, time, prvt, data):
@ -63,8 +66,8 @@ class MessageConsumer:
res.server = context.servers[res.server] res.server = context.servers[res.server]
if (res.server is not None and if (res.server is not None and
not isinstance(res.server, server.Server)): not isinstance(res.server, server.Server)):
print ("\033[1;35mWarning:\033[0m the server defined in this " logger.error("The server defined in this response doesn't "
"response doesn't exist: %s" % (res.server)) "exist: %s" % res.server)
res.server = None res.server = None
if res.server is None: if res.server is None:
res.server = self.srv res.server = self.srv
@ -77,8 +80,7 @@ class MessageConsumer:
context.hooks.add_hook(res.type, res.hook, res.src) context.hooks.add_hook(res.type, res.hook, res.src)
elif res is not None: elif res is not None:
print ("\033[1;35mWarning:\033[0m unrecognized response type " logger.error("Unrecognized response type: %s" % res)
": %s" % res)
def run(self, context): def run(self, context):
"""Create, parse and treat the message""" """Create, parse and treat the message"""
@ -90,11 +92,12 @@ class MessageConsumer:
msg.private = msg.private or msg.channel == self.srv.nick msg.private = msg.private or msg.channel == self.srv.nick
res = self.treat_in(context, msg) res = self.treat_in(context, msg)
except: except:
print ("\033[1;31mERROR:\033[0m occurred during the " logger.error("Error occurred during the processing of the message:"
"processing of the message: %s" % self.raw) " %s" % self.raw)
exc_type, exc_value, exc_traceback = sys.exc_info() exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_exception(exc_type, exc_value, logger.debug(traceback.format_exception(exc_type,
exc_traceback) exc_value,
exc_traceback))
return return
# Send message # Send message
@ -116,10 +119,11 @@ class EventConsumer:
try: try:
self.evt.launch_check() self.evt.launch_check()
except: except:
print ("\033[1;31mError:\033[0m during event end") logger.error("Error during event end")
exc_type, exc_value, exc_traceback = sys.exc_info() exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_exception(exc_type, exc_value, logger.debug(traceback.format_exception(exc_type,
exc_traceback) exc_value,
exc_traceback))
if self.evt.next is not None: if self.evt.next is not None:
context.add_event(self.evt, self.evt.id) context.add_event(self.evt, self.evt.id)

View File

@ -16,11 +16,14 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import re import re
from response import Response from response import Response
from exception import IRCException from exception import IRCException
logger = logging.getLogger(__name__)
class MessagesHook: class MessagesHook:
def __init__(self, context, bot): def __init__(self, context, bot):
self.context = context self.context = context
@ -51,16 +54,19 @@ class MessagesHook:
def add_hook(self, store, hook, module_src=None): def add_hook(self, store, hook, module_src=None):
"""Insert in the right place a hook into the given store""" """Insert in the right place a hook into the given store"""
logger.info("Adding hook '%s' to store '%s' from module '%s'" % (hook, store, module_src))
if module_src is None: if module_src is None:
print ("\033[1;35mWarning:\033[0m No source module was passed to " logger.warn("No source module was passed to add_hook function, "
"add_hook function, please fix it in order to be " "please fix it in order to be compatible with unload "
"compatible with unload feature") "feature")
if store in self.context.hooks_cache: if store in self.context.hooks_cache:
logger.debug("Cleaning hooks cache for " + store)
del self.context.hooks_cache[store] del self.context.hooks_cache[store]
if not hasattr(self, store): if not hasattr(self, store):
print ("\033[1;35mWarning:\033[0m unrecognized hook store") # TODO: raise custom exception, this is a user problem, not internal one!
logger.error("Unrecognized hook store: " + store)
return return
attr = getattr(self, store) attr = getattr(self, store)
@ -75,7 +81,7 @@ class MessagesHook:
elif isinstance(attr, list): elif isinstance(attr, list):
attr.append(hook) attr.append(hook)
else: else:
print ("\033[1;32mWarning:\033[0m unrecognized hook store type") logger.critical("Unrecognized hook store type: " + type(attr))
return return
if module_src is not None and hasattr(module_src, "REGISTERED_HOOKS"): if module_src is not None and hasattr(module_src, "REGISTERED_HOOKS"):
module_src.REGISTERED_HOOKS.append((store, hook)) module_src.REGISTERED_HOOKS.append((store, hook))
@ -147,7 +153,7 @@ class MessagesHook:
del self.context.hooks_cache[store] del self.context.hooks_cache[store]
if not hasattr(self, store): if not hasattr(self, store):
print ("Warning: unrecognized hook store type") logger.warn("unrecognized hook store type")
return return
attr = getattr(self, store) attr = getattr(self, store)

View File

@ -19,6 +19,7 @@
from importlib.abc import Finder from importlib.abc import Finder
from importlib.abc import SourceLoader from importlib.abc import SourceLoader
import imp import imp
import logging
import os import os
import sys import sys
@ -28,6 +29,8 @@ import hooks
import response import response
import xmlparser import xmlparser
logger = logging.getLogger(__name__)
class ModuleFinder(Finder): class ModuleFinder(Finder):
def __init__(self, context, prompt): def __init__(self, context, prompt):
self.context = context self.context = context
@ -143,22 +146,26 @@ class ModuleLoader(SourceLoader):
# Set module common functions and datas # Set module common functions and datas
module.__LOADED__ = True module.__LOADED__ = True
module.logger = logging.getLogger("module/" + fullname)
def prnt(*args): def prnt(*args):
print("[%s]" % module.name, *args) print("[%s]" % module.name, *args)
module.logger.info(*args)
def prnt_dbg(*args): def prnt_dbg(*args):
if module.DEBUG: if module.DEBUG:
print("{%s}" % module.name, *args) print("{%s}" % module.name, *args)
module.logger.debug(*args)
def mod_save(): def mod_save():
module.print_debug("Saving DATAS...") fpath = self.context.datas_path + "/" + module.name + ".xml"
module.DATAS.save(self.context.datas_path + "/" + module.name + ".xml") module.print_debug("Saving DATAS to " + fpath)
module.DATAS.save(fpath)
def send_response(server, res): def send_response(server, res):
if server in self.context.servers: if server in self.context.servers:
return self.context.servers[server].send_response(res, None) return self.context.servers[server].send_response(res, None)
else: else:
print("\033[1;35mWarning:\033[0m Try to send a message to the unknown server: %s" % server) module.logger.error("Try to send a message to the unknown server: %s" % server)
return False return False
def add_hook(store, hook): def add_hook(store, hook):
@ -210,9 +217,9 @@ class ModuleLoader(SourceLoader):
mod.MODS[md.name] = md mod.MODS[md.name] = md
break break
if depend["name"] not in module.MODS: if depend["name"] not in module.MODS:
print ("\033[1;31mERROR:\033[0m in module `%s', module " logger.error("In module `%s', module `%s' require by this "
"`%s' require by this module but is not loaded." "module but is not loaded." % (module.name,
% (module.name, depend["name"])) depend["name"]))
return return
# Add the module to the global modules list # Add the module to the global modules list
@ -225,8 +232,9 @@ class ModuleLoader(SourceLoader):
# Register hooks # Register hooks
register_hooks(module, self.context, self.prompt) register_hooks(module, self.context, self.prompt)
print (" Module `%s' successfully loaded." % module.name) logger.info("Module '%s' successfully loaded." % module.name)
else: else:
logger.error("An error occurs while importing `%s'." % module.name)
raise ImportError("An error occurs while importing `%s'." raise ImportError("An error occurs while importing `%s'."
% module.name) % module.name)
return module return module
@ -236,7 +244,7 @@ def add_cap_hook(prompt, module, cmd):
if hasattr(module, cmd["call"]): if hasattr(module, cmd["call"]):
prompt.add_cap_hook(cmd["name"], getattr(module, cmd["call"])) prompt.add_cap_hook(cmd["name"], getattr(module, cmd["call"]))
else: else:
print ("Warning: In module `%s', no function `%s' defined for `%s' " logger.warn("In module `%s', no function `%s' defined for `%s' "
"command hook." % (module.name, cmd["call"], cmd["name"])) "command hook." % (module.name, cmd["call"], cmd["name"]))
def register_hooks(module, context, prompt): def register_hooks(module, context, prompt):

View File

@ -76,10 +76,8 @@ class Message:
self.channel = words[3] self.channel = words[3]
self.content = self.pickWords(words[4:]) self.content = self.pickWords(words[4:])
else: else:
#print (line)
self.content = self.pickWords(words[3:]) self.content = self.pickWords(words[3:])
else: else:
print (line)
if self.cmd == 'PRIVMSG': if self.cmd == 'PRIVMSG':
self.channel = words[2].decode() self.channel = words[2].decode()
self.content = b' '.join(words[3:]) self.content = b' '.join(words[3:])
@ -247,7 +245,6 @@ class Message:
minute = result.group(9) minute = result.group(9)
second = result.group(11) second = result.group(11)
print ("Chaîne reconnue : %s/%s/%s %s:%s:%s"%(day, month, year, hour, minute, second))
if year == None: if year == None:
year = date.today().year year = date.today().year
if hour == None: if hour == None:

View File

@ -17,9 +17,10 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
import os
import imp import imp
import logging
import os
import sys
import traceback import traceback
import bot import bot
@ -28,6 +29,11 @@ from prompt.builtins import load_file
import importer import importer
if __name__ == "__main__": if __name__ == "__main__":
# Setup loggin interface
logging.basicConfig(filename='nemubot.log', level=logging.DEBUG)
logging.Formatter('%(asctime)s %(name)s %(levelname)s %(message)s')
logger = logging.getLogger(__name__)
# Create bot context # Create bot context
context = bot.Bot(0, "FIXME") context = bot.Bot(0, "FIXME")

View File

@ -16,9 +16,12 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import os import os
import xmlparser import xmlparser
logger = logging.getLogger(__name__)
def end(toks, context, prompt): def end(toks, context, prompt):
"""Quit the prompt for reload or exit""" """Quit the prompt for reload or exit"""
if toks[0] == "refresh": if toks[0] == "refresh":
@ -66,10 +69,10 @@ def load_file(filename, context):
if context.addServer(server, config["nick"], if context.addServer(server, config["nick"],
config["owner"], config["realname"], config["owner"], config["realname"],
server.hasAttribute("ssl")): server.hasAttribute("ssl")):
print (" Server `%s:%s' successfully added." logger.info("Server `%s:%s' successfully added."
% (server["server"], server["port"])) % (server["server"], server["port"]))
else: else:
print (" Server `%s:%s' already added, skiped." logger.warn("Server `%s:%s' already added, skiped."
% (server["server"], server["port"])) % (server["server"], server["port"]))
# Load files asked by the configuration file # Load files asked by the configuration file

View File

@ -16,9 +16,12 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import traceback import traceback
import sys import sys
logger = logging.getLogger(__name__)
class Response: class Response:
def __init__(self, sender, message=None, channel=None, nick=None, server=None, def __init__(self, sender, message=None, channel=None, nick=None, server=None,
nomore="No more message", title=None, more="(suite) ", count=None, nomore="No more message", title=None, more="(suite) ", count=None,
@ -54,7 +57,9 @@ class Response:
if sender is None or sender.find("!") < 0: if sender is None or sender.find("!") < 0:
if sender is not None: if sender is not None:
exc_type, exc_value, exc_traceback = sys.exc_info() exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_exception(exc_type, "\033[1;35mWarning:\033[0m bad sender provided in Response, it will be ignored.", exc_traceback) logger.warn(traceback.format_exception(exc_type,
"Bad sender provided in Response, it will be ignored.",
exc_traceback))
self.sender = None self.sender = None
else: else:
self.sender = sender self.sender = sender

View File

@ -55,7 +55,7 @@ class DCC(server.Server):
self.port = self.foundPort() self.port = self.foundPort()
if self.port is None: if self.port is None:
print ("No more available slot for DCC connection") self.logger.critical("No more available slot for DCC connection")
self.setError("Il n'y a plus de place disponible sur le serveur" self.setError("Il n'y a plus de place disponible sur le serveur"
" pour initialiser une session DCC.") " pour initialiser une session DCC.")
@ -81,7 +81,7 @@ class DCC(server.Server):
self.s = socket.socket() self.s = socket.socket()
try: try:
self.s.connect((host, port)) self.s.connect((host, port))
print ('Accepted user from', host, port, "for", self.sender) self.logger.info("Accepted user from %s:%d for %s" % (host, port, self.sender))
self.connected = True self.connected = True
self.stop = False self.stop = False
except: except:
@ -106,7 +106,7 @@ class DCC(server.Server):
self.setError("Une erreur s'est produite durant la tentative" self.setError("Une erreur s'est produite durant la tentative"
" d'ouverture d'une session DCC.") " d'ouverture d'une session DCC.")
return False return False
print ('Listen on', self.port, "for", self.sender) self.logger.info("Listening on %d for %s" % (self.port, self.sender))
#Send CTCP request for DCC #Send CTCP request for DCC
self.srv.send_ctcp(self.sender, self.srv.send_ctcp(self.sender,
@ -117,7 +117,7 @@ class DCC(server.Server):
s.listen(1) s.listen(1)
#Waiting for the client #Waiting for the client
(self.s, addr) = s.accept() (self.s, addr) = s.accept()
print ('Connected by', addr) self.logger.info("Connected by %d" % addr)
self.connected = True self.connected = True
return True return True
@ -151,7 +151,7 @@ class DCC(server.Server):
except RuntimeError: except RuntimeError:
pass pass
else: else:
print("File not found `%s'" % filename) self.logger.error("File not found `%s'" % filename)
def run(self): def run(self):
self.stopping.clear() self.stopping.clear()
@ -204,7 +204,7 @@ class DCC(server.Server):
if self.realname in self.srv.dcc_clients: if self.realname in self.srv.dcc_clients:
del self.srv.dcc_clients[self.realname] del self.srv.dcc_clients[self.realname]
print ("Closing connection with", self.nick) self.logger.info("Closing connection with " + self.nick)
self.stopping.set() self.stopping.set()
if self.closing_event is not None: if self.closing_event is not None:
self.closing_event() self.closing_event()

View File

@ -43,10 +43,10 @@ class IRCServer(server.Server):
realname -- string used as realname on this server realname -- string used as realname on this server
ssl -- require SSL? ssl -- require SSL?
""" """
server.Server.__init__(self)
self.node = node self.node = node
server.Server.__init__(self)
self.nick = nick self.nick = nick
self.owner = owner self.owner = owner
self.realname = realname self.realname = realname
@ -173,7 +173,7 @@ class IRCServer(server.Server):
self.s.connect((self.host, self.port)) #Connect to server self.s.connect((self.host, self.port)) #Connect to server
except socket.error as e: except socket.error as e:
self.s = None self.s = None
print ("\033[1;31mError:\033[0m Unable to connect to %s:%d: %s" self.logger.critical("Unable to connect to %s:%d: %s"
% (self.host, self.port, os.strerror(e.errno))) % (self.host, self.port, os.strerror(e.errno)))
return return
self.stopping.clear() self.stopping.clear()
@ -185,10 +185,10 @@ class IRCServer(server.Server):
self.realname)).encode()) self.realname)).encode())
raw = self.s.recv(1024) raw = self.s.recv(1024)
if not raw: if not raw:
print ("Unable to connect to %s:%d" % (self.host, self.port)) self.logger.critical("Unable to connect to %s:%d" % (self.host, self.port))
return return
self.connected = True self.connected = True
print ("Connection to %s:%d completed" % (self.host, self.port)) self.logger.info("Connection to %s:%d completed" % (self.host, self.port))
if len(self.channels) > 0: if len(self.channels) > 0:
for chn in self.channels.keys(): for chn in self.channels.keys():
@ -214,7 +214,7 @@ class IRCServer(server.Server):
self.connected = False self.connected = False
if self.closing_event is not None: if self.closing_event is not None:
self.closing_event() self.closing_event()
print ("Server `%s' successfully stopped." % self.id) self.logger.info("Server `%s' successfully stopped." % self.id)
self.stopping.set() self.stopping.set()
# Rearm Thread # Rearm Thread
threading.Thread.__init__(self) threading.Thread.__init__(self)
@ -255,17 +255,17 @@ class IRCServer(server.Server):
"""Send a message without checks or format""" """Send a message without checks or format"""
#TODO: add something for post message treatment here #TODO: add something for post message treatment here
if channel == self.nick: if channel == self.nick:
print ("\033[1;35mWarning:\033[0m Nemubot talks to himself: %s" % msg) self.logger.warn("Nemubot talks to himself: %s" % msg)
traceback.print_stack() self.logger.debug(traceback.print_stack())
if line is not None and channel is not None: if line is not None and channel is not None:
if self.s is None: if self.s is None:
print ("\033[1;35mWarning:\033[0m Attempt to send message on a non connected server: %s: %s" % (self.id, line)) self.logger.warn("Attempt to send message on a non connected server: %s: %s" % (self.id, line))
traceback.print_stack() self.logger.debug(traceback.format_stack())
elif len(line) < 442: elif len(line) < 442:
self.s.send(("%s %s :%s%s" % (cmd, channel, line, endl)).encode ()) self.s.send(("%s %s :%s%s" % (cmd, channel, line, endl)).encode ())
else: else:
print ("\033[1;35mWarning:\033[0m Message truncated due to size (%d ; max : 442) : %s" % (len(line), line)) self.logger.warn("Message truncated due to size (%d ; max : 442) : %s" % (len(line), line))
traceback.print_stack() self.logger.debug(traceback.format_stack())
self.s.send (("%s %s :%s%s" % (cmd, channel, line[0:442]+"<…>", endl)).encode ()) self.s.send (("%s %s :%s%s" % (cmd, channel, line[0:442]+"<…>", endl)).encode ())
def send_msg_usr(self, user, msg): def send_msg_usr(self, user, msg):

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import socket import socket
import threading import threading
@ -29,6 +30,8 @@ class Server(threading.Thread):
self.moremessages = dict() self.moremessages = dict()
self.logger = logging.getLogger(__name__ + "/" + self.id)
threading.Thread.__init__(self) threading.Thread.__init__(self)
def isDCC(self, to=None): def isDCC(self, to=None):
@ -142,7 +145,7 @@ class Server(threading.Thread):
self.connected = False self.connected = False
#Send a message in order to close the socket #Send a message in order to close the socket
try: try:
self.s.send(("Bye!\r\n" % self.nick).encode ()) self.s.send(("Bye!\r\n").encode ())
except: except:
pass pass
self.stopping.wait() self.stopping.wait()
@ -155,6 +158,7 @@ class Server(threading.Thread):
self._receive_action = receive_action self._receive_action = receive_action
if not self.connected: if not self.connected:
self.stop = False self.stop = False
self.logger.info("Entering main loop for server")
try: try:
self.start() self.start()
except RuntimeError: except RuntimeError: