ct 0.10.8.114__py3-none-any.whl → 0.10.8.115__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 CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "0.10.8.114"
1
+ __version__ = "0.10.8.115"
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, deploy, init, pubsub, start, index, migrate, doc, bench, util
15
-
16
- ctstart = start.go
17
- ctdeploy = deploy.run
18
- ctpubsub = pubsub.get_addr_and_start
19
- ctinit = init.parse_and_make
20
- ctindex = index.go
21
- ctmigrate = migrate.go
22
- ctdoc = doc.build
23
- ctbench = bench.run
24
- ctutil = util.run
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", default="index")
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
@@ -57,9 +57,9 @@ for line in lines:
57
57
  items.append([key, val])
58
58
 
59
59
  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"]:
60
+ 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
61
  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"]:
62
+ 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
63
  val = int(val)
64
64
  elif key in ["REL_SLEEP", "REL_TURBO"]:
65
65
  val = float(val)
@@ -92,11 +92,16 @@ for key, val in items:
92
92
  c.update(target, val)
93
93
 
94
94
  config.update("cache", pc)
95
- config.db.update("main", config.db[config.web.server])
95
+ if not config.db.main:
96
+ config.db.update("main", config.db[config.web.server])
97
+ if "DBPW" in config.db.main:
98
+ config.db.update("main", config.db.main.replace("DBPW", config.cache("database password? ")))
96
99
  for prop in ["deep", "flush", "timestamp", "allow"]:
97
100
  confyg.log.update(prop, config.log[prop])
98
- for prop in ["cache", "refcount", "main", "test", "blob", "alter", "echo"]:
101
+ for prop in ["cache", "refcount", "main", "test", "blob", "alter", "echo", "jsontext", "arraytext", "stringsize", "flatkeysize"]:
99
102
  dbcfg.update(prop, config.db[prop])
103
+ for prop in ["key", "named"]:
104
+ dbcfg.index.update(prop, config.db.index[prop])
100
105
  for prop in ["null", "size", "recycle", "overflow"]:
101
106
  dbcfg.pool.update(prop, config.db.pool[prop])
102
107
 
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(with_metaclass(CTMeta, ndb.Model)):
24
+ class ModelBase(ndb.Model, metaclass=CTMeta):
26
25
  index = Integer()
27
26
 
28
27
  def __eq__(self, other):
cantools/db/wp.py CHANGED
@@ -45,7 +45,7 @@ def trydb(attempts=5, wait=0.4):
45
45
  db = setdb()
46
46
  if db:
47
47
  return db
48
- log("trydb failed retry #" + attempt, important=True)
48
+ log("trydb failed retry #%s"%(attempt,), important=True)
49
49
  time.sleep(wait)
50
50
 
51
51
  def getdb(subdb=False):
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)
@@ -1,4 +1,6 @@
1
- class Actor(object):
1
+ from fyg.util import Named
2
+
3
+ class Actor(Named):
2
4
  def data(self):
3
5
  return {
4
6
  "name": self.name,
@@ -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(with_metaclass(BotMeta, Actor)):
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: '%s'"%(self.name,), 2)
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('Bot %s handling %s: "%s"'%(self.name, action, json.dumps(args)), 3)
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 log(self, data):
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.log(data)
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 run_dez_webserver
48
- run_dez_webserver()
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
@@ -78,6 +78,20 @@ def pcheck(pname, target, starter):
78
78
  cmd("killall screen; %s"%(starter,))
79
79
  return True
80
80
 
81
+ def pkill(pname, force=False):
82
+ pblock = output("ps -ef | grep %s | egrep -v 'screener|pkill|grep'"%(pname,))
83
+ if not pblock:
84
+ log("no '%s' processes!"%(pname,))
85
+ else:
86
+ plines = pblock.split("\n")
87
+ log("found %s '%s' processes"%(len(plines), pname), important=True)
88
+ if plines:
89
+ procs = [[w for w in line.split(" ") if w][1] for line in plines]
90
+ if force or confirm("kill %s '%s' processes"%(len(procs), pname)):
91
+ for proc in procs:
92
+ cmd("kill -9 %s"%(proc,))
93
+ log("goodbye")
94
+
81
95
  def binpath(bpath="/usr/bin/"):
82
96
  log("checking %s core modules"%(len(coremods),), important=True)
83
97
  missings = []
@@ -295,11 +309,12 @@ def upcheck(*procs):
295
309
  log("goodbye")
296
310
  close_log()
297
311
 
298
- def vitals(clean=False, thresh=90, dpath="."):
312
+ def vitals(clean=False, thresh=90, dpath=".", conlim=0):
313
+ from cantools.web import email_admins
299
314
  if clean == "False":
300
315
  clean = False
301
316
  thresh = int(thresh)
302
- from cantools.web import email_admins
317
+ conlim = int(conlim)
303
318
  os.chdir(dpath)
304
319
  set_log("cron-vitals.log")
305
320
  log("scanning vitals", important=True)
@@ -310,9 +325,12 @@ def vitals(clean=False, thresh=90, dpath="."):
310
325
  lz.append("inode usage: %s%%"%(inodes,))
311
326
  memuse = float(output("free | grep Mem | awk '{print $3/$2 * 100.0}'"))
312
327
  lz.append("memory usage: %s%%"%(memuse,))
328
+ if conlim:
329
+ concount = int(output("lsof -i | wc -l"))
330
+ lz.append("connections: %s"%(concount,))
313
331
  for l in lz:
314
332
  log(l)
315
- if hdrive > thresh or inodes > thresh or memuse > thresh:
333
+ if hdrive > thresh or inodes > thresh or memuse > thresh or (conlim and concount > conlim):
316
334
  log("threshold exceeded - notifying admins")
317
335
  if hdrive > thresh and clean:
318
336
  log("cleaning up!")
@@ -333,9 +351,9 @@ def sslredirect(port=80):
333
351
  def blacklist(ip):
334
352
  if not confirm("blacklist %s?"%(ip,)):
335
353
  return log("okay, bye!")
336
- from cantools.web import controller
354
+ from cantools.web import shield
337
355
  from cantools import config
338
- controller.setBlacklist()
356
+ shield.setBlacklist()
339
357
  blist = config.web.blacklist.obj()
340
358
  if ip in blist:
341
359
  return log("%s is already blacklisted! reason: %s"%(ip, blist[ip]))
cantools/web/__init__.py CHANGED
@@ -1,9 +1,13 @@
1
- from .util import config
1
+ from cantools import config
2
2
 
3
3
  if config.web.server == "gae":
4
4
  from .gae_server import *
5
5
  elif config.web.server == "dez":
6
- from cantools.web.dez_server import *
6
+ from .bw import *
7
+ from babyweb import *
8
+ from babyweb import mail
9
+ from babyweb.sms import send_sms
10
+ from babyweb.mail import send_mail, email_admins, email_reportees, mailer, reader, check_inbox, scanner, on_mail
7
11
  else:
8
12
  from cantools import util
9
13
  util.error("no web server specified")
cantools/web/bw.py ADDED
@@ -0,0 +1,70 @@
1
+ import json, gc, os, inspect, threading, psutil
2
+ from babyweb.daemons import WebBase, initWebs, logger_getter
3
+ from babyweb.server import run_dez_webserver
4
+ from babyweb.config import config as babyfyg
5
+ from babyweb.logger import log, syslog
6
+ from ..util import init_rel
7
+ from cantools import config
8
+
9
+ A_STATIC = {
10
+ "dynamic": { "/": "_/dynamic", "/css/": "_/css", "/js/CT/": "js/CT", "/logs/": "logs", "/logs": "logs" },
11
+ "static": { "/": "_/static", "/css/": "_/css", "/js/CT/": "js/CT", "/logs/": "logs", "/logs": "logs" },
12
+ "production": { "/": "_/production", "/css/": "_/css", "/logs/": "logs", "/logs": "logs" },
13
+ }
14
+ A_CB = { "/admin": "admin", "/_db": "_db" }
15
+
16
+ def setcfg():
17
+ syslog("passing configuration to babyweb")
18
+ for prop in ["cache", "encode", "mempad", "web", "cron", "scrambler"]:
19
+ babyfyg.update(prop, config[prop])
20
+ for prop in ["contacts", "reportees"]:
21
+ babyfyg.admin.update(prop, config.admin[prop])
22
+ for prop in ["verify", "certfile", "keyfile", "cacerts"]:
23
+ babyfyg.ssl.update(prop, config.ssl[prop])
24
+ for prop in ["oflist", "openfiles", "tracemalloc", "allow"]:
25
+ babyfyg.log.update(prop, config.log[prop])
26
+ for prop in ["active", "user", "gateway", "minport", "maxport"]:
27
+ babyfyg.proxy.update(prop, config.proxy[prop])
28
+ babyfyg.update("memcache", config.memcache.request)
29
+ bmfg = babyfyg.mail
30
+ bmfg.update("mailer", config.mailer)
31
+ bmfg.update("gmailer", config.gmailer)
32
+ bmfg.update("name", config.mailername)
33
+ bmfg.update("html", config.mailhtml)
34
+ bmfg.update("verbose", config.mailoud)
35
+ bmfg.update("scantick", config.mailscantick)
36
+
37
+ setcfg()
38
+
39
+ class Admin(WebBase):
40
+ def __init__(self, bind_address, port, logger_getter, shield, mempad):
41
+ self.logger = logger_getter("Admin")
42
+ acfg = config.admin
43
+ WebBase.__init__(self, bind_address, port, logger_getter, # share shield/blacklist
44
+ A_STATIC[config.mode], A_CB, acfg.whitelist, config.web.blacklist, shield, mempad)
45
+ self.add_cb_rule("/_report", self.report)
46
+
47
+ def report(self, req):
48
+ report = json.dumps({
49
+ "threads": threading.active_count(),
50
+ "stack_frames": len(inspect.stack()),
51
+ "web": self.controller.webs["web"].daemon.counter.report(),
52
+ "admin": self.daemon.counter.report(),
53
+ "gc": len(gc.get_objects()),
54
+ "mem": psutil.Process(os.getpid()).memory_percent()
55
+ })
56
+ self.logger.info(report)
57
+ self.daemon.respond(req, report)
58
+
59
+ def run_bw():
60
+ syslog("initializing web server")
61
+ init_rel()
62
+ initWebs({
63
+ "admin": {
64
+ "daemon": Admin,
65
+ "config": config.admin
66
+ }
67
+ })
68
+ config.admin.update("pw",
69
+ config.cache("admin password? ", overwrite=config.newpass))
70
+ run_dez_webserver()
@@ -60,9 +60,4 @@ def delmem(key):
60
60
 
61
61
  def clearmem():
62
62
  from google.appengine.api import memcache
63
- memcache.flush_all()
64
-
65
- set_getmem(getmem)
66
- set_setmem(setmem)
67
- set_delmem(delmem)
68
- set_clearmem(clearmem)
63
+ memcache.flush_all()