ct 0.10.8.114__py3-none-any.whl → 0.10.8.116__py3-none-any.whl
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.
- cantools/__init__.py +38 -13
- cantools/_db.py +1 -1
- cantools/cfg.py +13 -0
- cantools/config.py +12 -4
- cantools/db/__init__.py +3 -0
- cantools/db/gae/model.py +1 -2
- cantools/db/wp.py +1 -1
- cantools/scripts/index.py +2 -8
- cantools/scripts/init.py +1 -1
- cantools/scripts/pubsub/actor.py +3 -1
- cantools/scripts/pubsub/bots.py +11 -13
- cantools/scripts/start.py +2 -2
- cantools/util/__init__.py +2 -0
- cantools/util/admin.py +10 -18
- cantools/util/ai/__init__.py +8 -0
- cantools/util/ai/tox/__init__.py +15 -0
- cantools/util/ai/tox/duck.py +80 -0
- cantools/util/ai/tox/fzn.py +22 -0
- cantools/util/ai/tox/g4free.py +73 -0
- cantools/util/ai/vox.py +84 -0
- cantools/util/apper/__init__.py +1 -0
- cantools/util/apper/ander.py +101 -0
- cantools/util/apper/data.py +167 -0
- cantools/util/system.py +2 -23
- cantools/web/__init__.py +6 -2
- cantools/web/bw.py +70 -0
- cantools/web/gae_server.py +1 -6
- cantools/web/util.py +6 -409
- {ct-0.10.8.114.dist-info → ct-0.10.8.116.dist-info}/METADATA +7 -8
- ct-0.10.8.116.dist-info/RECORD +56 -0
- cantools/web/dez_server/__init__.py +0 -1
- cantools/web/dez_server/controller.py +0 -129
- cantools/web/dez_server/cron.py +0 -115
- cantools/web/dez_server/daemons.py +0 -64
- cantools/web/dez_server/mail.py +0 -24
- cantools/web/dez_server/response.py +0 -63
- cantools/web/dez_server/routes.py +0 -21
- cantools/web/dez_server/server.py +0 -229
- cantools/web/dez_server/sms.py +0 -12
- ct-0.10.8.114.dist-info/RECORD +0 -55
- {ct-0.10.8.114.dist-info → ct-0.10.8.116.dist-info}/LICENSE +0 -0
- {ct-0.10.8.114.dist-info → ct-0.10.8.116.dist-info}/WHEEL +0 -0
- {ct-0.10.8.114.dist-info → ct-0.10.8.116.dist-info}/entry_points.txt +0 -0
- {ct-0.10.8.114.dist-info → ct-0.10.8.116.dist-info}/top_level.txt +0 -0
cantools/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = "0.10.8.
|
|
1
|
+
__version__ = "0.10.8.116"
|
|
2
2
|
|
|
3
3
|
from . import util, hooks
|
|
4
4
|
from . import config as cfgmod
|
|
@@ -10,15 +10,40 @@ if config.web.server == "gae":
|
|
|
10
10
|
util.init_gae()
|
|
11
11
|
else:
|
|
12
12
|
util.init_basic()
|
|
13
|
-
from . import geo
|
|
14
|
-
from .scripts import builder,
|
|
15
|
-
|
|
16
|
-
ctstart
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
13
|
+
#from . import geo
|
|
14
|
+
from .scripts import builder, pubsub
|
|
15
|
+
|
|
16
|
+
def ctstart():
|
|
17
|
+
from .scripts import start
|
|
18
|
+
start.go()
|
|
19
|
+
|
|
20
|
+
def ctdeploy():
|
|
21
|
+
from .scripts import deploy
|
|
22
|
+
deploy.run()
|
|
23
|
+
|
|
24
|
+
def ctpubsub():
|
|
25
|
+
pubsub.get_addr_and_start()
|
|
26
|
+
|
|
27
|
+
def ctinit():
|
|
28
|
+
from .scripts import init
|
|
29
|
+
init.parse_and_make()
|
|
30
|
+
|
|
31
|
+
def ctindex():
|
|
32
|
+
from .scripts import index
|
|
33
|
+
index.go()
|
|
34
|
+
|
|
35
|
+
def ctmigrate():
|
|
36
|
+
from .scripts import migrate
|
|
37
|
+
migrate.go()
|
|
38
|
+
|
|
39
|
+
def ctdoc():
|
|
40
|
+
from .scripts import doc
|
|
41
|
+
doc.build()
|
|
42
|
+
|
|
43
|
+
def ctbench():
|
|
44
|
+
from .scripts import bench
|
|
45
|
+
bench.run()
|
|
46
|
+
|
|
47
|
+
def ctutil():
|
|
48
|
+
from .scripts import util
|
|
49
|
+
util.run()
|
cantools/_db.py
CHANGED
|
@@ -69,7 +69,7 @@ def response():
|
|
|
69
69
|
keys = cgi_get("keys", required=False)
|
|
70
70
|
exporter = cgi_get("exporter", default="export")
|
|
71
71
|
if mname:
|
|
72
|
-
order = cgi_get("order",
|
|
72
|
+
order = cgi_get("order", required=False)
|
|
73
73
|
if config.web.server == "gae":
|
|
74
74
|
order = getattr(get_model(mname), order)
|
|
75
75
|
res = get_page(mname, int(cgi_get("limit")), int(cgi_get("offset")), order,
|
cantools/cfg.py
CHANGED
|
@@ -69,6 +69,7 @@ cfg = {
|
|
|
69
69
|
"protocol": "http",
|
|
70
70
|
"xorigin": False,
|
|
71
71
|
"shield": False,
|
|
72
|
+
"debug": False,
|
|
72
73
|
"csp": None,
|
|
73
74
|
"log": None,
|
|
74
75
|
"errlog": None,
|
|
@@ -78,6 +79,9 @@ cfg = {
|
|
|
78
79
|
"blacklist": [],
|
|
79
80
|
"whitelist": []
|
|
80
81
|
},
|
|
82
|
+
"proxy": { # user, gateway, minport, maxport
|
|
83
|
+
"active": False
|
|
84
|
+
},
|
|
81
85
|
"ssl": {
|
|
82
86
|
"verify": True,
|
|
83
87
|
"certfile": None,
|
|
@@ -97,6 +101,15 @@ cfg = {
|
|
|
97
101
|
"alter": False, # add new columns to tables - sqlite only!
|
|
98
102
|
"echo": False,
|
|
99
103
|
"public": True, # read from db without credentials via _db.py web handler
|
|
104
|
+
"nopoly": False,
|
|
105
|
+
"jsontext": True,
|
|
106
|
+
"arraytext": True,
|
|
107
|
+
"stringsize": 500,
|
|
108
|
+
"flatkeysize": 80,
|
|
109
|
+
"index": {
|
|
110
|
+
"key": False,
|
|
111
|
+
"named": False
|
|
112
|
+
},
|
|
100
113
|
"pool": {
|
|
101
114
|
"null": True,
|
|
102
115
|
"size": 10,
|
cantools/config.py
CHANGED
|
@@ -40,6 +40,9 @@ gcpath = os.path.join(os.path.expanduser("~"), "ct.cfg")
|
|
|
40
40
|
if os.path.isfile(gcpath):
|
|
41
41
|
print("loading global configuration at: %s"%(gcpath,))
|
|
42
42
|
lines = read(gcpath, True) + lines
|
|
43
|
+
if os.path.isfile("extra.cfg"):
|
|
44
|
+
print("loading extra configuration at: extra.cfg")
|
|
45
|
+
lines = lines + read("extra.cfg", True)
|
|
43
46
|
for line in lines:
|
|
44
47
|
if line.startswith("#"):
|
|
45
48
|
continue
|
|
@@ -57,9 +60,9 @@ for line in lines:
|
|
|
57
60
|
items.append([key, val])
|
|
58
61
|
|
|
59
62
|
for key, val in items:
|
|
60
|
-
if key in ["ENCODE", "DB_ECHO", "DB_PUBLIC", "DB_REFCOUNT", "DB_CACHE", "DB_POOL_NULL", "GEO_TEST", "REL_VERBOSE", "REL_LOUDLISTEN", "MEMCACHE_REQUEST", "MEMCACHE_DB", "PUBSUB_ECHO", "PUBSUB_META", "PUBSUB_B64", "SSL_VERIFY", "ADMIN_MONITOR_LOG", "WEB_XORIGIN", "LOG_TIMESTAMP", "BUILD_PROD_CLOSURE", "BUILD_PROD_B64", "GMAILER", "MAILHTML", "MAILOUD"]:
|
|
63
|
+
if key in ["ENCODE", "DB_ECHO", "DB_PUBLIC", "DB_REFCOUNT", "DB_CACHE", "DB_JSONTEXT", "DB_ARRAYTEXT", "DB_NOPOLY", "DB_POOL_NULL", "DB_INDEX_KEYS", "DB_INDEX_NAMED", "PROXY_ACTIVE", "GEO_TEST", "REL_VERBOSE", "REL_LOUDLISTEN", "MEMCACHE_REQUEST", "MEMCACHE_DB", "PUBSUB_ECHO", "PUBSUB_META", "PUBSUB_B64", "SSL_VERIFY", "ADMIN_MONITOR_LOG", "WEB_DEBUG", "WEB_XORIGIN", "LOG_TIMESTAMP", "BUILD_PROD_CLOSURE", "BUILD_PROD_B64", "GMAILER", "MAILHTML", "MAILOUD"]:
|
|
61
64
|
val = val == "True"
|
|
62
|
-
elif key in ["PUBSUB_HISTORY", "MEMPAD", "WEB_SHIELD_CHUNK", "WEB_SHIELD_LIMIT", "WEB_SHIELD_INTERVAL", "MEMCACHE_PROX_TIMEOUT", "DB_POOL_SIZE", "DB_POOL_OVERFLOW", "DB_POOL_RECYCLE", "LOG_OPENFILES", "LOG_TRACEMALLOC", "MAILSCANTICK"]:
|
|
65
|
+
elif key in ["PUBSUB_HISTORY", "MEMPAD", "WEB_SHIELD_CHUNK", "WEB_SHIELD_LIMIT", "WEB_SHIELD_INTERVAL", "PROXY_MINPORT", "PROXY_MAXPORT", "MEMCACHE_PROX_TIMEOUT", "DB_POOL_SIZE", "DB_POOL_OVERFLOW", "DB_POOL_RECYCLE", "DB_STRINGSIZE", "DB_FLATKEYSIZE", "LOG_OPENFILES", "LOG_TRACEMALLOC", "MAILSCANTICK"]:
|
|
63
66
|
val = int(val)
|
|
64
67
|
elif key in ["REL_SLEEP", "REL_TURBO"]:
|
|
65
68
|
val = float(val)
|
|
@@ -92,11 +95,16 @@ for key, val in items:
|
|
|
92
95
|
c.update(target, val)
|
|
93
96
|
|
|
94
97
|
config.update("cache", pc)
|
|
95
|
-
config.db.
|
|
98
|
+
if not config.db.main:
|
|
99
|
+
config.db.update("main", config.db[config.web.server])
|
|
100
|
+
if "DBPW" in config.db.main:
|
|
101
|
+
config.db.update("main", config.db.main.replace("DBPW", config.cache("database password? ")))
|
|
96
102
|
for prop in ["deep", "flush", "timestamp", "allow"]:
|
|
97
103
|
confyg.log.update(prop, config.log[prop])
|
|
98
|
-
for prop in ["cache", "refcount", "main", "test", "blob", "alter", "echo"]:
|
|
104
|
+
for prop in ["cache", "refcount", "main", "test", "blob", "alter", "echo", "jsontext", "arraytext", "stringsize", "flatkeysize"]:
|
|
99
105
|
dbcfg.update(prop, config.db[prop])
|
|
106
|
+
for prop in ["key", "named"]:
|
|
107
|
+
dbcfg.index.update(prop, config.db.index[prop])
|
|
100
108
|
for prop in ["null", "size", "recycle", "overflow"]:
|
|
101
109
|
dbcfg.pool.update(prop, config.db.pool[prop])
|
|
102
110
|
|
cantools/db/__init__.py
CHANGED
|
@@ -5,12 +5,15 @@ if config.web.server == "gae":
|
|
|
5
5
|
from .gae.model import *
|
|
6
6
|
elif config.web.server == "dez":
|
|
7
7
|
from rel import tick
|
|
8
|
+
if not config.db.nopoly:
|
|
9
|
+
from databae.poly import ModelBase, TimeStampedBase
|
|
8
10
|
from databae import *
|
|
9
11
|
from cantools.web import set_pre_close, cgi_dump
|
|
10
12
|
def scoper(threadId):
|
|
11
13
|
if threadId == "MainThread":
|
|
12
14
|
threadId = tick()
|
|
13
15
|
return "%s%s"%(threadId, cgi_dump())
|
|
16
|
+
session = seshman.get()
|
|
14
17
|
set_scoper(scoper)
|
|
15
18
|
set_pre_close(seshman.close)
|
|
16
19
|
else:
|
cantools/db/gae/model.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
from .properties import *
|
|
3
|
-
from six import with_metaclass
|
|
4
3
|
|
|
5
4
|
class CTMeta(ndb.MetaModel):
|
|
6
5
|
def __new__(cls, name, bases, attrs):
|
|
@@ -22,7 +21,7 @@ class CTMeta(ndb.MetaModel):
|
|
|
22
21
|
modelsubs[lname] = super(CTMeta, cls).__new__(cls, name, bases, attrs)
|
|
23
22
|
return modelsubs[lname]
|
|
24
23
|
|
|
25
|
-
class ModelBase(
|
|
24
|
+
class ModelBase(ndb.Model, metaclass=CTMeta):
|
|
26
25
|
index = Integer()
|
|
27
26
|
|
|
28
27
|
def __eq__(self, other):
|
cantools/db/wp.py
CHANGED
cantools/scripts/index.py
CHANGED
|
@@ -44,16 +44,9 @@ Run this in 'index' mode on a database with lots of missing index values.
|
|
|
44
44
|
from getpass import getpass
|
|
45
45
|
from optparse import OptionParser
|
|
46
46
|
from fyg.util import log, error, batch
|
|
47
|
-
from cantools.db import get_schema, get_model, put_multi, delete_multi, unpad_key
|
|
47
|
+
from cantools.db import get_schema, get_model, put_multi, delete_multi, unpad_key, session, func
|
|
48
48
|
from cantools.web import fetch
|
|
49
49
|
from cantools import config
|
|
50
|
-
if config.web.server == "dez":
|
|
51
|
-
from cantools.db import session, func, refresh_counter
|
|
52
|
-
|
|
53
|
-
try:
|
|
54
|
-
input = raw_input # py2/3 compatibility
|
|
55
|
-
except NameError:
|
|
56
|
-
pass
|
|
57
50
|
|
|
58
51
|
counts = { "_counters": 0 }
|
|
59
52
|
RETRIES = 5
|
|
@@ -93,6 +86,7 @@ def refmap():
|
|
|
93
86
|
return rmap
|
|
94
87
|
|
|
95
88
|
def do_batch(chunk, reference):
|
|
89
|
+
from databae.lookup import refresh_counter
|
|
96
90
|
log("refreshing %s %s keys"%(len(chunk), reference), 1)
|
|
97
91
|
i = 0
|
|
98
92
|
rc = []
|
cantools/scripts/init.py
CHANGED
|
@@ -248,7 +248,7 @@ class Builder(object):
|
|
|
248
248
|
for dname, fnames in list(mod.init.syms.items()):
|
|
249
249
|
for fname in fnames:
|
|
250
250
|
sym(os.path.join(mod.__ct_mod_path__, dname, fname),
|
|
251
|
-
os.path.join(dname, fname))
|
|
251
|
+
os.path.join(dname, fname.strip("./")))
|
|
252
252
|
|
|
253
253
|
def vcignore(self):
|
|
254
254
|
log("configuring version control path exclusion", 1)
|
cantools/scripts/pubsub/actor.py
CHANGED
cantools/scripts/pubsub/bots.py
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import datetime, json, os
|
|
2
2
|
from cantools import config
|
|
3
3
|
from cantools.util import log, write
|
|
4
|
-
from cantools.web import fetch, send_mail
|
|
5
4
|
from .actor import Actor
|
|
6
|
-
try:
|
|
7
|
-
import psutil
|
|
8
|
-
except ImportError as e:
|
|
9
|
-
pass # google crap engine (get it if you need it!)
|
|
10
|
-
from six import with_metaclass
|
|
11
5
|
|
|
12
6
|
class BotMeta(type):
|
|
13
7
|
def __new__(cls, name, bases, attrs):
|
|
@@ -17,7 +11,7 @@ class BotMeta(type):
|
|
|
17
11
|
config.pubsub.bots.update(name.lower(), bc)
|
|
18
12
|
return bc
|
|
19
13
|
|
|
20
|
-
class Bot(
|
|
14
|
+
class Bot(Actor, metaclass=BotMeta):
|
|
21
15
|
num = 0
|
|
22
16
|
def __init__(self, server, channel, name=None):
|
|
23
17
|
Bot.num += 1
|
|
@@ -26,7 +20,7 @@ class Bot(with_metaclass(BotMeta, Actor)):
|
|
|
26
20
|
self.channel = channel # often we only care about one channel
|
|
27
21
|
self.channels = set()
|
|
28
22
|
self._set_defaults()
|
|
29
|
-
log("Bot Spawned
|
|
23
|
+
self.log("Bot Spawned")
|
|
30
24
|
channel.join(self)
|
|
31
25
|
self.server.bots[self.name] = self
|
|
32
26
|
|
|
@@ -41,7 +35,7 @@ class Bot(with_metaclass(BotMeta, Actor)):
|
|
|
41
35
|
|
|
42
36
|
def _default_handler(self, action):
|
|
43
37
|
def _h(*args):
|
|
44
|
-
log(
|
|
38
|
+
self.log("handling", action, ":", args)
|
|
45
39
|
return _h
|
|
46
40
|
|
|
47
41
|
def _set_defaults(self):
|
|
@@ -74,25 +68,29 @@ class Monitor(Bot):
|
|
|
74
68
|
os.mkdir(dp)
|
|
75
69
|
return os.path.join(dp, str(n.hour))
|
|
76
70
|
|
|
77
|
-
def
|
|
71
|
+
def report(self, data):
|
|
78
72
|
self.pub(data)
|
|
79
73
|
if config.admin.monitor.log:
|
|
80
74
|
write(data, self._datedir(), True, append=True, newline=True)
|
|
81
75
|
|
|
82
76
|
def _cpu(self):
|
|
77
|
+
import psutil
|
|
78
|
+
from cantools.web import send_mail
|
|
83
79
|
c = self.current["cpu"] = psutil.cpu_percent()
|
|
84
80
|
if self.alert.get("cpu"):
|
|
85
81
|
if c < config.admin.monitor.thresholds.cpu:
|
|
86
82
|
del self.alert["cpu"]
|
|
87
|
-
log("CPU calmed down")
|
|
83
|
+
self.log("CPU calmed down")
|
|
88
84
|
send_mail(config.admin.contacts, subject="High CPU", body="just ended")
|
|
89
85
|
else:
|
|
90
86
|
if c >= config.admin.monitor.thresholds.cpu:
|
|
91
87
|
self.alert["cpu"] = True
|
|
92
|
-
log("CPU just started going crazy")
|
|
88
|
+
self.log("CPU just started going crazy")
|
|
93
89
|
send_mail(config.admin.contacts, subject="High CPU", body="just started")
|
|
94
90
|
|
|
95
91
|
def _tick(self):
|
|
92
|
+
import psutil
|
|
93
|
+
from cantools.web import fetch
|
|
96
94
|
self._cpu()
|
|
97
95
|
dioc = psutil.disk_io_counters()
|
|
98
96
|
nioc = psutil.net_io_counters()
|
|
@@ -139,5 +137,5 @@ class Monitor(Bot):
|
|
|
139
137
|
if config.admin.monitor.proxy:
|
|
140
138
|
data["ips"]["proxy"] = fetch(config.admin.host, "/_report",
|
|
141
139
|
config.admin.monitor.proxy, True)["ips"]
|
|
142
|
-
self.
|
|
140
|
+
self.report(data)
|
|
143
141
|
return True
|
cantools/scripts/start.py
CHANGED
|
@@ -44,8 +44,8 @@ def go():
|
|
|
44
44
|
print(cmd)
|
|
45
45
|
subprocess.call(cmd, shell=True)
|
|
46
46
|
elif options.web_backend == "dez":
|
|
47
|
-
from cantools.web import
|
|
48
|
-
|
|
47
|
+
from cantools.web import run_bw
|
|
48
|
+
run_bw()
|
|
49
49
|
else:
|
|
50
50
|
error("invalid web_backend: %s"%(options.web_backend,))
|
|
51
51
|
|
cantools/util/__init__.py
CHANGED
|
@@ -7,9 +7,11 @@ from .media import transcode, segment, hlsify, shouldMoveMoov, crop, resizep2, t
|
|
|
7
7
|
from .admin import certs, screener
|
|
8
8
|
from .apper import android
|
|
9
9
|
from .ai import tox, vox, tellme
|
|
10
|
+
from .package import pipper
|
|
10
11
|
|
|
11
12
|
def init_basic():
|
|
12
13
|
os.path.isdir("emails") and sys.path.append("emails")
|
|
14
|
+
sys.path.insert(0, ".") # for dynamically loading modules
|
|
13
15
|
|
|
14
16
|
def init_rel():
|
|
15
17
|
import rel
|
cantools/util/admin.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os, sys, rel, time, datetime
|
|
2
|
+
from fyg.util import pcount, pcheck, pkill
|
|
2
3
|
from cantools.util import cmd, output, error, log, set_log, close_log, read, write, confirm, rm
|
|
3
4
|
|
|
4
5
|
coremods = ["screen", "ctstart", "ctpubsub", "ctutil", "ctinit", "dez_reverse_proxy", "dez_websocket_proxy"]
|
|
@@ -65,19 +66,6 @@ def certs(dpath="/root", sname=None):
|
|
|
65
66
|
log("goodbye")
|
|
66
67
|
close_log()
|
|
67
68
|
|
|
68
|
-
def pcount(pname):
|
|
69
|
-
log("checking count: %s"%(pname,), important=True)
|
|
70
|
-
num = int(output("ps -ef | grep %s | egrep -v 'screener|pcount|grep' | wc -l"%(pname,)))
|
|
71
|
-
log("%s count: %s"%(pname, num), 1)
|
|
72
|
-
return num
|
|
73
|
-
|
|
74
|
-
def pcheck(pname, target, starter):
|
|
75
|
-
if target and pcount(pname) != target:
|
|
76
|
-
log("not enough %s processes - restarting screen!"%(pname,), 1)
|
|
77
|
-
log(output("screen -Q windows"), important=True)
|
|
78
|
-
cmd("killall screen; %s"%(starter,))
|
|
79
|
-
return True
|
|
80
|
-
|
|
81
69
|
def binpath(bpath="/usr/bin/"):
|
|
82
70
|
log("checking %s core modules"%(len(coremods),), important=True)
|
|
83
71
|
missings = []
|
|
@@ -295,11 +283,12 @@ def upcheck(*procs):
|
|
|
295
283
|
log("goodbye")
|
|
296
284
|
close_log()
|
|
297
285
|
|
|
298
|
-
def vitals(clean=False, thresh=90, dpath="."):
|
|
286
|
+
def vitals(clean=False, thresh=90, dpath=".", conlim=0):
|
|
287
|
+
from cantools.web import email_admins
|
|
299
288
|
if clean == "False":
|
|
300
289
|
clean = False
|
|
301
290
|
thresh = int(thresh)
|
|
302
|
-
|
|
291
|
+
conlim = int(conlim)
|
|
303
292
|
os.chdir(dpath)
|
|
304
293
|
set_log("cron-vitals.log")
|
|
305
294
|
log("scanning vitals", important=True)
|
|
@@ -310,9 +299,12 @@ def vitals(clean=False, thresh=90, dpath="."):
|
|
|
310
299
|
lz.append("inode usage: %s%%"%(inodes,))
|
|
311
300
|
memuse = float(output("free | grep Mem | awk '{print $3/$2 * 100.0}'"))
|
|
312
301
|
lz.append("memory usage: %s%%"%(memuse,))
|
|
302
|
+
if conlim:
|
|
303
|
+
concount = int(output("lsof -i | wc -l"))
|
|
304
|
+
lz.append("connections: %s"%(concount,))
|
|
313
305
|
for l in lz:
|
|
314
306
|
log(l)
|
|
315
|
-
if hdrive > thresh or inodes > thresh or memuse > thresh:
|
|
307
|
+
if hdrive > thresh or inodes > thresh or memuse > thresh or (conlim and concount > conlim):
|
|
316
308
|
log("threshold exceeded - notifying admins")
|
|
317
309
|
if hdrive > thresh and clean:
|
|
318
310
|
log("cleaning up!")
|
|
@@ -333,9 +325,9 @@ def sslredirect(port=80):
|
|
|
333
325
|
def blacklist(ip):
|
|
334
326
|
if not confirm("blacklist %s?"%(ip,)):
|
|
335
327
|
return log("okay, bye!")
|
|
336
|
-
from cantools.web import
|
|
328
|
+
from cantools.web import shield
|
|
337
329
|
from cantools import config
|
|
338
|
-
|
|
330
|
+
shield.setBlacklist()
|
|
339
331
|
blist = config.web.blacklist.obj()
|
|
340
332
|
if ip in blist:
|
|
341
333
|
return log("%s is already blacklisted! reason: %s"%(ip, blist[ip]))
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from .tox import tox, g4chat, g4image, fzn, duck, pb
|
|
2
|
+
from .vox import vox, kvoices
|
|
3
|
+
|
|
4
|
+
def tellme(prompt, voice="random", identity="gpt-4o-mini", filename="tts", unsaid=False, silent=False):
|
|
5
|
+
print("tellme(%s, %s, %s)"%(voice, identity, filename), prompt)
|
|
6
|
+
resp = tox(prompt, identity)
|
|
7
|
+
unsaid or vox(resp, voice, filename=filename, say=not silent)
|
|
8
|
+
return resp
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from .duck import duck # not currently working :'(
|
|
2
|
+
from .g4free import g4chat, g4image, gchatters
|
|
3
|
+
from .fzn import fzn
|
|
4
|
+
|
|
5
|
+
# pb
|
|
6
|
+
def pb(question, botname, appid, userkey):
|
|
7
|
+
from pb_py import main as PB
|
|
8
|
+
resp = PB.talk(userkey, appid, "aiaas.pandorabots.com", botname, question)["response"]
|
|
9
|
+
return resp.split("[URL]")[0]
|
|
10
|
+
|
|
11
|
+
# wrapper
|
|
12
|
+
def tox(statement, identity="Anonymous", name=None, mood=None, asker=None, options=None):
|
|
13
|
+
if identity in gchatters:
|
|
14
|
+
return g4chat(statement, identity)
|
|
15
|
+
return fzn(statement, identity, name, mood, asker, options)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import random
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
|
|
4
|
+
def nosay():
|
|
5
|
+
return random.choice([
|
|
6
|
+
"i'm confused",
|
|
7
|
+
"you broke me",
|
|
8
|
+
"you're killing me bro",
|
|
9
|
+
"that question ruined me",
|
|
10
|
+
"your words somehow fried my circuits",
|
|
11
|
+
"i literally don't know how to answer that"
|
|
12
|
+
])
|
|
13
|
+
|
|
14
|
+
def notyet():
|
|
15
|
+
return random.choice([
|
|
16
|
+
"slow down",
|
|
17
|
+
"not so fast",
|
|
18
|
+
"wait a minute",
|
|
19
|
+
"take your time",
|
|
20
|
+
"slow your roll",
|
|
21
|
+
"i need a moment",
|
|
22
|
+
"hold your horses"
|
|
23
|
+
])
|
|
24
|
+
|
|
25
|
+
# ddg
|
|
26
|
+
DDGAI = {
|
|
27
|
+
"bot": None,
|
|
28
|
+
"last": None
|
|
29
|
+
}
|
|
30
|
+
DUX = ["gpt-4o-mini", "llama-3.3-70b", "claude-3-haiku", "o3-mini", "mistral-small-3"]
|
|
31
|
+
OLDUX = ["o3-mini", "gpt-4o-mini", "claude-3-haiku", "llama-3.1-70b", "mixtral-8x7b"]
|
|
32
|
+
delimiases = {
|
|
33
|
+
"False": False,
|
|
34
|
+
True: "\n",
|
|
35
|
+
"True": "\n",
|
|
36
|
+
"LINE": "\n",
|
|
37
|
+
"PARAGRAPH": "\n",
|
|
38
|
+
"SENTENCE": ".",
|
|
39
|
+
"PHRASE": [".", "!", "?"]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
def ddgai():
|
|
43
|
+
if not DDGAI["bot"]:
|
|
44
|
+
from duckai import DuckAI
|
|
45
|
+
DDGAI["bot"] = DuckAI()
|
|
46
|
+
return DDGAI["bot"]
|
|
47
|
+
|
|
48
|
+
def toosoon():
|
|
49
|
+
now = datetime.now()
|
|
50
|
+
if DDGAI["last"] and (now - DDGAI["last"]).seconds < 15:
|
|
51
|
+
return True
|
|
52
|
+
DDGAI["last"] = now
|
|
53
|
+
|
|
54
|
+
def duck(prompt, model="gpt-4o-mini", shorten=False, strip=False, timeout=30):
|
|
55
|
+
if toosoon():
|
|
56
|
+
return notyet()
|
|
57
|
+
try:
|
|
58
|
+
resp = ddgai().chat(prompt, model, int(timeout))
|
|
59
|
+
except:
|
|
60
|
+
resp = nosay()
|
|
61
|
+
print(resp)
|
|
62
|
+
if shorten in delimiases:
|
|
63
|
+
shorten = delimiases[shorten]
|
|
64
|
+
if shorten:
|
|
65
|
+
if type(shorten) is not list:
|
|
66
|
+
shorten = [shorten]
|
|
67
|
+
for sho in shorten:
|
|
68
|
+
resp = resp.split(sho).pop(0)
|
|
69
|
+
print("shortened to:")
|
|
70
|
+
print(resp)
|
|
71
|
+
if strip:
|
|
72
|
+
resp = resp.replace("\n", " ").replace(" & ", " and ")
|
|
73
|
+
while " <" in resp and "> " in resp:
|
|
74
|
+
resp = resp[:resp.index(" <") + 1] + resp[resp.index("> ") + 1:]
|
|
75
|
+
while "```" in resp:
|
|
76
|
+
start = resp.index("```") + 3
|
|
77
|
+
resp = resp[:start] + resp[resp.index("```", start) + 3:]
|
|
78
|
+
print("stripped to:")
|
|
79
|
+
print(resp)
|
|
80
|
+
return resp
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# aiio
|
|
2
|
+
afcfg = {
|
|
3
|
+
"host": "ai.fzn.party",
|
|
4
|
+
"path": "_respond",
|
|
5
|
+
"proto": "https"
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
def fzn(statement, identity="Anonymous", name=None, mood=None, asker=None, options=None):
|
|
9
|
+
from cantools.web import post
|
|
10
|
+
params = {
|
|
11
|
+
"identity": identity,
|
|
12
|
+
"statement": statement,
|
|
13
|
+
"options": options,
|
|
14
|
+
"mood": mood,
|
|
15
|
+
"name": name,
|
|
16
|
+
"asker": asker
|
|
17
|
+
}
|
|
18
|
+
fu = "%s://%s/%s"%(afcfg["proto"], afcfg["host"], afcfg["path"])
|
|
19
|
+
print("fzn", fu, params)
|
|
20
|
+
resp = post(fu, data=params, ctjson=True)
|
|
21
|
+
print(resp)
|
|
22
|
+
return resp
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
class G4F(object):
|
|
3
|
+
def __init__(self, log=print):
|
|
4
|
+
self.logger = log
|
|
5
|
+
self.client = None
|
|
6
|
+
|
|
7
|
+
def log(self, *msg):
|
|
8
|
+
self.logger("G4F", *msg)
|
|
9
|
+
|
|
10
|
+
def getClient(self):
|
|
11
|
+
if not self.client:
|
|
12
|
+
self.log("setting up client")
|
|
13
|
+
from g4f.client import Client
|
|
14
|
+
self.client = Client()
|
|
15
|
+
return self.client
|
|
16
|
+
|
|
17
|
+
def chat(self, prompt, model="gpt-4o-mini", short=True):
|
|
18
|
+
self.log("chat(%s)"%(model,), prompt)
|
|
19
|
+
messages = [{ "role": "user", "content": prompt }]
|
|
20
|
+
short and messages.insert(0, {
|
|
21
|
+
"role": "user",
|
|
22
|
+
"content": "one sentence responses please"
|
|
23
|
+
})
|
|
24
|
+
return self.getClient().chat.completions.create(
|
|
25
|
+
model=model,
|
|
26
|
+
messages=messages
|
|
27
|
+
).choices[0].message.content
|
|
28
|
+
|
|
29
|
+
def image(self, prompt, model="flux"):
|
|
30
|
+
self.log("image(%s)"%(model,), prompt)
|
|
31
|
+
return self.getClient().images.generate(
|
|
32
|
+
model=model,
|
|
33
|
+
prompt=prompt,
|
|
34
|
+
response_format="url"
|
|
35
|
+
).data[0].url
|
|
36
|
+
|
|
37
|
+
def __call__(self, action, prompt, model):
|
|
38
|
+
self.log("calling", action, "with", model, ":", prompt)
|
|
39
|
+
resp = getattr(self, action)(prompt, model)
|
|
40
|
+
self.log("got", resp)
|
|
41
|
+
return resp
|
|
42
|
+
|
|
43
|
+
gchatters = ["gpt-4o-mini", "gpt-4o", "gpt-4.1", "deepseek-v3"]
|
|
44
|
+
gimagers = ["flux", "dalle-3", "gpt-image"]
|
|
45
|
+
VAGENT = None
|
|
46
|
+
g4fer = G4F()
|
|
47
|
+
|
|
48
|
+
def vagent():
|
|
49
|
+
global VAGENT
|
|
50
|
+
if not VAGENT:
|
|
51
|
+
from venvr import getagent
|
|
52
|
+
VAGENT = getagent("g4f", [{
|
|
53
|
+
"requirements": "requirements-slim.txt",
|
|
54
|
+
"git": "xtekky/gpt4free",
|
|
55
|
+
"sym": "g4f"
|
|
56
|
+
}])
|
|
57
|
+
VAGENT.register(G4F)
|
|
58
|
+
return VAGENT
|
|
59
|
+
|
|
60
|
+
def g4do(action, prompt, model):
|
|
61
|
+
try:
|
|
62
|
+
import g4f
|
|
63
|
+
print("found g4f")
|
|
64
|
+
return g4fer(action, prompt, model)
|
|
65
|
+
except:
|
|
66
|
+
print("no g4f - using venvr")
|
|
67
|
+
return vagent().run("G4F", action, prompt, model)
|
|
68
|
+
|
|
69
|
+
def g4image(prompt, model="flux"):
|
|
70
|
+
return g4do("image", prompt, model)
|
|
71
|
+
|
|
72
|
+
def g4chat(prompt, model="gpt-4o-mini"):
|
|
73
|
+
return g4do("chat", prompt, model)
|