PageRenderTime 53ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/working-env/lib/python2.5/TurboGears-1.0.2.2-py2.5.egg/turbogears/command/base.py

https://github.com/thraxil/gtreed
Python | 391 lines | 371 code | 13 blank | 7 comment | 7 complexity | 08d722ee9de2bee0097aac3b4d190dea MD5 | raw file
Possible License(s): LGPL-3.0
  1. "Commands for the TurboGears command line tool."
  2. import optparse
  3. import sys
  4. import os
  5. import os.path
  6. import glob
  7. import pkg_resources
  8. import dispatch
  9. import configobj
  10. import turbogears
  11. from turbogears.util import get_model, load_project_config, get_project_config, get_package_name
  12. from turbogears.identity import SecureObject,from_any_host
  13. from turbogears import config, database
  14. sys.path.insert(0, os.getcwd())
  15. no_connection_param = ["help", "list"]
  16. no_model_param = ["help"]
  17. def silent_os_remove(fname):
  18. """
  19. Tries to remove file FNAME but mutes any error that may happen.
  20. Returns True if file was actually removed and false otherwise
  21. """
  22. try:
  23. os.remove(fname)
  24. return True
  25. except os.error:
  26. pass
  27. return False
  28. class CommandWithDB(object):
  29. "Base class for commands that need to use the database"
  30. config = None
  31. def __init__(self, version):
  32. pass
  33. def find_config(self):
  34. """Chooses the config file, trying to guess whether this is a
  35. development or installed project."""
  36. load_project_config(self.config)
  37. self.dburi = turbogears.config.get("sqlobject.dburi", None)
  38. if self.dburi and self.dburi.startswith("notrans_"):
  39. self.dburi = self.dburi[8:]
  40. [dispatch.generic()]
  41. def sacommand(command, args):
  42. pass
  43. [sacommand.when("command == 'help'")]
  44. def sahelp(command, args):
  45. print """TurboGears SQLAlchemy Helper
  46. help this display
  47. create create the database tables
  48. """
  49. [sacommand.when("command == 'create'")]
  50. def sacreate(command, args):
  51. print "Creating tables at %s" % (config.get("sqlalchemy.dburi"))
  52. from turbogears.database import bind_meta_data, metadata
  53. bind_meta_data()
  54. get_model()
  55. metadata.create_all()
  56. class SQL(CommandWithDB):
  57. """
  58. Wrapper command for sqlobject-admin, and provide some sqlalchemy support.
  59. This automatically supplies sqlobject-admin with the database that
  60. is found in the config file. Will also supply the model module as
  61. appropriate."""
  62. desc = "Run the database provider manager"
  63. need_project = True
  64. def __init__(self, version):
  65. if len(sys.argv) == 1 or sys.argv[1][0] == "-":
  66. parser = optparse.OptionParser(
  67. usage="%prog sql [command]\n\n" \
  68. "hint: '%prog sql help' will list the sqlobject " \
  69. "commands",
  70. version="%prog " + version)
  71. parser.add_option("-c", "--config", help="config file",
  72. dest="config")
  73. (options, args) = parser.parse_args(sys.argv[1:3])
  74. if not options.config:
  75. parser.error("Please provide a valid option or command.")
  76. self.config = options.config
  77. # get rid of our config option
  78. if not args:
  79. del sys.argv[1:3]
  80. else:
  81. del sys.argv[1]
  82. self.find_config()
  83. def run(self):
  84. "Executes the sqlobject-admin code."
  85. if not "--egg" in sys.argv and not turbogears.util.get_project_name():
  86. print "this don't look like a turbogears project"
  87. return
  88. else:
  89. command = sys.argv[1]
  90. if config.get("sqlalchemy.dburi"):
  91. try:
  92. sacommand(command, sys.argv)
  93. except dispatch.interfaces.NoApplicableMethods:
  94. sacommand("help", [])
  95. return
  96. sqlobjcommand = command
  97. if sqlobjcommand not in no_connection_param:
  98. if not self.dburi:
  99. print """Database URI not specified in the config file (%s).
  100. Please be sure it's on the command line.""" % self.config
  101. else:
  102. print "Using database URI %s" % self.dburi
  103. sys.argv.insert(2, self.dburi)
  104. sys.argv.insert(2, "-c")
  105. if sqlobjcommand not in no_model_param:
  106. if not "--egg" in sys.argv:
  107. eggname = glob.glob("*.egg-info")
  108. if not eggname or not \
  109. os.path.exists(os.path.join(eggname[0], "sqlobject.txt")):
  110. eggname = self.fix_egginfo(eggname)
  111. eggname = eggname[0].replace(".egg-info", "")
  112. if not "." in sys.path:
  113. sys.path.append(".")
  114. pkg_resources.working_set.add_entry(".")
  115. sys.argv.insert(2, eggname)
  116. sys.argv.insert(2, "--egg")
  117. from sqlobject.manager import command
  118. command.the_runner.run(sys.argv)
  119. def fix_egginfo(self, eggname):
  120. print """
  121. This project seems incomplete. In order to use the sqlobject commands
  122. without manually specifying a model, there needs to be an
  123. egg-info directory with an appropriate sqlobject.txt file.
  124. I can fix this automatically. Would you like me to?
  125. """
  126. dofix = raw_input("Enter [y] or n: ")
  127. if not dofix or dofix.lower()[0] == 'y':
  128. oldargs = sys.argv
  129. sys.argv = ["setup.py", "egg_info"]
  130. import imp
  131. imp.load_module("setup", *imp.find_module("setup", ["."]))
  132. sys.argv = oldargs
  133. import setuptools
  134. package = setuptools.find_packages()[0]
  135. eggname = glob.glob("*.egg-info")
  136. sqlobjectmeta = open(os.path.join(eggname[0], "sqlobject.txt"), "w")
  137. sqlobjectmeta.write("""db_module=%(package)s.model
  138. history_dir=$base/%(package)s/sqlobject-history
  139. """ % dict(package=package))
  140. else:
  141. sys.exit(0)
  142. return eggname
  143. class Shell(CommandWithDB):
  144. """Convenient version of the Python interactive shell.
  145. This shell attempts to locate your configuration file and model module
  146. so that it can import everything from your model and make it available
  147. in the Python shell namespace."""
  148. desc = "Start a Python prompt with your database available"
  149. need_project = True
  150. def run(self):
  151. "Run the shell"
  152. self.find_config()
  153. mod = get_model()
  154. if mod:
  155. locals = mod.__dict__
  156. else:
  157. locals = dict(__name__="tg-admin")
  158. if config.get("sqlalchemy.dburi"):
  159. using_sqlalchemy = True
  160. database.bind_meta_data()
  161. locals.update(session=database.session,
  162. metadata=database.metadata)
  163. else:
  164. using_sqlalchemy = False
  165. try:
  166. # try to use IPython if possible
  167. import IPython
  168. class CustomIPShell(IPython.iplib.InteractiveShell):
  169. def raw_input(self, *args, **kw):
  170. try:
  171. return \
  172. IPython.iplib.InteractiveShell.raw_input(self,
  173. *args, **kw)
  174. except EOFError:
  175. b = raw_input("Do you wish to commit your "
  176. "database changes? [yes]")
  177. if not b.startswith("n"):
  178. if using_sqlalchemy:
  179. self.push("session.flush()")
  180. else:
  181. self.push("hub.commit()")
  182. raise EOFError
  183. shell = IPython.Shell.IPShell(user_ns=locals,
  184. shell_class=CustomIPShell)
  185. shell.mainloop()
  186. except ImportError:
  187. import code
  188. class CustomShell(code.InteractiveConsole):
  189. def raw_input(self, *args, **kw):
  190. try:
  191. import readline
  192. except ImportError:
  193. pass
  194. try:
  195. return code.InteractiveConsole.raw_input(self,
  196. *args, **kw)
  197. except EOFError:
  198. b = raw_input("Do you wish to commit your "
  199. "database changes? [yes]")
  200. if not b.startswith("n"):
  201. if using_sqlalchemy:
  202. self.push("session.flush()")
  203. else:
  204. self.push("hub.commit()")
  205. raise EOFError
  206. shell = CustomShell(locals=locals)
  207. shell.interact()
  208. class ToolboxCommand(CommandWithDB):
  209. desc = "Launch the TurboGears Toolbox"
  210. def __init__(self, version):
  211. self.hostlist = ['127.0.0.1','::1']
  212. parser = optparse.OptionParser(
  213. usage="%prog toolbox [options]", version="%prog " + version)
  214. parser.add_option("-n", "--no-open",
  215. help="don't open browser automatically",
  216. dest="noopen", action="store_true",
  217. default=False)
  218. parser.add_option("-c", "--add-client",
  219. help="allow the client ip address specified to connect to toolbox (Can be specified more than once)",
  220. dest="host", action="append", default=None)
  221. parser.add_option("-p", "--port",
  222. help="port to run the Toolbox on", dest="port", default=7654)
  223. parser.add_option("--conf", help="config file to use", dest="config", default=get_project_config())
  224. (options, args) = parser.parse_args(sys.argv[1:])
  225. self.port = int(options.port)
  226. self.noopen = options.noopen
  227. self.config = options.config
  228. if options.host:
  229. self.hostlist = self.hostlist + options.host
  230. turbogears.widgets.load_widgets()
  231. def openbrowser(self):
  232. import webbrowser
  233. webbrowser.open("http://localhost:%d" % self.port)
  234. def run(self):
  235. from turbogears.toolbox.catwalk import CatWalk
  236. import cherrypy
  237. from turbogears import toolbox
  238. try:
  239. if get_package_name():
  240. conf = turbogears.config.config_obj( configfile = self.config,
  241. modulename="%s.config" % get_package_name() )
  242. else:
  243. conf = turbogears.config.config_obj( configfile = self.config )
  244. new_conf = {}
  245. for key in ( "sqlobject.dburi", "sqlalchemy.dburi", "visit.on", "visit.manager", "visit.saprovider.model",
  246. "identity.provider", "identity.saprovider.model.group", "identity.saprovider.model.permission",
  247. "identity.saprovider.model.user", "identity.saprovider.model.visit", "identity.on"):
  248. new_conf[key] = conf.get("global").get(key, None)
  249. turbogears.config.update({"global" : new_conf})
  250. except AttributeError, e:
  251. pass
  252. root = SecureObject(toolbox.Toolbox(),from_any_host(self.hostlist), exclude=['noaccess'])
  253. cherrypy.tree.mount(root, "/")
  254. turbogears.config.update({"global" : {
  255. "server.socket_port" : self.port,
  256. "server.environment" : "development",
  257. "server.log_to_screen" : True,
  258. "autoreload.on" : False,
  259. "server.package" : "turbogears.toolbox",
  260. "log_debug_info_filter.on" : False,
  261. "identity.failure_url" : "/noaccess"
  262. }})
  263. if not self.noopen:
  264. cherrypy.server.start_with_callback(self.openbrowser)
  265. else:
  266. cherrypy.server.start()
  267. commands = None
  268. def main():
  269. "Main command runner. Manages the primary command line arguments."
  270. # add commands defined by entrypoints
  271. commands = {}
  272. for entrypoint in pkg_resources.iter_entry_points("turbogears.command"):
  273. command = entrypoint.load()
  274. commands[entrypoint.name] = (command.desc, entrypoint)
  275. def _help():
  276. "Custom help text for tg-admin."
  277. print """
  278. TurboGears %s command line interface
  279. Usage: %s [options] <command>
  280. Options:
  281. -c CONFIG --config=CONFIG Config file to use
  282. -e EGG_SPEC --egg=EGG_SPEC Run command on given Egg
  283. Commands:""" % (turbogears.__version__, sys.argv[0])
  284. longest = max([len(key) for key in commands.keys()])
  285. format = "%" + str(longest) + "s %s"
  286. commandlist = commands.keys()
  287. commandlist.sort()
  288. for key in commandlist:
  289. print format % (key, commands[key][0])
  290. parser = optparse.OptionParser()
  291. parser.allow_interspersed_args = False
  292. parser.add_option("-c", "--config", dest="config")
  293. parser.add_option("-e", "--egg", dest="egg")
  294. parser.print_help = _help
  295. (options, args) = parser.parse_args(sys.argv[1:])
  296. # if not command is found display help
  297. if not args or not commands.has_key(args[0]):
  298. _help()
  299. sys.exit()
  300. commandname = args[0]
  301. # strip command and any global options from the sys.argv
  302. sys.argv = [sys.argv[0],] + args[1:]
  303. command = commands[commandname][1]
  304. command = command.load()
  305. if options.egg:
  306. egg = pkg_resources.get_distribution(options.egg)
  307. os.chdir(egg.location)
  308. if hasattr(command,"need_project"):
  309. if not turbogears.util.get_project_name():
  310. print "This command needs to be run from inside a project directory"
  311. return
  312. elif not options.config and not os.path.isfile(turbogears.util.get_project_config()):
  313. print """No default config file was found.
  314. If it has been renamed use:
  315. tg-admin --config=<FILE> %s""" % commandname
  316. return
  317. command.config = options.config
  318. command = command(turbogears.__version__)
  319. command.run()
  320. __all__ = ["main"]