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.
Files changed (44) hide show
  1. cantools/__init__.py +38 -13
  2. cantools/_db.py +1 -1
  3. cantools/cfg.py +13 -0
  4. cantools/config.py +12 -4
  5. cantools/db/__init__.py +3 -0
  6. cantools/db/gae/model.py +1 -2
  7. cantools/db/wp.py +1 -1
  8. cantools/scripts/index.py +2 -8
  9. cantools/scripts/init.py +1 -1
  10. cantools/scripts/pubsub/actor.py +3 -1
  11. cantools/scripts/pubsub/bots.py +11 -13
  12. cantools/scripts/start.py +2 -2
  13. cantools/util/__init__.py +2 -0
  14. cantools/util/admin.py +10 -18
  15. cantools/util/ai/__init__.py +8 -0
  16. cantools/util/ai/tox/__init__.py +15 -0
  17. cantools/util/ai/tox/duck.py +80 -0
  18. cantools/util/ai/tox/fzn.py +22 -0
  19. cantools/util/ai/tox/g4free.py +73 -0
  20. cantools/util/ai/vox.py +84 -0
  21. cantools/util/apper/__init__.py +1 -0
  22. cantools/util/apper/ander.py +101 -0
  23. cantools/util/apper/data.py +167 -0
  24. cantools/util/system.py +2 -23
  25. cantools/web/__init__.py +6 -2
  26. cantools/web/bw.py +70 -0
  27. cantools/web/gae_server.py +1 -6
  28. cantools/web/util.py +6 -409
  29. {ct-0.10.8.114.dist-info → ct-0.10.8.116.dist-info}/METADATA +7 -8
  30. ct-0.10.8.116.dist-info/RECORD +56 -0
  31. cantools/web/dez_server/__init__.py +0 -1
  32. cantools/web/dez_server/controller.py +0 -129
  33. cantools/web/dez_server/cron.py +0 -115
  34. cantools/web/dez_server/daemons.py +0 -64
  35. cantools/web/dez_server/mail.py +0 -24
  36. cantools/web/dez_server/response.py +0 -63
  37. cantools/web/dez_server/routes.py +0 -21
  38. cantools/web/dez_server/server.py +0 -229
  39. cantools/web/dez_server/sms.py +0 -12
  40. ct-0.10.8.114.dist-info/RECORD +0 -55
  41. {ct-0.10.8.114.dist-info → ct-0.10.8.116.dist-info}/LICENSE +0 -0
  42. {ct-0.10.8.114.dist-info → ct-0.10.8.116.dist-info}/WHEEL +0 -0
  43. {ct-0.10.8.114.dist-info → ct-0.10.8.116.dist-info}/entry_points.txt +0 -0
  44. {ct-0.10.8.114.dist-info → ct-0.10.8.116.dist-info}/top_level.txt +0 -0
cantools/web/util.py CHANGED
@@ -1,87 +1,10 @@
1
- import re, os, sys, ast, json, time, threading
2
- try:
3
- from urllib.parse import quote, unquote, urlencode # py3
4
- from urllib.request import urlopen, Request
5
- except:
6
- from urllib import quote, unquote, urlencode # py2.7
7
- from urllib2 import urlopen, Request
8
- from base64 import b64encode, b64decode
1
+ import re, os, sys, ast, json, time
2
+ from urllib.parse import urlencode
3
+ from urllib.request import urlopen, Request
9
4
  from dez.http.static import StaticStore
5
+ from babyweb.util import local, send_file
6
+ from babyweb.config import config as tinyfyg
10
7
  from cantools import config
11
- from six import string_types
12
-
13
- DEBUG = True
14
-
15
- # memcache stuff -- overwrite with setters
16
- def getmem(key, tojson=True):
17
- log("memcache getting: %s"%(key,))
18
-
19
- def setmem(key, val, fromjson=True):
20
- log("memcache setting: %s -> %s"%(key, val))
21
-
22
- def delmem(key):
23
- log("memcache deleting: %s"%(key,))
24
-
25
- def clearmem():
26
- log("memcache clearing")
27
-
28
- def set_getmem(f):
29
- global getmem
30
- getmem = f
31
-
32
- def set_setmem(f):
33
- global setmem
34
- setmem = f
35
-
36
- def set_delmem(f):
37
- global delmem
38
- delmem = f
39
-
40
- def set_clearmem(f):
41
- global clearmem
42
- clearmem = f
43
-
44
- # logging -- overwrite with setlog if ya want
45
- def log(*args, **kwargs):
46
- print(args, kwargs)
47
-
48
- # encoding, decoding -- may overwrite with setenc/setdec, but not _that_ necessary
49
- _c = config.scrambler
50
- _cl = len(_c)
51
- _chl = int(_cl / 2)
52
-
53
- def flip(c):
54
- i = _c.find(c)
55
- if i == -1:
56
- return c
57
- return _c[(i + _chl) % _cl]
58
-
59
- def scramble(s):
60
- return "".join([flip(c) for c in s])
61
-
62
- def enc(data):
63
- return scramble(b64encode(hasattr(data, "encode") and data.encode() or data).decode())
64
-
65
- def dec(data):
66
- return data.startswith("{") and data or b64decode(scramble(data)).decode()
67
-
68
- # setters (see above)
69
- def setlog(f):
70
- global log
71
- log = f
72
-
73
- def setenc(f):
74
- global enc
75
- enc = f
76
-
77
- def setdec(f):
78
- global dec
79
- dec = f
80
-
81
- # threading
82
- localvars = threading.local()
83
- def local(key, fallback=None):
84
- return getattr(localvars, key, fallback)
85
8
 
86
9
  # request functions
87
10
  def deUnicodeDict(d):
@@ -92,335 +15,9 @@ def deUnicodeDict(d):
92
15
  n[str(v)] = deUnicodeDict(d[v])
93
16
  return n
94
17
 
95
- def cgi_dump():
96
- return local("request_string")
97
-
98
- def cgi_read():
99
- return local("read", sys.stdin.read)()
100
-
101
- def set_read(f):
102
- localvars.read = f
103
-
104
- def set_redir(f):
105
- localvars.redir = f
106
-
107
- def rdec(data):
108
- bdata = b64decode(data.encode())
109
- try: # py2
110
- return unquote(bdata).decode()
111
- except: #py3
112
- return unquote(bdata.decode())
113
-
114
- def renc(data):
115
- try: # py2
116
- return b64encode(quote(data).encode()).decode()
117
- except: #py3
118
- return b64encode(quote(data.encode())).decode()
119
-
120
- def rb64(data, de=False): # depped
121
- log("[DEPRECATION WARNING] Something just called rb64(), which is depped -- use rec_conv()")
122
- return rec_conv(data, de)
123
-
124
- def rec_conv(data, de=False):
125
- if isinstance(data, bytes):
126
- try:
127
- data = data.decode()
128
- except:
129
- pass
130
- if isinstance(data, string_types):
131
- return (de and rdec or renc)(data)
132
- elif isinstance(data, dict):
133
- for k, v in list(data.items()):
134
- data[k] = rec_conv(v, de)
135
- elif isinstance(data, list):
136
- return [rec_conv(d, de) for d in data]
137
- return data
138
-
139
- def qs_get(x, y):
140
- val = localvars.request.getvalue(x, y)
141
- if val:
142
- val = unquote(val)
143
- return val
144
-
145
- def cgi_load(force=False):
146
- localvars.request_string = cgi_read()
147
- data = config.encode and dec(localvars.request_string) or localvars.request_string
148
- try:
149
- try:
150
- jdata = json.loads(data)
151
- except:
152
- jdata = ast.literal_eval(data)
153
- try:
154
- localvars.request = rec_conv(jdata, True)
155
- except:
156
- localvars.request = jdata
157
- except:
158
- import cgi
159
- localvars.request = cgi.FieldStorage()
160
- setattr(localvars.request, "get", qs_get)
161
- if not localvars.request:
162
- if force or config.web.server == "dez":
163
- localvars.request = {}
164
- else:
165
- fail('no request data!')
166
-
167
- def cgi_get(key, choices=None, required=True, default=None, shield=False, decode=False, base64=False):
168
- request = local("request")
169
- val = request.get(key, default)
170
- if val is None:
171
- required and fail('no value submitted for required field: "%s" [%s]'%(key, request))
172
- elif shield:
173
- ip = local("ip")
174
- shield = config.web.shield
175
- if shield(val, ip, fspath=True, count=False):
176
- log('cgi_get() shield bounced "%s" for "%s"'%(ip, shield.ip(ip)["message"]))
177
- fail()
178
- if choices and val not in choices:
179
- fail('invalid value for "%s": "%s"'%(key, val))
180
- if base64 and val:
181
- val = b64decode(unquote(val))
182
- if decode and val:
183
- val = unquote(val)
184
- return val
185
-
186
- # response functions
187
- def _send(data):
188
- send = local("send")
189
- if send:
190
- send(data)
191
- else:
192
- print(data)
193
-
194
- def set_send(f):
195
- localvars.send = f
196
-
197
- def _close():
198
- local("close", sys.exit)()
199
-
200
- def set_close(f):
201
- localvars.close = f
202
-
203
- def _pre_close():
204
- pass
205
-
206
- def set_pre_close(f):
207
- global _pre_close
208
- _pre_close = f
209
-
210
- def _header(hkey, hval):
211
- header = local("header")
212
- if header:
213
- header(hkey, hval)
214
- else:
215
- _send("%s: %s"%(hkey, hval))
216
-
217
- def set_header(f):
218
- localvars.header = f
219
-
220
- def _write(data, exit=True, savename=None):
221
- if savename:
222
- setmem(savename, data, False)
223
- # try:
224
- # data = data.decode('ascii', 'replace').encode('utf-8')
225
- # except Exception as e:
226
- # data = data.encode('utf-8')
227
- _send(data)
228
- if exit:
229
- _pre_close()
230
- _close()
231
-
232
- def trysavedresponse(key=None):
233
- key = key or local("request_string")
234
- response = getmem(key, False)
235
- response and _write(response, exit=True)
236
-
237
- def dez_wrap(resp, failure):
238
- from cantools.db import seshman
239
- from rel.errors import AbortBranch
240
- def f():
241
- try:
242
- resp()
243
- except AbortBranch as e:
244
- seshman.close()
245
- raise AbortBranch() # handled in rel
246
- except SystemExit:
247
- pass
248
- except Exception as e:
249
- failure(e)
250
- return f
251
-
252
- def gae_wrap(resp, failure):
253
- def f():
254
- try:
255
- resp()
256
- except SystemExit:
257
- pass
258
- except Exception as e:
259
- failure(e)
260
- return f
261
-
262
- resp_wrap = { "dez": dez_wrap, "gae": gae_wrap }
263
-
264
- def do_respond(responseFunc, failMsg="failed", failHtml=False, failNoEnc=False, noLoad=False, threaded=False, response=None, autowin=True):
265
- def resp():
266
- response and response.set_cbs()
267
- noLoad or cgi_load()
268
- responseFunc()
269
- autowin and succeed()
270
-
271
- def failure(e):
272
- fail(data=failMsg, html=failHtml, err=e, noenc=failNoEnc)
273
-
274
- wrapped_response = resp_wrap[config.web.server](resp, failure)
275
- if threaded: # dez only!!!
276
- from rel import thread
277
- thread(wrapped_response)
278
- else:
279
- wrapped_response()
280
-
281
- def redirect(addr, msg="", noscript=False, exit=True, metas=None):
282
- a = "<script>"
283
- if msg:
284
- a += 'alert("%s"); '%(msg,)
285
- a += "document.location = '%s';</script>"%(addr,)
286
- if noscript:
287
- a += '<noscript>This site requires Javascript to function properly. To enable Javascript in your browser, please follow <a href="http://www.google.com/support/bin/answer.py?answer=23852">these instructions</a>. Thank you, and have a nice day.</noscript>'
288
- if metas:
289
- a = "<html><head>%s%s</head><body></body></html>"%(metas, a)
290
- _header("Content-Type", "text/html")
291
- _write(_env(True)%(a,), exit)
292
-
293
18
  def setcachedefault(shouldCache=True):
294
- # deprecated -- should set via config.memcache.update("requst", [bool])
295
19
  config.memcache.update("request", shouldCache)
296
-
297
- def _env(html):
298
- return "%s"
299
-
300
- def set_env(f):
301
- global _env
302
- _env = f
303
-
304
- def processResponse(data, code):
305
- if code == "1":
306
- try:
307
- data = json.dumps(data)
308
- except:
309
- data = json.dumps(rec_conv(data))
310
- code = "3"
311
- elif code == "0":
312
- try:
313
- json.dumps(data)
314
- except:
315
- data = rec_conv(data)
316
- code = "2"
317
- return "%s%s"%(code, data)
318
-
319
- def succeed_sync(func, cb):
320
- d = {}
321
- def handle(*a, **k):
322
- d["a"] = a
323
- d["k"] = k
324
- func(handle)
325
- while True:
326
- time.sleep(0.01)
327
- if d["a"] or d["k"]:
328
- succeed(cb(*d["a"], **d["k"]))
329
-
330
- def succeed(data="", html=False, noenc=False, savename=None, cache=False):
331
- if cache or config.memcache.request:
332
- savename = local("request_string")
333
- _header("Content-Type", "text/%s"%(html and "html" or "plain"))
334
- draw = processResponse(data, "1")
335
- dstring = (config.encode and not noenc) and enc(draw) or draw
336
- _write(_env(html)%(dstring,), savename=savename)
337
-
338
- def fail(data="failed", html=False, err=None, noenc=False, exit=True):
339
- if err:
340
- # log it
341
- import traceback
342
- logdata = "%s --- %s --> %s"%(data, repr(err), traceback.format_exc())
343
- log(logdata, "error")
344
- if DEBUG:
345
- # write it
346
- data = logdata
347
- resp = local("response")
348
- reqstring = local("request_string")
349
- path = resp and resp.request.url or "can't find path!"
350
- ip = local("ip") or (resp and resp.ip or "can't find ip!")
351
- edump = "%s\n\n%s\n\n%s\n\n%s"%(path, ip, reqstring, logdata)
352
- shield = config.web.shield
353
- if reqstring and shield(reqstring, ip):
354
- data = "nabra"
355
- reason = shield.ip(ip)["message"]
356
- logline = "%s - IP (%s) banned!"%(reason, ip)
357
- edump = "%s\n\n%s"%(logline, edump)
358
- log(logline)
359
- elif config.web.eflags:
360
- samples = {
361
- "traceback": logdata
362
- }
363
- if reqstring:
364
- samples["request"] = reqstring
365
- for sample in samples:
366
- for ef in config.web.eflags:
367
- if ef in samples[sample]:
368
- reason = '"%s" in %s'%(ef, sample)
369
- logline = "%s - IP (%s) banned!"%(reason, ip)
370
- edump = "%s\n\n%s"%(logline, edump)
371
- shield.suss(ip, reason)
372
- log(logline)
373
- if config.web.report:
374
- from cantools.web import email_admins
375
- email_admins("error encountered", edump)
376
- _header("Content-Type", "text/%s"%(html and "html" or "plain"))
377
- draw = processResponse(data, "0")
378
- dstring = (config.encode and not noenc) and enc(draw) or draw
379
- _write(_env(html)%(dstring,), exit)
380
-
381
- def _headers(headers):
382
- for k, v in list(headers.items()):
383
- _header(k, v)
384
- if config.web.server == "gae":
385
- _send("")
386
-
387
- def send_pdf(data, title=None):
388
- if title:
389
- _headers({
390
- "Content-Type": 'application/pdf; name="%s.pdf"'%(title,),
391
- "Content-Disposition": 'attachment; filename="%s.pdf"'%(title,)
392
- })
393
- else:
394
- _headers({"Content-Type": "application/pdf"})
395
- _send(data)
396
- _close()
397
-
398
- def send_image(data):
399
- _headers({"Content-Type": "image/png"})
400
- _send(data)
401
- _close()
402
-
403
- FILETYPES = {"pdf": "application/pdf", "img": "image/png", "ico": "image/ico", "html": "text/html"}
404
-
405
- def send_file(data, file_type=None, detect=False, headers={}):
406
- if detect:
407
- import magic
408
- file_type = data and magic.from_buffer(data, True)
409
- if file_type:
410
- headers["Content-Type"] = FILETYPES.get(file_type, file_type)
411
- _headers(headers)
412
- _send(data)
413
- _close()
414
-
415
- def send_text(data, dtype="html", fname=None, exit=True, headers={}):
416
- headers["Content-Type"] = "text/%s"%(dtype,)
417
- if fname:
418
- headers['Content-Disposition'] = 'attachment; filename="%s.%s"'%(fname, dtype)
419
- _headers(headers)
420
- _write(data, exit)
421
-
422
- def send_xml(data):
423
- send_text(data, "xml")
20
+ tinyfyg.update("memcache", shouldCache)
424
21
 
425
22
  # misc
426
23
  def verify_recaptcha(cresponse, pkey):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ct
3
- Version: 0.10.8.114
3
+ Version: 0.10.8.116
4
4
  Summary: Modern minimal web framework
5
5
  Author: Mario Balibrera
6
6
  Author-email: mario.balibrera@gmail.com
@@ -13,13 +13,12 @@ Classifier: Operating System :: OS Independent
13
13
  Classifier: Programming Language :: Python
14
14
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
15
  License-File: LICENSE
16
+ Requires-Dist: babyweb >=0.1.2
16
17
  Requires-Dist: catmail >=0.1.9.1
17
- Requires-Dist: databae >=0.1.4.6
18
- Requires-Dist: dez >=0.10.10.37
19
- Requires-Dist: fyg >=0.1.7.2
20
- Requires-Dist: rel >=0.4.9.20
21
- Requires-Dist: requests >=2.3.0
22
- Requires-Dist: six >=1.12.0
23
- Requires-Dist: venvr >=0.1.5.3
18
+ Requires-Dist: databae >=0.1.5.1
19
+ Requires-Dist: dez >=0.10.10.45
20
+ Requires-Dist: fyg >=0.1.7.9
21
+ Requires-Dist: rel >=0.4.9.23
22
+ Requires-Dist: venvr >=0.1.5.8
24
23
 
25
24
  This portable modern web framework is the application-neutral backbone of Civil Action Network. It includes: a pubsub WebSocket server and bot platform; swappable web backends capable of targeting high-concurrency standalone or cloud platforms; a variable-mode application compiler; a broad-spectrum ORM and database migration tools; a built in administrative interface; and a rich modular JavaScript library.
@@ -0,0 +1,56 @@
1
+ cantools/__init__.py,sha256=pYszyy7Gwi8eK0nDPsJq5aIok5xQnYLERkM74roIzFE,824
2
+ cantools/_db.py,sha256=g-kXshJpjfLiYPg8GtTrae1bD0uZ8eWbYi8ORKaXGNs,5075
3
+ cantools/_memcache.py,sha256=xv_rumi1mrr6Br4ofZXTA6deNOEyZg6nwFW6QEcUVZ4,2154
4
+ cantools/_pay.py,sha256=hvu8SiFVUySVIu5W1SZuD_6DHaUWnmy0XOITPlt1C3M,1292
5
+ cantools/admin.py,sha256=MuRKvFQ_LhGqRro6cY6e6PGOBjLXGwKKcTJ1GuAa3K0,1182
6
+ cantools/cfg.py,sha256=N1hBT_MwuHIYAtZ0vczjnE9B_cvwq_IcgTWRvoBUGZI,8920
7
+ cantools/config.py,sha256=FA9VmBhYhSIshizUjA7zrGNmgjYgoItrRGac-mKhp0o,5182
8
+ cantools/geo.py,sha256=WQMWp142niNzRf4WXRurzGPiFaZ3orbDpBwQC2gZXn0,5422
9
+ cantools/hooks.py,sha256=kEnYBt8Fl6EFJz_u-jPQjGQTXa9TxACZxPMbgUW3cHc,219
10
+ cantools/db/__init__.py,sha256=slJyO03jrCTEqDWzXUkrsmolGoJTO42FPJSLCE87RSM,614
11
+ cantools/db/admin.py,sha256=czWPFWaCb0qlJV3Smq2FsInp2xp6DUYZ08UhtRfDl7A,849
12
+ cantools/db/wp.py,sha256=YgUmeHk5WwvTjYxYeFbNr0gpgJBgZ9OsiRKx0jkxA9o,2801
13
+ cantools/db/gae/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ cantools/db/gae/model.py,sha256=2FO8XyhexspGCuguzECfAnQAbtn1OTVQUIUr7JDrEP8,4567
15
+ cantools/db/gae/properties.py,sha256=hhmW_S6ratX0kKu7ZPf59Z8ovh-3oWZ9GyfnppeeaDw,773
16
+ cantools/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ cantools/scripts/bench.py,sha256=3fwR3R4tewBFiRk_X-G75Kau8ZaZRr1-ztlH9AEbN6M,6480
18
+ cantools/scripts/builder.py,sha256=7zx79yNlm7klMA-pGWN4zuluEQ33T87rOFFd7qfJwEA,10942
19
+ cantools/scripts/deploy.py,sha256=1qubH9OQop9C4Px7c2VEJrcVBD8-0qMj86WxKuDxv44,5802
20
+ cantools/scripts/doc.py,sha256=2FdYNifZ3H5fCbJ-M4fPGNDpy4FIvPY2Uon8hIkP-fA,7957
21
+ cantools/scripts/index.py,sha256=8RAx0Ixtv8eYPU_CMsCVFFuZ4khcHMubdnXxzBm8Ctw,8545
22
+ cantools/scripts/init.py,sha256=DXc-rdjud5hrxdxIECrZaWTQ4xKKJTm4GY8D21FWm7s,14515
23
+ cantools/scripts/migrate.py,sha256=LgS1A6M-XFyXkXICFxbrQ9htcHMtS1L8o1dgRvj1cN0,18718
24
+ cantools/scripts/start.py,sha256=eU6DlHcINlfr_CS5rYEHSSi83V38JYDN98xuiXxTpNE,2257
25
+ cantools/scripts/util.py,sha256=44Q08c8CuEVxC3NlkUPyS5w1X8SQp6F6CdjMvddrL0M,595
26
+ cantools/scripts/pubsub/__init__.py,sha256=mSwkEEsjzPGwhxViS747ESZpqOnk1eH1RFOekNPgHc4,1025
27
+ cantools/scripts/pubsub/actor.py,sha256=8Lb5zTaLs1iIucKJLSIgtQF9znMVM0wbhiffi8QTDcI,356
28
+ cantools/scripts/pubsub/bots.py,sha256=D_A6-TlCTtgC3-v8q-aJ3X4taMqtHKWa2kpHNATIU0Y,4302
29
+ cantools/scripts/pubsub/channel.py,sha256=racPeZThUoKJK2TYFfNtwKkxjP5jLUwTWozoZzQb3t8,2333
30
+ cantools/scripts/pubsub/ps.py,sha256=enpSroRCKdJ4GS7M7mpv5mh0z6_rtv_JLpri2NvyJQ0,5216
31
+ cantools/scripts/pubsub/user.py,sha256=B1LdCmmwxgtTNgWGmtxDVzPruYjgw5J-vIjmcB0kbck,1554
32
+ cantools/util/__init__.py,sha256=zZ_0RSbOyChUvp4PBfuzKNy4KRQHJXv8abv-LO2T06I,3444
33
+ cantools/util/admin.py,sha256=b5lb4X1N7VfeL0MutMT_cWIpTMz3ehL900YkCN9DLPE,18469
34
+ cantools/util/data.py,sha256=RrvVmgQkelSCXHj0oqRkg_aifX6qI7IsrBAJr0wvq8s,2911
35
+ cantools/util/media.py,sha256=-znYq87blesL_rMc2OfYmum69z1uiyMe0XmGL--bS2g,8585
36
+ cantools/util/package.py,sha256=cKJwC7OoLRmQ2dzYtjZjpQoW09ojZ_nTTqgx0fCimHI,3998
37
+ cantools/util/system.py,sha256=DqwxuQWX1f60N7-fdfazc5vfhB_k1LgzqED3xpjgXyw,1301
38
+ cantools/util/ai/__init__.py,sha256=MXVRzXC8IGGKMxyhBYma-UzRi0EY4tdDe2to77zhp14,358
39
+ cantools/util/ai/vox.py,sha256=aoEhO3nwo1ITi9ONSfuNviSWFqWmUCvtJhD0AlNcN1g,2601
40
+ cantools/util/ai/tox/__init__.py,sha256=Gd8XKP_201ZjiovuO7t0dIueGYQxRTKPQ3vx6ALdgx0,542
41
+ cantools/util/ai/tox/duck.py,sha256=rH8trJg8JygAmHzdTOeyaR27wgS3bjEtRdSBYTwYcvg,1818
42
+ cantools/util/ai/tox/fzn.py,sha256=u0LWvJb8T_xkhQidRNuAbVVQybMt2zI9_D-O2lgrFwE,501
43
+ cantools/util/ai/tox/g4free.py,sha256=9mxrNGmB_5C5Yv9g452EQpkt5a-Wua5iTgIE3iBYl4E,1792
44
+ cantools/util/apper/__init__.py,sha256=SZdGKLZfPtwxhLjLmdihWERD09cGNJBwnvu8cTPStis,26
45
+ cantools/util/apper/ander.py,sha256=gnvwMqtSLgQDjYIbHCbI9PAOU-ToV_A2rYpc-JI_OrY,3504
46
+ cantools/util/apper/data.py,sha256=HSk_LRBnuCAzorK8Waw5yDFoyBZoTvAd46pPQYlE51E,5146
47
+ cantools/web/__init__.py,sha256=nJOA_sNuT31LgFauWGUjznjhWoubjb1JqGVg2XWXjhM,407
48
+ cantools/web/bw.py,sha256=N-cimUHYyDuHv8v2Ut0twsi8yBDMb3alw1m9EpCYDEs,2704
49
+ cantools/web/gae_server.py,sha256=dPLkEsvzOb-wEFCSMleCvIElNnJoLRMdAGw5DYytwGU,2007
50
+ cantools/web/util.py,sha256=ovacYpR6VtJVw9MvL9jJuXdkMKKv8A5GxjWE-KlYe70,4367
51
+ ct-0.10.8.116.dist-info/LICENSE,sha256=lUkxqJkYxLYhvL52PQdG8L3aqmG241XXmThs30isJTU,1078
52
+ ct-0.10.8.116.dist-info/METADATA,sha256=0yjaCxOawMmRBy0WNIgVMrSCF7im9xnsQ3Ls5fkJyPE,1175
53
+ ct-0.10.8.116.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
54
+ ct-0.10.8.116.dist-info/entry_points.txt,sha256=Gd3wUZp5AMeazvq2oIOh4qn57T2joZ8NeHenLhXG4Hw,261
55
+ ct-0.10.8.116.dist-info/top_level.txt,sha256=Tl_rJpBXgVrhgmBrKozbrcQrKnOIX89JqFF7aF_4EbA,9
56
+ ct-0.10.8.116.dist-info/RECORD,,
@@ -1 +0,0 @@
1
- from .server import *
@@ -1,129 +0,0 @@
1
- import os, sys, platform
2
- from dez.network import SocketController, daemon_wrapper
3
- from dez.http.server.shield import Shield
4
- from dez.logging import get_logger_getter
5
- from cantools import config
6
- from .daemons import Web, Admin
7
- from .response import Response
8
- from .cron import Cron
9
- from cantools import config, __version__
10
- from ..util import *
11
- from ...util import read, write, log as syslog
12
-
13
- logger_getter = get_logger_getter("httpd", syslog, config.log.allow)
14
- CTR = None
15
-
16
- class DController(SocketController):
17
- def __init__(self, *args, **kwargs):
18
- self.logger = logger_getter("Controller")
19
- SocketController.__init__(self, *args, **kwargs)
20
- self.handlers = {}
21
- self.modules = {}
22
- self.blcount = 0
23
- self.blchunk = getattr(config.web.shield, "chunk", 5)
24
- self.logger.info("cantools: %s"%(__version__,))
25
- self.logger.info("Python: %s"%(sys.version.split(' ')[0],))
26
- self.logger.info("System: " + " > ".join([part for part in platform.uname() if part]))
27
-
28
- def _respond(self, resp, *args, **kwargs):
29
- if resp == "nothread": # "on start nothread" cron
30
- kwargs["noLoad"] = True
31
- elif resp: # regular request
32
- kwargs["response"] = resp
33
- localvars.response = resp
34
- else: # regular cron
35
- kwargs["noLoad"] = True
36
- kwargs["threaded"] = True
37
- do_respond(*args, **kwargs)
38
-
39
- def register_handler(self, args, kwargs):
40
- self.logger.info("register handler: %s"%(self.curpath,))
41
- self.handlers[self.curpath] = lambda resp : self._respond(resp, *args, **kwargs)
42
-
43
- def trigger_handler(self, rule, target, req=None, option=None):
44
- self.curpath = rule
45
- if rule not in self.handlers:
46
- if target in self.modules:
47
- self.logger.info("linking module: %s"%(target,))
48
- self.handlers[rule] = self.modules[target]
49
- else:
50
- self.logger.info("importing module: %s"%(target,))
51
- __import__(target)
52
- self.modules[target] = self.handlers[rule]
53
- self.handlers[rule](req and Response(req) or option)
54
-
55
- def blup(self):
56
- wcfg = config.web
57
- bl = wcfg.blacklist.obj()
58
- blen = len(bl.keys())
59
- self.logger.warn("saving %s IPs in black.list"%(blen,))
60
- write(bl, "black.list", isjson=True)
61
- if wcfg.report and self.blcount != blen:
62
- self.blcount = blen
63
- if not blen % self.blchunk:
64
- from cantools.web import email_admins
65
- email_admins("sketch IPs blacklisted", "sketch count: %s"%(blen,))
66
- wcfg.blacklister and wcfg.blacklister.update(bl)
67
-
68
- class PaperShield(object):
69
- def __init__(self):
70
- self.logger = logger_getter("PaperShield")
71
- self.default = { "reason": "I'm just a paper shield!" }
72
- self.ips = {}
73
-
74
- def __call__(self, path, ip, fspath=False, count=True):
75
- self.logger.access('NOOP > paperShield("%s", "%s", fspath=%s, count=%s)'%(path, ip, fspath, count))
76
-
77
- def suss(self, ip, reason):
78
- self.logger.access("suss(%s) -> %s"%(ip, reason))
79
- self.ips[ip] = { "reason": reason }
80
-
81
- def ip(self, ip):
82
- return self.ips.get(ip, self.default)
83
-
84
- def setBlacklist():
85
- bl = {}
86
- for preban in config.web.blacklist:
87
- bl[preban] = "config ban"
88
- if os.path.isfile("black.list"):
89
- try:
90
- bsaved = read("black.list", isjson=True)
91
- except: # old style
92
- bsaved = {}
93
- for line in read("black.list", lines=True):
94
- bsaved[line.strip()] = "legacy ban"
95
- bsaved and bl.update(bsaved)
96
- config.web.update("blacklist", bl)
97
-
98
- def getController():
99
- global CTR
100
- if not CTR:
101
- # controller
102
- CTR = DController()
103
-
104
- shield = None
105
- shfg = config.web.shield
106
- if shfg: # web/admin share shield and blacklist
107
- setBlacklist()
108
- shield = Shield(config.web.blacklist, logger_getter, CTR.blup,
109
- getattr(shfg, "limit", 400),
110
- getattr(shfg, "interval", 2))
111
- config.web.update("shield", shield or PaperShield())
112
- mempad = config.mempad
113
-
114
- # web
115
- CTR.web = CTR.register_address(config.web.host,
116
- config.web.port, dclass=daemon_wrapper(Web, logger_getter, shield, mempad))
117
- CTR.web.controller = CTR
118
-
119
- # admin
120
- config.admin.update("pw",
121
- config.cache("admin password? ", overwrite=config.newpass))
122
- CTR.admin = CTR.register_address(config.admin.host,
123
- config.admin.port, dclass=daemon_wrapper(Admin, logger_getter, shield, mempad))
124
- CTR.admin.controller = CTR
125
-
126
- # cron
127
- Cron(CTR, logger_getter)
128
-
129
- return CTR