F [dialog] offer to create backup. refactor to use l.c.shellutils.ASK
authorNicolas Chauvat <nicolas.chauvat@logilab.fr>
Fri, 31 Jul 2009 23:26:52 +0200
changeset 2615 1ea41b7c0836
parent 2614 351f1fcfa53c
child 2616 4501ee760eec
F [dialog] offer to create backup. refactor to use l.c.shellutils.ASK
common/migration.py
cwctl.py
devtools/devctl.py
server/serverctl.py
server/sqlutils.py
test/data/schema.py
toolsutils.py
web/webctl.py
--- a/common/migration.py	Fri Jul 31 23:22:19 2009 +0200
+++ b/common/migration.py	Fri Jul 31 23:26:52 2009 +0200
@@ -15,6 +15,7 @@
 
 from logilab.common.decorators import cached
 from logilab.common.configuration import REQUIRED, read_old_config
+from logilab.common.shellutils import ASK
 
 from cubicweb import ConfigurationError
 
@@ -69,11 +70,10 @@
     ability to show the script's content
     """
     while True:
-        confirm = raw_input('Execute %r (Y/n/s[how]) ?' % scriptpath)
-        confirm = confirm.strip().lower()
-        if confirm in ('n', 'no'):
+        answer = ASK.ask('Execute %r ?' % scriptpath, ('Y','n','show'), 'Y')
+        if answer == 'n':
             return False
-        elif confirm in ('s', 'show'):
+        elif answer == 'show':
             stream = open(scriptpath)
             scriptcontent = stream.read()
             stream.close()
@@ -188,26 +188,24 @@
 
         if `retry` is true the r[etry] answer may return 2
         """
-        print question,
-        possibleanswers = 'Y/n'
+        possibleanswers = ['Y','n']
         if abort:
-            possibleanswers += '/a[bort]'
+            possibleanswers.append('abort')
         if shell:
-            possibleanswers += '/s[hell]'
+            possibleanswers.append('shell')
         if retry:
-            possibleanswers += '/r[etry]'
+            possibleanswers.append('retry')
         try:
-            confirm = raw_input('(%s): ' % ( possibleanswers, ))
-            answer = confirm.strip().lower()
+            answer = ASK.ask(question, possibleanswers, 'Y')
         except (EOFError, KeyboardInterrupt):
             answer = 'abort'
-        if answer in ('n', 'no'):
+        if answer == 'n':
             return False
-        if answer in ('r', 'retry'):
+        if answer == 'retry':
             return 2
-        if answer in ('a', 'abort'):
+        if answer == 'abort':
             raise SystemExit(1)
-        if shell and answer in ('s', 'shell'):
+        if shell and answer == 'shell':
             self.interactive_shell()
             return self.confirm(question)
         return True
--- a/cwctl.py	Fri Jul 31 23:22:19 2009 +0200
+++ b/cwctl.py	Fri Jul 31 23:26:52 2009 +0200
@@ -9,10 +9,11 @@
 from os.path import exists, join, isfile, isdir
 
 from logilab.common.clcommands import register_commands, pop_arg
+from logilab.common.shellutils import ASK
 
 from cubicweb import ConfigurationError, ExecutionError, BadCommandUsage, underline_title
 from cubicweb.cwconfig import CubicWebConfiguration as cwcfg, CONFIGURATIONS
-from cubicweb.toolsutils import Command, main_run,  rm, create_dir, confirm
+from cubicweb.toolsutils import Command, main_run,  rm, create_dir
 
 def wait_process_end(pid, maxtry=10, waittime=1):
     """wait for a process to actually die"""
--- a/devtools/devctl.py	Fri Jul 31 23:22:19 2009 +0200
+++ b/devtools/devctl.py	Fri Jul 31 23:26:52 2009 +0200
@@ -17,15 +17,15 @@
 from logilab.common import STD_BLACKLIST
 from logilab.common.modutils import get_module_files
 from logilab.common.textutils import get_csv
+from logilab.common.shellutils import ASK
 from logilab.common.clcommands import register_commands
 
 from cubicweb import CW_SOFTWARE_ROOT as BASEDIR, BadCommandUsage, underline_title
 from cubicweb.__pkginfo__ import version as cubicwebversion
-from cubicweb.toolsutils import Command, confirm, copy_skeleton
+from cubicweb.toolsutils import Command, copy_skeleton
 from cubicweb.web.webconfig import WebConfiguration
 from cubicweb.server.serverconfig import ServerConfiguration
 
-
 class DevCubeConfiguration(ServerConfiguration, WebConfiguration):
     """dummy config to get full library schema and entities"""
     creating = True
@@ -483,7 +483,7 @@
                                       " Please specify it using the --directory option")
             cubesdir = cubespath[0]
         if not isdir(cubesdir):
-            print "creating cubes directory", cubesdir
+            print "-> creating cubes directory", cubesdir
             try:
                 mkdir(cubesdir)
             except OSError, err:
@@ -492,19 +492,20 @@
         if exists(cubedir):
             self.fail("%s already exists !" % (cubedir))
         skeldir = join(BASEDIR, 'skeleton')
+        default_name = 'cubicweb-%s' % cubename.lower()
         if verbose:
-            distname = raw_input('Debian name for your cube (just type enter to use the cube name): ').strip()
+            distname = raw_input('Debian name for your cube ? [%s]): ' % default_name).strip()
             if not distname:
-                distname = 'cubicweb-%s' % cubename.lower()
+                distname = default_name
             elif not distname.startswith('cubicweb-'):
-                if confirm('do you mean cubicweb-%s ?' % distname):
+                if ASK.confirm('Do you mean cubicweb-%s ?' % distname):
                     distname = 'cubicweb-' + distname
         else:
-            distname = 'cubicweb-%s' % cubename.lower()
+            distname = default_name
 
         longdesc = shortdesc = raw_input('Enter a short description for your cube: ')
         if verbose:
-            longdesc = raw_input('Enter a long description (or nothing if you want to reuse the short one): ')
+            longdesc = raw_input('Enter a long description (leave empty to reuse the short one): ')
         if verbose:
             includes = self._ask_for_dependancies()
             if len(includes) == 1:
@@ -529,14 +530,14 @@
     def _ask_for_dependancies(self):
         includes = []
         for stdtype in ServerConfiguration.available_cubes():
-            ans = raw_input("Depends on cube %s? (N/y/s(kip)/t(ype)"
-                            % stdtype).lower().strip()
-            if ans == 'y':
+            answer = ASK.ask("Depends on cube %s? " % stdtype,
+                             ('N','y','skip','type'), 'N')
+            if answer == 'y':
                 includes.append(stdtype)
-            if ans == 't':
+            if answer == 'type':
                 includes = get_csv(raw_input('type dependancies: '))
                 break
-            elif ans == 's':
+            elif answer == 'skip':
                 break
         return includes
 
--- a/server/serverctl.py	Fri Jul 31 23:22:19 2009 +0200
+++ b/server/serverctl.py	Fri Jul 31 23:26:52 2009 +0200
@@ -12,9 +12,10 @@
 
 from logilab.common.configuration import Configuration
 from logilab.common.clcommands import register_commands, cmd_run, pop_arg
+from logilab.common.shellutils import ASK
 
 from cubicweb import AuthenticationError, ExecutionError, ConfigurationError, underline_title
-from cubicweb.toolsutils import Command, CommandHandler, confirm
+from cubicweb.toolsutils import Command, CommandHandler
 from cubicweb.server import SOURCE_TYPES
 from cubicweb.server.utils import ask_source_config
 from cubicweb.server.serverconfig import USER_OPTIONS, ServerConfiguration
@@ -139,7 +140,7 @@
             if cube in SOURCE_TYPES:
                 sourcescfg[cube] = ask_source_config(cube, inputlevel)
         print
-        while confirm('Enter another source ?', default_is_yes=False):
+        while ASK.confirm('Enter another source ?', default_is_yes=False):
             available = sorted(stype for stype in SOURCE_TYPES
                                if not stype in cubes)
             while True:
@@ -169,7 +170,7 @@
         config.write_bootstrap_cubes_file(cubes)
 
     def postcreate(self):
-        if confirm('Do you want to run db-create to create the system database ?'):
+        if ASK.confirm('Run db-create to create the system database ?'):
             verbosity = (self.config.mode == 'installed') and 'y' or 'n'
             cmd_run('db-create', self.config.appid, '--verbose=%s' % verbosity)
         else:
@@ -187,7 +188,7 @@
         source = self.config.sources()['system']
         dbname = source['db-name']
         helper = get_adv_func_helper(source['db-driver'])
-        if confirm('Delete database %s ?' % dbname):
+        if ASK.confirm('Delete database %s ?' % dbname):
             user = source['db-user'] or None
             cnx = _db_sys_cnx(source, 'DROP DATABASE', user=user)
             cursor = cnx.cursor()
@@ -196,7 +197,7 @@
                 print '-> database %s dropped.' % dbname
                 # XXX should check we are not connected as user
                 if user and helper.users_support and \
-                       confirm('Delete user %s ?' % user, default_is_yes=False):
+                       ASK.confirm('Delete user %s ?' % user, default_is_yes=False):
                     cursor.execute('DROP USER %s' % user)
                     print '-> user %s dropped.' % user
                 cnx.commit()
@@ -277,12 +278,12 @@
                 if helper.users_support:
                     user = source['db-user']
                     if not helper.user_exists(cursor, user) and \
-                           confirm('Create db user %s ?' % user, default_is_yes=False):
+                           ASK.confirm('Create db user %s ?' % user, default_is_yes=False):
                         helper.create_user(source['db-user'], source['db-password'])
                         print '-> user %s created.' % user
                 dbname = source['db-name']
                 if dbname in helper.list_databases(cursor):
-                    if confirm('Database %s already exists -- do you want to drop it ?' % dbname):
+                    if ASK.confirm('Database %s already exists -- do you want to drop it ?' % dbname):
                         cursor.execute('DROP DATABASE %s' % dbname)
                     else:
                         return
@@ -310,7 +311,7 @@
         cnx.commit()
         print '-> database for instance %s created and necessary extensions installed.' % appid
         print
-        if confirm('Do you want to run db-init to initialize the system database ?'):
+        if ASK.confirm('Run db-init to initialize the system database ?'):
             cmd_run('db-init', config.appid)
         else:
             print ('-> nevermind, you can do it later with '
@@ -491,7 +492,7 @@
         raise ExecutionError('Error while retrieving the dump')
     rmcmd = 'ssh -t %s "rm -f /tmp/%s.dump"' % (host, appid)
     print rmcmd
-    if os.system(rmcmd) and not confirm(
+    if os.system(rmcmd) and not ASK.confirm(
         'An error occured while deleting remote dump. Continue anyway?'):
         raise ExecutionError('Error while deleting remote dump')
 
--- a/server/sqlutils.py	Fri Jul 31 23:22:19 2009 +0200
+++ b/server/sqlutils.py	Fri Jul 31 23:26:52 2009 +0200
@@ -199,20 +199,21 @@
         cmd = self.dbhelper.backup_command(self.dbname, self.dbhost,
                                            self.dbuser, backupfile,
                                            keepownership=False)
-        while True:
-            print cmd
-            if os.system(cmd):
-                print '-> error while backuping the base'
-                answer = confirm('Continue anyway?',
-                                 shell=False, abort=False, retry=True)
-                if not answer:
-                    raise SystemExit(1)
-                if answer == 1: # 1: continue, 2: retry
-                    break
+        backupdir = os.path.dirname(backupfile)
+        if not os.path.exists(backupdir):
+            if confirm('%s does not exist. Create it?' % backupdir,
+                       abort=False, shell=False):
+                os.mkdir(backupdir)
             else:
-                print '-> backup file',  backupfile
-                restrict_perms_to_user(backupfile, self.info)
-                break
+                print '-> failed to backup instance'
+                return
+        if os.system(cmd):
+            print '-> error trying to backup with command', cmd
+            if not confirm('Continue anyway?', default_is_yes=False):
+                raise SystemExit(1)
+        else:
+            print '-> backup file',  backupfile
+            restrict_perms_to_user(backupfile, self.info)
 
     def restore_from_file(self, backupfile, confirm, drop=True):
         for cmd in self.dbhelper.restore_commands(self.dbname, self.dbhost,
@@ -223,9 +224,8 @@
             while True:
                 print cmd
                 if os.system(cmd):
-                    print 'error while restoring the base'
-                    print 'OOOOOPS', confirm
-                    answer = confirm('continue anyway?',
+                    print '-> error while restoring the base'
+                    answer = confirm('Continue anyway?',
                                      shell=False, abort=False, retry=True)
                     if not answer:
                         raise SystemExit(1)
@@ -233,7 +233,7 @@
                         break
                 else:
                     break
-        print 'database restored'
+        print '-> database restored.'
 
     def merge_args(self, args, query_args):
         if args is not None:
--- a/test/data/schema.py	Fri Jul 31 23:22:19 2009 +0200
+++ b/test/data/schema.py	Fri Jul 31 23:26:52 2009 +0200
@@ -5,6 +5,9 @@
 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
 """
+
+from yams.buildobjs import EntityType, String, SubjectRelation, RelationDefinition
+
 class Personne(EntityType):
     nom = String(required=True)
     prenom = String()
--- a/toolsutils.py	Fri Jul 31 23:22:19 2009 +0200
+++ b/toolsutils.py	Fri Jul 31 23:26:52 2009 +0200
@@ -16,7 +16,7 @@
 from logilab.common.clcommands import Command as BaseCommand, \
      main_run as base_main_run
 from logilab.common.compat import any
-from logilab.common.shellutils import confirm
+from logilab.common.shellutils import ASK
 
 from cubicweb import warning
 from cubicweb import ConfigurationError, ExecutionError
@@ -72,7 +72,7 @@
         if askconfirm:
             print
             print diffs
-            action = raw_input('replace (N/y/q) ? ').lower()
+            action = ASK.ask('Replace ?', ('N','y','q'), 'N')
         else:
             action = 'y'
         if action == 'y':
@@ -117,7 +117,7 @@
             if fname.endswith('.tmpl'):
                 tfpath = tfpath[:-5]
                 if not askconfirm or not exists(tfpath) or \
-                       confirm('%s exists, overwrite?' % tfpath):
+                       ASK.confirm('%s exists, overwrite?' % tfpath):
                     fill_templated_file(fpath, tfpath, context)
                     print '[generate] %s <-- %s' % (tfpath, fpath)
             elif exists(tfpath):
--- a/web/webctl.py	Fri Jul 31 23:22:19 2009 +0200
+++ b/web/webctl.py	Fri Jul 31 23:26:52 2009 +0200
@@ -9,8 +9,8 @@
 __docformat__ = "restructuredtext en"
 
 from cubicweb import underline_title
-from cubicweb.toolsutils import CommandHandler, confirm
-
+from cubicweb.toolsutils import CommandHandler
+from logilab.common.shellutils import ASK
 
 class WebCreateHandler(CommandHandler):
     cmdname = 'create'
@@ -22,7 +22,7 @@
         if config.repo_method == 'pyro':
             print '\n'+underline_title('Repository server configuration')
             config.input_config('pyro-client', inputlevel)
-        if confirm('Allow anonymous access ?', False):
+        if ASK.confirm('Allow anonymous access ?', False):
             config.global_set_option('anonymous-user', 'anon')
             config.global_set_option('anonymous-password', 'anon')