Compare commits
3 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 26faed014f | |||
| f9970cba42 | |||
| 35ae6b6245 |
29 changed files with 252 additions and 134 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -3,4 +3,6 @@
|
||||||
TAGS
|
TAGS
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
__pycache__
|
__pycache__
|
||||||
|
build/
|
||||||
datas/
|
datas/
|
||||||
|
dist/
|
||||||
|
|
|
||||||
7
.travis.yml
Normal file
7
.travis.yml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
language: python
|
||||||
|
python:
|
||||||
|
- 3.2
|
||||||
|
- 3.3
|
||||||
|
- 3.4
|
||||||
|
install: pip install -r requirements.txt
|
||||||
|
script: pip install .
|
||||||
18
README.md
18
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
|
## Documentation
|
||||||
|
|
||||||
Have a look to the wiki at https://github.com/nemunaire/nemubot/wiki
|
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.
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -22,14 +22,14 @@ import os
|
||||||
import imp
|
import imp
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
import bot
|
import nemubot
|
||||||
import prompt
|
from nemubot import prompt
|
||||||
from prompt.builtins import load_file
|
from nemubot.prompt.builtins import load_file
|
||||||
import importer
|
from nemubot import importer
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Create bot context
|
# Create bot context
|
||||||
context = bot.Bot(0, "FIXME")
|
context = nemubot.Bot()
|
||||||
|
|
||||||
# Load the prompt
|
# Load the prompt
|
||||||
prmpt = prompt.Prompt()
|
prmpt = prompt.Prompt()
|
||||||
|
|
@ -50,7 +50,7 @@ if __name__ == "__main__":
|
||||||
else:
|
else:
|
||||||
load_file(arg, context)
|
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()))
|
os.getpid()))
|
||||||
while prmpt.run(context):
|
while prmpt.run(context):
|
||||||
try:
|
try:
|
||||||
|
|
@ -63,7 +63,7 @@ if __name__ == "__main__":
|
||||||
# Reload all other modules
|
# Reload all other modules
|
||||||
bot.reload()
|
bot.reload()
|
||||||
print ("\033[1;32mContext reloaded\033[0m, now in Nemubot %s" %
|
print ("\033[1;32mContext reloaded\033[0m, now in Nemubot %s" %
|
||||||
context.version_txt)
|
nemubot.__version__)
|
||||||
except:
|
except:
|
||||||
print ("\033[1;31mUnable to reload the prompt due to errors.\033[0"
|
print ("\033[1;31mUnable to reload the prompt due to errors.\033[0"
|
||||||
"m Fix them before trying to reload the prompt.")
|
"m Fix them before trying to reload the prompt.")
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -25,8 +25,8 @@ import time
|
||||||
import threading
|
import threading
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
import message
|
import nemubot.message
|
||||||
import server
|
from nemubot import server
|
||||||
|
|
||||||
#Store all used ports
|
#Store all used ports
|
||||||
PORTS = list()
|
PORTS = list()
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -23,12 +23,12 @@ import socket
|
||||||
import threading
|
import threading
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from channel import Channel
|
from nemubot.channel import Channel
|
||||||
from DCC import DCC
|
from nemubot.DCC import DCC
|
||||||
from hooks import Hook
|
from nemubot.hooks import Hook
|
||||||
import message
|
import nemubot.message
|
||||||
import server
|
from nemubot import server
|
||||||
import xmlparser
|
import nemubot.xmlparser
|
||||||
|
|
||||||
class IRCServer(server.Server):
|
class IRCServer(server.Server):
|
||||||
"""Class to interact with an IRC server"""
|
"""Class to interact with an IRC server"""
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# 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
|
# 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/>.
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
from datetime import timedelta
|
from ipaddress import ip_address
|
||||||
|
import logging
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
import threading
|
import uuid
|
||||||
import time
|
|
||||||
import re
|
|
||||||
|
|
||||||
import consumer
|
__version__ = '4.0.dev0'
|
||||||
import event
|
__author__ = 'nemunaire'
|
||||||
import hooks
|
|
||||||
from networkbot import NetworkBot
|
|
||||||
from IRCServer import IRCServer
|
|
||||||
from DCC import DCC
|
|
||||||
import response
|
|
||||||
|
|
||||||
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:
|
class Bot:
|
||||||
def __init__(self, ip, realname, mp=list()):
|
|
||||||
# Bot general informations
|
|
||||||
self.version = 3.3
|
|
||||||
self.version_txt = "3.3"
|
|
||||||
|
|
||||||
# Save various informations
|
"""Class containing the bot context and ensuring key goals"""
|
||||||
self.ip = ip
|
|
||||||
self.realname = realname
|
def __init__(self, ip="127.0.0.1", modules_paths=list(), data_path="./datas/"):
|
||||||
self.ctcp_capabilities = dict()
|
"""Initialize the bot context
|
||||||
self.init_ctcp_capabilities()
|
|
||||||
|
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
|
# Keep global context: servers and modules
|
||||||
self.servers = dict()
|
self.servers = dict()
|
||||||
self.modules = dict()
|
self.modules = dict()
|
||||||
|
|
||||||
# Context paths
|
|
||||||
self.modules_path = mp
|
|
||||||
self.datas_path = './datas/'
|
|
||||||
|
|
||||||
# Events
|
# Events
|
||||||
self.events = list()
|
self.events = list()
|
||||||
self.event_timer = None
|
self.event_timer = None
|
||||||
|
|
@ -62,13 +66,16 @@ class Bot:
|
||||||
|
|
||||||
# Other known bots, making a bots network
|
# Other known bots, making a bots network
|
||||||
self.network = dict()
|
self.network = dict()
|
||||||
self.hooks_cache = dict()
|
self._hooks_cache = dict()
|
||||||
|
|
||||||
# Messages to be treated
|
# Messages to be treated
|
||||||
self.cnsr_queue = Queue()
|
self.cnsr_queue = Queue()
|
||||||
self.cnsr_thrd = list()
|
self.cnsr_thrd = list()
|
||||||
self.cnsr_thrd_size = -1
|
self.cnsr_thrd_size = -1
|
||||||
|
|
||||||
|
# Stop the class thread
|
||||||
|
self.stop = False
|
||||||
|
|
||||||
self.hooks.add_hook("irc_hook",
|
self.hooks.add_hook("irc_hook",
|
||||||
hooks.Hook(self.treat_prvmsg, "PRIVMSG"),
|
hooks.Hook(self.treat_prvmsg, "PRIVMSG"),
|
||||||
self)
|
self)
|
||||||
|
|
@ -80,13 +87,13 @@ class Bot:
|
||||||
self.ctcp_capabilities["CLIENTINFO"] = self._ctcp_clientinfo
|
self.ctcp_capabilities["CLIENTINFO"] = self._ctcp_clientinfo
|
||||||
self.ctcp_capabilities["DCC"] = self._ctcp_dcc
|
self.ctcp_capabilities["DCC"] = self._ctcp_dcc
|
||||||
self.ctcp_capabilities["NEMUBOT"] = lambda srv, msg: _ctcp_response(
|
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(
|
self.ctcp_capabilities["TIME"] = lambda srv, msg: _ctcp_response(
|
||||||
msg.sender, "TIME %s" % (datetime.now()))
|
msg.sender, "TIME %s" % (datetime.now()))
|
||||||
self.ctcp_capabilities["USERINFO"] = lambda srv, msg: _ctcp_response(
|
self.ctcp_capabilities["USERINFO"] = lambda srv, msg: _ctcp_response(
|
||||||
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" % __version__)
|
||||||
|
|
||||||
def _ctcp_clientinfo(self, srv, msg):
|
def _ctcp_clientinfo(self, srv, msg):
|
||||||
"""Response to CLIENTINFO CTCP message"""
|
"""Response to CLIENTINFO CTCP message"""
|
||||||
|
|
@ -104,6 +111,8 @@ class Bot:
|
||||||
print ("DCC: unable to connect to %s:%s" % (ip, msg.cmds[4]))
|
print ("DCC: unable to connect to %s:%s" % (ip, msg.cmds[4]))
|
||||||
|
|
||||||
|
|
||||||
|
# Events methods
|
||||||
|
|
||||||
def add_event(self, evt, eid=None, module_src=None):
|
def add_event(self, evt, eid=None, module_src=None):
|
||||||
"""Register an event and return its identifiant for futur update"""
|
"""Register an event and return its identifiant for futur update"""
|
||||||
if eid is None:
|
if eid is None:
|
||||||
|
|
@ -125,7 +134,7 @@ class Bot:
|
||||||
break
|
break
|
||||||
self.events.insert(i + 1, evt)
|
self.events.insert(i + 1, evt)
|
||||||
if i == -1:
|
if i == -1:
|
||||||
self.update_timer()
|
self._update_event_timer()
|
||||||
if len(self.events) <= 0 or self.events[i+1] != evt:
|
if len(self.events) <= 0 or self.events[i+1] != evt:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
@ -138,7 +147,7 @@ class Bot:
|
||||||
"""Find and remove an event from list"""
|
"""Find and remove an event from list"""
|
||||||
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_event_timer()
|
||||||
if module_src is not None:
|
if module_src is not None:
|
||||||
module_src.REGISTERED_EVENTS.remove(evt.id)
|
module_src.REGISTERED_EVENTS.remove(evt.id)
|
||||||
return True
|
return True
|
||||||
|
|
@ -152,7 +161,7 @@ class Bot:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def update_timer(self):
|
def _update_event_timer(self):
|
||||||
"""Relaunch the timer to end with the closest event"""
|
"""Relaunch the timer to end with the closest event"""
|
||||||
# Reset the timer if this is the first item
|
# Reset the timer if this is the first item
|
||||||
if self.event_timer is not None:
|
if self.event_timer is not None:
|
||||||
|
|
@ -180,9 +189,11 @@ class Bot:
|
||||||
self.cnsr_queue.put_nowait(consumer.EventConsumer(evt))
|
self.cnsr_queue.put_nowait(consumer.EventConsumer(evt))
|
||||||
self.update_consumers()
|
self.update_consumers()
|
||||||
|
|
||||||
self.update_timer()
|
self._update_event_timer()
|
||||||
|
|
||||||
|
|
||||||
|
# Server methods
|
||||||
|
|
||||||
def addServer(self, node, nick, owner, realname, ssl=False):
|
def addServer(self, node, nick, owner, realname, ssl=False):
|
||||||
"""Add a new server to the context"""
|
"""Add a new server to the context"""
|
||||||
srv = IRCServer(node, nick, owner, realname, ssl)
|
srv = IRCServer(node, nick, owner, realname, ssl)
|
||||||
|
|
@ -199,6 +210,8 @@ class Bot:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# Modules methods
|
||||||
|
|
||||||
def add_module(self, module):
|
def add_module(self, module):
|
||||||
"""Add a module to the context, if already exists, unload the
|
"""Add a module to the context, if already exists, unload the
|
||||||
old one before"""
|
old one before"""
|
||||||
|
|
@ -218,8 +231,8 @@ class Bot:
|
||||||
if path[len(path)-1] != "/":
|
if path[len(path)-1] != "/":
|
||||||
path = path + "/"
|
path = path + "/"
|
||||||
|
|
||||||
if path not in self.modules_path:
|
if path not in self.modules_paths:
|
||||||
self.modules_path.append(path)
|
self.modules_paths.append(path)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
@ -243,6 +256,9 @@ class Bot:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# Consumers methods
|
||||||
|
|
||||||
def update_consumers(self):
|
def update_consumers(self):
|
||||||
"""Launch new consumer thread if necessary"""
|
"""Launch new consumer thread if necessary"""
|
||||||
if self.cnsr_queue.qsize() > self.cnsr_thrd_size:
|
if self.cnsr_queue.qsize() > self.cnsr_thrd_size:
|
||||||
|
|
@ -292,14 +308,14 @@ class Bot:
|
||||||
# Hooks cache
|
# Hooks cache
|
||||||
|
|
||||||
def create_cache(self, name):
|
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):
|
if isinstance(self.hooks.__dict__[name], list):
|
||||||
self.hooks_cache[name] = list()
|
self._hooks_cache[name] = list()
|
||||||
|
|
||||||
# Start by adding locals hooks
|
# Start by adding locals hooks
|
||||||
for h in self.hooks.__dict__[name]:
|
for h in self.hooks.__dict__[name]:
|
||||||
tpl = (h, 0, self.hooks.__dict__[name], self.hooks.bot)
|
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
|
# Now, add extermal hooks
|
||||||
level = 0
|
level = 0
|
||||||
|
|
@ -309,17 +325,17 @@ class Bot:
|
||||||
if len(self.network[ext].hooks) > level:
|
if len(self.network[ext].hooks) > level:
|
||||||
lvl_exist = True
|
lvl_exist = True
|
||||||
for h in self.network[ext].hooks[level].__dict__[name]:
|
for h in self.network[ext].hooks[level].__dict__[name]:
|
||||||
if h not in self.hooks_cache[name]:
|
if h not in self._hooks_cache[name]:
|
||||||
self.hooks_cache[name].append((h, level + 1,
|
self._hooks_cache[name].append((h, level + 1,
|
||||||
self.network[ext].hooks[level].__dict__[name], self.network[ext].hooks[level].bot))
|
self.network[ext].hooks[level].__dict__[name], self.network[ext].hooks[level].bot))
|
||||||
level += 1
|
level += 1
|
||||||
|
|
||||||
elif isinstance(self.hooks.__dict__[name], dict):
|
elif isinstance(self.hooks.__dict__[name], dict):
|
||||||
self.hooks_cache[name] = dict()
|
self._hooks_cache[name] = dict()
|
||||||
|
|
||||||
# Start by adding locals hooks
|
# Start by adding locals hooks
|
||||||
for h in self.hooks.__dict__[name]:
|
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.__dict__[name],
|
||||||
self.hooks.bot)
|
self.hooks.bot)
|
||||||
|
|
||||||
|
|
@ -331,14 +347,14 @@ class Bot:
|
||||||
if len(self.network[ext].hooks) > level:
|
if len(self.network[ext].hooks) > level:
|
||||||
lvl_exist = True
|
lvl_exist = True
|
||||||
for h in self.network[ext].hooks[level].__dict__[name]:
|
for h in self.network[ext].hooks[level].__dict__[name]:
|
||||||
if h not in self.hooks_cache[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)
|
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
|
level += 1
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise Exception(name + " hook type unrecognized")
|
raise Exception(name + " hook type unrecognized")
|
||||||
|
|
||||||
return self.hooks_cache[name]
|
return self._hooks_cache[name]
|
||||||
|
|
||||||
# Treatment
|
# Treatment
|
||||||
|
|
||||||
|
|
@ -603,7 +619,7 @@ def _help_msg(sndr, modules, cmd):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def hotswap(bak):
|
def hotswap(bak):
|
||||||
return Bot(bak.servers, bak.modules, bak.modules_path)
|
return Bot(bak.servers, bak.modules, bak.modules_paths)
|
||||||
|
|
||||||
def reload():
|
def reload():
|
||||||
import imp
|
import imp
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -22,11 +22,10 @@ import threading
|
||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import bot
|
from nemubot.DCC import DCC
|
||||||
from DCC import DCC
|
from nemubot.message import Message
|
||||||
from message import Message
|
from nemubot import response
|
||||||
import response
|
from nemubot import server
|
||||||
import server
|
|
||||||
|
|
||||||
class MessageConsumer:
|
class MessageConsumer:
|
||||||
"""Store a message before treating"""
|
"""Store a message before treating"""
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# 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
|
# 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/>.
|
||||||
|
|
||||||
from response import Response
|
from nemubot.response import Response
|
||||||
|
|
||||||
class IRCException(Exception):
|
class IRCException(Exception):
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -18,8 +18,8 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from response import Response
|
from nemubot.response import Response
|
||||||
from exception import IRCException
|
from nemubot.exception import IRCException
|
||||||
|
|
||||||
class MessagesHook:
|
class MessagesHook:
|
||||||
def __init__(self, context, bot):
|
def __init__(self, context, bot):
|
||||||
|
|
@ -56,8 +56,8 @@ class MessagesHook:
|
||||||
"add_hook function, please fix it in order to be "
|
"add_hook function, please fix it in order to be "
|
||||||
"compatible with unload feature")
|
"compatible with unload feature")
|
||||||
|
|
||||||
if store in self.context.hooks_cache:
|
if store in self.context._hooks_cache:
|
||||||
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")
|
print ("\033[1;35mWarning:\033[0m unrecognized hook store")
|
||||||
|
|
@ -143,8 +143,8 @@ class MessagesHook:
|
||||||
|
|
||||||
def del_hook(self, store, hook, module_src=None):
|
def del_hook(self, store, hook, module_src=None):
|
||||||
"""Remove a registered hook from a given store"""
|
"""Remove a registered hook from a given store"""
|
||||||
if store in self.context.hooks_cache:
|
if store in self.context._hooks_cache:
|
||||||
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")
|
print ("Warning: unrecognized hook store type")
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# 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
|
# 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/>.
|
||||||
|
|
||||||
|
from distutils.version import StrictVersion
|
||||||
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 os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import event
|
import nemubot
|
||||||
import exception
|
from nemubot import event
|
||||||
from hooks import Hook
|
from nemubot import exception
|
||||||
import response
|
from nemubot.hooks import Hook
|
||||||
import xmlparser
|
from nemubot import response
|
||||||
|
from nemubot import xmlparser
|
||||||
|
|
||||||
class ModuleFinder(Finder):
|
class ModuleFinder(Finder):
|
||||||
def __init__(self, context, prompt):
|
def __init__(self, context, prompt):
|
||||||
|
|
@ -37,7 +39,7 @@ class ModuleFinder(Finder):
|
||||||
#print ("looking for", fullname, "in", path)
|
#print ("looking for", fullname, "in", path)
|
||||||
# Search only for new nemubot modules (packages init)
|
# Search only for new nemubot modules (packages init)
|
||||||
if path is None:
|
if path is None:
|
||||||
for mpath in self.context.modules_path:
|
for mpath in self.context.modules_paths:
|
||||||
#print ("looking for", fullname, "in", mpath)
|
#print ("looking for", fullname, "in", mpath)
|
||||||
if os.path.isfile(mpath + fullname + ".xml"):
|
if os.path.isfile(mpath + fullname + ".xml"):
|
||||||
return ModuleLoader(self.context, self.prompt, fullname,
|
return ModuleLoader(self.context, self.prompt, fullname,
|
||||||
|
|
@ -137,7 +139,7 @@ class ModuleLoader(SourceLoader):
|
||||||
if not hasattr(module, "nemubotversion"):
|
if not hasattr(module, "nemubotversion"):
|
||||||
raise ImportError("Module `%s' is not a nemubot module."%self.name)
|
raise ImportError("Module `%s' is not a nemubot module."%self.name)
|
||||||
# Check module version
|
# 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 "
|
raise ImportError("Module `%s' is not compatible with this "
|
||||||
"version." % self.name)
|
"version." % self.name)
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -21,10 +21,10 @@ import re
|
||||||
import shlex
|
import shlex
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import credits
|
import nemubot.credits
|
||||||
from credits import Credits
|
from nemubot.credits import Credits
|
||||||
from response import Response
|
from nemubot.response import Response
|
||||||
import xmlparser
|
import nemubot.xmlparser
|
||||||
|
|
||||||
CREDITS = {}
|
CREDITS = {}
|
||||||
filename = ""
|
filename = ""
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -22,9 +22,9 @@ import shlex
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import zlib
|
import zlib
|
||||||
|
|
||||||
from DCC import DCC
|
from nemubot.DCC import DCC
|
||||||
import hooks
|
import nemubot.hooks
|
||||||
from response import Response
|
from nemubot.response import Response
|
||||||
|
|
||||||
class NetworkBot:
|
class NetworkBot:
|
||||||
def __init__(self, context, srv, dest, dcc=None):
|
def __init__(self, context, srv, dest, dcc=None):
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# 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 <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import xmlparser
|
|
||||||
|
from nemubot import xmlparser
|
||||||
|
|
||||||
def end(toks, context, prompt):
|
def end(toks, context, prompt):
|
||||||
"""Quit the prompt for reload or exit"""
|
"""Quit the prompt for reload or exit"""
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -165,7 +165,7 @@ class Response:
|
||||||
self.elt = 0
|
self.elt = 0
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
import hooks
|
import nemubot.hooks
|
||||||
class Hook:
|
class Hook:
|
||||||
def __init__(self, TYPE, call, name=None, data=None, regexp=None,
|
def __init__(self, TYPE, call, name=None, data=None, regexp=None,
|
||||||
channels=list(), server=None, end=None, call_end=None,
|
channels=list(), server=None, end=None, call_end=None,
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Nemubot is a modulable IRC bot, built around XML configuration files.
|
# Nemubot is a smart and modulable IM bot.
|
||||||
# Copyright (C) 2012 Mercier Pierre-Olivier
|
# Copyright (C) 2012-2014 nemunaire
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -19,9 +19,9 @@
|
||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from networkbot import NetworkBot
|
from nemubot.networkbot import NetworkBot
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 4.0
|
||||||
NODATA = True
|
NODATA = True
|
||||||
|
|
||||||
def getserver(toks, context, prompt):
|
def getserver(toks, context, prompt):
|
||||||
|
|
|
||||||
0
requirements.txt
Normal file
0
requirements.txt
Normal file
77
setup.py
Normal file
77
setup.py
Normal file
|
|
@ -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,
|
||||||
|
)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue