-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathkarkat.py
executable file
·144 lines (118 loc) · 4.31 KB
/
karkat.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
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Usage: %(name)s [options] <config>
Options:
-h --help Show this message.
--version Show version.
-p PACKAGE, --plugins=PACKAGE Set plugin package [default: plugins]
-e PLUGINS, --exclude=PLUGINS Don't load these plugins
-d --debug Turn on debugging
-i PASSWORD, --identify=PASSWORD Identify with the given password
-s --stdin Take password from STDIN
-r --restart Restart on disconnect
-c NUM, --conns=NUM Number of output connections [default: 1]
"""
import os
import socket
import sys
from collections import deque
import docopt
from bot.workers.ircsenders import IRCSender as Printer
from bot.threads import StatefulBot, Bot
from util.irc import Callback, Message
import util.text
import util.scheduler
__version__ = 2.0
socket.setdefaulttimeout(1800)
GP_CALLERS = 2
def main():
"""
Karkat's mainloop simply spawns a server and registers all plugins.
You can replace this.
"""
# Check if we are running on a compatible python interpreter
if (sys.version_info.minor < 3):
return print("Error: your version of python is unsupported; please upgrade to python>=3.3")
# Parse command line args
args = docopt.docopt(__doc__ % {"name": sys.argv[0]}, version=__version__)
exclude = args["--exclude"].split(",") if args["--exclude"] else []
config_file = args["<config>"]
num_connections = int(args["--conns"])
if args["--stdin"]:
args["--identify"] = input("Password: ")
sys.argv.extend(["--identify", args["--identify"]])
if args["--debug"]:
debug = 0.15
else:
debug = None
server = StatefulBot(config_file, debug=debug)
if int(args["--conns"]) > 1:
def cleanup(output):
""" Signal main thread to terminate """
output.connected = False
outputs = [Bot(config_file) for i in range(num_connections-1)]
for output in outputs:
output.connect()
server.printer.add(output)
server.register("DIE", cleanup)
output.start()
if args["--restart"]:
server.restart = True
server.connect()
os.makedirs(server.get_config_dir(), exist_ok=True)
plugins = deque(args["--plugins"].split(","))
loaded = []
while plugins:
plugin = plugins.popleft()
if plugin in exclude:
print("Skipping %s" % plugin)
continue
try:
__import__(plugin)
mod = sys.modules[plugin]
except ImportError:
print("Warning: %s not loaded." % (plugin))
else:
if "__modules__" in dir(mod):
plugins.extend("%s.%s" % (plugin, i) for i in mod.__modules__)
loaded.append(mod)
for module in loaded:
print("Loading %s" % module.__name__)
server.loadplugin(module)
if args["--identify"]:
def authenticate(server, line):
""" Sends nickserv credentials after the server preamble. """
msg = Message(line)
if msg.address.nick == "NickServ":
if "is a registered nick." in msg.text:
cmd = "nickserv AUTH %s"
elif msg.text.startswith("This nickname is registered."):
cmd = "nickserv IDENTIFY %s"
else:
return
server.sendline(cmd % args["--identify"])
server.register("notice", authenticate)
if args["--debug"]:
@Callback.inline
def log(server, line):
""" Prints all inbound irc messages. """
print("%s → %s" % (server.server[0], util.text.ircstrip(line)))
server.printer.verbosity = Printer.FULL_MESSAGE | Printer.QUEUE_STATE
server.register("ALL", log)
print("Running...")
server.start()
try:
server.join()
except KeyboardInterrupt:
print("Terminating...")
server.connected = False
server.sock.send("QUIT\r\n".encode("utf-8"))
util.scheduler.stop()
if server.restart is True:
print("Restarting...")
sys.stdout.flush()
sys.stderr.flush()
os.execv(sys.argv[0], sys.argv)
if __name__ == "__main__":
main()