211 | | class DumPyKota(PyKotaTool) : |
212 | | """A class for dumpykota.""" |
213 | | def main(self, arguments, options) : |
214 | | """Print Quota Data Dumper.""" |
215 | | if not self.config.isAdmin : |
216 | | raise PyKotaToolError, "%s : %s" % (pwd.getpwuid(os.geteuid())[0], _("You're not allowed to use this command.")) |
217 | | |
218 | | extractonly = {} |
219 | | for filterexp in arguments : |
220 | | if filterexp.strip() : |
221 | | try : |
222 | | (filterkey, filtervalue) = [part.strip() for part in filterexp.split("=")] |
223 | | if filterkey not in [ "username", |
224 | | "groupname", |
225 | | "printername", |
226 | | "pgroupname", |
227 | | ] : |
228 | | raise ValueError |
229 | | except ValueError : |
230 | | raise PyKotaToolError, _("Invalid value [%s] for --filter command line option, see help.") % filterexp |
231 | | else : |
232 | | extractonly.update({ filterkey : filtervalue }) |
233 | | |
234 | | datatype = options["data"] |
235 | | if datatype not in [ "history", |
236 | | "users", |
237 | | "groups", |
238 | | "printers", |
239 | | "upquotas", |
240 | | "gpquotas", |
241 | | "payments", |
242 | | "pmembers", |
243 | | "umembers", |
244 | | ] : |
245 | | raise PyKotaToolError, _("Invalid modifier [%s] for --data command line option, see help.") % datatype |
246 | | |
247 | | format = options["format"] |
248 | | if (format not in [ "csv", |
249 | | "ssv", |
250 | | "tsv", |
251 | | "xml", |
252 | | "cups", |
253 | | ]) \ |
254 | | or ((format == "cups") and (datatype != "history")) : |
255 | | raise PyKotaToolError, _("Invalid modifier [%s] for --format command line option, see help.") % format |
256 | | |
257 | | if (format == "xml") and not hasJAXML : |
258 | | raise PyKotaToolError, _("XML output is disabled because the jaxml module is not available.") |
259 | | |
260 | | entries = getattr(self.storage, "extract%s" % datatype.title())(extractonly) |
261 | | if entries : |
262 | | mustclose = 0 |
263 | | if options["output"].strip() == "-" : |
264 | | self.outfile = sys.stdout |
265 | | else : |
266 | | self.outfile = open(options["output"], "w") |
267 | | mustclose = 1 |
268 | | |
269 | | retcode = getattr(self, "dump%s" % format.title())(entries, datatype) |
270 | | |
271 | | if mustclose : |
272 | | self.outfile.close() |
273 | | |
274 | | return retcode |
275 | | return 0 |
276 | | |
277 | | def dumpWithSeparator(self, separator, entries) : |
278 | | """Dumps datas with a separator.""" |
279 | | for entry in entries : |
280 | | line = separator.join([ '"%s"' % field for field in entry ]) |
281 | | try : |
282 | | self.outfile.write("%s\n" % line) |
283 | | except IOError, msg : |
284 | | sys.stderr.write("%s : %s\n" % (_("PyKota data dumper failed : I/O error"), msg)) |
285 | | return -1 |
286 | | return 0 |
287 | | |
288 | | def dumpCsv(self, entries, dummy) : |
289 | | """Dumps datas with a comma as the separator.""" |
290 | | return self.dumpWithSeparator(",", entries) |
291 | | |
292 | | def dumpSsv(self, entries, dummy) : |
293 | | """Dumps datas with a comma as the separator.""" |
294 | | return self.dumpWithSeparator(";", entries) |
295 | | |
296 | | def dumpTsv(self, entries, dummy) : |
297 | | """Dumps datas with a comma as the separator.""" |
298 | | return self.dumpWithSeparator("\t", entries) |
299 | | |
300 | | def dumpCups(self, entries, dummy) : |
301 | | """Dumps history datas as CUPS' page_log format.""" |
302 | | fieldnames = entries[0] |
303 | | fields = {} |
304 | | for i in range(len(fieldnames)) : |
305 | | fields[fieldnames[i]] = i |
306 | | sortindex = fields["jobdate"] |
307 | | entries = entries[1:] |
308 | | entries.sort(lambda m,n : cmp(m[sortindex], n[sortindex])) |
309 | | for entry in entries[1:] : |
310 | | printername = entry[fields["printername"]] |
311 | | username = entry[fields["username"]] |
312 | | jobid = entry[fields["jobid"]] |
313 | | jobdate = DateTime.ISO.ParseDateTime(entry[fields["jobdate"]]) |
314 | | gmtoffset = jobdate.gmtoffset() |
315 | | jobdate = "%s %+03i00" % (jobdate.strftime("%d/%b/%Y:%H:%M:%S"), gmtoffset.hour) |
316 | | jobsize = entry[fields["jobsize"]] |
317 | | copies = entry[fields["copies"]] |
318 | | hostname = entry[fields["hostname"]] |
319 | | self.outfile.write("%s %s %s [%s] %s %s - %s\n" % (printername, username, jobid, jobdate, jobsize, copies, hostname)) |
320 | | |
321 | | def dumpXml(self, entries, datatype) : |
322 | | """Dumps datas as XML.""" |
323 | | x = jaxml.XML_document(encoding="UTF-8") |
324 | | x.pykota(version=version.__version__, author=version.__author__) |
325 | | x.dump(storage=self.config.getStorageBackend()["storagebackend"], type=datatype) |
326 | | headers = entries[0] |
327 | | for entry in entries[1:] : |
328 | | x._push() |
329 | | x.entry() |
330 | | for i in range(len(entry)) : |
331 | | value = str(entry[i]) |
332 | | typval = type(entry[i]).__name__ |
333 | | try : |
334 | | value = unicode(value, self.getCharset()).encode("UTF-8") |
335 | | except UnicodeError : |
336 | | pass |
337 | | x.attribute(value, type=typval, name=headers[i]) |
338 | | x._pop() |
339 | | x._output(self.outfile) |
340 | | |