Changeset 1475

Show
Ignore:
Timestamp:
05/13/04 15:59:30 (20 years ago)
Author:
jalet
Message:

Code simplifications

Location:
pykota/trunk
Files:
2 added
4 removed
12 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/bin/pkhint

    r1423 r1475  
    2424# 
    2525# $Log$ 
     26# Revision 1.7  2004/05/13 13:59:27  jalet 
     27# Code simplifications 
     28# 
    2629# Revision 1.6  2004/03/30 12:59:47  jalet 
    2730# Fixed path problem 
     
    211214                    snmpcommand = self.accepts(SNMPTESTS, hostname) 
    212215                    if snmpcommand is not None : 
    213                         accounter = "querying" 
     216                        accounter = "hardware" 
    214217                        requester = 'external(/usr/share/pykota/waitprinter.sh %(printer)s && ' + snmpcommand + ')' 
    215218                        configuration.append((printer, accounter, requester)) 
     
    217220                        netpjlcommand = self.accepts(NETPJLTESTS, hostname, port) 
    218221                        if netpjlcommand is not None : 
    219                             accounter = "querying" 
     222                            accounter = "hardware" 
    220223                            requester = 'external(' + netpjlcommand + ')' 
    221224                            configuration.append((printer, accounter, requester)) 
  • pykota/trunk/conf/pykota.conf.sample

    r1442 r1475  
    182182# supported values : 
    183183# 
    184 #    - querying : asks the printer for its lifetime page counter 
     184#    - hardware : asks the printer for its lifetime page counter 
    185185#                 via either SNMP, AppleTalk, or any external 
    186186#                 command. This method is the method used by 
    187187#                 default in PyKota since its beginning. 
    188188# 
    189 #    - external : delegates the job's size computation to any  
    190 #                 external command of your choice. A stupid and  
    191 #                 completely unreliable example, but which 
    192 #                 shows what this command may be is : 
    193 # 
    194 #                   accounter: external(/bin/grep -c showpage) 
    195 # 
    196 #                 Another one, which should work with all DSC 
    197 #                 compliant Postscript files : 
    198 # 
    199 #                   accounter: external(/bin/grep -c "%%Page:") 
    200 # 
    201 #                 Finally the new smart external accounter which 
    202 #                 can handle both PostScript and PCL documents : 
    203 # 
    204 #                   accounter: external(/usr/bin/pkpgcounter) 
    205 #  
    206 #    - stupid : counts the occurences of the 'showpage' postscript 
    207 #               statement in the document to be printed. 
    208 #               THIS IS NOT RELIABLE. This is just to serve as 
    209 #               an example on how to implement your own accounting 
    210 #               method. Use pkpgcounter instead. 
    211 # 
     189#    - software : delegates the job's size computation to any  
     190#                 external command of your choice.  
     191# 
     192#                 best choice for this is probably to set it 
     193#                 this way : 
     194# 
     195#                   accounter: software(/usr/bin/pkpgcounter) 
     196# 
     197#                 pkpgcounter is a command line tool which is 
     198#                 part of PyKota and which can handle both 
     199#                 DSC compliant PostScript documents and PCL5 
     200#                 documents. More file formats will be added 
     201#                 in the future, as time permits. 
     202# 
     203#                 while pkpgcounter is the recommended value 
     204#                 you can use whatever command you want provided 
     205#                 that your command accepts the job's data on its 
     206#                 standard input and prints the job's size in pages 
     207#                 as a single integer on its standard output. 
     208#  
    212209# This value can be set either globally or on a per printer basis 
    213210# If both are defined, the printer option has priority. 
    214 # if not set it defaults to 'querying'. 
    215 # 
    216 # A script which seems to be accurate, copy it from the 
    217 # untested/postscript directory to another place. 
    218 # accounter: external(/usr/share/pykota/pagecount.sh) 
    219 # WARNING : it may not work when multiple copies are asked. 
    220 #           this breaks ghostscript, I don't know why yet. 
     211# if not set it defaults to 'hardware'. 
    221212# 
    222213# default value  
    223 accounter: querying 
     214accounter: hardware 
     215# accounter: software(/usr/bin/pkpgcounter) 
    224216 
    225217# Print Quota administrator 
     
    326318 
    327319# How to query the hpmarketing printer for its page counter. 
    328 # THIS IS ONLY USED IF YOU HAVE SET 'accounter' TO 'querying' 
     320# THIS IS ONLY USED IF YOU HAVE SET 'accounter' TO 'hardware' 
    329321# JUST COMMENT IT OUT IF YOU USE ANY OTHER ACCOUNTING METHOD. 
    330322# (it would be ignored anyway) 
     
    332324# In the lines below "%(printer)s" is automatically replaced 
    333325# at run time with your printer's Fully Qualified Domain Name 
     326# for network printers. 
    334327# e.g. myprinter.example.com 
    335328# 
    336 # Only snmp(community, oid) and external(command) are supported 
     329# Only value supported is : external(... your command here...)  
    337330# 
    338331# Example :  
     332# 
    339333#     requester: external(/usr/bin/snmpget -v1 -c public -Ov %(printer)s mib-2.43.10.2.1.4.1.1 | cut -f 2,2 -d " ") 
    340 # and : 
    341 #     requester: snmp(public, mib-2.43.10.2.1.4.1.1) 
    342 # are equivalent 
    343 # 
    344 ################################################# 
    345 # NB : the 'snmp()' requester is now deprecated # 
    346 # because it has some accuracy problems.        # 
    347 # please use 'external()' instead.              # 
    348 ################################################# 
    349334# 
    350335# Another untested example, using npadmin : 
     336# 
    351337#     requester: external(/usr/bin/npadmin --pagecount %(printer)s) 
    352338# 
     
    355341# pagecount.ps file from untested/netatalk into /etc or any  
    356342# appropriate location) 
     343# 
    357344#     requester: external(/usr/share/pykota/papwaitprinter.sh "MyPrinter:LaserWriter@*" && /usr/bin/pap -p "MyPrinter:LaserWriter@*" /usr/share/pykota/pagecount.ps  2>/dev/null | /bin/grep -v status | /bin/grep -v Connect | /usr/bin/tail -1) 
    358345# 
     
    361348#     requester: external(/bin/cat /usr/share/pykota/pagecount.pjl >/dev/lp0 && /usr/bin/head -2 </dev/lp0 | /usr/bin/tail -1) 
    362349#  
    363 #  
    364350# This value can be set either globally or per printer or both. 
    365351# If both are defined, the printer option has priority. 
    366 # 
    367 # NB : The SNMP oid mib-2.43.10.2.1.4.1.1 works on HP Laserjet Printers, but it may 
    368 #      be different with other brands, refer to your printer's documentation  
    369 #      for details. Also you may have to specify -v2c or -v3 depending on your  
    370 #      printer's support for different versions of the SNMP specification. 
    371 # 
    372352# 
    373353# Some examples and comments provided by Bob Martel from csuohio.edu 
     
    382362# 
    383363# requester: external(/opt/local/net-snmp/bin/snmpwalk -v 1 -Cc -c public -Ov %(printer)s | grep Counter32 | tail -2 | head -1 | cut -d " " -f2) 
    384 # 
    385364# 
    386365# An example using netcat and a preformatted PJL job which you can find 
     
    390369# requester: external(/bin/nc -w 2 %(printer)s 9100 </usr/share/pykota/pagecount.pjl | /usr/bin/tail -2) 
    391370# 
    392 # 
    393371# An example using the contributed pagecount.pl script which does  
    394372# the same as above, but should work on more printers :  
    395373# 
    396374# requester: external(/usr/share/pykota/pagecount.pl %(printer)s 9100) 
    397 # 
    398375# 
    399376# WARNING : In any case, when using an external requester, please test the command line outside 
     
    404381# not yet finished (not all pages are printed, but the complete job is in  
    405382# the printer) 
     383# 
     384# YOU ABSOLUTELY HAVE TO BE SURE YOU HAVE A SCRIPT WHICH WAITS FOR THE 
     385# PRINTER BEING READY BEFORE ASKING FOR ITS INTERNAL PAGE COUNTER. 
     386# 
     387# PYKOTA INCLUDES SUCH SCRIPTS FOR SNMP AND APPLETALK PRINTERS, MORE TO COME 
     388# 
     389# default value 
    406390requester: external(/usr/share/pykota/waitprinter.sh %(printer)s && /usr/bin/snmpget -v1 -c public -Ov %(printer)s mib-2.43.10.2.1.4.1.1 | cut -f 2,2 -d " ") 
    407391 
  • pykota/trunk/docs/filterpykota.sgml

    r1386 r1475  
    7272   
    7373  <para> 
    74     When using the <literal>querying</literal> accounting method, 
     74    When using the <literal>hardware</literal> accounting method, 
    7575    <application>pykota</application> asks the printer for its internal page counter, reads from the Quota DataBase the internal 
    7676    page counter for this printer when the previous job was launched, computes the difference, and report it as the  
     
    8686   
    8787  <para> 
    88     When using the <literal>external</literal> accounting method, 
     88    When using the <literal>software</literal> accounting method, 
    8989    and if the user is still allowed to print, 
    9090    the command you specified is launched with the job's data on its  
     
    9292    pages on a single line on its standard output. This number is then 
    9393    read by PyKota and used to update the current user's quota information. 
    94     Of course checks are also done like with the <literal>querying</literal> 
     94    Of course checks are also done like with the <literal>hardware</literal> 
    9595    accounting method, to see if the current job is allowed to be printed or not. 
    9696  </para> 
     
    108108 
    109109$Log$ 
     110Revision 1.10  2004/05/13 13:59:28  jalet 
     111Code simplifications 
     112 
    110113Revision 1.9  2004/03/03 19:35:36  jalet 
    111114Spelling problem. Thanks to Jurandy Martins 
  • pykota/trunk/NEWS

    r1473 r1475  
    2222PyKota NEWS : 
    2323 
     24    - 1.19alpha8 : 
     25     
     26        - 'querying' accounting method is now called 'hardware' 
     27         
     28        - 'external' accounting method is now called 'software' 
     29         
     30        - 'stupid' accounting method doesn't exist anymore 
     31         
     32        - 'snmp' requester doesn't exist anymore 
     33         
     34        - code simplifications in external requester 
     35         
    2436    - 1.19alpha7 : 
    2537      
  • pykota/trunk/pykota/accounters/Makefile.am

    r1417 r1475  
    22 
    33pykota_accounters_PYTHON =      \ 
    4         external.py                             \ 
     4        software.py                             \ 
    55        __init__.py                             \ 
    6         querying.py                             \ 
    7         stupid.py                                
     6        hardware.py 
    87 
  • pykota/trunk/pykota/config.py

    r1371 r1475  
    2222# 
    2323# $Log$ 
     24# Revision 1.46  2004/05/13 13:59:28  jalet 
     25# Code simplifications 
     26# 
    2427# Revision 1.45  2004/03/01 10:22:30  jalet 
    2528# Can now extract per printer pre and post hooks from the configuration file 
     
    303306        """Returns the accounter backend to use for a given printer. 
    304307         
    305            if it is not set, it defaults to 'querying' which means ask printer 
     308           if it is not set, it defaults to 'hardware' which means ask printer 
    306309           for its internal lifetime page counter. 
    307310        """    
    308         validaccounters = [ "querying", "stupid", "external" ]      
     311        validaccounters = [ "hardware", "software" ]      
    309312        fullaccounter = self.getPrinterOption(printername, "accounter").strip() 
    310         if fullaccounter.lower().startswith("external") :     
     313        if fullaccounter.lower().startswith("software") :     
    311314            try : 
    312315                (accounter, args) = [x.strip() for x in fullaccounter.split('(', 1)] 
     
    343346        except PyKotaConfigError :     
    344347            # No requester defined, maybe it is not needed if accounting method 
    345             # is not set to 'querying', but if we are called, then the accounting 
    346             # method really IS 'querying', and so there's a big problem. 
     348            # is not set to 'hardware', but if we are called, then the accounting 
     349            # method really IS 'hardware', and so there's a big problem. 
    347350            raise PyKotaConfigError, _("Option requester for printer %s was not set") % printername 
    348351        else :     
     
    355358            if not args : 
    356359                raise PyKotaConfigError, _("Invalid requester %s for printer %s") % (fullrequester, printername) 
    357             validrequesters = [ "snmp", "external" ] # TODO : add more requesters 
     360            validrequesters = [ "external" ]  
    358361            requester = requester.lower() 
    359362            if requester not in validrequesters : 
  • pykota/trunk/pykota/requesters/external.py

    r1433 r1475  
    2222# 
    2323# $Log$ 
     24# Revision 1.12  2004/05/13 13:59:30  jalet 
     25# Code simplifications 
     26# 
    2427# Revision 1.11  2004/04/09 22:24:47  jalet 
    2528# Began work on correct handling of child processes when jobs are cancelled by 
     
    6366# 
    6467 
     68import sys 
    6569import os 
     70import popen2 
     71import signal 
    6672from pykota.requester import PyKotaRequesterError 
    6773 
     
    8288        if printer is None : 
    8389            raise PyKotaRequesterError, _("Unknown printer address in EXTERNAL(%s) for printer %s") % (commandline, self.printername) 
    84         answer = os.popen(commandline) 
     90        error = 1 
     91        pagecounter = None 
     92        child = popen2.Popen4(commandline)     
    8593        try : 
    86             pagecounter = int(answer.readline().strip()) 
     94            pagecounter = int(child.fromchild.readline().strip()) 
    8795        except ValueError :     
     96            pass 
     97        except IOError :     
     98            # we were interrupted by a signal, certainely a SIGTERM 
     99            # caused by the user cancelling the current job 
     100            try : 
     101                os.kill(child.pid, signal.SIGTERM) 
     102            except :     
     103                pass # already killed ? 
     104            self.kotabackend.logger.log_message(_("SIGTERM was sent to external requester %s (pid: %s)") % (commandline, child.pid), "info") 
     105        else :     
     106            error = 0 
     107        child.fromchild.close()     
     108        child.tochild.close() 
     109        status = child.wait() 
     110        if (not error) and os.WIFEXITED(status) and (not os.WEXITSTATUS(status)) : 
     111            return pagecounter 
     112        else :     
    88113            raise PyKotaRequesterError, _("Unable to query printer %s via EXTERNAL(%s)") % (printer, commandline)  
    89         answer.close() 
    90         return pagecounter 
    91114         
  • pykota/trunk/pykota/requesters/Makefile.am

    r1417 r1475  
    33pykota_requesters_PYTHON =      \ 
    44        external.py                             \ 
    5         __init__.py                             \ 
    6         snmp.py 
     5        __init__.py 
    76 
  • pykota/trunk/pykota/tool.py

    r1469 r1475  
    2222# 
    2323# $Log$ 
     24# Revision 1.86  2004/05/13 13:59:28  jalet 
     25# Code simplifications 
     26# 
    2427# Revision 1.85  2004/05/11 08:26:27  jalet 
    2528# Now catches connection problems to SMTP server 
     
    809812             
    810813    def prehook(self, userpquota) : 
    811         """Allows pluging of an external hook before the job gets printed.""" 
     814        """Allows plugging of an external hook before the job gets printed.""" 
    812815        prehook = self.config.getPreHook(userpquota.Printer.Name) 
    813816        if prehook : 
     
    816819         
    817820    def posthook(self, userpquota) : 
    818         """Allows pluging of an external hook after the job gets printed and/or denied.""" 
     821        """Allows plugging of an external hook after the job gets printed and/or denied.""" 
    819822        posthook = self.config.getPostHook(userpquota.Printer.Name) 
    820823        if posthook : 
  • pykota/trunk/pykota/version.py

    r1473 r1475  
    2222# 
    2323 
    24 __version__ = "1.19alpha7_unofficial" 
     24__version__ = "1.19alpha8_unofficial" 
    2525 
    2626__doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng.""" 
  • pykota/trunk/README

    r1408 r1475  
    4343         
    4444        - Supports OpenLDAP as the Quota Storage backend. 
    45           Complete LDAP schema and sample tree are included. 
     45          Complete LDAP schema and sample empty tree are included. 
    4646          Plugging PyKota into your existing LDAP infrastructure 
    4747          is really easy thanks to PyKota's great configurability. 
     
    4949    Printers :         
    5050     
     51        - Hardware or Software accounting methods are completely 
     52          configurable. 
     53           
    5154        - Supports any printer which can report its internal 
    52           page counter. 
     55          page counter. Can ask printers for their internal  
     56          page counter via SNMP, Netatalk, or any other way. 
     57          This is completely configurable. 
     58           
     59        - Supports PostScript and PCL5 printers natively, 
     60          more formats to come. 
    5361           
    5462        - Supports any other printer via GhostScript. 
    5563          Depending on the printer some configuration may 
    5664          be needed. 
    57          
    58         - Can ask printers for their internal page counter 
    59           via SNMP, Netatalk, or any other mean of your 
    60           choice. This is completely configurable. 
    61            
    62         - External accounting methods are configurable. 
    6365             
    6466    Quota systems :         
     
    156158implemented : 
    157159 
    158   - The 'querying' method consists in querying the printer (via SNMP 
     160  - The 'hardware' method consists in querying the printer (via SNMP 
    159161    or Netatalk or any other method of your choice) for its total pages  
    160162    counter. 
     
    168170    of one print job, but this is generally ok. 
    169171     
    170   - The 'external' method consists in delegating the computation of the 
     172  - The 'software' method consists in delegating the computation of the 
    171173    job's size in number of pages to any external command of your choice. 
    172174    The command can read the job's data from its standard input and MUST 
     
    174176    account are reported immediately, both with CUPS and LPRng. 
    175177     
    176   - The 'stupid' method consists in counting the 'showpage' PostSript   
    177     statements in the job. THIS IS UNRELIABLE, SO DON'T USE IT, but  
    178     can serve as an example if you plan to write your own accounting  
    179     method for integration into PyKota. It basically works like the  
    180     'external' method, but does the computation internally and in 
    181     a non-reliable way. 
    182    
    183178PyKota is known to work fine with HP Laserjet 2100 and 2200, and  
    184179Apple LaserWriter 16/600 PS, both with CUPS and LPRng, under  
  • pykota/trunk/setup.py

    r1430 r1475  
    2424# 
    2525# $Log$ 
     26# Revision 1.40  2004/05/13 13:59:27  jalet 
     27# Code simplifications 
     28# 
    2629# Revision 1.39  2004/04/08 17:07:41  jalet 
    2730# pkpgcounter added 
     
    173176    sys.exit(-1) 
    174177 
     178from distutils import sysconfig 
    175179sys.path.insert(0, "pykota") 
    176180from pykota.version import __version__, __doc__ 
     
    179183ACTION_ABORT = 1 
    180184 
     185def checkOldModule(path) : 
     186    """Checks if an old PyKota module is still in the destination (in case of upgrade).""" 
     187    fname = os.path.join(sysconfig.get_python_lib(), "pykota", path) 
     188    for ext in ["py", "pyc", "pyo"] : 
     189        fullname = "%s.%s" % (fname, ext) 
     190        if os.path.isfile(fullname) : 
     191            sys.stderr.write("ERROR : old module %s still exists. Remove it and restart installation.\n" % fullname) 
     192            sys.stderr.write("INSTALLATION ABORTED !\n") 
     193            sys.exit(-1) 
     194     
    181195def checkOldScript(cmd) : 
    182196    """Checks if an old shell script is still around in /usr/bin.""" 
     
    282296                sys.stderr.write("\nINSTALLATION ABORTED !\nPlease correct the problem and restart installation.\n") 
    283297                sys.exit(-1) 
     298                 
     299        # now checks if pre-1.19alpha8 code is still there        
     300        for module in ["accounters/querying", "accounters/external", "requesters/snmp"] : 
     301            checkOldModule(module) 
    284302         
    285303    # Second stage, we will fail if onfiguration is incorrect for security reasons 
     
    348366     
    349367    # WARNING MESSAGE     
    350     sys.stdout.write("WARNING : IF YOU ARE UPGRADING FROM A PRE-1.14 TO 1.16 OR ABOVE\n") 
     368    sys.stdout.write("WARNING : IF YOU ARE UPGRADING FROM A PRE-1.19alpha7 TO 1.19alpha7 OR ABOVE\n") 
    351369    sys.stdout.write("AND USE THE POSTGRESQL BACKEND, THEN YOU HAVE TO MODIFY YOUR\n") 
    352     sys.stdout.write("DATABASE SCHEMA USING initscripts/postgresql/upgrade-to-1.14.sql\n") 
    353     sys.stdout.write("AND initscripts/postgresql/upgrade-to-1.16.sql\n") 
     370    sys.stdout.write("DATABASE SCHEMA USING initscripts/postgresql/upgrade-to-1.19.sql\n") 
    354371    sys.stdout.write("PLEASE READ DOCUMENTATION IN initscripts/postgresql/ TO LEARN HOW TO DO.\n") 
    355372    sys.stdout.write("YOU CAN DO THAT AFTER THE INSTALLATION IS FINISHED, OR PRESS CTRL+C NOW.\n") 
    356     sys.stdout.write("\n\nYOU DON'T HAVE ANYTHING SPECIAL TO DO IF THIS IS YOUR FIRST INSTALLATION\nOR IF YOU ARE ALREADY RUNNING VERSION 1.16 OR ABOVE.\n\n") 
     373    sys.stdout.write("\n\nYOU DON'T HAVE ANYTHING SPECIAL TO DO IF THIS IS YOUR FIRST INSTALLATION\nOR IF YOU ARE ALREADY RUNNING VERSION 1.19alpha7 OR ABOVE.\n\n") 
    357374    dummy = raw_input("Please press ENTER when you have read the message above. ") 
    358375