genocide 191__tar.gz → 201__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-191 → genocide-201}/PKG-INFO +1 -1
- {genocide-191 → genocide-201}/docs/_static/genocide.css +1 -1
- {genocide-191 → genocide-201}/docs/conf.py +2 -1
- {genocide-191 → genocide-201}/docs/manual.rst +0 -3
- genocide-201/genocide/caching.py +30 -0
- genocide-201/genocide/clients.py +110 -0
- {genocide-191 → genocide-201}/genocide/command.py +36 -54
- genocide-201/genocide/decoder.py +46 -0
- genocide-201/genocide/default.py +28 -0
- genocide-201/genocide/encoder.py +49 -0
- genocide-201/genocide/excepts.py +59 -0
- genocide-201/genocide/locater.py +103 -0
- genocide-201/genocide/lookups.py +25 -0
- {genocide-191 → genocide-201}/genocide/modules/err.py +4 -5
- genocide-201/genocide/modules/flt.py +18 -0
- {genocide-191 → genocide-201}/genocide/modules/irc.py +44 -51
- {genocide-191 → genocide-201}/genocide/modules/mod.py +1 -4
- {genocide-191 → genocide-201}/genocide/modules/req.py +1 -1
- {genocide-191 → genocide-201}/genocide/modules/rss.py +163 -40
- {genocide-191 → genocide-201}/genocide/modules/thr.py +3 -3
- {genocide-191 → genocide-201}/genocide/modules/upt.py +2 -2
- {genocide-191 → genocide-201}/genocide/objects.py +31 -134
- genocide-201/genocide/package.py +104 -0
- genocide-201/genocide/persist.py +66 -0
- genocide-201/genocide/reactor.py +160 -0
- genocide-191/bin/genocide → genocide-201/genocide/runtime.py +59 -38
- genocide-201/genocide/threads.py +114 -0
- genocide-201/genocide/utility.py +58 -0
- genocide-201/genocide/workdir.py +58 -0
- {genocide-191 → genocide-201}/genocide.egg-info/PKG-INFO +1 -1
- {genocide-191 → genocide-201}/genocide.egg-info/SOURCES.txt +14 -16
- genocide-201/genocide.egg-info/entry_points.txt +2 -0
- {genocide-191 → genocide-201}/pyproject.toml +5 -1
- {genocide-191 → genocide-201}/setup.py +1 -3
- genocide-191/genocide/clients.py +0 -121
- genocide-191/genocide/modules/__init__.py +0 -1
- genocide-191/genocide/modules/cmd.py +0 -12
- genocide-191/genocide/modules/face.py +0 -26
- genocide-191/genocide/modules/flt.py +0 -17
- genocide-191/genocide/modules/fnd.py +0 -29
- genocide-191/genocide/modules/log.py +0 -35
- genocide-191/genocide/modules/mbx.py +0 -140
- genocide-191/genocide/modules/mdl.py +0 -430
- genocide-191/genocide/modules/opm.py +0 -165
- genocide-191/genocide/modules/rst.py +0 -116
- genocide-191/genocide/modules/slg.py +0 -20
- genocide-191/genocide/modules/tdo.py +0 -51
- genocide-191/genocide/modules/tmr.py +0 -227
- genocide-191/genocide/modules/udp.py +0 -114
- genocide-191/genocide/modules/wsd.py +0 -195
- genocide-191/genocide/persist.py +0 -271
- genocide-191/genocide/runtime.py +0 -227
- {genocide-191 → genocide-201}/README.rst +0 -0
- {genocide-191 → genocide-201}/docs/ECHAabilify.png +0 -0
- {genocide-191 → genocide-201}/docs/ECHAclozapine.png +0 -0
- {genocide-191 → genocide-201}/docs/ECHAhaldol.png +0 -0
- {genocide-191 → genocide-201}/docs/ECHAzyprexa.png +0 -0
- {genocide-191 → genocide-201}/docs/OTP111.png +0 -0
- {genocide-191 → genocide-201}/docs/OTP222.png +0 -0
- {genocide-191 → genocide-201}/docs/_templates/base.rst +0 -0
- {genocide-191 → genocide-201}/docs/_templates/class.rst +0 -0
- {genocide-191 → genocide-201}/docs/_templates/mine.rst +0 -0
- {genocide-191 → genocide-201}/docs/_templates/module.rst +0 -0
- {genocide-191 → genocide-201}/docs/about.rst +0 -0
- {genocide-191 → genocide-201}/docs/ack.png +0 -0
- {genocide-191 → genocide-201}/docs/ack3.png +0 -0
- {genocide-191 → genocide-201}/docs/beuker.png +0 -0
- {genocide-191 → genocide-201}/docs/bevestigd.jpg +0 -0
- {genocide-191 → genocide-201}/docs/bylaw.png +0 -0
- {genocide-191 → genocide-201}/docs/evidence.rst +0 -0
- {genocide-191 → genocide-201}/docs/files/sitemap.xml +0 -0
- {genocide-191 → genocide-201}/docs/genocide.jpg +0 -0
- {genocide-191 → genocide-201}/docs/genocide.png +0 -0
- {genocide-191 → genocide-201}/docs/genocidesmile.png +0 -0
- {genocide-191 → genocide-201}/docs/guilty.rst +0 -0
- {genocide-191 → genocide-201}/docs/index.rst +0 -0
- {genocide-191 → genocide-201}/docs/informed.jpg +0 -0
- {genocide-191 → genocide-201}/docs/kamer2.png +0 -0
- {genocide-191 → genocide-201}/docs/opdehoogte.jpg +0 -0
- {genocide-191 → genocide-201}/docs/pdf/EM_Ack_OTP-CR-117_19.pdf +0 -0
- {genocide-191 → genocide-201}/docs/pdf/EM_T04_OTP-CR-117_19.pdf +0 -0
- {genocide-191 → genocide-201}/docs/pdf/EM_T07_OTP-CR-117_19_001.pdf +0 -0
- {genocide-191 → genocide-201}/docs/pdf/Kamer.pdf +0 -0
- {genocide-191 → genocide-201}/docs/pdf/Rome-Statute.pdf +0 -0
- {genocide-191 → genocide-201}/docs/pdf/bevestigd.pdf +0 -0
- {genocide-191 → genocide-201}/docs/reconsider.rst +0 -0
- {genocide-191 → genocide-201}/docs/request.rst +0 -0
- {genocide-191 → genocide-201}/docs/robots.txt +0 -0
- {genocide-191 → genocide-201}/docs/since.png +0 -0
- {genocide-191 → genocide-201}/docs/skull3.png +0 -0
- {genocide-191 → genocide-201}/docs/verbatim4.png +0 -0
- {genocide-191 → genocide-201}/docs/verbatim7.png +0 -0
- {genocide-191 → genocide-201}/docs/verzoek.jpg +0 -0
- {genocide-191 → genocide-201}/docs/writings.rst +0 -0
- {genocide-191 → genocide-201}/docs/zyprexa.png +0 -0
- {genocide-191 → genocide-201}/genocide.egg-info/dependency_links.txt +0 -0
- {genocide-191 → genocide-201}/genocide.egg-info/top_level.txt +0 -0
- {genocide-191 → genocide-201}/setup.cfg +0 -0
|
@@ -63,6 +63,7 @@ extensions = [
|
|
|
63
63
|
html_title = "Since 4 March 2019"
|
|
64
64
|
html_style = 'genocide.css'
|
|
65
65
|
html_static_path = ["_static", "_static/genocide.css", "files/sitemap.xml"]
|
|
66
|
+
#html_css_files = ["genocide.css", "alabaster.css"]
|
|
66
67
|
html_css_files = ["genocide.css",]
|
|
67
68
|
html_short_title = "%s %s" % (NAME, VERSION)
|
|
68
69
|
html_theme = "alabaster"
|
|
@@ -84,7 +85,7 @@ html_use_index = True
|
|
|
84
85
|
html_split_index = True
|
|
85
86
|
html_show_sourcelink = False
|
|
86
87
|
html_show_sphinx = False
|
|
87
|
-
html_show_copyright =
|
|
88
|
+
html_show_copyright = False
|
|
88
89
|
html_copy_source = False
|
|
89
90
|
html_use_opensearch = 'http://%s.rtfd.io/' % NAME
|
|
90
91
|
html_file_suffix = '.html'
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"caching"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Cache:
|
|
8
|
+
|
|
9
|
+
objs = {}
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def add(path, obj):
|
|
13
|
+
Cache.objs[path] = obj
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
def get(path):
|
|
17
|
+
return Cache.objs.get(path, None)
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def typed(matcher):
|
|
21
|
+
for key in Cache.objs:
|
|
22
|
+
if matcher not in key:
|
|
23
|
+
continue
|
|
24
|
+
yield Cache.objs.get(key)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def __dir__():
|
|
28
|
+
return (
|
|
29
|
+
'Cache',
|
|
30
|
+
)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"clients"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import queue
|
|
9
|
+
import threading
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from .default import Default
|
|
13
|
+
from .reactor import Fleet, Reactor
|
|
14
|
+
from .threads import launch
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Config(Default):
|
|
18
|
+
|
|
19
|
+
init = "irc,mdl,rss"
|
|
20
|
+
name = __file__.rsplit(os.sep, maxsplit=2)[-2]
|
|
21
|
+
opts = Default()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Client(Reactor):
|
|
25
|
+
|
|
26
|
+
def __init__(self):
|
|
27
|
+
Reactor.__init__(self)
|
|
28
|
+
Fleet.add(self)
|
|
29
|
+
|
|
30
|
+
def raw(self, txt) -> None:
|
|
31
|
+
raise NotImplementedError("raw")
|
|
32
|
+
|
|
33
|
+
def say(self, channel, txt) -> None:
|
|
34
|
+
self.raw(txt)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Output:
|
|
38
|
+
|
|
39
|
+
def __init__(self):
|
|
40
|
+
self.oqueue = queue.Queue()
|
|
41
|
+
self.running = threading.Event()
|
|
42
|
+
|
|
43
|
+
def loop(self) -> None:
|
|
44
|
+
self.running.set()
|
|
45
|
+
while self.running.is_set():
|
|
46
|
+
evt = self.oqueue.get()
|
|
47
|
+
if evt is None:
|
|
48
|
+
self.oqueue.task_done()
|
|
49
|
+
break
|
|
50
|
+
Fleet.display(evt)
|
|
51
|
+
self.oqueue.task_done()
|
|
52
|
+
|
|
53
|
+
def oput(self,evt) -> None:
|
|
54
|
+
if not self.running.is_set():
|
|
55
|
+
Fleet.display(evt)
|
|
56
|
+
self.oqueue.put(evt)
|
|
57
|
+
|
|
58
|
+
def start(self) -> None:
|
|
59
|
+
if not self.running.is_set():
|
|
60
|
+
self.running.set()
|
|
61
|
+
launch(self.loop)
|
|
62
|
+
|
|
63
|
+
def stop(self) -> None:
|
|
64
|
+
self.running.clear()
|
|
65
|
+
self.oqueue.put(None)
|
|
66
|
+
|
|
67
|
+
def wait(self) -> None:
|
|
68
|
+
self.oqueue.join()
|
|
69
|
+
self.running.wait()
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class Buffered(Client, Output):
|
|
73
|
+
|
|
74
|
+
def __init__(self):
|
|
75
|
+
Client.__init__(self)
|
|
76
|
+
Output.__init__(self)
|
|
77
|
+
|
|
78
|
+
def raw(self, txt) -> None:
|
|
79
|
+
raise NotImplementedError("raw")
|
|
80
|
+
|
|
81
|
+
def start(self) -> None:
|
|
82
|
+
Output.start(self)
|
|
83
|
+
Client.start(self)
|
|
84
|
+
|
|
85
|
+
def stop(self) -> None:
|
|
86
|
+
Output.stop(self)
|
|
87
|
+
Client.stop(self)
|
|
88
|
+
|
|
89
|
+
def wait(self) -> None:
|
|
90
|
+
Output.wait(self)
|
|
91
|
+
Client.wait(self)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def debug(txt) -> None:
|
|
95
|
+
if "v" in Config.opts:
|
|
96
|
+
output(txt)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def output(txt) -> None:
|
|
100
|
+
"output here"
|
|
101
|
+
# print(txt)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def __dir__():
|
|
105
|
+
return (
|
|
106
|
+
'Default',
|
|
107
|
+
'Client',
|
|
108
|
+
'Fleet',
|
|
109
|
+
'debug'
|
|
110
|
+
)
|
|
@@ -1,28 +1,40 @@
|
|
|
1
1
|
# This file is placed in the Public Domain.
|
|
2
|
-
# pylint: disable=C0115,C0116,R0912,W0105
|
|
3
2
|
|
|
4
3
|
|
|
5
|
-
"
|
|
4
|
+
"command"
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
import inspect
|
|
9
|
-
import
|
|
8
|
+
import threading
|
|
10
9
|
|
|
11
10
|
|
|
12
|
-
from
|
|
13
|
-
from
|
|
11
|
+
from .default import Default
|
|
12
|
+
from .package import Table, gettable
|
|
14
13
|
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
initlock = threading.RLock()
|
|
16
|
+
loadlock = threading.RLock()
|
|
17
|
+
lock = threading.RLock()
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class Commands:
|
|
20
21
|
|
|
21
22
|
cmds = {}
|
|
23
|
+
names = gettable()
|
|
22
24
|
|
|
23
25
|
@staticmethod
|
|
24
|
-
def add(func):
|
|
26
|
+
def add(func, mod=None):
|
|
25
27
|
Commands.cmds[func.__name__] = func
|
|
28
|
+
if mod:
|
|
29
|
+
Commands.names[func.__name__] = mod.__name__
|
|
30
|
+
|
|
31
|
+
@staticmethod
|
|
32
|
+
def get(cmd):
|
|
33
|
+
return Commands.cmds.get(cmd, None)
|
|
34
|
+
|
|
35
|
+
@staticmethod
|
|
36
|
+
def getname(cmd):
|
|
37
|
+
return Commands.names.get(cmd)
|
|
26
38
|
|
|
27
39
|
@staticmethod
|
|
28
40
|
def scan(mod):
|
|
@@ -30,29 +42,23 @@ class Commands:
|
|
|
30
42
|
if key.startswith("cb"):
|
|
31
43
|
continue
|
|
32
44
|
if 'event' in cmdz.__code__.co_varnames:
|
|
33
|
-
Commands.add(cmdz)
|
|
45
|
+
Commands.add(cmdz, mod)
|
|
34
46
|
|
|
35
47
|
|
|
36
|
-
def command(
|
|
48
|
+
def command(evt):
|
|
37
49
|
parse(evt)
|
|
38
|
-
func = Commands.
|
|
39
|
-
if func:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
for modname in dir(pkg):
|
|
51
|
-
if modname in spl(disable):
|
|
52
|
-
continue
|
|
53
|
-
if modname.startswith("__"):
|
|
54
|
-
continue
|
|
55
|
-
yield getattr(pkg, modname)
|
|
50
|
+
func = Commands.get(evt.cmd)
|
|
51
|
+
if not func:
|
|
52
|
+
mname = Commands.names.get(evt.cmd)
|
|
53
|
+
if mname:
|
|
54
|
+
mod = Table.load(mname)
|
|
55
|
+
Commands.scan(mod)
|
|
56
|
+
func = Commands.get(evt.cmd)
|
|
57
|
+
if not func:
|
|
58
|
+
evt.ready()
|
|
59
|
+
return
|
|
60
|
+
func(evt)
|
|
61
|
+
evt.display()
|
|
56
62
|
|
|
57
63
|
|
|
58
64
|
def parse(obj, txt=None):
|
|
@@ -68,7 +74,7 @@ def parse(obj, txt=None):
|
|
|
68
74
|
obj.index = None
|
|
69
75
|
obj.mod = ""
|
|
70
76
|
obj.opts = ""
|
|
71
|
-
obj.result =
|
|
77
|
+
obj.result = {}
|
|
72
78
|
obj.sets = Default()
|
|
73
79
|
obj.txt = txt or ""
|
|
74
80
|
obj.otxt = obj.txt
|
|
@@ -109,34 +115,10 @@ def parse(obj, txt=None):
|
|
|
109
115
|
return obj
|
|
110
116
|
|
|
111
117
|
|
|
112
|
-
def scan(*pkgs, init=False, disable=""):
|
|
113
|
-
result = []
|
|
114
|
-
for mod in modloop(*pkgs, disable=disable):
|
|
115
|
-
if not isinstance(mod, types.ModuleType):
|
|
116
|
-
continue
|
|
117
|
-
Commands.scan(mod)
|
|
118
|
-
thr = None
|
|
119
|
-
if init and "init" in dir(mod):
|
|
120
|
-
thr = launch(mod.init)
|
|
121
|
-
result.append((mod, thr))
|
|
122
|
-
return result
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
def spl(txt):
|
|
126
|
-
try:
|
|
127
|
-
result = txt.split(',')
|
|
128
|
-
except (TypeError, ValueError):
|
|
129
|
-
result = txt
|
|
130
|
-
return [x for x in result if x]
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
"interface"
|
|
134
|
-
|
|
135
|
-
|
|
136
118
|
def __dir__():
|
|
137
119
|
return (
|
|
138
120
|
'Commands',
|
|
139
121
|
'command',
|
|
140
|
-
'
|
|
141
|
-
'
|
|
122
|
+
'cmd',
|
|
123
|
+
'parse'
|
|
142
124
|
)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"decoding"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from .objects import Object, construct
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ObjectDecoder(json.JSONDecoder):
|
|
14
|
+
|
|
15
|
+
def __init__(self, *args, **kwargs):
|
|
16
|
+
json.JSONDecoder.__init__(self, *args, **kwargs)
|
|
17
|
+
|
|
18
|
+
def decode(self, s, _w=None):
|
|
19
|
+
val = json.JSONDecoder.decode(self, s)
|
|
20
|
+
if isinstance(val, dict):
|
|
21
|
+
return hook(val)
|
|
22
|
+
return val
|
|
23
|
+
|
|
24
|
+
def raw_decode(self, s, idx=0):
|
|
25
|
+
return json.JSONDecoder.raw_decode(self, s, idx)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def hook(objdict):
|
|
29
|
+
obj = Object()
|
|
30
|
+
construct(obj, objdict)
|
|
31
|
+
return obj
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def loads(string, *args, **kw):
|
|
35
|
+
kw["cls"] = ObjectDecoder
|
|
36
|
+
kw["object_hook"] = hook
|
|
37
|
+
return json.loads(string, *args, **kw)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def __dir__():
|
|
42
|
+
return (
|
|
43
|
+
'ObjectDecoder',
|
|
44
|
+
'hook',
|
|
45
|
+
'loads'
|
|
46
|
+
)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"default values"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Default:
|
|
8
|
+
|
|
9
|
+
def __contains__(self, key):
|
|
10
|
+
return key in dir(self)
|
|
11
|
+
|
|
12
|
+
def __getattr__(self, key):
|
|
13
|
+
return self.__dict__.get(key, "")
|
|
14
|
+
|
|
15
|
+
def __iter__(self):
|
|
16
|
+
return iter(self.__dict__)
|
|
17
|
+
|
|
18
|
+
def __len__(self):
|
|
19
|
+
return len(self.__dict__)
|
|
20
|
+
|
|
21
|
+
def __str__(self):
|
|
22
|
+
return str(self.__dict__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def __dir__():
|
|
26
|
+
return (
|
|
27
|
+
'Default',
|
|
28
|
+
)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"encoder"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from .objects import Object
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ObjectEncoder(json.JSONEncoder):
|
|
14
|
+
|
|
15
|
+
def __init__(self, *args, **kwargs):
|
|
16
|
+
json.JSONEncoder.__init__(self, *args, **kwargs)
|
|
17
|
+
|
|
18
|
+
def default(self, o):
|
|
19
|
+
if isinstance(o, dict):
|
|
20
|
+
return o.items()
|
|
21
|
+
if issubclass(type(o), Object):
|
|
22
|
+
return vars(o)
|
|
23
|
+
if isinstance(o, list):
|
|
24
|
+
return iter(o)
|
|
25
|
+
try:
|
|
26
|
+
return json.JSONEncoder.default(self, o)
|
|
27
|
+
except TypeError:
|
|
28
|
+
try:
|
|
29
|
+
return vars(o)
|
|
30
|
+
except TypeError:
|
|
31
|
+
return repr(o)
|
|
32
|
+
|
|
33
|
+
def encode(self, o) -> str:
|
|
34
|
+
return json.JSONEncoder.encode(self, o)
|
|
35
|
+
|
|
36
|
+
def iterencode(self, o, _one_shot=False):
|
|
37
|
+
return json.JSONEncoder.iterencode(self, o, _one_shot)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def dumps(*args, **kw):
|
|
41
|
+
kw["cls"] = ObjectEncoder
|
|
42
|
+
return json.dumps(*args, **kw)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def __dir__():
|
|
46
|
+
return (
|
|
47
|
+
'ObjectEncoder',
|
|
48
|
+
'dumps'
|
|
49
|
+
)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"exception handling"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import traceback
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
DEBUG = True
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Errors:
|
|
14
|
+
|
|
15
|
+
name = __file__.rsplit(".", maxsplit=2)[-2]
|
|
16
|
+
errors = []
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def format(exc) -> str:
|
|
20
|
+
exctype, excvalue, trb = type(exc), exc, exc.__traceback__
|
|
21
|
+
trace = traceback.extract_tb(trb)
|
|
22
|
+
result = ""
|
|
23
|
+
for i in trace:
|
|
24
|
+
fname = i[0]
|
|
25
|
+
linenr = i[1]
|
|
26
|
+
plugfile = fname[:-3].split("/")
|
|
27
|
+
mod = []
|
|
28
|
+
for i in plugfile[::-1]:
|
|
29
|
+
mod.append(i)
|
|
30
|
+
if Errors.name in i:
|
|
31
|
+
break
|
|
32
|
+
ownname = '.'.join(mod[::-1])
|
|
33
|
+
if ownname.endswith("__"):
|
|
34
|
+
continue
|
|
35
|
+
if ownname.startswith("<"):
|
|
36
|
+
continue
|
|
37
|
+
result += f"{ownname}:{linenr} "
|
|
38
|
+
del trace
|
|
39
|
+
res = f"{exctype} {result[:-1]} {excvalue}"
|
|
40
|
+
return res
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def full(exc) -> str:
|
|
44
|
+
return traceback.format_exception(
|
|
45
|
+
type(exc),
|
|
46
|
+
exc,
|
|
47
|
+
exc.__traceback__
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def errors() -> []:
|
|
52
|
+
return Errors.errors
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def later(exc) -> None:
|
|
56
|
+
excp = exc.with_traceback(exc.__traceback__)
|
|
57
|
+
fmt = Errors.format(excp)
|
|
58
|
+
if fmt not in Errors.errors:
|
|
59
|
+
Errors.errors.append(fmt)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"find objects"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
from .caching import Cache
|
|
12
|
+
from .objects import Object, fqn, items, update
|
|
13
|
+
from .persist import read
|
|
14
|
+
from .workdir import long, skel, store
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
p = os.path.join
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def fns(clz):
|
|
21
|
+
dname = ''
|
|
22
|
+
pth = store(clz)
|
|
23
|
+
for rootdir, dirs, _files in os.walk(pth, topdown=False):
|
|
24
|
+
if dirs:
|
|
25
|
+
for dname in sorted(dirs):
|
|
26
|
+
if dname.count('-') == 2:
|
|
27
|
+
ddd = p(rootdir, dname)
|
|
28
|
+
for fll in os.listdir(ddd):
|
|
29
|
+
yield p(ddd, fll)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def fntime(daystr):
|
|
33
|
+
daystr = daystr.replace('_', ':')
|
|
34
|
+
datestr = ' '.join(daystr.split(os.sep)[-2:])
|
|
35
|
+
if '.' in datestr:
|
|
36
|
+
datestr, rest = datestr.rsplit('.', 1)
|
|
37
|
+
else:
|
|
38
|
+
rest = ''
|
|
39
|
+
timed = time.mktime(time.strptime(datestr, '%Y-%m-%d %H:%M:%S'))
|
|
40
|
+
if rest:
|
|
41
|
+
timed += float('.' + rest)
|
|
42
|
+
return timed
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def find(clz, selector=None, deleted=False, matching=False):
|
|
46
|
+
skel()
|
|
47
|
+
pth = long(clz)
|
|
48
|
+
res = []
|
|
49
|
+
for fnm in fns(pth):
|
|
50
|
+
obj = Cache.get(fnm)
|
|
51
|
+
if not obj:
|
|
52
|
+
obj = Object()
|
|
53
|
+
read(obj, fnm)
|
|
54
|
+
Cache.add(fnm, obj)
|
|
55
|
+
if not deleted and '__deleted__' in dir(obj) and obj.__deleted__:
|
|
56
|
+
continue
|
|
57
|
+
if selector and not search(obj, selector, matching):
|
|
58
|
+
continue
|
|
59
|
+
res.append((fnm, obj))
|
|
60
|
+
return sorted(res, key=lambda x: fntime(x[0]))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def last(obj, selector=None):
|
|
64
|
+
if selector is None:
|
|
65
|
+
selector = {}
|
|
66
|
+
result = sorted(
|
|
67
|
+
find(fqn(obj), selector),
|
|
68
|
+
key=lambda x: fntime(x[0])
|
|
69
|
+
)
|
|
70
|
+
res = None
|
|
71
|
+
if result:
|
|
72
|
+
inp = result[-1]
|
|
73
|
+
update(obj, inp[-1])
|
|
74
|
+
res = inp[0]
|
|
75
|
+
return res
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def search(obj, selector, matching=None):
|
|
79
|
+
res = False
|
|
80
|
+
if not selector:
|
|
81
|
+
return res
|
|
82
|
+
for key, value in items(selector):
|
|
83
|
+
val = getattr(obj, key, None)
|
|
84
|
+
if not val:
|
|
85
|
+
continue
|
|
86
|
+
if matching and value == val:
|
|
87
|
+
res = True
|
|
88
|
+
elif str(value).lower() in str(val).lower() or value == "match":
|
|
89
|
+
res = True
|
|
90
|
+
else:
|
|
91
|
+
res = False
|
|
92
|
+
break
|
|
93
|
+
return res
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def __dir__():
|
|
97
|
+
return (
|
|
98
|
+
'fns',
|
|
99
|
+
'fntime',
|
|
100
|
+
'find',
|
|
101
|
+
'last',
|
|
102
|
+
'search'
|
|
103
|
+
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"lookup tables"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
NAMES = {
|
|
8
|
+
"cfg": "genocide.modules.irc",
|
|
9
|
+
"dpl": "genocide.modules.rss",
|
|
10
|
+
"err": "genocide.modules.err",
|
|
11
|
+
"exp": "genocide.modules.rss",
|
|
12
|
+
"flt": "genocide.modules.flt",
|
|
13
|
+
"imp": "genocide.modules.rss",
|
|
14
|
+
"mod": "genocide.modules.mod",
|
|
15
|
+
"mre": "genocide.modules.irc",
|
|
16
|
+
"nme": "genocide.modules.rss",
|
|
17
|
+
"pwd": "genocide.modules.irc",
|
|
18
|
+
"rem": "genocide.modules.rss",
|
|
19
|
+
"req": "genocide.modules.req",
|
|
20
|
+
"res": "genocide.modules.rss",
|
|
21
|
+
"rss": "genocide.modules.rss",
|
|
22
|
+
"syn": "genocide.modules.rss",
|
|
23
|
+
"thr": "genocide.modules.thr",
|
|
24
|
+
"upt": "genocide.modules.upt"
|
|
25
|
+
}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
# This file is placed in the Public Domain.
|
|
2
|
-
# pylint: disable=C0116
|
|
2
|
+
# pylint: disable=C0116,E0402
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
"errors"
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
from
|
|
8
|
+
from ..excepts import Errors
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def err(event):
|
|
12
12
|
nmr = 0
|
|
13
|
-
for
|
|
14
|
-
|
|
15
|
-
event.reply(line.strip())
|
|
13
|
+
for line in Errors.errors:
|
|
14
|
+
event.reply(line.strip())
|
|
16
15
|
nmr += 1
|
|
17
16
|
if not nmr:
|
|
18
17
|
event.reply("no errors")
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
# pylint: disable=C0116,E0402
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
"fleet"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
from ..objects import fmt
|
|
9
|
+
from ..threads import name
|
|
10
|
+
from ..clients import Fleet
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def flt(event):
|
|
14
|
+
bots = Fleet.bots.values()
|
|
15
|
+
try:
|
|
16
|
+
event.reply(fmt(list(Fleet.bots.values())[int(event.args[0])]))
|
|
17
|
+
except (KeyError, IndexError, ValueError):
|
|
18
|
+
event.reply(",".join([name(x).split(".")[-1] for x in bots]))
|