Code

This commit was generated by cvs2svn to compensate for changes in r2,
[roundup.git] / roundup.py
1 #! /usr/bin/python
3 import sys
4 if int(sys.version[0]) < 2:
5     print 'Roundup requires python 2.0 or later.'
6     sys.exit(1)
8 import string, os, getpass
9 import config, date, roundupdb
11 def determineLogin(argv):
12     n = 2
13     name = password = ''
14     if sys.argv[2] == '-user':
15         l = sys.argv[3].split(':')
16         name = l[0]
17         if len(l) > 1:
18             password = l[1]
19         n = 4
20     elif os.environ.has_key('ROUNDUP_LOGIN'):
21         l = os.environ['ROUNDUP_LOGIN'].split(':')
22         name = l[0]
23         if len(l) > 1:
24             password = l[1]
25     while not name:
26         name = raw_input('Login name: ')
27     while not password:
28         password = getpass.getpass('  password: ')
29     return n, roundupdb.openDB(config.DATABASE, name, password)
31 def usage():
32     print '''Usage:
34  roundup init
35  roundup spec classname
36  roundup create [-user login] classanme propname=value ...
37  roundup list [-list] classname
38  roundup history [-list] designator
39  roundup get [-list] designator[,designator,...] propname
40  roundup set [-user login] designator[,designator,...] propname=value ...
41  roundup find [-list] classname propname=value ...
42  roundup retire designator[,designator,...]
44 A designator is a classname and a nodeid concatenated, eg. bug1, user10, ...
46 Property values are represented as strings in command arguments and in the
47 printed results:
48  . Strings are, well, strings.
49  . Date values are printed in the full date format in the local time zone, and
50    accepted in the full format or any of the partial formats explained below.
51  . Link values are printed as node designators. When given as an argument,
52    node designators and key strings are both accepted.
53  . Multilink values are printed as lists of node designators joined by commas.
54    When given as an argument, node designators and key strings are both
55    accepted; an empty string, a single node, or a list of nodes joined by
56    commas is accepted.
58 When multiple nodes are specified to the roundup get or roundup set
59 commands, the specified properties are retrieved or set on all the listed
60 nodes. 
62 When multiple results are returned by the roundup get or roundup find
63 commands, they are printed one per line (default) or joined by commas (with
64 the -list) option. 
66 Where the command changes data, a login name/password is required. The
67 login may be specified as either "name" or "name:password".
68  . ROUNDUP_LOGIN environment variable
69  . the -user command-line option
70 If either the name or password is not supplied, they are obtained from the
71 command-line. 
73 Date format examples:
74   "2000-04-17.03:45" means <Date 2000-04-17.08:45:00>
75   "2000-04-17" means <Date 2000-04-17.00:00:00>
76   "01-25" means <Date yyyy-01-25.00:00:00>
77   "08-13.22:13" means <Date yyyy-08-14.03:13:00>
78   "11-07.09:32:43" means <Date yyyy-11-07.14:32:43>
79   "14:25" means <Date yyyy-mm-dd.19:25:00>
80   "8:47:11" means <Date yyyy-mm-dd.13:47:11>
81   "." means "right now"
82 '''
84 def main():
86     if len(sys.argv) == 1:
87         usage()
88         return 1
90     command = sys.argv[1]
91     if command == 'init':
92         password = ''
93         confirm = 'x'
94         while password != confirm:
95             password = getpass.getpass('Admin Password:')
96             confirm = getpass.getpass('       Confirm:')
97         roundupdb.initDB(config.DATABASE, password)
98         return 0
100     if command == 'get':
101         db = roundupdb.openDB(config.DATABASE)
102         designators = string.split(sys.argv[2], ',')
103         propname = sys.argv[3]
104         for designator in designators:
105             classname, nodeid = roundupdb.splitDesignator(designator)
106             print db.getclass(classname).get(nodeid, propname)
108     elif command == 'set':
109         n, db = determineLogin(sys.argv)
110         designators = string.split(sys.argv[n], ',')
111         props = {}
112         for prop in sys.argv[n+1:]:
113             key, value = prop.split('=')
114             props[key] = value
115         for designator in designators:
116             classname, nodeid = roundupdb.splitDesignator(designator)
117             cl = db.getclass(classname)
118             properties = cl.getprops()
119             for key, value in props.items():
120                 type =  properties[key]
121                 if type.isStringType:
122                     continue
123                 elif type.isDateType:
124                     props[key] = date.Date(value)
125                 elif type.isIntervalType:
126                     props[key] = date.Interval(value)
127                 elif type.isLinkType:
128                     props[key] = value
129                 elif type.isMultilinkType:
130                     props[key] = value.split(',')
131             apply(cl.set, (nodeid, ), props)
133     elif command == 'find':
134         db = roundupdb.openDB(config.DATABASE)
135         classname = sys.argv[2]
136         cl = db.getclass(classname)
138         # look up the linked-to class and get the nodeid that has the value
139         propname, value = sys.argv[3:].split('=')
140         propcl = cl[propname].classname
141         nodeid = propcl.lookup(value)
143         # now do the find
144         print cl.find(propname, nodeid)
146     elif command == 'spec':
147         db = roundupdb.openDB(config.DATABASE)
148         classname = sys.argv[2]
149         cl = db.getclass(classname)
150         for key, value in cl.properties.items():
151             print '%s: %s'%(key, value)
153     elif command == 'create':
154         n, db = determineLogin(sys.argv)
155         classname = sys.argv[n]
156         cl = db.getclass(classname)
157         props = {}
158         properties = cl.getprops()
159         for prop in sys.argv[n+1:]:
160             key, value = prop.split('=')
161             type =  properties[key]
162             if type.isStringType:
163                 props[key] = value 
164             elif type.isDateType:
165                 props[key] = date.Date(value)
166             elif type.isIntervalType:
167                 props[key] = date.Interval(value)
168             elif type.isLinkType:
169                 props[key] = value
170             elif type.isMultilinkType:
171                 props[key] = value.split(',')
172         print apply(cl.create, (), props)
174     elif command == 'list':
175         db = roundupdb.openDB(config.DATABASE)
176         classname = sys.argv[2]
177         cl = db.getclass(classname)
178         key = cl.getkey() or cl.properties.keys()[0]
179         for nodeid in cl.list():
180             value = cl.get(nodeid, key)
181             print "%4s: %s"%(nodeid, value)
183     elif command == 'history':
184         db = roundupdb.openDB(config.DATABASE)
185         classname, nodeid = roundupdb.splitDesignator(sys.argv[2])
186         print db.getclass(classname).history(nodeid)
188     elif command == 'retire':
189         n, db = determineLogin(sys.argv)
190         designators = string.split(sys.argv[2], ',')
191         for designator in designators:
192             classname, nodeid = roundupdb.splitDesignator(designator)
193             db.getclass(classname).retire(nodeid)
195     else:
196         usage()
197         return 1
199     db.close()
200     return 0
202 if __name__ == '__main__':
203     sys.exit(main())