ct 0.10.8.114__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 +24 -0
- cantools/_db.py +142 -0
- cantools/_memcache.py +76 -0
- cantools/_pay.py +46 -0
- cantools/admin.py +31 -0
- cantools/cfg.py +347 -0
- cantools/config.py +131 -0
- cantools/db/__init__.py +18 -0
- cantools/db/admin.py +27 -0
- cantools/db/gae/__init__.py +0 -0
- cantools/db/gae/model.py +127 -0
- cantools/db/gae/properties.py +35 -0
- cantools/db/wp.py +99 -0
- cantools/geo.py +188 -0
- cantools/hooks.py +13 -0
- cantools/scripts/__init__.py +0 -0
- cantools/scripts/bench.py +167 -0
- cantools/scripts/builder.py +272 -0
- cantools/scripts/deploy.py +154 -0
- cantools/scripts/doc.py +239 -0
- cantools/scripts/index.py +226 -0
- cantools/scripts/init.py +345 -0
- cantools/scripts/migrate.py +593 -0
- cantools/scripts/pubsub/__init__.py +28 -0
- cantools/scripts/pubsub/actor.py +13 -0
- cantools/scripts/pubsub/bots.py +143 -0
- cantools/scripts/pubsub/channel.py +85 -0
- cantools/scripts/pubsub/ps.py +145 -0
- cantools/scripts/pubsub/user.py +51 -0
- cantools/scripts/start.py +53 -0
- cantools/scripts/util.py +24 -0
- cantools/util/__init__.py +78 -0
- cantools/util/admin.py +620 -0
- cantools/util/data.py +109 -0
- cantools/util/media.py +303 -0
- cantools/util/package.py +125 -0
- cantools/util/system.py +73 -0
- cantools/web/__init__.py +9 -0
- cantools/web/dez_server/__init__.py +1 -0
- cantools/web/dez_server/controller.py +129 -0
- cantools/web/dez_server/cron.py +115 -0
- cantools/web/dez_server/daemons.py +64 -0
- cantools/web/dez_server/mail.py +24 -0
- cantools/web/dez_server/response.py +63 -0
- cantools/web/dez_server/routes.py +21 -0
- cantools/web/dez_server/server.py +229 -0
- cantools/web/dez_server/sms.py +12 -0
- cantools/web/gae_server.py +68 -0
- cantools/web/util.py +552 -0
- ct-0.10.8.114.dist-info/LICENSE +9 -0
- ct-0.10.8.114.dist-info/METADATA +25 -0
- ct-0.10.8.114.dist-info/RECORD +55 -0
- ct-0.10.8.114.dist-info/WHEEL +5 -0
- ct-0.10.8.114.dist-info/entry_points.txt +10 -0
- ct-0.10.8.114.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import datetime, json, os
|
|
2
|
+
from cantools import config
|
|
3
|
+
from cantools.util import log, write
|
|
4
|
+
from cantools.web import fetch, send_mail
|
|
5
|
+
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
|
+
|
|
12
|
+
class BotMeta(type):
|
|
13
|
+
def __new__(cls, name, bases, attrs):
|
|
14
|
+
bc = type.__new__(cls, name, bases, attrs)
|
|
15
|
+
if name != "Bot":
|
|
16
|
+
name != "Monitor" and log("Initializing Bot Class: %s"%(name,), important=True)
|
|
17
|
+
config.pubsub.bots.update(name.lower(), bc)
|
|
18
|
+
return bc
|
|
19
|
+
|
|
20
|
+
class Bot(with_metaclass(BotMeta, Actor)):
|
|
21
|
+
num = 0
|
|
22
|
+
def __init__(self, server, channel, name=None):
|
|
23
|
+
Bot.num += 1
|
|
24
|
+
self.name = name or (self.__class__.__name__ + str(Bot.num))
|
|
25
|
+
self.server = server
|
|
26
|
+
self.channel = channel # often we only care about one channel
|
|
27
|
+
self.channels = set()
|
|
28
|
+
self._set_defaults()
|
|
29
|
+
log("Bot Spawned: '%s'"%(self.name,), 2)
|
|
30
|
+
channel.join(self)
|
|
31
|
+
self.server.bots[self.name] = self
|
|
32
|
+
|
|
33
|
+
def pub(self, message):
|
|
34
|
+
self.server.publish({
|
|
35
|
+
"message": message,
|
|
36
|
+
"channel": self.channel.name
|
|
37
|
+
}, self)
|
|
38
|
+
|
|
39
|
+
def write(self, obj): # receive message from channel
|
|
40
|
+
getattr(self, "on_%s"%(obj["action"],))(obj["data"])
|
|
41
|
+
|
|
42
|
+
def _default_handler(self, action):
|
|
43
|
+
def _h(*args):
|
|
44
|
+
log('Bot %s handling %s: "%s"'%(self.name, action, json.dumps(args)), 3)
|
|
45
|
+
return _h
|
|
46
|
+
|
|
47
|
+
def _set_defaults(self):
|
|
48
|
+
for action in ["channel", "publish", "subscribe", "unsubscribe", "pm", "error", "meta"]:
|
|
49
|
+
hname = "on_%s"%(action,)
|
|
50
|
+
if not hasattr(self, hname):
|
|
51
|
+
setattr(self, hname, self._default_handler(action))
|
|
52
|
+
|
|
53
|
+
class Monitor(Bot):
|
|
54
|
+
def __init__(self, server, channel, name="monitor"): # only one monitor
|
|
55
|
+
import event # here for google crap engine
|
|
56
|
+
self.current = {}
|
|
57
|
+
self.alert = {}
|
|
58
|
+
Bot.__init__(self, server, channel, name)
|
|
59
|
+
event.timeout(config.admin.monitor.interval, self._tick)
|
|
60
|
+
|
|
61
|
+
def _datedir(self):
|
|
62
|
+
n = datetime.datetime.now()
|
|
63
|
+
lp = os.path.join("logs", "monitor")
|
|
64
|
+
yp = os.path.join(lp, str(n.year))
|
|
65
|
+
mp = os.path.join(yp, str(n.month))
|
|
66
|
+
dp = os.path.join(mp, str(n.day))
|
|
67
|
+
if not os.path.isdir(lp):
|
|
68
|
+
os.mkdir(lp)
|
|
69
|
+
if not os.path.isdir(yp):
|
|
70
|
+
os.mkdir(yp)
|
|
71
|
+
if not os.path.isdir(mp):
|
|
72
|
+
os.mkdir(mp)
|
|
73
|
+
if not os.path.isdir(dp):
|
|
74
|
+
os.mkdir(dp)
|
|
75
|
+
return os.path.join(dp, str(n.hour))
|
|
76
|
+
|
|
77
|
+
def log(self, data):
|
|
78
|
+
self.pub(data)
|
|
79
|
+
if config.admin.monitor.log:
|
|
80
|
+
write(data, self._datedir(), True, append=True, newline=True)
|
|
81
|
+
|
|
82
|
+
def _cpu(self):
|
|
83
|
+
c = self.current["cpu"] = psutil.cpu_percent()
|
|
84
|
+
if self.alert.get("cpu"):
|
|
85
|
+
if c < config.admin.monitor.thresholds.cpu:
|
|
86
|
+
del self.alert["cpu"]
|
|
87
|
+
log("CPU calmed down")
|
|
88
|
+
send_mail(config.admin.contacts, subject="High CPU", body="just ended")
|
|
89
|
+
else:
|
|
90
|
+
if c >= config.admin.monitor.thresholds.cpu:
|
|
91
|
+
self.alert["cpu"] = True
|
|
92
|
+
log("CPU just started going crazy")
|
|
93
|
+
send_mail(config.admin.contacts, subject="High CPU", body="just started")
|
|
94
|
+
|
|
95
|
+
def _tick(self):
|
|
96
|
+
self._cpu()
|
|
97
|
+
dioc = psutil.disk_io_counters()
|
|
98
|
+
nioc = psutil.net_io_counters()
|
|
99
|
+
dmon = fetch(config.admin.host, "/_report",
|
|
100
|
+
config.admin.port, True, protocol=config.admin.protocol)
|
|
101
|
+
data = {
|
|
102
|
+
"gc": dmon["gc"],
|
|
103
|
+
"cpu": self.current["cpu"],
|
|
104
|
+
"read": dioc.read_time,
|
|
105
|
+
"write": dioc.write_time,
|
|
106
|
+
"sent": nioc.bytes_sent,
|
|
107
|
+
"recv": nioc.bytes_recv,
|
|
108
|
+
"process_memory": dmon["mem"],
|
|
109
|
+
"threads": dmon["threads"],
|
|
110
|
+
"stack_frames": dmon["stack_frames"],
|
|
111
|
+
"virtual_memory": psutil.virtual_memory().percent,
|
|
112
|
+
"swap_memory": psutil.swap_memory().percent,
|
|
113
|
+
"connections": len(psutil.net_connections()),
|
|
114
|
+
"web_connections": dmon["web"]["connections"],
|
|
115
|
+
"admin_connections": dmon["admin"]["connections"],
|
|
116
|
+
"web_requests": dmon["web"]["requests"],
|
|
117
|
+
"admin_requests": dmon["admin"]["requests"],
|
|
118
|
+
"totals": {
|
|
119
|
+
"web": {
|
|
120
|
+
"connections": dmon["web"]["total_connections"],
|
|
121
|
+
"requests": dmon["web"]["total_requests"],
|
|
122
|
+
"rolls": dmon["web"]["rolls"]
|
|
123
|
+
},
|
|
124
|
+
"admin": {
|
|
125
|
+
"connections": dmon["admin"]["total_connections"],
|
|
126
|
+
"requests": dmon["admin"]["total_requests"],
|
|
127
|
+
"rolls": dmon["admin"]["rolls"]
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
"devices": {
|
|
131
|
+
"web": dmon["web"]["devices"],
|
|
132
|
+
"admin": dmon["admin"]["devices"]
|
|
133
|
+
},
|
|
134
|
+
"ips": {
|
|
135
|
+
"web": dmon["web"]["ips"],
|
|
136
|
+
"admin": dmon["admin"]["ips"]
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if config.admin.monitor.proxy:
|
|
140
|
+
data["ips"]["proxy"] = fetch(config.admin.host, "/_report",
|
|
141
|
+
config.admin.monitor.proxy, True)["ips"]
|
|
142
|
+
self.log(data)
|
|
143
|
+
return True
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from cantools import config
|
|
2
|
+
|
|
3
|
+
def diffmerge(orig, diff): # move this somewhere else....
|
|
4
|
+
for k, v in diff.items():
|
|
5
|
+
if type(v) == dict:
|
|
6
|
+
if k not in orig:
|
|
7
|
+
orig[k] = {}
|
|
8
|
+
diffmerge(orig[k], v)
|
|
9
|
+
else:
|
|
10
|
+
orig[k] = v
|
|
11
|
+
|
|
12
|
+
class PubSubChannel(object):
|
|
13
|
+
def __init__(self, name, server):
|
|
14
|
+
self._log = server._log
|
|
15
|
+
self.server = server
|
|
16
|
+
self.name = name
|
|
17
|
+
self.users = set()
|
|
18
|
+
self.history = []
|
|
19
|
+
self.metadata = {}
|
|
20
|
+
self._log('NEW CHANNEL: "%s"'%(name,), 1, True)
|
|
21
|
+
|
|
22
|
+
def data(self):
|
|
23
|
+
return {
|
|
24
|
+
"name": self.name,
|
|
25
|
+
"users": [u.name for u in self.users]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
def _broadcast(self, obj):
|
|
29
|
+
for user in self.users:
|
|
30
|
+
if config.pubsub.echo or user.name != obj["data"]["user"]:
|
|
31
|
+
user.write(obj)
|
|
32
|
+
for user in list(self.server.admins.values()):
|
|
33
|
+
user.write(obj)
|
|
34
|
+
|
|
35
|
+
def meta(self, subobj):
|
|
36
|
+
subobj["channel"] = self.name
|
|
37
|
+
self._broadcast({
|
|
38
|
+
"action": "meta",
|
|
39
|
+
"data": subobj
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
def chmeta(self, subobj):
|
|
43
|
+
subobj["channel"] = self.name # _usually_ unnecessary
|
|
44
|
+
diffmerge(self.metadata, subobj["meta"])
|
|
45
|
+
# self.metadata = subobj["meta"]
|
|
46
|
+
self._broadcast({
|
|
47
|
+
"action": "chmeta",
|
|
48
|
+
"data": subobj
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
def write(self, subobj):
|
|
52
|
+
subobj["channel"] = self.name
|
|
53
|
+
obj = {
|
|
54
|
+
"action": "publish",
|
|
55
|
+
"data": subobj
|
|
56
|
+
}
|
|
57
|
+
self._broadcast(obj)
|
|
58
|
+
self.history.append(subobj)
|
|
59
|
+
self.history = self.history[-config.pubsub.history:]
|
|
60
|
+
|
|
61
|
+
def leave(self, user):
|
|
62
|
+
if user in self.users:
|
|
63
|
+
self.users.remove(user)
|
|
64
|
+
user.leave(self)
|
|
65
|
+
self._broadcast({
|
|
66
|
+
"action": "unsubscribe",
|
|
67
|
+
"data": {
|
|
68
|
+
"user": user.name,
|
|
69
|
+
"channel": self.name
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
def join(self, user):
|
|
74
|
+
data = {
|
|
75
|
+
"user": user.name,
|
|
76
|
+
"channel": self.name
|
|
77
|
+
}
|
|
78
|
+
if config.pubsub.meta:
|
|
79
|
+
data["meta"] = user.meta
|
|
80
|
+
self._broadcast({
|
|
81
|
+
"action": "subscribe",
|
|
82
|
+
"data": data
|
|
83
|
+
})
|
|
84
|
+
self.users.add(user)
|
|
85
|
+
user.join(self)
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import os, sys
|
|
2
|
+
from base64 import b64encode
|
|
3
|
+
from dez.network.websocket import WebSocketDaemon
|
|
4
|
+
from cantools import config
|
|
5
|
+
from cantools.util import log, set_log
|
|
6
|
+
from .user import PubSubUser
|
|
7
|
+
from .channel import PubSubChannel
|
|
8
|
+
|
|
9
|
+
class PubSub(WebSocketDaemon):
|
|
10
|
+
def __init__(self, *args, **kwargs):
|
|
11
|
+
if config.pubsub.log:
|
|
12
|
+
set_log(os.path.join("logs", config.pubsub.log))
|
|
13
|
+
kwargs["b64"] = config.pubsub.b64
|
|
14
|
+
kwargs["isJSON"] = True
|
|
15
|
+
kwargs["report_cb"] = self._log
|
|
16
|
+
kwargs["cb"] = self.connect
|
|
17
|
+
kwargs["certfile"] = config.ssl.pubsubcert or config.ssl.certfile
|
|
18
|
+
kwargs["keyfile"] = config.ssl.pubsubkey or config.ssl.keyfile
|
|
19
|
+
kwargs["cacerts"] = config.ssl.pubsubcacerts or config.ssl.cacerts
|
|
20
|
+
if "silent" in kwargs:
|
|
21
|
+
self.silent = kwargs["silent"]
|
|
22
|
+
del kwargs["silent"]
|
|
23
|
+
else:
|
|
24
|
+
self.silent = False
|
|
25
|
+
WebSocketDaemon.__init__(self, *args, **kwargs)
|
|
26
|
+
self.bots = {}
|
|
27
|
+
self.users = {}
|
|
28
|
+
self.admins = {}
|
|
29
|
+
self.channels = {}
|
|
30
|
+
self.loadBots()
|
|
31
|
+
config.admin.update("pw", config.cache("admin password? "))
|
|
32
|
+
self._log("Initialized PubSub Server @ %s:%s"%(self.hostname, self.port), important=True)
|
|
33
|
+
|
|
34
|
+
def loadBots(self):
|
|
35
|
+
self._log("Loading Bots: %s"%(config.pubsub.botnames,))
|
|
36
|
+
sys.path.insert(0, "bots") # for dynamically loading bot modules
|
|
37
|
+
for bname in config.pubsub.botnames:
|
|
38
|
+
self._log("Importing Bot: %s"%(bname,), 2)
|
|
39
|
+
__import__(bname) # config modified in pubsub.bots.BotMeta.__new__()
|
|
40
|
+
|
|
41
|
+
def newUser(self, u):
|
|
42
|
+
if not u.name: # on dc?
|
|
43
|
+
self._log("user disconnected without registering")
|
|
44
|
+
u.conn.close()
|
|
45
|
+
elif u.name.startswith("__admin__") and u.name.endswith(b64encode(config.admin.pw.encode()).decode()):
|
|
46
|
+
self.admins[u.name] = u
|
|
47
|
+
self.snapshot(u)
|
|
48
|
+
else:
|
|
49
|
+
self.users[u.name] = u
|
|
50
|
+
|
|
51
|
+
def client(self, name):
|
|
52
|
+
return self.users.get(name) or self.bots.get(name) or self.admins.get(name)
|
|
53
|
+
|
|
54
|
+
def snapshot(self, admin):
|
|
55
|
+
admin.write({
|
|
56
|
+
"action": "snapshot",
|
|
57
|
+
"data": {
|
|
58
|
+
"bots": [b.data() for b in list(self.bots.values())],
|
|
59
|
+
"users": [u.data() for u in list(self.users.values())],
|
|
60
|
+
"admins": [a.data() for a in list(self.admins.values())],
|
|
61
|
+
"channels": [c.data() for c in list(self.channels.values())]
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
def pm(self, data, user):
|
|
66
|
+
recipient = self.client(data["user"])
|
|
67
|
+
if not recipient:
|
|
68
|
+
return user._error("no such user!")
|
|
69
|
+
recipient.write({
|
|
70
|
+
"action": "pm",
|
|
71
|
+
"data": {
|
|
72
|
+
"user": user.name,
|
|
73
|
+
"message": data["message"]
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
def subscribe(self, channel, user):
|
|
78
|
+
self._check_channel(channel)
|
|
79
|
+
chan = self.channels[channel]
|
|
80
|
+
chan.join(user)
|
|
81
|
+
self._log('SUBSCRIBE: "%s" -> "%s"'%(user.name, channel), 2)
|
|
82
|
+
data = {
|
|
83
|
+
"channel": channel,
|
|
84
|
+
"presence": [u.name for u in chan.users],
|
|
85
|
+
"history": chan.history
|
|
86
|
+
}
|
|
87
|
+
if config.pubsub.meta:
|
|
88
|
+
data["meta"] = {
|
|
89
|
+
"channel": chan.metadata,
|
|
90
|
+
"users": [u.meta for u in chan.users]
|
|
91
|
+
}
|
|
92
|
+
user.write({
|
|
93
|
+
"action": "channel",
|
|
94
|
+
"data": data
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
def unsubscribe(self, channel, user):
|
|
98
|
+
if self._check_channel(channel, True) and user in self.channels[channel].users:
|
|
99
|
+
self.channels[channel].leave(user)
|
|
100
|
+
self._log('UNSUBSCRIBE: "%s" -> "%s"'%(user.name, channel), 2)
|
|
101
|
+
else:
|
|
102
|
+
self._log('FAILED UNSUBSCRIBE: "%s" -> "%s"'%(user.name, channel), 2)
|
|
103
|
+
|
|
104
|
+
def meta(self, data, user):
|
|
105
|
+
channel = data["channel"]
|
|
106
|
+
self._check_channel(channel)
|
|
107
|
+
user.meta = data["meta"]
|
|
108
|
+
self.channels[channel].meta({
|
|
109
|
+
"meta": user.meta,
|
|
110
|
+
"user": user.name
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
def chmeta(self, data, user):
|
|
114
|
+
channel = data["channel"]
|
|
115
|
+
self._check_channel(channel)
|
|
116
|
+
self.channels[channel].chmeta(data)
|
|
117
|
+
|
|
118
|
+
def publish(self, data, user):
|
|
119
|
+
channel = data["channel"]
|
|
120
|
+
self._check_channel(channel)
|
|
121
|
+
self.channels[channel].write({
|
|
122
|
+
"message": data["message"],
|
|
123
|
+
"user": user.name
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
def _new_channel(self, channel):
|
|
127
|
+
self.channels[channel] = PubSubChannel(channel, self)
|
|
128
|
+
# check for bots...
|
|
129
|
+
botname = channel.split("_")[0]
|
|
130
|
+
if botname in config.pubsub.bots:
|
|
131
|
+
self._log("Generating Bot '%s' for channel '%s'"%(botname, channel), 2)
|
|
132
|
+
config.pubsub.bots[botname](self, self.channels[channel])
|
|
133
|
+
|
|
134
|
+
def _check_channel(self, channel, justBool=False):
|
|
135
|
+
condition = channel in self.channels
|
|
136
|
+
if not condition and not justBool:
|
|
137
|
+
self._new_channel(channel)
|
|
138
|
+
return condition
|
|
139
|
+
|
|
140
|
+
def _log(self, data, level=0, important=False):
|
|
141
|
+
if not self.silent:
|
|
142
|
+
log(data, level=level, important=important)
|
|
143
|
+
|
|
144
|
+
def connect(self, conn):
|
|
145
|
+
PubSubUser(conn, self, self._log)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from .actor import Actor
|
|
3
|
+
|
|
4
|
+
class PubSubUser(Actor):
|
|
5
|
+
id = 0
|
|
6
|
+
def __init__(self, conn, server, logger):
|
|
7
|
+
PubSubUser.id += 1
|
|
8
|
+
self.id = PubSubUser.id
|
|
9
|
+
self.conn = conn
|
|
10
|
+
self.server = server
|
|
11
|
+
self._log = logger
|
|
12
|
+
self.channels = set()
|
|
13
|
+
self.conn.set_cb(self._register)
|
|
14
|
+
self._log('NEW CONNECTION (%s)'%(self.id,), 1, True)
|
|
15
|
+
|
|
16
|
+
def write(self, data):
|
|
17
|
+
data["data"]["datetime"] = str(datetime.utcnow())
|
|
18
|
+
self.conn.write(data)
|
|
19
|
+
|
|
20
|
+
def _read(self, obj):
|
|
21
|
+
if obj["action"] == "close":
|
|
22
|
+
return self.conn.close()
|
|
23
|
+
getattr(self.server, obj["action"])(obj["data"], self)
|
|
24
|
+
|
|
25
|
+
def _close(self):
|
|
26
|
+
if self.name in self.server.users:
|
|
27
|
+
del self.server.users[self.name]
|
|
28
|
+
elif self.name in self.server.admins:
|
|
29
|
+
del self.server.admins[self.name]
|
|
30
|
+
for channel in list(self.channels):
|
|
31
|
+
channel.leave(self)
|
|
32
|
+
|
|
33
|
+
def _error(self, message):
|
|
34
|
+
self.write({
|
|
35
|
+
"action": "error",
|
|
36
|
+
"data": {
|
|
37
|
+
"message": message
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
def _register(self, obj):
|
|
42
|
+
name = obj.get("data")
|
|
43
|
+
if not name:
|
|
44
|
+
self._log("no name provided! assigning index (%s)."%(self.id,))
|
|
45
|
+
name = str(self.id)
|
|
46
|
+
self._log('REGISTER: "%s"'%(name,), 1, True)
|
|
47
|
+
self.name = name
|
|
48
|
+
self.meta = obj.get("meta")
|
|
49
|
+
self.server.newUser(self)
|
|
50
|
+
self.conn.set_cb(self._read)
|
|
51
|
+
self.conn.set_close_cb(self._close)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
### Usage: ctstart [--web_backend=BACKEND] [--port=PORT] [--datastore=DS_PATH]
|
|
3
|
+
|
|
4
|
+
### Options:
|
|
5
|
+
-h, --help show this help message and exit
|
|
6
|
+
-w WEB_BACKEND, --web_backend=WEB_BACKEND
|
|
7
|
+
web backend. options: dez, gae. (default: dez)
|
|
8
|
+
-p PORT, --port=PORT select your port (default=8080)
|
|
9
|
+
-a ADMIN_PORT, --admin_port=ADMIN_PORT
|
|
10
|
+
select your port (default=8002)
|
|
11
|
+
-d DATASTORE, --datastore=DATASTORE
|
|
12
|
+
select your datastore file (default=sqlite:///data.db)
|
|
13
|
+
-o, --overwrite_password
|
|
14
|
+
overwrite admin password (default=False)
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from optparse import OptionParser
|
|
18
|
+
from cantools import config
|
|
19
|
+
from cantools.util import error
|
|
20
|
+
|
|
21
|
+
def go():
|
|
22
|
+
parser = OptionParser("ctstart [--web_backend=BACKEND] [--port=PORT] [--datastore=DS_PATH]")
|
|
23
|
+
parser.add_option("-w", "--web_backend", dest="web_backend", default=config.web.server,
|
|
24
|
+
help="web backend. options: dez, gae. (default: %s)"%(config.web.server,))
|
|
25
|
+
parser.add_option("-p", "--port", dest="port", default=config.web.port,
|
|
26
|
+
help="select your port (default=%s)"%(config.web.port,))
|
|
27
|
+
parser.add_option("-a", "--admin_port", dest="admin_port", default=config.admin.port,
|
|
28
|
+
help="select your port (default=%s)"%(config.admin.port,))
|
|
29
|
+
parser.add_option("-d", "--datastore", dest="datastore", default=config.db.main,
|
|
30
|
+
help="select your datastore file (default=%s)"%(config.db.main,))
|
|
31
|
+
parser.add_option("-o", "--overwrite_password", action="store_true", dest="overwrite_password",
|
|
32
|
+
default=False, help="overwrite admin password (default=False)")
|
|
33
|
+
options, args = parser.parse_args()
|
|
34
|
+
|
|
35
|
+
config.web.update("port", int(options.port))
|
|
36
|
+
config.admin.update("port", int(options.admin_port))
|
|
37
|
+
if options.overwrite_password:
|
|
38
|
+
config.update("newpass", True)
|
|
39
|
+
|
|
40
|
+
if options.web_backend == "gae":
|
|
41
|
+
import subprocess
|
|
42
|
+
cmd = 'dev_appserver.py . --host=%s --port=%s --admin_port=%s --datastore_path=%s'%(config.web.host,
|
|
43
|
+
options.port, options.admin_port, options.datastore)
|
|
44
|
+
print(cmd)
|
|
45
|
+
subprocess.call(cmd, shell=True)
|
|
46
|
+
elif options.web_backend == "dez":
|
|
47
|
+
from cantools.web import run_dez_webserver
|
|
48
|
+
run_dez_webserver()
|
|
49
|
+
else:
|
|
50
|
+
error("invalid web_backend: %s"%(options.web_backend,))
|
|
51
|
+
|
|
52
|
+
if __name__ == "__main__":
|
|
53
|
+
go()
|
cantools/scripts/util.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
### Usage: ctutil [module] [function] [..parameters]
|
|
3
|
+
|
|
4
|
+
### Options:
|
|
5
|
+
-h, --help show this help message and exit
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from optparse import OptionParser
|
|
9
|
+
from cantools import util
|
|
10
|
+
log = util.log
|
|
11
|
+
error = util.error
|
|
12
|
+
|
|
13
|
+
def run():
|
|
14
|
+
parser = OptionParser("ctutil [module] [function] [..parameters]")
|
|
15
|
+
args = parser.parse_args()[1]
|
|
16
|
+
args or error("what module?")
|
|
17
|
+
module = args.pop(0)
|
|
18
|
+
args or error("what function?")
|
|
19
|
+
function = args.pop(0)
|
|
20
|
+
#log("calling %s.%s(%s)"%(module, function, ", ".join(args)))
|
|
21
|
+
getattr(getattr(util, module), function)(*args)
|
|
22
|
+
|
|
23
|
+
if __name__ == "__main__":
|
|
24
|
+
run()
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import os, sys
|
|
2
|
+
from fyg.util import read, write, writejson, confirm, batch, indir, rm # backwards compat
|
|
3
|
+
from fyg.util.reporting import set_log, close_log, log, set_error, error, start_timer, end_timer
|
|
4
|
+
from .system import cp, sym, mkdir, sed, py, pymod, cmd, output
|
|
5
|
+
from .data import getxls, gettsv, getcsv, getcsv_from_data, flatten, arr2csv, token
|
|
6
|
+
from .media import transcode, segment, hlsify, shouldMoveMoov, crop, resizep2, thumb, dlp, repitch
|
|
7
|
+
from .admin import certs, screener
|
|
8
|
+
from .apper import android
|
|
9
|
+
from .ai import tox, vox, tellme
|
|
10
|
+
|
|
11
|
+
def init_basic():
|
|
12
|
+
os.path.isdir("emails") and sys.path.append("emails")
|
|
13
|
+
|
|
14
|
+
def init_rel():
|
|
15
|
+
import rel
|
|
16
|
+
from rel.util import loudListen
|
|
17
|
+
from cantools import config
|
|
18
|
+
rcfg = config.rel
|
|
19
|
+
if rcfg.sleep:
|
|
20
|
+
rel.set_sleep(rcfg.sleep)
|
|
21
|
+
if rcfg.turbo:
|
|
22
|
+
rel.set_turbo(rcfg.turbo)
|
|
23
|
+
rel.set_verbose(rcfg.verbose)
|
|
24
|
+
loudListen(rcfg.loudlisten)
|
|
25
|
+
|
|
26
|
+
def init_gae():
|
|
27
|
+
try:
|
|
28
|
+
from google import appengine
|
|
29
|
+
except: # running outside of dev_appserver
|
|
30
|
+
gae_p = None
|
|
31
|
+
for p in os.environ["PATH"].split(":"):
|
|
32
|
+
if p.endswith("google_appengine"):
|
|
33
|
+
gae_p = p
|
|
34
|
+
break
|
|
35
|
+
if not gae_p:
|
|
36
|
+
from cantools import config
|
|
37
|
+
gae_p = config.cache("\n".join([
|
|
38
|
+
"can't find google - please enter the path to google_appengine",
|
|
39
|
+
" - if you DON'T have a copy, get one here:",
|
|
40
|
+
" https://cloud.google.com/appengine/downloads#Google_App_Engine_SDK_for_Python",
|
|
41
|
+
" - if you DO have a copy, enter the path to it below",
|
|
42
|
+
"so what's the path? "]), password=False)
|
|
43
|
+
if not gae_p:
|
|
44
|
+
error("can't find google_appengine in path! please add and retry.")
|
|
45
|
+
sys.path.append(gae_p)
|
|
46
|
+
if 'google' in sys.modules:
|
|
47
|
+
del sys.modules['google']
|
|
48
|
+
import dev_appserver
|
|
49
|
+
dev_appserver.fix_sys_path()
|
|
50
|
+
sys.path.insert(0, ".")
|
|
51
|
+
|
|
52
|
+
# accesses ct gae app running locally or elsewhere (other than app engine production, aka gcloud)
|
|
53
|
+
def init_ndb():
|
|
54
|
+
from cantools import config
|
|
55
|
+
from google.appengine.ext.remote_api import remote_api_stub
|
|
56
|
+
remote_api_stub.ConfigureRemoteDatastore("", "/remote_api",
|
|
57
|
+
lambda : ("user@email.com", "password"),
|
|
58
|
+
servername="%s:%s"%(config.web.host, config.web.port))
|
|
59
|
+
|
|
60
|
+
# these are essentially not recommended. google's
|
|
61
|
+
# rules for operating outside of their native environment
|
|
62
|
+
# are crappy and generally get worse with time. these
|
|
63
|
+
# _sort of_ work, but easily get messed up. it's whatever.
|
|
64
|
+
def init_ndb_cloud(url=None):
|
|
65
|
+
from cantools import config
|
|
66
|
+
from google.appengine.ext.remote_api import remote_api_stub
|
|
67
|
+
if not url:
|
|
68
|
+
app_id = read("app.yaml", True)[0].split(": ")[1].strip()
|
|
69
|
+
url = "%s.appspot.com"%(app_id,)
|
|
70
|
+
remote_api_stub.ConfigureRemoteApiForOAuth(url, "/_ah/remote_api")
|
|
71
|
+
|
|
72
|
+
def init_ndb_depped(datastore_file="/dev/null"):
|
|
73
|
+
from google.appengine.api import apiproxy_stub_map, datastore_file_stub
|
|
74
|
+
app_id = read("app.yaml", True)[0].split(": ")[1].strip()
|
|
75
|
+
os.environ['APPLICATION_ID'] = app_id
|
|
76
|
+
apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()
|
|
77
|
+
stub = datastore_file_stub.DatastoreFileStub(app_id, datastore_file, '/')
|
|
78
|
+
apiproxy_stub_map.apiproxy.RegisterStub('datastore_v3', stub)
|