# Based on devtools.commands.quickstart.py by TurboGears Team 2008 # Used under the MIT License # import pkg_resources import re import optparse from paste.script import command from paste.script import create_distro import os, pwd, sys import stat import string, random import readline, getpass beginning_letter = re.compile(r"^[^a-z]*") valid_only = re.compile(r"[^a-z0-9_]") class BazstartCommand(command.Command): """Create a new Bazki project. Create a new Bazki project with this command. Example usage:: $ paster bazstart yourproject """ version = pkg_resources.get_distribution('Bazki').version tgversion = pkg_resources.get_distribution('turbogears2').version max_args = 3 min_args = 0 summary = __doc__.splitlines()[0] usage = '\n' + __doc__ group_name = "Bazki" name = None package = None dburl = None username = None elmname = None password = None svn_repository = None templates = "bazki" dry_run = False no_input = False secret = ''.join(random.choice(string.lowercase) for x in xrange(16)) bazkitype = 'bazki' extra_db = None custom_db = None remove_db = None admin_path = 'Object/User/Admin' admin = 'Admin' extra_controllers = [] statics = ['bazki'] urlprefix = None suppress_output = False repo = None parser = command.Command.standard_parser(quiet=True) parser = optparse.OptionParser( usage="%prog quickstart [options] [project name]", version="%prog " + version) parser.add_option("-p", "--package", help="package name for the code", dest="package") parser.add_option("-r", "--svn-repository", metavar="REPOS", help="create project in given SVN repository", dest="svn_repository", default=svn_repository) parser.add_option("-d", "--dburl", help="specify URL for database used", dest="dburl") parser.add_option("-u", "--username", help="specify username for initial admin user", dest="username") parser.add_option("-e", "--elmname", help="specify element name for inital admin user", dest="elmname") parser.add_option("-P", "--password", help="specify password for initial admin user", dest="password") parser.add_option( "--urlprefix", help="specify the public urlprefix for this site", dest="urlprefix") parser.add_option("--custom-db", help="specify a tree of extra custom database yaml files " "(used for tests)", dest="custom_db") parser.add_option( "--remove-db", help="specify a path in the initial db to remove (used for tests)", dest="remove_db") parser.add_option("--dry-run", help="dry run (don't actually do anything)", action="store_true", dest="dry_run") parser.add_option("-q", "--quiet", help="suppress output", action="store_true", dest="suppress_output") parser.add_option("--noinput", help="no input (don't ask any questions)", action="store_true", dest="no_input") def command(self): """Quickstarts the new project.""" for k in self.options.__dict__: if self.options.__dict__[k] is not None: self.__dict__[k] = self.options.__dict__[k] if self.args: self.name = self.args[0] while not self.name: self.name = raw_input("Enter project name: ") if self.package is None: package = self.name.lower() package = beginning_letter.sub("", package) package = valid_only.sub("", package) if package and self.no_input: self.package = package else: self.package = None while not self.package: self.package = raw_input( "Enter package name [%s]: " % package).strip() or package if self.dburl is None: dburl=('mysql://sql.mit.edu/%s+%s?read_default_file=%s' % (getpass.getuser(), self.package, os.path.expanduser('~/.my.cnf'))) if self.no_input: self.dburl = dburl else: while not self.dburl: self.dburl = raw_input( "Enter database URL, of the form mysql://hostname/dbname?read_default_file=~/.my.cnf [%s]: " % dburl).strip() or dburl if self.username is None: username=pwd.getpwuid(os.getuid())[0] if self.no_input: self.username = username else: while not self.username: self.username = raw_input( "Enter username for initial admin user [%s]: " % username).strip() or username if self.elmname is None: elmname=self.username[0].upper()+self.username[1:] if self.no_input: self.elmname = elmname else: while not self.elmname: self.elmname = raw_input( "Enter element name for initial admin user [%s]: " % elmname).strip() or elmname if self.password is None: if self.no_input: self.password = ''.join(random.choice(string.lowercase) for x in xrange(16)) else: while not self.password: self.password = getpass.getpass( "Enter password for initial admin user (visible to anyone with edit access): ") if self.urlprefix is None: urlprefix = 'http://%s.scripts.mit.edu/%s' % (getpass.getuser(), self.package) if self.no_input: self.urlprefix = urlprefix else: while not self.urlprefix: self.urlprefix = raw_input( "Enter public URL prefix [%s]: " % urlprefix).strip() or urlprefix self.name = pkg_resources.safe_name(self.name) env = pkg_resources.Environment() if self.name.lower() in env: print 'The name "%s" is already in use by' % self.name, for dist in env[self.name]: print dist return import imp try: if imp.find_module(self.package): print 'The package name "%s" is already in use' % self.package return except ImportError: pass if os.path.exists(self.name): print 'A directory called "%s" already exists. Exiting.' % self.name return command = create_distro.CreateDistroCommand("create") cmd_args = [] for template in self.templates.split(): cmd_args.append("--template=%s" % template) if self.svn_repository: cmd_args.append("--svn-repository=%s" % self.svn_repository) if self.dry_run: cmd_args.append("--simulate") cmd_args.append("-q") if self.suppress_output: cmd_args.append("-q") cmd_args.append(self.name) cmd_args.append("package=%s" % self.package) cmd_args.append("bazversion=%s" % self.version) cmd_args.append("tgversion=%s" % self.tgversion) cmd_args.append("dburl=%s" % self.dburl) cmd_args.append("username=%s" % self.username) cmd_args.append("elmname=%s" % self.elmname) cmd_args.append("password=%s" % self.password) cmd_args.append("secret=%s" % self.secret) cmd_args.append("projectroot=%s" % os.path.abspath(self.name)) cmd_args.append("bazkitype=%s" % self.bazkitype) cmd_args.append("admin=%s" % self.admin) cmd_args.append("extra_controllers=%s" % ';'.join(self.extra_controllers)) cmd_args.append("statics=%s" % ';'.join(self.statics)) cmd_args.append("urlprefix=%s" % self.urlprefix) # Sitedir hack # # To use this hack, put the following at the start of ~/bin/paster: ## import site ## # sitedir hack ## __paster_sitedir__='/mit/xavid/lib/python2.5/site-packages/' ## site.addsitedir(__paster_sitedir__) import __main__ if hasattr(__main__,'__paster_sitedir__'): print >>sys.stderr, "Using sitedir:", __main__.__paster_sitedir__ sitedir = __main__.__paster_sitedir__ else: sitedir = '' cmd_args.append("sitedir=%s" % sitedir) command.run(cmd_args) if not self.dry_run: os.chdir(self.name) for path in ['precommit.py', 'clear-database.py', 'prod.py', 'webroot/dispatch.fcgi']: if os.path.exists(path): oldmode = os.stat(path).st_mode os.chmod(path, oldmode | stat.S_IXUSR) sys.argv = ["setup.py", "egg_info"] import imp imp.load_module("setup", *imp.find_module("setup", ["."])) # dirty hack to allow "empty" dirs for base, path, files in os.walk("./"): for file in files: if file == "empty": os.remove(os.path.join(base, file)) # Create "public" and "bazki" symlinks os.symlink(os.path.join('..', self.package, 'public'), os.path.join('webroot','__public')) bazlib = os.path.dirname(os.path.dirname( os.path.abspath(__file__))) for s in self.statics: os.symlink(os.path.join(bazlib, s, 'static'), os.path.join('webroot', s)) # Initialize the database using a subversion import from . import bootstrap bootstrap.bootstrap(self.name, self.package, self.suppress_output, self.username,self.elmname,self.password, self.bazkitype, self.extra_db, self.custom_db, self.remove_db.split(':') if self.remove_db else [], self.admin_path, self.urlprefix, self.repo)