bigtalk 1__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.
- bigtalk-1/MANIFEST.in +3 -0
- bigtalk-1/PKG-INFO +70 -0
- bigtalk-1/README.rst +55 -0
- bigtalk-1/bigtalk/brokers.py +36 -0
- bigtalk-1/bigtalk/clients.py +87 -0
- bigtalk-1/bigtalk/command.py +49 -0
- bigtalk-1/bigtalk/handler.py +54 -0
- bigtalk-1/bigtalk/kernels.py +69 -0
- bigtalk-1/bigtalk/locater.py +86 -0
- bigtalk-1/bigtalk/loggers.py +37 -0
- bigtalk-1/bigtalk/message.py +46 -0
- bigtalk-1/bigtalk/methods.py +139 -0
- bigtalk-1/bigtalk/objects.py +99 -0
- bigtalk-1/bigtalk/package.py +79 -0
- bigtalk-1/bigtalk/persist.py +69 -0
- bigtalk-1/bigtalk/repeats.py +63 -0
- bigtalk-1/bigtalk/serials.py +53 -0
- bigtalk-1/bigtalk/statics.py +52 -0
- bigtalk-1/bigtalk/threads.py +92 -0
- bigtalk-1/bigtalk/utility.py +245 -0
- bigtalk-1/bigtalk/workdir.py +67 -0
- bigtalk-1/bigtalk.egg-info/PKG-INFO +70 -0
- bigtalk-1/bigtalk.egg-info/SOURCES.txt +49 -0
- bigtalk-1/bigtalk.egg-info/dependency_links.txt +1 -0
- bigtalk-1/bigtalk.egg-info/top_level.txt +1 -0
- bigtalk-1/bin/clean +50 -0
- bigtalk-1/mods/atr.py +23 -0
- bigtalk-1/mods/flt.py +18 -0
- bigtalk-1/mods/fnd.py +31 -0
- bigtalk-1/mods/irc.py +657 -0
- bigtalk-1/mods/log.py +33 -0
- bigtalk-1/mods/lst.py +12 -0
- bigtalk-1/mods/man.py +242 -0
- bigtalk-1/mods/mbx.py +123 -0
- bigtalk-1/mods/mdl.py +447 -0
- bigtalk-1/mods/mod.py +8 -0
- bigtalk-1/mods/pth.py +12 -0
- bigtalk-1/mods/req.py +71 -0
- bigtalk-1/mods/rss.py +517 -0
- bigtalk-1/mods/rst.py +125 -0
- bigtalk-1/mods/sil.py +19 -0
- bigtalk-1/mods/slg.py +8 -0
- bigtalk-1/mods/tdo.py +49 -0
- bigtalk-1/mods/thr.py +33 -0
- bigtalk-1/mods/tmr.py +109 -0
- bigtalk-1/mods/udp.py +117 -0
- bigtalk-1/mods/upt.py +14 -0
- bigtalk-1/mods/web.py +138 -0
- bigtalk-1/mods/wsd.py +210 -0
- bigtalk-1/pyproject.toml +36 -0
- bigtalk-1/setup.cfg +4 -0
bigtalk-1/MANIFEST.in
ADDED
bigtalk-1/PKG-INFO
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bigtalk
|
|
3
|
+
Version: 1
|
|
4
|
+
Summary: Big Talk
|
|
5
|
+
Author-email: Bart <bthate@dds.nl>
|
|
6
|
+
License-Expression: Unlicense
|
|
7
|
+
Project-URL: home, https://pypi.org/project/bigtalk
|
|
8
|
+
Project-URL: bugs, https://github.com/nixtniet/bigtalk/issues
|
|
9
|
+
Project-URL: source, https://github.com/nixtniet/bigtalk
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Operating System :: Unix
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Utilities
|
|
14
|
+
Description-Content-Type: text/x-rst
|
|
15
|
+
|
|
16
|
+
B I G T A L K
|
|
17
|
+
=============
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
**NAME**
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
|
24
|
+
| ``bigtalk`` - Big Talk
|
|
25
|
+
|
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
**SYNOPSIS**
|
|
29
|
+
|
|
30
|
+
::
|
|
31
|
+
|
|
32
|
+
>>> from bigtalk.objects import Object
|
|
33
|
+
>>> from bigtalk.serials import Jsondumps, loads
|
|
34
|
+
>>> o = Object()
|
|
35
|
+
>>> o.a = "b"
|
|
36
|
+
>>> print(Json.loads(Json.dumps(o)))
|
|
37
|
+
{'a': 'b'}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
**DESCRIPTION**
|
|
41
|
+
|
|
42
|
+
BigTalk has all you need to program a unix cli program, such as disk
|
|
43
|
+
perisistence for configuration files, event handler to handle the
|
|
44
|
+
client/server connection, etc.
|
|
45
|
+
|
|
46
|
+
BiGTalk contains python3 code to program objects in a functional
|
|
47
|
+
way. it provides an “clean namespace” Object class that only has
|
|
48
|
+
dunder methods, so the namespace is not cluttered with method names.
|
|
49
|
+
This makes storing and reading to/from json possible.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
**INSTALL**
|
|
53
|
+
|
|
54
|
+
installation is done with pip
|
|
55
|
+
|
|
56
|
+
|
|
|
57
|
+
| ``$ pip install bigtalk``
|
|
58
|
+
|
|
|
59
|
+
|
|
60
|
+
**AUTHOR**
|
|
61
|
+
|
|
62
|
+
|
|
|
63
|
+
| Bart Thate <``bthate@dds.nl``>
|
|
64
|
+
|
|
|
65
|
+
|
|
66
|
+
**COPYRIGHT**
|
|
67
|
+
|
|
68
|
+
|
|
|
69
|
+
| ``BigTalk`` is Public Domain.
|
|
70
|
+
|
|
bigtalk-1/README.rst
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
B I G T A L K
|
|
2
|
+
=============
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
**NAME**
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
|
9
|
+
| ``bigtalk`` - Big Talk
|
|
10
|
+
|
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
**SYNOPSIS**
|
|
14
|
+
|
|
15
|
+
::
|
|
16
|
+
|
|
17
|
+
>>> from bigtalk.objects import Object
|
|
18
|
+
>>> from bigtalk.serials import Jsondumps, loads
|
|
19
|
+
>>> o = Object()
|
|
20
|
+
>>> o.a = "b"
|
|
21
|
+
>>> print(Json.loads(Json.dumps(o)))
|
|
22
|
+
{'a': 'b'}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
**DESCRIPTION**
|
|
26
|
+
|
|
27
|
+
BigTalk has all you need to program a unix cli program, such as disk
|
|
28
|
+
perisistence for configuration files, event handler to handle the
|
|
29
|
+
client/server connection, etc.
|
|
30
|
+
|
|
31
|
+
BiGTalk contains python3 code to program objects in a functional
|
|
32
|
+
way. it provides an “clean namespace” Object class that only has
|
|
33
|
+
dunder methods, so the namespace is not cluttered with method names.
|
|
34
|
+
This makes storing and reading to/from json possible.
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
**INSTALL**
|
|
38
|
+
|
|
39
|
+
installation is done with pip
|
|
40
|
+
|
|
41
|
+
|
|
|
42
|
+
| ``$ pip install bigtalk``
|
|
43
|
+
|
|
|
44
|
+
|
|
45
|
+
**AUTHOR**
|
|
46
|
+
|
|
47
|
+
|
|
|
48
|
+
| Bart Thate <``bthate@dds.nl``>
|
|
49
|
+
|
|
|
50
|
+
|
|
51
|
+
**COPYRIGHT**
|
|
52
|
+
|
|
53
|
+
|
|
|
54
|
+
| ``BigTalk`` is Public Domain.
|
|
55
|
+
|
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
Broker.objects[repr(obj)] = obj
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
def all(attr):
|
|
17
|
+
for obj in Broker.objects.values():
|
|
18
|
+
if attr in dir(obj):
|
|
19
|
+
yield obj
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def get(origin):
|
|
23
|
+
return Broker.objects.get(origin)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def like(txt):
|
|
28
|
+
for orig in Broker.objects:
|
|
29
|
+
if orig.split()[0] in orig.split()[0]:
|
|
30
|
+
yield orig
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def __dir__():
|
|
34
|
+
return (
|
|
35
|
+
'Broker',
|
|
36
|
+
)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"client-side event handling"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
import queue
|
|
9
|
+
import threading
|
|
10
|
+
import _thread
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
from .brokers import Broker
|
|
14
|
+
from .command import Commands
|
|
15
|
+
from .handler import Handler
|
|
16
|
+
from .threads import Threads
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Client(Handler):
|
|
20
|
+
|
|
21
|
+
def __init__(self):
|
|
22
|
+
super().__init__()
|
|
23
|
+
self.olock = threading.RLock()
|
|
24
|
+
self.oqueue = queue.Queue()
|
|
25
|
+
self.silent = True
|
|
26
|
+
Broker.add(self)
|
|
27
|
+
|
|
28
|
+
def announce(self, text):
|
|
29
|
+
if not self.silent:
|
|
30
|
+
self.raw(text)
|
|
31
|
+
|
|
32
|
+
def display(self, event):
|
|
33
|
+
with self.olock:
|
|
34
|
+
for tme in event.result:
|
|
35
|
+
txt = event.result.get(tme)
|
|
36
|
+
self.dosay(event.channel, txt)
|
|
37
|
+
|
|
38
|
+
def dosay(self, channel, text):
|
|
39
|
+
self.say(channel, text)
|
|
40
|
+
|
|
41
|
+
def raw(self, text):
|
|
42
|
+
raise NotImplementedError("raw")
|
|
43
|
+
|
|
44
|
+
def say(self, channel, text):
|
|
45
|
+
self.raw(text)
|
|
46
|
+
|
|
47
|
+
def wait(self):
|
|
48
|
+
try:
|
|
49
|
+
self.oqueue.join()
|
|
50
|
+
except Exception as ex:
|
|
51
|
+
logging.exception(ex)
|
|
52
|
+
_thread.interrupt_main()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class CLI(Client):
|
|
56
|
+
|
|
57
|
+
def __init__(self):
|
|
58
|
+
super().__init__()
|
|
59
|
+
self.register("command", Commands.command)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class Output(Client):
|
|
63
|
+
|
|
64
|
+
def output(self):
|
|
65
|
+
while True:
|
|
66
|
+
event = self.oqueue.get()
|
|
67
|
+
if event is None:
|
|
68
|
+
self.oqueue.task_done()
|
|
69
|
+
break
|
|
70
|
+
self.display(event)
|
|
71
|
+
self.oqueue.task_done()
|
|
72
|
+
|
|
73
|
+
def start(self):
|
|
74
|
+
Threads.launch(self.output)
|
|
75
|
+
super().start()
|
|
76
|
+
|
|
77
|
+
def stop(self):
|
|
78
|
+
self.oqueue.put(None)
|
|
79
|
+
super().stop()
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def __dir__():
|
|
83
|
+
return (
|
|
84
|
+
'Client',
|
|
85
|
+
'CLI',
|
|
86
|
+
'Output'
|
|
87
|
+
)
|
|
@@ -0,0 +1,49 @@
|
|
|
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 .methods import Methods
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Commands:
|
|
14
|
+
|
|
15
|
+
cmds = {}
|
|
16
|
+
names = {}
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def add(*args):
|
|
20
|
+
for func in args:
|
|
21
|
+
name = func.__name__
|
|
22
|
+
Commands.cmds[name] = func
|
|
23
|
+
Commands.names[name] = func.__module__.split(".")[-1]
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def command(evt):
|
|
27
|
+
Methods.parse(evt, evt.text)
|
|
28
|
+
func = Commands.get(evt.cmd)
|
|
29
|
+
if func:
|
|
30
|
+
func(evt)
|
|
31
|
+
evt.display()
|
|
32
|
+
evt.ready()
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def get(cmd):
|
|
36
|
+
return Commands.cmds.get(cmd, None)
|
|
37
|
+
|
|
38
|
+
@staticmethod
|
|
39
|
+
def scan(module):
|
|
40
|
+
for key, cmdz in inspect.getmembers(module, inspect.isfunction):
|
|
41
|
+
if 'event' not in inspect.signature(cmdz).parameters:
|
|
42
|
+
continue
|
|
43
|
+
Commands.add(cmdz)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def __dir__():
|
|
47
|
+
return (
|
|
48
|
+
'Commands',
|
|
49
|
+
)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"handle your own events"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import queue
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from .threads import Threads
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Handler:
|
|
14
|
+
|
|
15
|
+
def __init__(self):
|
|
16
|
+
self.cbs = {}
|
|
17
|
+
self.queue = queue.Queue()
|
|
18
|
+
|
|
19
|
+
def callback(self, event):
|
|
20
|
+
func = self.cbs.get(event.kind, None)
|
|
21
|
+
if not func:
|
|
22
|
+
event.ready()
|
|
23
|
+
return
|
|
24
|
+
name = event.text and event.text.split()[0]
|
|
25
|
+
event._thr = Threads.launch(func, event, name=name)
|
|
26
|
+
|
|
27
|
+
def loop(self):
|
|
28
|
+
while True:
|
|
29
|
+
event = self.poll()
|
|
30
|
+
if not event:
|
|
31
|
+
break
|
|
32
|
+
event.orig = repr(self)
|
|
33
|
+
self.callback(event)
|
|
34
|
+
|
|
35
|
+
def poll(self):
|
|
36
|
+
return self.queue.get()
|
|
37
|
+
|
|
38
|
+
def put(self, event):
|
|
39
|
+
self.queue.put(event)
|
|
40
|
+
|
|
41
|
+
def register(self, kind, callback):
|
|
42
|
+
self.cbs[kind] = callback
|
|
43
|
+
|
|
44
|
+
def start(self):
|
|
45
|
+
Threads.launch(self.loop)
|
|
46
|
+
|
|
47
|
+
def stop(self):
|
|
48
|
+
self.queue.put(None)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def __dir__():
|
|
52
|
+
return (
|
|
53
|
+
'Handler',
|
|
54
|
+
)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"in the beginning"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import time
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from .command import Commands
|
|
11
|
+
from .loggers import Logging
|
|
12
|
+
from .objects import Default
|
|
13
|
+
from .package import Mods
|
|
14
|
+
from .threads import Threads
|
|
15
|
+
from .utility import Utils
|
|
16
|
+
from .workdir import Workdir
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Config(Default):
|
|
20
|
+
|
|
21
|
+
debug = False
|
|
22
|
+
init = ""
|
|
23
|
+
level = "info"
|
|
24
|
+
name = ""
|
|
25
|
+
opts = ""
|
|
26
|
+
sets = Default()
|
|
27
|
+
version = 0
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Kernel:
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def configure(local=False, network=False):
|
|
34
|
+
assert Config.name
|
|
35
|
+
Logging.level(Config.sets.level or "info")
|
|
36
|
+
Workdir.configure(Config.name)
|
|
37
|
+
Mods.configure(local, network)
|
|
38
|
+
|
|
39
|
+
@staticmethod
|
|
40
|
+
def forever():
|
|
41
|
+
while True:
|
|
42
|
+
try:
|
|
43
|
+
time.sleep(0.1)
|
|
44
|
+
except (KeyboardInterrupt, EOFError):
|
|
45
|
+
break
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def init(names, wait=False):
|
|
49
|
+
thrs = []
|
|
50
|
+
for name in Utils.spl(names):
|
|
51
|
+
mod = Mods.get(name)
|
|
52
|
+
if "init" not in dir(mod):
|
|
53
|
+
continue
|
|
54
|
+
thrs.append(Threads.launch(mod.init))
|
|
55
|
+
if wait:
|
|
56
|
+
for thr in thrs:
|
|
57
|
+
thr.join()
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
def scanner(names):
|
|
61
|
+
for mod in Mods.mods(names):
|
|
62
|
+
Commands.scan(mod)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def __dir__():
|
|
66
|
+
return (
|
|
67
|
+
'Config',
|
|
68
|
+
'Kernel'
|
|
69
|
+
)
|
|
@@ -0,0 +1,86 @@
|
|
|
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 .methods import Methods
|
|
12
|
+
from .objects import Object
|
|
13
|
+
from .persist import Cache, Disk
|
|
14
|
+
from .workdir import Workdir
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
keys = Object.keys
|
|
18
|
+
update = Object.update
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Locater:
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def attrs(kind):
|
|
25
|
+
objs = list(Locater.find(kind))
|
|
26
|
+
if objs:
|
|
27
|
+
return list(keys(objs[0][1]))
|
|
28
|
+
return []
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def find(kind, selector={}, removed=False, matching=False):
|
|
32
|
+
fullname = Workdir.long(kind)
|
|
33
|
+
for pth in Locater.fns(fullname):
|
|
34
|
+
obj = Cache.get(pth)
|
|
35
|
+
if not obj:
|
|
36
|
+
obj = Object()
|
|
37
|
+
Disk.read(obj, pth)
|
|
38
|
+
Cache.add(pth, obj)
|
|
39
|
+
if not removed and Methods.deleted(obj):
|
|
40
|
+
continue
|
|
41
|
+
if selector and not Methods.search(obj, selector, matching):
|
|
42
|
+
continue
|
|
43
|
+
yield pth, obj
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def fns(kind):
|
|
47
|
+
path = Workdir.store(kind)
|
|
48
|
+
for rootdir, dirs, _files in os.walk(path, topdown=True):
|
|
49
|
+
for dname in dirs:
|
|
50
|
+
if dname.count("-") != 2:
|
|
51
|
+
continue
|
|
52
|
+
ddd = os.path.join(rootdir, dname)
|
|
53
|
+
for fll in os.listdir(ddd):
|
|
54
|
+
yield os.path.join(ddd, fll)
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def fntime(daystr):
|
|
58
|
+
datestr = " ".join(daystr.split(os.sep)[-2:])
|
|
59
|
+
datestr = datestr.replace("_", " ")
|
|
60
|
+
if "." in datestr:
|
|
61
|
+
datestr, rest = datestr.rsplit(".", 1)
|
|
62
|
+
else:
|
|
63
|
+
rest = ""
|
|
64
|
+
timed = time.mktime(time.strptime(datestr, "%Y-%m-%d %H:%M:%S"))
|
|
65
|
+
if rest:
|
|
66
|
+
timed += float("." + rest)
|
|
67
|
+
return float(timed)
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
def last(obj, selector={}):
|
|
71
|
+
result = sorted(
|
|
72
|
+
Locater.find(Object.fqn(obj), selector),
|
|
73
|
+
key=lambda x: Locater.fntime(x[0])
|
|
74
|
+
)
|
|
75
|
+
res = ""
|
|
76
|
+
if result:
|
|
77
|
+
inp = result[-1]
|
|
78
|
+
update(obj, inp[-1])
|
|
79
|
+
res = inp[0]
|
|
80
|
+
return res
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def __dir__():
|
|
84
|
+
return (
|
|
85
|
+
'Locater',
|
|
86
|
+
)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"log exceptions"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Format(logging.Formatter):
|
|
11
|
+
|
|
12
|
+
def format(self, record):
|
|
13
|
+
record.module = record.module.upper()
|
|
14
|
+
return logging.Formatter.format(self, record)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Logging:
|
|
18
|
+
|
|
19
|
+
datefmt = "%H:%M:%S"
|
|
20
|
+
format = "%(module).3s %(message)s"
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def level(loglevel):
|
|
24
|
+
formatter = Format(Logging.format, Logging.datefmt)
|
|
25
|
+
stream = logging.StreamHandler()
|
|
26
|
+
stream.setFormatter(formatter)
|
|
27
|
+
logging.basicConfig(
|
|
28
|
+
level=loglevel.upper(),
|
|
29
|
+
handlers=[stream,],
|
|
30
|
+
force=True
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def __dir__():
|
|
35
|
+
return (
|
|
36
|
+
'Logging',
|
|
37
|
+
)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# This file is placed in the Public Domain.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
"only message"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import threading
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
from .brokers import Broker
|
|
12
|
+
from .objects import Default
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Message(Default):
|
|
16
|
+
|
|
17
|
+
def __init__(self):
|
|
18
|
+
super().__init__()
|
|
19
|
+
self._ready = threading.Event()
|
|
20
|
+
self.result = {}
|
|
21
|
+
self.thr = None
|
|
22
|
+
self.args = []
|
|
23
|
+
self.index = 0
|
|
24
|
+
self.kind = "event"
|
|
25
|
+
self.orig = ""
|
|
26
|
+
|
|
27
|
+
def display(evt):
|
|
28
|
+
bot = Broker.get(evt.orig)
|
|
29
|
+
bot.display(evt)
|
|
30
|
+
|
|
31
|
+
def ready(self):
|
|
32
|
+
self._ready.set()
|
|
33
|
+
|
|
34
|
+
def reply(self, text):
|
|
35
|
+
self.result[time.time()] = text
|
|
36
|
+
|
|
37
|
+
def wait(self, timeout=0.0):
|
|
38
|
+
if self.thr:
|
|
39
|
+
self.thr.join(timeout)
|
|
40
|
+
self._ready.wait(timeout or None)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def __dir__():
|
|
44
|
+
return (
|
|
45
|
+
'Message',
|
|
46
|
+
)
|