def __init__(self, name): # Init base class Command.__init__(self, name) # Parser configuration self.parser.add_option("-f", "--file", dest="file", help="write report to FILE", metavar="FILE") self.parser.add_option("-x", "--foo", dest="foo", help="assign a value for foo", metavar="FOO") self.parser.add_option("-q", "--quiet", action="store_false", dest="verbose", default=True, help="don't print status messages to stdout") return
class Seed(Command): summary = "--NO SUMMARY--" usage = "--NO USAGE--" group_name = "manage1" parser = Command.standard_parser(verbose=False) def command(self): print("----Delete Database----") Session.query(model.Course).delete() Session.query(model.CourseSchedule).delete() # Session.query(model.Users).delete() print("----Delete Done----") # users.role_create("admin") # users.role_create("delete") # users.role_create("editor") # users.group_create("student") # # users.user_create("*****@*****.**", password="******") # users.user_add_role("*****@*****.**", role="editor") # users.user_set_group("*****@*****.**", 'student') # users.user_create("*****@*****.**", password="******") # users.user_add_role("*****@*****.**", role="delete") # users.user_add_role("*****@*****.**", role="admin") Session.commit() print("----Seed Database----") # for i in range(100): # student = model.Users(email=faker.email(), password='******', group_id = 2) # student.user_info = model.UsersInfo(name=faker.name()) # Session.add(student) import datetime start = [] end = [] start.append( datetime.datetime(year=2017, month=8, day=01, hour=8, minute=20))
class BaseCommand(Command): "Base command" min_args = 0 max_args = 1 parser = Command.standard_parser(verbose=True) parser.set_conflict_handler("resolve") def init(self): "init" if len(self.args) == 0: config_file = '/etc/baruwa/production.ini' else: config_file = self.args[0] if not os.path.isfile(config_file): raise BadCommand('%sError: CONFIG_FILE not found at: %s, ' 'Please specify a CONFIG_FILE' % (self.parser.get_usage(), config_file)) here = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) here = os.path.dirname(here) config_name = 'config:' + config_file self.logging_file_config(config_file) conf = appconfig(config_name, relative_to=here) conf.update(dict(app_conf=conf.local_conf, global_conf=conf.global_conf)) wsgiapp = loadapp(config_name, relative_to=here) self.conf = conf
class AdhocracyCommand(Command): parser = Command.standard_parser(verbose=True) parser.add_option('-c', '--config', dest='config', default='development.ini', help='Config file to use.') default_verbosity = 1 group_name = 'adhocracy' def _load_config(self): from paste.deploy import appconfig if not self.options.config: msg = 'No config file supplied' raise self.BadCommand(msg) self.filename = os.path.abspath(self.options.config) self.logging_file_config(self.filename) conf = appconfig('config:' + self.filename) conf.update(dict(app_conf=conf.local_conf, global_conf=conf.global_conf)) paste.deploy.config.CONFIG.push_thread_config(conf) wsgiapp = loadapp('config:' + self.filename) test_app = paste.fixture.TestApp(wsgiapp) tresponse = test_app.get('/_test_vars') request_id = int(tresponse.body) test_app.pre_request_hook = lambda self: \ paste.registry.restorer.restoration_end() test_app.post_request_hook = lambda self: \ paste.registry.restorer.restoration_begin(request_id) paste.registry.restorer.restoration_begin(request_id) def _setup_app(self): cmd = paste.script.appinstall.SetupCommand('setup-app') cmd.run([self.filename])
class PShellCommand(PCommand): """Open an interactive shell with a :app:`Pyramid` app loaded. This command accepts two positional arguments: ``config_file`` -- specifies the PasteDeploy config file to use for the interactive shell. ``section_name`` -- specifies the section name in the PasteDeploy config file that represents the application. Example:: $ paster pshell myapp.ini main .. note:: You should use a ``section_name`` that refers to the actual ``app`` section in the config file that points at your Pyramid app without any middleware wrapping, or this command will almost certainly fail. """ summary = "Open an interactive shell with a pyramid app loaded" min_args = 2 max_args = 2 parser = Command.standard_parser(simulate=True) parser.add_option('-d', '--disable-ipython', action='store_true', dest='disable_ipython', help="Don't use IPython even if it is available") def command(self, IPShell=_marker): if IPShell is _marker: try: #pragma no cover from IPython.Shell import IPShell except ImportError: #pragma no cover IPShell = None cprt = ('Type "help" for more information. "root" is the Pyramid app ' 'root object, "registry" is the Pyramid registry object.') banner = "Python %s on %s\n%s" % (sys.version, sys.platform, cprt) config_file, section_name = self.args self.logging_file_config(config_file) app = self.get_app(config_file, section_name, loadapp=self.loadapp[0]) root, closer = self.get_root(app) shell_globals = {'root': root, 'registry': app.registry} if IPShell is not None and not self.options.disable_ipython: try: shell = IPShell(argv=[], user_ns=shell_globals) shell.IP.BANNER = shell.IP.BANNER + '\n\n' + banner shell.mainloop() finally: closer() else: try: self.interact[0](banner, local=shell_globals) finally: closer()
class RoutesCommand(Command): """Print the applications routes The optional CONFIG_FILE argument specifies the config file to use. CONFIG_FILE defaults to 'development.ini'. Example:: $ paster routes my-development.ini """ summary = __doc__.splitlines()[0] usage = '\n' + __doc__ min_args = 0 max_args = 1 group_name = 'pylons' parser = Command.standard_parser(simulate=True) parser.add_option('-q', action='count', dest='quiet', default=0, help=("Do not load logging configuration from the " "config file")) def command(self): """Main command to create a new shell""" self.verbose = 3 if len(self.args) == 0: # Assume the .ini file is ./development.ini config_file = 'development.ini' if not os.path.isfile(config_file): raise BadCommand('%sError: CONFIG_FILE not found at: .%s%s\n' 'Please specify a CONFIG_FILE' % \ (self.parser.get_usage(), os.path.sep, config_file)) else: config_file = self.args[0] config_name = 'config:%s' % config_file here_dir = os.getcwd() if not self.options.quiet: # Configure logging from the config file self.logging_file_config(config_file) # Load the wsgi app first so that everything is initialized right wsgiapp = loadapp(config_name, relative_to=here_dir) test_app = paste.fixture.TestApp(wsgiapp) # Query the test app to setup the environment and get the mapper tresponse = test_app.get('/_test_vars') mapper = tresponse.config.get('routes.map') if mapper: print mapper
class LoadStructure(Command): max_args = 1 min_args = 1 usage = 'CONFIGFILE' group_name = 'cms' summary = 'Loads the database with a basic website structure' parser = Command.standard_parser() def command(self): print "TODO: Actually load basic website structure into the database"
class CAMQPAdminCommand(CeleryCommand): """CAMQP Admin CAMQP celery admin tool. """ usage = 'CONFIG_FILE [camqadm options...]' summary = __doc__.splitlines()[0] description = "".join(__doc__.splitlines()[2:]) parser = Command.standard_parser(quiet=True) celery_command = camqadm.AMQPAdminCommand
class CeleryEventCommand(CeleryCommand): """Celery event command. Capture celery events. """ usage = 'CONFIG_FILE [celeryev options...]' summary = __doc__.splitlines()[0] description = "".join(__doc__.splitlines()[2:]) parser = Command.standard_parser(quiet=True) celery_command = celeryev.EvCommand
class CeleryDaemonCommand(CeleryCommand): """Start the celery worker Starts the celery worker that uses a paste.deploy configuration file. """ usage = 'CONFIG_FILE [celeryd options...]' summary = __doc__.splitlines()[0] description = "".join(__doc__.splitlines()[2:]) parser = Command.standard_parser(quiet=True) celery_command = celeryd.WorkerCommand
class CeleryBeatCommand(CeleryCommand): """Start the celery beat server Starts the celery beat server using a paste.deploy configuration file. """ usage = 'CONFIG_FILE [celerybeat options...]' summary = __doc__.splitlines()[0] description = "".join(__doc__.splitlines()[2:]) parser = Command.standard_parser(quiet=True) celery_command = celerybeat.BeatCommand
class LoadAppCommand(Command): """Load the app and all associated StackedObjectProxies. Useful for batch scripts. The optional CONFIG_FILE argument specifies the config file to use for the interactive shell. CONFIG_FILE defaults to 'development.ini'. This allows you to test your mapper, models, and simulate web requests using ``paste.fixture``. This class has been adapted from pylons.commands.ShellCommand. """ summary = __doc__.splitlines()[0] min_args = 0 max_args = 1 group_name = 'pylons' parser = Command.standard_parser() parser.add_option( '-q', action='count', dest='quiet', default=0, help="Do not load logging configuration from the config file") def __init__(self, name, summary): self.summary = summary Command.__init__(self, name) def command(self): """Main command to create a new shell""" self.verbose = 3 if len(self.args) == 0: # Assume the .ini file is ./development.ini config_file = 'development.ini' if not os.path.isfile(config_file): raise BadCommand('CONFIG_FILE not found at: .%s%s\n' 'Please specify a CONFIG_FILE' % \ (os.path.sep, config_file) ) else: config_file = self.args[0] init_mediadrop(config_file, here_dir=os.getcwd(), disable_logging=self.options.quiet) def parse_args(self, args): self.options, self.args = self.parser.parse_args(args)
def run(self, args): """ Overrides Command.run Checks for a config file argument and loads it. """ if len(args) < self.min_args: raise BadCommand(self.min_args_error % {'min_args': self.min_args, 'actual_args': len(args)}) # Decrement because we're going to lob off the first argument. # @@ This is hacky self.min_args -= 1 self.bootstrap_config(args[0]) self.update_parser() return Command.run(self, args[1:])
def run(self, args): """ Overrides Command.run Checks for a config file argument and loads it. """ if len(args) < self.min_args: raise BadCommand(self.min_args_error % { 'min_args': self.min_args, 'actual_args': len(args) }) # Decrement because we're going to lob off the first argument. # @@ This is hacky self.min_args -= 1 self.bootstrap_config(args[0]) self.update_parser() return Command.run(self, args[1:])
class RunMigrationCommand(BaseCommand): """Run a migration script Example:: $ paster migrate development.ini some_migration """ summary = __doc__.splitlines()[0] usage = '\n' + __doc__ parser = Command.standard_parser(simulate=True) parser.add_option('--list', dest='list_scripts', action='store_true', help="List available migration scripts") def command(self): """Main command that starts the migration.""" super(RunMigrationCommand, self).command() if self.options.list_scripts: self.list_scripts() return if not self.restvars: raise BadCommand("You must specify a migration script to run") script = self.restvars[0] if not hasattr(scripts, script): raise BadCommand("The migration script %s does not exist" % script) migrator = getattr(scripts, script) migrator() def list_scripts(self): print "Available migration scripts:" for script_name in scripts.__all__: script = getattr(scripts, script_name) doc = script.__doc__ or "" print " ", script_name, "\t", doc.splitlines()[0] if doc else ""
def make_standard_parser(cls, verbose=True, interactive=False, no_interactive=False, simulate=False, quiet=False, overwrite=False): parser = Command.standard_parser(verbose=verbose, interactive=interactive, no_interactive=no_interactive, simulate=simulate, quiet=quiet, overwrite=overwrite) parser.option_class = cls.ToolOption parser.add_option('--ignore-warnings', action='store_true', dest='ignore_warnings', help="If true, changes are committed even when the " "tool reports warnings (unless the --simulate " "flag is set).") return parser
class TutorialTemplate(Command): summary = "Creation of new functionality of basic tutorial" usage = "--NO USAGE--" group_name = "pawsapp" parser = Command.standard_parser() def command(self): try: file_op = FileOp(source_dir=('pylons', 'templates')) file_op.template_vars.update({ 'name': self.args[0], 'file_name': self.args[1] }) except: traceback.print_exc(file=sys.stdout) print traceback.format_exc() file_op.copy_file(template='site_tutorial.mako_tmpl', dest='templates', filename='tutorial_' + self.args[0] + '.mako', template_renderer=paste_script_template_renderer)
class SyncDbCommand(Command): """Syncs the CouchDB views on disk with the database. Example:: $ paster syncdb my-development.ini This will also create the database if it does not exist """ summary = __doc__.splitlines()[0] usage = '\n' + __doc__ min_args = 1 max_args = 1 group_name = 'couchdbkit' default_verbosity = 3 parser = Command.standard_parser(simulate=True) def command(self): """Main command to sync db""" config_file = self.args[0] config_name = 'config:%s' % config_file here_dir = os.getcwd() if not self.options.quiet: # Configure logging from the config file self.logging_file_config(config_file) # Load the wsgi app first so that everything is initialized right wsgiapp = loadapp(config_name, relative_to=here_dir) try: design_path = wsgiapp.config['couchdb.design'] except KeyError: design_path = default_design_path(wsgiapp.config) # This syncs the main database. sync_design(wsgiapp.config['couchdb.db'], design_path)
class AddAdminUserCommand(Command): # Parser configuration summary = "--NO SUMMARY--" usage = "--NO USAGE--" group_name = "eportfolio" parser = Command.standard_parser(verbose=False) def command(self): self._setup_db() self._populate_db() transaction.commit() def _setup_db(self): config_uri = 'config:%s' % self.args[0] here_dir = os.getcwd() settings = appconfig(config_uri, name='eportfolio', relative_to=here_dir) db_string = settings.get('db_string') if db_string is None: raise ValueError( "No 'db_string' value in application configuration.") initialize_sql(db_string) def _populate_db(self): session = DBSession() # Add a teacher ############### Change user name and email here ############### if not session.query(Teacher).filter( Teacher.email == u"*****@*****.**").all(): admin = Teacher(first_name=u'Admin', last_name=u'User', email=u"*****@*****.**", password=u'password') session.add(admin)
class CeleryDaemonCommand(CeleryCommand): """Start the celery worker Starts the celery worker that uses a paste.deploy configuration file. """ usage = 'CONFIG_FILE [celeryd options...]' summary = __doc__.splitlines()[0] description = "".join(__doc__.splitlines()[2:]) parser = Command.standard_parser(quiet=True) def update_parser(self, args): from celery.bin.celeryd import WorkerCommand w = WorkerCommand() w.setup_app_from_commandline(['celeryd']) for x in w.get_options(): self.parser.add_option(x) def command(self): from celery.bin.celeryd import WorkerCommand w = WorkerCommand() w.execute_from_commandline(['celeryd'] + sys.argv[3:])
class ServeCommand(Command): min_args = 0 usage = 'CONFIG_FILE [start|stop|restart|status] [var=value]' takes_config_file = 1 summary = "Serve the described application" description = """\ This command serves a web application that uses a paste.deploy configuration file for the server and application. If start/stop/restart is given, then --daemon is implied, and it will start (normal operation), stop (--stop-daemon), or do both. You can also include variable assignments like 'http_port=8080' and then use %(http_port)s in your config files. """ # used by subclasses that configure apps and servers differently requires_config_file = True parser = Command.standard_parser(quiet=True) parser.add_option('-n', '--app-name', dest='app_name', metavar='NAME', help="Load the named application (default main)") parser.add_option('-s', '--server', dest='server', metavar='SERVER_TYPE', help="Use the named server.") parser.add_option('--server-name', dest='server_name', metavar='SECTION_NAME', help="Use the named server as defined in the configuration file (default: main)") if hasattr(os, 'fork'): parser.add_option('--daemon', dest="daemon", action="store_true", help="Run in daemon (background) mode") parser.add_option('--pid-file', dest='pid_file', metavar='FILENAME', help="Save PID to file (default to paster.pid if running in daemon mode)") parser.add_option('--log-file', dest='log_file', metavar='LOG_FILE', help="Save output to the given log file (redirects stdout)") parser.add_option('--reload', dest='reload', action='store_true', help="Use auto-restart file monitor") parser.add_option('--reload-interval', dest='reload_interval', default=1, help="Seconds between checking files (low number can cause significant CPU usage)") parser.add_option('--monitor-restart', dest='monitor_restart', action='store_true', help="Auto-restart server if it dies") parser.add_option('--status', action='store_true', dest='show_status', help="Show the status of the (presumably daemonized) server") if hasattr(os, 'setuid'): # I don't think these are available on Windows parser.add_option('--user', dest='set_user', metavar="USERNAME", help="Set the user (usually only possible when run as root)") parser.add_option('--group', dest='set_group', metavar="GROUP", help="Set the group (usually only possible when run as root)") parser.add_option('--stop-daemon', dest='stop_daemon', action='store_true', help='Stop a daemonized server (given a PID file, or default paster.pid file)') if jython: parser.add_option('--disable-jython-reloader', action='store_true', dest='disable_jython_reloader', help="Disable the Jython reloader") _scheme_re = re.compile(r'^[a-z][a-z]+:', re.I) default_verbosity = 1 _reloader_environ_key = 'PYTHON_RELOADER_SHOULD_RUN' _monitor_environ_key = 'PASTE_MONITOR_SHOULD_RUN' possible_subcommands = ('start', 'stop', 'restart', 'status') def command(self): if self.options.stop_daemon: return self.stop_daemon() if not hasattr(self.options, 'set_user'): # Windows case: self.options.set_user = self.options.set_group = None # @@: Is this the right stage to set the user at? self.change_user_group( self.options.set_user, self.options.set_group) if self.requires_config_file: if not self.args: raise BadCommand('You must give a config file') app_spec = self.args[0] if (len(self.args) > 1 and self.args[1] in self.possible_subcommands): cmd = self.args[1] restvars = self.args[2:] else: cmd = None restvars = self.args[1:] else: app_spec = "" if (self.args and self.args[0] in self.possible_subcommands): cmd = self.args[0] restvars = self.args[1:] else: cmd = None restvars = self.args[:] if (getattr(self.options, 'daemon', False) and getattr(self.options, 'reload', False)): raise BadCommand('The --daemon and --reload options may not be used together') jython_monitor = False if self.options.reload: if jython and not self.options.disable_jython_reloader: # JythonMonitor raises the special SystemRestart # exception that'll cause the Jython interpreter to # reload in the existing Java process (avoiding # subprocess startup time) try: from paste.reloader import JythonMonitor except ImportError: pass else: jython_monitor = JythonMonitor(poll_interval=int( self.options.reload_interval)) if self.requires_config_file: jython_monitor.watch_file(self.args[0]) if not jython_monitor: if os.environ.get(self._reloader_environ_key): from paste import reloader if self.verbose > 1: print('Running reloading file monitor') reloader.install(int(self.options.reload_interval)) if self.requires_config_file: reloader.watch_file(self.args[0]) else: return self.restart_with_reloader() if cmd not in (None, 'start', 'stop', 'restart', 'status'): raise BadCommand( 'Error: must give start|stop|restart (not %s)' % cmd) if cmd == 'status' or self.options.show_status: return self.show_status() if cmd == 'restart' or cmd == 'stop': result = self.stop_daemon() if result: if cmd == 'restart': print("Could not stop daemon; aborting") else: print("Could not stop daemon") return result if cmd == 'stop': return result self.options.daemon = True if cmd == 'start': self.options.daemon = True app_name = self.options.app_name vars = self.parse_vars(restvars) if not self._scheme_re.search(app_spec): app_spec = 'config:' + app_spec server_name = self.options.server_name if self.options.server: server_spec = 'egg:PasteScript' assert server_name is None server_name = self.options.server else: server_spec = app_spec base = os.getcwd() if getattr(self.options, 'daemon', False): if not self.options.pid_file: self.options.pid_file = 'paster.pid' if not self.options.log_file: self.options.log_file = 'paster.log' # Ensure the log file is writeable if self.options.log_file: try: writeable_log_file = open(self.options.log_file, 'a') except IOError as ioe: msg = 'Error: Unable to write to log file: %s' % ioe raise BadCommand(msg) writeable_log_file.close() # Ensure the pid file is writeable if self.options.pid_file: try: writeable_pid_file = open(self.options.pid_file, 'a') except IOError as ioe: msg = 'Error: Unable to write to pid file: %s' % ioe raise BadCommand(msg) writeable_pid_file.close() if getattr(self.options, 'daemon', False): try: self.daemonize() except DaemonizeException as ex: if self.verbose > 0: print(str(ex)) return if (self.options.monitor_restart and not os.environ.get(self._monitor_environ_key)): return self.restart_with_monitor() if self.options.pid_file: self.record_pid(self.options.pid_file) if self.options.log_file: stdout_log = LazyWriter(self.options.log_file, 'a') sys.stdout = stdout_log sys.stderr = stdout_log logging.basicConfig(stream=stdout_log) log_fn = app_spec if log_fn.startswith('config:'): log_fn = app_spec[len('config:'):] elif log_fn.startswith('egg:'): log_fn = None if log_fn: log_fn = os.path.join(base, log_fn) self.logging_file_config(log_fn) try: server = self.loadserver(server_spec, name=server_name, relative_to=base, global_conf=vars) app = self.loadapp(app_spec, name=app_name, relative_to=base, global_conf=vars) except SyntaxError as e: if self.options.reload and os.environ.get(self._reloader_environ_key): traceback.print_exc() reloader.watch_file(e.filename) while True: time.sleep(60*60) else: raise if self.verbose > 0: if hasattr(os, 'getpid'): msg = 'Starting server in PID %i.' % os.getpid() else: msg = 'Starting server.' print(msg) def serve(): try: server(app) except (SystemExit, KeyboardInterrupt) as e: if self.verbose > 1: raise if str(e): msg = ' '+str(e) else: msg = '' print('Exiting%s (-v to see traceback)' % msg) if jython_monitor: # JythonMonitor has to be ran from the main thread threading.Thread(target=serve).start() print('Starting Jython file monitor') jython_monitor.periodic_reload() else: serve() def loadserver(self, server_spec, name, relative_to, **kw): return loadserver( server_spec, name=name, relative_to=relative_to, **kw) def loadapp(self, app_spec, name, relative_to, **kw): return loadapp( app_spec, name=name, relative_to=relative_to, **kw) def daemonize(self): pid = live_pidfile(self.options.pid_file) if pid: raise DaemonizeException( "Daemon is already running (PID: %s from PID file %s)" % (pid, self.options.pid_file)) if self.verbose > 0: print('Entering daemon mode') pid = os.fork() if pid: # The forked process also has a handle on resources, so we # *don't* want proper termination of the process, we just # want to exit quick (which os._exit() does) os._exit(0) # Make this the session leader os.setsid() # Fork again for good measure! pid = os.fork() if pid: os._exit(0) # @@: Should we set the umask and cwd now? import resource # Resource usage information. maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] if (maxfd == resource.RLIM_INFINITY): maxfd = MAXFD # Iterate through and close all file descriptors. for fd in range(0, maxfd): try: os.close(fd) except OSError: # ERROR, fd wasn't open to begin with (ignored) pass if (hasattr(os, "devnull")): REDIRECT_TO = os.devnull else: REDIRECT_TO = "/dev/null" os.open(REDIRECT_TO, os.O_RDWR) # standard input (0) # Duplicate standard input to standard output and standard error. os.dup2(0, 1) # standard output (1) os.dup2(0, 2) # standard error (2) def record_pid(self, pid_file): pid = os.getpid() if self.verbose > 1: print('Writing PID %s to %s' % (pid, pid_file)) f = open(pid_file, 'w') f.write(str(pid)) f.close() atexit.register(_remove_pid_file, pid, pid_file, self.verbose) def stop_daemon(self): pid_file = self.options.pid_file or 'paster.pid' if not os.path.exists(pid_file): print('No PID file exists in %s' % pid_file) return 1 pid = read_pidfile(pid_file) if not pid: print("Not a valid PID file in %s" % pid_file) return 1 pid = live_pidfile(pid_file) if not pid: print("PID in %s is not valid (deleting)" % pid_file) try: os.unlink(pid_file) except (OSError, IOError) as e: print("Could not delete: %s" % e) return 2 return 1 for j in range(10): if not live_pidfile(pid_file): break import signal os.kill(pid, signal.SIGINT) time.sleep(1) for j in range(10): if not live_pidfile(pid_file): break import signal os.kill(pid, signal.SIGTERM) time.sleep(1) else: print("failed to kill web process %s" % pid) return 3 if os.path.exists(pid_file): os.unlink(pid_file) return 0 def show_status(self): pid_file = self.options.pid_file or 'paster.pid' if not os.path.exists(pid_file): print('No PID file %s' % pid_file) return 1 pid = read_pidfile(pid_file) if not pid: print('No PID in file %s' % pid_file) return 1 pid = live_pidfile(pid_file) if not pid: print('PID %s in %s is not running' % (pid, pid_file)) return 1 print('Server running in PID %s' % pid) return 0 def restart_with_reloader(self): self.restart_with_monitor(reloader=True) def restart_with_monitor(self, reloader=False): if self.verbose > 0: if reloader: print('Starting subprocess with file monitor') else: print('Starting subprocess with monitor parent') while 1: args = [self.quote_first_command_arg(sys.executable)] + sys.argv new_environ = os.environ.copy() if reloader: new_environ[self._reloader_environ_key] = 'true' else: new_environ[self._monitor_environ_key] = 'true' proc = None try: try: _turn_sigterm_into_systemexit() proc = subprocess.Popen(args, env=new_environ) exit_code = proc.wait() proc = None except KeyboardInterrupt: print('^C caught in monitor process') if self.verbose > 1: raise return 1 finally: if (proc is not None and hasattr(os, 'kill')): import signal try: os.kill(proc.pid, signal.SIGTERM) except (OSError, IOError): pass if reloader: # Reloader always exits with code 3; but if we are # a monitor, any exit code will restart if exit_code != 3: return exit_code if self.verbose > 0: print('-'*20, 'Restarting', '-'*20) def change_user_group(self, user, group): if not user and not group: return import pwd, grp uid = gid = None if group: try: gid = int(group) group = grp.getgrgid(gid).gr_name except ValueError: import grp try: entry = grp.getgrnam(group) except KeyError: raise BadCommand( "Bad group: %r; no such group exists" % group) gid = entry.gr_gid try: uid = int(user) user = pwd.getpwuid(uid).pw_name except ValueError: try: entry = pwd.getpwnam(user) except KeyError: raise BadCommand( "Bad username: %r; no such user exists" % user) if not gid: gid = entry.pw_gid uid = entry.pw_uid if self.verbose > 0: print('Changing user to %s:%s (%s:%s)' % ( user, group or '(unknown)', uid, gid)) if hasattr(os, 'initgroups'): os.initgroups(user, gid) else: os.setgroups([e.gr_gid for e in grp.getgrall() if user in e.gr_mem] + [gid]) if gid: os.setgid(gid) if uid: os.setuid(uid)
def _configureLogging(inputFile): from paste.script.command import Command c = Command('unused') c.logging_file_config(inputFile)
def __init__(self, name): Command.__init__(self, name) self.parser = Command.standard_parser(verbose=False) self.parser.add_option('-c', '--config', dest='config', default='development.ini', help='Config file to use.') return
class PViewsCommand(PCommand): """Print, for a given URL, the views that might match. Underneath each potentially matching route, list the predicates required. Underneath each route+predicate set, print each view that might match and its predicates. This command accepts two positional arguments: ``config_uri`` -- specifies the PasteDeploy config file to use for the interactive shell. The format is ``inifile#name``. If the name is left off, ``main`` will be assumed. ``url`` -- specifies the URL that will be used to find matching views. Example:: $ paster proutes myapp.ini#main url """ summary = "Print all views in an application that might match a URL" min_args = 2 max_args = 2 stdout = sys.stdout parser = Command.standard_parser(simulate=True) def out(self, msg): # pragma: no cover print msg def _find_multi_routes(self, mapper, request): infos = [] path = request.environ['PATH_INFO'] # find all routes that match path, regardless of predicates for route in mapper.get_routes(): match = route.match(path) if match is not None: info = {'match': match, 'route': route} infos.append(info) return infos def _find_view(self, url, registry): """ Accept ``url`` and ``registry``; create a :term:`request` and find a :app:`Pyramid` view based on introspection of :term:`view configuration` within the application registry; return the view. """ from zope.interface import providedBy from zope.interface import implements from pyramid.interfaces import IRequest from pyramid.interfaces import IRootFactory from pyramid.interfaces import IRouteRequest from pyramid.interfaces import IRequestFactory from pyramid.interfaces import IRoutesMapper from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import ITraverser from pyramid.request import Request from pyramid.traversal import DefaultRootFactory from pyramid.traversal import ResourceTreeTraverser q = registry.queryUtility root_factory = q(IRootFactory, default=DefaultRootFactory) routes_mapper = q(IRoutesMapper) request_factory = q(IRequestFactory, default=Request) adapters = registry.adapters request = None class RoutesMultiView(object): implements(IMultiView) def __init__(self, infos, context_iface, root_factory, request): self.views = [] for info in infos: match, route = info['match'], info['route'] if route is not None: request_iface = registry.queryUtility(IRouteRequest, name=route.name, default=IRequest) view = adapters.lookup( (IViewClassifier, request_iface, context_iface), IView, name='', default=None) if view is None: continue view.__request_attrs__ = {} view.__request_attrs__['matchdict'] = match view.__request_attrs__['matched_route'] = route root_factory = route.factory or root_factory root = root_factory(request) traverser = adapters.queryAdapter(root, ITraverser) if traverser is None: traverser = ResourceTreeTraverser(root) tdict = traverser(request) view.__request_attrs__.update(tdict) if not hasattr(view, '__view_attr__'): view.__view_attr__ = '' self.views.append((None, view, None)) # create the request environ = { 'wsgi.url_scheme': 'http', 'SERVER_NAME': 'localhost', 'SERVER_PORT': '8080', 'REQUEST_METHOD': 'GET', 'PATH_INFO': url, } request = request_factory(environ) context = None routes_multiview = None attrs = request.__dict__ attrs['registry'] = registry request_iface = IRequest # find the root object if routes_mapper is not None: infos = self._find_multi_routes(routes_mapper, request) if len(infos) == 1: info = infos[0] match, route = info['match'], info['route'] if route is not None: attrs['matchdict'] = match attrs['matched_route'] = route request.environ['bfg.routes.matchdict'] = match request_iface = registry.queryUtility(IRouteRequest, name=route.name, default=IRequest) root_factory = route.factory or root_factory if len(infos) > 1: routes_multiview = infos root = root_factory(request) attrs['root'] = root # find a context traverser = adapters.queryAdapter(root, ITraverser) if traverser is None: traverser = ResourceTreeTraverser(root) tdict = traverser(request) context, view_name, subpath, traversed, vroot, vroot_path = ( tdict['context'], tdict['view_name'], tdict['subpath'], tdict['traversed'], tdict['virtual_root'], tdict['virtual_root_path']) attrs.update(tdict) # find a view callable context_iface = providedBy(context) if routes_multiview is None: view = adapters.lookup( (IViewClassifier, request_iface, context_iface), IView, name=view_name, default=None) else: view = RoutesMultiView(infos, context_iface, root_factory, request) # routes are not registered with a view name if view is None: view = adapters.lookup( (IViewClassifier, request_iface, context_iface), IView, name='', default=None) # we don't want a multiview here if IMultiView.providedBy(view): view = None if view is not None: view.__request_attrs__ = attrs return view def output_route_attrs(self, attrs, indent): route = attrs['matched_route'] self.out("%sroute name: %s" % (indent, route.name)) self.out("%sroute pattern: %s" % (indent, route.pattern)) self.out("%sroute path: %s" % (indent, route.path)) self.out("%ssubpath: %s" % (indent, '/'.join(attrs['subpath']))) predicates = ', '.join([p.__text__ for p in route.predicates]) if predicates != '': self.out("%sroute predicates (%s)" % (indent, predicates)) def output_view_info(self, view_wrapper, level=1): indent = " " * level name = getattr(view_wrapper, '__name__', '') module = getattr(view_wrapper, '__module__', '') attr = getattr(view_wrapper, '__view_attr__', None) request_attrs = getattr(view_wrapper, '__request_attrs__', {}) if attr is not None: view_callable = "%s.%s.%s" % (module, name, attr) else: attr = view_wrapper.__class__.__name__ if attr == 'function': attr = name view_callable = "%s.%s" % (module, attr) self.out('') if 'matched_route' in request_attrs: self.out("%sRoute:" % indent) self.out("%s------" % indent) self.output_route_attrs(request_attrs, indent) permission = getattr(view_wrapper, '__permission__', None) if not IMultiView.providedBy(view_wrapper): # single view for this route, so repeat call without route data del request_attrs['matched_route'] self.output_view_info(view_wrapper, level + 1) else: self.out("%sView:" % indent) self.out("%s-----" % indent) self.out("%s%s" % (indent, view_callable)) permission = getattr(view_wrapper, '__permission__', None) if permission is not None: self.out("%srequired permission = %s" % (indent, permission)) predicates = getattr(view_wrapper, '__predicates__', None) if predicates is not None: predicate_text = ', '.join([p.__text__ for p in predicates]) self.out("%sview predicates (%s)" % (indent, predicate_text)) def command(self): config_uri, url = self.args if not url.startswith('/'): url = '/%s' % url env = self.bootstrap[0](config_uri) registry = env['registry'] view = self._find_view(url, registry) self.out('') self.out("URL = %s" % url) self.out('') if view is not None: self.out(" context: %s" % view.__request_attrs__['context']) self.out(" view name: %s" % view.__request_attrs__['view_name']) if IMultiView.providedBy(view): for dummy, view_wrapper, dummy in view.views: self.output_view_info(view_wrapper) if IMultiView.providedBy(view_wrapper): for dummy, mv_view_wrapper, dummy in view_wrapper.views: self.output_view_info(mv_view_wrapper, level=2) else: if view is not None: self.output_view_info(view) else: self.out(" Not found.") self.out('')
class PTweensCommand(PCommand): """Print all implicit and explicit :term:`tween` objects used by a Pyramid application. The handler output includes whether the system is using an explicit tweens ordering (will be true when the ``pyramid.tweens`` setting is used) or an implicit tweens ordering (will be true when the ``pyramid.tweens`` setting is *not* used). This command accepts one positional argument: ``config_uri`` -- specifies the PasteDeploy config file to use for the interactive shell. The format is ``inifile#name``. If the name is left off, ``main`` will be assumed. Example:: $ paster ptweens myapp.ini#main """ summary = "Print all tweens related to a Pyramid application" min_args = 1 max_args = 1 stdout = sys.stdout parser = Command.standard_parser(simulate=True) def _get_tweens(self, registry): from pyramid.config import Configurator config = Configurator(registry=registry) return config.registry.queryUtility(ITweens) def out(self, msg): # pragma: no cover print msg def show_chain(self, chain): fmt = '%-10s %-65s' self.out(fmt % ('Position', 'Name')) self.out(fmt % ('-' * len('Position'), '-' * len('Name'))) self.out(fmt % ('-', INGRESS)) for pos, (name, _) in enumerate(chain): self.out(fmt % (pos, name)) self.out(fmt % ('-', MAIN)) def command(self): config_uri = self.args[0] env = self.bootstrap[0](config_uri) registry = env['registry'] tweens = self._get_tweens(registry) if tweens is not None: explicit = tweens.explicit if explicit: self.out('"pyramid.tweens" config value set ' '(explicitly ordered tweens used)') self.out('') self.out('Explicit Tween Chain (used)') self.out('') self.show_chain(tweens.explicit) self.out('') self.out('Implicit Tween Chain (not used)') self.out('') self.show_chain(tweens.implicit()) else: self.out('"pyramid.tweens" config value NOT set ' '(implicitly ordered tweens used)') self.out('') self.out('Implicit Tween Chain') self.out('') self.show_chain(tweens.implicit())
class ControllerCommand(Command): """Create a Controller and accompanying functional test The Controller command will create the standard controller template file and associated functional test to speed creation of controllers. Example usage:: yourproj% paster controller comments Creating yourproj/yourproj/controllers/comments.py Creating yourproj/yourproj/tests/functional/test_comments.py If you'd like to have controllers underneath a directory, just include the path as the controller name and the necessary directories will be created for you:: yourproj% paster controller admin/trackback Creating yourproj/controllers/admin Creating yourproj/yourproj/controllers/admin/trackback.py Creating yourproj/yourproj/tests/functional/test_admin_trackback.py """ summary = __doc__.splitlines()[0] usage = '\n' + __doc__ min_args = 1 max_args = 1 group_name = 'pylons' default_verbosity = 3 parser = Command.standard_parser(simulate=True) parser.add_option('--no-test', action='store_true', dest='no_test', help="Don't create the test; just the controller") def command(self): """Main command to create controller""" try: file_op = FileOp(source_dir=('pylons', 'templates')) try: name, directory = file_op.parse_path_name_args(self.args[0]) except: raise BadCommand('No egg_info directory was found') # Check the name isn't the same as the package base_package = file_op.find_dir('controllers', True)[0] if base_package.lower() == name.lower(): raise BadCommand( 'Your controller name should not be the same as ' 'the package name %r.' % base_package) # Validate the name name = name.replace('-', '_') validate_name(name) # Determine the module's import statement if is_minimal_template(base_package): importstatement = ('from %s.controllers import BaseController' % base_package) else: importstatement = ('from %s.lib.base import BaseController' % base_package) if defines_render(base_package): importstatement += ', render' # Setup the controller fullname = os.path.join(directory, name) controller_name = util.class_name_from_module_name( name.split('/')[-1]) if not fullname.startswith(os.sep): fullname = os.sep + fullname testname = fullname.replace(os.sep, '_')[1:] module_dir = directory.replace('/', os.path.sep) check_controller_existence(base_package, module_dir, name) file_op.template_vars.update( {'name': controller_name, 'fname': os.path.join(directory, name).replace('\\', '/'), 'tmpl_name': name, 'package': base_package, 'importstatement': importstatement}) file_op.copy_file(template='controller.py_tmpl', dest=os.path.join('controllers', directory), filename=name, template_renderer=paste_script_template_renderer) if not self.options.no_test: file_op.copy_file( template='test_controller.py_tmpl', dest=os.path.join('tests', 'functional'), filename='test_' + testname, template_renderer=paste_script_template_renderer) except BadCommand, e: raise BadCommand('An error occurred. %s' % e) except:
class LoadAppCommand(Command): """Load the app and all associated StackedObjectProxies. Useful for batch scripts. The optional CONFIG_FILE argument specifies the config file to use for the interactive shell. CONFIG_FILE defaults to 'development.ini'. This allows you to test your mapper, models, and simulate web requests using ``paste.fixture``. This class has been adapted from pylons.commands.ShellCommand. """ summary = __doc__.splitlines()[0] min_args = 0 max_args = 1 group_name = 'pylons' parser = Command.standard_parser() parser.add_option('-q', action='count', dest='quiet', default=0, help="Do not load logging configuration from the config file") def __init__(self, name, summary): self.summary = summary Command.__init__(self, name) def command(self): """Main command to create a new shell""" self.verbose = 3 if len(self.args) == 0: # Assume the .ini file is ./development.ini config_file = 'development.ini' if not os.path.isfile(config_file): raise BadCommand('CONFIG_FILE not found at: .%s%s\n' 'Please specify a CONFIG_FILE' % \ (os.path.sep, config_file) ) else: config_file = self.args[0] config_name = 'config:%s' % config_file here_dir = os.getcwd() if not self.options.quiet: # Configure logging from the config file self.logging_file_config(config_file) # XXX: Note, initializing CONFIG here is Legacy support. pylons.config # will automatically be initialized and restored via the registry # restorer along with the other StackedObjectProxys # Load app config into paste.deploy to simulate request config # Setup the Paste CONFIG object, adding app_conf/global_conf for legacy # code conf = appconfig(config_name, relative_to=here_dir) conf.update(dict(app_conf=conf.local_conf, global_conf=conf.global_conf)) paste.deploy.config.CONFIG.push_thread_config(conf) # Load locals and populate with objects for use in shell sys.path.insert(0, here_dir) # Load the wsgi app first so that everything is initialized right wsgiapp = loadapp(config_name, relative_to=here_dir) test_app = paste.fixture.TestApp(wsgiapp) # Query the test app to setup the environment tresponse = test_app.get('/_test_vars') request_id = int(tresponse.body) # Disable restoration during test_app requests test_app.pre_request_hook = lambda self: \ paste.registry.restorer.restoration_end() test_app.post_request_hook = lambda self: \ paste.registry.restorer.restoration_begin(request_id) # Restore the state of the Pylons special objects # (StackedObjectProxies) paste.registry.restorer.restoration_begin(request_id) def parse_args(self, args): self.options, self.args = self.parser.parse_args(args)
def __init__(self, name): Command.__init__(self, name) self._report_callback = lambda : None
class RestControllerCommand(Command): """Create a REST Controller and accompanying functional test The RestController command will create a REST-based Controller file for use with the :meth:`~routes.mapper.Mapper.resource` REST-based dispatching. This template includes the methods that :meth:`~routes.mapper.Mapper.resource` dispatches to in addition to doc strings for clarification on when the methods will be called. The first argument should be the singular form of the REST resource. The second argument is the plural form of the word. If its a nested controller, put the directory information in front as shown in the second example below. Example usage:: yourproj% paster restcontroller comment comments Creating yourproj/yourproj/controllers/comments.py Creating yourproj/yourproj/tests/functional/test_comments.py If you'd like to have controllers underneath a directory, just include the path as the controller name and the necessary directories will be created for you:: yourproj% paster restcontroller admin/tracback admin/trackbacks Creating yourproj/controllers/admin Creating yourproj/yourproj/controllers/admin/trackbacks.py Creating yourproj/yourproj/tests/functional/test_admin_trackbacks.py """ summary = __doc__.splitlines()[0] usage = '\n' + __doc__ min_args = 2 max_args = 2 group_name = 'pylons' default_verbosity = 3 parser = Command.standard_parser(simulate=True) parser.add_option('--no-test', action='store_true', dest='no_test', help="Don't create the test; just the controller") def command(self): """Main command to create controller""" try: file_op = FileOp(source_dir=('pylons', 'templates')) try: singularname, singulardirectory = \ file_op.parse_path_name_args(self.args[0]) pluralname, pluraldirectory = \ file_op.parse_path_name_args(self.args[1]) except: raise BadCommand('No egg_info directory was found') # Check the name isn't the same as the package base_package = file_op.find_dir('controllers', True)[0] if base_package.lower() == pluralname.lower(): raise BadCommand( 'Your controller name should not be the same as ' 'the package name %r.' % base_package) # Validate the name for name in [pluralname]: name = name.replace('-', '_') validate_name(name) # Determine the module's import statement if is_minimal_template(base_package): importstatement = ('from %s.controllers import BaseController' % base_package) else: importstatement = ('from %s.lib.base import BaseController' % base_package) if defines_render(base_package): importstatement += ', render' module_dir = pluraldirectory.replace('/', os.path.sep) check_controller_existence(base_package, module_dir, name) # Setup the controller fullname = os.path.join(pluraldirectory, pluralname) controller_name = util.class_name_from_module_name( pluralname.split('/')[-1]) if not fullname.startswith(os.sep): fullname = os.sep + fullname testname = fullname.replace(os.sep, '_')[1:] nameprefix = '' path = '' if pluraldirectory: nameprefix = pluraldirectory.replace(os.path.sep, '_') + '_' path = pluraldirectory + '/' controller_c = '' if nameprefix: controller_c = ", controller='%s', \n\t" % \ '/'.join([pluraldirectory, pluralname]) controller_c += "path_prefix='/%s', name_prefix='%s'" % \ (pluraldirectory, nameprefix) command = "map.resource('%s', '%s'%s)\n" % \ (singularname, pluralname, controller_c) file_op.template_vars.update( {'classname': controller_name, 'pluralname': pluralname, 'singularname': singularname, 'name': controller_name, 'nameprefix': nameprefix, 'package': base_package, 'path': path, 'resource_command': command.replace('\n\t', '\n%s#%s' % \ (' ' * 4, ' ' * 9)), 'fname': os.path.join(pluraldirectory, pluralname), 'importstatement': importstatement}) resource_command = ("\nTo create the appropriate RESTful mapping, " "add a map statement to your\n") resource_command += ("config/routing.py file near the top like " "this:\n\n") resource_command += command file_op.copy_file(template='restcontroller.py_tmpl', dest=os.path.join('controllers', pluraldirectory), filename=pluralname, template_renderer=paste_script_template_renderer) if not self.options.no_test: file_op.copy_file( template='test_restcontroller.py_tmpl', dest=os.path.join('tests', 'functional'), filename='test_' + testname, template_renderer=paste_script_template_renderer) print resource_command except BadCommand, e: raise BadCommand('An error occurred. %s' % e) except:
class PRoutesCommand(PCommand): """Print all URL dispatch routes used by a Pyramid application in the order in which they are evaluated. Each route includes the name of the route, the pattern of the route, and the view callable which will be invoked when the route is matched. This command accepts two positional arguments: ``config_file`` -- specifies the PasteDeploy config file to use for the interactive shell. ``section_name`` -- specifies the section name in the PasteDeploy config file that represents the application. Example:: $ paster proutes myapp.ini main .. note:: You should use a ``section_name`` that refers to the actual ``app`` section in the config file that points at your Pyramid app without any middleware wrapping, or this command will almost certainly fail. """ summary = "Print all URL dispatch routes related to a Pyramid application" min_args = 2 max_args = 2 stdout = sys.stdout parser = Command.standard_parser(simulate=True) def _get_mapper(self, app): from pyramid.config import Configurator registry = app.registry config = Configurator(registry=registry) return config.get_routes_mapper() def out(self, msg): # pragma: no cover print msg def command(self): from pyramid.interfaces import IRouteRequest from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IView from zope.interface import Interface config_file, section_name = self.args app = self.get_app(config_file, section_name, loadapp=self.loadapp[0]) registry = app.registry mapper = self._get_mapper(app) if mapper is not None: routes = mapper.get_routes() fmt = '%-15s %-30s %-25s' if not routes: return self.out(fmt % ('Name', 'Pattern', 'View')) self.out( fmt % ('-' * len('Name'), '-' * len('Pattern'), '-' * len('View'))) for route in routes: request_iface = registry.queryUtility(IRouteRequest, name=route.name) view_callable = None if (request_iface is None) or (route.factory is not None): self.out(fmt % (route.name, route.pattern, '<unknown>')) else: view_callable = registry.adapters.lookup( (IViewClassifier, request_iface, Interface), IView, name='', default=None) self.out(fmt % (route.name, route.pattern, view_callable))
class ShellCommand(Command): """Open an interactive shell with the Pylons app loaded The optional CONFIG_FILE argument specifies the config file to use for the interactive shell. CONFIG_FILE defaults to 'development.ini'. This allows you to test your mapper, models, and simulate web requests using ``paste.fixture``. Example:: $ paster shell my-development.ini """ summary = __doc__.splitlines()[0] usage = '\n' + __doc__ min_args = 0 max_args = 1 group_name = 'pylons' parser = Command.standard_parser(simulate=True) parser.add_option('-d', '--disable-ipython', action='store_true', dest='disable_ipython', help="Don't use IPython if it is available") parser.add_option('-q', action='count', dest='quiet', default=0, help=("Do not load logging configuration from the " "config file")) def command(self): """Main command to create a new shell""" self.verbose = 3 if len(self.args) == 0: # Assume the .ini file is ./development.ini config_file = 'development.ini' if not os.path.isfile(config_file): raise BadCommand('%sError: CONFIG_FILE not found at: .%s%s\n' 'Please specify a CONFIG_FILE' % \ (self.parser.get_usage(), os.path.sep, config_file)) else: config_file = self.args[0] config_name = 'config:%s' % config_file here_dir = os.getcwd() locs = dict(__name__="pylons-admin") if not self.options.quiet: # Configure logging from the config file self.logging_file_config(config_file) # Load locals and populate with objects for use in shell sys.path.insert(0, here_dir) # Load the wsgi app first so that everything is initialized right wsgiapp = loadapp(config_name, relative_to=here_dir) test_app = paste.fixture.TestApp(wsgiapp) # Query the test app to setup the environment tresponse = test_app.get('/_test_vars') request_id = int(tresponse.body) # Disable restoration during test_app requests test_app.pre_request_hook = lambda self: \ paste.registry.restorer.restoration_end() test_app.post_request_hook = lambda self: \ paste.registry.restorer.restoration_begin(request_id) # Restore the state of the Pylons special objects # (StackedObjectProxies) paste.registry.restorer.restoration_begin(request_id) # Determine the package name from the pylons.config object pkg_name = pylons.config['pylons.package'] # Start the rest of our imports now that the app is loaded if is_minimal_template(pkg_name, True): model_module = None helpers_module = pkg_name + '.helpers' base_module = pkg_name + '.controllers' else: model_module = pkg_name + '.model' helpers_module = pkg_name + '.lib.helpers' base_module = pkg_name + '.lib.base' if model_module and can_import(model_module): locs['model'] = sys.modules[model_module] if can_import(helpers_module): locs['h'] = sys.modules[helpers_module] exec ('from pylons import app_globals, config, request, response, ' 'session, tmpl_context, url') in locs exec ('from pylons.controllers.util import abort, redirect') in locs exec 'from pylons.i18n import _, ungettext, N_' in locs locs.pop('__builtins__', None) # Import all objects from the base module __import__(base_module) base = sys.modules[base_module] base_public = [__name for __name in dir(base) if not \ __name.startswith('_') or __name == '_'] locs.update((name, getattr(base, name)) for name in base_public) locs.update(dict(wsgiapp=wsgiapp, app=test_app)) mapper = tresponse.config.get('routes.map') if mapper: locs['mapper'] = mapper banner = " All objects from %s are available\n" % base_module banner += " Additional Objects:\n" if mapper: banner += " %-10s - %s\n" % ('mapper', 'Routes mapper object') banner += " %-10s - %s\n" % ('wsgiapp', "This project's WSGI App instance") banner += " %-10s - %s\n" % ('app', 'paste.fixture wrapped around wsgiapp') try: if self.options.disable_ipython: raise ImportError() # try to use IPython if possible try: # ipython >= 0.11 from IPython.frontend.terminal.embed import InteractiveShellEmbed shell = InteractiveShellEmbed(banner2=banner) except ImportError: # ipython < 0.11 from IPython.Shell import IPShellEmbed shell = IPShellEmbed(argv=self.args) shell.set_banner(shell.IP.BANNER + '\n\n' + banner) try: shell(local_ns=locs, global_ns={}) finally: paste.registry.restorer.restoration_end() except ImportError: import code py_prefix = sys.platform.startswith('java') and 'J' or 'P' newbanner = "Pylons Interactive Shell\n%sython %s\n\n" % \ (py_prefix, sys.version) banner = newbanner + banner shell = code.InteractiveConsole(locals=locs) try: import readline except ImportError: pass try: shell.interact(banner) finally: paste.registry.restorer.restoration_end()
def __init__(self, *arg, **kw): # needs to be in constructor to support Jython (used to be at class # scope as ``usage = '\n' + __doc__``. self.usage = '\n' + self.__doc__ Command.__init__(self, *arg, **kw)
def __init__(self, name, summary): self.summary = summary Command.__init__(self, name)
class ShellCommand(Command): """Open an interactive shell with the Pylons app loaded The optional CONFIG_FILE argument specifies the config file to use for the interactive shell. CONFIG_FILE defaults to 'development.ini'. This allows you to test your mapper, models, and simulate web requests using ``paste.fixture``. Example:: $ paster shell my-development.ini """ summary = __doc__.splitlines()[0] usage = '\n' + __doc__ min_args = 0 max_args = 1 group_name = 'pylons' parser = Command.standard_parser(simulate=True) parser.add_option('-d', '--disable-ipython', action='store_true', dest='disable_ipython', help="Don't use IPython if it is available") parser.add_option( '-q', action='count', dest='quiet', default=0, help="Do not load logging configuration from the config file") def command(self): """Main command to create a new shell""" self.verbose = 3 if len(self.args) == 0: # Assume the .ini file is ./development.ini config_file = 'development.ini' if not os.path.isfile(config_file): raise BadCommand('%sError: CONFIG_FILE not found at: .%s%s\n' 'Please specify a CONFIG_FILE' % \ (self.parser.get_usage(), os.path.sep, config_file)) else: config_file = self.args[0] config_name = 'config:%s' % config_file here_dir = os.getcwd() locs = dict(__name__="pylons-admin") # XXX: Note, initializing CONFIG here is Legacy support. pylons.config # will automatically be initialized and restored via the registry # restorer along with the other StackedObjectProxys # Load app config into paste.deploy to simulate request config # Setup the Paste CONFIG object, adding app_conf/global_conf for legacy # code conf = appconfig(config_name, relative_to=here_dir) conf.update( dict(app_conf=conf.local_conf, global_conf=conf.global_conf)) paste.deploy.config.CONFIG.push_thread_config(conf) # Load locals and populate with objects for use in shell sys.path.insert(0, here_dir) # Load the wsgi app first so that everything is initialized right wsgiapp = loadapp(config_name, relative_to=here_dir) test_app = paste.fixture.TestApp(wsgiapp) # Query the test app to setup the environment tresponse = test_app.get('/_test_vars') request_id = int(tresponse.body) # Disable restoration during test_app requests test_app.pre_request_hook = lambda self: \ paste.registry.restorer.restoration_end() test_app.post_request_hook = lambda self: \ paste.registry.restorer.restoration_begin(request_id) # Restore the state of the Pylons special objects # (StackedObjectProxies) paste.registry.restorer.restoration_begin(request_id) # Determine the package name from the .egg-info top_level.txt. egg_info = find_egg_info_dir(here_dir) f = open(os.path.join(egg_info, 'top_level.txt')) packages = [ l.strip() for l in f.readlines() if l.strip() and not l.strip().startswith('#') ] f.close() # Start the rest of our imports now that the app is loaded found_base = False for pkg_name in packages: # Import all objects from the base module base_module = pkg_name + '.lib.base' found_base = can_import(base_module) if not found_base: # Minimal template base_module = pkg_name + '.controllers' found_base = can_import(base_module) if found_base: break if not found_base: raise ImportError("Could not import base module. Are you sure " "this is a Pylons app?") base = sys.modules[base_module] base_public = [__name for __name in dir(base) if not \ __name.startswith('_') or __name == '_'] for name in base_public: locs[name] = getattr(base, name) locs.update(dict(wsgiapp=wsgiapp, app=test_app)) mapper = tresponse.config.get('routes.map') if mapper: locs['mapper'] = mapper banner = " All objects from %s are available\n" % base_module banner += " Additional Objects:\n" if mapper: banner += " %-10s - %s\n" % ('mapper', 'Routes mapper object') banner += " %-10s - %s\n" % ('wsgiapp', "This project's WSGI App instance") banner += " %-10s - %s\n" % ('app', 'paste.fixture wrapped around wsgiapp') if not self.options.quiet: # Configure logging from the config file self.logging_file_config(config_file) try: if self.options.disable_ipython: raise ImportError() # try to use IPython if possible from IPython.Shell import IPShellEmbed shell = IPShellEmbed(argv=self.args) shell.set_banner(shell.IP.BANNER + '\n\n' + banner) try: shell(local_ns=locs, global_ns={}) finally: paste.registry.restorer.restoration_end() except ImportError: import code newbanner = "Pylons Interactive Shell\nPython %s\n\n" % sys.version banner = newbanner + banner shell = code.InteractiveConsole(locals=locs) try: import readline except ImportError: pass try: shell.interact(banner) finally: paste.registry.restorer.restoration_end()