root / pykota / trunk / pykota / cups.py @ 3498

Revision 3498, 5.1 kB (checked in by jerome, 13 years ago)

Ensures IPP requests are decoded using the charset they were encoded in,
and which may not always be UTF-8 with old CUPS releases.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1# -*- coding: utf-8 -*-
2#
3# PyKota : Print Quotas for CUPS
4#
5# (c) 2003-2009 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 3 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, see <http://www.gnu.org/licenses/>.
18#
19# $Id$
20#
21
22"""This module implements some CUPS specific classes."""
23
24from pykota.errors import PyKotaToolError
25try :
26    from pkipplib import pkipplib
27except ImportError :
28    raise RuntimeError, "The python-pkipplib module is now mandatory. You can download pkipplib from http://www.pykota.com/"
29
30class JobTicket :
31    """A class to hold CUPS print job informations."""
32    def __init__(self, jobid=None, printername=None, copies=1, filename=None, \
33                       options=None) :
34        """Initializes a print job's information."""
35        self.JobId = jobid
36        self.PrinterName = printername
37        self.Copies = copies
38        self.FileName = filename
39        self.Options = options
40        self.Charset = None
41        self.OriginatingUserName = None
42        self.OriginalUserName = None
43        self.Title = None
44        self.BillingCode = None
45        self.OriginatingHostName = None
46        self.TimeAtCreation = None
47        self.TimeAtProcessing = None
48        self.MimeType = None
49        self.UUID = None
50        if self.JobId is not None :
51            self.retrieveAttributesFromCUPS()
52
53    def getAttributeTypeAndValue(self, ippanswer, attribute, category="job") :
54        """Retrieves a particular attribute's type and value from an IPP answer.
55
56           Returns a tuple of the form (type, value).
57        """
58        try :
59            return getattr(ippanswer, category)[attribute][0]
60        except KeyError :
61            return (None, None)
62
63    def retrieveAttributesFromCUPS(self) :
64        """Retrieve attribute's values from CUPS."""
65        server = pkipplib.CUPS() # TODO : username and password and/or encryption
66        answer = server.getJobAttributes(self.JobId)
67        if answer is None :
68            raise PyKotaToolError, "Network error while querying the CUPS server : %s" \
69                                      % server.lastErrorMessage
70        (dummy, self.Charset) = self.getAttributeTypeAndValue(answer, "attributes-charset", "operation")
71        (dummy, self.OriginatingUserName) = self.getAttributeTypeAndValue(answer, "job-originating-user-name")
72        (dummy, self.Title) = self.getAttributeTypeAndValue(answer, "job-name")
73        (dummy, self.BillingCode) = self.getAttributeTypeAndValue(answer, "job-billing")
74        (dummy, self.OriginatingHostName) = self.getAttributeTypeAndValue(answer, "job-originating-host-name")
75        (dummy, self.UUID) = self.getAttributeTypeAndValue(answer, "job-uuid")
76        (dummy, self.TimeAtCreation) = self.getAttributeTypeAndValue(answer, "time-at-creation")
77        (dummy, self.TimeAtProcessing) = self.getAttributeTypeAndValue(answer, "time-at-processing")
78        (dummy, self.MimeType) = self.getAttributeTypeAndValue(answer, "document-format")
79
80        # handle Kerberized usernames as described here :
81        # http://www.mit.edu/~kerberos/krb5-1.5/krb5-1.5.4/doc/krb5-user/What-is-a-Kerberos-Principal_003f.html
82        #
83        # Only does this if there's a "@" in the username, otherwise we could break non-kerberized
84        # usernames containing a "/", like Samba/Windows usernames in some cases.
85        if self.OriginatingUserName.find("@") != -1 :
86            self.OriginatingUserName = self.OriginatingUserName.split("@", 1)[0].split("/")[0]
87
88        for attrib in ("OriginatingUserName",
89                       "OriginatingHostName",
90                       "Title",
91                       "BillingCode",
92                       "PrinterName",
93                       "Options",
94                       "Charset",
95                       "UUID",
96                       "MimeType") :
97            try :
98                setattr(self, attrib,
99                              getattr(self, attrib).decode(self.Charset, "replace")) # Charset itself should only be stored in ascii anyway
100            except AttributeError :
101                pass
102
103        self.OriginalUserName = self.OriginatingUserName[:]
104
105if __name__ == "__main__" :
106    import sys
107    if len(sys.argv) != 2 :
108        sys.stderr.write("usage : python cups.py jobid\n")
109    else :
110        job = JobTicket(int(sys.argv[1]), "FakePrinter")
111        for attribute in ("PrinterName", "Charset", "JobId", "Copies",
112                          "FileName", "OriginatingUserName",
113                          "Title", "BillingCode", "OriginatingHostName",
114                          "TimeAtCreation", "TimeAtProcessing", "UUID",
115                          "MimeType") :
116            sys.stdout.write("%s : %s\n" % (attribute, repr(getattr(job, attribute))))
Note: See TracBrowser for help on using the browser.