Mercurial > p > roundup > code
comparison roundup/admin.py @ 3669:07d1d8e22271
new "exporttables" command in roundup-admin [SF#1533791]
roundup-admin "export" may specify classes to exclude [SF#1533791]
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Fri, 11 Aug 2006 05:00:19 +0000 |
| parents | ba06fb4030d0 |
| children | 64f0b85ea603 |
comparison
equal
deleted
inserted
replaced
| 3668:a15c15510e99 | 3669:07d1d8e22271 |
|---|---|
| 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.102 2006-07-17 14:47:23 schlatterbeck Exp $ | 19 # $Id: admin.py,v 1.103 2006-08-11 05:00:19 richard Exp $ |
| 20 | 20 |
| 21 '''Administration commands for maintaining Roundup trackers. | 21 '''Administration commands for maintaining Roundup trackers. |
| 22 ''' | 22 ''' |
| 23 __docformat__ = 'restructuredtext' | 23 __docformat__ = 'restructuredtext' |
| 24 | 24 |
| 1053 except IndexError: | 1053 except IndexError: |
| 1054 raise UsageError, _('no such %(classname)s node "%(nodeid)s"')%locals() | 1054 raise UsageError, _('no such %(classname)s node "%(nodeid)s"')%locals() |
| 1055 return 0 | 1055 return 0 |
| 1056 | 1056 |
| 1057 def do_export(self, args): | 1057 def do_export(self, args): |
| 1058 ""'''Usage: export [class[,class]] export_dir | 1058 ""'''Usage: export [[-]class[,class]] export_dir |
| 1059 Export the database to colon-separated-value files. | 1059 Export the database to colon-separated-value files. |
| 1060 | 1060 To exclude the files (e.g. for the msg or file class), |
| 1061 Optionally limit the export to just the names classes. | 1061 use the exporttables command. |
| 1062 | |
| 1063 Optionally limit the export to just the named classes | |
| 1064 or exclude the named classes, if the 1st argument starts with '-'. | |
| 1062 | 1065 |
| 1063 This action exports the current data from the database into | 1066 This action exports the current data from the database into |
| 1064 colon-separated-value files that are placed in the nominated | 1067 colon-separated-value files that are placed in the nominated |
| 1065 destination directory. | 1068 destination directory. |
| 1066 ''' | 1069 ''' |
| 1070 | 1073 |
| 1071 dir = args[-1] | 1074 dir = args[-1] |
| 1072 | 1075 |
| 1073 # get the list of classes to export | 1076 # get the list of classes to export |
| 1074 if len(args) == 2: | 1077 if len(args) == 2: |
| 1075 classes = args[0].split(',') | 1078 if args[0].startswith('-'): |
| 1079 classes = [ c for c in self.db.classes.keys() | |
| 1080 if not c in args[0][1:].split(',') ] | |
| 1081 else: | |
| 1082 classes = args[0].split(',') | |
| 1076 else: | 1083 else: |
| 1077 classes = self.db.classes.keys() | 1084 classes = self.db.classes.keys() |
| 1078 | 1085 |
| 1079 class colon_separated(csv.excel): | 1086 class colon_separated(csv.excel): |
| 1080 delimiter = ':' | 1087 delimiter = ':' |
| 1084 os.makedirs(dir) | 1091 os.makedirs(dir) |
| 1085 | 1092 |
| 1086 # do all the classes specified | 1093 # do all the classes specified |
| 1087 for classname in classes: | 1094 for classname in classes: |
| 1088 cl = self.get_class(classname) | 1095 cl = self.get_class(classname) |
| 1096 | |
| 1097 f = open(os.path.join(dir, classname+'.csv'), 'wb') | |
| 1098 writer = csv.writer(f, colon_separated) | |
| 1099 | |
| 1100 properties = cl.getprops() | |
| 1101 propnames = cl.export_propnames() | |
| 1102 fields = propnames[:] | |
| 1103 fields.append('is retired') | |
| 1104 writer.writerow(fields) | |
| 1105 | |
| 1106 # all nodes for this class | |
| 1107 for nodeid in cl.getnodeids(): | |
| 1108 if self.verbose: | |
| 1109 sys.stdout.write('Exporting %s - %s\r'%(classname, nodeid)) | |
| 1110 sys.stdout.flush() | |
| 1111 if self.verbose: | |
| 1112 sys.stdout.write('Exporting %s - %s\r'%(classname, nodeid)) | |
| 1113 sys.stdout.flush() | |
| 1114 writer.writerow(cl.export_list(propnames, nodeid)) | |
| 1115 if hasattr(cl, 'export_files'): | |
| 1116 cl.export_files(dir, nodeid) | |
| 1117 | |
| 1118 # close this file | |
| 1119 f.close() | |
| 1120 if self.verbose: | |
| 1121 sys.stdout.write("\nExporting Journal for %s\n" % classname) | |
| 1122 sys.stdout.flush() | |
| 1123 journals = csv.writer(jf, colon_separated) | |
| 1124 map(journals.writerow, cl.export_journals()) | |
| 1125 jf.close() | |
| 1126 return 0 | |
| 1127 | |
| 1128 def do_exporttables(self, args): | |
| 1129 ""'''Usage: exporttables [[-]class[,class]] export_dir | |
| 1130 Export the database to colon-separated-value files, excluding the | |
| 1131 files below $TRACKER_HOME/db/files/ (which can be archived separately). | |
| 1132 To include the files, use the export command. | |
| 1133 | |
| 1134 Optionally limit the export to just the named classes | |
| 1135 or exclude the named classes, if the 1st argument starts with '-'. | |
| 1136 | |
| 1137 This action exports the current data from the database into | |
| 1138 colon-separated-value files that are placed in the nominated | |
| 1139 destination directory. | |
| 1140 ''' | |
| 1141 # grab the directory to export to | |
| 1142 if len(args) < 1: | |
| 1143 raise UsageError, _('Not enough arguments supplied') | |
| 1144 | |
| 1145 dir = args[-1] | |
| 1146 | |
| 1147 # get the list of classes to export | |
| 1148 if len(args) == 2: | |
| 1149 if args[0].startswith('-'): | |
| 1150 classes = [ c for c in self.db.classes.keys() | |
| 1151 if not c in args[0][1:].split(',') ] | |
| 1152 else: | |
| 1153 classes = args[0].split(',') | |
| 1154 else: | |
| 1155 classes = self.db.classes.keys() | |
| 1156 | |
| 1157 class colon_separated(csv.excel): | |
| 1158 delimiter = ':' | |
| 1159 | |
| 1160 # make sure target dir exists | |
| 1161 if not os.path.exists(dir): | |
| 1162 os.makedirs(dir) | |
| 1163 | |
| 1164 # do all the classes specified | |
| 1165 for classname in classes: | |
| 1166 cl = self.get_class(classname) | |
| 1167 if hasattr(cl, 'export_files'): | |
| 1168 sys.stdout.write('Exporting %s WITHOUT the files\r\n' % classname) | |
| 1089 | 1169 |
| 1090 f = open(os.path.join(dir, classname+'.csv'), 'wb') | 1170 f = open(os.path.join(dir, classname+'.csv'), 'wb') |
| 1091 writer = csv.writer(f, colon_separated) | 1171 writer = csv.writer(f, colon_separated) |
| 1092 | 1172 |
| 1093 properties = cl.getprops() | 1173 properties = cl.getprops() |
| 1100 for nodeid in cl.getnodeids(): | 1180 for nodeid in cl.getnodeids(): |
| 1101 if self.verbose: | 1181 if self.verbose: |
| 1102 sys.stdout.write('Exporting %s - %s\r'%(classname, nodeid)) | 1182 sys.stdout.write('Exporting %s - %s\r'%(classname, nodeid)) |
| 1103 sys.stdout.flush() | 1183 sys.stdout.flush() |
| 1104 writer.writerow(cl.export_list(propnames, nodeid)) | 1184 writer.writerow(cl.export_list(propnames, nodeid)) |
| 1105 if hasattr(cl, 'export_files'): | |
| 1106 cl.export_files(dir, nodeid) | |
| 1107 | 1185 |
| 1108 # close this file | 1186 # close this file |
| 1109 f.close() | 1187 f.close() |
| 1188 | |
| 1189 # export the journals | |
| 1190 jf = open(os.path.join(dir, classname+'-journals.csv'), 'wb') | |
| 1191 if self.verbose: | |
| 1192 sys.stdout.write("\nExporting Journal for %s\n" % classname) | |
| 1193 sys.stdout.flush() | |
| 1110 | 1194 |
| 1111 # export the journals | 1195 # export the journals |
| 1112 jf = open(os.path.join(dir, classname+'-journals.csv'), 'wb') | 1196 jf = open(os.path.join(dir, classname+'-journals.csv'), 'wb') |
| 1113 if self.verbose: | 1197 if self.verbose: |
| 1114 sys.stdout.write("\nExporting Journal for %s\n" % classname) | 1198 sys.stdout.write("\nExporting Journal for %s\n" % classname) |
