diff --git a/webnotes/install_lib/install.py b/webnotes/install_lib/install.py index 27c0d1047b..2e090d9b31 100755 --- a/webnotes/install_lib/install.py +++ b/webnotes/install_lib/install.py @@ -8,77 +8,100 @@ from __future__ import unicode_literals import os, sys, json import webnotes -from webnotes import conf import webnotes.db import getpass + from webnotes.model.db_schema import DbManager from webnotes.model.sync import sync_for class Installer: - def __init__(self, root_login, root_password=None): + def __init__(self, root_login, root_password=None, db_name=None, site=None): + make_conf(db_name, site=site) + self.site = site + + self.make_connection(root_login, root_password, site) + + webnotes.local.conn = self.conn + webnotes.local.session = webnotes._dict({'user':'Administrator'}) + + self.dbman = DbManager(self.conn) + + def make_connection(self, root_login, root_password, site): if root_login: if not root_password: - root_password = conf.get("root_password") or None + try: + webnotes.init(site=site) + root_password = webnotes.conf.get("root_password") or None + except ImportError: + pass + if not root_password: root_password = getpass.getpass("MySQL root password: ") self.root_password = root_password self.conn = webnotes.db.Database(user=root_login, password=root_password) - webnotes.local.conn = self.conn - webnotes.local.session = webnotes._dict({'user':'Administrator'}) + def install(self, db_name, source_sql=None, admin_password = 'admin', verbose=0, + force=0): - self.dbman = DbManager(self.conn) - - def import_from_db(self, target, source_path='', password = 'admin', verbose=0): - """ - a very simplified version, just for the time being..will eventually be deprecated once the framework stabilizes. - """ - # delete user (if exists) - self.dbman.delete_user(target) + if force or (db_name not in self.dbman.get_database_list()): + # delete user (if exists) + self.dbman.delete_user(db_name) + else: + raise Exception("Database %s already exists" % (db_name,)) # create user and db - self.dbman.create_user(target, conf.db_password) + self.dbman.create_user(db_name, webnotes.conf.db_password) - if verbose: print "Created user %s" % target + if verbose: print "Created user %s" % db_name # create a database - self.dbman.create_database(target) - if verbose: print "Created database %s" % target + self.dbman.create_database(db_name) + if verbose: print "Created database %s" % db_name # grant privileges to user - self.dbman.grant_all_privileges(target,target) - if verbose: print "Granted privileges to user %s and database %s" % (target, target) + self.dbman.grant_all_privileges(db_name, db_name) + if verbose: print "Granted privileges to user %s and database %s" % (db_name, db_name) # flush user privileges self.dbman.flush_privileges() + + # close root connection + self.conn.close() - self.conn.use(target) + webnotes.connect(db_name=db_name, site=self.site) + self.dbman = DbManager(webnotes.conn) - # import in target + # import in db_name if verbose: print "Starting database import..." # get the path of the sql file to import - source_given = True - if not source_path: - source_given = False - source_path = os.path.join(os.path.dirname(webnotes.__file__), "..", 'conf', 'Framework.sql') + if not source_sql: + source_sql = os.path.join(os.path.dirname(webnotes.__file__), "..", + 'conf', 'Framework.sql') - self.dbman.restore_database(target, source_path, target, conf.db_password) - if verbose: print "Imported from database %s" % source_path + self.dbman.restore_database(db_name, source_sql, db_name, webnotes.conf.db_password) + if verbose: print "Imported from database %s" % source_sql + + self.create_auth_table() # fresh app - if 'Framework.sql' in source_path: + if 'Framework.sql' in source_sql: print "Installing app..." self.install_app() # update admin password - self.create_auth_table() - self.update_admin_password(password) + self.update_admin_password(admin_password) - self.conn.close() - - return target + # create public folder + from webnotes.install_lib import setup_public_folder + setup_public_folder.make(site=self.site) + + if not self.site: + from webnotes.build import bundle + bundle(False) + + return db_name def install_app(self): sync_for("lib", force=True, sync_everything=True) @@ -104,7 +127,7 @@ class Installer: def update_admin_password(self, password): from webnotes.auth import _update_password webnotes.conn.begin() - _update_password("Administrator", conf.get("admin_password") or password) + _update_password("Administrator", webnotes.conf.get("admin_password") or password) webnotes.conn.commit() @@ -151,12 +174,68 @@ class Installer: webnotes.conn.commit() def create_auth_table(self): - webnotes.conn.sql("""drop table if exists __Auth""") - webnotes.conn.sql("""create table __Auth ( - `user` VARCHAR(180) NOT NULL PRIMARY KEY, - `password` VARCHAR(180) NOT NULL - ) ENGINE=InnoDB DEFAULT CHARSET=utf8""") - + webnotes.conn.sql_ddl("""drop table if exists __Auth""") + webnotes.conn.sql_ddl("""create table __Auth ( + `user` VARCHAR(180) NOT NULL PRIMARY KEY, + `password` VARCHAR(180) NOT NULL + ) ENGINE=InnoDB DEFAULT CHARSET=utf8""") + +def make_conf(db_name=None, db_password=None, site=None, site_config=None): + try: + import conf + + if site: + # conf exists and site is specified, create site_config.json + make_site_config(site, db_name, db_password, site_config) + elif os.path.exists("conf.py"): + print "conf.py exists" + else: + # pyc file exists but py doesn't + raise ImportError + + except ImportError: + if site: + raise Exception("conf.py does not exist") + else: + # create conf.py + with open(os.path.join("lib", "conf", "conf.py"), "r") as confsrc: + with open("conf.py", "w") as conftar: + conftar.write(confsrc.read() % get_conf_params(db_name, db_password)) + + webnotes.destroy() + webnotes.init(site=site) + +def make_site_config(site, db_name=None, db_password=None, site_config=None): + import conf + if not getattr(conf, "sites_dir", None): + raise Exception("sites_dir missing in conf.py") + + site_path = os.path.join(conf.sites_dir, site) + + if not os.path.exists(site_path): + os.mkdir(site_path) + + site_file = os.path.join(site_path, "site_config.json") + + if not os.path.exists(site_file): + if not site_config: + site_config = get_conf_params(db_name, db_password) + + with open(site_file, "w") as f: + f.write(json.dumps(site_config, indent=1)) + +def get_conf_params(db_name=None, db_password=None): + if not db_name: + db_name = raw_input("Database Name: ") + if not db_name: + raise Exception("Database Name Required") + + if not db_password: + from webnotes.utils import random_string + db_password = random_string(16) + + return {"db_name": db_name, "db_password": db_password} + def install_fixtures(): print "Importing install fixtures..." for basepath, folders, files in os.walk(os.path.join("app", "startup", "install_fixtures")): diff --git a/webnotes/install_lib/setup_public_folder.py b/webnotes/install_lib/setup_public_folder.py index 7777c0a090..2d416bf58d 100644 --- a/webnotes/install_lib/setup_public_folder.py +++ b/webnotes/install_lib/setup_public_folder.py @@ -5,26 +5,37 @@ from __future__ import unicode_literals import os +import webnotes -def make(): +def make(site=None): """make public folder symlinks if missing""" + from webnotes.utils import get_site_base_path, get_base_path, get_path - dirs = ["public", "public/js", "public/css", "public/files", "public/backups"] + webnotes.init(site=site) - for dirname in dirs: - if not os.path.exists(dirname): - os.mkdir(dirname) + site_path = get_site_base_path() if site else get_base_path() - os.chdir("public") + # setup standard folders + for param in ("public_path", "backup_path", "files_path"): + path = os.path.join(site_path, webnotes.conf.get(param)) + if not os.path.exists(path): + os.mkdir(path) - symlinks = [ - ["app", "../app/public"], - ["lib", "../lib/public"], - ["unsupported.html", "../lib/public/html/unsupported.html"] - ] + # setup js and css folders + if not site: + for folder in ("js", "css"): + path = get_path(webnotes.conf.public_path, folder) + if not os.path.exists(path): + os.mkdir(path) + + os.chdir(webnotes.conf.public_path) + symlinks = [ + ["app", "../app/public"], + ["lib", "../lib/public"], + ] - for link in symlinks: - if not os.path.exists(link[0]) and os.path.exists(link[1]): - os.symlink(link[1], link[0]) - - os.chdir('..') + for link in symlinks: + if not os.path.exists(link[0]) and os.path.exists(link[1]): + os.symlink(link[1], link[0]) + + os.chdir("..") diff --git a/webnotes/utils/__init__.py b/webnotes/utils/__init__.py index 0e13c269cd..2f5868ff57 100644 --- a/webnotes/utils/__init__.py +++ b/webnotes/utils/__init__.py @@ -826,8 +826,10 @@ def get_site_base_path(sites_dir=None, hostname=None): if conf and not conf.sites_dir: return get_base_path() - if not sites_dir and not hostname: + if not sites_dir: sites_dir = conf.sites_dir + + if not hostname: hostname = conf.site import os diff --git a/wnf.py b/wnf.py index ff34499535..fce904c27a 100755 --- a/wnf.py +++ b/wnf.py @@ -43,6 +43,8 @@ def setup_parser(): # common parser.add_argument("-f", "--force", default=False, action="store_true", help="Force execution where applicable (look for [-f] in help)") + parser.add_argument("--site", nargs="?", metavar="SITE-NAME or all", + help="Run for a particular site") return parser.parse_args() @@ -88,7 +90,7 @@ def setup_utilities(parser): help="Build docs") parser.add_argument("--domain", nargs="*", help="Get or set domain in Website Settings") - parser.add_argument("--make_conf", default=False, action="store_true", + parser.add_argument("--make_conf", nargs="*", metavar=("DB-NAME", "DB-PASSWORD"), help="Create new conf.py file") # clear @@ -153,10 +155,9 @@ def setup_translation(parser): # install def _install(opts, args): - webnotes.init(site=args.site) from webnotes.install_lib.install import Installer - inst = Installer('root') - inst.import_from_db(*opts, verbose=1) + inst = Installer('root', db_name=opts[0], site=args.site) + inst.install(*opts, verbose=1, force=args.force) def install(opts, args): _install(opts, args) @@ -225,7 +226,6 @@ def reload_doc(opts, args): def build(opts, args): import webnotes.build - webnotes.connect(site=args.site) webnotes.build.bundle(False) def watch(opts, args): @@ -248,6 +248,10 @@ def domain(opts, args): webnotes.conn.commit() else: print webnotes.conn.get_value("Website Settings", None, "subdomain") + +def make_conf(opts, args): + from webnotes.install_lib.install import make_conf + make_conf(*opts, site=args.site) # git def git(opts, args=None):