root / pykota / trunk / pykota / dumper.py @ 2218

Revision 2218, 7.5 kB (checked in by jerome, 19 years ago)

The data dumper now supports filtering by hostname
or billing code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1# PyKota Print Quota Data Dumper
2#
3# PyKota - Print Quotas for CUPS and LPRng
4#
5# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19#
20# $Id$
21#
22#
23
24import sys
25import os
26import pwd
27from mx import DateTime
28
29try :
30    import jaxml
31except ImportError :   
32    sys.stderr.write("The jaxml Python module is not installed. XML output is disabled.\n")
33    sys.stderr.write("Download jaxml from http://www.librelogiciel.com/software/ or from your Debian archive of choice\n")
34    hasJAXML = 0
35else :   
36    hasJAXML = 1
37
38from pykota import version
39from pykota.tool import PyKotaTool, PyKotaToolError, N_
40
41class DumPyKota(PyKotaTool) :       
42    """A class for dumpykota."""
43    validdatatypes = { "history" : N_("History"),
44                       "users" : N_("Users"),
45                       "groups" : N_("Groups"),
46                       "printers" : N_("Printers"),
47                       "upquotas" : N_("Users Print Quotas"),
48                       "gpquotas" : N_("Users Groups Print Quotas"),
49                       "payments" : N_("History of Payments"),
50                       "pmembers" : N_("Printers Groups Membership"), 
51                       "umembers" : N_("Users Groups Membership"),
52                     }
53    validformats = { "csv" : N_("Comma Separated Values"),
54                     "ssv" : N_("Semicolon Separated Values"),
55                     "tsv" : N_("Tabulation Separated Values"),
56                     "xml" : N_("eXtensible Markup Language"),
57                     "cups" : N_("CUPS' page_log"),
58                   } 
59    validfilterkeys = [ "username",
60                        "groupname",
61                        "printername",
62                        "pgroupname",
63                        "hostname",
64                        "billingcode",
65                      ]
66    def main(self, arguments, options, restricted=1) :
67        """Print Quota Data Dumper."""
68        if restricted and not self.config.isAdmin :
69            raise PyKotaToolError, "%s : %s" % (pwd.getpwuid(os.geteuid())[0], _("You're not allowed to use this command."))
70           
71        extractonly = {}
72        for filterexp in arguments :
73            if filterexp.strip() :
74                try :
75                    (filterkey, filtervalue) = [part.strip() for part in filterexp.split("=")]
76                    if filterkey not in self.validfilterkeys :
77                        raise ValueError               
78                except ValueError :   
79                    raise PyKotaToolError, _("Invalid filter value [%s], see help.") % filterexp
80                else :   
81                    extractonly.update({ filterkey : filtervalue })
82           
83        datatype = options["data"]
84        if datatype not in self.validdatatypes.keys() :
85            raise PyKotaToolError, _("Invalid modifier [%s] for --data command line option, see help.") % datatype
86                   
87        format = options["format"]
88        if (format not in self.validformats.keys()) \
89              or ((format == "cups") and (datatype != "history")) :
90            raise PyKotaToolError, _("Invalid modifier [%s] for --format command line option, see help.") % format
91           
92        if (format == "xml") and not hasJAXML :
93            raise PyKotaToolError, _("XML output is disabled because the jaxml module is not available.")
94           
95        entries = getattr(self.storage, "extract%s" % datatype.title())(extractonly)
96        if entries :
97            mustclose = 0   
98            if options["output"].strip() == "-" :   
99                self.outfile = sys.stdout
100            else :   
101                self.outfile = open(options["output"], "w")
102                mustclose = 1
103               
104            retcode = getattr(self, "dump%s" % format.title())(entries, datatype)
105           
106            if mustclose :
107                self.outfile.close()
108               
109            return retcode   
110        return 0
111       
112    def dumpWithSeparator(self, separator, entries) :   
113        """Dumps datas with a separator."""
114        for entry in entries :
115            line = separator.join([ '"%s"' % field for field in entry ])
116            try :
117                self.outfile.write("%s\n" % line)
118            except IOError, msg :   
119                sys.stderr.write("%s : %s\n" % (_("PyKota data dumper failed : I/O error"), msg))
120                return -1
121        return 0       
122       
123    def dumpCsv(self, entries, dummy) :   
124        """Dumps datas with a comma as the separator."""
125        return self.dumpWithSeparator(",", entries)
126                           
127    def dumpSsv(self, entries, dummy) :   
128        """Dumps datas with a comma as the separator."""
129        return self.dumpWithSeparator(";", entries)
130                           
131    def dumpTsv(self, entries, dummy) :   
132        """Dumps datas with a comma as the separator."""
133        return self.dumpWithSeparator("\t", entries)
134       
135    def dumpCups(self, entries, dummy) :   
136        """Dumps history datas as CUPS' page_log format."""
137        fieldnames = entries[0]
138        fields = {}
139        for i in range(len(fieldnames)) :
140            fields[fieldnames[i]] = i
141        sortindex = fields["jobdate"]   
142        entries = entries[1:]
143        entries.sort(lambda m,n,si=sortindex : cmp(m[si], n[si]))
144        for entry in entries[1:] :   
145            printername = entry[fields["printername"]]
146            username = entry[fields["username"]]
147            jobid = entry[fields["jobid"]]
148            jobdate = DateTime.ISO.ParseDateTime(entry[fields["jobdate"]])
149            gmtoffset = jobdate.gmtoffset()
150            jobdate = "%s %+03i00" % (jobdate.strftime("%d/%b/%Y:%H:%M:%S"), gmtoffset.hour)
151            jobsize = entry[fields["jobsize"]] or 0
152            copies = entry[fields["copies"]] or 1
153            hostname = entry[fields["hostname"]] or ""
154            billingcode = entry[fields["billingcode"]] or "-"
155            for pagenum in range(1, jobsize+1) :
156                self.outfile.write("%s %s %s [%s] %s %s %s %s\n" % (printername, username, jobid, jobdate, pagenum, copies, billingcode, hostname))
157       
158    def dumpXml(self, entries, datatype) :   
159        """Dumps datas as XML."""
160        x = jaxml.XML_document(encoding="UTF-8")
161        x.pykota(version=version.__version__, author=version.__author__)
162        x.dump(storage=self.config.getStorageBackend()["storagebackend"], type=datatype)
163        headers = entries[0]
164        for entry in entries[1:] :
165            x._push()
166            x.entry()
167            for i in range(len(entry)) :
168                value = str(entry[i])
169                typval = type(entry[i]).__name__
170                try :
171                    value = unicode(value, self.getCharset()).encode("UTF-8")
172                except UnicodeError :   
173                    pass
174                x.attribute(value, type=typval, name=headers[i])
175            x._pop()   
176        x._output(self.outfile)
Note: See TracBrowser for help on using the browser.