Code

8aa660f152492a5fc4c7f0aad13d896e344c137d
[roundup.git] / roundup.py
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())
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.
238 # Revision 1.2  2001/07/19 05:52:22  anthonybaxter
239 # Added CVS keywords Id and Log