root / pykota / trunk / bin / edpykota @ 3481

Revision 3481, 17.2 kB (checked in by jerome, 15 years ago)

Changed copyright years.
Copyright years are now dynamic when displayed by a command line tool.

  • 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: 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 quota entries manager for PyKota."""
25
26import sys
27
28import pykota.appinit
29from pykota.utils import run
30from pykota.commandline import PyKotaOptionParser
31from pykota.errors import PyKotaCommandLineError
32from pykota.tool import PyKotaTool
33from pykota.storage import StorageUserPQuota, StorageGroupPQuota
34from pykota.progressbar import Percent
35
36class EdPyKota(PyKotaTool) :
37    """A class for edpykota."""
38    def modifyPQEntry(self, pqkey, pqentry, noquota, softlimit, hardlimit, increase, reset, hardreset, suffix, used) :
39        """Modifies a print quota entry."""
40        if noquota or ((softlimit is not None) and (hardlimit is not None)) :
41            pqentry.setLimits(softlimit, hardlimit)
42        if increase :
43            newsoft = (pqentry.SoftLimit or 0) + increase
44            newhard = (pqentry.HardLimit or 0) + increase
45            if (newsoft >= 0) and (newhard >= 0) :
46                pqentry.setLimits(newsoft, newhard)
47            else :
48                self.printInfo(_("You can't set negative limits for %s") % pqkey, "error")
49        if reset :
50            pqentry.reset()
51        if hardreset :
52            pqentry.hardreset()
53        if suffix == "User" :
54            if used :
55                pqentry.setUsage(used)
56
57    def main(self, names, options) :
58        """Edit user or group quotas."""
59        islist = (options.action == "list")
60        isadd = (options.action == "add")
61        isdelete = (options.action == "delete")
62
63        if not islist :
64            self.adminOnly()
65
66        names = self.sanitizeNames(names, options.groups)
67        if not names :
68            if isdelete :
69                raise PyKotaCommandLineError, _("You must specify users or groups names on the command line.")
70            names = [u"*"]
71
72        if (((islist or isdelete) and (options.used  \
73                                      or options.softlimit \
74                                      or options.hardlimit \
75                                      or options.reset \
76                                      or options.hardreset \
77                                      or options.noquota \
78                                      or options.increase \
79                                      or options.skipexisting))) \
80             or (options.groups and (options.used \
81                                  or options.increase \
82                                  or options.reset \
83                                  or options.hardreset)) :
84            raise PyKotaCommandLineError, _("Incompatible command line options. Please look at the online help or manual page.")
85
86        suffix = (options.groups and "Group") or "User"
87        printernames = options.printer.split(",")
88
89        if not islist :
90            percent = Percent(self)
91            percent.display("%s..." % _("Extracting datas"))
92        printers = self.storage.getMatchingPrinters(options.printer)
93        entries = getattr(self.storage, "getMatching%ss" % suffix)(",".join(names))
94        if not islist :
95            percent.setSize(len(printers) * len(entries))
96
97        if islist :
98            for printer in printers :
99                for entry in entries :
100                    pqentry = getattr(self.storage, "get%sPQuota" % suffix)(entry, printer)
101                    if pqentry.Exists :
102                        self.display("%s@%s\n" % (entry.Name, printer.Name))
103                        self.display("    %s\n" % (_("Page counter : %s") % pqentry.PageCounter))
104                        self.display("    %s\n" % (_("Lifetime page counter : %s") % pqentry.LifePageCounter))
105                        self.display("    %s\n" % (_("Soft limit : %s") % pqentry.SoftLimit))
106                        self.display("    %s\n" % (_("Hard limit : %s") % pqentry.HardLimit))
107                        self.display("    %s\n" % (_("Date limit : %s") % pqentry.DateLimit))
108                        self.display("    %s (Not supported yet)\n" % (_("Maximum job size : %s") % ((pqentry.MaxJobSize and (_("%s pages") % pqentry.MaxJobSize)) or _("Unlimited"))))
109                        if hasattr(pqentry, "WarnCount") :
110                            self.display("    %s\n" % (_("Warning banners printed : %s") % pqentry.WarnCount))
111                        self.display("\n")
112        elif isdelete :
113            percent.display("\n%s..." % _("Deletion"))
114            getattr(self.storage, "deleteMany%sPQuotas" % suffix)(printers, entries)
115            percent.display("\n")
116        else :
117            used = options.used
118            if used :
119                used = used.strip()
120                try :
121                    int(used)
122                except ValueError :
123                    raise PyKotaCommandLineError, _("Invalid used value %s.") % used
124
125            increase = options.increase
126            if increase :
127                try :
128                    increase = int(increase.strip())
129                except ValueError :
130                    raise PyKotaCommandLineError, _("Invalid increase value %s.") % increase
131
132            softlimit = hardlimit = None
133            if not options.noquota :
134                if options.softlimit :
135                    try :
136                        softlimit = int(options.softlimit.strip())
137                        if softlimit < 0 :
138                            raise ValueError
139                    except ValueError :
140                        raise PyKotaCommandLineError, _("Invalid softlimit value %s.") % options.softlimit
141                if options.hardlimit :
142                    try :
143                        hardlimit = int(options.hardlimit.strip())
144                        if hardlimit < 0 :
145                            raise ValueError
146                    except ValueError :
147                        raise PyKotaCommandLineError, _("Invalid hardlimit value %s.") % options.hardlimit
148                if (softlimit is not None) and (hardlimit is not None) and (hardlimit < softlimit) :
149                    self.printInfo(_("Hard limit %(hardlimit)i is less than soft limit %(softlimit)i, values will be exchanged.") \
150                                       % locals())
151                    (softlimit, hardlimit) = (hardlimit, softlimit)
152                if hardlimit is None :
153                    hardlimit = softlimit
154                    if hardlimit is not None :
155                        self.printInfo(_("Undefined hard limit set to soft limit (%s).") % str(hardlimit))
156                if softlimit is None :
157                    softlimit = hardlimit
158                    if softlimit is not None :
159                        self.printInfo(_("Undefined soft limit set to hard limit (%s).") % str(softlimit))
160
161            self.storage.beginTransaction()
162            try :
163                if isadd :
164                    percent.display("\n%s...\n" % _("Creation"))
165                    if not entries :
166                        self.printInfo(_("No entry matches %s. Please use pkusers to create them first.") \
167                                           % (" ".join(names)), "warn")
168
169                    factory = globals()["Storage%sPQuota" % suffix]
170                    for printer in printers :
171                        pname = printer.Name
172                        for entry in entries :
173                            ename = entry.Name
174                            pqkey = "%s@%s" % (ename, pname)
175                            pqentry = factory(self.storage, entry, printer)
176                            self.modifyPQEntry(pqkey,
177                                               pqentry,
178                                               options.noquota,
179                                               softlimit,
180                                               hardlimit,
181                                               increase,
182                                               options.reset,
183                                               options.hardreset,
184                                               suffix,
185                                               used)
186                            oldpqentry = getattr(self.storage, "add%sPQuota" % suffix)(pqentry)
187                            if oldpqentry is not None :
188                                if options.skipexisting :
189                                    self.logdebug("%s print quota entry %s@%s already exists, skipping." \
190                                                      % (suffix, ename, pname))
191                                else :
192                                    self.logdebug("%s print quota entry %s@%s already exists, will be modified." \
193                                                      % (suffix, ename, pname))
194                                    self.modifyPQEntry(pqkey,
195                                                       oldpqentry,
196                                                       options.noquota,
197                                                       softlimit,
198                                                       hardlimit,
199                                                       increase,
200                                                       options.reset,
201                                                       options.hardreset,
202                                                       suffix,
203                                                       used)
204                                    oldpqentry.save()
205                            percent.oneMore()
206                else :
207                    percent.display("\n%s...\n" % _("Modification"))
208                    for printer in printers :
209                        for entry in entries :
210                            pqkey = "%s@%s" % (entry.Name, printer.Name)
211                            pqentry = getattr(self.storage, "get%sPQuota" % suffix)(entry, printer)
212                            if pqentry.Exists :
213                                self.modifyPQEntry(pqkey,
214                                                   pqentry,
215                                                   options.noquota,
216                                                   softlimit,
217                                                   hardlimit,
218                                                   increase,
219                                                   options.reset,
220                                                   options.hardreset,
221                                                   suffix,
222                                                   used)
223                                pqentry.save()
224                            percent.oneMore()
225            except :
226                self.storage.rollbackTransaction()
227                raise
228            else :
229                self.storage.commitTransaction()
230
231        if not islist :
232            percent.done()
233
234if __name__ == "__main__" :
235    parser = PyKotaOptionParser(description=_("Manages PyKota print quota entries for users or users groups. A print quota entry is related to both an user and a printer, or to both a group and a printer, meaning that for example different users can have different page count limits on the same printer. If an user doesn't have a print quota entry on a particular printer, he won't be allowed to print to it."),
236                                usage="edpykota [options] [usernames|groupnames]")
237    parser.add_option("-a", "--add",
238                            action="store_const",
239                            const="add",
240                            dest="action",
241                            help=_("Add new, or modify existing, users or groups print quota entries."))
242    parser.add_option("-d", "--delete",
243                            action="store_const",
244                            const="delete",
245                            dest="action",
246                            help=_("Delete the specified users or groups print quota entries. When deleting users print quota entries, the matching jobs are also deleted from the printing history."))
247    parser.add_option("-S", "--softlimit",
248                            dest="softlimit",
249                            help=_("Set the soft page count limit for the specified print quota entries. Users can print over this limit for a number of days specified in the 'gracedelay' directive in pykota.conf"))
250    parser.add_option("-H", "--hardlimit",
251                            dest="hardlimit",
252                            help=_("Set the hard page count limit for the specified print quota entries. Users are never allowed to print over this limit."))
253    parser.add_option("-g", "--groups",
254                            action="store_true",
255                            dest="groups",
256                            help=_("Manage groups print quota entries instead of users print quota entries."))
257    parser.add_option("-I", "--increase",
258                            dest="increase",
259                            help=_("Increase the existing soft and hard page count limits for the specified print quota entries. You can decrease the values instead by prefixing this parameter with a negative sign."))
260    parser.add_option("-L", "--list",
261                            action="store_const",
262                            const="list",
263                            dest="action",
264                            help=_("Display detailed informations about the specified users or groups print quota entries."))
265    parser.add_option("-n", "--noquota",
266                            dest="noquota",
267                            action="store_true",
268                            help=_("Set no limit for both soft and hard page counts for the specified users or groups print quota entries."))
269    parser.add_option("-P", "--printer",
270                            dest="printer",
271                            default="*",
272                            help=_("Specify a comma separated list of printers you want to manage print quota entries on. The default is '*', meaning all printers."))
273    parser.add_option("-r", "--reset",
274                            dest="reset",
275                            action="store_true",
276                            help=_("Reset the actual page counter for the specified users print quota entries (doesn't work for groups print quota entries). The life time page counter is left unchanged."))
277    parser.add_option("-R", "--hardreset",
278                            dest="hardreset",
279                            action="store_true",
280                            help=_("Reset the actual and life time page counters for the specified users print quota entries (doesn't work for groups print quota entries). This is a shortcut for --used 0."))
281    parser.add_option("-s", "--skipexisting",
282                            action="store_true",
283                            dest="skipexisting",
284                            help=_("If --add is used, ensure that existing users or groups print quota entries won't be modified."))
285    parser.add_option("-U", "--used",
286                            dest="used",
287                            help=_("Set the values of both the actual and life time page counters for the specified users print quota entries (doesn't work for groups print quota entries). This can be useful when migrating from a different print quota software. The values can also be increased or decreased by prefixing this parameter with either a positive or negative sign."))
288
289    parser.add_example("--add john paul george ringo",
290                       _("Would create print quota entries with no page count limits for these four users on all existing printers."))
291    parser.add_example("--printer HP --softlimit 50 --hardlimit 60 jerome",
292                       _("Would allow user 'jerome' to print up to 60 pages on printer 'HP'. This user would be warned when he would have reached 50 pages on this printer. Both the user and printer must have been created previously using the pkusers and pkprinters commands, respectively."))
293    parser.add_example("--groups --softlimit 500 --hardlimit 600 support financial",
294                       _("Would set soft and hard page count limits on any printer for groups 'support' and 'financial'."))
295    parser.add_example('--reset --printer HP jerome "jo*"',
296                       _("Would reset the actual page counter for users 'jerome' and all users whose name begins with 'jo' on printer 'HP'."))
297    parser.add_example("--printer HPCOLOR --noquota jerome",
298                       _("Would allow this user to print without any page limit on printer 'HPCOLOR'. Depending on how this user is limited, he may still be subject to being limited by the number of available credits in his account."))
299    parser.add_example("--add --skipexisting",
300                       _("Would create a print quota entry for each user on each printer for which none already existed. You'll most likely want to use this command at least once after initial setup."))
301    run(parser, EdPyKota)
Note: See TracBrowser for help on using the browser.