Changeset 3327

Show
Ignore:
Timestamp:
02/02/08 20:47:11 (16 years ago)
Author:
jerome
Message:

warnpykota converted to new style.

Location:
pykota/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/bin/warnpykota

    r3295 r3327  
    2525import os 
    2626import pwd 
     27import socket 
     28import smtplib 
     29from email.MIMEText import MIMEText 
     30from email.Header import Header 
     31import email.Utils 
    2732 
    2833import pykota.appinit 
    2934from pykota.utils import * 
    30  
     35from pykota.commandline import PyKotaOptionParser 
    3136from pykota.errors import PyKotaCommandLineError 
    3237from pykota.tool import PyKotaTool 
    3338 
    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 
     40notifications to users or groups who have reached the limit of their 
     41printing quota.""" 
    8142         
    8243class WarnPyKota(PyKotaTool) :         
    8344    """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         
    84187    def main(self, ugnames, options) : 
    85188        """Warn users or groups over print quota.""" 
     
    95198            # protects other users from mail bombing if they are 
    96199            # 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 : 
    99202                user = self.storage.getUser(username) 
    100203                if user.Exists : 
     
    104207            else : 
    105208                ugnames = [ username ] 
    106          
    107         printers = self.storage.getMatchingPrinters(options["printer"]) 
     209                 
     210        printername = options.printer 
     211        printers = self.storage.getMatchingPrinters(printername) 
    108212        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() 
    110215        alreadydone = {} 
    111216        for printer in printers : 
    112             if options["groups"] : 
     217            if options.groups : 
    113218                for (group, grouppquota) in self.storage.getPrinterGroupsAndQuotas(printer, ugnames) : 
    114219                    self.warnGroupPQuota(grouppquota) 
     
    128233                      
    129234if __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  
    345345                return 0 
    346346        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.Name 
    366         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"] = adminmail 
    371         msg["To"] = usermail 
    372         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"] = adminmail 
    382         msg["To"] = adminmail 
    383         self.sendMessage(adminmail, adminmail, msg.as_string()) 
    384347         
    385348    def _checkUserPQuota(self, userpquota) :             
     
    584547        return cmd % locals() 
    585548         
    586     def warnGroupPQuota(self, grouppquota) : 
    587         """Checks a group quota and send messages if quota is exceeded on current printer.""" 
    588         group = grouppquota.Group 
    589         printer = grouppquota.Printer 
    590         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 action         
    626          
    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.User 
    630         printer = userpquota.Printer 
    631         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.Name 
    640             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 action         
    679