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.
Files changed (55) hide show
  1. cantools/__init__.py +24 -0
  2. cantools/_db.py +142 -0
  3. cantools/_memcache.py +76 -0
  4. cantools/_pay.py +46 -0
  5. cantools/admin.py +31 -0
  6. cantools/cfg.py +347 -0
  7. cantools/config.py +131 -0
  8. cantools/db/__init__.py +18 -0
  9. cantools/db/admin.py +27 -0
  10. cantools/db/gae/__init__.py +0 -0
  11. cantools/db/gae/model.py +127 -0
  12. cantools/db/gae/properties.py +35 -0
  13. cantools/db/wp.py +99 -0
  14. cantools/geo.py +188 -0
  15. cantools/hooks.py +13 -0
  16. cantools/scripts/__init__.py +0 -0
  17. cantools/scripts/bench.py +167 -0
  18. cantools/scripts/builder.py +272 -0
  19. cantools/scripts/deploy.py +154 -0
  20. cantools/scripts/doc.py +239 -0
  21. cantools/scripts/index.py +226 -0
  22. cantools/scripts/init.py +345 -0
  23. cantools/scripts/migrate.py +593 -0
  24. cantools/scripts/pubsub/__init__.py +28 -0
  25. cantools/scripts/pubsub/actor.py +13 -0
  26. cantools/scripts/pubsub/bots.py +143 -0
  27. cantools/scripts/pubsub/channel.py +85 -0
  28. cantools/scripts/pubsub/ps.py +145 -0
  29. cantools/scripts/pubsub/user.py +51 -0
  30. cantools/scripts/start.py +53 -0
  31. cantools/scripts/util.py +24 -0
  32. cantools/util/__init__.py +78 -0
  33. cantools/util/admin.py +620 -0
  34. cantools/util/data.py +109 -0
  35. cantools/util/media.py +303 -0
  36. cantools/util/package.py +125 -0
  37. cantools/util/system.py +73 -0
  38. cantools/web/__init__.py +9 -0
  39. cantools/web/dez_server/__init__.py +1 -0
  40. cantools/web/dez_server/controller.py +129 -0
  41. cantools/web/dez_server/cron.py +115 -0
  42. cantools/web/dez_server/daemons.py +64 -0
  43. cantools/web/dez_server/mail.py +24 -0
  44. cantools/web/dez_server/response.py +63 -0
  45. cantools/web/dez_server/routes.py +21 -0
  46. cantools/web/dez_server/server.py +229 -0
  47. cantools/web/dez_server/sms.py +12 -0
  48. cantools/web/gae_server.py +68 -0
  49. cantools/web/util.py +552 -0
  50. ct-0.10.8.114.dist-info/LICENSE +9 -0
  51. ct-0.10.8.114.dist-info/METADATA +25 -0
  52. ct-0.10.8.114.dist-info/RECORD +55 -0
  53. ct-0.10.8.114.dist-info/WHEEL +5 -0
  54. ct-0.10.8.114.dist-info/entry_points.txt +10 -0
  55. ct-0.10.8.114.dist-info/top_level.txt +1 -0
@@ -0,0 +1,345 @@
1
+ """
2
+ ### Usage: ctinit [projname] [-ru] [--plugins=P1|P2|P3] [--cantools_path=PATH] [--web_backend=BACKEND]
3
+
4
+ ### Options:
5
+ -h, --help show this help message and exit
6
+ -p PLUGINS, --plugins=PLUGINS
7
+ which plugins would you like to use in your project?
8
+ -c CANTOOLS_PATH, --cantools_path=CANTOOLS_PATH
9
+ where is cantools? (default: /guessed/path/from/__file__)
10
+ -w WEB_BACKEND, --web_backend=WEB_BACKEND
11
+ web backend. options: dez, gae. (default: dez)
12
+ -r, --refresh_symlinks
13
+ add symlinks to project, create any missing directories,
14
+ and configure version control path exclusion (if desired)
15
+ -u, --update update cantools and all managed plugins
16
+ -a, --admin compile admin pages [ctdev only]
17
+
18
+ NB: it may be necessary to specify --cantools_path. Normally, this is derived from
19
+ the __file__ property (the location of the ctinit script, init.py). However, if the
20
+ package lives in your Python dist-packages (as with 'easy_install', as well as
21
+ 'setup.py install', and now even 'pip3 install'), it does not contain the client-side
22
+ files necessary for an end-to-end web application, and these files therefore cannot be
23
+ symlinked into your new project. In these cases, indicate --cantools_path (the path to
24
+ the cloned cantools repository on your computer), and everything should work fine.
25
+
26
+ Generally speaking, one should clone the cantools github repository, 'setup.py install'
27
+ it (for the 'ct' commands), and then run 'setup.py develop' - actually now instead of
28
+ setup.py anything, just use pip3 install -e - which will point 'cantools' at your cloned
29
+ cantools repo and keep the package up to date as you periodically 'git pull' the latest
30
+ version. Similarly, plugins should be kept in 'develop' mode, as they also will generally
31
+ have non-python files of consequence.
32
+
33
+ In most cases, the developer won't have to pay much attention to this stuff, because
34
+ initializing or refreshing a project will automatically install any necessary plugins
35
+ that aren't already present. Similarly, the --update flag pulls down the latest versions
36
+ of cantools and all managed plugins. Thus, plugins are dealt with under the hood without
37
+ any need for the developer to know or do anything beyond 'ctinit -r'.
38
+ """
39
+
40
+ import os, sys
41
+ from optparse import OptionParser
42
+ from fyg.util import confirm
43
+ from cantools import config, include_plugin, mods_and_repos
44
+ from cantools.util import log, error, cp, sym, mkdir, rm, py, cmd, output, read
45
+ from cantools.util.package import pipper, refresh_plugins
46
+ from cantools.util.admin import install
47
+ from .builder import build_all
48
+
49
+ try:
50
+ input = raw_input # py2/3 compatibility
51
+ except NameError:
52
+ pass
53
+
54
+ CTP = __file__.rsplit(os.path.sep, 2)[0]
55
+
56
+ class Builder(object):
57
+ def __init__(self, pname=None, cantools_path=CTP, web_backend="dez", refresh_symlinks=False, install_dependencies=False):
58
+ if not pname and not refresh_symlinks:
59
+ pname = input("project name? ")
60
+ log("Initializing %s Project: %s"%(web_backend, pname or "(refresh)"))
61
+ self.pname = pname
62
+ self.ctroot = cantools_path
63
+ if not os.path.exists(self.ctroot):
64
+ error("failed to establish cantools root",
65
+ "We tried: %s"%(self.ctroot,),
66
+ "This directory does not contain cantools.",
67
+ "You can download cantools at https://github.com/bubbleboy14/cantools",
68
+ "Please pass the path to your local copy of cantools via the -c flag."
69
+ )
70
+ self.web_backend = web_backend
71
+ self.refresh_symlinks = refresh_symlinks
72
+ self.install_dependencies = install_dependencies
73
+ self.plugins = {}
74
+ self.pipper = None
75
+ self.installed = set()
76
+ self.install_sysdeps()
77
+ self.install_plugins()
78
+ if refresh_symlinks:
79
+ self.plugdirs()
80
+ else:
81
+ self.build_dirs()
82
+ self.make_files()
83
+ self.vcignore()
84
+ self.generate_symlinks()
85
+
86
+ def _install(self, repo):
87
+ log("Building Package: %s"%(repo,), important=True)
88
+ self.pipper = self.pipper or pipper()
89
+ curdir = os.getcwd()
90
+ if not os.path.isdir(config.plugin.path):
91
+ mkdir(config.plugin.path)
92
+ os.chdir(config.plugin.path)
93
+ log("cloning repository", important=True)
94
+ plug = repo.split("/")[1]
95
+ cmd("git clone https://github.com/%s.git"%(repo,))
96
+ os.chdir(plug)
97
+ log("installing plugin", important=True)
98
+ # cmd("python setup.py install", True) # unnecessary right?
99
+ # py("setup.py develop", True)
100
+ self.pipper()
101
+ # os.chdir("%s/.."%(self.ctroot,))
102
+ # log("restoring cantools develop status", important=True)
103
+ # py("setup.py develop", True)
104
+ os.chdir(curdir)
105
+ sys.path.insert(0, os.path.join(config.plugin.path, plug))
106
+ self._getplug(plug)
107
+
108
+ def _update(self, cfg, prop, lines):
109
+ cfg.update(prop, "%s\r\n%s"%(cfg[prop], "\r\n".join(lines)))
110
+
111
+ def _getplug(self, plugin):
112
+ log("Installing Plugin: %s"%(plugin,), important=True)
113
+ mod = self.plugins[plugin] = __import__(plugin)
114
+ mod.__ct_mod_path__ = mod.__file__.rsplit(os.path.sep, 1)[0]
115
+ init = mod.init
116
+ jscc = os.path.join(mod.__ct_mod_path__, "js", "config.js")
117
+ ctab = os.path.join(mod.__ct_mod_path__, "cron.yaml")
118
+ if os.path.isfile(jscc):
119
+ log("adding custom config entries to core.config (js)", 3)
120
+ config.init.config.update(plugin, read(jscc, isjson=True))
121
+ if os.path.isfile(ctab):
122
+ log("adding custom cron schedule", 3)
123
+ config.init.update("cron", "%s\n\n%s"%(config.init.cron, read(ctab)))
124
+ if hasattr(init, "util"):
125
+ log("adding post instructions to core.util (js)", 3)
126
+ self._update(config.init.util, "post", [init.util])
127
+ if hasattr(init, "model"):
128
+ log("adding %s imports to model"%(len(init.model),), 3)
129
+ self._update(config.init, "model", ["from %s import %s"%(m,
130
+ ", ".join(k)) for (m, k) in list(init.model.items())])
131
+ if hasattr(init, "routes"):
132
+ log("adding %s routes to app.yaml"%(len(init.routes),), 3)
133
+ self._update(config.init.yaml, "core", ["- url: %s\r\n %s: %s"%(u,
134
+ s.endswith(".py") and "script" or "static_dir", s) for (u,
135
+ s) in list(init.routes.items())])
136
+ if hasattr(init, "requires"):
137
+ log("installing %s ct dependencies"%(len(init.requires),), 3)
138
+ self._getplugs(*mods_and_repos(init.requires))
139
+ if self.install_dependencies and hasattr(init, "dependencies"):
140
+ log("installing %s system dependencies"%(len(init.dependencies),), 3)
141
+ install(*init.dependencies)
142
+
143
+ def _getplugs(self, plugs, repos=None):
144
+ for i in range(len(plugs)):
145
+ plugin = plugs[i]
146
+ log("Plugin: %s"%(plugin,), 2)
147
+ if plugin in self.installed:
148
+ log("already installed :)", 3)
149
+ continue
150
+ try:
151
+ self._getplug(plugin)
152
+ except ImportError:
153
+ log("plugin '%s' not found! attempting install."%(plugin,), important=True)
154
+ self._install((repos or config.plugin.repos)[i])
155
+ self.installed.add(plugin)
156
+
157
+ def install_plugins(self):
158
+ pil = len(config.plugin.modules)
159
+ if pil:
160
+ log("Installing %s Plugins"%(pil,), 1)
161
+ self._getplugs(config.plugin.modules)
162
+
163
+ def install_sysdeps(self):
164
+ dlen = len(config.build.dependencies)
165
+ if dlen and self.install_dependencies:
166
+ log("Installing %s System Dependencies"%(dlen,), 1)
167
+ install(*config.build.dependencies)
168
+
169
+ def plugdirs(self):
170
+ log("Building Directories for %s Plugins"%(len(list(self.plugins.keys())),), important=True)
171
+ for mod in list(self.plugins.values()):
172
+ if hasattr(mod.init, "dirs"):
173
+ for d in mod.init.dirs:
174
+ if os.path.exists(d):
175
+ log("already exists: %s"%(d,))
176
+ else:
177
+ mkdir(d)
178
+
179
+ def build_dirs(self):
180
+ log("building directories", 1)
181
+ mkdir(self.pname)
182
+ os.chdir(self.pname)
183
+ for d in config.init.dirs:
184
+ mkdir(d)
185
+ jsc = os.path.join(config.js.path, "core")
186
+ mkdir(jsc)
187
+ mkdir("emails")
188
+ if self.plugins:
189
+ self.plugdirs()
190
+
191
+ def make_files(self):
192
+ log("generating configuration", 1)
193
+ cp((self.web_backend == "gae") and "%s\r\n%s"%(config.init.yaml.gae,
194
+ config.init.yaml.core)%(self.pname,) or config.init.yaml.core, "app.yaml")
195
+ cfg = config.init.ctcfg%(self.web_backend,)
196
+ if self.plugins:
197
+ cfg = os.linesep.join([cfg, "PLUGIN_MODULES = %s"%("|".join([r.replace("%s/"%(config.plugin.base,), "") for r in config.plugin.repos]),)])
198
+ cp(cfg, "ct.cfg")
199
+ log("demo index page", 1)
200
+ cp(config.init.html%(self.pname,), os.path.join("html", "index.html"))
201
+ log("model", 1)
202
+ cp(config.init.model, "model.py")
203
+ log("cron", 1)
204
+ cp(config.init.cron, "cron.yaml")
205
+ jsc = os.path.join(config.js.path, "core.js")
206
+ jscc = os.path.join(config.js.path, "core", "config.js")
207
+ jscu = os.path.join(config.js.path, "core", "util.js")
208
+ log("Building core js files: %s, %s, %s"%(jsc, jscc, jscu), important=True)
209
+ cp(os.linesep.join(config.init.core), jsc)
210
+ cp("core.config = %s;"%(config.init.config.json(),), jscc)
211
+ cp(config.init.util.template%(config.init.util.main.json(), config.init.util.post), jscu)
212
+ log("Copying files from plugins", important=True)
213
+ for plugin, mod in list(self.plugins.items()):
214
+ if hasattr(mod.init, "templates"):
215
+ log("email templates [%s]: %s"%(plugin, mod.init.templates), 1, important=True)
216
+ cp(read(os.path.join(mod.__ct_mod_path__, mod.init.templates)),
217
+ os.path.join("emails", mod.init.templates))
218
+ if hasattr(mod.init, "copies"):
219
+ for dname, fnames in list(mod.init.copies.items()):
220
+ dp = os.path.join(mod.__ct_mod_path__, dname)
221
+ if fnames == "*":
222
+ log("copying contents of %s/%s to %s"%(plugin, dname, dname), 1)
223
+ cmd("cp -r %s %s"%(os.path.join(dp, "*"), dname))
224
+ else:
225
+ for fname in fnames:
226
+ log("%s [%s]"%(fname, plugin), 1)
227
+ cp(read(os.path.join(dp, fname), binary=True),
228
+ os.path.join(dname, fname))
229
+
230
+ def generate_symlinks(self):
231
+ log("creating symlinks", 1)
232
+ if self.refresh_symlinks:
233
+ for d in config.init.dirs:
234
+ if not os.path.isdir(d):
235
+ mkdir(d)
236
+ if self.web_backend == "gae":
237
+ sym(self.ctroot, "cantools")
238
+ ctp = os.path.join(self.ctroot, "CT")
239
+ sym(ctp, os.path.join(config.js.path, "CT"))
240
+ sym(os.path.join(self.ctroot, "css", "ct.css"), os.path.join("css", "ct.css"))
241
+ sym(os.path.join(self.ctroot, "admin"), "_")
242
+ sym(os.path.join(self.ctroot, "admin.py"), "admin.py")
243
+ sym(os.path.join(self.ctroot, "_db.py"), "_db.py")
244
+ sym(os.path.join(self.ctroot, "_memcache.py"), "_memcache.py")
245
+ sym(os.path.join(self.ctroot, "_pay.py"), "_pay.py")
246
+ for mod in list(self.plugins.values()):
247
+ if hasattr(mod.init, "syms"):
248
+ for dname, fnames in list(mod.init.syms.items()):
249
+ for fname in fnames:
250
+ sym(os.path.join(mod.__ct_mod_path__, dname, fname),
251
+ os.path.join(dname, fname))
252
+
253
+ def vcignore(self):
254
+ log("configuring version control path exclusion", 1)
255
+ for plugin, mod in list(self.plugins.items()):
256
+ if hasattr(mod.init, "syms"):
257
+ log("loading rules for plugin: %s"%(plugin,), 2)
258
+ for dname, fnames in list(mod.init.syms.items()):
259
+ for fname in fnames:
260
+ if not config.init.vcignore[dname]:
261
+ config.init.vcignore.update(dname, [])
262
+ config.init.vcignore[dname].append(fname)
263
+ else:
264
+ log("no symlinks - skipping plugin: %s"%(plugin,), 2)
265
+ itype = input("would you like to generate exclusion rules for symlinks and dot files (if you select svn, we will add the project to your repository first)? [NO/git/svn] ")
266
+ config.init.vcignore.update(config.js.path, config.init.vcignore.js)
267
+ if itype == "git":
268
+ log("configuring git", 2)
269
+ cfg = config.init.vcignore["."]
270
+ for path in [p for p in list(config.init.vcignore.keys()) if p != "."]:
271
+ for fname in config.init.vcignore[path]:
272
+ cfg.append(os.path.join(path, fname))
273
+ cp("\n".join(cfg), ".gitignore")
274
+ elif itype == "svn":
275
+ log("configuring svn", 2)
276
+ cmd("svn add .")
277
+ for root, files in list(config.init.vcignore.items()):
278
+ cp("\n".join(files), "_tmp")
279
+ cmd("svn propset svn:ignore -F _tmp %s"%(root,))
280
+ rm("_tmp")
281
+
282
+ def update(autodeps=False):
283
+ log("Updating cantools and managed plugins", important=True)
284
+ os.chdir(CTP)
285
+ log("retrieving latest cantools", 1)
286
+ pullout = output("git pull", loud=True)
287
+ if os.path.isdir(config.plugin.path):
288
+ dname, dirs, files = next(os.walk(config.plugin.path))
289
+ log("updating %s managed plugins"%(len(dirs),), 1)
290
+ for d in dirs:
291
+ os.chdir(os.path.join(config.plugin.path, d))
292
+ log("retrieving latest %s"%(d,), 2)
293
+ cmd("git pull")
294
+ log("finished updates", 1)
295
+ if autodeps:
296
+ dodeps = "setup.py" in pullout
297
+ dodeps and log("setup file has changed!", important=True)
298
+ else:
299
+ dodeps = confirm("update cantools dependencies")
300
+ if dodeps:
301
+ os.chdir("%s/.."%(CTP,))
302
+ log("updating dependencies", important=True)
303
+ pipper(execute=True, force=autodeps)
304
+
305
+ def admin():
306
+ log("compiling admin pages -- thanks for developing!!", important=True)
307
+ os.chdir(os.path.join(CTP, "admin"))
308
+ build_all("admin", CTP)
309
+ log("finished compilation")
310
+
311
+ def parse_and_make():
312
+ parser = OptionParser("ctinit [projname] [-ru] [--plugins=P1|P2|P3] [--cantools_path=PATH] [--web_backend=BACKEND]")
313
+ parser.add_option("-p", "--plugins", dest="plugins", default="",
314
+ help="which plugins would you like to use in your project?")
315
+ parser.add_option("-c", "--cantools_path", dest="cantools_path", default=CTP,
316
+ help="where is cantools? (default: %s)"%(CTP,))
317
+ parser.add_option("-w", "--web_backend", dest="web_backend", default="dez",
318
+ help="web backend. options: dez, gae. (default: dez)")
319
+ parser.add_option("-r", "--refresh_symlinks", action="store_true", dest="refresh_symlinks", default=False,
320
+ help="add symlinks to project, create any missing directories, and configure version control path exclusion (if desired)")
321
+ parser.add_option("-i", "--install_dependencies", action="store_true", dest="install_dependencies",
322
+ default=False, help="install (via system package manager) non-Python dependencies")
323
+ parser.add_option("-u", "--update", action="store_true",
324
+ dest="update", default=False, help="update cantools and all managed plugins")
325
+ parser.add_option("-d", "--deps", action="store_true",
326
+ dest="deps", default=False, help="install dependencies if setup file has changed")
327
+ parser.add_option("-a", "--admin", action="store_true",
328
+ dest="admin", default=False, help="compile admin pages [ctdev only]")
329
+ options, args = parser.parse_args()
330
+ if options.update:
331
+ update(options.deps)
332
+ elif options.admin:
333
+ admin()
334
+ elif options.plugins == "refresh":
335
+ refresh_plugins()
336
+ else:
337
+ if options.plugins:
338
+ for p in options.plugins.split("|"):
339
+ include_plugin(p)
340
+ Builder(len(args) and args[0], options.cantools_path, options.web_backend,
341
+ options.refresh_symlinks, options.install_dependencies)
342
+ log("done! goodbye.")
343
+
344
+ if __name__ == "__main__":
345
+ parse_and_make()