diff --git a/.gitignore b/.gitignore
index 50aca48..3981a19 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,6 @@
TAGS
*.py[cod]
__pycache__
+build/
datas/
+dist/
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..77a606b
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,7 @@
+language: python
+python:
+ - 3.2
+ - 3.3
+ - 3.4
+install: pip install -r requirements.txt
+script: pip install .
diff --git a/README.md b/README.md
index e021df2..7720bb6 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,21 @@
-# *nemubot*
+# nemubot
-An extremely modulable IRC bot, built around XML configuration files!
+A smart and modulable IM bot!
+
+## Usage
+
+TODO
## Documentation
Have a look to the wiki at https://github.com/nemunaire/nemubot/wiki
+
+## Building
+
+TODO
+
+## License
+
+This software is copyright (c) 2014 by nemunaire.
+
+This is free software; you can redistribute it and/or modify it under the same terms as GNU Affero General Public Licence v3.
diff --git a/nemubot.py b/bin/nemubot
similarity index 86%
rename from nemubot.py
rename to bin/nemubot
index 4e77007..1d19424 100755
--- a/nemubot.py
+++ b/bin/nemubot
@@ -1,8 +1,8 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -22,14 +22,14 @@ import os
import imp
import traceback
-import bot
-import prompt
-from prompt.builtins import load_file
-import importer
+import nemubot
+from nemubot import prompt
+from nemubot.prompt.builtins import load_file
+from nemubot import importer
if __name__ == "__main__":
# Create bot context
- context = bot.Bot(0, "FIXME")
+ context = nemubot.Bot()
# Load the prompt
prmpt = prompt.Prompt()
@@ -50,7 +50,7 @@ if __name__ == "__main__":
else:
load_file(arg, context)
- print ("Nemubot v%s ready, my PID is %i!" % (context.version_txt,
+ print ("Nemubot v%s ready, my PID is %i!" % (nemubot.__version__,
os.getpid()))
while prmpt.run(context):
try:
@@ -63,7 +63,7 @@ if __name__ == "__main__":
# Reload all other modules
bot.reload()
print ("\033[1;32mContext reloaded\033[0m, now in Nemubot %s" %
- context.version_txt)
+ nemubot.__version__)
except:
print ("\033[1;31mUnable to reload the prompt due to errors.\033[0"
"m Fix them before trying to reload the prompt.")
diff --git a/nemuspeak.py b/bin/nemuspeak
similarity index 100%
rename from nemuspeak.py
rename to bin/nemuspeak
diff --git a/DCC.py b/lib/DCC.py
similarity index 98%
rename from DCC.py
rename to lib/DCC.py
index 5dc46ea..1f3de55 100644
--- a/DCC.py
+++ b/lib/DCC.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -25,8 +25,8 @@ import time
import threading
import traceback
-import message
-import server
+import nemubot.message
+from nemubot import server
#Store all used ports
PORTS = list()
diff --git a/IRCServer.py b/lib/IRCServer.py
similarity index 97%
rename from IRCServer.py
rename to lib/IRCServer.py
index c208b44..549396e 100644
--- a/IRCServer.py
+++ b/lib/IRCServer.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -23,12 +23,12 @@ import socket
import threading
import traceback
-from channel import Channel
-from DCC import DCC
-from hooks import Hook
-import message
-import server
-import xmlparser
+from nemubot.channel import Channel
+from nemubot.DCC import DCC
+from nemubot.hooks import Hook
+import nemubot.message
+from nemubot import server
+import nemubot.xmlparser
class IRCServer(server.Server):
"""Class to interact with an IRC server"""
diff --git a/bot.py b/lib/__init__.py
similarity index 90%
rename from bot.py
rename to lib/__init__.py
index ff66b8a..72144f4 100644
--- a/bot.py
+++ b/lib/__init__.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -16,43 +16,47 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-from datetime import datetime
-from datetime import timedelta
+from datetime import datetime, timedelta
+from ipaddress import ip_address
+import logging
from queue import Queue
-import threading
-import time
-import re
+import uuid
-import consumer
-import event
-import hooks
-from networkbot import NetworkBot
-from IRCServer import IRCServer
-from DCC import DCC
-import response
+__version__ = '4.0.dev0'
+__author__ = 'nemunaire'
-ID_letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+from nemubot import consumer
+from nemubot import event
+from nemubot import hooks
+from nemubot.networkbot import NetworkBot
+from nemubot.IRCServer import IRCServer
+from nemubot.DCC import DCC
+from nemubot import response
class Bot:
- def __init__(self, ip, realname, mp=list()):
- # Bot general informations
- self.version = 3.3
- self.version_txt = "3.3"
- # Save various informations
- self.ip = ip
- self.realname = realname
- self.ctcp_capabilities = dict()
- self.init_ctcp_capabilities()
+ """Class containing the bot context and ensuring key goals"""
+
+ def __init__(self, ip="127.0.0.1", modules_paths=list(), data_path="./datas/"):
+ """Initialize the bot context
+
+ Keyword arguments:
+ ip -- The external IP of the bot (default: 127.0.0.1)
+ modules_paths -- Paths to all directories where looking for module
+ data_path -- Path to directory where store bot context data
+ """
+
+ # External IP for accessing this bot
+ self.ip = ip_address(ip)
+
+ # Context paths
+ self.modules_paths = modules_paths
+ self.data_path = data_path
# Keep global context: servers and modules
self.servers = dict()
self.modules = dict()
- # Context paths
- self.modules_path = mp
- self.datas_path = './datas/'
-
# Events
self.events = list()
self.event_timer = None
@@ -62,13 +66,16 @@ class Bot:
# Other known bots, making a bots network
self.network = dict()
- self.hooks_cache = dict()
+ self._hooks_cache = dict()
# Messages to be treated
self.cnsr_queue = Queue()
self.cnsr_thrd = list()
self.cnsr_thrd_size = -1
+ # Stop the class thread
+ self.stop = False
+
self.hooks.add_hook("irc_hook",
hooks.Hook(self.treat_prvmsg, "PRIVMSG"),
self)
@@ -80,13 +87,13 @@ class Bot:
self.ctcp_capabilities["CLIENTINFO"] = self._ctcp_clientinfo
self.ctcp_capabilities["DCC"] = self._ctcp_dcc
self.ctcp_capabilities["NEMUBOT"] = lambda srv, msg: _ctcp_response(
- msg.sender, "NEMUBOT %f" % self.version)
+ msg.sender, "NEMUBOT %f" % __version__)
self.ctcp_capabilities["TIME"] = lambda srv, msg: _ctcp_response(
msg.sender, "TIME %s" % (datetime.now()))
self.ctcp_capabilities["USERINFO"] = lambda srv, msg: _ctcp_response(
msg.sender, "USERINFO %s" % self.realname)
self.ctcp_capabilities["VERSION"] = lambda srv, msg: _ctcp_response(
- msg.sender, "VERSION nemubot v%s" % self.version_txt)
+ msg.sender, "VERSION nemubot v%s" % __version__)
def _ctcp_clientinfo(self, srv, msg):
"""Response to CLIENTINFO CTCP message"""
@@ -104,6 +111,8 @@ class Bot:
print ("DCC: unable to connect to %s:%s" % (ip, msg.cmds[4]))
+ # Events methods
+
def add_event(self, evt, eid=None, module_src=None):
"""Register an event and return its identifiant for futur update"""
if eid is None:
@@ -125,7 +134,7 @@ class Bot:
break
self.events.insert(i + 1, evt)
if i == -1:
- self.update_timer()
+ self._update_event_timer()
if len(self.events) <= 0 or self.events[i+1] != evt:
return None
@@ -138,7 +147,7 @@ class Bot:
"""Find and remove an event from list"""
if len(self.events) > 0 and id == self.events[0].id:
self.events.remove(self.events[0])
- self.update_timer()
+ self._update_event_timer()
if module_src is not None:
module_src.REGISTERED_EVENTS.remove(evt.id)
return True
@@ -152,7 +161,7 @@ class Bot:
return True
return False
- def update_timer(self):
+ def _update_event_timer(self):
"""Relaunch the timer to end with the closest event"""
# Reset the timer if this is the first item
if self.event_timer is not None:
@@ -180,9 +189,11 @@ class Bot:
self.cnsr_queue.put_nowait(consumer.EventConsumer(evt))
self.update_consumers()
- self.update_timer()
+ self._update_event_timer()
+ # Server methods
+
def addServer(self, node, nick, owner, realname, ssl=False):
"""Add a new server to the context"""
srv = IRCServer(node, nick, owner, realname, ssl)
@@ -199,6 +210,8 @@ class Bot:
return False
+ # Modules methods
+
def add_module(self, module):
"""Add a module to the context, if already exists, unload the
old one before"""
@@ -218,8 +231,8 @@ class Bot:
if path[len(path)-1] != "/":
path = path + "/"
- if path not in self.modules_path:
- self.modules_path.append(path)
+ if path not in self.modules_paths:
+ self.modules_paths.append(path)
return True
return False
@@ -243,6 +256,9 @@ class Bot:
return True
return False
+
+ # Consumers methods
+
def update_consumers(self):
"""Launch new consumer thread if necessary"""
if self.cnsr_queue.qsize() > self.cnsr_thrd_size:
@@ -292,14 +308,14 @@ class Bot:
# Hooks cache
def create_cache(self, name):
- if name not in self.hooks_cache:
+ if name not in self._hooks_cache:
if isinstance(self.hooks.__dict__[name], list):
- self.hooks_cache[name] = list()
+ self._hooks_cache[name] = list()
# Start by adding locals hooks
for h in self.hooks.__dict__[name]:
tpl = (h, 0, self.hooks.__dict__[name], self.hooks.bot)
- self.hooks_cache[name].append(tpl)
+ self._hooks_cache[name].append(tpl)
# Now, add extermal hooks
level = 0
@@ -309,17 +325,17 @@ class Bot:
if len(self.network[ext].hooks) > level:
lvl_exist = True
for h in self.network[ext].hooks[level].__dict__[name]:
- if h not in self.hooks_cache[name]:
- self.hooks_cache[name].append((h, level + 1,
+ if h not in self._hooks_cache[name]:
+ self._hooks_cache[name].append((h, level + 1,
self.network[ext].hooks[level].__dict__[name], self.network[ext].hooks[level].bot))
level += 1
elif isinstance(self.hooks.__dict__[name], dict):
- self.hooks_cache[name] = dict()
+ self._hooks_cache[name] = dict()
# Start by adding locals hooks
for h in self.hooks.__dict__[name]:
- self.hooks_cache[name][h] = (self.hooks.__dict__[name][h], 0,
+ self._hooks_cache[name][h] = (self.hooks.__dict__[name][h], 0,
self.hooks.__dict__[name],
self.hooks.bot)
@@ -331,14 +347,14 @@ class Bot:
if len(self.network[ext].hooks) > level:
lvl_exist = True
for h in self.network[ext].hooks[level].__dict__[name]:
- if h not in self.hooks_cache[name]:
- self.hooks_cache[name][h] = (self.network[ext].hooks[level].__dict__[name][h], level + 1, self.network[ext].hooks[level].__dict__[name], self.network[ext].hooks[level].bot)
+ if h not in self._hooks_cache[name]:
+ self._hooks_cache[name][h] = (self.network[ext].hooks[level].__dict__[name][h], level + 1, self.network[ext].hooks[level].__dict__[name], self.network[ext].hooks[level].bot)
level += 1
else:
raise Exception(name + " hook type unrecognized")
- return self.hooks_cache[name]
+ return self._hooks_cache[name]
# Treatment
@@ -603,7 +619,7 @@ def _help_msg(sndr, modules, cmd):
return res
def hotswap(bak):
- return Bot(bak.servers, bak.modules, bak.modules_path)
+ return Bot(bak.servers, bak.modules, bak.modules_paths)
def reload():
import imp
diff --git a/channel.py b/lib/channel.py
similarity index 96%
rename from channel.py
rename to lib/channel.py
index 6a67d76..914d29e 100644
--- a/channel.py
+++ b/lib/channel.py
@@ -1,7 +1,7 @@
# coding=utf-8
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
diff --git a/consumer.py b/lib/consumer.py
similarity index 95%
rename from consumer.py
rename to lib/consumer.py
index dc2bcd5..933ad40 100644
--- a/consumer.py
+++ b/lib/consumer.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -22,11 +22,10 @@ import threading
import traceback
import sys
-import bot
-from DCC import DCC
-from message import Message
-import response
-import server
+from nemubot.DCC import DCC
+from nemubot.message import Message
+from nemubot import response
+from nemubot import server
class MessageConsumer:
"""Store a message before treating"""
diff --git a/credits.py b/lib/credits.py
similarity index 100%
rename from credits.py
rename to lib/credits.py
diff --git a/event.py b/lib/event.py
similarity index 97%
rename from event.py
rename to lib/event.py
index 89b10f3..5160127 100644
--- a/event.py
+++ b/lib/event.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
diff --git a/exception.py b/lib/exception.py
similarity index 87%
rename from exception.py
rename to lib/exception.py
index 7acfaf8..51346bb 100644
--- a/exception.py
+++ b/lib/exception.py
@@ -1,7 +1,7 @@
# coding=utf-8
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-from response import Response
+from nemubot.response import Response
class IRCException(Exception):
diff --git a/hooks.py b/lib/hooks.py
similarity index 95%
rename from hooks.py
rename to lib/hooks.py
index e247be3..b560523 100644
--- a/hooks.py
+++ b/lib/hooks.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -18,8 +18,8 @@
import re
-from response import Response
-from exception import IRCException
+from nemubot.response import Response
+from nemubot.exception import IRCException
class MessagesHook:
def __init__(self, context, bot):
@@ -56,8 +56,8 @@ class MessagesHook:
"add_hook function, please fix it in order to be "
"compatible with unload feature")
- if store in self.context.hooks_cache:
- del self.context.hooks_cache[store]
+ if store in self.context._hooks_cache:
+ del self.context._hooks_cache[store]
if not hasattr(self, store):
print ("\033[1;35mWarning:\033[0m unrecognized hook store")
@@ -143,8 +143,8 @@ class MessagesHook:
def del_hook(self, store, hook, module_src=None):
"""Remove a registered hook from a given store"""
- if store in self.context.hooks_cache:
- del self.context.hooks_cache[store]
+ if store in self.context._hooks_cache:
+ del self.context._hooks_cache[store]
if not hasattr(self, store):
print ("Warning: unrecognized hook store type")
diff --git a/importer.py b/lib/importer.py
similarity index 95%
rename from importer.py
rename to lib/importer.py
index 8249b1f..126d8f0 100644
--- a/importer.py
+++ b/lib/importer.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -16,17 +16,19 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
+from distutils.version import StrictVersion
from importlib.abc import Finder
from importlib.abc import SourceLoader
import imp
import os
import sys
-import event
-import exception
-from hooks import Hook
-import response
-import xmlparser
+import nemubot
+from nemubot import event
+from nemubot import exception
+from nemubot.hooks import Hook
+from nemubot import response
+from nemubot import xmlparser
class ModuleFinder(Finder):
def __init__(self, context, prompt):
@@ -37,7 +39,7 @@ class ModuleFinder(Finder):
#print ("looking for", fullname, "in", path)
# Search only for new nemubot modules (packages init)
if path is None:
- for mpath in self.context.modules_path:
+ for mpath in self.context.modules_paths:
#print ("looking for", fullname, "in", mpath)
if os.path.isfile(mpath + fullname + ".xml"):
return ModuleLoader(self.context, self.prompt, fullname,
@@ -137,7 +139,7 @@ class ModuleLoader(SourceLoader):
if not hasattr(module, "nemubotversion"):
raise ImportError("Module `%s' is not a nemubot module."%self.name)
# Check module version
- if module.nemubotversion != self.context.version:
+ if StrictVersion(module.nemubotversion) != StrictVersion(nemubot.__version__):
raise ImportError("Module `%s' is not compatible with this "
"version." % self.name)
diff --git a/message.py b/lib/message.py
similarity index 97%
rename from message.py
rename to lib/message.py
index d14a16d..86c920f 100644
--- a/message.py
+++ b/lib/message.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -21,10 +21,10 @@ import re
import shlex
import time
-import credits
-from credits import Credits
-from response import Response
-import xmlparser
+import nemubot.credits
+from nemubot.credits import Credits
+from nemubot.response import Response
+import nemubot.xmlparser
CREDITS = {}
filename = ""
diff --git a/networkbot.py b/lib/networkbot.py
similarity index 97%
rename from networkbot.py
rename to lib/networkbot.py
index 756ab3c..0839e50 100644
--- a/networkbot.py
+++ b/lib/networkbot.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -22,9 +22,9 @@ import shlex
import urllib.parse
import zlib
-from DCC import DCC
-import hooks
-from response import Response
+from nemubot.DCC import DCC
+import nemubot.hooks
+from nemubot.response import Response
class NetworkBot:
def __init__(self, context, srv, dest, dcc=None):
diff --git a/prompt/__init__.py b/lib/prompt/__init__.py
similarity index 96%
rename from prompt/__init__.py
rename to lib/prompt/__init__.py
index 62c8dc3..d4046b1 100644
--- a/prompt/__init__.py
+++ b/lib/prompt/__init__.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
diff --git a/prompt/builtins.py b/lib/prompt/builtins.py
similarity index 97%
rename from prompt/builtins.py
rename to lib/prompt/builtins.py
index 6e7aa5a..d21909a 100644
--- a/prompt/builtins.py
+++ b/lib/prompt/builtins.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -17,7 +17,8 @@
# along with this program. If not, see .
import os
-import xmlparser
+
+from nemubot import xmlparser
def end(toks, context, prompt):
"""Quit the prompt for reload or exit"""
diff --git a/response.py b/lib/response.py
similarity index 97%
rename from response.py
rename to lib/response.py
index 9fda7f8..ae14b98 100644
--- a/response.py
+++ b/lib/response.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -165,7 +165,7 @@ class Response:
self.elt = 0
return msg
-import hooks
+import nemubot.hooks
class Hook:
def __init__(self, TYPE, call, name=None, data=None, regexp=None,
channels=list(), server=None, end=None, call_end=None,
diff --git a/server.py b/lib/server.py
similarity index 97%
rename from server.py
rename to lib/server.py
index e16bd57..1496154 100644
--- a/server.py
+++ b/lib/server.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
diff --git a/tools/__init__.py b/lib/tools/__init__.py
similarity index 100%
rename from tools/__init__.py
rename to lib/tools/__init__.py
diff --git a/tools/web.py b/lib/tools/web.py
similarity index 97%
rename from tools/web.py
rename to lib/tools/web.py
index 4a59878..a7219d5 100644
--- a/tools/web.py
+++ b/lib/tools/web.py
@@ -1,7 +1,7 @@
# coding=utf-8
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
diff --git a/tools/wrapper.py b/lib/tools/wrapper.py
similarity index 93%
rename from tools/wrapper.py
rename to lib/tools/wrapper.py
index 3f4f5e6..bbe4ce4 100644
--- a/tools/wrapper.py
+++ b/lib/tools/wrapper.py
@@ -1,7 +1,7 @@
# coding=utf-8
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
diff --git a/xmlparser/__init__.py b/lib/xmlparser/__init__.py
similarity index 94%
rename from xmlparser/__init__.py
rename to lib/xmlparser/__init__.py
index adfb85b..1d8bf35 100644
--- a/xmlparser/__init__.py
+++ b/lib/xmlparser/__init__.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
diff --git a/xmlparser/node.py b/lib/xmlparser/node.py
similarity index 100%
rename from xmlparser/node.py
rename to lib/xmlparser/node.py
diff --git a/modules/cmd_server.py b/modules/cmd_server.py
index 8248da9..34bed3b 100644
--- a/modules/cmd_server.py
+++ b/modules/cmd_server.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
-# Nemubot is a modulable IRC bot, built around XML configuration files.
-# Copyright (C) 2012 Mercier Pierre-Olivier
+# Nemubot is a smart and modulable IM bot.
+# Copyright (C) 2012-2014 nemunaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -19,9 +19,9 @@
import traceback
import sys
-from networkbot import NetworkBot
+from nemubot.networkbot import NetworkBot
-nemubotversion = 3.3
+nemubotversion = 4.0
NODATA = True
def getserver(toks, context, prompt):
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..e69de29
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..181e318
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python3
+#-*- encoding: utf-8 -*-
+
+import os
+import re
+from glob import glob
+try:
+ from setuptools import setup
+except ImportError:
+ from distutils.core import setup
+
+with open(os.path.join(os.path.dirname(__file__),
+ 'lib',
+ '__init__.py')) as f:
+ version = re.search("__version__ = '([^']+)'", f.read()).group(1)
+
+with open('requirements.txt', 'r') as f:
+ requires = [x.strip() for x in f if x.strip()]
+
+#with open('test-requirements.txt', 'r') as f:
+# test_requires = [x.strip() for x in f if x.strip()]
+
+dirs = os.listdir("./modules/")
+data_files = []
+for i in dirs:
+ data_files.append(("nemubot/modules", glob('./modules/' + i + '/*')))
+
+setup(
+ name="nemubot",
+ version=version,
+ description="A smart and modulable IM bot!",
+ long_description=open('README.md').read(),
+
+ author='nemunaire',
+ author_email='nemunaire@nemunai.re',
+
+ url='https://github.com/nemunaire/nemubot',
+ license='AGPLv3',
+
+ classifiers=[
+ 'Development Status :: 2 - Pre-Alpha',
+
+ 'Environment :: Console',
+
+ 'Topic :: Communications :: Chat :: Internet Relay Chat',
+ 'Intended Audience :: Information Technology',
+
+ 'License :: OSI Approved :: GNU Affero General Public License v3',
+
+ 'Operating System :: POSIX',
+
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.2',
+ 'Programming Language :: Python :: 3.3',
+ 'Programming Language :: Python :: 3.4',
+ ],
+
+ keywords='bot irc',
+
+ install_requires = requires,
+
+ package_dir={ 'nemubot': 'lib' },
+
+ packages=[
+ 'nemubot',
+ 'nemubot.prompt',
+ 'nemubot.tools',
+ 'nemubot.xmlparser',
+ ],
+
+ scripts=[
+ 'bin/nemubot',
+# 'bin/module_tester',
+ ],
+
+# data_files=data_files,
+)