genocide 230__tar.gz → 232__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {genocide-230 → genocide-232}/PKG-INFO +2 -2
- genocide-232/genocide/brokers.py +50 -0
- genocide-232/genocide/command.py +61 -0
- genocide-232/genocide/defines.py +42 -0
- genocide-232/genocide/encoder.py +57 -0
- genocide-232/genocide/handler.py +201 -0
- {genocide-230 → genocide-232}/genocide/loggers.py +12 -13
- genocide-232/genocide/modules/__init__.py +4 -0
- {genocide-230 → genocide-232}/genocide/modules/atr.py +5 -5
- genocide-232/genocide/modules/flt.py +23 -0
- genocide-232/genocide/modules/fnd.py +29 -0
- {genocide-230 → genocide-232}/genocide/modules/irc.py +68 -171
- {genocide-230 → genocide-232}/genocide/modules/log.py +9 -4
- {genocide-230 → genocide-232}/genocide/modules/man.py +39 -36
- {genocide-230 → genocide-232}/genocide/modules/mbx.py +30 -11
- {genocide-230 → genocide-232}/genocide/modules/mdl.py +30 -47
- genocide-232/genocide/modules/pth.py +16 -0
- genocide-232/genocide/modules/rss.py +665 -0
- {genocide-230 → genocide-232}/genocide/modules/rst.py +27 -14
- genocide-232/genocide/modules/sil.py +25 -0
- {genocide-230 → genocide-232}/genocide/modules/tdo.py +11 -6
- {genocide-230 → genocide-232}/genocide/modules/thr.py +5 -2
- {genocide-230 → genocide-232}/genocide/modules/tmr.py +31 -25
- {genocide-230 → genocide-232}/genocide/modules/udp.py +20 -15
- {genocide-230 → genocide-232}/genocide/modules/upt.py +5 -2
- genocide-232/genocide/modules/wdr.py +11 -0
- {genocide-230 → genocide-232}/genocide/modules/web.py +17 -12
- {genocide-230 → genocide-232}/genocide/modules/wsd.py +48 -6
- genocide-232/genocide/objects.py +328 -0
- genocide-232/genocide/package.py +109 -0
- genocide-232/genocide/persist.py +233 -0
- genocide-232/genocide/runtime.py +377 -0
- genocide-232/genocide/threads.py +147 -0
- genocide-232/genocide/utility.py +187 -0
- {genocide-230 → genocide-232}/genocide.egg-info/PKG-INFO +2 -2
- genocide-232/genocide.egg-info/SOURCES.txt +95 -0
- genocide-232/genocide.egg-info/entry_points.txt +2 -0
- {genocide-230 → genocide-232}/pyproject.toml +13 -10
- genocide-230/bin/genocide +0 -384
- genocide-230/genocide/brokers.py +0 -42
- genocide-230/genocide/clients.py +0 -96
- genocide-230/genocide/command.py +0 -71
- genocide-230/genocide/configs.py +0 -26
- genocide-230/genocide/defines.py +0 -102
- genocide-230/genocide/handler.py +0 -63
- genocide-230/genocide/message.py +0 -50
- genocide-230/genocide/methods.py +0 -154
- genocide-230/genocide/modules/__init__.py +0 -52
- genocide-230/genocide/modules/flt.py +0 -16
- genocide-230/genocide/modules/fnd.py +0 -24
- genocide-230/genocide/modules/lst.py +0 -12
- genocide-230/genocide/modules/pth.py +0 -13
- genocide-230/genocide/modules/rss.py +0 -502
- genocide-230/genocide/modules/sil.py +0 -16
- genocide-230/genocide/network/__init__.py +0 -4
- genocide-230/genocide/objects.py +0 -119
- genocide-230/genocide/persist.py +0 -131
- genocide-230/genocide/repeats.py +0 -67
- genocide-230/genocide/serials.py +0 -57
- genocide-230/genocide/statics.py +0 -52
- genocide-230/genocide/threads.py +0 -85
- genocide-230/genocide/timings.py +0 -206
- genocide-230/genocide/utility.py +0 -65
- genocide-230/genocide/workdir.py +0 -74
- genocide-230/genocide.egg-info/SOURCES.txt +0 -103
- genocide-230/setup.py +0 -13
- {genocide-230 → genocide-232}/README.rst +0 -0
- {genocide-230 → genocide-232}/genocide/modules/req.py +0 -0
- {genocide-230 → genocide-232}/genocide/modules/slg.py +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/ECHAabilify.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/ECHAclozapine.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/ECHAhaldol.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/ECHAzyprexa.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/OTP111.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/OTP222.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/abilifypubchem.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/ack3.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/bevestigd.jpg +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/clozapinepubchem.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/genocide.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/haldolpubchem.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/informed.jpg +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/kamer2.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/skull3.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_images/zyprexapubchem.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/alabaster.css +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/basic.css +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/custom.css +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/doctools.js +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/documentation_options.js +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/file.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/genocide.css +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/language_data.js +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/minus.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/opensearch.xml +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/plus.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/pygments.css +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/searchtools.js +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/sitemap.xml +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/skull3.png +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/_static/sphinx_highlight.js +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/about.html +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/evidence.html +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/genindex-all.html +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/genindex.html +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/guilty.html +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/index.html +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/manual.html +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/objects.inv +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/pdf/EM_Ack_OTP-CR-117_19.pdf +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/pdf/EM_T04_OTP-CR-117_19.pdf +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/pdf/EM_T07_OTP-CR-117_19_001.pdf +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/pdf/Kamer.pdf +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/pdf/Rome-Statute.pdf +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/pdf/bevestigd.pdf +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/pubchem.html +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/reconsider.html +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/request.html +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/robots.txt +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/search.html +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/searchindex.js +0 -0
- {genocide-230/genocide/nucleus → genocide-232/genocide/network}/writings.html +0 -0
- {genocide-230 → genocide-232}/genocide.egg-info/dependency_links.txt +0 -0
- {genocide-230 → genocide-232}/genocide.egg-info/top_level.txt +0 -0
- {genocide-230 → genocide-232}/setup.cfg +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"an object for a string"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Broker:
|
|
8
|
+
|
|
9
|
+
objects = {}
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def add(obj):
|
|
13
|
+
"add object to the broker, key is repr(obj)."
|
|
14
|
+
Broker.objects[repr(obj)] = obj
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def announce(txt):
|
|
18
|
+
"announce text on all objects with an announce method."
|
|
19
|
+
for obj in Broker.objs("announce"):
|
|
20
|
+
obj.announce(txt)
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def get(origin):
|
|
24
|
+
"object by repr(obj)."
|
|
25
|
+
return Broker.objects.get(origin)
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def objs(attr):
|
|
29
|
+
"objects with a certain attribute."
|
|
30
|
+
for obj in Broker.objects.values():
|
|
31
|
+
if attr in dir(obj):
|
|
32
|
+
yield obj
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def has(obj):
|
|
36
|
+
"whether the Broker has object."
|
|
37
|
+
return repr(obj) in Broker.objects
|
|
38
|
+
|
|
39
|
+
@staticmethod
|
|
40
|
+
def like(txt):
|
|
41
|
+
"all keys with a substring in their key."
|
|
42
|
+
for orig in Broker.objects:
|
|
43
|
+
if txt in orig.split()[0]:
|
|
44
|
+
yield orig
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def __dir__():
|
|
48
|
+
return (
|
|
49
|
+
'Broker',
|
|
50
|
+
)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"write your own commands"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import inspect
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from .brokers import Broker
|
|
11
|
+
from .objects import Methods
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Commands:
|
|
15
|
+
|
|
16
|
+
cmds = {}
|
|
17
|
+
names = {}
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def add(*args):
|
|
21
|
+
"add functions to commands."
|
|
22
|
+
for func in args:
|
|
23
|
+
name = func.__name__
|
|
24
|
+
Commands.cmds[name] = func
|
|
25
|
+
Commands.names[name] = func.__module__.split(".")[-1]
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def command(evt):
|
|
29
|
+
"command callback."
|
|
30
|
+
Methods.parse(evt, evt.text)
|
|
31
|
+
func = Commands.get(evt.cmd)
|
|
32
|
+
if func:
|
|
33
|
+
func(evt)
|
|
34
|
+
bot = Broker.get(evt.orig)
|
|
35
|
+
if bot:
|
|
36
|
+
bot.display(evt)
|
|
37
|
+
evt.ready()
|
|
38
|
+
|
|
39
|
+
@staticmethod
|
|
40
|
+
def get(cmd):
|
|
41
|
+
"get function for command."
|
|
42
|
+
return Commands.cmds.get(cmd, None)
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def has(cmd):
|
|
46
|
+
"whether cmd is registered."
|
|
47
|
+
return cmd in Commands.cmds
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def scan(module):
|
|
51
|
+
"scan a module for functions with event as argument."
|
|
52
|
+
for key, cmdz in inspect.getmembers(module, inspect.isfunction):
|
|
53
|
+
if 'event' not in inspect.signature(cmdz).parameters:
|
|
54
|
+
continue
|
|
55
|
+
Commands.add(cmdz)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def __dir__():
|
|
59
|
+
return (
|
|
60
|
+
'Commands',
|
|
61
|
+
)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"configurations"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
from .objects import Data, Dict, Methods
|
|
8
|
+
from .utility import Utils
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Configuration(Data):
|
|
12
|
+
|
|
13
|
+
def __init__(self, *args, **kwargs):
|
|
14
|
+
super().__init__()
|
|
15
|
+
if args:
|
|
16
|
+
Dict.update(self, args[0])
|
|
17
|
+
if kwargs:
|
|
18
|
+
Dict.update(self, kwargs)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class MainConfig(type):
|
|
22
|
+
|
|
23
|
+
def __getattr__(cls, key):
|
|
24
|
+
if key not in dir(cls):
|
|
25
|
+
return ""
|
|
26
|
+
return cls.__getattribute__(key)
|
|
27
|
+
|
|
28
|
+
def __str__(cls):
|
|
29
|
+
return str(Methods.skip(cls.__dict__))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Main(metaclass=MainConfig):
|
|
33
|
+
|
|
34
|
+
name = Utils.pkgname(Configuration)
|
|
35
|
+
wdr = f".{name}"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def __dir__():
|
|
39
|
+
return (
|
|
40
|
+
'Configuration',
|
|
41
|
+
'Main'
|
|
42
|
+
)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"encoder/decoder"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import types
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Encoder(json.JSONEncoder):
|
|
12
|
+
|
|
13
|
+
def default(self, o):
|
|
14
|
+
if isinstance(o, dict):
|
|
15
|
+
return o.items()
|
|
16
|
+
if isinstance(o, list):
|
|
17
|
+
return iter(o)
|
|
18
|
+
if isinstance(o, types.MappingProxyType):
|
|
19
|
+
return dict(o)
|
|
20
|
+
try:
|
|
21
|
+
return json.JSONEncoder.default(self, o)
|
|
22
|
+
except TypeError:
|
|
23
|
+
try:
|
|
24
|
+
return vars(o)
|
|
25
|
+
except TypeError:
|
|
26
|
+
return repr(o)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class Json:
|
|
30
|
+
|
|
31
|
+
@staticmethod
|
|
32
|
+
def dump(*args, **kw):
|
|
33
|
+
"dump object to disk."
|
|
34
|
+
kw["cls"] = Encoder
|
|
35
|
+
return json.dump(*args, **kw)
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def dumps(*args, **kw):
|
|
39
|
+
"dump object to string."
|
|
40
|
+
kw["cls"] = Encoder
|
|
41
|
+
return json.dumps(*args, **kw)
|
|
42
|
+
|
|
43
|
+
@staticmethod
|
|
44
|
+
def load(s, *args, **kw):
|
|
45
|
+
"load object from disk."
|
|
46
|
+
return json.load(s, *args, **kw)
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
def loads(s, *args, **kw):
|
|
50
|
+
"load object from string."
|
|
51
|
+
return json.loads(s, *args, **kw)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def __dir__():
|
|
55
|
+
return (
|
|
56
|
+
'Json',
|
|
57
|
+
)
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"callback engine"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
import queue
|
|
9
|
+
import threading
|
|
10
|
+
import time
|
|
11
|
+
import _thread
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
from .brokers import Broker
|
|
15
|
+
from .threads import Thread
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Event:
|
|
19
|
+
|
|
20
|
+
def __init__(self):
|
|
21
|
+
self._ready = threading.Event()
|
|
22
|
+
self._thr = None
|
|
23
|
+
self.result = {}
|
|
24
|
+
self.args = []
|
|
25
|
+
self.index = 0
|
|
26
|
+
self.kind = "event"
|
|
27
|
+
|
|
28
|
+
def __getattr__(self, key):
|
|
29
|
+
return self.__dict__.get(key, "")
|
|
30
|
+
|
|
31
|
+
def __str__(self):
|
|
32
|
+
return str(self.__dict__)
|
|
33
|
+
|
|
34
|
+
def ready(self):
|
|
35
|
+
"flag message as ready."
|
|
36
|
+
self._ready.set()
|
|
37
|
+
|
|
38
|
+
def reply(self, text):
|
|
39
|
+
"add text to result."
|
|
40
|
+
self.result[time.time()] = text
|
|
41
|
+
|
|
42
|
+
def wait(self, timeout=0.0):
|
|
43
|
+
"wait for completion."
|
|
44
|
+
self._ready.wait(timeout or None)
|
|
45
|
+
if self._thr:
|
|
46
|
+
self._thr.join(timeout or None)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class Handler:
|
|
50
|
+
|
|
51
|
+
def __init__(self):
|
|
52
|
+
self.cbs = {}
|
|
53
|
+
self.queue = queue.Queue()
|
|
54
|
+
self.running = threading.Event()
|
|
55
|
+
|
|
56
|
+
def callback(self, event):
|
|
57
|
+
"run callback function with event."
|
|
58
|
+
func = self.cbs.get(event.kind, None)
|
|
59
|
+
if not func:
|
|
60
|
+
event.ready()
|
|
61
|
+
return
|
|
62
|
+
name = event.text and event.text.split()[0]
|
|
63
|
+
event._thr = Thread.launch(func, event, name=name)
|
|
64
|
+
|
|
65
|
+
def loop(self):
|
|
66
|
+
"event loop."
|
|
67
|
+
while self.running.is_set():
|
|
68
|
+
event = self.queue.get()
|
|
69
|
+
if not event:
|
|
70
|
+
break
|
|
71
|
+
event.orig = repr(self)
|
|
72
|
+
self.callback(event)
|
|
73
|
+
|
|
74
|
+
def put(self, event):
|
|
75
|
+
"put event on queue."
|
|
76
|
+
self.queue.put(event)
|
|
77
|
+
|
|
78
|
+
def register(self, kind, callback):
|
|
79
|
+
"register callback."
|
|
80
|
+
self.cbs[kind] = callback
|
|
81
|
+
|
|
82
|
+
def start(self):
|
|
83
|
+
"start event handler loop."
|
|
84
|
+
self.running.set()
|
|
85
|
+
Thread.launch(self.loop)
|
|
86
|
+
|
|
87
|
+
def stop(self):
|
|
88
|
+
"stop event handler loop."
|
|
89
|
+
self.running.clear()
|
|
90
|
+
self.queue.put(None)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class Client(Handler):
|
|
94
|
+
|
|
95
|
+
def __init__(self):
|
|
96
|
+
Handler.__init__(self)
|
|
97
|
+
self.iqueue = queue.Queue()
|
|
98
|
+
self.olock = threading.RLock()
|
|
99
|
+
self.silent = False
|
|
100
|
+
self.stopped = threading.Event()
|
|
101
|
+
Broker.add(self)
|
|
102
|
+
|
|
103
|
+
def announce(self, text):
|
|
104
|
+
"announce text to all channels."
|
|
105
|
+
if not self.silent:
|
|
106
|
+
self.raw(text)
|
|
107
|
+
|
|
108
|
+
def display(self, event):
|
|
109
|
+
"display event results."
|
|
110
|
+
with self.olock:
|
|
111
|
+
for tme in event.result:
|
|
112
|
+
self.dosay(event.channel, event.result.get(tme))
|
|
113
|
+
|
|
114
|
+
def dosay(self, channel, text):
|
|
115
|
+
"say called by display."
|
|
116
|
+
self.say(channel, text)
|
|
117
|
+
|
|
118
|
+
def loop(self):
|
|
119
|
+
"input loop."
|
|
120
|
+
while True:
|
|
121
|
+
event = self.poll()
|
|
122
|
+
if not event or self.stopped.is_set():
|
|
123
|
+
break
|
|
124
|
+
event.orig = repr(self)
|
|
125
|
+
self.callback(event)
|
|
126
|
+
|
|
127
|
+
def poll(self):
|
|
128
|
+
"return event."
|
|
129
|
+
return self.iqueue.get()
|
|
130
|
+
|
|
131
|
+
def put(self, event):
|
|
132
|
+
self.iqueue.put(event)
|
|
133
|
+
|
|
134
|
+
def raw(self, text):
|
|
135
|
+
"raw output."
|
|
136
|
+
|
|
137
|
+
def say(self, channel, text):
|
|
138
|
+
"say text in channel."
|
|
139
|
+
self.raw(text)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class Console(Client):
|
|
143
|
+
|
|
144
|
+
def loop(self):
|
|
145
|
+
"input loop."
|
|
146
|
+
while True:
|
|
147
|
+
event = self.poll()
|
|
148
|
+
if not event or self.stopped.is_set():
|
|
149
|
+
break
|
|
150
|
+
event.orig = repr(self)
|
|
151
|
+
self.callback(event)
|
|
152
|
+
event.wait()
|
|
153
|
+
|
|
154
|
+
def poll(self):
|
|
155
|
+
"return event."
|
|
156
|
+
return self.iqueue.get()
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class Output(Client):
|
|
160
|
+
|
|
161
|
+
def __init__(self):
|
|
162
|
+
super().__init__()
|
|
163
|
+
self.oqueue = queue.Queue()
|
|
164
|
+
|
|
165
|
+
def output(self):
|
|
166
|
+
"output loop."
|
|
167
|
+
while True:
|
|
168
|
+
event = self.oqueue.get()
|
|
169
|
+
if event is None:
|
|
170
|
+
self.oqueue.task_done()
|
|
171
|
+
break
|
|
172
|
+
self.display(event)
|
|
173
|
+
self.oqueue.task_done()
|
|
174
|
+
|
|
175
|
+
def start(self):
|
|
176
|
+
"start output loop."
|
|
177
|
+
super().start()
|
|
178
|
+
Thread.launch(self.output)
|
|
179
|
+
|
|
180
|
+
def stop(self):
|
|
181
|
+
"stop output loop."
|
|
182
|
+
super().stop()
|
|
183
|
+
self.oqueue.put(None)
|
|
184
|
+
|
|
185
|
+
def wait(self):
|
|
186
|
+
"wait for output to finish."
|
|
187
|
+
try:
|
|
188
|
+
self.oqueue.join()
|
|
189
|
+
except Exception as ex:
|
|
190
|
+
logging.exception(ex)
|
|
191
|
+
_thread.interrupt_main()
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def __dir__():
|
|
195
|
+
return (
|
|
196
|
+
'Client',
|
|
197
|
+
'Console',
|
|
198
|
+
'Event',
|
|
199
|
+
'Handler',
|
|
200
|
+
'Output'
|
|
201
|
+
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# This file is placed in the Public Domain.
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
"
|
|
4
|
+
"logging"
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
import logging
|
|
@@ -19,21 +19,20 @@ class Log:
|
|
|
19
19
|
datefmt = "%H:%M:%S"
|
|
20
20
|
format = "%(module).3s %(message)s"
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
def level(loglevel):
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
@staticmethod
|
|
23
|
+
def level(loglevel):
|
|
24
|
+
"set log level."
|
|
25
|
+
formatter = Format(Log.format, Log.datefmt)
|
|
26
|
+
stream = logging.StreamHandler()
|
|
27
|
+
stream.setFormatter(formatter)
|
|
28
|
+
logging.basicConfig(
|
|
29
|
+
level=loglevel.upper(),
|
|
30
|
+
handlers=[stream,],
|
|
31
|
+
force=True
|
|
32
|
+
)
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
def __dir__():
|
|
36
36
|
return (
|
|
37
37
|
'Log',
|
|
38
|
-
'level'
|
|
39
38
|
)
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
# This file is placed in the Public Domain.
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
"
|
|
4
|
+
"show attributes"
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
from genocide.
|
|
7
|
+
from genocide.persist import Locate, Workdir
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def atr(event):
|
|
11
11
|
if not event.rest:
|
|
12
|
-
res = sorted({x.split('.')[-1].lower() for x in kinds()})
|
|
12
|
+
res = sorted({x.split('.')[-1].lower() for x in Workdir.kinds()})
|
|
13
13
|
if res:
|
|
14
14
|
event.reply(",".join(res))
|
|
15
15
|
else:
|
|
16
16
|
event.reply("no types")
|
|
17
17
|
return
|
|
18
|
-
itms = attrs(event.args[0])
|
|
18
|
+
itms = Locate.attrs(event.args[0])
|
|
19
19
|
if not itms:
|
|
20
|
-
event.reply("no
|
|
20
|
+
event.reply("no attributes")
|
|
21
21
|
else:
|
|
22
22
|
event.reply(",".join(itms))
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"show bot in fleet"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
from genocide.brokers import Broker
|
|
8
|
+
from genocide.objects import Methods
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def flt(event):
|
|
12
|
+
clts = list(Broker.objs("announce"))
|
|
13
|
+
if not clts:
|
|
14
|
+
event.reply("no bots")
|
|
15
|
+
return
|
|
16
|
+
if event.args:
|
|
17
|
+
index = int(event.args[0])
|
|
18
|
+
if index < len(clts):
|
|
19
|
+
event.reply(str(clts[index]))
|
|
20
|
+
else:
|
|
21
|
+
event.reply("no matching client in fleet.")
|
|
22
|
+
return
|
|
23
|
+
event.reply(' | '.join([Methods.fqn(o).split(".")[-1] for o in clts]))
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"locate objects"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import time
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from genocide.objects import Methods
|
|
11
|
+
from genocide.persist import Locate, Workdir
|
|
12
|
+
from genocide.utility import Time
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def fnd(event):
|
|
16
|
+
if not event.rest:
|
|
17
|
+
res = sorted([x.split('.')[-1].lower() for x in Workdir.kinds()])
|
|
18
|
+
if res:
|
|
19
|
+
event.reply(",".join(res))
|
|
20
|
+
else:
|
|
21
|
+
event.reply("no data yet.")
|
|
22
|
+
return
|
|
23
|
+
otype = event.args[0]
|
|
24
|
+
nmr = 0
|
|
25
|
+
for fnm, obj in sorted(Locate.find(otype, event.gets), key=lambda x: Time.fntime(x[0])):
|
|
26
|
+
event.reply(f"{nmr} {Methods.fmt(obj)} {Time.elapsed(time.time()-Time.fntime(fnm))}")
|
|
27
|
+
nmr += 1
|
|
28
|
+
if not nmr:
|
|
29
|
+
event.reply("no result")
|