| 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 | |
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) |