#! /usr/bin/env python # -*- coding: ISO-8859-15 -*- # PyKota Print Quota Warning sender # # PyKota - Print Quotas for CUPS and LPRng # # (c) 2003, 2004, 2005 Jerome Alet # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. # # $Id$ # # $Log$ # Revision 1.37 2005/01/17 08:44:24 jalet # Modified copyright years # # Revision 1.36 2004/10/12 17:08:32 jalet # alreadydone mapping was reset in each iteration, this is fixed. # # Revision 1.35 2004/10/12 09:14:03 jalet # Ensures that warnpykota still test other quota entries for each user if # he has not been warned, even if limited by his account balance. # # Revision 1.34 2004/10/12 09:09:04 jalet # Now warnpykota warns users limited by balance only once per launch. # # Revision 1.33 2004/10/12 08:58:53 jalet # Now warnpykota only warns users who have already printed, to not confuse # users who have just opened their account. # # Revision 1.32 2004/10/11 22:53:05 jalet # Postponed string interpolation to help message's output method # # Revision 1.31 2004/10/11 12:49:06 jalet # Renders help translatable # # Revision 1.30 2004/10/06 10:05:47 jalet # Minor changes to allow any PyKota administrator to launch enhanced versions # of the commands, and not only the root user. # # Revision 1.29 2004/06/18 13:34:49 jalet # Now all tracebacks include PyKota's version number # # Revision 1.28 2004/06/07 18:43:41 jalet # Fixed over-verbose exits when displaying help or version number # # Revision 1.27 2004/06/03 21:50:34 jalet # Improved error logging. # crashrecipient directive added. # Now exports the job's size in bytes too. # # Revision 1.26 2004/01/08 14:10:32 jalet # Copyright year changed. # # Revision 1.25 2003/10/09 21:25:26 jalet # Multiple printer names or wildcards can be passed on the command line # separated with commas. # Beta phase. # # Revision 1.24 2003/10/07 09:07:28 jalet # Character encoding added to please latest version of Python # # Revision 1.23 2003/08/18 16:35:28 jalet # New pychecker pass, on the tools this time. # # Revision 1.22 2003/07/29 20:55:17 jalet # 1.14 is out ! # # Revision 1.21 2003/07/07 12:19:52 jalet # Now repykota and warnpykota --groups check the groups the user is a member of # in the print quota database, not in the system passwd/group files # # Revision 1.20 2003/06/25 14:10:01 jalet # Hey, it may work (edpykota --reset excepted) ! # # Revision 1.19 2003/04/29 22:03:38 jalet # Better error handling. # # Revision 1.18 2003/04/23 22:13:56 jalet # Preliminary support for LPRng added BUT STILL UNTESTED. # # Revision 1.17 2003/04/17 13:32:17 jalet # bad documentation string # # Revision 1.16 2003/04/16 12:35:49 jalet # Groups quota work now ! # # Revision 1.15 2003/04/10 21:47:20 jalet # Job history added. Upgrade script neutralized for now ! # # Revision 1.14 2003/04/08 21:31:39 jalet # (anything or 0) = anything !!! Go back to school Jerome ! # # Revision 1.13 2003/04/08 21:13:44 jalet # Prepare --groups option to work. # # Revision 1.12 2003/04/08 21:10:18 jalet # Checks --groups option presence instead of --users because --users is the default. # # Revision 1.11 2003/03/29 13:45:27 jalet # GPL paragraphs were incorrectly (from memory) copied into the sources. # Two README files were added. # Upgrade script for PostgreSQL pre 1.01 schema was added. # # Revision 1.10 2003/03/25 11:45:32 jalet # Clearer help. # # Revision 1.9 2003/03/09 23:39:14 jalet # Simplified translations. # # Revision 1.8 2003/02/10 12:07:30 jalet # Now repykota should output the recorded total page number for each printer too. # # Revision 1.7 2003/02/09 13:40:29 jalet # typo # # Revision 1.6 2003/02/09 12:56:53 jalet # Internationalization begins... # # Revision 1.5 2003/02/07 23:24:38 jalet # Empty line deleted # # Revision 1.4 2003/02/06 23:25:40 jalet # Cleaner docstring # # Revision 1.3 2003/02/06 23:20:02 jalet # warnpykota doesn't need any user/group name argument, mimicing the # warnquota disk quota tool. # # Revision 1.2 2003/02/06 22:54:33 jalet # warnpykota should be ok # # # import sys import os import pwd from pykota.tool import PyKotaTool, PyKotaToolError, crashed, N_ from pykota.config import PyKotaConfigError from pykota.storage import PyKotaStorageError __doc__ = N_("""warnpykota v%s (c) 2003, 2004, 2005 C@LL - Conseil Internet & Logiciels Libres Sends mail to users over print quota. command line usage : warnpykota [options] [names] options : -v | --version Prints warnpykota's version number then exits. -h | --help Prints this message then exits. -u | --users Warns users over their print quota, this is the default. -g | --groups Warns users whose groups quota are over limit. -P | --printer p Verify quotas on this printer only. Actually p can use wildcards characters to select only some printers. The default value is *, meaning all printers. You can specify several names or wildcards, by separating them with commas. examples : $ warnpykota --printer lp This will warn all users of the lp printer who have exceeded their print quota. $ warnpykota This will warn all users who have exceeded their print quota on any printer. $ warnpykota --groups --printer "laserjet*" "dev*" This will warn all users of groups which names begins with "dev" and who have exceeded their print quota on any printer which name begins with "laserjet" If launched by an user who is not a PyKota administrator, additionnal arguments representing users or groups names are ignored, and only the current user/group is reported. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Please e-mail bugs to: %s""") class WarnPyKota(PyKotaTool) : """A class for warnpykota.""" def main(self, ugnames, options) : """Warn users or groups over print quota.""" if self.config.isAdmin : # PyKota administrator if not ugnames : # no username, means all usernames ugnames = [ "*" ] else : # not a PyKota administrator # warns only the current user # the utility of this is discutable, but at least it # protects other users from mail bombing if they are # over quota. username = pwd.getpwuid(os.geteuid())[0] if options["groups"] : user = self.storage.getUser(username) if user.Exists : ugnames = [ g.Name for g in self.storage.getUserGroups(user) ] else : ugnames = [ ] else : ugnames = [ username ] printers = self.storage.getMatchingPrinters(options["printer"]) if not printers : raise PyKotaToolError, _("There's no printer matching %s") % options["printer"] alreadydone = {} for printer in printers : if options["groups"] : for (group, grouppquota) in self.storage.getPrinterGroupsAndQuotas(printer, ugnames) : self.warnGroupPQuota(grouppquota) else : for (user, userpquota) in self.storage.getPrinterUsersAndQuotas(printer, ugnames) : # we only want to warn users who have ever printed something # and don't want to warn users who have never printed if (user.AccountBalance and (user.AccountBalance != user.LifeTimePaid)) or \ userpquota.PageCounter or userpquota.LifePageCounter or \ self.storage.getUserNbJobsFromHistory(user) : done = alreadydone.get(user.Name) if (user.LimitBy.lower() != 'balance') or not done : action = self.warnUserPQuota(userpquota) if not done : alreadydone[user.Name] = (action in ('WARN', 'DENY')) if __name__ == "__main__" : retcode = 0 try : defaults = { \ "printer" : "*", \ } short_options = "vhugP:" long_options = ["help", "version", "users", "groups", "printer="] # Initializes the command line tool sender = WarnPyKota(doc=__doc__) # parse and checks the command line (options, args) = sender.parseCommandline(sys.argv[1:], short_options, long_options, allownothing=1) # sets long options options["help"] = options["h"] or options["help"] options["version"] = options["v"] or options["version"] options["users"] = options["u"] or options["users"] options["groups"] = options["g"] or options["groups"] options["printer"] = options["P"] or options["printer"] or defaults["printer"] if options["help"] : sender.display_usage_and_quit() elif options["version"] : sender.display_version_and_quit() elif options["users"] and options["groups"] : raise PyKotaToolError, _("incompatible options, see help.") else : retcode = sender.main(args, options) except SystemExit : pass except : try : sender.crashed("warnpykota failed") except : crashed("warnpykota failed") retcode = -1 try : sender.storage.close() except (TypeError, NameError, AttributeError) : pass sys.exit(retcode)