genocide 201__tar.gz → 203__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-201 → genocide-203}/PKG-INFO +1 -1
- genocide-203/genocide/__init__.py +4 -0
- genocide-201/genocide/runtime.py → genocide-203/genocide/__main__.py +139 -62
- genocide-201/genocide/caching.py → genocide-203/genocide/cache.py +6 -3
- genocide-203/genocide/client.py +30 -0
- genocide-201/genocide/persist.py → genocide-203/genocide/disk.py +5 -17
- genocide-201/genocide/excepts.py → genocide-203/genocide/error.py +16 -14
- genocide-203/genocide/event.py +47 -0
- genocide-201/genocide/locater.py → genocide-203/genocide/find.py +25 -17
- genocide-203/genocide/fleet.py +61 -0
- genocide-203/genocide/html/_static/alabaster.css +703 -0
- genocide-203/genocide/html/_static/basic.css +903 -0
- genocide-203/genocide/html/_static/custom.css +1 -0
- genocide-203/genocide/html/_static/doctools.js +156 -0
- genocide-203/genocide/html/_static/documentation_options.js +14 -0
- genocide-203/genocide/html/_static/file.png +0 -0
- genocide-203/genocide/html/_static/language_data.js +199 -0
- genocide-203/genocide/html/_static/minus.png +0 -0
- genocide-203/genocide/html/_static/opensearch.xml +11 -0
- genocide-203/genocide/html/_static/plus.png +0 -0
- genocide-203/genocide/html/_static/pygments.css +74 -0
- genocide-203/genocide/html/_static/searchtools.js +566 -0
- genocide-203/genocide/html/_static/skull3.png +0 -0
- genocide-203/genocide/html/_static/sphinx_highlight.js +144 -0
- genocide-203/genocide/html/about.html +83 -0
- genocide-203/genocide/html/evidence.html +68 -0
- genocide-203/genocide/html/genindex-all.html +58 -0
- genocide-203/genocide/html/genindex.html +63 -0
- genocide-203/genocide/html/guilty.html +66 -0
- genocide-203/genocide/html/index.html +111 -0
- genocide-203/genocide/html/manual.html +230 -0
- genocide-203/genocide/html/objects.inv +0 -0
- genocide-203/genocide/html/reconsider.html +109 -0
- genocide-203/genocide/html/request.html +85 -0
- genocide-203/genocide/html/search.html +87 -0
- genocide-203/genocide/html/searchindex.js +1 -0
- genocide-203/genocide/html/writings.html +162 -0
- genocide-203/genocide/modules/__init__.py +241 -0
- genocide-203/genocide/modules/pth.py +20 -0
- {genocide-201 → genocide-203}/genocide/modules/req.py +0 -1
- genocide-203/genocide/modules/slg.py +11 -0
- genocide-203/genocide/modules/tbl.py +20 -0
- genocide-201/genocide/objects.py → genocide-203/genocide/object.py +81 -8
- genocide-203/genocide/reactor.py +77 -0
- genocide-201/genocide/threads.py → genocide-203/genocide/thread.py +5 -51
- genocide-203/genocide/timer.py +58 -0
- genocide-203/genocide/utils.py +244 -0
- {genocide-201 → genocide-203}/genocide/workdir.py +9 -6
- {genocide-201 → genocide-203}/genocide.egg-info/PKG-INFO +1 -1
- genocide-203/genocide.egg-info/SOURCES.txt +76 -0
- genocide-203/genocide.egg-info/entry_points.txt +2 -0
- genocide-203/pyproject.toml +53 -0
- genocide-201/docs/_templates/base.rst +0 -29
- genocide-201/docs/_templates/class.rst +0 -32
- genocide-201/docs/_templates/mine.rst +0 -59
- genocide-201/docs/_templates/module.rst +0 -59
- genocide-201/docs/about.rst +0 -60
- genocide-201/docs/ack.png +0 -0
- genocide-201/docs/beuker.png +0 -0
- genocide-201/docs/bylaw.png +0 -0
- genocide-201/docs/conf.py +0 -133
- genocide-201/docs/evidence.rst +0 -80
- genocide-201/docs/genocide.jpg +0 -0
- genocide-201/docs/genocidesmile.png +0 -0
- genocide-201/docs/guilty.rst +0 -62
- genocide-201/docs/index.rst +0 -80
- genocide-201/docs/manual.rst +0 -185
- genocide-201/docs/opdehoogte.jpg +0 -0
- genocide-201/docs/reconsider.rst +0 -54
- genocide-201/docs/request.rst +0 -47
- genocide-201/docs/since.png +0 -0
- genocide-201/docs/verbatim4.png +0 -0
- genocide-201/docs/verbatim7.png +0 -0
- genocide-201/docs/verzoek.jpg +0 -0
- genocide-201/docs/writings.rst +0 -99
- genocide-201/docs/zyprexa.png +0 -0
- genocide-201/genocide/clients.py +0 -110
- genocide-201/genocide/command.py +0 -124
- genocide-201/genocide/decoder.py +0 -46
- genocide-201/genocide/default.py +0 -28
- genocide-201/genocide/encoder.py +0 -49
- genocide-201/genocide/lookups.py +0 -25
- genocide-201/genocide/modules/err.py +0 -19
- genocide-201/genocide/modules/flt.py +0 -18
- genocide-201/genocide/modules/irc.py +0 -635
- genocide-201/genocide/modules/mod.py +0 -22
- genocide-201/genocide/modules/rss.py +0 -493
- genocide-201/genocide/modules/thr.py +0 -42
- genocide-201/genocide/modules/upt.py +0 -18
- genocide-201/genocide/package.py +0 -104
- genocide-201/genocide/reactor.py +0 -160
- genocide-201/genocide/utility.py +0 -58
- genocide-201/genocide.egg-info/SOURCES.txt +0 -78
- genocide-201/genocide.egg-info/entry_points.txt +0 -2
- genocide-201/pyproject.toml +0 -104
- {genocide-201 → genocide-203}/README.rst +0 -0
- {genocide-201/docs → genocide-203/genocide/html/_images}/ECHAabilify.png +0 -0
- {genocide-201/docs → genocide-203/genocide/html/_images}/ECHAclozapine.png +0 -0
- {genocide-201/docs → genocide-203/genocide/html/_images}/ECHAhaldol.png +0 -0
- {genocide-201/docs → genocide-203/genocide/html/_images}/ECHAzyprexa.png +0 -0
- {genocide-201/docs → genocide-203/genocide/html/_images}/OTP111.png +0 -0
- {genocide-201/docs → genocide-203/genocide/html/_images}/OTP222.png +0 -0
- {genocide-201/docs → genocide-203/genocide/html/_images}/ack3.png +0 -0
- {genocide-201/docs → genocide-203/genocide/html/_images}/bevestigd.jpg +0 -0
- {genocide-201/docs → genocide-203/genocide/html/_images}/genocide.png +0 -0
- {genocide-201/docs → genocide-203/genocide/html/_images}/informed.jpg +0 -0
- {genocide-201/docs → genocide-203/genocide/html/_images}/kamer2.png +0 -0
- {genocide-201/docs → genocide-203/genocide/html/_images}/skull3.png +0 -0
- {genocide-201/docs → genocide-203/genocide/html}/_static/genocide.css +0 -0
- {genocide-201/docs/files → genocide-203/genocide/html/_static}/sitemap.xml +0 -0
- {genocide-201/docs → genocide-203/genocide/html}/robots.txt +0 -0
- {genocide-201/docs → genocide-203/genocide}/pdf/EM_Ack_OTP-CR-117_19.pdf +0 -0
- {genocide-201/docs → genocide-203/genocide}/pdf/EM_T04_OTP-CR-117_19.pdf +0 -0
- {genocide-201/docs → genocide-203/genocide}/pdf/EM_T07_OTP-CR-117_19_001.pdf +0 -0
- {genocide-201/docs → genocide-203/genocide}/pdf/Kamer.pdf +0 -0
- {genocide-201/docs → genocide-203/genocide}/pdf/Rome-Statute.pdf +0 -0
- {genocide-201/docs → genocide-203/genocide}/pdf/bevestigd.pdf +0 -0
- {genocide-201 → genocide-203}/genocide.egg-info/dependency_links.txt +0 -0
- {genocide-201 → genocide-203}/genocide.egg-info/top_level.txt +0 -0
- {genocide-201 → genocide-203}/setup.cfg +0 -0
- {genocide-201 → genocide-203}/setup.py +0 -0
|
@@ -1,40 +1,37 @@
|
|
|
1
1
|
# This file is placed in the Public Domain.
|
|
2
|
-
# pylint: disable=C,R0903,W0105,W0212,W0611,W0613,W0718,E0402
|
|
3
2
|
|
|
4
3
|
|
|
5
|
-
"main"
|
|
4
|
+
"main program"
|
|
6
5
|
|
|
7
6
|
|
|
7
|
+
import hashlib
|
|
8
8
|
import os
|
|
9
9
|
import pathlib
|
|
10
|
+
import signal
|
|
10
11
|
import sys
|
|
11
12
|
import time
|
|
12
|
-
import
|
|
13
|
+
import types
|
|
13
14
|
import _thread
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
from .command import Commands, command, parse
|
|
18
|
-
from .encoder import dumps
|
|
19
|
-
from .excepts import errors, later
|
|
20
|
-
from .package import Table
|
|
21
|
-
from .reactor import Event, Fleet
|
|
22
|
-
from .threads import launch
|
|
23
|
-
from .utility import spl
|
|
24
|
-
from .workdir import Workdir, pidname
|
|
17
|
+
sys.path.insert(0, os.getcwd())
|
|
25
18
|
|
|
26
19
|
|
|
27
|
-
from .
|
|
28
|
-
from .
|
|
20
|
+
from .client import Client
|
|
21
|
+
from .error import Errors
|
|
22
|
+
from .event import Event
|
|
23
|
+
from .modules import Commands, Main, command, load, mods, modules, parse, scan
|
|
24
|
+
from .object import dumps
|
|
25
|
+
from .thread import launch
|
|
26
|
+
from .utils import nodebug, spl
|
|
27
|
+
from .workdir import Workdir, pidname
|
|
29
28
|
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
p = os.path.join
|
|
33
|
-
pname = f"{Config.name}.modules"
|
|
30
|
+
p = os.path.join
|
|
34
31
|
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
def output(txt):
|
|
34
|
+
print(txt)
|
|
38
35
|
|
|
39
36
|
|
|
40
37
|
class CLI(Client):
|
|
@@ -43,9 +40,6 @@ class CLI(Client):
|
|
|
43
40
|
Client.__init__(self)
|
|
44
41
|
self.register("command", command)
|
|
45
42
|
|
|
46
|
-
def announce(self, txt):
|
|
47
|
-
pass
|
|
48
|
-
|
|
49
43
|
def raw(self, txt):
|
|
50
44
|
output(txt.encode('utf-8', 'replace').decode("utf-8"))
|
|
51
45
|
|
|
@@ -53,7 +47,7 @@ class CLI(Client):
|
|
|
53
47
|
class Console(CLI):
|
|
54
48
|
|
|
55
49
|
def announce(self, txt):
|
|
56
|
-
|
|
50
|
+
output(txt)
|
|
57
51
|
|
|
58
52
|
def callback(self, evt):
|
|
59
53
|
CLI.callback(self, evt)
|
|
@@ -66,9 +60,29 @@ class Console(CLI):
|
|
|
66
60
|
return evt
|
|
67
61
|
|
|
68
62
|
|
|
63
|
+
"output"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def nil(txt):
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def enable():
|
|
71
|
+
global output
|
|
72
|
+
output = print
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def disable():
|
|
76
|
+
global output
|
|
77
|
+
output = nil
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
"utilities"
|
|
81
|
+
|
|
82
|
+
|
|
69
83
|
def banner():
|
|
70
84
|
tme = time.ctime(time.time()).replace(" ", " ")
|
|
71
|
-
output(f"{
|
|
85
|
+
output(f"{Main.name.upper()} since {tme}")
|
|
72
86
|
|
|
73
87
|
|
|
74
88
|
def check(txt):
|
|
@@ -110,6 +124,31 @@ def forever():
|
|
|
110
124
|
_thread.interrupt_main()
|
|
111
125
|
|
|
112
126
|
|
|
127
|
+
def inits(names) -> [types.ModuleType]:
|
|
128
|
+
mods = []
|
|
129
|
+
for name in spl(names):
|
|
130
|
+
mod = load(name)
|
|
131
|
+
if not mod:
|
|
132
|
+
continue
|
|
133
|
+
if "init" in dir(mod):
|
|
134
|
+
thr = launch(mod.init)
|
|
135
|
+
mods.append((mod, thr))
|
|
136
|
+
return mods
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def md5sum(mod):
|
|
140
|
+
with open(mod.__file__, "r", encoding="utf-8") as file:
|
|
141
|
+
txt = file.read().encode("utf-8")
|
|
142
|
+
return str(hashlib.md5(txt).hexdigest())
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def modnames(path) -> [str]:
|
|
146
|
+
return [
|
|
147
|
+
x[:-3] for x in os.listdir(path)
|
|
148
|
+
if x.endswith(".py") and not x.startswith("__")
|
|
149
|
+
]
|
|
150
|
+
|
|
151
|
+
|
|
113
152
|
def pidfile(filename):
|
|
114
153
|
if os.path.exists(filename):
|
|
115
154
|
os.unlink(filename)
|
|
@@ -127,30 +166,46 @@ def privileges():
|
|
|
127
166
|
os.setuid(pwnam2.pw_uid)
|
|
128
167
|
|
|
129
168
|
|
|
169
|
+
def setwd(name, path=""):
|
|
170
|
+
Main.name = name
|
|
171
|
+
path = path or os.path.expanduser(f"~/.{name}")
|
|
172
|
+
Workdir.wdr = path
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
"handlers"
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def handler(signum, frame):
|
|
179
|
+
_thread.interrupt_main()
|
|
180
|
+
|
|
181
|
+
|
|
130
182
|
"scripts"
|
|
131
183
|
|
|
132
184
|
|
|
133
185
|
def background():
|
|
134
|
-
daemon(
|
|
186
|
+
daemon("-v" in sys.argv)
|
|
187
|
+
setwd(Main.name)
|
|
135
188
|
privileges()
|
|
136
|
-
|
|
189
|
+
disable()
|
|
190
|
+
pidfile(pidname(Main.name))
|
|
137
191
|
Commands.add(cmd)
|
|
138
|
-
|
|
192
|
+
inits(Main.init or "irc,rss")
|
|
139
193
|
forever()
|
|
140
194
|
|
|
141
195
|
|
|
142
196
|
def console():
|
|
143
197
|
import readline # noqa: F401
|
|
198
|
+
setwd(Main.name)
|
|
199
|
+
enable()
|
|
144
200
|
Commands.add(cmd)
|
|
145
|
-
parse(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if "v" in
|
|
201
|
+
parse(Main, " ".join(sys.argv[1:]))
|
|
202
|
+
Main.init = Main.sets.init or Main.init
|
|
203
|
+
Main.verbose = Main.sets.verbose or Main.verbose
|
|
204
|
+
if "v" in Main.opts:
|
|
149
205
|
banner()
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
thr.join()
|
|
206
|
+
for _mod, thr in inits(Main.init):
|
|
207
|
+
if "w" in Main.opts:
|
|
208
|
+
thr.join()
|
|
154
209
|
csl = Console()
|
|
155
210
|
csl.start()
|
|
156
211
|
forever()
|
|
@@ -159,23 +214,31 @@ def console():
|
|
|
159
214
|
def control():
|
|
160
215
|
if len(sys.argv) == 1:
|
|
161
216
|
return
|
|
217
|
+
setwd(Main.name)
|
|
218
|
+
Workdir.wdr = os.path.expanduser(f"~/.{Main.name}")
|
|
219
|
+
enable()
|
|
162
220
|
Commands.add(cmd)
|
|
221
|
+
Commands.add(md5)
|
|
163
222
|
Commands.add(srv)
|
|
164
223
|
Commands.add(tbl)
|
|
165
|
-
parse(
|
|
224
|
+
parse(Main, " ".join(sys.argv[1:]))
|
|
166
225
|
csl = CLI()
|
|
167
226
|
evt = Event()
|
|
168
227
|
evt.orig = repr(csl)
|
|
169
228
|
evt.type = "command"
|
|
170
|
-
evt.txt =
|
|
229
|
+
evt.txt = Main.otxt
|
|
171
230
|
command(evt)
|
|
172
231
|
evt.wait()
|
|
173
232
|
|
|
233
|
+
|
|
174
234
|
def service():
|
|
235
|
+
signal.signal(signal.SIGHUP, handler)
|
|
236
|
+
nodebug()
|
|
237
|
+
setwd(Main.name)
|
|
175
238
|
privileges()
|
|
176
|
-
pidfile(pidname(
|
|
239
|
+
pidfile(pidname(Main.name))
|
|
177
240
|
Commands.add(cmd)
|
|
178
|
-
|
|
241
|
+
inits(Main.init or "irc,rss")
|
|
179
242
|
forever()
|
|
180
243
|
|
|
181
244
|
|
|
@@ -183,18 +246,24 @@ def service():
|
|
|
183
246
|
|
|
184
247
|
|
|
185
248
|
def cmd(event):
|
|
186
|
-
event.reply(",".join(sorted(Commands.names)))
|
|
249
|
+
event.reply(",".join(sorted([x for x in Commands.names if x not in Main.ignore])))
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def md5(event):
|
|
253
|
+
table = mods("tbl")[0]
|
|
254
|
+
event.reply(md5sum(table))
|
|
187
255
|
|
|
188
256
|
|
|
189
257
|
def srv(event):
|
|
190
258
|
import getpass
|
|
191
259
|
name = getpass.getuser()
|
|
192
|
-
event.reply(TXT % (
|
|
260
|
+
event.reply(TXT % (Main.name.upper(), name, name, name, Main.name))
|
|
193
261
|
|
|
194
262
|
|
|
195
263
|
def tbl(event):
|
|
196
|
-
|
|
197
|
-
|
|
264
|
+
import genocide.modules
|
|
265
|
+
for mod in mods():
|
|
266
|
+
scan(mod)
|
|
198
267
|
event.reply("# This file is placed in the Public Domain.")
|
|
199
268
|
event.reply("")
|
|
200
269
|
event.reply("")
|
|
@@ -202,7 +271,13 @@ def tbl(event):
|
|
|
202
271
|
event.reply("")
|
|
203
272
|
event.reply("")
|
|
204
273
|
event.reply(f"NAMES = {dumps(Commands.names, indent=4, sort_keys=True)}")
|
|
205
|
-
|
|
274
|
+
event.reply("")
|
|
275
|
+
event.reply("")
|
|
276
|
+
event.reply("MD5 = {")
|
|
277
|
+
for mod in mods():
|
|
278
|
+
event.reply(f' "{mod.__name__.split(".")[-1]}": "{md5sum(mod)}",')
|
|
279
|
+
event.reply("}")
|
|
280
|
+
|
|
206
281
|
|
|
207
282
|
"data"
|
|
208
283
|
|
|
@@ -224,6 +299,15 @@ WantedBy=multi-user.target"""
|
|
|
224
299
|
"runtime"
|
|
225
300
|
|
|
226
301
|
|
|
302
|
+
def wrapped(func):
|
|
303
|
+
try:
|
|
304
|
+
func()
|
|
305
|
+
except (KeyboardInterrupt, EOFError):
|
|
306
|
+
output("")
|
|
307
|
+
for exc in Errors.errors:
|
|
308
|
+
print(Errors.format(exc))
|
|
309
|
+
|
|
310
|
+
|
|
227
311
|
def wrap(func):
|
|
228
312
|
import termios
|
|
229
313
|
old = None
|
|
@@ -232,37 +316,30 @@ def wrap(func):
|
|
|
232
316
|
except termios.error:
|
|
233
317
|
pass
|
|
234
318
|
try:
|
|
235
|
-
func
|
|
236
|
-
except (KeyboardInterrupt, EOFError):
|
|
237
|
-
output("")
|
|
238
|
-
except Exception as exc:
|
|
239
|
-
later(exc)
|
|
319
|
+
wrapped(func)
|
|
240
320
|
finally:
|
|
241
321
|
if old:
|
|
242
322
|
termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, old)
|
|
243
|
-
for line in errors():
|
|
244
|
-
output(line)
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
def wrapped():
|
|
248
|
-
wrap(main)
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
def wraps():
|
|
252
|
-
wrap(service)
|
|
253
323
|
|
|
254
324
|
|
|
255
325
|
def main():
|
|
326
|
+
if check("a"):
|
|
327
|
+
Main.ignore = ""
|
|
328
|
+
Main.init = ",".join(modules())
|
|
329
|
+
for mod in mods():
|
|
330
|
+
mod.DEBUG = False
|
|
331
|
+
if check("v"):
|
|
332
|
+
setattr(Main.opts, "v", True)
|
|
333
|
+
enable()
|
|
256
334
|
if check("c"):
|
|
257
335
|
wrap(console)
|
|
258
336
|
elif check("d"):
|
|
259
337
|
background()
|
|
260
338
|
elif check("s"):
|
|
261
|
-
|
|
339
|
+
wrapped(service)
|
|
262
340
|
else:
|
|
263
|
-
control
|
|
341
|
+
wrapped(control)
|
|
264
342
|
|
|
265
343
|
|
|
266
344
|
if __name__ == "__main__":
|
|
267
345
|
main()
|
|
268
|
-
sys.exit(0)
|
|
@@ -4,20 +4,23 @@
|
|
|
4
4
|
"caching"
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
import typing
|
|
8
|
+
|
|
9
|
+
|
|
7
10
|
class Cache:
|
|
8
11
|
|
|
9
12
|
objs = {}
|
|
10
13
|
|
|
11
14
|
@staticmethod
|
|
12
|
-
def add(path, obj):
|
|
15
|
+
def add(path, obj) -> None:
|
|
13
16
|
Cache.objs[path] = obj
|
|
14
17
|
|
|
15
18
|
@staticmethod
|
|
16
|
-
def get(path):
|
|
19
|
+
def get(path) -> typing.Any:
|
|
17
20
|
return Cache.objs.get(path, None)
|
|
18
21
|
|
|
19
22
|
@staticmethod
|
|
20
|
-
def typed(matcher):
|
|
23
|
+
def typed(matcher) -> [typing.Any]:
|
|
21
24
|
for key in Cache.objs:
|
|
22
25
|
if matcher not in key:
|
|
23
26
|
continue
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"client"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
from .fleet import Fleet
|
|
8
|
+
from .reactor import Reactor
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Client(Reactor):
|
|
12
|
+
|
|
13
|
+
def __init__(self):
|
|
14
|
+
Reactor.__init__(self)
|
|
15
|
+
Fleet.add(self)
|
|
16
|
+
|
|
17
|
+
def announce(self, txt) -> None:
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
def raw(self, txt) -> None:
|
|
21
|
+
raise NotImplementedError("raw")
|
|
22
|
+
|
|
23
|
+
def say(self, channel, txt) -> None:
|
|
24
|
+
self.raw(txt)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def __dir__():
|
|
28
|
+
return (
|
|
29
|
+
'Client',
|
|
30
|
+
)
|
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
# This file is placed in the Public Domain.
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
"
|
|
4
|
+
"read/write"
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
import datetime
|
|
8
|
-
import os
|
|
9
7
|
import json
|
|
10
8
|
import pathlib
|
|
11
9
|
import threading
|
|
12
10
|
|
|
13
11
|
|
|
14
|
-
from .
|
|
15
|
-
from .encoder import dumps
|
|
16
|
-
from .objects import fqn, update
|
|
17
|
-
from .workdir import store
|
|
12
|
+
from .object import loads, dumps, update
|
|
18
13
|
|
|
19
14
|
|
|
20
|
-
p = os.path.join
|
|
21
15
|
lock = threading.RLock()
|
|
22
16
|
|
|
23
17
|
|
|
@@ -26,15 +20,11 @@ class DecodeError(Exception):
|
|
|
26
20
|
pass
|
|
27
21
|
|
|
28
22
|
|
|
29
|
-
def cdir(pth):
|
|
23
|
+
def cdir(pth) -> None:
|
|
30
24
|
path = pathlib.Path(pth)
|
|
31
25
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
32
26
|
|
|
33
27
|
|
|
34
|
-
def ident(obj):
|
|
35
|
-
return p(fqn(obj),*str(datetime.datetime.now()).split())
|
|
36
|
-
|
|
37
|
-
|
|
38
28
|
def read(obj, pth):
|
|
39
29
|
with lock:
|
|
40
30
|
with open(pth, 'r', encoding='utf-8') as ofile:
|
|
@@ -46,10 +36,8 @@ def read(obj, pth):
|
|
|
46
36
|
return pth
|
|
47
37
|
|
|
48
38
|
|
|
49
|
-
def write(obj, pth
|
|
39
|
+
def write(obj, pth):
|
|
50
40
|
with lock:
|
|
51
|
-
if pth is None:
|
|
52
|
-
pth = store(ident(obj))
|
|
53
41
|
cdir(pth)
|
|
54
42
|
txt = dumps(obj, indent=4)
|
|
55
43
|
with open(pth, 'w', encoding='utf-8') as ofile:
|
|
@@ -59,8 +47,8 @@ def write(obj, pth=None):
|
|
|
59
47
|
|
|
60
48
|
def __dir__():
|
|
61
49
|
return (
|
|
50
|
+
'DecodeError',
|
|
62
51
|
'cdir',
|
|
63
|
-
'ident',
|
|
64
52
|
'read',
|
|
65
53
|
'write'
|
|
66
54
|
)
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
# This file is placed in the Public Domain.
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
"exception handling"
|
|
4
|
+
"deferred exception handling"
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
import traceback
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
DEBUG = True
|
|
11
|
-
|
|
12
|
-
|
|
13
10
|
class Errors:
|
|
14
11
|
|
|
15
|
-
name = __file__.rsplit("
|
|
12
|
+
name = __file__.rsplit("/", maxsplit=2)[-2]
|
|
16
13
|
errors = []
|
|
17
14
|
|
|
18
15
|
@staticmethod
|
|
@@ -22,12 +19,14 @@ class Errors:
|
|
|
22
19
|
result = ""
|
|
23
20
|
for i in trace:
|
|
24
21
|
fname = i[0]
|
|
22
|
+
if fname.endswith(".py"):
|
|
23
|
+
fname = fname[:-3]
|
|
25
24
|
linenr = i[1]
|
|
26
|
-
plugfile = fname
|
|
25
|
+
plugfile = fname.split("/")
|
|
27
26
|
mod = []
|
|
28
27
|
for i in plugfile[::-1]:
|
|
29
28
|
mod.append(i)
|
|
30
|
-
if Errors.name in i:
|
|
29
|
+
if Errors.name in i or "bin" in i:
|
|
31
30
|
break
|
|
32
31
|
ownname = '.'.join(mod[::-1])
|
|
33
32
|
if ownname.endswith("__"):
|
|
@@ -37,6 +36,9 @@ class Errors:
|
|
|
37
36
|
result += f"{ownname}:{linenr} "
|
|
38
37
|
del trace
|
|
39
38
|
res = f"{exctype} {result[:-1]} {excvalue}"
|
|
39
|
+
if "__notes__" in dir(exc):
|
|
40
|
+
for note in exc.__notes__:
|
|
41
|
+
res += f" {note}"
|
|
40
42
|
return res
|
|
41
43
|
|
|
42
44
|
@staticmethod
|
|
@@ -48,12 +50,12 @@ class Errors:
|
|
|
48
50
|
)
|
|
49
51
|
|
|
50
52
|
|
|
51
|
-
def
|
|
52
|
-
|
|
53
|
+
def later(exc, txt="") -> None:
|
|
54
|
+
Errors.errors.append(exc)
|
|
53
55
|
|
|
54
56
|
|
|
55
|
-
def
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
def __dir__():
|
|
58
|
+
return (
|
|
59
|
+
'Errors',
|
|
60
|
+
'later'
|
|
61
|
+
)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"event"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import threading
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
from .fleet import Fleet
|
|
12
|
+
from .object import Default
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Event(Default):
|
|
16
|
+
|
|
17
|
+
def __init__(self):
|
|
18
|
+
Default.__init__(self)
|
|
19
|
+
self._ready = threading.Event()
|
|
20
|
+
self._thr = None
|
|
21
|
+
self.ctime = time.time()
|
|
22
|
+
self.result = {}
|
|
23
|
+
self.type = "event"
|
|
24
|
+
self.txt = ""
|
|
25
|
+
|
|
26
|
+
def display(self):
|
|
27
|
+
Fleet.display(self)
|
|
28
|
+
|
|
29
|
+
def done(self) -> None:
|
|
30
|
+
self.reply("ok")
|
|
31
|
+
|
|
32
|
+
def ready(self) -> None:
|
|
33
|
+
self._ready.set()
|
|
34
|
+
|
|
35
|
+
def reply(self, txt) -> None:
|
|
36
|
+
self.result[time.time()] = txt
|
|
37
|
+
|
|
38
|
+
def wait(self) -> None:
|
|
39
|
+
self._ready.wait()
|
|
40
|
+
if self._thr:
|
|
41
|
+
self._thr.join()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def __dir__():
|
|
45
|
+
return (
|
|
46
|
+
'Event',
|
|
47
|
+
)
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
# This file is placed in the Public Domain.
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
"
|
|
4
|
+
"locate objects"
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
import datetime
|
|
7
8
|
import os
|
|
8
9
|
import time
|
|
9
10
|
|
|
10
11
|
|
|
11
|
-
from .
|
|
12
|
-
from .
|
|
13
|
-
from .
|
|
12
|
+
from .cache import Cache
|
|
13
|
+
from .disk import read
|
|
14
|
+
from .object import Object, fqn, items, update
|
|
14
15
|
from .workdir import long, skel, store
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
p = os.path.join
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
def fns(clz):
|
|
21
|
-
dname = ''
|
|
21
|
+
def fns(clz) -> [str]:
|
|
22
22
|
pth = store(clz)
|
|
23
23
|
for rootdir, dirs, _files in os.walk(pth, topdown=False):
|
|
24
24
|
if dirs:
|
|
@@ -29,9 +29,9 @@ def fns(clz):
|
|
|
29
29
|
yield p(ddd, fll)
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
def fntime(daystr):
|
|
33
|
-
daystr = daystr.replace('_', ':')
|
|
32
|
+
def fntime(daystr) -> int:
|
|
34
33
|
datestr = ' '.join(daystr.split(os.sep)[-2:])
|
|
34
|
+
datestr = datestr.replace("_", " ")
|
|
35
35
|
if '.' in datestr:
|
|
36
36
|
datestr, rest = datestr.rsplit('.', 1)
|
|
37
37
|
else:
|
|
@@ -42,25 +42,32 @@ def fntime(daystr):
|
|
|
42
42
|
return timed
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
def find(clz, selector=None, deleted=False, matching=False):
|
|
45
|
+
def find(clz, selector=None, deleted=False, matching=False) -> [Object]:
|
|
46
46
|
skel()
|
|
47
|
-
pth = long(clz)
|
|
48
47
|
res = []
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
clz = long(clz)
|
|
49
|
+
for pth in fns(clz):
|
|
50
|
+
obj = Cache.get(pth)
|
|
51
51
|
if not obj:
|
|
52
52
|
obj = Object()
|
|
53
|
-
read(obj,
|
|
54
|
-
Cache.add(
|
|
53
|
+
read(obj, pth)
|
|
54
|
+
Cache.add(pth, obj)
|
|
55
55
|
if not deleted and '__deleted__' in dir(obj) and obj.__deleted__:
|
|
56
56
|
continue
|
|
57
57
|
if selector and not search(obj, selector, matching):
|
|
58
58
|
continue
|
|
59
|
-
res.append((
|
|
59
|
+
res.append((pth, obj))
|
|
60
60
|
return sorted(res, key=lambda x: fntime(x[0]))
|
|
61
61
|
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
"methods"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def ident(obj) -> str:
|
|
67
|
+
return p(fqn(obj),*str(datetime.datetime.now()).split())
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def last(obj, selector=None) -> Object:
|
|
64
71
|
if selector is None:
|
|
65
72
|
selector = {}
|
|
66
73
|
result = sorted(
|
|
@@ -75,7 +82,7 @@ def last(obj, selector=None):
|
|
|
75
82
|
return res
|
|
76
83
|
|
|
77
84
|
|
|
78
|
-
def search(obj, selector, matching=None):
|
|
85
|
+
def search(obj, selector, matching=None) -> bool:
|
|
79
86
|
res = False
|
|
80
87
|
if not selector:
|
|
81
88
|
return res
|
|
@@ -99,5 +106,6 @@ def __dir__():
|
|
|
99
106
|
'fntime',
|
|
100
107
|
'find',
|
|
101
108
|
'last',
|
|
109
|
+
'ident',
|
|
102
110
|
'search'
|
|
103
111
|
)
|