root / pykota / trunk / bin / warnpykota @ 3260

Revision 3260, 6.5 kB (checked in by jerome, 16 years ago)

Changed license to GNU GPL v3 or later.
Changed Python source encoding from ISO-8859-15 to UTF-8 (only ASCII
was used anyway).

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[696]1#! /usr/bin/env python
[3260]2# -*- coding: UTF-8 -*-
[696]3#
[3260]4# PyKota : Print Quotas for CUPS
[696]5#
[3133]6# (c) 2003, 2004, 2005, 2006, 2007 Jerome Alet <alet@librelogiciel.com>
[3260]7# This program is free software: you can redistribute it and/or modify
[873]8# it under the terms of the GNU General Public License as published by
[3260]9# the Free Software Foundation, either version 3 of the License, or
[873]10# (at your option) any later version.
[3260]11#
[873]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
[3260]18# along with this program.  If not, see <http://www.gnu.org/licenses/>.
[696]19#
20# $Id$
21#
[2028]22#
[696]23
[728]24import sys
[1041]25import os
26import pwd
[728]27
[2829]28from pykota.tool import PyKotaTool, PyKotaCommandLineError, crashed, N_
[728]29
[2344]30__doc__ = N_("""warnpykota v%(__version__)s (c) %(__years__)s %(__author__)s
[728]31
[730]32Sends mail to users over print quota.
33
[728]34command line usage :
35
[1041]36  warnpykota  [options]  [names]
[728]37
38options :
39
40  -v | --version       Prints warnpykota's version number then exits.
41  -h | --help          Prints this message then exits.
42 
[866]43  -u | --users         Warns users over their print quota, this is the
44                       default.
[728]45 
[934]46  -g | --groups        Warns users whose groups quota are over limit.
[728]47 
48  -P | --printer p     Verify quotas on this printer only. Actually p can
49                       use wildcards characters to select only
50                       some printers. The default value is *, meaning
51                       all printers.
[1156]52                       You can specify several names or wildcards,
53                       by separating them with commas.
[728]54 
55examples :                             
56
57  $ warnpykota --printer lp
58 
59  This will warn all users of the lp printer who have exceeded their
60  print quota.
61
62  $ warnpykota
63 
64  This will warn all users  who have exceeded their print quota on
65  any printer.
66
[1041]67  $ warnpykota --groups --printer "laserjet*" "dev*"
[728]68 
[1041]69  This will warn all users of groups which names begins with "dev" and
70  who have exceeded their print quota on any printer which name begins
71  with "laserjet"
72 
[1785]73  If launched by an user who is not a PyKota administrator, additionnal
74  arguments representing users or groups names are ignored, and only the
75  current user/group is reported.
[2344]76""")
[728]77       
78class WarnPyKota(PyKotaTool) :       
79    """A class for warnpykota."""
[1041]80    def main(self, ugnames, options) :
[728]81        """Warn users or groups over print quota."""
[1785]82        if self.config.isAdmin :
83            # PyKota administrator
[1041]84            if not ugnames :
85                # no username, means all usernames
86                ugnames = [ "*" ]
87        else :       
[1785]88            # not a PyKota administrator
[1041]89            # warns only the current user
90            # the utility of this is discutable, but at least it
91            # protects other users from mail bombing if they are
92            # over quota.
[1785]93            username = pwd.getpwuid(os.geteuid())[0]
[1041]94            if options["groups"] :
[1071]95                user = self.storage.getUser(username)
96                if user.Exists :
97                    ugnames = [ g.Name for g in self.storage.getUserGroups(user) ]
98                else :   
99                    ugnames = [ ]
[1041]100            else :
[1071]101                ugnames = [ username ]
[1041]102       
[900]103        printers = self.storage.getMatchingPrinters(options["printer"])
104        if not printers :
[2512]105            raise PyKotaCommandLineError, _("There's no printer matching %s") % options["printer"]
[1810]106        alreadydone = {}
[1041]107        for printer in printers :
[890]108            if options["groups"] :
[1041]109                for (group, grouppquota) in self.storage.getPrinterGroupsAndQuotas(printer, ugnames) :
110                    self.warnGroupPQuota(grouppquota)
[890]111            else :
[1041]112                for (user, userpquota) in self.storage.getPrinterUsersAndQuotas(printer, ugnames) :
[1806]113                    # we only want to warn users who have ever printed something
114                    # and don't want to warn users who have never printed
[2692]115                    if ((user.AccountBalance > self.config.getBalanceZero()) and \
116                       (user.AccountBalance != user.LifeTimePaid)) or \
[1806]117                       userpquota.PageCounter or userpquota.LifePageCounter or \
118                       self.storage.getUserNbJobsFromHistory(user) :
[1808]119                        done = alreadydone.get(user.Name)
[2547]120                        if (user.LimitBy == 'quota') or not done :
[1808]121                            action = self.warnUserPQuota(userpquota)
122                            if not done :
123                                alreadydone[user.Name] = (action in ('WARN', 'DENY'))
[728]124                     
125if __name__ == "__main__" : 
[1113]126    retcode = 0
[728]127    try :
128        defaults = { \
129                     "printer" : "*", \
130                   }
131        short_options = "vhugP:"
132        long_options = ["help", "version", "users", "groups", "printer="]
133       
134        # Initializes the command line tool
135        sender = WarnPyKota(doc=__doc__)
[2210]136        sender.deferredInit()
[728]137       
138        # parse and checks the command line
[729]139        (options, args) = sender.parseCommandline(sys.argv[1:], short_options, long_options, allownothing=1)
[728]140       
141        # sets long options
142        options["help"] = options["h"] or options["help"]
143        options["version"] = options["v"] or options["version"]
[895]144        options["users"] = options["u"] or options["users"]
145        options["groups"] = options["g"] or options["groups"]
[728]146        options["printer"] = options["P"] or options["printer"] or defaults["printer"]
147       
148        if options["help"] :
149            sender.display_usage_and_quit()
150        elif options["version"] :
151            sender.display_version_and_quit()
152        elif options["users"] and options["groups"] :   
[2512]153            raise PyKotaCommandLineError, _("incompatible options, see help.")
[728]154        else :
[1113]155            retcode = sender.main(args, options)
[2216]156    except KeyboardInterrupt :       
157        sys.stderr.write("\nInterrupted with Ctrl+C !\n")
[2609]158        retcode = -3
[2512]159    except PyKotaCommandLineError, msg :   
160        sys.stderr.write("%s : %s\n" % (sys.argv[0], msg))
[2609]161        retcode = -2
[1526]162    except SystemExit :       
163        pass
[1517]164    except :
165        try :
166            sender.crashed("warnpykota failed")
167        except :   
[1546]168            crashed("warnpykota failed")
[1113]169        retcode = -1
170       
171    try :
172        sender.storage.close()
173    except (TypeError, NameError, AttributeError) :   
174        pass
175       
176    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.