1 #! /usr/bin/python
3 # $Id: roundup.py,v 1.2 2001-07-19 05:52:22 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 roundup spec classname
38 roundup create [-user login] classanme propname=value ...
39 roundup list [-list] classname
40 roundup history [-list] designator
41 roundup get [-list] designator[,designator,...] propname
42 roundup set [-user login] designator[,designator,...] propname=value ...
43 roundup find [-list] classname propname=value ...
44 roundup retire designator[,designator,...]
46 A designator is a classname and a nodeid concatenated, eg. bug1, user10, ...
48 Property values are represented as strings in command arguments and in the
49 printed results:
50 . Strings are, well, strings.
51 . Date values are printed in the full date format in the local time zone, and
52 accepted in the full format or any of the partial formats explained below.
53 . Link values are printed as node designators. When given as an argument,
54 node designators and key strings are both accepted.
55 . Multilink values are printed as lists of node designators joined by commas.
56 When given as an argument, node designators and key strings are both
57 accepted; an empty string, a single node, or a list of nodes joined by
58 commas is accepted.
60 When multiple nodes are specified to the roundup get or roundup set
61 commands, the specified properties are retrieved or set on all the listed
62 nodes.
64 When multiple results are returned by the roundup get or roundup find
65 commands, they are printed one per line (default) or joined by commas (with
66 the -list) option.
68 Where the command changes data, a login name/password is required. The
69 login may be specified as either "name" or "name:password".
70 . ROUNDUP_LOGIN environment variable
71 . the -user command-line option
72 If either the name or password is not supplied, they are obtained from the
73 command-line.
75 Date format examples:
76 "2000-04-17.03:45" means <Date 2000-04-17.08:45:00>
77 "2000-04-17" means <Date 2000-04-17.00:00:00>
78 "01-25" means <Date yyyy-01-25.00:00:00>
79 "08-13.22:13" means <Date yyyy-08-14.03:13:00>
80 "11-07.09:32:43" means <Date yyyy-11-07.14:32:43>
81 "14:25" means <Date yyyy-mm-dd.19:25:00>
82 "8:47:11" means <Date yyyy-mm-dd.13:47:11>
83 "." means "right now"
84 '''
86 def main():
88 if len(sys.argv) == 1:
89 usage()
90 return 1
92 command = sys.argv[1]
93 if command == 'init':
94 password = ''
95 confirm = 'x'
96 while password != confirm:
97 password = getpass.getpass('Admin Password:')
98 confirm = getpass.getpass(' Confirm:')
99 roundupdb.initDB(config.DATABASE, password)
100 return 0
102 if command == 'get':
103 db = roundupdb.openDB(config.DATABASE)
104 designators = string.split(sys.argv[2], ',')
105 propname = sys.argv[3]
106 for designator in designators:
107 classname, nodeid = roundupdb.splitDesignator(designator)
108 print db.getclass(classname).get(nodeid, propname)
110 elif command == 'set':
111 n, db = determineLogin(sys.argv)
112 designators = string.split(sys.argv[n], ',')
113 props = {}
114 for prop in sys.argv[n+1:]:
115 key, value = prop.split('=')
116 props[key] = value
117 for designator in designators:
118 classname, nodeid = roundupdb.splitDesignator(designator)
119 cl = db.getclass(classname)
120 properties = cl.getprops()
121 for key, value in props.items():
122 type = properties[key]
123 if type.isStringType:
124 continue
125 elif type.isDateType:
126 props[key] = date.Date(value)
127 elif type.isIntervalType:
128 props[key] = date.Interval(value)
129 elif type.isLinkType:
130 props[key] = value
131 elif type.isMultilinkType:
132 props[key] = value.split(',')
133 apply(cl.set, (nodeid, ), props)
135 elif command == 'find':
136 db = roundupdb.openDB(config.DATABASE)
137 classname = sys.argv[2]
138 cl = db.getclass(classname)
140 # look up the linked-to class and get the nodeid that has the value
141 propname, value = sys.argv[3:].split('=')
142 propcl = cl[propname].classname
143 nodeid = propcl.lookup(value)
145 # now do the find
146 print cl.find(propname, nodeid)
148 elif command == 'spec':
149 db = roundupdb.openDB(config.DATABASE)
150 classname = sys.argv[2]
151 cl = db.getclass(classname)
152 for key, value in cl.properties.items():
153 print '%s: %s'%(key, value)
155 elif command == 'create':
156 n, db = determineLogin(sys.argv)
157 classname = sys.argv[n]
158 cl = db.getclass(classname)
159 props = {}
160 properties = cl.getprops()
161 for prop in sys.argv[n+1:]:
162 key, value = prop.split('=')
163 type = properties[key]
164 if type.isStringType:
165 props[key] = value
166 elif type.isDateType:
167 props[key] = date.Date(value)
168 elif type.isIntervalType:
169 props[key] = date.Interval(value)
170 elif type.isLinkType:
171 props[key] = value
172 elif type.isMultilinkType:
173 props[key] = value.split(',')
174 print apply(cl.create, (), props)
176 elif command == 'list':
177 db = roundupdb.openDB(config.DATABASE)
178 classname = sys.argv[2]
179 cl = db.getclass(classname)
180 key = cl.getkey() or cl.properties.keys()[0]
181 for nodeid in cl.list():
182 value = cl.get(nodeid, key)
183 print "%4s: %s"%(nodeid, value)
185 elif command == 'history':
186 db = roundupdb.openDB(config.DATABASE)
187 classname, nodeid = roundupdb.splitDesignator(sys.argv[2])
188 print db.getclass(classname).history(nodeid)
190 elif command == 'retire':
191 n, db = determineLogin(sys.argv)
192 designators = string.split(sys.argv[2], ',')
193 for designator in designators:
194 classname, nodeid = roundupdb.splitDesignator(designator)
195 db.getclass(classname).retire(nodeid)
197 else:
198 usage()
199 return 1
201 db.close()
202 return 0
204 if __name__ == '__main__':
205 sys.exit(main())
207 #
208 # $Log: not supported by cvs2svn $
209 #