root / pykota / trunk / bin / warnpykota @ 2614

Revision 2609, 6.7 kB (checked in by jerome, 19 years ago)

Insufficient permission to run a command now exits with status -2.
Error in command line options now exits with status -2.
Processing interrupted with Ctrl+C (or SIGTERM) now exits with status -3.

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