root / pykota / trunk / bin / dumpykota @ 2013

Revision 2013, 14.7 kB (checked in by jalet, 19 years ago)

Now dumpykota can dump the history into CUPS' page_log format, allowing the
use of tools like PrintAnalyzer? or phpPrintAnalyzer along with PyKota

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