root / pykota / trunk / bin / dumpykota @ 2007

Revision 1991, 13.2 kB (checked in by jalet, 19 years ago)

The dumpykota command now supports extended filtering capabilities with
the PostgreSQL backend. LDAP doesn't yet support such possibilities.

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