root / pykota / trunk / bin / dumpykota @ 2010

Revision 2010, 13.3 kB (checked in by jalet, 19 years ago)

Fixed field type's name in XML dumps.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1#! /usr/bin/env python
2# -*- coding: ISO-8859-15 -*-
3
4# PyKota Print Quota Data Dumper
5#
6# PyKota - Print Quotas for CUPS and LPRng
7#
8# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22#
23# $Id$
24#
25# $Log$
26# Revision 1.18  2005/01/07 12:40:53  jalet
27# Fixed field type's name in XML dumps.
28#
29# Revision 1.17  2004/12/21 15:50:00  jalet
30# The dumpykota command now supports extended filtering capabilities with
31# the PostgreSQL backend. LDAP doesn't yet support such possibilities.
32#
33# Revision 1.16  2004/12/21 14:45:31  jalet
34# Prepared dumpykota to accept the new --filter command line option. Some
35# additionnal work needs to be done in the backends though.
36#
37# Revision 1.15  2004/10/12 15:37:00  jalet
38# Now outputs the name of the offending user if a mere mortal tries to use
39# one of these commands !!!
40#
41# Revision 1.14  2004/10/11 22:53:05  jalet
42# Postponed string interpolation to help message's output method
43#
44# Revision 1.13  2004/10/11 12:49:06  jalet
45# Renders help translatable
46#
47# Revision 1.12  2004/10/07 21:14:28  jalet
48# Hopefully final fix for data encoding to and from the database
49#
50# Revision 1.11  2004/10/07 14:35:40  jalet
51# Now edpykota refuses to launch if the user is not a PyKota administrator.
52# dumpykota : now has the same error message than edpykota in this case.
53#
54# Revision 1.10  2004/10/06 10:05:47  jalet
55# Minor changes to allow any PyKota administrator to launch enhanced versions
56# of the commands, and not only the root user.
57#
58# Revision 1.9  2004/10/05 20:08:46  jalet
59# Misleading help message. Thx to Johannes Laemmermann.
60#
61# Revision 1.8  2004/10/05 09:59:19  jalet
62# Restore compatibility with Python 2.1
63#
64# Revision 1.7  2004/10/04 21:25:29  jalet
65# dumpykota can now output datas in the XML format
66#
67# Revision 1.6  2004/09/15 18:28:41  jalet
68# Updated help for dumpykota
69#
70# Revision 1.5  2004/09/15 07:38:05  jalet
71# Fix for uninitialized variable
72#
73# Revision 1.4  2004/09/15 07:26:19  jalet
74# Data dumps are now ordered by entry creation date if applicable.
75# Now dumpykota exits with a message when there's a broken pipe like
76# in dumpykota --data history | head -3
77#
78# Revision 1.3  2004/09/15 06:58:25  jalet
79# User groups membership and printer groups membership can now be dumped too
80#
81# Revision 1.2  2004/09/14 22:29:12  jalet
82# First version of dumpykota. Works fine but only with PostgreSQL backend
83# for now.
84#
85# Revision 1.1  2004/07/01 19:22:37  jalet
86# First draft of dumpykota
87#
88#
89#
90
91import sys
92import os
93import pwd
94
95try :
96    import jaxml
97except ImportError :   
98    sys.stderr.write("The jaxml Python module is not installed. XML output is disabled.\n")
99    sys.stderr.write("Download jaxml from http://www.librelogiciel.com/software/ or from your Debian archive of choice\n")
100    hasJAXML = 0
101else :   
102    hasJAXML = 1
103
104from pykota import version
105from pykota.tool import PyKotaTool, PyKotaToolError, crashed, N_
106from pykota.config import PyKotaConfigError
107from pykota.storage import PyKotaStorageError
108
109__doc__ = N_("""dumpykota v%s (c) 2003-2004 C@LL - Conseil Internet & Logiciels Libres
110
111Dumps PyKota database's content.
112
113command line usage :
114
115  dumpykota [options] [filterexpr]
116
117options :
118
119  -v | --version       Prints dumpykota's version number then exits.
120  -h | --help          Prints this message then exits.
121 
122  -d | --data type     Dumps 'type' datas. Allowed types are :
123                       
124                         - history : dumps the jobs history.
125                         - users : dumps users.
126                         - groups : dumps user groups.
127                         - printers : dump printers.
128                         - upquotas : dump user quotas.
129                         - gpquotas : dump user groups quotas.
130                         - payments : dumps user payments.
131                         - pmembers : dumps printer groups members.
132                         - umembers : dumps user groups members.
133                         
134                       NB : the -d | --data command line option   
135                       is MANDATORY.
136 
137  -f | --format fmt    Dumps datas in the 'fmt' format. When not specified,
138                       the format is to dump datas in the csv format (comma
139                       separated values). All data dumped is between double
140                       quotes. Allowed formats are :
141                       
142                         - csv : separate datas with commas
143                         - ssv : separate datas with semicolons
144                         - tsv : separate datas with tabs
145                         - xml : dump data as XML
146                         
147  -o | --output fname  All datas will be dumped to the file instead of
148                       to the standard output. The special '-' filename
149                       is the default value and means stdout.
150                       WARNING : existing files are truncated !
151                       
152  Use the filter expressions to extract only parts of the
153  datas. Allowed filters are of the form :
154               
155         key=value
156                         
157  Allowed keys for now are : 
158                       
159         username       User's name
160         groupname      Users group's name
161         printername    Printer's name
162         pgroupname     Printers group's name
163         
164  Contrary to other PyKota management tools, wildcard characters are not
165  expanded, so you can't use them.
166 
167  NB : not all keys are allowed for each data type, so the result may be
168  empty if you use a key not available for a particular data type.
169 
170Examples :
171
172  $ dumpykota --data history --format csv >myfile.csv
173 
174  This dumps the history in a comma separated values file, for possible
175  use in a spreadsheet.
176 
177  $ dumpykota --data users --format xml -o users.xml
178 
179  Dumps all users datas to the users.xml file.
180 
181  $ dumpykota --data history printername=HP2100 username=jerome
182 
183  Dumps the job history for user jerome on printer HP2100 only.
184 
185This program is free software; you can redistribute it and/or modify
186it under the terms of the GNU General Public License as published by
187the Free Software Foundation; either version 2 of the License, or
188(at your option) any later version.
189
190This program is distributed in the hope that it will be useful,
191but WITHOUT ANY WARRANTY; without even the implied warranty of
192MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
193GNU General Public License for more details.
194
195You should have received a copy of the GNU General Public License
196along with this program; if not, write to the Free Software
197Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
198
199Please e-mail bugs to: %s""")
200       
201class DumPyKota(PyKotaTool) :       
202    """A class for dumpykota."""
203    def main(self, arguments, options) :
204        """Print Quota Data Dumper."""
205        if not self.config.isAdmin :
206            raise PyKotaToolError, "%s : %s" % (pwd.getpwuid(os.geteuid())[0], _("You're not allowed to use this command."))
207           
208        extractonly = {}
209        for filterexp in arguments :
210            if filterexp.strip() :
211                try :
212                    (filterkey, filtervalue) = [part.strip() for part in filterexp.split("=")]
213                    if filterkey not in [ "username",
214                                          "groupname",
215                                          "printername",
216                                          "pgroupname",
217                                        ] :
218                        raise ValueError               
219                except ValueError :   
220                    raise PyKotaToolError, _("Invalid value [%s] for --filter command line option, see help.") % filterexp
221                else :   
222                    extractonly.update({ filterkey : filtervalue })
223           
224        datatype = options["data"]
225        if datatype not in [ "history",
226                             "users",
227                             "groups",
228                             "printers",
229                             "upquotas",
230                             "gpquotas",
231                             "payments",
232                             "pmembers",
233                             "umembers",
234                           ] :
235            raise PyKotaToolError, _("Invalid modifier [%s] for --data command line option, see help.") % datatype
236                   
237        format = options["format"]
238        if format not in [ "csv",
239                           "ssv",
240                           "tsv",
241                           "xml",
242                         ] :
243            raise PyKotaToolError, _("Invalid modifier [%s] for --format command line option, see help.") % datatype
244           
245        if (format == "xml") and not hasJAXML :
246            raise PyKotaToolError, _("XML output is disabled because the jaxml module is not available.")
247           
248        entries = getattr(self.storage, "extract%s" % datatype.title())(extractonly)   
249        if entries :
250            mustclose = 0   
251            if options["output"].strip() == "-" :   
252                self.outfile = sys.stdout
253            else :   
254                self.outfile = open(options["output"], "w")
255                mustclose = 1
256               
257            retcode = getattr(self, "dump%s" % format.title())(entries, datatype)
258           
259            if mustclose :
260                self.outfile.close()
261               
262            return retcode   
263        return 0
264       
265    def dumpWithSeparator(self, separator, entries) :   
266        """Dumps datas with a separator."""
267        for entry in entries :
268            line = separator.join([ '"%s"' % field for field in entry ])
269            try :
270                self.outfile.write("%s\n" % line)
271            except IOError, msg :   
272                sys.stderr.write("%s : %s\n" % (_("PyKota data dumper failed : I/O error"), msg))
273                return -1
274        return 0       
275       
276    def dumpCsv(self, entries, dummy) :   
277        """Dumps datas with a comma as the separator."""
278        return self.dumpWithSeparator(",", entries)
279                           
280    def dumpSsv(self, entries, dummy) :   
281        """Dumps datas with a comma as the separator."""
282        return self.dumpWithSeparator(";", entries)
283                           
284    def dumpTsv(self, entries, dummy) :   
285        """Dumps datas with a comma as the separator."""
286        return self.dumpWithSeparator("\t", entries)
287       
288    def dumpXml(self, entries, datatype) :   
289        """Dumps datas as XML."""
290        x = jaxml.XML_document(encoding="UTF-8")
291        x.pykota(version=version.__version__, author=version.__author__)
292        x.dump(storage=self.config.getStorageBackend()["storagebackend"], type=datatype)
293        headers = entries[0]
294        for entry in entries[1:] :
295            x._push()
296            x.entry()
297            for i in range(len(entry)) :
298                value = str(entry[i])
299                typval = type(entry[i]).__name__
300                try :
301                    value = unicode(value, self.getCharset()).encode("UTF-8")
302                except UnicodeError :   
303                    pass
304                x.attribute(value, type=typval, name=headers[i])
305            x._pop()   
306        x._output(self.outfile)
307                           
308if __name__ == "__main__" : 
309    retcode = 0
310    try :
311        defaults = { \
312                     "format" : "csv", \
313                     "output" : "-", \
314                   }
315        short_options = "vhd:f:o:"
316        long_options = ["help", "version", "data=", "format=", "output="]
317       
318        # Initializes the command line tool
319        dumper = DumPyKota(doc=__doc__)
320       
321        # parse and checks the command line
322        (options, args) = dumper.parseCommandline(sys.argv[1:], short_options, long_options, allownothing=1)
323       
324        # sets long options
325        options["help"] = options["h"] or options["help"]
326        options["version"] = options["v"] or options["version"]
327        options["data"] = options["d"] or options["data"]
328        options["format"] = options["f"] or options["format"] or defaults["format"]
329        options["output"] = options["o"] or options["output"] or defaults["output"]
330       
331        if options["help"] :
332            dumper.display_usage_and_quit()
333        elif options["version"] :
334            dumper.display_version_and_quit()
335        elif options["data"] is None :   
336            raise PyKotaToolError, _("The -d | --data command line option is mandatory, see help.")
337        else :
338            retcode = dumper.main(args, options)
339    except SystemExit :       
340        pass
341    except :
342        try :
343            dumper.crashed("dumpykota failed")
344        except :   
345            crashed("dumpykota failed")
346        retcode = -1
347
348    try :
349        dumper.storage.close()
350    except (TypeError, NameError, AttributeError) :   
351        pass
352       
353    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.