diff --git a/roundup-admin b/roundup-admin
index a1be5c39a190cb073273bc43d2b0ec0092be2edd..85eee36243e2607bbeb6bd644c025b5d231506b0 100755 (executable)
--- a/roundup-admin
+++ b/roundup-admin
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: roundup-admin,v 1.15 2001-08-07 00:24:42 richard Exp $
+# $Id: roundup-admin,v 1.22 2001-10-09 07:25:59 richard Exp $
import sys
if int(sys.version[0]) < 2:
sys.exit(1)
import string, os, getpass, getopt, re
-from roundup import date, roundupdb, init
+from roundup import date, roundupdb, init, password
import roundup.instance
def usage(message=''):
Commands:
%s
-
Help:
roundup-admin -h
- roundup-admin help
- -- this help
- roundup-admin help <command>
- -- command-specific help
- roundup-admin morehelp
- -- even more detailed help
-
-'''%(message, '\n '.join(commands))
+ roundup-admin help -- this help
+ roundup-admin help <command> -- command-specific help
+ roundup-admin morehelp -- even more detailed help
+Options:
+ -i instance home -- specify the issue tracker "home directory" to administer
+ -u -- the user[:password] to use for commands
+ -c -- when outputting lists of data, just comma-separate them'''%(
+message, '\n '.join(commands))
def moreusage(message=''):
usage(message)
print '''
All commands (except help) require an instance specifier. This is just the path
-to the roundup instance you're working with. It may be specified in the
-environment variable ROUNDUP_INSTANCE or on the command line as "-i instance".
+to the roundup instance you're working with. A roundup instance is where
+roundup keeps the database and configuration file that defines an issue
+tracker. It may be thought of as the issue tracker's "home directory". It may
+be specified in the environment variable ROUNDUP_INSTANCE or on the command
+line as "-i instance".
A designator is a classname and a nodeid concatenated, eg. bug1, user10, ...
if template not in templates:
print 'Templates:', ', '.join(templates)
while template not in templates:
- template = raw_input('Select template [classic]: ').strip()
+ template = raw_input('Select template [extended]: ').strip()
if not template:
- template = 'classic'
+ template = 'extended'
import roundup.backends
backends = roundup.backends.__all__
Retrieves the property value of the nodes specified by the designators.
'''
- designators = string.split(args[0], ',')
- propname = args[1]
+ propname = args[0]
+ designators = string.split(args[1], ',')
# TODO: handle the -c option
for designator in designators:
classname, nodeid = roundupdb.splitDesignator(designator)
Sets the property to the value for all designators given.
'''
+ from roundup import hyperdb
+
designators = string.split(args[0], ',')
props = {}
for prop in args[1:]:
properties = cl.getprops()
for key, value in props.items():
type = properties[key]
- if type.isStringType:
+ if isinstance(type, hyperdb.String):
continue
- elif type.isDateType:
+ elif isinstance(type, hyperdb.Password):
+ props[key] = password.Password(value)
+ elif isinstance(type, hyperdb.Date):
props[key] = date.Date(value)
- elif type.isIntervalType:
+ elif isinstance(type, hyperdb.Interval):
props[key] = date.Interval(value)
- elif type.isLinkType:
+ elif isinstance(type, hyperdb.Link):
props[key] = value
- elif type.isMultilinkType:
+ elif isinstance(type, hyperdb.Multilink):
props[key] = value.split(',')
apply(cl.set, (nodeid, ), props)
return 0
'''
classname = args[0]
cl = db.getclass(classname)
+ keyprop = cl.getkey()
for key, value in cl.properties.items():
- print '%s: %s'%(key, value)
+ if keyprop == key:
+ print '%s: %s (key property)'%(key, value)
+ else:
+ print '%s: %s'%(key, value)
-def do_create(db, args):
+def do_create(db, args, pretty_re=re.compile(r'<roundup\.hyperdb\.(.*)>')):
'''Usage: create classname property=value ...
Create a new entry of a given class.
name=value arguments provided on the command line after the "create"
command.
'''
+ from roundup import hyperdb
+
classname = args[0]
cl = db.getclass(classname)
props = {}
- properties = cl.getprops()
- for prop in args[1:]:
- key, value = prop.split('=')
- type = properties[key]
- if type.isStringType:
+ properties = cl.getprops(protected = 0)
+ if len(args) == 1:
+ # ask for the properties
+ for key, value in properties.items():
+ if key == 'id': continue
+ m = pretty_re.match(str(value))
+ if m:
+ value = m.group(1)
+ value = raw_input('%s (%s): '%(key.capitalize(), value))
+ if value:
+ props[key] = value
+ else:
+ # use the args
+ for prop in args[1:]:
+ key, value = prop.split('=')
props[key] = value
- elif type.isDateType:
+
+ # convert types
+ for key in props.keys():
+ type = properties[key]
+ if isinstance(type, hyperdb.Date):
props[key] = date.Date(value)
- elif type.isIntervalType:
+ elif isinstance(type, hyperdb.Interval):
props[key] = date.Interval(value)
- elif type.isLinkType:
- props[key] = value
- elif type.isMultilinkType:
+ elif isinstance(type, hyperdb.Multilink):
props[key] = value.split(',')
- print apply(cl.create, (), props)
+
+ if cl.getkey() and not props.has_key(cl.getkey()):
+ print "You must provide the '%s' property."%cl.getkey()
+ else:
+ print apply(cl.create, (), props)
+
return 0
def do_list(db, args):
# for nodeid in cl.list():
# node = {}
# for name, type in properties:
-# if type.isMultilinkType:
+# isinstance( if type, hyperdb.Multilink):
# node[name] = cl.get(nodeid, name, [])
# else:
# node[name] = cl.get(nodeid, name, None)
return 0
if opt == '-i':
instance_home = arg
- if opt == '-u':
- l = arg.split(':')
- name = l[0]
- if len(l) > 1:
- password = l[1]
if opt == '-c':
comma_sep = 1
if command == 'init':
return do_init(instance_home, args)
- # open the database
- if command in ('create', 'set', 'retire', 'freshen'):
- while not name:
- name = raw_input('Login name: ')
- while not password:
- password = getpass.getpass(' password: ')
-
- # get the instance
- instance = roundup.instance.open(instance_home)
-
function = figureCommands().get(command, None)
# not a valid command
usage('Unknown command "%s"'%command)
return 1
- db = instance.open(name or 'admin')
+ # get the instance
+ instance = roundup.instance.open(instance_home)
+ db = instance.open('admin')
+
+ # do the command
try:
return function(db, args[1:])
finally:
#
# $Log: not supported by cvs2svn $
+# Revision 1.21 2001/10/05 02:23:24 richard
+# . roundup-admin create now prompts for property info if none is supplied
+# on the command-line.
+# . hyperdb Class getprops() method may now return only the mutable
+# properties.
+# . Login now uses cookies, which makes it a whole lot more flexible. We can
+# now support anonymous user access (read-only, unless there's an
+# "anonymous" user, in which case write access is permitted). Login
+# handling has been moved into cgi_client.Client.main()
+# . The "extended" schema is now the default in roundup init.
+# . The schemas have had their page headings modified to cope with the new
+# login handling. Existing installations should copy the interfaces.py
+# file from the roundup lib directory to their instance home.
+# . Incorrectly had a Bizar Software copyright on the cgitb.py module from
+# Ping - has been removed.
+# . Fixed a whole bunch of places in the CGI interface where we should have
+# been returning Not Found instead of throwing an exception.
+# . Fixed a deviation from the spec: trying to modify the 'id' property of
+# an item now throws an exception.
+#
+# Revision 1.20 2001/10/04 02:12:42 richard
+# Added nicer command-line item adding: passing no arguments will enter an
+# interactive more which asks for each property in turn. While I was at it, I
+# fixed an implementation problem WRT the spec - I wasn't raising a
+# ValueError if the key property was missing from a create(). Also added a
+# protected=boolean argument to getprops() so we can list only the mutable
+# properties (defaults to yes, which lists the immutables).
+#
+# Revision 1.19 2001/10/01 06:40:43 richard
+# made do_get have the args in the correct order
+#
+# Revision 1.18 2001/09/18 22:58:37 richard
+#
+# Added some more help to roundu-admin
+#
+# Revision 1.17 2001/08/28 05:58:33 anthonybaxter
+# added missing 'import' statements.
+#
+# Revision 1.16 2001/08/12 06:32:36 richard
+# using isinstance(blah, Foo) now instead of isFooType
+#
+# Revision 1.15 2001/08/07 00:24:42 richard
+# stupid typo
+#
# Revision 1.14 2001/08/07 00:15:51 richard
# Added the copyright/license notice to (nearly) all files at request of
# Bizar Software.