Changeset 1000

Show
Ignore:
Timestamp:
05/28/03 01:00:21 (21 years ago)
Author:
jalet
Message:

Big rewrite of external accounting methods.
Should work well now.

Location:
pykota/trunk
Files:
7 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/bin/pykota

    r976 r1000  
    2323# 
    2424# $Log$ 
     25# Revision 1.32  2003/05/27 23:00:20  jalet 
     26# Big rewrite of external accounting methods. 
     27# Should work well now. 
     28# 
    2529# Revision 1.31  2003/04/30 13:36:39  jalet 
    2630# Stupid accounting method was added. 
     
    150154    def __init__(self) : 
    151155        PyKotaTool.__init__(self) 
    152         (self.printingsystem, self.printerhostname, self.printername, self.username, self.jobid, self.inputfile) = self.extractInfoFromCupsOrLprng() 
     156        (self.printingsystem, self.printerhostname, self.printername, self.username, self.jobid, self.inputfile, self.copies) = self.extractInfoFromCupsOrLprng() 
    153157        self.accounter = openAccounter(self) 
    154158     
     
    174178                destination = destination[1:] 
    175179            printerhostname = destination.split("/")[0].split(":")[0] 
    176             return ("CUPS", printerhostname, os.environ.get("PRINTER"), sys.argv[2].strip(), sys.argv[1].strip(), inputfile) 
     180            return ("CUPS", printerhostname, os.environ.get("PRINTER"), sys.argv[2].strip(), sys.argv[1].strip(), inputfile, int(sys.argv[4].strip())) 
    177181        else :     
    178182            # Try to detect LPRng 
    179             jseen = Jseen = Pseen = nseen = rseen = None 
     183            jseen = Jseen = Pseen = nseen = rseen = Kseen = None 
    180184            for arg in sys.argv : 
    181185                if arg.startswith("-j") : 
     
    191195                elif arg.startswith("-r") :     
    192196                    rseen = arg[2:].strip() 
     197                elif arg.startswith("-K") or arg.startswith("-#") :     
     198                    Kseen = int(arg[2:].strip()) 
     199            if Kseen is None :         
     200                Kseen = 1       # we assume the user wants at least one copy... 
    193201            if jseen and Pseen and nseen and rseen :         
    194                 return ("LPRNG", rseen, Pseen, nseen, jseen, Jseen) 
    195         return (None, None, None, None, None, None)   # Unknown printing system           
     202                return ("LPRNG", rseen, Pseen, nseen, jseen, Jseen, Kseen) 
     203        return (None, None, None, None, None, None, None)   # Unknown printing system           
    196204         
    197205    def acceptJob(self) :         
  • pykota/trunk/conf/pykota.conf.sample

    r999 r1000  
    6868# 
    6969#                   accounter: external(/bin/grep -c showpage) 
     70# 
     71#                 Another one, which should work with all DSC 
     72#                 compliant Postscript files : 
     73# 
     74#                   accounter: external(/bin/grep -c "%%Page:") 
    7075#  
    7176#    - stupid : counts the occurences of the 'showpage' postscript 
     
    8388# untested/postscript directory to another place. 
    8489# accounter: external(/usr/local/bin/pagecount.sh) 
    85 # WARNING : it may produce broken pipes, I don't know why yet. YMMV. 
     90# WARNING : it may not work when multiple copies are asked. 
     91#           this breaks ghostscript, I don't know why yet. 
    8692# 
    8793# default value  
  • pykota/trunk/NEWS

    r998 r1000  
    2222PyKota NEWS : 
    2323 
     24    - 1.08alpha3 : 
     25     
     26        - External accounting methods were partly rewritten : 
     27          
     28          - No more "broken pipe" should happen. 
     29           
     30          - They now take care of the number of copies 
     31            This may be unneeded though, if the postscript 
     32            file already does this, because this would 
     33            overcharge users (number of copies counted 
     34            two times). NEEDS MORE TESTING. 
     35             
     36          - The sample configuration file now contains   
     37            an external accounting method example which should 
     38            work with all DSC compliant Postscript files. 
     39             
     40        - Some small bugs were fixed.     
     41         
    2442    - 1.08alpha2 : 
    2543     
    2644        - Now works with net-snmp v5.0 and above. 
    2745          It already worked, but the sample configuration  
    28           file didn't contain appropriate values... 
     46          file didn't contain appropriate values... 
    2947         
    3048    - 1.07 : Release of the Shame ! 
  • pykota/trunk/pykota/accounters/external.py

    r995 r1000  
    2121# 
    2222# $Log$ 
     23# Revision 1.3  2003/05/27 23:00:21  jalet 
     24# Big rewrite of external accounting methods. 
     25# Should work well now. 
     26# 
    2327# Revision 1.2  2003/05/13 13:54:20  jalet 
    2428# Better handling of broken pipes 
     
    4246           The command must print the job size on its standard output and exit successfully. 
    4347        """ 
    44         # get the job size     
    45         jobsize = self.getJobSize() 
     48        # get the job size, which is real job size * number of copies. 
     49        jobsize = self.getJobSize() * self.filter.copies 
    4650             
    4751        # get last job information for this printer 
     
    8185             
    8286        # launches external accounter 
     87        infilename = tempfile.mktemp() 
     88        outfilename = tempfile.mktemp() 
     89        errfilename = tempfile.mktemp() 
     90         
    8391        try : 
    84             process = popen2.Popen3("%s" % self.arguments) 
    85          
    8692            # feed it with our data 
     93            fakeinput = open(infilename, "wb") 
    8794            data = infile.read(256*1024)     
    8895            while data : 
    89                 process.tochild.write(data) 
    90                 temporary.write(data) 
     96                fakeinput.write(data) 
     97                if temporary is not None : 
     98                    temporary.write(data) 
    9199                data = infile.read(256*1024) 
    92             process.tochild.close() 
     100            fakeinput.close() 
    93101         
    94             # wait for child process to exit (or die) 
    95             retcode = process.wait() 
     102            # launches child process 
     103            command = "%s <%s >%s 2>%s" % (self.arguments, infilename, outfilename, errfilename) 
     104            o = open("/tmp/comm", "w") 
     105            o.write("%s\n" % command) 
     106            o.close() 
     107            retcode = os.system(command) 
    96108             
    97109            # check exit status 
    98             if os.WIFEXITED(retcode) and not os.WEXITSTATUS(retcode) : 
     110            if (os.WIFEXITED(retcode) and not os.WEXITSTATUS(retcode)) or os.stat(errfilename) : 
    99111                # tries to extract the job size from the external accounter's 
    100112                # standard output 
     113                childoutput = open(outfilename, "r") 
    101114                try : 
    102                     pagecount = int(process.fromchild.readline().strip()) 
     115                    pagecount = int(childoutput.readline().strip()) 
    103116                except (AttributeError, ValueError) : 
    104117                    self.filter.logger.log_message(_("Unable to compute job size with external accounter %s") % self.arguments) 
    105118                    pagecount = 0 
     119                childoutput.close()     
    106120            else : 
    107121                self.filter.logger.log_message(_("Unable to compute job size with external accounter %s") % self.arguments) 
    108122                pagecount = 0 
    109             process.fromchild.close()     
     123            os.remove(infilename) 
     124            os.remove(outfilename) 
     125            os.remove(errfilename) 
    110126        except IOError, msg :     
     127            # TODO : temporary files may remain on the filesystem... 
    111128            msg = "%s : %s" % (self.arguments, msg)  
    112129            self.filter.logger.log_message(_("Unable to compute job size with external accounter %s") % msg) 
  • pykota/trunk/pykota/accounters/stupid.py

    r977 r1000  
    2121# 
    2222# $Log$ 
     23# Revision 1.3  2003/05/27 23:00:21  jalet 
     24# Big rewrite of external accounting methods. 
     25# Should work well now. 
     26# 
    2327# Revision 1.2  2003/04/30 13:40:47  jalet 
    2428# Small fix 
     
    4448         
    4549        # get the job size     
    46         jobsize = self.getJobSize() 
     50        jobsize = self.getJobSize() * self.filter.copies 
    4751             
    4852        # get last job information for this printer 
     
    8690        pagecount = 0 
    8791        for line in infile.xreadlines() : 
    88             if line.startswith("showpage") : 
    89                 pagecount += 1 
     92            pagecount += line.count("showpage") 
    9093            if temporary is not None :     
    9194                temporary.write(line)     
  • pykota/trunk/pykota/config.py

    r980 r1000  
    2121# 
    2222# $Log$ 
     23# Revision 1.27  2003/05/27 23:00:21  jalet 
     24# Big rewrite of external accounting methods. 
     25# Should work well now. 
     26# 
    2327# Revision 1.26  2003/04/30 19:53:58  jalet 
    2428# 1.05 
     
    205209        validaccounters = [ "querying", "stupid", "external" ]      
    206210        try : 
    207             fullaccounter = self.getPrinterOption(printer, "accounter").strip().lower() 
     211            fullaccounter = self.getPrinterOption(printer, "accounter").strip() 
    208212        except PyKotaConfigError :     
    209213            fullaccounter = "querying" 
    210         if fullaccounter.startswith("external") :     
     214        if fullaccounter.lower().startswith("external") :     
    211215            try : 
    212216                (accounter, args) = [x.strip() for x in fullaccounter.split('(', 1)] 
     
    217221            if not args : 
    218222                raise PyKotaConfigError, _("Invalid external accounter %s for printer %s") % (fullaccounter, printer) 
    219             return (accounter, args)     
    220         elif fullaccounter not in validaccounters : 
     223            return (accounter.lower(), args)     
     224        elif fullaccounter.lower() not in validaccounters : 
    221225            raise PyKotaConfigError, _("Option accounter in section %s only supports values in %s") % (printer, str(validaccounters)) 
    222226        else :     
    223             return (fullaccounter, None) 
     227            return (fullaccounter.lower(), None) 
    224228         
    225229    def getRequesterBackend(self, printer) :     
     
    242246                raise PyKotaConfigError, _("Invalid requester %s for printer %s") % (fullrequester, printer) 
    243247            validrequesters = [ "snmp", "external" ] # TODO : add more requesters 
     248            requester = requester.lower() 
    244249            if requester not in validrequesters : 
    245250                raise PyKotaConfigError, _("Option requester for printer %s only supports values in %s") % (printer, str(validrequesters)) 
  • pykota/trunk/pykota/version.py

    r998 r1000  
    2121# 
    2222 
    23 __version__ = "1.08alpha2_unofficial" 
     23__version__ = "1.08alpha3_unofficial" 
    2424 
    2525__doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""