- Timestamp:
- 02/02/08 20:47:11 (17 years ago)
- Location:
- pykota/trunk
- Files:
-
- 2 modified
Legend:
- Unmodified
- Added
- Removed
-
pykota/trunk/bin/warnpykota
r3295 r3327 25 25 import os 26 26 import pwd 27 import socket 28 import smtplib 29 from email.MIMEText import MIMEText 30 from email.Header import Header 31 import email.Utils 27 32 28 33 import pykota.appinit 29 34 from pykota.utils import * 30 35 from pykota.commandline import PyKotaOptionParser 31 36 from pykota.errors import PyKotaCommandLineError 32 37 from pykota.tool import PyKotaTool 33 38 34 __doc__ = N_("""warnpykota v%(__version__)s (c) %(__years__)s %(__author__)s 35 36 Sends mail to users over print quota. 37 38 command line usage : 39 40 warnpykota [options] [names] 41 42 options : 43 44 -v | --version Prints warnpykota's version number then exits. 45 -h | --help Prints this message then exits. 46 47 -u | --users Warns users over their print quota, this is the 48 default. 49 50 -g | --groups Warns users whose groups quota are over limit. 51 52 -P | --printer p Verify quotas on this printer only. Actually p can 53 use wildcards characters to select only 54 some printers. The default value is *, meaning 55 all printers. 56 You can specify several names or wildcards, 57 by separating them with commas. 58 59 examples : 60 61 $ warnpykota --printer lp 62 63 This will warn all users of the lp printer who have exceeded their 64 print quota. 65 66 $ warnpykota 67 68 This will warn all users who have exceeded their print quota on 69 any printer. 70 71 $ warnpykota --groups --printer "laserjet*" "dev*" 72 73 This will warn all users of groups which names begins with "dev" and 74 who have exceeded their print quota on any printer which name begins 75 with "laserjet" 76 77 If launched by an user who is not a PyKota administrator, additionnal 78 arguments representing users or groups names are ignored, and only the 79 current user/group is reported. 80 """) 39 """This command line tool can automatically send periodic email 40 notifications to users or groups who have reached the limit of their 41 printing quota.""" 81 42 82 43 class WarnPyKota(PyKotaTool) : 83 44 """A class for warnpykota.""" 45 def sendMessage(self, adminmail, touser, fullmessage) : 46 """Sends an email message containing headers to some user.""" 47 smtpserver = self.smtpserver 48 try : 49 server = smtplib.SMTP(smtpserver) 50 except socket.error, msg : 51 self.printInfo(_("Impossible to connect to SMTP server : %(smtpserver)s") \ 52 % locals(), \ 53 "error") 54 else : 55 try : 56 server.sendmail(adminmail, [touser], fullmessage) 57 except smtplib.SMTPException, answer : 58 for (k, v) in answer.recipients.items() : 59 errormsg = v[0] 60 errorvalue = v[1] 61 self.printInfo(_("Impossible to send mail to %(touser)s, error %(errormsg)s : %(errorvalue)s") \ 62 % locals(), \ 63 "error") 64 server.quit() 65 66 def sendMessageToUser(self, admin, adminmail, user, subject, message) : 67 """Sends an email message to a user.""" 68 message += _("\n\nPlease contact your system administrator :\n\n\t%s - <%s>\n") % (admin, adminmail) 69 usermail = user.Email or user.Name 70 if "@" not in usermail : 71 usermail = "%s@%s" % (usermail, self.maildomain or self.smtpserver or "localhost") 72 msg = MIMEText(message.encode(self.charset, "replace"), _charset=self.charset) 73 msg["Subject"] = Header(subject, charset=self.charset) 74 msg["From"] = adminmail 75 msg["To"] = usermail 76 msg["Date"] = email.Utils.formatdate(localtime=True) 77 self.sendMessage(adminmail, usermail, msg.as_string()) 78 79 def sendMessageToAdmin(self, adminmail, subject, message) : 80 """Sends an email message to the Print Quota administrator.""" 81 if "@" not in adminmail : 82 adminmail = "%s@%s" % (adminmail, self.maildomain or self.smtpserver or "localhost") 83 msg = MIMEText(message.encode(self.charset, "replace"), _charset=self.charset) 84 msg["Subject"] = Header(subject, charset=self.charset) 85 msg["From"] = adminmail 86 msg["To"] = adminmail 87 self.sendMessage(adminmail, adminmail, msg.as_string()) 88 89 def warnGroupPQuota(self, grouppquota) : 90 """Checks a group quota and send messages if quota is exceeded on current printer.""" 91 group = grouppquota.Group 92 groupname = group.Name 93 printer = grouppquota.Printer 94 printername = printer.Name 95 admin = self.config.getAdmin(printername) 96 adminmail = self.config.getAdminMail(printername) 97 (mailto, arguments) = self.config.getMailTo(printername) 98 if group.LimitBy in ("noquota", "nochange") : 99 action = "ALLOW" 100 else : 101 action = self.checkGroupPQuota(grouppquota) 102 if action.startswith("POLICY_") : 103 action = action[7:] 104 if action == "DENY" : 105 adminmessage = _("Print Quota exceeded for group %(groupname)s on printer %(printername)s") % locals() 106 self.printInfo(adminmessage) 107 if mailto in [ "BOTH", "ADMIN" ] : 108 self.sendMessageToAdmin(adminmail, _("Print Quota"), adminmessage) 109 if mailto in [ "BOTH", "USER", "EXTERNAL" ] : 110 for user in self.storage.getGroupMembers(group) : 111 if mailto != "EXTERNAL" : 112 self.sendMessageToUser(admin, adminmail, user, _("Print Quota Exceeded"), self.config.getHardWarn(printername)) 113 else : 114 self.externalMailTo(arguments, action, user, printer, self.config.getHardWarn(printername)) 115 elif action == "WARN" : 116 adminmessage = _("Print Quota low for group %(groupname)s on printer %(printername)s") % locals() 117 self.printInfo(adminmessage) 118 if mailto in [ "BOTH", "ADMIN" ] : 119 self.sendMessageToAdmin(adminmail, _("Print Quota"), adminmessage) 120 if group.LimitBy and (group.LimitBy.lower() == "balance") : 121 message = self.config.getPoorWarn() 122 else : 123 message = self.config.getSoftWarn(printername) 124 if mailto in [ "BOTH", "USER", "EXTERNAL" ] : 125 for user in self.storage.getGroupMembers(group) : 126 if mailto != "EXTERNAL" : 127 self.sendMessageToUser(admin, adminmail, user, _("Print Quota Exceeded"), message) 128 else : 129 self.externalMailTo(arguments, action, user, printer, message) 130 return action 131 132 def warnUserPQuota(self, userpquota) : 133 """Checks a user quota and send him a message if quota is exceeded on current printer.""" 134 user = userpquota.User 135 username = user.Name 136 printer = userpquota.Printer 137 printername = printer.Name 138 admin = self.config.getAdmin(printername) 139 adminmail = self.config.getAdminMail(printername) 140 (mailto, arguments) = self.config.getMailTo(printername) 141 142 if user.LimitBy in ("noquota", "nochange") : 143 action = "ALLOW" 144 elif user.LimitBy == "noprint" : 145 action = "DENY" 146 message = _("User %(username)s is not allowed to print at this time.") % locals() 147 self.printInfo(message) 148 if mailto in [ "BOTH", "USER", "EXTERNAL" ] : 149 if mailto != "EXTERNAL" : 150 self.sendMessageToUser(admin, adminmail, user, _("Printing denied."), message) 151 else : 152 self.externalMailTo(arguments, action, user, printer, message) 153 if mailto in [ "BOTH", "ADMIN" ] : 154 self.sendMessageToAdmin(adminmail, _("Print Quota"), message) 155 else : 156 action = self.checkUserPQuota(userpquota) 157 if action.startswith("POLICY_") : 158 action = action[7:] 159 160 if action == "DENY" : 161 adminmessage = _("Print Quota exceeded for user %(username)s on printer %(printername)s") % locals() 162 self.printInfo(adminmessage) 163 if mailto in [ "BOTH", "USER", "EXTERNAL" ] : 164 message = self.config.getHardWarn(printername) 165 if mailto != "EXTERNAL" : 166 self.sendMessageToUser(admin, adminmail, user, _("Print Quota Exceeded"), message) 167 else : 168 self.externalMailTo(arguments, action, user, printer, message) 169 if mailto in [ "BOTH", "ADMIN" ] : 170 self.sendMessageToAdmin(adminmail, _("Print Quota"), adminmessage) 171 elif action == "WARN" : 172 adminmessage = _("Print Quota low for user %(username)s on printer %(printername)s") % locals() 173 self.printInfo(adminmessage) 174 if mailto in [ "BOTH", "USER", "EXTERNAL" ] : 175 if user.LimitBy and (user.LimitBy.lower() == "balance") : 176 message = self.config.getPoorWarn() 177 else : 178 message = self.config.getSoftWarn(printername) 179 if mailto != "EXTERNAL" : 180 self.sendMessageToUser(admin, adminmail, user, _("Print Quota Low"), message) 181 else : 182 self.externalMailTo(arguments, action, user, printer, message) 183 if mailto in [ "BOTH", "ADMIN" ] : 184 self.sendMessageToAdmin(adminmail, _("Print Quota"), adminmessage) 185 return action 186 84 187 def main(self, ugnames, options) : 85 188 """Warn users or groups over print quota.""" … … 95 198 # protects other users from mail bombing if they are 96 199 # over quota. 97 username = pwd.getpwuid(os.geteuid())[0] 98 if options ["groups"]:200 username = pwd.getpwuid(os.geteuid())[0].decode("ANSI_X3.4-1968", "replace") 201 if options.groups : 99 202 user = self.storage.getUser(username) 100 203 if user.Exists : … … 104 207 else : 105 208 ugnames = [ username ] 106 107 printers = self.storage.getMatchingPrinters(options["printer"]) 209 210 printername = options.printer 211 printers = self.storage.getMatchingPrinters(printername) 108 212 if not printers : 109 raise PyKotaCommandLineError, _("There's no printer matching %s") % options["printer"] 213 raise PyKotaCommandLineError, _("There's no printer matching %(printername)s") \ 214 % locals() 110 215 alreadydone = {} 111 216 for printer in printers : 112 if options ["groups"]:217 if options.groups : 113 218 for (group, grouppquota) in self.storage.getPrinterGroupsAndQuotas(printer, ugnames) : 114 219 self.warnGroupPQuota(grouppquota) … … 128 233 129 234 if __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 logerr("\nInterrupted with Ctrl+C !\n") 162 retcode = -3 163 except PyKotaCommandLineError, msg : 164 logerr("%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) 235 parser = PyKotaOptionParser(description=_("A tool to warn users and groups who have reached the limit of their printing quota."), 236 usage="warnpykota [options] [usernames|groupnames]") 237 parser.add_option("-g", "--groups", 238 action="store_true", 239 dest="groups", 240 help=_("Notify all members for all the named groups which have reached the limit of their printing quota. Without this option, individual users are notified instead of users groups.")) 241 parser.add_option("-P", "--printer", 242 dest="printer", 243 default="*", 244 help=_("Check if quota is over on this printer only. You can specify several printer names by separating them with commas. The default value is '%default', which means all printers.")) 245 246 parser.add_example('', 247 _("This would notify all users who have reached the limit of their printing quota on any printer.")) 248 parser.add_example('--printer HP2100', 249 _("This would notify all users who have reached the limit of their printing quota on printer 'HP2100'.")) 250 parser.add_example('--groups --printer "HP*,XER*" "dev*"', 251 _("This would notify all users of the groups whose name begins with 'dev' and for which the printing quota limit is reached on any printer whose name begins with 'HP' or 'XER'.")) 252 253 run(parser, WarnPyKota) -
pykota/trunk/pykota/tool.py
r3324 r3327 345 345 return 0 346 346 return 1 347 348 def sendMessage(self, adminmail, touser, fullmessage) :349 """Sends an email message containing headers to some user."""350 try :351 server = smtplib.SMTP(self.smtpserver)352 except socket.error, msg :353 self.printInfo(_("Impossible to connect to SMTP server : %s") % msg, "error")354 else :355 try :356 server.sendmail(adminmail, [touser], fullmessage)357 except smtplib.SMTPException, answer :358 for (k, v) in answer.recipients.items() :359 self.printInfo(_("Impossible to send mail to %s, error %s : %s") % (k, v[0], v[1]), "error")360 server.quit()361 362 def sendMessageToUser(self, admin, adminmail, user, subject, message) :363 """Sends an email message to a user."""364 message += _("\n\nPlease contact your system administrator :\n\n\t%s - <%s>\n") % (admin, adminmail)365 usermail = user.Email or user.Name366 if "@" not in usermail :367 usermail = "%s@%s" % (usermail, self.maildomain or self.smtpserver or "localhost")368 msg = MIMEText(message, _charset=self.charset)369 msg["Subject"] = Header(subject, charset=self.charset)370 msg["From"] = adminmail371 msg["To"] = usermail372 msg["Date"] = email.Utils.formatdate(localtime=True)373 self.sendMessage(adminmail, usermail, msg.as_string())374 375 def sendMessageToAdmin(self, adminmail, subject, message) :376 """Sends an email message to the Print Quota administrator."""377 if "@" not in adminmail :378 adminmail = "%s@%s" % (adminmail, self.maildomain or self.smtpserver or "localhost")379 msg = MIMEText(message, _charset=self.charset)380 msg["Subject"] = Header(subject, charset=self.charset)381 msg["From"] = adminmail382 msg["To"] = adminmail383 self.sendMessage(adminmail, adminmail, msg.as_string())384 347 385 348 def _checkUserPQuota(self, userpquota) : … … 584 547 return cmd % locals() 585 548 586 def warnGroupPQuota(self, grouppquota) :587 """Checks a group quota and send messages if quota is exceeded on current printer."""588 group = grouppquota.Group589 printer = grouppquota.Printer590 admin = self.config.getAdmin(printer.Name)591 adminmail = self.config.getAdminMail(printer.Name)592 (mailto, arguments) = self.config.getMailTo(printer.Name)593 if group.LimitBy in ("noquota", "nochange") :594 action = "ALLOW"595 else :596 action = self.checkGroupPQuota(grouppquota)597 if action.startswith("POLICY_") :598 action = action[7:]599 if action == "DENY" :600 adminmessage = _("Print Quota exceeded for group %s on printer %s") % (group.Name, printer.Name)601 self.printInfo(adminmessage)602 if mailto in [ "BOTH", "ADMIN" ] :603 self.sendMessageToAdmin(adminmail, _("Print Quota"), adminmessage)604 if mailto in [ "BOTH", "USER", "EXTERNAL" ] :605 for user in self.storage.getGroupMembers(group) :606 if mailto != "EXTERNAL" :607 self.sendMessageToUser(admin, adminmail, user, _("Print Quota Exceeded"), self.config.getHardWarn(printer.Name))608 else :609 self.externalMailTo(arguments, action, user, printer, self.config.getHardWarn(printer.Name))610 elif action == "WARN" :611 adminmessage = _("Print Quota low for group %s on printer %s") % (group.Name, printer.Name)612 self.printInfo(adminmessage)613 if mailto in [ "BOTH", "ADMIN" ] :614 self.sendMessageToAdmin(adminmail, _("Print Quota"), adminmessage)615 if group.LimitBy and (group.LimitBy.lower() == "balance") :616 message = self.config.getPoorWarn()617 else :618 message = self.config.getSoftWarn(printer.Name)619 if mailto in [ "BOTH", "USER", "EXTERNAL" ] :620 for user in self.storage.getGroupMembers(group) :621 if mailto != "EXTERNAL" :622 self.sendMessageToUser(admin, adminmail, user, _("Print Quota Exceeded"), message)623 else :624 self.externalMailTo(arguments, action, user, printer, message)625 return action626 627 def warnUserPQuota(self, userpquota) :628 """Checks a user quota and send him a message if quota is exceeded on current printer."""629 user = userpquota.User630 printer = userpquota.Printer631 admin = self.config.getAdmin(printer.Name)632 adminmail = self.config.getAdminMail(printer.Name)633 (mailto, arguments) = self.config.getMailTo(printer.Name)634 635 if user.LimitBy in ("noquota", "nochange") :636 action = "ALLOW"637 elif user.LimitBy == "noprint" :638 action = "DENY"639 message = _("User %s is not allowed to print at this time.") % user.Name640 self.printInfo(message)641 if mailto in [ "BOTH", "USER", "EXTERNAL" ] :642 if mailto != "EXTERNAL" :643 self.sendMessageToUser(admin, adminmail, user, _("Printing denied."), message)644 else :645 self.externalMailTo(arguments, action, user, printer, message)646 if mailto in [ "BOTH", "ADMIN" ] :647 self.sendMessageToAdmin(adminmail, _("Print Quota"), message)648 else :649 action = self.checkUserPQuota(userpquota)650 if action.startswith("POLICY_") :651 action = action[7:]652 653 if action == "DENY" :654 adminmessage = _("Print Quota exceeded for user %s on printer %s") % (user.Name, printer.Name)655 self.printInfo(adminmessage)656 if mailto in [ "BOTH", "USER", "EXTERNAL" ] :657 message = self.config.getHardWarn(printer.Name)658 if mailto != "EXTERNAL" :659 self.sendMessageToUser(admin, adminmail, user, _("Print Quota Exceeded"), message)660 else :661 self.externalMailTo(arguments, action, user, printer, message)662 if mailto in [ "BOTH", "ADMIN" ] :663 self.sendMessageToAdmin(adminmail, _("Print Quota"), adminmessage)664 elif action == "WARN" :665 adminmessage = _("Print Quota low for user %s on printer %s") % (user.Name, printer.Name)666 self.printInfo(adminmessage)667 if mailto in [ "BOTH", "USER", "EXTERNAL" ] :668 if user.LimitBy and (user.LimitBy.lower() == "balance") :669 message = self.config.getPoorWarn()670 else :671 message = self.config.getSoftWarn(printer.Name)672 if mailto != "EXTERNAL" :673 self.sendMessageToUser(admin, adminmail, user, _("Print Quota Low"), message)674 else :675 self.externalMailTo(arguments, action, user, printer, message)676 if mailto in [ "BOTH", "ADMIN" ] :677 self.sendMessageToAdmin(adminmail, _("Print Quota"), adminmessage)678 return action679