comparison roundup/admin.py @ 1767:fdaa0b751355

python2.3 CSV support, also missing thankyou in index.txt :)
author Richard Jones <richard@users.sourceforge.net>
date Thu, 28 Aug 2003 04:46:54 +0000
parents ab7760caf6ff
children d4c0c65adb2c
comparison
equal deleted inserted replaced
1765:14a2f1529759 1767:fdaa0b751355
14 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
15 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" 15 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
16 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, 16 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
17 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 17 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
18 # 18 #
19 # $Id: admin.py,v 1.56 2003-08-26 00:06:55 richard Exp $ 19 # $Id: admin.py,v 1.57 2003-08-28 04:46:39 richard Exp $
20 20
21 '''Administration commands for maintaining Roundup trackers. 21 '''Administration commands for maintaining Roundup trackers.
22 ''' 22 '''
23 23
24 import sys, os, getpass, getopt, re, UserDict, shutil, rfc822 24 import sys, os, getpass, getopt, re, UserDict, shutil, rfc822
25 try: 25 from roundup import date, hyperdb, roundupdb, init, password, token, rcsv
26 import csv
27 except ImportError:
28 csv = None
29 from roundup import date, hyperdb, roundupdb, init, password, token
30 from roundup import __version__ as roundup_version 26 from roundup import __version__ as roundup_version
31 import roundup.instance 27 import roundup.instance
32 from roundup.i18n import _ 28 from roundup.i18n import _
33 29
34 class CommandDict(UserDict.UserDict): 30 class CommandDict(UserDict.UserDict):
1061 1057
1062 This action exports the current data from the database into 1058 This action exports the current data from the database into
1063 colon-separated-value files that are placed in the nominated 1059 colon-separated-value files that are placed in the nominated
1064 destination directory. The journals are not exported. 1060 destination directory. The journals are not exported.
1065 ''' 1061 '''
1066 # we need the CSV module
1067 if csv is None:
1068 raise UsageError, \
1069 _('Sorry, you need the csv module to use this function.\n'
1070 'Get it from: http://www.object-craft.com.au/projects/csv/')
1071
1072 # grab the directory to export to 1062 # grab the directory to export to
1073 if len(args) < 1: 1063 if len(args) < 1:
1074 raise UsageError, _('Not enough arguments supplied') 1064 raise UsageError, _('Not enough arguments supplied')
1065 if rcsv.error:
1066 raise UsageError, _(rcsv.error)
1067
1075 dir = args[-1] 1068 dir = args[-1]
1076 1069
1077 # get the list of classes to export 1070 # get the list of classes to export
1078 if len(args) == 2: 1071 if len(args) == 2:
1079 classes = args[0].split(',') 1072 classes = args[0].split(',')
1080 else: 1073 else:
1081 classes = self.db.classes.keys() 1074 classes = self.db.classes.keys()
1082 1075
1083 # use the csv parser if we can - it's faster
1084 p = csv.parser(field_sep=':')
1085
1086 # do all the classes specified 1076 # do all the classes specified
1087 for classname in classes: 1077 for classname in classes:
1088 cl = self.get_class(classname) 1078 cl = self.get_class(classname)
1089 f = open(os.path.join(dir, classname+'.csv'), 'w') 1079 f = open(os.path.join(dir, classname+'.csv'), 'w')
1080 writer = rcsv.writer(f, rcsv.colon_separated)
1090 properties = cl.getprops() 1081 properties = cl.getprops()
1091 propnames = properties.keys() 1082 propnames = properties.keys()
1092 propnames.sort() 1083 propnames.sort()
1093 l = propnames[:] 1084 fields = propnames[:]
1094 l.append('is retired') 1085 fields.append('is retired')
1095 print >> f, p.join(l) 1086 writer.writerow(fields)
1096 1087
1097 # all nodes for this class (not using list() 'cos it doesn't 1088 # all nodes for this class (not using list() 'cos it doesn't
1098 # include retired nodes) 1089 # include retired nodes)
1099 1090
1100 for nodeid in self.db.getclass(classname).getnodeids(): 1091 for nodeid in self.db.getclass(classname).getnodeids():
1101 # get the regular props 1092 # get the regular props
1102 print >>f, p.join(cl.export_list(propnames, nodeid)) 1093 writer.writerow (cl.export_list(propnames, nodeid))
1103 1094
1104 # close this file 1095 # close this file
1105 f.close() 1096 f.close()
1106 return 0 1097 return 0
1107 1098
1120 create a new database using the imported data, then create a new 1111 create a new database using the imported data, then create a new
1121 database (or, tediously, retire all the old data.) 1112 database (or, tediously, retire all the old data.)
1122 ''' 1113 '''
1123 if len(args) < 1: 1114 if len(args) < 1:
1124 raise UsageError, _('Not enough arguments supplied') 1115 raise UsageError, _('Not enough arguments supplied')
1125 if csv is None: 1116 if rcsv.error:
1126 raise UsageError, \ 1117 raise UsageError, _(rcsv.error)
1127 _('Sorry, you need the csv module to use this function.\n'
1128 'Get it from: http://www.object-craft.com.au/projects/csv/')
1129
1130 from roundup import hyperdb 1118 from roundup import hyperdb
1131 1119
1132 for file in os.listdir(args[0]): 1120 for file in os.listdir(args[0]):
1133 # we only care about CSV files 1121 # we only care about CSV files
1134 if not file.endswith('.csv'): 1122 if not file.endswith('.csv'):
1139 # get the classname 1127 # get the classname
1140 classname = os.path.splitext(file)[0] 1128 classname = os.path.splitext(file)[0]
1141 1129
1142 # ensure that the properties and the CSV file headings match 1130 # ensure that the properties and the CSV file headings match
1143 cl = self.get_class(classname) 1131 cl = self.get_class(classname)
1144 p = csv.parser(field_sep=':') 1132 reader = rcsv.reader(f, rcsv.colon_separated)
1145 file_props = p.parse(f.readline()) 1133 file_props = None
1134 maxid = 1
1146 1135
1147 # loop through the file and create a node for each entry 1136 # loop through the file and create a node for each entry
1148 maxid = 1 1137 for r in reader:
1149 while 1: 1138 if file_props is None:
1150 line = f.readline() 1139 file_props = r
1151 if not line: break 1140 continue
1152
1153 # parse lines until we get a complete entry
1154 while 1:
1155 l = p.parse(line)
1156 if l: break
1157 line = f.readline()
1158 if not line:
1159 raise ValueError, "Unexpected EOF during CSV parse"
1160 1141
1161 # do the import and figure the current highest nodeid 1142 # do the import and figure the current highest nodeid
1162 maxid = max(maxid, int(cl.import_list(file_props, l))) 1143 maxid = max(maxid, int(cl.import_list(file_props, r)))
1163 1144
1145 # set the id counter
1164 print 'setting', classname, maxid+1 1146 print 'setting', classname, maxid+1
1165 self.db.setid(classname, str(maxid+1)) 1147 self.db.setid(classname, str(maxid+1))
1166 return 0 1148 return 0
1167 1149
1168 def do_pack(self, args): 1150 def do_pack(self, args):

Roundup Issue Tracker: http://roundup-tracker.org/