-
Notifications
You must be signed in to change notification settings - Fork 1
/
neubot.py
executable file
·179 lines (155 loc) · 6.27 KB
/
neubot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is part of NeuBot.
#
# NeuBot is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (c) 2010, Jim Persson, All rights reserved.
from controllers.irccontroller import IRCController
from controllers.eventcontroller import EventController
from controllers.plugincontroller import PluginController
from controllers.configcontroller import ConfigController
from controllers.datastorecontroller import DatastoreController
from controllers.ircnetscontroller import IRCNetsController
from lib.logger import Logger
import threading
##
# @mainpage NeuBot Developer Documentation
#
# @section module Writing modules
#
# Module skeleton
# @code
# from lib.plugin import Plugin
# class MyModule(Plugin):
# def __init__(self):
# self.name = "Skeleton Module"
# self.author = "Jim Persson"
# self.version = "1.0"
#
# # Register commands
# self.event.register_command("mycommand", self.cmd_mycommand)
# self.event.register_command("privilegedcommand", self.cmd_privilegedcommand, True)
#
# # Register an event
# self.event.register_event("PRIVMSG", self.event_privmsghook)
#
# # Register a timer
# self.event.register_timer(self.timer_timeout, 10)
#
# # Put a value in the data store
# self.store.put("a_list", [1,2,3,4])
#
# # This method is called when the plugin is unloaded
# # it's VERY important that you clean up any threads etc that the plugin is using here
# def cleanup(self):
# pass
#
# def cmd_mycommand(self, irc, params):
# """Does nothing special"""
# irc.reply("Params: " + params)
#
# def cmd_privilegedcommand(self, irc, params):
# """This command is privileged"""
# # Retrieve a value from the data store and display it to the user
# tmp = self.store.get("a_list")
# irc.reply(tmp)
#
# def event_privmsghook(self, irc):
# irc.reply("Message from " + irc.message.source)
#
# def timer_timeout(self):
# # Timer fired
# pass
# @endcode
#
# When a module is instantiated it is automatically given a few attributes
# <ul>
# <li>self.event @link controllers.eventcontroller.EventController EventController @endlink</li>
# <li>self.store @link lib.db.store.Store Store @endlink (Wrapper around @link controllers.datastorecontroller.DatastoreController DatastoreController @endlink)</li>
# <li>self.plugin @link controllers.plugincontroller.PluginController PluginController @endlink - Be careful with this one</li>
# <li>self.config @link controllers.configcontroller.ConfigController ConfigController @endlink</li>
# </ul>
#
# When a command callback is called it is given two arguments
# <ul>
# <li>irc @link controllers.ircmessagecontroller.IRCMessageController IRCMessageController @endlink - Wrapper around the IRCController along with some convenience functions</li>
# <li>params @link models.arguments.Arguments Argments @endlink - The arguments to the command preparsed and packaged</li>
# </ul>
#
# Command documentation for callbacks can be put in the __doc__ for that command by writing the help in a triple-quote enclosed comment
# in the method header
# @code
# def cmd_mycommand(self, irc, params):
# """
# This is the documentation for this command.
# It can be on multiple lines if needed."""
# irc.reply("Hello!")
# @endcode
#
# @section useful_classes Useful classes
# <ul>
# <li>@link controllers.ircmessagecontroller.IRCMessageController IRCMessageController @endlink - Gets passed as the first argument to command callbacks
# <li>@link controllers.irccontroller.IRCController IRCController @endlink - Methods not handled by IRCMessageController is taken care by the current IRCController
# </ul>
##
# Bot entrypoint
class NeuBot:
"""NeuBot"""
def __init__(self):
self.eventcontroller = EventController()
self.plugincontroller = PluginController()
self.ircnetscontroller = IRCNetsController()
self.config = ConfigController()
self.config.reload()
self.quit_event = threading.Event()
self.eventcontroller.register_system_event("BOT_QUIT", self.system_quit)
def system_quit(self, params):
self.quit_event.set()
def start(self):
# Initialize data store
DatastoreController().set_driver(self.config.get('datastore'))
Logger.set_loglevel(self.config.get('log.level'))
for plugin in self.config.get('coreplugins'):
Logger.info("Loading core plugin '%s'" % plugin)
self.plugincontroller.load_plugin(plugin, 'core')
for plugin in self.config.get('plugins'):
Logger.info("Loading plugin '%s'" % plugin)
self.plugincontroller.load_plugin(plugin)
if len(self.config.get('ircnets')) == 0:
raise Exception("There has to be at least one ircnet to connect to")
for net in self.config.get('ircnets'):
irc = IRCController(self.eventcontroller)
irc.set_configuration(net)
Logger.info("Connecting to %s..." % irc.get_ircnet_name())
irc.connect()
self.ircnetscontroller.add_ircnet(irc.get_ircnet_name(), irc)
def stop(self):
self.ircnetscontroller.disconnect_all()
self.plugincontroller.unload_all()
if __name__ == "__main__":
bot = None
try:
Logger.info("Initializing...")
bot = NeuBot()
bot.start()
while not bot.quit_event.isSet():
bot.quit_event.wait(1)
except KeyboardInterrupt:
Logger.info("Keyboard interrupt detected. Shutting down.")
except Exception as e:
Logger.fatal("Fatal error: %s" % e)
finally:
if bot:
bot.stop()