genocide 232__tar.gz → 233__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-232 → genocide-233}/PKG-INFO +5 -2
- {genocide-232 → genocide-233}/README.rst +3 -0
- genocide-233/genocide/booting.py +137 -0
- genocide-233/genocide/brokers.py +58 -0
- genocide-233/genocide/command.py +77 -0
- genocide-232/genocide/defines.py → genocide-233/genocide/configs.py +7 -11
- {genocide-232 → genocide-233}/genocide/encoder.py +21 -11
- {genocide-232 → genocide-233}/genocide/handler.py +71 -32
- genocide-233/genocide/modules/adm.py +54 -0
- genocide-233/genocide/modules/bsc.py +40 -0
- genocide-233/genocide/modules/cfg.py +49 -0
- genocide-232/genocide/modules/atr.py → genocide-233/genocide/modules/fie.py +7 -7
- {genocide-232 → genocide-233}/genocide/modules/flt.py +1 -1
- {genocide-232 → genocide-233}/genocide/modules/fnd.py +15 -0
- {genocide-232 → genocide-233}/genocide/modules/irc.py +21 -20
- genocide-233/genocide/modules/log.py +25 -0
- {genocide-232 → genocide-233}/genocide/modules/man.py +31 -20
- genocide-233/genocide/modules/mbx.py +90 -0
- {genocide-232 → genocide-233}/genocide/modules/mdl.py +12 -14
- {genocide-232 → genocide-233}/genocide/modules/pth.py +1 -1
- genocide-233/genocide/modules/pwd.py +18 -0
- {genocide-232 → genocide-233}/genocide/modules/req.py +2 -1
- {genocide-232 → genocide-233}/genocide/modules/rss.py +47 -41
- {genocide-232 → genocide-233}/genocide/modules/rst.py +4 -4
- genocide-233/genocide/modules/tbl.py +0 -0
- {genocide-232 → genocide-233}/genocide/modules/tdo.py +4 -14
- {genocide-232 → genocide-233}/genocide/modules/tmr.py +20 -39
- {genocide-232 → genocide-233}/genocide/modules/udp.py +10 -6
- {genocide-232 → genocide-233}/genocide/modules/web.py +18 -15
- {genocide-232 → genocide-233}/genocide/modules/wsd.py +1 -2
- genocide-233/genocide/network/_images/abilifynew2.png +0 -0
- genocide-233/genocide/network/_images/clozapinenew2.png +0 -0
- genocide-233/genocide/network/_images/haloperidolnew2.png +0 -0
- genocide-233/genocide/network/_images/zyprexanew2.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_static/documentation_options.js +1 -1
- {genocide-232 → genocide-233}/genocide/network/_static/genocide.css +2 -2
- {genocide-232 → genocide-233}/genocide/network/_static/opensearch.xml +4 -4
- genocide-233/genocide/network/_static/otpcr.css +72 -0
- {genocide-232 → genocide-233}/genocide/network/_static/sitemap.xml +6 -6
- {genocide-232 → genocide-233}/genocide/network/about.html +5 -5
- genocide-233/genocide/network/echa.html +68 -0
- {genocide-232 → genocide-233}/genocide/network/evidence.html +9 -7
- {genocide-232 → genocide-233}/genocide/network/genindex-all.html +2 -2
- {genocide-232 → genocide-233}/genocide/network/genindex.html +2 -2
- genocide-233/genocide/network/googlea6568bcc05c8d50b.html +1 -0
- {genocide-232 → genocide-233}/genocide/network/guilty.html +6 -6
- {genocide-232 → genocide-233}/genocide/network/index.html +9 -5
- {genocide-232 → genocide-233}/genocide/network/manual.html +164 -53
- genocide-233/genocide/network/objects.inv +6 -0
- {genocide-232 → genocide-233}/genocide/network/pubchem.html +9 -9
- {genocide-232 → genocide-233}/genocide/network/reconsider.html +6 -6
- {genocide-232 → genocide-233}/genocide/network/request.html +5 -6
- genocide-233/genocide/network/robots.txt +4 -0
- {genocide-232 → genocide-233}/genocide/network/search.html +2 -2
- genocide-233/genocide/network/searchindex.js +1 -0
- {genocide-232 → genocide-233}/genocide/network/writings.html +6 -6
- {genocide-232 → genocide-233}/genocide/objects.py +87 -64
- genocide-233/genocide/package.py +154 -0
- {genocide-232 → genocide-233}/genocide/persist.py +64 -75
- genocide-233/genocide/runtime.py +195 -0
- {genocide-232 → genocide-233}/genocide/threads.py +37 -31
- {genocide-232 → genocide-233}/genocide/utility.py +108 -29
- {genocide-232 → genocide-233}/genocide.egg-info/PKG-INFO +5 -2
- {genocide-232 → genocide-233}/genocide.egg-info/SOURCES.txt +15 -4
- genocide-233/genocide.egg-info/entry_points.txt +2 -0
- {genocide-232 → genocide-233}/pyproject.toml +4 -3
- genocide-232/genocide/brokers.py +0 -50
- genocide-232/genocide/command.py +0 -61
- genocide-232/genocide/loggers.py +0 -38
- genocide-232/genocide/modules/log.py +0 -35
- genocide-232/genocide/modules/mbx.py +0 -133
- genocide-232/genocide/modules/upt.py +0 -17
- genocide-232/genocide/network/objects.inv +0 -0
- genocide-232/genocide/network/robots.txt +0 -2
- genocide-232/genocide/network/searchindex.js +0 -1
- genocide-232/genocide/package.py +0 -109
- genocide-232/genocide/runtime.py +0 -377
- genocide-232/genocide.egg-info/entry_points.txt +0 -2
- {genocide-232 → genocide-233}/genocide/modules/__init__.py +0 -0
- {genocide-232 → genocide-233}/genocide/modules/sil.py +0 -0
- {genocide-232 → genocide-233}/genocide/modules/slg.py +0 -0
- {genocide-232 → genocide-233}/genocide/modules/thr.py +0 -0
- {genocide-232 → genocide-233}/genocide/modules/wdr.py +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/ECHAabilify.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/ECHAclozapine.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/ECHAhaldol.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/ECHAzyprexa.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/OTP111.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/OTP222.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/abilifypubchem.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/ack3.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/bevestigd.jpg +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/clozapinepubchem.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/genocide.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/haldolpubchem.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/informed.jpg +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/kamer2.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/skull3.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_images/zyprexapubchem.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_static/alabaster.css +0 -0
- {genocide-232 → genocide-233}/genocide/network/_static/basic.css +0 -0
- {genocide-232 → genocide-233}/genocide/network/_static/custom.css +0 -0
- {genocide-232 → genocide-233}/genocide/network/_static/doctools.js +0 -0
- {genocide-232 → genocide-233}/genocide/network/_static/file.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_static/language_data.js +0 -0
- {genocide-232 → genocide-233}/genocide/network/_static/minus.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_static/plus.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_static/pygments.css +0 -0
- {genocide-232 → genocide-233}/genocide/network/_static/searchtools.js +0 -0
- {genocide-232 → genocide-233}/genocide/network/_static/skull3.png +0 -0
- {genocide-232 → genocide-233}/genocide/network/_static/sphinx_highlight.js +0 -0
- {genocide-232 → genocide-233}/genocide/network/pdf/EM_Ack_OTP-CR-117_19.pdf +0 -0
- {genocide-232 → genocide-233}/genocide/network/pdf/EM_T04_OTP-CR-117_19.pdf +0 -0
- {genocide-232 → genocide-233}/genocide/network/pdf/EM_T07_OTP-CR-117_19_001.pdf +0 -0
- {genocide-232 → genocide-233}/genocide/network/pdf/Kamer.pdf +0 -0
- {genocide-232 → genocide-233}/genocide/network/pdf/Rome-Statute.pdf +0 -0
- {genocide-232 → genocide-233}/genocide/network/pdf/bevestigd.pdf +0 -0
- {genocide-232 → genocide-233}/genocide.egg-info/dependency_links.txt +0 -0
- {genocide-232 → genocide-233}/genocide.egg-info/top_level.txt +0 -0
- {genocide-232 → genocide-233}/setup.cfg +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: genocide
|
|
3
|
-
Version:
|
|
4
|
-
Summary: Since 4
|
|
3
|
+
Version: 233
|
|
4
|
+
Summary: Since 4 March 2019.
|
|
5
5
|
Author-email: Bart Thate <bthate@dds.nl>
|
|
6
6
|
License-Expression: Unlicense
|
|
7
7
|
Project-URL: home, https://pypi.org/project/genocide
|
|
@@ -66,3 +66,6 @@ are poison at the time they voted for this law and the day the Wfz law took
|
|
|
66
66
|
effect (1-1-2019), i ask the prosecutor to prosecute the king for making the
|
|
67
67
|
commiting of the above mentioned crimes (killing, torture and impotent making)
|
|
68
68
|
possible.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
(*) The website of the **ECHA** <European Chemical Agency> has been updated in January 2026 and no longer shows a skull and bones when visited.
|
|
@@ -51,3 +51,6 @@ are poison at the time they voted for this law and the day the Wfz law took
|
|
|
51
51
|
effect (1-1-2019), i ask the prosecutor to prosecute the king for making the
|
|
52
52
|
commiting of the above mentioned crimes (killing, torture and impotent making)
|
|
53
53
|
possible.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
(*) The website of the **ECHA** <European Chemical Agency> has been updated in January 2026 and no longer shows a skull and bones when visited.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"at the beginning"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import argparse
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from .runtime import Runtime
|
|
11
|
+
from .command import Commands
|
|
12
|
+
from .configs import Main
|
|
13
|
+
from .handler import Console, Event
|
|
14
|
+
from .objects import Object
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Arguments:
|
|
18
|
+
|
|
19
|
+
args = None
|
|
20
|
+
txt = None
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def getargs(cls):
|
|
24
|
+
"parse commandline arguments."
|
|
25
|
+
parser = argparse.ArgumentParser(prog=Main.name, description=f"{Main.name.upper()}")
|
|
26
|
+
parser.add_argument("-a", "--all", action="store_true", help="load all modules.")
|
|
27
|
+
parser.add_argument("-c", "--console", action="store_true", help="start console.")
|
|
28
|
+
parser.add_argument("-d", "--daemon", action="store_true", help="start background daemon.")
|
|
29
|
+
parser.add_argument("-i", "--ignore", default="", help='modules to ignore.')
|
|
30
|
+
parser.add_argument("-l", "--level", default=Main.level, help='set loglevel.')
|
|
31
|
+
parser.add_argument("-m", "--mods", default="", help='modules to load.')
|
|
32
|
+
parser.add_argument("-n", "--index", action="store", type=int, help="set index to use.")
|
|
33
|
+
parser.add_argument("-r", "--read", action="store_true", help="read config on start.")
|
|
34
|
+
parser.add_argument("-s", "--service", action="store_true", help="start service.")
|
|
35
|
+
parser.add_argument("-v", "--verbose", action='store_true', help='enable verbose.')
|
|
36
|
+
parser.add_argument("-w", "--wait", action='store_true', help='wait for services to start.')
|
|
37
|
+
parser.add_argument("-u", "--user", action="store_true", help="use local mods directory.")
|
|
38
|
+
parser.add_argument("-x", "--admin", action="store_true", help="enable admin mode.")
|
|
39
|
+
parser.add_argument("--wdr", help='set working directory.')
|
|
40
|
+
parser.add_argument("--nochdir", action="store_true", help='set working directory.')
|
|
41
|
+
parser.add_argument("--noignore", action="store_true", help="disable ignore")
|
|
42
|
+
cls.args, arguments = parser.parse_known_args()
|
|
43
|
+
cls.txt = " ".join(arguments)
|
|
44
|
+
Object.merge(Main, cls.args)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class Line(Console):
|
|
48
|
+
|
|
49
|
+
def raw(self, text):
|
|
50
|
+
"write to console."
|
|
51
|
+
print(text.encode('utf-8', 'replace').decode("utf-8"))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class CSL(Line):
|
|
55
|
+
|
|
56
|
+
def poll(self):
|
|
57
|
+
"poll for an event."
|
|
58
|
+
evt = Event()
|
|
59
|
+
evt.orig = repr(self)
|
|
60
|
+
evt.text = input("> ")
|
|
61
|
+
evt.kind = "command"
|
|
62
|
+
return evt
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class Scripts:
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def background():
|
|
69
|
+
"background script."
|
|
70
|
+
Runtime.daemon(Main.verbose, Main.nochdir)
|
|
71
|
+
Runtime.privileges()
|
|
72
|
+
Runtime.configure(Main)
|
|
73
|
+
Runtime.pidfile(Main.name)
|
|
74
|
+
Runtime.scan(Main)
|
|
75
|
+
Runtime.init(Main)
|
|
76
|
+
Runtime.forever()
|
|
77
|
+
|
|
78
|
+
@staticmethod
|
|
79
|
+
def cmd(text):
|
|
80
|
+
cli = Line()
|
|
81
|
+
for txt in text.split(" ! "):
|
|
82
|
+
evt = Event()
|
|
83
|
+
evt.kind = "command"
|
|
84
|
+
evt.orig = repr(cli)
|
|
85
|
+
evt.text = txt
|
|
86
|
+
Commands.command(evt)
|
|
87
|
+
evt.wait()
|
|
88
|
+
|
|
89
|
+
@staticmethod
|
|
90
|
+
def console():
|
|
91
|
+
"console script."
|
|
92
|
+
import readline
|
|
93
|
+
readline.redisplay()
|
|
94
|
+
Runtime.configure(Main)
|
|
95
|
+
if Main.verbose:
|
|
96
|
+
Runtime.banner()
|
|
97
|
+
Runtime.scan(Main)
|
|
98
|
+
Runtime.init(Main)
|
|
99
|
+
csl = CSL()
|
|
100
|
+
csl.start()
|
|
101
|
+
Runtime.forever()
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def control():
|
|
105
|
+
"cli script."
|
|
106
|
+
if not Arguments.txt:
|
|
107
|
+
return
|
|
108
|
+
Main.all = True
|
|
109
|
+
Runtime.configure(Main)
|
|
110
|
+
Runtime.scan(Main)
|
|
111
|
+
Scripts.cmd(Arguments.txt)
|
|
112
|
+
|
|
113
|
+
@staticmethod
|
|
114
|
+
def service():
|
|
115
|
+
"service script."
|
|
116
|
+
Runtime.privileges()
|
|
117
|
+
Runtime.configure(Main)
|
|
118
|
+
Runtime.scan(Main)
|
|
119
|
+
Runtime.banner()
|
|
120
|
+
Runtime.pidfile(Main.name)
|
|
121
|
+
Runtime.init(Main)
|
|
122
|
+
Runtime.forever()
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def main():
|
|
126
|
+
"main"
|
|
127
|
+
Arguments.getargs()
|
|
128
|
+
Main.all = True
|
|
129
|
+
Main.ignore = "mbx,rst,udp,web,wsd"
|
|
130
|
+
if Main.daemon:
|
|
131
|
+
Runtime.wrap(Scripts.background)
|
|
132
|
+
elif Main.console:
|
|
133
|
+
Runtime.wrap(Scripts.console)
|
|
134
|
+
elif Main.service:
|
|
135
|
+
Runtime.wrap(Scripts.service)
|
|
136
|
+
else:
|
|
137
|
+
Runtime.wrap(Scripts.control)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"brokers"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Broker:
|
|
8
|
+
|
|
9
|
+
objects = {}
|
|
10
|
+
|
|
11
|
+
@classmethod
|
|
12
|
+
def add(cls, obj):
|
|
13
|
+
"add object to the broker, key is repr(obj)."
|
|
14
|
+
cls.objects[repr(obj)] = obj
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def announce(cls, txt):
|
|
18
|
+
"announce text on all objects with an announce method."
|
|
19
|
+
for obj in cls.objs("announce"):
|
|
20
|
+
obj.announce(txt)
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def get(cls, origin):
|
|
24
|
+
"object by repr(obj)."
|
|
25
|
+
return cls.objects.get(origin)
|
|
26
|
+
|
|
27
|
+
@classmethod
|
|
28
|
+
def has(cls, obj):
|
|
29
|
+
"whether the Broker has object."
|
|
30
|
+
return repr(obj) in cls.objects
|
|
31
|
+
|
|
32
|
+
@classmethod
|
|
33
|
+
def like(cls, txt):
|
|
34
|
+
"all keys with a substring in their key."
|
|
35
|
+
for orig in cls.objects:
|
|
36
|
+
if txt in orig.split()[0]:
|
|
37
|
+
yield orig, cls.get(orig)
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def objs(cls, attr):
|
|
41
|
+
"objects with a certain attribute."
|
|
42
|
+
for obj in cls.objects.values():
|
|
43
|
+
if attr in dir(obj):
|
|
44
|
+
yield obj
|
|
45
|
+
|
|
46
|
+
@classmethod
|
|
47
|
+
def stop(cls):
|
|
48
|
+
"announce text on all objects with an announce method."
|
|
49
|
+
for obj in cls.objs("stop"):
|
|
50
|
+
if "wait" in dir(obj):
|
|
51
|
+
obj.wait()
|
|
52
|
+
obj.stop()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def __dir__():
|
|
56
|
+
return (
|
|
57
|
+
'Broker',
|
|
58
|
+
)
|
|
@@ -0,0 +1,77 @@
|
|
|
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 .objects import Methods
|
|
11
|
+
from .package import Mods
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Commands:
|
|
15
|
+
|
|
16
|
+
cmds = {}
|
|
17
|
+
names = {}
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def add(cls, *args):
|
|
21
|
+
"add functions to commands."
|
|
22
|
+
for func in args:
|
|
23
|
+
name = func.__name__
|
|
24
|
+
cls.cmds[name] = func
|
|
25
|
+
modname = func.__module__.split(".")[-1]
|
|
26
|
+
if "__" in modname:
|
|
27
|
+
continue
|
|
28
|
+
cls.names[name] = modname
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
def command(cls, evt):
|
|
32
|
+
"command callback."
|
|
33
|
+
Methods.parse(evt, evt.text)
|
|
34
|
+
func = cls.get(evt.cmd)
|
|
35
|
+
if not func:
|
|
36
|
+
name = cls.names.get(evt.cmd)
|
|
37
|
+
mod = None
|
|
38
|
+
if name:
|
|
39
|
+
mod = Mods.get(name)
|
|
40
|
+
if mod:
|
|
41
|
+
cls.scan(mod)
|
|
42
|
+
func = cls.get(evt.cmd)
|
|
43
|
+
if func:
|
|
44
|
+
func(evt)
|
|
45
|
+
evt.display()
|
|
46
|
+
evt.ready()
|
|
47
|
+
|
|
48
|
+
@classmethod
|
|
49
|
+
def commands(cls, orig):
|
|
50
|
+
"list cpmmands available."
|
|
51
|
+
return cls.names.keys()
|
|
52
|
+
|
|
53
|
+
@classmethod
|
|
54
|
+
def get(cls, cmd):
|
|
55
|
+
"get function for command."
|
|
56
|
+
return cls.cmds.get(cmd, None)
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def scan(cls, module):
|
|
60
|
+
"scan a module for functions with event as argument."
|
|
61
|
+
for key, cmdz in inspect.getmembers(module, inspect.isfunction):
|
|
62
|
+
if 'event' in inspect.signature(cmdz).parameters:
|
|
63
|
+
cls.add(cmdz)
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def table(cls):
|
|
67
|
+
"load names from table."
|
|
68
|
+
mod = Mods.get("tbl")
|
|
69
|
+
names = getattr(mod, "NAMES", None)
|
|
70
|
+
if names:
|
|
71
|
+
cls.names.update(names)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def __dir__():
|
|
75
|
+
return (
|
|
76
|
+
'Commands',
|
|
77
|
+
)
|
|
@@ -4,18 +4,13 @@
|
|
|
4
4
|
"configurations"
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
from .objects import
|
|
7
|
+
from .objects import Base, Object
|
|
8
8
|
from .utility import Utils
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class Configuration(
|
|
11
|
+
class Configuration(Base):
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
super().__init__()
|
|
15
|
-
if args:
|
|
16
|
-
Dict.update(self, args[0])
|
|
17
|
-
if kwargs:
|
|
18
|
-
Dict.update(self, kwargs)
|
|
13
|
+
pass
|
|
19
14
|
|
|
20
15
|
|
|
21
16
|
class MainConfig(type):
|
|
@@ -26,13 +21,14 @@ class MainConfig(type):
|
|
|
26
21
|
return cls.__getattribute__(key)
|
|
27
22
|
|
|
28
23
|
def __str__(cls):
|
|
29
|
-
return str(
|
|
24
|
+
return str(Object.skip(cls.__dict__))
|
|
30
25
|
|
|
31
26
|
|
|
32
27
|
class Main(metaclass=MainConfig):
|
|
33
28
|
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
level = "info"
|
|
30
|
+
name = Utils.pkgname(MainConfig)
|
|
31
|
+
wdr = ""
|
|
36
32
|
|
|
37
33
|
|
|
38
34
|
def __dir__():
|
|
@@ -5,25 +5,35 @@
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
import json
|
|
8
|
+
import threading
|
|
8
9
|
import types
|
|
9
10
|
|
|
10
11
|
|
|
12
|
+
from .objects import Object
|
|
13
|
+
|
|
14
|
+
|
|
11
15
|
class Encoder(json.JSONEncoder):
|
|
12
16
|
|
|
17
|
+
lock = threading.RLock()
|
|
18
|
+
|
|
13
19
|
def default(self, o):
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
"generate serializable versions."
|
|
21
|
+
with Encoder.lock:
|
|
22
|
+
if isinstance(o, type):
|
|
23
|
+
return Object.skip(o)
|
|
24
|
+
if isinstance(o, dict):
|
|
25
|
+
return o.items()
|
|
26
|
+
if isinstance(o, list):
|
|
27
|
+
return iter(o)
|
|
28
|
+
if isinstance(o, types.MappingProxyType):
|
|
29
|
+
return dict(o)
|
|
23
30
|
try:
|
|
24
|
-
return
|
|
31
|
+
return json.JSONEncoder.default(self, o)
|
|
25
32
|
except TypeError:
|
|
26
|
-
|
|
33
|
+
try:
|
|
34
|
+
return vars(o)
|
|
35
|
+
except TypeError:
|
|
36
|
+
return repr(o)
|
|
27
37
|
|
|
28
38
|
|
|
29
39
|
class Json:
|
|
@@ -4,32 +4,44 @@
|
|
|
4
4
|
"callback engine"
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
import collections
|
|
7
8
|
import logging
|
|
8
9
|
import queue
|
|
9
10
|
import threading
|
|
10
|
-
import time
|
|
11
11
|
import _thread
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
from .brokers import Broker
|
|
15
|
+
from .command import Commands
|
|
16
|
+
from .objects import Base
|
|
15
17
|
from .threads import Thread
|
|
16
18
|
|
|
17
19
|
|
|
18
|
-
class Event:
|
|
20
|
+
class Event(Base):
|
|
19
21
|
|
|
20
22
|
def __init__(self):
|
|
23
|
+
Base.__init__(self)
|
|
21
24
|
self._ready = threading.Event()
|
|
22
25
|
self._thr = None
|
|
23
|
-
self.result = {}
|
|
24
26
|
self.args = []
|
|
27
|
+
self.channel = ""
|
|
25
28
|
self.index = 0
|
|
26
29
|
self.kind = "event"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def
|
|
32
|
-
|
|
30
|
+
self.orig = ""
|
|
31
|
+
self.result = collections.deque()
|
|
32
|
+
self.text = ""
|
|
33
|
+
|
|
34
|
+
def display(self):
|
|
35
|
+
"print results."
|
|
36
|
+
bot = Broker.get(self.orig)
|
|
37
|
+
if bot:
|
|
38
|
+
bot.display(self)
|
|
39
|
+
|
|
40
|
+
def ok(self, txt=""):
|
|
41
|
+
"print ok response."
|
|
42
|
+
if not txt:
|
|
43
|
+
txt = self.text
|
|
44
|
+
self.reply(f"ok {txt}".strip())
|
|
33
45
|
|
|
34
46
|
def ready(self):
|
|
35
47
|
"flag message as ready."
|
|
@@ -37,13 +49,13 @@ class Event:
|
|
|
37
49
|
|
|
38
50
|
def reply(self, text):
|
|
39
51
|
"add text to result."
|
|
40
|
-
self.result
|
|
52
|
+
self.result.append(text)
|
|
41
53
|
|
|
42
54
|
def wait(self, timeout=0.0):
|
|
43
55
|
"wait for completion."
|
|
44
|
-
self._ready.wait(timeout or None)
|
|
45
56
|
if self._thr:
|
|
46
57
|
self._thr.join(timeout or None)
|
|
58
|
+
self._ready.wait(timeout or None)
|
|
47
59
|
|
|
48
60
|
|
|
49
61
|
class Handler:
|
|
@@ -66,7 +78,7 @@ class Handler:
|
|
|
66
78
|
"event loop."
|
|
67
79
|
while self.running.is_set():
|
|
68
80
|
event = self.queue.get()
|
|
69
|
-
if
|
|
81
|
+
if event is None:
|
|
70
82
|
break
|
|
71
83
|
event.orig = repr(self)
|
|
72
84
|
self.callback(event)
|
|
@@ -79,16 +91,19 @@ class Handler:
|
|
|
79
91
|
"register callback."
|
|
80
92
|
self.cbs[kind] = callback
|
|
81
93
|
|
|
82
|
-
def start(self):
|
|
94
|
+
def start(self, daemon=True):
|
|
83
95
|
"start event handler loop."
|
|
84
96
|
self.running.set()
|
|
85
|
-
Thread.launch(self.loop)
|
|
97
|
+
Thread.launch(self.loop, daemon=daemon)
|
|
86
98
|
|
|
87
99
|
def stop(self):
|
|
88
100
|
"stop event handler loop."
|
|
89
101
|
self.running.clear()
|
|
90
102
|
self.queue.put(None)
|
|
91
103
|
|
|
104
|
+
def wait(self):
|
|
105
|
+
pass
|
|
106
|
+
|
|
92
107
|
|
|
93
108
|
class Client(Handler):
|
|
94
109
|
|
|
@@ -108,8 +123,8 @@ class Client(Handler):
|
|
|
108
123
|
def display(self, event):
|
|
109
124
|
"display event results."
|
|
110
125
|
with self.olock:
|
|
111
|
-
for
|
|
112
|
-
self.dosay(event.channel,
|
|
126
|
+
for txt in event.result:
|
|
127
|
+
self.dosay(event.channel, txt)
|
|
113
128
|
|
|
114
129
|
def dosay(self, channel, text):
|
|
115
130
|
"say called by display."
|
|
@@ -117,18 +132,15 @@ class Client(Handler):
|
|
|
117
132
|
|
|
118
133
|
def loop(self):
|
|
119
134
|
"input loop."
|
|
120
|
-
while
|
|
121
|
-
event = self.
|
|
122
|
-
if not event
|
|
135
|
+
while self.running.is_set():
|
|
136
|
+
event = self.iqueue.get()
|
|
137
|
+
if not event:
|
|
123
138
|
break
|
|
124
139
|
event.orig = repr(self)
|
|
125
140
|
self.callback(event)
|
|
126
141
|
|
|
127
|
-
def poll(self):
|
|
128
|
-
"return event."
|
|
129
|
-
return self.iqueue.get()
|
|
130
|
-
|
|
131
142
|
def put(self, event):
|
|
143
|
+
"put event into queue."
|
|
132
144
|
self.iqueue.put(event)
|
|
133
145
|
|
|
134
146
|
def raw(self, text):
|
|
@@ -138,25 +150,52 @@ class Client(Handler):
|
|
|
138
150
|
"say text in channel."
|
|
139
151
|
self.raw(text)
|
|
140
152
|
|
|
153
|
+
def stop(self):
|
|
154
|
+
"stop client."
|
|
155
|
+
self.running.clear()
|
|
156
|
+
self.iqueue.put(None)
|
|
141
157
|
|
|
142
|
-
|
|
158
|
+
|
|
159
|
+
class Polled(Client):
|
|
143
160
|
|
|
144
161
|
def loop(self):
|
|
145
|
-
"
|
|
146
|
-
while
|
|
162
|
+
"polling loop."
|
|
163
|
+
while self.running.is_set():
|
|
147
164
|
event = self.poll()
|
|
148
|
-
if
|
|
165
|
+
if event is None:
|
|
149
166
|
break
|
|
167
|
+
if not event.text:
|
|
168
|
+
event.ready()
|
|
169
|
+
continue
|
|
150
170
|
event.orig = repr(self)
|
|
151
171
|
self.callback(event)
|
|
152
|
-
event.wait()
|
|
153
172
|
|
|
154
173
|
def poll(self):
|
|
155
174
|
"return event."
|
|
156
175
|
return self.iqueue.get()
|
|
157
176
|
|
|
158
177
|
|
|
159
|
-
class
|
|
178
|
+
class Console(Polled):
|
|
179
|
+
|
|
180
|
+
def __init__(self):
|
|
181
|
+
super().__init__()
|
|
182
|
+
self.register("command", Commands.command)
|
|
183
|
+
|
|
184
|
+
def loop(self):
|
|
185
|
+
"input loop."
|
|
186
|
+
while self.running.is_set():
|
|
187
|
+
event = self.poll()
|
|
188
|
+
if event is None:
|
|
189
|
+
break
|
|
190
|
+
if not event.text:
|
|
191
|
+
event.ready()
|
|
192
|
+
continue
|
|
193
|
+
event.orig = repr(self)
|
|
194
|
+
self.callback(event)
|
|
195
|
+
event.wait()
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
class Output(Polled):
|
|
160
199
|
|
|
161
200
|
def __init__(self):
|
|
162
201
|
super().__init__()
|
|
@@ -164,7 +203,7 @@ class Output(Client):
|
|
|
164
203
|
|
|
165
204
|
def output(self):
|
|
166
205
|
"output loop."
|
|
167
|
-
while
|
|
206
|
+
while self.running.is_set():
|
|
168
207
|
event = self.oqueue.get()
|
|
169
208
|
if event is None:
|
|
170
209
|
self.oqueue.task_done()
|
|
@@ -172,10 +211,10 @@ class Output(Client):
|
|
|
172
211
|
self.display(event)
|
|
173
212
|
self.oqueue.task_done()
|
|
174
213
|
|
|
175
|
-
def start(self):
|
|
214
|
+
def start(self, daemon=True):
|
|
176
215
|
"start output loop."
|
|
177
216
|
super().start()
|
|
178
|
-
Thread.launch(self.output)
|
|
217
|
+
Thread.launch(self.output, daemon=daemon)
|
|
179
218
|
|
|
180
219
|
def stop(self):
|
|
181
220
|
"stop output loop."
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"administrator"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
from genocide.command import Commands
|
|
8
|
+
from genocide.configs import Main
|
|
9
|
+
from genocide.encoder import Json
|
|
10
|
+
from genocide.package import Mods
|
|
11
|
+
from genocide.persist import Workdir
|
|
12
|
+
from genocide.runtime import Runtime
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def srv(event):
|
|
16
|
+
"generate systemd service file."
|
|
17
|
+
import getpass
|
|
18
|
+
name = getpass.getuser()
|
|
19
|
+
event.reply(SYSTEMD % (Main.name.upper(), name, name, name, Main.name))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def tbl(event):
|
|
23
|
+
"create table."
|
|
24
|
+
Runtime.md5s = {}
|
|
25
|
+
Commands.names = {}
|
|
26
|
+
Mods.md5s = {}
|
|
27
|
+
for name, module in Mods.all():
|
|
28
|
+
Commands.scan(module)
|
|
29
|
+
Runtime.setmd5s()
|
|
30
|
+
Mods.setmd5s()
|
|
31
|
+
event.reply("# This file is placed in the Pubic Domain.\n\n")
|
|
32
|
+
event.reply('"tables"\n\n')
|
|
33
|
+
event.reply(f"CORE = {Json.dumps(Runtime.md5s, indent=4, sort_keys=True)}\n\n")
|
|
34
|
+
event.reply(f"NAMES = {Json.dumps(Commands.names, indent=4, sort_keys=True)}\n\n")
|
|
35
|
+
event.reply(f"MD5 = {Json.dumps(Mods.md5s, indent=4, sort_keys=True)}")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def wdr(event):
|
|
39
|
+
"show working directory."
|
|
40
|
+
event.reply(Workdir.workdir())
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
SYSTEMD = """[Unit]
|
|
44
|
+
Description=%s
|
|
45
|
+
After=multi-user.target
|
|
46
|
+
|
|
47
|
+
[Service]
|
|
48
|
+
Type=simple
|
|
49
|
+
User=%s
|
|
50
|
+
Group=%s
|
|
51
|
+
ExecStart=/home/%s/.local/bin/%s -s
|
|
52
|
+
|
|
53
|
+
[Install]
|
|
54
|
+
WantedBy=multi-user.target"""
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"administrator"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import time
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from genocide.command import Commands
|
|
11
|
+
from genocide.configs import Main
|
|
12
|
+
from genocide.package import Mods
|
|
13
|
+
from genocide.utility import Time, Utils
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
STARTTIME = time.time()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def cmd(event):
|
|
20
|
+
"list available commands."
|
|
21
|
+
event.reply(",".join(sorted(Commands.commands(event.orig))))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def mod(event):
|
|
25
|
+
"list available modules."
|
|
26
|
+
mods = Mods.list()
|
|
27
|
+
if not mods:
|
|
28
|
+
event.reply("no modules available")
|
|
29
|
+
return
|
|
30
|
+
event.reply(mods)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def upt(event):
|
|
34
|
+
"show uptiome."
|
|
35
|
+
event.reply(Time.elapsed(time.time()-STARTTIME))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def ver(event):
|
|
39
|
+
"show verson."
|
|
40
|
+
event.reply(f"{Main.name.upper()} {Utils.md5sum(Mods.path('tbl') or '')[:7]}")
|