root / pykota / trunk / pykota / config.py @ 3288

Revision 3288, 35.0 kB (checked in by jerome, 16 years ago)

Moved all exceptions definitions to a dedicated module.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1# -*- coding: UTF-8 -*-
2#
3# PyKota : Print Quotas for CUPS
4#
5# (c) 2003, 2004, 2005, 2006, 2007, 2008 Jerome Alet <alet@librelogiciel.com>
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18#
19# $Id$
20#
21#
22
23"""This module defines classes used to parse PyKota configuration files."""
24
25import os
26import tempfile
27import ConfigParser
28
29from pykota.errors import PyKotaConfigError   
30
31class PyKotaConfig :
32    """A class to deal with PyKota's configuration."""
33    def __init__(self, directory) :
34        """Reads and checks the configuration file."""
35        self.isAdmin = 0
36        self.directory = directory
37        self.filename = os.path.join(directory, "pykota.conf")
38        self.adminfilename = os.path.join(directory, "pykotadmin.conf")
39        if not os.access(self.filename, os.R_OK) :
40            raise PyKotaConfigError, _("Configuration file %s can't be read. Please check that the file exists and that your permissions are sufficient.") % self.filename
41        if not os.path.isfile(self.adminfilename) :
42            raise PyKotaConfigError, _("Configuration file %s not found.") % self.adminfilename
43        if os.access(self.adminfilename, os.R_OK) :   
44            self.isAdmin = 1
45        self.config = ConfigParser.ConfigParser()
46        self.config.read([self.filename])
47           
48    def isTrue(self, option) :       
49        """Returns True if option is set to true, else False."""
50        if (option is not None) and (option.strip().upper() in ['Y', 'YES', '1', 'ON', 'T', 'TRUE']) :
51            return True
52        else :   
53            return False
54                       
55    def isFalse(self, option) :       
56        """Returns True if option is set to false, else False."""
57        if (option is not None) and (option.strip().upper() in ['N', 'NO', '0', 'OFF', 'F', 'FALSE']) :
58            return True
59        else :   
60            return False
61                       
62    def getPrinterNames(self) :   
63        """Returns the list of configured printers, i.e. all sections names minus 'global'."""
64        return [pname for pname in self.config.sections() if pname != "global"]
65       
66    def getGlobalOption(self, option, ignore=0) :   
67        """Returns an option from the global section, or raises a PyKotaConfigError if ignore is not set, else returns None."""
68        try :
69            return self.config.get("global", option, raw=1)
70        except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) :   
71            if ignore :
72                return None
73            else :
74                raise PyKotaConfigError, _("Option %s not found in section global of %s") % (option, self.filename)
75               
76    def getPrinterOption(self, printername, option) :   
77        """Returns an option from the printer section, or the global section, or raises a PyKotaConfigError."""
78        globaloption = self.getGlobalOption(option, ignore=1)
79        try :
80            return self.config.get(printername, option, raw=1)
81        except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) :   
82            if globaloption is not None :
83                return globaloption
84            else :
85                raise PyKotaConfigError, _("Option %s not found in section %s of %s") % (option, printername, self.filename)
86       
87    def getStorageBackend(self) :   
88        """Returns the storage backend information as a Python mapping."""       
89        backendinfo = {}
90        backend = self.getGlobalOption("storagebackend").lower()
91        backendinfo["storagebackend"] = backend
92        if backend == "sqlitestorage" :
93            issqlite = 1
94            backendinfo["storagename"] = self.getGlobalOption("storagename")
95            for option in ["storageserver", "storageuser", "storageuserpw"] :
96                backendinfo[option] = None         
97        else :
98            issqlite = 0
99            for option in ["storageserver", "storagename", "storageuser"] :
100                backendinfo[option] = self.getGlobalOption(option)
101            backendinfo["storageuserpw"] = self.getGlobalOption("storageuserpw", ignore=1)  # password is optional
102           
103        backendinfo["storageadmin"] = None
104        backendinfo["storageadminpw"] = None
105        if self.isAdmin :
106            adminconf = ConfigParser.ConfigParser()
107            adminconf.read([self.adminfilename])
108            if adminconf.sections() : # were we able to read the file ?
109                try :
110                    backendinfo["storageadmin"] = adminconf.get("global", "storageadmin", raw=1)
111                except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) :   
112                    if not issqlite :
113                        raise PyKotaConfigError, _("Option %s not found in section global of %s") % ("storageadmin", self.adminfilename)
114                try :
115                    backendinfo["storageadminpw"] = adminconf.get("global", "storageadminpw", raw=1)
116                except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) :   
117                    pass # Password is optional
118                # Now try to overwrite the storagebackend, storageserver
119                # and storagename. This allows admins to use the master LDAP
120                # server directly and users to use the replicas transparently.
121                try :
122                    backendinfo["storagebackend"] = adminconf.get("global", "storagebackend", raw=1)
123                except ConfigParser.NoOptionError :
124                    pass
125                try :
126                    backendinfo["storageserver"] = adminconf.get("global", "storageserver", raw=1)
127                except ConfigParser.NoOptionError :
128                    pass
129                try :
130                    backendinfo["storagename"] = adminconf.get("global", "storagename", raw=1)
131                except ConfigParser.NoOptionError :
132                    pass
133        return backendinfo
134       
135    def getLDAPInfo(self) :   
136        """Returns some hints for the LDAP backend."""       
137        ldapinfo = {}
138        for option in [ "userbase", "userrdn", \
139                        "balancebase", "balancerdn", \
140                        "groupbase", "grouprdn", "groupmembers", \
141                        "printerbase", "printerrdn", \
142                        "userquotabase", "groupquotabase", \
143                        "jobbase", "lastjobbase", "billingcodebase", \
144                        "newuser", "newgroup", \
145                        "usermail", \
146                      ] :
147            ldapinfo[option] = self.getGlobalOption(option).strip()
148        for field in ["newuser", "newgroup"] :
149            if ldapinfo[field].lower().startswith('attach(') :
150                ldapinfo[field] = ldapinfo[field][7:-1]
151               
152        # should we use TLS, by default (if unset) value is NO       
153        ldapinfo["ldaptls"] = self.isTrue(self.getGlobalOption("ldaptls", ignore=1))
154        ldapinfo["cacert"] = self.getGlobalOption("cacert", ignore=1)
155        if ldapinfo["cacert"] :
156            ldapinfo["cacert"] = ldapinfo["cacert"].strip()
157        if ldapinfo["ldaptls"] :   
158            if not os.access(ldapinfo["cacert"] or "", os.R_OK) :
159                raise PyKotaConfigError, _("Option ldaptls is set, but certificate %s is not readable.") % str(ldapinfo["cacert"])
160        return ldapinfo
161       
162    def getLoggingBackend(self) :   
163        """Returns the logging backend information."""
164        validloggers = [ "stderr", "system" ] 
165        try :
166            logger = self.getGlobalOption("logger").lower()
167        except PyKotaConfigError :   
168            logger = "system"
169        if logger not in validloggers :             
170            raise PyKotaConfigError, _("Option logger only supports values in %s") % str(validloggers)
171        return logger   
172       
173    def getLogoURL(self) :
174        """Returns the URL to use for the logo in the CGI scripts."""
175        url = self.getGlobalOption("logourl", ignore=1) or \
176                   "http://www.pykota.com/pykota.png"
177        return url.strip()           
178       
179    def getLogoLink(self) :
180        """Returns the URL to go to when the user clicks on the logo in the CGI scripts."""
181        url = self.getGlobalOption("logolink", ignore=1) or \
182                   "http://www.pykota.com/"
183        return url.strip()           
184   
185    def getPreAccounterBackend(self, printername) :   
186        """Returns the preaccounter backend to use for a given printer."""
187        validaccounters = [ "software", "ink" ]     
188        try :
189            fullaccounter = self.getPrinterOption(printername, "preaccounter").strip()
190        except PyKotaConfigError :   
191            return ("software", "")
192        else :   
193            flower = fullaccounter.lower()
194            for vac in validaccounters :
195                if flower.startswith(vac) :   
196                    try :
197                        (accounter, args) = [x.strip() for x in fullaccounter.split('(', 1)]
198                    except ValueError :   
199                        raise PyKotaConfigError, _("Invalid preaccounter %s for printer %s") % (fullaccounter, printername)
200                    if args.endswith(')') :
201                        args = args[:-1].strip()
202                    if (vac == "ink") and not args :   
203                        raise PyKotaConfigError, _("Invalid preaccounter %s for printer %s") % (fullaccounter, printername)
204                    return (vac, args)
205            raise PyKotaConfigError, _("Option preaccounter in section %s only supports values in %s") % (printername, str(validaccounters))
206       
207    def getAccounterBackend(self, printername) :   
208        """Returns the accounter backend to use for a given printer."""
209        validaccounters = [ "hardware", "software", "ink" ]     
210        try :
211            fullaccounter = self.getPrinterOption(printername, "accounter").strip()
212        except PyKotaConfigError :   
213            return ("software", "")
214        else :   
215            flower = fullaccounter.lower()
216            for vac in validaccounters :
217                if flower.startswith(vac) :   
218                    try :
219                        (accounter, args) = [x.strip() for x in fullaccounter.split('(', 1)]
220                    except ValueError :   
221                        raise PyKotaConfigError, _("Invalid accounter %s for printer %s") % (fullaccounter, printername)
222                    if args.endswith(')') :
223                        args = args[:-1].strip()
224                    if (vac in ("hardware", "ink")) and not args :
225                        raise PyKotaConfigError, _("Invalid accounter %s for printer %s") % (fullaccounter, printername)
226                    return (vac, args)
227            raise PyKotaConfigError, _("Option accounter in section %s only supports values in %s") % (printername, str(validaccounters))
228       
229    def getPreHook(self, printername) :   
230        """Returns the prehook command line to launch, or None if unset."""
231        try :
232            return self.getPrinterOption(printername, "prehook").strip()
233        except PyKotaConfigError :   
234            return      # No command to launch in the pre-hook
235           
236    def getPostHook(self, printername) :   
237        """Returns the posthook command line to launch, or None if unset."""
238        try :
239            return self.getPrinterOption(printername, "posthook").strip()
240        except PyKotaConfigError :   
241            return      # No command to launch in the post-hook
242           
243    def getStripTitle(self, printername) :   
244        """Returns the striptitle directive's content, or None if unset."""
245        try :
246            return self.getPrinterOption(printername, "striptitle").strip()
247        except PyKotaConfigError :   
248            return      # No prefix to strip off
249           
250    def getAskConfirmation(self, printername) :       
251        """Returns the askconfirmation directive's content, or None if unset."""
252        try :
253            return self.getPrinterOption(printername, "askconfirmation").strip()
254        except PyKotaConfigError :   
255            return      # No overwriting will be done
256           
257    def getOverwriteJobTicket(self, printername) :       
258        """Returns the overwrite_jobticket directive's content, or None if unset."""
259        try :
260            return self.getPrinterOption(printername, "overwrite_jobticket").strip()
261        except PyKotaConfigError :   
262            return      # No overwriting will be done
263       
264    def getUnknownBillingCode(self, printername) :       
265        """Returns the unknown_billingcode directive's content, or the default value if unset."""
266        validvalues = [ "CREATE", "DENY" ]
267        try :
268            fullvalue = self.getPrinterOption(printername, "unknown_billingcode")
269        except PyKotaConfigError :   
270            return ("CREATE", None)
271        else :   
272            try :
273                value = [x.strip() for x in fullvalue.split('(', 1)]
274            except ValueError :   
275                raise PyKotaConfigError, _("Invalid unknown_billingcode directive %s for printer %s") % (fullvalue, printername)
276            if len(value) == 1 :   
277                value.append("")
278            (value, args) = value   
279            if args.endswith(')') :
280                args = args[:-1]
281            value = value.upper()   
282            if (value == "DENY") and not args :
283                return ("DENY", None)
284            if value not in validvalues :
285                raise PyKotaConfigError, _("Directive unknown_billingcode in section %s only supports values in %s") % (printername, str(validvalues))
286            return (value, args)
287       
288    def getPrinterEnforcement(self, printername) :   
289        """Returns if quota enforcement should be strict or laxist for the current printer."""
290        validenforcements = [ "STRICT", "LAXIST" ]     
291        try :
292            enforcement = self.getPrinterOption(printername, "enforcement")
293        except PyKotaConfigError :   
294            return "LAXIST"
295        else :   
296            enforcement = enforcement.upper()
297            if enforcement not in validenforcements :
298                raise PyKotaConfigError, _("Option enforcement in section %s only supports values in %s") % (printername, str(validenforcements))
299            return enforcement   
300           
301    def getPrinterOnBackendError(self, printername) :   
302        """Returns what must be done whenever the real CUPS backend fails."""
303        validactions = [ "CHARGE", "NOCHARGE" ]     
304        try :
305            action = self.getPrinterOption(printername, "onbackenderror")
306        except PyKotaConfigError :   
307            return ["NOCHARGE"]
308        else :   
309            action = action.upper().split(",")
310            error = False
311            for act in action :
312                if act not in validactions :
313                    if act.startswith("RETRY:") :
314                        try :
315                            (num, delay) = [int(p) for p in act[6:].split(":", 2)]
316                        except ValueError :   
317                            error = True
318                    else :       
319                        error = True
320            if error :
321                raise PyKotaConfigError, _("Option onbackenderror in section %s only supports values 'charge', 'nocharge', and 'retry:num:delay'") % printername
322            return action 
323           
324    def getPrinterOnAccounterError(self, printername) :   
325        """Returns what must be done whenever the accounter fails."""
326        validactions = [ "CONTINUE", "STOP" ]     
327        try :
328            action = self.getPrinterOption(printername, "onaccountererror")
329        except PyKotaConfigError :   
330            return "STOP"
331        else :   
332            action = action.upper()
333            if action not in validactions :
334                raise PyKotaConfigError, _("Option onaccountererror in section %s only supports values in %s") % (printername, str(validactions))
335            return action 
336           
337    def getPrinterPolicy(self, printername) :   
338        """Returns the default policy for the current printer."""
339        validpolicies = [ "ALLOW", "DENY", "EXTERNAL" ]     
340        try :
341            fullpolicy = self.getPrinterOption(printername, "policy")
342        except PyKotaConfigError :   
343            return ("DENY", None)
344        else :   
345            try :
346                policy = [x.strip() for x in fullpolicy.split('(', 1)]
347            except ValueError :   
348                raise PyKotaConfigError, _("Invalid policy %s for printer %s") % (fullpolicy, printername)
349            if len(policy) == 1 :   
350                policy.append("")
351            (policy, args) = policy   
352            if args.endswith(')') :
353                args = args[:-1]
354            policy = policy.upper()   
355            if (policy == "EXTERNAL") and not args :
356                raise PyKotaConfigError, _("Invalid policy %s for printer %s") % (fullpolicy, printername)
357            if policy not in validpolicies :
358                raise PyKotaConfigError, _("Option policy in section %s only supports values in %s") % (printername, str(validpolicies))
359            return (policy, args)
360       
361    def getCrashRecipient(self) :   
362        """Returns the email address of the software crash messages recipient."""
363        try :
364            return self.getGlobalOption("crashrecipient")
365        except :   
366            return
367           
368    def getSMTPServer(self) :   
369        """Returns the SMTP server to use to send messages to users."""
370        try :
371            return self.getGlobalOption("smtpserver")
372        except PyKotaConfigError :   
373            return "localhost"
374       
375    def getMailDomain(self) :   
376        """Returns the mail domain to use to send messages to users."""
377        try :
378            return self.getGlobalOption("maildomain")
379        except PyKotaConfigError :   
380            return 
381       
382    def getAdminMail(self, printername) :   
383        """Returns the Email address of the Print Quota Administrator."""
384        try :
385            return self.getPrinterOption(printername, "adminmail")
386        except PyKotaConfigError :   
387            return "root@localhost"
388       
389    def getAdmin(self, printername) :   
390        """Returns the full name of the Print Quota Administrator."""
391        try :
392            return self.getPrinterOption(printername, "admin")
393        except PyKotaConfigError :   
394            return "root"
395       
396    def getMailTo(self, printername) :   
397        """Returns the recipient of email messages."""
398        validmailtos = [ "EXTERNAL", "NOBODY", "NONE", "NOONE", "BITBUCKET", "DEVNULL", "BOTH", "USER", "ADMIN" ]
399        try :
400            fullmailto = self.getPrinterOption(printername, "mailto")
401        except PyKotaConfigError :   
402            return ("BOTH", None)
403        else :   
404            try :
405                mailto = [x.strip() for x in fullmailto.split('(', 1)]
406            except ValueError :   
407                raise PyKotaConfigError, _("Invalid option mailto %s for printer %s") % (fullmailto, printername)
408            if len(mailto) == 1 :   
409                mailto.append("")
410            (mailto, args) = mailto   
411            if args.endswith(')') :
412                args = args[:-1]
413            mailto = mailto.upper()   
414            if (mailto == "EXTERNAL") and not args :
415                raise PyKotaConfigError, _("Invalid option mailto %s for printer %s") % (fullmailto, printername)
416            if mailto not in validmailtos :
417                raise PyKotaConfigError, _("Option mailto in section %s only supports values in %s") % (printername, str(validmailtos))
418            return (mailto, args)
419       
420    def getMaxDenyBanners(self, printername) :   
421        """Returns the maximum number of deny banners to be printed for a particular user on a particular printer."""
422        try :
423            maxdb = self.getPrinterOption(printername, "maxdenybanners")
424        except PyKotaConfigError :   
425            return 0 # default value is to forbid printing a deny banner.
426        try :
427            value = int(maxdb.strip())
428            if value < 0 :
429                raise ValueError
430        except (TypeError, ValueError) :   
431            raise PyKotaConfigError, _("Invalid maximal deny banners counter %s") % maxdb
432        else :   
433            return value
434
435    def getPrintCancelledBanners(self, printername) :
436        """Returns True if a banner should be printed when a job is cancelled, else False."""
437        try :
438            return self.isTrue(self.getPrinterOption(printername, "printcancelledbanners"))
439        except PyKotaConfigError :
440            return True
441             
442    def getGraceDelay(self, printername) :   
443        """Returns the grace delay in days."""
444        try :
445            gd = self.getPrinterOption(printername, "gracedelay")
446        except PyKotaConfigError :   
447            gd = 7      # default value of 7 days
448        try :
449            return int(gd)
450        except (TypeError, ValueError) :   
451            raise PyKotaConfigError, _("Invalid grace delay %s") % gd
452           
453    def getPoorMan(self) :   
454        """Returns the poor man's threshold."""
455        try :
456            pm = self.getGlobalOption("poorman")
457        except PyKotaConfigError :   
458            pm = 1.0    # default value of 1 unit
459        try :
460            return float(pm)
461        except (TypeError, ValueError) :   
462            raise PyKotaConfigError, _("Invalid poor man's threshold %s") % pm
463           
464    def getBalanceZero(self) :   
465        """Returns the value of the zero for balance limitation."""
466        try :
467            bz = self.getGlobalOption("balancezero")
468        except PyKotaConfigError :   
469            bz = 0.0    # default value, zero is 0.0
470        try :
471            return float(bz)
472        except (TypeError, ValueError) :   
473            raise PyKotaConfigError, _("Invalid balancezero value %s") % bz
474           
475    def getPoorWarn(self) :   
476        """Returns the poor man's warning message."""
477        try :
478            return self.getGlobalOption("poorwarn")
479        except PyKotaConfigError :   
480            return _("Your Print Quota account balance is Low.\nSoon you'll not be allowed to print anymore.\nPlease contact the Print Quota Administrator to solve the problem.")
481           
482    def getHardWarn(self, printername) :   
483        """Returns the hard limit error message."""
484        try :
485            return self.getPrinterOption(printername, "hardwarn")
486        except PyKotaConfigError :   
487            return _("You are not allowed to print anymore because\nyour Print Quota is exceeded on printer %s.") % printername
488           
489    def getSoftWarn(self, printername) :   
490        """Returns the soft limit error message."""
491        try :
492            return self.getPrinterOption(printername, "softwarn")
493        except PyKotaConfigError :   
494            return _("You will soon be forbidden to print anymore because\nyour Print Quota is almost reached on printer %s.") % printername
495           
496    def getPrivacy(self) :       
497        """Returns True if privacy is activated, else False."""
498        return self.isTrue(self.getGlobalOption("privacy", ignore=1))
499       
500    def getDebug(self) :         
501        """Returns True if debugging is activated, else False."""
502        return self.isTrue(self.getGlobalOption("debug", ignore=1))
503           
504    def getCaching(self) :         
505        """Returns True if database caching is enabled, else False."""
506        return self.isTrue(self.getGlobalOption("storagecaching", ignore=1))
507           
508    def getLDAPCache(self) :         
509        """Returns True if low-level LDAP caching is enabled, else False."""
510        return self.isTrue(self.getGlobalOption("ldapcache", ignore=1))
511           
512    def getDisableHistory(self) :         
513        """Returns True if we want to disable history, else False."""
514        return self.isTrue(self.getGlobalOption("disablehistory", ignore=1))
515           
516    def getUserNameToLower(self) :         
517        """Deprecated."""
518        return self.getGlobalOption("utolower", ignore=1)
519       
520    def getUserNameCase(self) :
521        """Returns value for user name case: upper, lower or native"""
522        validvalues = [ "upper", "lower", "native" ]
523        try :
524            value = self.getGlobalOption("usernamecase", ignore=1).strip().lower()
525        except AttributeError :   
526            value = "native"
527        if value not in validvalues :
528            raise PyKotaConfigError, _("Option usernamecase only supports values in %s") % str(validvalues)
529        return value
530       
531    def getRejectUnknown(self) :         
532        """Returns True if we want to reject the creation of unknown users or groups, else False."""
533        return self.isTrue(self.getGlobalOption("reject_unknown", ignore=1))
534       
535    def getPrinterKeepFiles(self, printername) :         
536        """Returns True if files must be kept on disk, else False."""
537        try : 
538            return self.isTrue(self.getPrinterOption(printername, "keepfiles"))
539        except PyKotaConfigError :   
540            return False
541           
542    def getPrinterDirectory(self, printername) :         
543        """Returns the path to our working directory, else a directory suitable for temporary files."""
544        try : 
545            return self.getPrinterOption(printername, "directory").strip()
546        except PyKotaConfigError :   
547            return tempfile.gettempdir()
548           
549    def getDenyDuplicates(self, printername) :         
550        """Returns True or a command if we want to deny duplicate jobs, else False."""
551        try : 
552            denyduplicates = self.getPrinterOption(printername, "denyduplicates")
553        except PyKotaConfigError :   
554            return False
555        else :   
556            if self.isTrue(denyduplicates) :
557                return True
558            elif self.isFalse(denyduplicates) :
559                return False
560            else :   
561                # it's a command to run.
562                return denyduplicates
563               
564    def getDuplicatesDelay(self, printername) :         
565        """Returns the number of seconds after which two identical jobs are not considered a duplicate anymore."""
566        try : 
567            duplicatesdelay = self.getPrinterOption(printername, "duplicatesdelay")
568        except PyKotaConfigError :   
569            return 0
570        else :   
571            try :
572                return int(duplicatesdelay)
573            except (TypeError, ValueError) :
574                raise PyKotaConfigError, _("Incorrect value %s for the duplicatesdelay directive in section %s") % (str(duplicatesdelay), printername)
575       
576    def getNoPrintingMaxDelay(self, printername) :         
577        """Returns the max number of seconds to wait for the printer to be in 'printing' mode."""
578        try : 
579            maxdelay = self.getPrinterOption(printername, "noprintingmaxdelay")
580        except PyKotaConfigError :   
581            return None         # tells to use hardcoded value
582        else :   
583            try :
584                maxdelay = int(maxdelay)
585                if maxdelay < 0 :
586                    raise ValueError
587            except (TypeError, ValueError) :
588                raise PyKotaConfigError, _("Incorrect value %s for the noprintingmaxdelay directive in section %s") % (str(maxdelay), printername)
589            else :   
590                return maxdelay
591       
592    def getStatusStabilizationLoops(self, printername) :   
593        """Returns the number of times the printer must return the 'idle' status to consider it stable."""
594        try : 
595            stab = self.getPrinterOption(printername, "statusstabilizationloops")
596        except PyKotaConfigError :   
597            return None         # tells to use hardcoded value
598        else :   
599            try :
600                stab = int(stab)
601                if stab < 1 :
602                    raise ValueError
603            except (TypeError, ValueError) :
604                raise PyKotaConfigError, _("Incorrect value %s for the statusstabilizationloops directive in section %s") % (str(stab), printername)
605            else :   
606                return stab
607       
608    def getStatusStabilizationDelay(self, printername) :   
609        """Returns the number of seconds to wait between two checks of the printer's status."""
610        try : 
611            stab = self.getPrinterOption(printername, "statusstabilizationdelay")
612        except PyKotaConfigError :   
613            return None         # tells to use hardcoded value
614        else :   
615            try :
616                stab = float(stab)
617                if stab < 0.25 :
618                    raise ValueError
619            except (TypeError, ValueError) :
620                raise PyKotaConfigError, _("Incorrect value %s for the statusstabilizationdelay directive in section %s") % (str(stab), printername)
621            else :   
622                return stab
623       
624    def getPrinterSNMPErrorMask(self, printername) :   
625        """Returns the SNMP error mask for a particular printer, or None if not defined."""
626        try : 
627            errmask = self.getPrinterOption(printername, "snmperrormask").lower()
628        except PyKotaConfigError :   
629            return None         # tells to use hardcoded value
630        else :   
631            try :
632                if errmask.startswith("0x") :
633                    value = int(errmask, 16)
634                elif errmask.startswith("0") :   
635                    value = int(errmask, 8)
636                else :   
637                    value = int(errmask)
638                if 0 <= value < 65536 :
639                    return value
640                else :   
641                    raise ValueError
642            except ValueError :   
643                raise PyKotaConfigError, _("Incorrect value %s for the snmperrormask directive in section %s") % (errmask, printername)
644       
645    def getWinbindSeparator(self) :         
646        """Returns the winbind separator's value if it is set, else None."""
647        return self.getGlobalOption("winbind_separator", ignore=1)
648
649    def getAccountBanner(self, printername) :
650        """Returns which banner(s) to account for: NONE, BOTH, STARTING, ENDING."""
651        validvalues = [ "NONE", "BOTH", "STARTING", "ENDING" ]     
652        try :
653            value = self.getPrinterOption(printername, "accountbanner")
654        except PyKotaConfigError :   
655            return "BOTH"       # Default value of BOTH
656        else :   
657            value = value.strip().upper()
658            if value not in validvalues :
659                raise PyKotaConfigError, _("Option accountbanner in section %s only supports values in %s") % (printername, str(validvalues))
660            return value 
661
662    def getAvoidDuplicateBanners(self, printername) :
663        """Returns normalized value for avoiding extra banners. """
664        try :
665            avoidduplicatebanners = self.getPrinterOption(printername, "avoidduplicatebanners").upper()
666        except PyKotaConfigError :
667            return "NO"
668        else :
669            try :
670                value = int(avoidduplicatebanners)
671                if value < 0 :
672                    raise ValueError
673            except ValueError :
674                if avoidduplicatebanners not in ["YES", "NO"] :
675                    raise PyKotaConfigError, _("Option avoidduplicatebanners only accepts 'yes', 'no', or a positive integer.")
676                else :
677                    value = avoidduplicatebanners
678            return value
679
680    def getStartingBanner(self, printername) :
681        """Returns the startingbanner value if set, else None."""
682        try :
683            return self.getPrinterOption(printername, "startingbanner").strip()
684        except PyKotaConfigError :
685            return None
686
687    def getEndingBanner(self, printername) :
688        """Returns the endingbanner value if set, else None."""
689        try :
690            return self.getPrinterOption(printername, "endingbanner").strip()
691        except PyKotaConfigError :
692            return None
693           
694    def getTrustJobSize(self, printername) :
695        """Returns the normalized value of the trustjobsize's directive."""
696        try :
697            value = self.getPrinterOption(printername, "trustjobsize").strip().upper()
698        except PyKotaConfigError :
699            return (None, "YES")
700        else :   
701            if value == "YES" :
702                return (None, "YES")
703            try :   
704                (limit, replacement) = [p.strip() for p in value.split(">")[1].split(":")]
705                limit = int(limit)
706                try :
707                    replacement = int(replacement) 
708                except ValueError :   
709                    if replacement != "PRECOMPUTED" :
710                        raise
711                if limit < 0 :
712                    raise ValueError
713                if (replacement != "PRECOMPUTED") and (replacement < 0) :
714                    raise ValueError
715            except (IndexError, ValueError, TypeError) :
716                raise PyKotaConfigError, _("Option trustjobsize for printer %s is incorrect") % printername
717            return (limit, replacement)   
718           
719    def getPrinterCoefficients(self, printername) :
720        """Returns a mapping of coefficients for a particular printer."""
721        branchbasename = "coefficient_"
722        try :
723            globalbranches = [ (k, self.config.get("global", k)) for k in self.config.options("global") if k.startswith(branchbasename) ]
724        except ConfigParser.NoSectionError, msg :
725            raise PyKotaConfigError, "Invalid configuration file : %s" % msg
726        try :
727            sectionbranches = [ (k, self.config.get(printername, k)) for k in self.config.options(printername) if k.startswith(branchbasename) ]
728        except ConfigParser.NoSectionError, msg :
729            sectionbranches = []
730        branches = {}
731        for (k, v) in globalbranches :
732            k = k.split('_', 1)[1]
733            value = v.strip()
734            if value :
735                try :
736                    branches[k] = float(value)
737                except ValueError :   
738                    raise PyKotaConfigError, "Invalid coefficient %s (%s) for printer %s" % (k, value, printername)
739               
740        for (k, v) in sectionbranches :
741            k = k.split('_', 1)[1]
742            value = v.strip()
743            if value :
744                try :
745                    branches[k] = float(value) # overwrite any global option or set a new value
746                except ValueError :   
747                    raise PyKotaConfigError, "Invalid coefficient %s (%s) for printer %s" % (k, value, printername)
748            else :
749                del branches[k] # empty value disables a global option
750        return branches
751       
752    def getPrinterSkipInitialWait(self, printername) :
753        """Returns True if we want to skip the initial waiting loop, else False."""
754        try :
755            return self.isTrue(self.getPrinterOption(printername, "skipinitialwait"))
756        except PyKotaConfigError :
757            return False
Note: See TracBrowser for help on using the browser.