1 | #! /usr/bin/env python |
---|
2 | # -*- coding: utf-8 -*- |
---|
3 | # |
---|
4 | # PyKota : Print Quotas for CUPS |
---|
5 | # |
---|
6 | # (c) 2003-2009 Jerome Alet <alet@librelogiciel.com> |
---|
7 | # This program is free software: you can redistribute it and/or modify |
---|
8 | # it under the terms of the GNU General Public License as published by |
---|
9 | # the Free Software Foundation, either version 3 of the License, or |
---|
10 | # (at your option) any later version. |
---|
11 | # |
---|
12 | # This program is distributed in the hope that it will be useful, |
---|
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
15 | # GNU General Public License for more details. |
---|
16 | # |
---|
17 | # You should have received a copy of the GNU General Public License |
---|
18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
---|
19 | # |
---|
20 | # $Id$ |
---|
21 | # |
---|
22 | # |
---|
23 | |
---|
24 | """A print quote generator for PyKota""" |
---|
25 | |
---|
26 | import sys |
---|
27 | import os |
---|
28 | import pwd |
---|
29 | |
---|
30 | import pykota.appinit |
---|
31 | from pykota.utils import run |
---|
32 | from pykota.commandline import PyKotaOptionParser |
---|
33 | from pykota.errors import PyKotaCommandLineError |
---|
34 | from pykota.tool import PyKotaTool |
---|
35 | from pykota.accounter import openAccounter |
---|
36 | |
---|
37 | class PyKotMe(PyKotaTool) : |
---|
38 | """A class for pykotme.""" |
---|
39 | def main(self, files, options) : |
---|
40 | """Gives print quotes.""" |
---|
41 | if (not sys.stdin.isatty()) and ("-" not in files) : |
---|
42 | # TODO : create a named temporary file for standard input |
---|
43 | # TODO : because if there are several printers on the command |
---|
44 | # TODO : line and they have different preaccounter directives, |
---|
45 | # TODO : the standard input will already be consumed when looping |
---|
46 | # TODO : over the second printer below. |
---|
47 | files.append("-") |
---|
48 | |
---|
49 | printers = self.storage.getMatchingPrinters(options.printer) |
---|
50 | if not printers : |
---|
51 | raise PyKotaCommandLineError, _("There's no printer matching %s") % options.printer |
---|
52 | |
---|
53 | username = pwd.getpwuid(os.getuid())[0] |
---|
54 | if options.user : |
---|
55 | if not self.config.isAdmin : |
---|
56 | self.printInfo(_("The --user command line option will be ignored because you are not a PyKota Administrator."), "warn") |
---|
57 | else : |
---|
58 | username = options.user |
---|
59 | |
---|
60 | user = self.storage.getUser(username) |
---|
61 | if not user.Exists : |
---|
62 | self.printInfo(_("There's no user matching '%(username)s'.") \ |
---|
63 | % locals(), |
---|
64 | "error") |
---|
65 | else : |
---|
66 | if user.LimitBy and (user.LimitBy.lower() == "balance"): |
---|
67 | self.display("%s\n" % (_("Your account balance : %.2f") % (user.AccountBalance or 0.0))) |
---|
68 | |
---|
69 | sizeprinted = False |
---|
70 | done = {} |
---|
71 | for printer in printers : |
---|
72 | # Now fake some values. TODO : improve API to not need this anymore |
---|
73 | printername = printer.Name |
---|
74 | self.PrinterName = printer.Name |
---|
75 | self.JobSizeBytes = 1 |
---|
76 | self.preaccounter = openAccounter(self, ispreaccounter=1) |
---|
77 | key = self.preaccounter.name + self.preaccounter.arguments |
---|
78 | if not done.has_key(key) : |
---|
79 | totalsize = 0 |
---|
80 | inkusage = [] |
---|
81 | for filename in files : |
---|
82 | self.DataFile = filename |
---|
83 | self.preaccounter.beginJob(None) |
---|
84 | self.preaccounter.endJob(None) |
---|
85 | totalsize += self.preaccounter.getJobSize(None) |
---|
86 | inkusage.extend(self.preaccounter.inkUsage) |
---|
87 | done[key] = (totalsize, inkusage) |
---|
88 | (totalsize, inkusage) = done[key] |
---|
89 | if not sizeprinted : |
---|
90 | self.display("%s\n" % (_("Job size : %i pages") % totalsize)) |
---|
91 | sizeprinted = True |
---|
92 | userpquota = self.storage.getUserPQuota(user, printer) |
---|
93 | if userpquota.Exists : |
---|
94 | if printer.MaxJobSize and (totalsize > printer.MaxJobSize) : |
---|
95 | self.display("%s\n" % (_("User %(username)s is not allowed to print so many pages on printer %(printername)s at this time.") % locals())) |
---|
96 | else : |
---|
97 | cost = userpquota.computeJobPrice(totalsize, inkusage) |
---|
98 | msg = _("Cost on printer %s : %.2f") % (printer.Name, cost) |
---|
99 | if printer.PassThrough : |
---|
100 | msg = "%s (%s)" % (msg, _("won't be charged, printer is in passthrough mode")) |
---|
101 | elif user.LimitBy == "nochange" : |
---|
102 | msg = "%s (%s)" % (msg, _("won't be charged, account is immutable")) |
---|
103 | self.display("%s\n" % msg) |
---|
104 | if user.LimitBy == "noprint" : |
---|
105 | self.display("%s\n" % (_("User %(username)s is forbidden to print at this time.") % locals())) |
---|
106 | |
---|
107 | if __name__ == "__main__" : |
---|
108 | parser = PyKotaOptionParser(description=_("Generates print quotes for end users."), |
---|
109 | usage="pykotme [options] [files]") |
---|
110 | parser.add_option("-P", "--printer", |
---|
111 | dest="printer", |
---|
112 | default="*", |
---|
113 | help=_("Acts on this printer only. You can specify several printer names by separating them with commas. The default value is '%default', which means all printers.")) |
---|
114 | parser.add_option("-u", "--user", |
---|
115 | dest="user", |
---|
116 | help=_("Acts on this user only. Only one username can be specified this way. The default value is the name of the user who launched this command. This option is ignored when the command is not launched by a PyKota Administrator.")) |
---|
117 | |
---|
118 | parser.add_example("--printer apple file1.ps <file2.pclxl", |
---|
119 | _("This would show the number of pages needed to print these two files, as well as the cost of printing them to the 'apple' printer for the user who launched this command.")) |
---|
120 | parser.add_example("--user john", |
---|
121 | _("This would show the number of pages needed to print the content of the standard input, and the cost of printing this on all printers for user 'john'.")) |
---|
122 | run(parser, PyKotMe) |
---|