libbot 51__tar.gz → 53__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.
Files changed (37) hide show
  1. {libbot-51 → libbot-53}/PKG-INFO +5 -4
  2. {libbot-51 → libbot-53}/README.rst +4 -3
  3. libbot-53/bin/bot +81 -0
  4. libbot-53/bin/botd +68 -0
  5. libbot-51/bot/spec.py → libbot-53/bot/__init__.py +11 -7
  6. {libbot-51 → libbot-53}/bot/disk.py +58 -11
  7. {libbot-51 → libbot-53}/bot/error.py +1 -0
  8. {libbot-51 → libbot-53}/bot/modules/__init__.py +1 -1
  9. {libbot-51 → libbot-53}/bot/modules/cmd.py +1 -1
  10. {libbot-51 → libbot-53}/bot/modules/err.py +0 -3
  11. {libbot-51 → libbot-53}/bot/modules/fnd.py +1 -5
  12. {libbot-51 → libbot-53}/bot/modules/irc.py +7 -3
  13. {libbot-51 → libbot-53}/bot/modules/log.py +1 -8
  14. {libbot-51 → libbot-53}/bot/modules/mbx.py +2 -14
  15. {libbot-51 → libbot-53}/bot/modules/mod.py +0 -3
  16. {libbot-51 → libbot-53}/bot/modules/rss.py +8 -4
  17. {libbot-51 → libbot-53}/bot/modules/shp.py +1 -8
  18. {libbot-51 → libbot-53}/bot/modules/tdo.py +1 -8
  19. {libbot-51 → libbot-53}/bot/modules/thr.py +1 -8
  20. {libbot-51 → libbot-53}/bot/modules/udp.py +1 -1
  21. {libbot-51 → libbot-53}/bot/object.py +0 -58
  22. libbot-53/bot/parse.py +76 -0
  23. {libbot-51 → libbot-53}/bot/run.py +30 -82
  24. {libbot-51 → libbot-53}/bot/thread.py +5 -11
  25. {libbot-51 → libbot-53}/libbot.egg-info/PKG-INFO +5 -4
  26. {libbot-51 → libbot-53}/libbot.egg-info/SOURCES.txt +2 -3
  27. {libbot-51 → libbot-53}/pyproject.toml +3 -2
  28. libbot-51/bin/bot +0 -133
  29. libbot-51/bot/__init__.py +0 -10
  30. libbot-51/bot/modules/wsh.py +0 -58
  31. libbot-51/test/test_detect.py +0 -25
  32. {libbot-51 → libbot-53}/libbot.egg-info/dependency_links.txt +0 -0
  33. {libbot-51 → libbot-53}/libbot.egg-info/top_level.txt +0 -0
  34. {libbot-51 → libbot-53}/libbot.egg-info/zip-safe +0 -0
  35. {libbot-51 → libbot-53}/setup.cfg +0 -0
  36. {libbot-51 → libbot-53}/setup.py +0 -0
  37. {libbot-51 → libbot-53}/test/test_none.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: libbot
3
- Version: 51
3
+ Version: 53
4
4
  Summary: the python3 bot namespace
5
5
  Author-email: libbot <libbotx@gmail.com>
6
6
  License: Public Domain
@@ -160,7 +160,7 @@ here is a list of the most basic commands::
160
160
  SYSTEMD
161
161
  =======
162
162
 
163
- save the following it in /etc/systems/system/libbot.service and
163
+ save the following it in /etc/systems/system/botd.service and
164
164
  replace "<user>" with the user running pipx::
165
165
 
166
166
  [Unit]
@@ -173,7 +173,7 @@ replace "<user>" with the user running pipx::
173
173
  User=<user>
174
174
  Group=<user>
175
175
  WorkingDirectory=/home/<user>/.bot
176
- ExecStart=/home/<user>/.local/pipx/venvs/libbot/bin/bot -d
176
+ ExecStart=/home/<user>/.local/pipx/venvs/libbot/bin/botd
177
177
  RemainAfterExit=yes
178
178
 
179
179
  [Install]
@@ -181,7 +181,7 @@ replace "<user>" with the user running pipx::
181
181
 
182
182
  then run this::
183
183
 
184
- sudo systemctl enable libbot --now
184
+ sudo systemctl enable botd --now
185
185
 
186
186
 
187
187
  FILES
@@ -191,6 +191,7 @@ FILES
191
191
 
192
192
  ~/.bot
193
193
  ~/.local/bin/bot
194
+ ~/.local/bin/botd
194
195
  ~/.local/pipx/venvs/libbot/
195
196
 
196
197
 
@@ -144,7 +144,7 @@ here is a list of the most basic commands::
144
144
  SYSTEMD
145
145
  =======
146
146
 
147
- save the following it in /etc/systems/system/libbot.service and
147
+ save the following it in /etc/systems/system/botd.service and
148
148
  replace "<user>" with the user running pipx::
149
149
 
150
150
  [Unit]
@@ -157,7 +157,7 @@ replace "<user>" with the user running pipx::
157
157
  User=<user>
158
158
  Group=<user>
159
159
  WorkingDirectory=/home/<user>/.bot
160
- ExecStart=/home/<user>/.local/pipx/venvs/libbot/bin/bot -d
160
+ ExecStart=/home/<user>/.local/pipx/venvs/libbot/bin/botd
161
161
  RemainAfterExit=yes
162
162
 
163
163
  [Install]
@@ -165,7 +165,7 @@ replace "<user>" with the user running pipx::
165
165
 
166
166
  then run this::
167
167
 
168
- sudo systemctl enable libbot --now
168
+ sudo systemctl enable botd --now
169
169
 
170
170
 
171
171
  FILES
@@ -175,6 +175,7 @@ FILES
175
175
 
176
176
  ~/.bot
177
177
  ~/.local/bin/bot
178
+ ~/.local/bin/botd
178
179
  ~/.local/pipx/venvs/libbot/
179
180
 
180
181
 
libbot-53/bin/bot ADDED
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env python3
2
+ # This file is placed in the Public Domain.
3
+ #
4
+ # pylint: disable=C0103,C0115,C0116,C0209,C0413,W0201,R0903,W0212,W0105,W0613
5
+
6
+
7
+ "program"
8
+
9
+
10
+ import os
11
+ import sys
12
+ import termios
13
+ import time
14
+
15
+
16
+ sys.path.insert(0, os.getcwd())
17
+
18
+
19
+ from bot import CLI, Commands, Default, Errors, Event, Storage
20
+ from bot import command, forever, parse, lsmod, modules, scan
21
+
22
+
23
+ Cfg = Default()
24
+ Cfg.name = __file__.rsplit(os.sep, maxsplit=1)[-1].lower()
25
+ Storage.wd = os.path.expanduser(f"~/.{Cfg.name}")
26
+
27
+
28
+ class CLI(CLI):
29
+
30
+ def dosay(self, channel, txt):
31
+ print(txt.encode('utf-8', 'replace').decode())
32
+ sys.stdout.flush()
33
+
34
+
35
+ class Console(CLI):
36
+
37
+
38
+ def poll(self) -> Event:
39
+ evt = Event()
40
+ evt.orig = object.__repr__(self)
41
+ evt.txt = input("> ")
42
+ evt.type = "command"
43
+ return evt
44
+
45
+
46
+ def wrap(func) -> None:
47
+ old = None
48
+ try:
49
+ old = termios.tcgetattr(sys.stdin.fileno())
50
+ except termios.error:
51
+ pass
52
+ try:
53
+ func()
54
+ except (EOFError, KeyboardInterrupt):
55
+ print("")
56
+ sys.stdout.flush()
57
+ finally:
58
+ if old:
59
+ termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, old)
60
+
61
+
62
+ def main():
63
+ parse(Cfg, " ".join(sys.argv[1:]))
64
+ if "v" in Cfg.opts:
65
+ dte = time.ctime(time.time()).replace(" ", " ")
66
+ print(f"{Cfg.name.upper()} started {Cfg.opts.upper()} started {dte}")
67
+ Cfg.mod = ",".join((lsmod(modules.__path__[0])))
68
+ if 'c' in Cfg.opts:
69
+ scan(modules, Cfg.mod, True)
70
+ csl = Console()
71
+ csl.start()
72
+ forever()
73
+ scan(modules, Cfg.mod)
74
+ cli = CLI()
75
+ command(Cfg.otxt, cli)
76
+ Errors.show()
77
+
78
+
79
+ if __name__ == "__main__":
80
+ wrap(main)
81
+
libbot-53/bin/botd ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env python3
2
+ # This file is placed in the Public Domain.
3
+ #
4
+ # pylint: disable=C0115,C0116,C0209,C0413,W0201,R0903,W0212,W0105,W0613
5
+
6
+
7
+ "daemon"
8
+
9
+
10
+ import getpass
11
+ import os
12
+ import pwd
13
+ import sys
14
+
15
+
16
+ from bot import Default, Storage, modules, cdir, forever, lsmod, scan
17
+
18
+
19
+ Cfg = Default()
20
+ Cfg.mod = ",".join((lsmod(modules.__path__[0])))
21
+ Cfg.name = "bot"
22
+ Storage.wd = os.path.expanduser(f"~/.{Cfg.name}")
23
+ Cfg.pidfile = os.path.join(Storage.wd, f"{Cfg.name}.pid")
24
+ Cfg.user = getpass.getuser()
25
+
26
+
27
+ def daemon(pidfile, verbose=False):
28
+ pid = os.fork()
29
+ if pid != 0:
30
+ os._exit(0)
31
+ os.setsid()
32
+ pid2 = os.fork()
33
+ if pid2 != 0:
34
+ os._exit(0)
35
+ if not verbose:
36
+ with open('/dev/null', 'r', encoding="utf-8") as sis:
37
+ os.dup2(sis.fileno(), sys.stdin.fileno())
38
+ with open('/dev/null', 'a+', encoding="utf-8") as sos:
39
+ os.dup2(sos.fileno(), sys.stdout.fileno())
40
+ with open('/dev/null', 'a+', encoding="utf-8") as ses:
41
+ os.dup2(ses.fileno(), sys.stderr.fileno())
42
+ os.umask(0)
43
+ os.chdir("/")
44
+ if os.path.exists(pidfile):
45
+ os.unlink(pidfile)
46
+ cdir(os.path.dirname(pidfile))
47
+ with open(pidfile, "w", encoding="utf-8") as fds:
48
+ fds.write(str(os.getpid()))
49
+
50
+
51
+ def privileges(username):
52
+ pwnam = pwd.getpwnam(username)
53
+ os.setgid(pwnam.pw_gid)
54
+ os.setuid(pwnam.pw_uid)
55
+
56
+
57
+ def main():
58
+ if "v" in Cfg.opts:
59
+ dte = time.ctime(time.time()).replace(" ", " ")
60
+ print(f"{Cfg.name.upper()} started {dte} {Cfg.opts.upper()} {Cfg.mod.upper()}")
61
+ print(Cfg)
62
+ daemon(Cfg.pidfile, "v" in Cfg.opts)
63
+ privileges(Cfg.user)
64
+ scan(modules, Cfg.mod, True)
65
+ forever()
66
+
67
+
68
+ main()
@@ -3,7 +3,7 @@
3
3
  # pylint: disable=E0603,E0402,W0401,W0614
4
4
 
5
5
 
6
- "the python3 bot namespace"
6
+ "specification"
7
7
 
8
8
 
9
9
  from .disk import *
@@ -12,17 +12,19 @@ from .object import *
12
12
  from .run import *
13
13
  from .thread import *
14
14
 
15
+
15
16
  def __dir__():
16
17
  return (
17
18
  'Broker',
19
+ 'CLI',
18
20
  'Censor',
19
21
  'Commands',
20
- 'Cfg',
21
- 'CLI',
22
22
  'Default',
23
23
  'Errors',
24
24
  'Event',
25
25
  'Object',
26
+ 'ObjectDecoder',
27
+ 'ObjectEncoder',
26
28
  'Reactor',
27
29
  'Repeater',
28
30
  'Storage',
@@ -32,14 +34,16 @@ def __dir__():
32
34
  'command',
33
35
  'construct',
34
36
  'debug',
37
+ 'disk',
35
38
  'dump',
36
39
  'dumps',
37
40
  'edit',
41
+ 'error',
38
42
  'fetch',
39
- 'find',
43
+ 'find',
40
44
  'fmt',
41
45
  'fns',
42
- 'fntime',
46
+ 'fntime',
43
47
  'forever',
44
48
  'fqn',
45
49
  'hook',
@@ -50,10 +54,10 @@ def __dir__():
50
54
  'last',
51
55
  'launch',
52
56
  'load',
53
- 'loads',
54
- 'lock',
57
+ 'loads',
55
58
  'lsmod',
56
59
  'name',
60
+ 'object',
57
61
  'parse',
58
62
  'read',
59
63
  'scan',
@@ -1,21 +1,24 @@
1
1
  # This file is placed in the Public Domain.
2
2
  #
3
- # pylint: disable=C0112,C0115,C0116,W0105,R0903,E0402,C0209,R1710,C0413,C0103
3
+ # pylint: disable=C,R,W0105,E0402
4
4
 
5
5
 
6
6
  "storage"
7
7
 
8
8
 
9
+ import datetime
9
10
  import inspect
10
11
  import os
12
+ import pathlib
11
13
  import time
14
+ import _thread
12
15
 
13
16
 
14
- from .object import Object, cdir, read, write
15
- from .object import Default, fqn, ident, search, update
17
+ from .object import Object, Default, dump, fqn, items, load, update
18
+ from .parse import spl
16
19
 
17
20
 
18
- "defines"
21
+ lock = _thread.allocate_lock()
19
22
 
20
23
 
21
24
  def __dir__():
@@ -27,14 +30,12 @@ def __dir__():
27
30
  'fntime',
28
31
  'laps',
29
32
  'last',
33
+ 'lsmod',
30
34
  'strip',
31
35
  'sync'
32
36
  )
33
37
 
34
38
 
35
- "storage"
36
-
37
-
38
39
  class Storage(Object):
39
40
 
40
41
  classes = {}
@@ -97,7 +98,9 @@ class Storage(Object):
97
98
  Storage.add(clz)
98
99
 
99
100
 
100
- "utilities"
101
+ def cdir(pth) -> None:
102
+ pth = pathlib.Path(pth)
103
+ os.makedirs(pth, exist_ok=True)
101
104
 
102
105
 
103
106
  def find(mtc, selector=None, index=None) -> []:
@@ -142,6 +145,13 @@ def fntime(daystr) -> float:
142
145
  return timed
143
146
 
144
147
 
148
+ def ident(obj) -> str:
149
+ return os.path.join(
150
+ fqn(obj),
151
+ os.path.join(*str(datetime.datetime.now()).split())
152
+ )
153
+
154
+
145
155
  def laps(seconds, short=True) -> str:
146
156
  txt = ""
147
157
  nsec = float(seconds)
@@ -181,11 +191,19 @@ def laps(seconds, short=True) -> str:
181
191
  return txt
182
192
 
183
193
 
184
- def strip(pth, nmr=3) -> str:
185
- return os.sep.join(pth.split(os.sep)[-nmr:])
194
+ def lsmod(path) -> []:
195
+ if not os.path.exists(path):
196
+ return {}
197
+ for fnm in os.listdir(path):
198
+ if not fnm.endswith(".py"):
199
+ continue
200
+ if fnm in ["__main__.py", "__init__.py"]:
201
+ continue
202
+ yield fnm[:-3]
186
203
 
187
204
 
188
- "methods"
205
+ def strip(pth, nmr=3) -> str:
206
+ return os.sep.join(pth.split(os.sep)[-nmr:])
189
207
 
190
208
 
191
209
  def fetch(obj, pth) -> None:
@@ -207,9 +225,38 @@ def last(obj, selector=None) -> None:
207
225
  return inp[0]
208
226
 
209
227
 
228
+ def read(obj, pth) -> None:
229
+ with lock:
230
+ with open(pth, 'r', encoding='utf-8') as ofile:
231
+ update(obj, load(ofile))
232
+
233
+
234
+ def search(obj, selector) -> bool:
235
+ res = False
236
+ for key, value in items(selector):
237
+ if key not in obj:
238
+ res = False
239
+ break
240
+ for vval in spl(str(value)):
241
+ val = getattr(obj, key, None)
242
+ if str(vval).lower() in str(val).lower():
243
+ res = True
244
+ else:
245
+ res = False
246
+ break
247
+ return res
248
+
249
+
210
250
  def sync(obj, pth=None) -> str:
211
251
  if pth is None:
212
252
  pth = ident(obj)
213
253
  pth2 = Storage.store(pth)
214
254
  write(obj, pth2)
215
255
  return pth
256
+
257
+
258
+ def write(obj, pth) -> None:
259
+ with lock:
260
+ cdir(os.path.dirname(pth))
261
+ with open(pth, 'w', encoding='utf-8') as ofile:
262
+ dump(obj, ofile)
@@ -7,6 +7,7 @@
7
7
 
8
8
 
9
9
  import io
10
+ import traceback
10
11
 
11
12
 
12
13
  from .object import Object
@@ -6,4 +6,4 @@
6
6
  "preimport"
7
7
 
8
8
 
9
- from . import cmd, err, irc, log, mod, rss, shp, tdo, thr, wsh
9
+ from . import cmd, err, irc, log, mod, rss, shp, tdo, thr
@@ -6,7 +6,7 @@
6
6
  "list of commands"
7
7
 
8
8
 
9
- from ..run import Commands
9
+ from bot import Commands
10
10
 
11
11
 
12
12
  def cmd(event):
@@ -9,9 +9,6 @@
9
9
  from bot import Broker, Errors
10
10
 
11
11
 
12
- "commands"
13
-
14
-
15
12
  def err(event):
16
13
  nmr = 0
17
14
  for bot in Broker.objs:
@@ -9,11 +9,7 @@
9
9
  import time
10
10
 
11
11
 
12
- from ..disk import Storage, find, fntime, laps
13
- from ..object import fmt, keys
14
-
15
-
16
- "command"
12
+ from bot import Storage, find, fntime, fmt, keys, laps
17
13
 
18
14
 
19
15
  def fnd(event):
@@ -12,17 +12,21 @@ import os
12
12
  import queue
13
13
  import socket
14
14
  import ssl
15
+ import sys
15
16
  import textwrap
16
17
  import threading
17
18
  import time
18
19
  import _thread
19
20
 
20
21
 
21
- from bot import Broker, Censor, Cfg, Commands, Default, Event, Object, Reactor
22
- from bot import debug, edit, find, fmt, keys, last, launch, sync
22
+ from bot.disk import find, last, sync
23
+ from bot.error import Censor, debug
24
+ from bot.object import Default, Object, edit, fmt, keys
25
+ from bot.run import Broker, Commands, Event, Reactor
26
+ from bot.thread import launch
23
27
 
24
28
 
25
- NAME = Cfg.name or __file__.split(os.sep)[-3].lower()
29
+ NAME = "bot"
26
30
 
27
31
 
28
32
  Censor.words = ["PING", "PONG", "PRIVMSG"]
@@ -9,11 +9,7 @@
9
9
  import time
10
10
 
11
11
 
12
- from ..disk import find, fntime, laps, sync
13
- from ..object import Object
14
-
15
-
16
- "log"
12
+ from bot import Object, find, fntime, laps, sync
17
13
 
18
14
 
19
15
  class Log(Object):
@@ -23,9 +19,6 @@ class Log(Object):
23
19
  self.txt = ''
24
20
 
25
21
 
26
- "command"
27
-
28
-
29
22
  def log(event):
30
23
  if not event.rest:
31
24
  nmr = 0
@@ -3,6 +3,7 @@
3
3
  # pylint: disable=C0115,C0116,C0209,W0212,E1101,W0105,C0413,W0105,R0903,E0401
4
4
  # pylint: disable=E0402
5
5
 
6
+
6
7
  "mailbox"
7
8
 
8
9
 
@@ -10,11 +11,7 @@ import mailbox
10
11
  import os
11
12
 
12
13
 
13
- from ..disk import fqn, sync
14
- from ..object import Object, update
15
-
16
-
17
- "defines"
14
+ from bot import Object, fqn, sync, update
18
15
 
19
16
 
20
17
  bdmonths = [
@@ -50,9 +47,6 @@ monthint = {
50
47
  }
51
48
 
52
49
 
53
- "email"
54
-
55
-
56
50
  class Email(Object):
57
51
 
58
52
  def __init__(self, *args, **kwargs):
@@ -60,9 +54,6 @@ class Email(Object):
60
54
  self.text = ""
61
55
 
62
56
 
63
- "utility"
64
-
65
-
66
57
  def to_date(date):
67
58
  date = date.replace("_", ":")
68
59
  res = date.split()
@@ -121,9 +112,6 @@ def to_date(date):
121
112
  return ddd
122
113
 
123
114
 
124
- "command"
125
-
126
-
127
115
  def mbx(event):
128
116
  if not event.args:
129
117
  event.reply("mbx <path>")
@@ -9,9 +9,6 @@
9
9
  import os
10
10
 
11
11
 
12
- "command"
13
-
14
-
15
12
  def mod(event):
16
13
  path = os.path.join(os.sep, *__file__.split(os.sep)[:-1])
17
14
  modlist = [
@@ -18,9 +18,10 @@ from urllib.error import HTTPError, URLError
18
18
  from urllib.parse import quote_plus, urlencode
19
19
 
20
20
 
21
- from bot import Default, Object, fmt, update
22
- from bot import Broker, Cfg, Repeater, launch
23
- from bot import find, fntime, laps, last, sync
21
+ from bot.disk import find, fntime, laps, last, sync
22
+ from bot.object import Default, Object, fmt, update
23
+ from bot.run import Broker
24
+ from bot.thread import Repeater, launch
24
25
 
25
26
 
26
27
  def init():
@@ -29,6 +30,9 @@ def init():
29
30
  return fetcher
30
31
 
31
32
 
33
+ DEBUG = False
34
+
35
+
32
36
  fetchlock = _thread.allocate_lock()
33
37
 
34
38
 
@@ -153,7 +157,7 @@ class Parser(Object):
153
157
 
154
158
 
155
159
  def getfeed(url, item):
156
- if Cfg.debug:
160
+ if DEBUG:
157
161
  return [Object(), Object()]
158
162
  try:
159
163
  result = geturl(url)
@@ -9,11 +9,7 @@
9
9
  import time
10
10
 
11
11
 
12
- from ..disk import find, fntime, laps, sync
13
- from ..object import Object
14
-
15
-
16
- "shop"
12
+ from bot import Object, find, fntime, laps, sync
17
13
 
18
14
 
19
15
  class Shop(Object):
@@ -29,9 +25,6 @@ class Shop(Object):
29
25
  return len(self.__dict__)
30
26
 
31
27
 
32
- "commands"
33
-
34
-
35
28
  def got(event):
36
29
  if not event.args:
37
30
  return
@@ -9,11 +9,7 @@
9
9
  import time
10
10
 
11
11
 
12
- from ..disk import find, fntime, laps, sync
13
- from ..object import Object
14
-
15
-
16
- "todo"
12
+ from bot import Object, find, fntime, laps, sync
17
13
 
18
14
 
19
15
  class Todo(Object):
@@ -23,9 +19,6 @@ class Todo(Object):
23
19
  self.txt = ''
24
20
 
25
21
 
26
- "commands"
27
-
28
-
29
22
  def dne(event):
30
23
  if not event.args:
31
24
  event.reply("dne <txt>")
@@ -10,19 +10,12 @@ import threading
10
10
  import time
11
11
 
12
12
 
13
- from ..disk import laps
14
- from ..object import Object, update
15
-
16
-
17
- "defines"
13
+ from bot import Object, laps, update
18
14
 
19
15
 
20
16
  STARTTIME = time.time()
21
17
 
22
18
 
23
- "command"
24
-
25
-
26
19
  def thr(event):
27
20
  result = []
28
21
  for thread in sorted(threading.enumerate(), key=lambda x: x.name):
@@ -12,7 +12,7 @@ import sys
12
12
  import time
13
13
 
14
14
 
15
- from bot import Broker, Object, launch, last
15
+ from bot import Broker, Object, last, launch
16
16
 
17
17
 
18
18
  def init():