8aa660f152492a5fc4c7f0aad13d896e344c137d
1 #! /usr/bin/python
3 # $Id: roundup.py,v 1.4 2001-07-19 06:27:07 anthonybaxter Exp $
5 import sys
6 if int(sys.version[0]) < 2:
7 print 'Roundup requires python 2.0 or later.'
8 sys.exit(1)
10 import string, os, getpass
11 import config, date, roundupdb
13 def determineLogin(argv):
14 n = 2
15 name = password = ''
16 if sys.argv[2] == '-user':
17 l = sys.argv[3].split(':')
18 name = l[0]
19 if len(l) > 1:
20 password = l[1]
21 n = 4
22 elif os.environ.has_key('ROUNDUP_LOGIN'):
23 l = os.environ['ROUNDUP_LOGIN'].split(':')
24 name = l[0]
25 if len(l) > 1:
26 password = l[1]
27 while not name:
28 name = raw_input('Login name: ')
29 while not password:
30 password = getpass.getpass(' password: ')
31 return n, roundupdb.openDB(config.DATABASE, name, password)
33 def usage():
34 print '''Usage:
36 roundup init
37 -- initialise the database
38 roundup spec classname
39 -- show the properties for a classname
40 roundup create [-user login] classname propname=value ...
41 -- create a new entry of a given class
42 roundup list [-list] classname
43 -- list the instances of a class
44 roundup history [-list] designator
45 -- show the history entries of a designator
46 roundup get [-list] designator[,designator,...] propname
47 -- get the given property of one or more designator(s)
48 roundup set [-user login] designator[,designator,...] propname=value ...
49 -- set the given property of one or more designator(s)
50 roundup find [-list] classname propname=value ...
51 -- find the class instances with a given property
52 roundup retire designator[,designator,...]
53 -- "retire" a designator
54 roundup help
55 -- this help
56 roundup morehelp
57 -- even more detailed help
58 '''
60 def moreusage():
61 usage()
62 print '''
63 A designator is a classname and a nodeid concatenated, eg. bug1, user10, ...
65 Property values are represented as strings in command arguments and in the
66 printed results:
67 . Strings are, well, strings.
68 . Date values are printed in the full date format in the local time zone, and
69 accepted in the full format or any of the partial formats explained below.
70 . Link values are printed as node designators. When given as an argument,
71 node designators and key strings are both accepted.
72 . Multilink values are printed as lists of node designators joined by commas.
73 When given as an argument, node designators and key strings are both
74 accepted; an empty string, a single node, or a list of nodes joined by
75 commas is accepted.
77 When multiple nodes are specified to the roundup get or roundup set
78 commands, the specified properties are retrieved or set on all the listed
79 nodes.
81 When multiple results are returned by the roundup get or roundup find
82 commands, they are printed one per line (default) or joined by commas (with
83 the -list) option.
85 Where the command changes data, a login name/password is required. The
86 login may be specified as either "name" or "name:password".
87 . ROUNDUP_LOGIN environment variable
88 . the -user command-line option
89 If either the name or password is not supplied, they are obtained from the
90 command-line.
92 Date format examples:
93 "2000-04-17.03:45" means <Date 2000-04-17.08:45:00>
94 "2000-04-17" means <Date 2000-04-17.00:00:00>
95 "01-25" means <Date yyyy-01-25.00:00:00>
96 "08-13.22:13" means <Date yyyy-08-14.03:13:00>
97 "11-07.09:32:43" means <Date yyyy-11-07.14:32:43>
98 "14:25" means <Date yyyy-mm-dd.19:25:00>
99 "8:47:11" means <Date yyyy-mm-dd.13:47:11>
100 "." means "right now"
101 '''
103 def main():
105 if len(sys.argv) == 1:
106 usage()
107 return 1
109 command = sys.argv[1]
110 if command == 'init':
111 password = ''
112 confirm = 'x'
113 while password != confirm:
114 password = getpass.getpass('Admin Password:')
115 confirm = getpass.getpass(' Confirm:')
116 roundupdb.initDB(config.DATABASE, password)
117 return 0
119 if command == 'get':
120 db = roundupdb.openDB(config.DATABASE)
121 designators = string.split(sys.argv[2], ',')
122 propname = sys.argv[3]
123 for designator in designators:
124 classname, nodeid = roundupdb.splitDesignator(designator)
125 print db.getclass(classname).get(nodeid, propname)
127 elif command == 'set':
128 n, db = determineLogin(sys.argv)
129 designators = string.split(sys.argv[n], ',')
130 props = {}
131 for prop in sys.argv[n+1:]:
132 key, value = prop.split('=')
133 props[key] = value
134 for designator in designators:
135 classname, nodeid = roundupdb.splitDesignator(designator)
136 cl = db.getclass(classname)
137 properties = cl.getprops()
138 for key, value in props.items():
139 type = properties[key]
140 if type.isStringType:
141 continue
142 elif type.isDateType:
143 props[key] = date.Date(value)
144 elif type.isIntervalType:
145 props[key] = date.Interval(value)
146 elif type.isLinkType:
147 props[key] = value
148 elif type.isMultilinkType:
149 props[key] = value.split(',')
150 apply(cl.set, (nodeid, ), props)
152 elif command == 'find':
153 db = roundupdb.openDB(config.DATABASE)
154 classname = sys.argv[2]
155 cl = db.getclass(classname)
157 # look up the linked-to class and get the nodeid that has the value
158 propname, value = sys.argv[3:].split('=')
159 propcl = cl[propname].classname
160 nodeid = propcl.lookup(value)
162 # now do the find
163 print cl.find(propname, nodeid)
165 elif command == 'spec':
166 db = roundupdb.openDB(config.DATABASE)
167 classname = sys.argv[2]
168 cl = db.getclass(classname)
169 for key, value in cl.properties.items():
170 print '%s: %s'%(key, value)
172 elif command == 'create':
173 n, db = determineLogin(sys.argv)
174 classname = sys.argv[n]
175 cl = db.getclass(classname)
176 props = {}
177 properties = cl.getprops()
178 for prop in sys.argv[n+1:]:
179 key, value = prop.split('=')
180 type = properties[key]
181 if type.isStringType:
182 props[key] = value
183 elif type.isDateType:
184 props[key] = date.Date(value)
185 elif type.isIntervalType:
186 props[key] = date.Interval(value)
187 elif type.isLinkType:
188 props[key] = value
189 elif type.isMultilinkType:
190 props[key] = value.split(',')
191 print apply(cl.create, (), props)
193 elif command == 'list':
194 db = roundupdb.openDB(config.DATABASE)
195 classname = sys.argv[2]
196 cl = db.getclass(classname)
197 key = cl.getkey() or cl.properties.keys()[0]
198 for nodeid in cl.list():
199 value = cl.get(nodeid, key)
200 print "%4s: %s"%(nodeid, value)
202 elif command == 'history':
203 db = roundupdb.openDB(config.DATABASE)
204 classname, nodeid = roundupdb.splitDesignator(sys.argv[2])
205 print db.getclass(classname).history(nodeid)
207 elif command == 'retire':
208 n, db = determineLogin(sys.argv)
209 designators = string.split(sys.argv[2], ',')
210 for designator in designators:
211 classname, nodeid = roundupdb.splitDesignator(designator)
212 db.getclass(classname).retire(nodeid)
214 elif command == 'help':
215 usage()
216 return 0
218 elif command == 'morehelp':
219 moreusage()
220 return 0
222 else:
223 print "Unknown command '%s'"%command
224 usage()
225 return 1
227 db.close()
228 return 0
230 if __name__ == '__main__':
231 sys.exit(main())
233 #
234 # $Log: not supported by cvs2svn $
235 # Revision 1.3 2001/07/19 06:08:24 anthonybaxter
236 # fixed typo in usage string because it was bugging me each time I saw it.
237 #
238 # Revision 1.2 2001/07/19 05:52:22 anthonybaxter
239 # Added CVS keywords Id and Log
240 #