Changeset 527 for pkpgcounter

Show
Ignore:
Timestamp:
11/28/07 18:28:30 (17 years ago)
Author:
jerome
Message:

Now the presence of executable dependencies is tested at runtime.

Location:
pkpgcounter/trunk
Files:
14 modified

Legend:

Unmodified
Added
Removed
  • pkpgcounter/trunk/pkpgpdls/analyzer.py

    r524 r527  
    5757        self.mustclose = None 
    5858         
    59     def findExecutable(self, command) : 
    60         """Finds an executable in the PATH and returns True if found else False.""" 
    61         for path in os.environ.get("PATH", "").split(":") : 
    62             fullname = os.path.abspath(os.path.join(os.path.expanduser(path), command)) 
    63             if os.path.isfile(fullname) and os.access(fullname, os.X_OK) : 
    64                 return True 
    65         return False 
    66          
    6759    def getJobSize(self) :     
    6860        """Returns the job's size.""" 
     
    7466                size = pdlhandler.getJobSize() 
    7567            except pdlparser.PDLParserError, msg :     
    76                 raise pdlparser.PDLParserError, "Unknown file format for %s (%s)" % (self.filename, msg) 
     68                raise pdlparser.PDLParserError, "Unsupported file format for %s (%s)" % (self.filename, msg) 
    7769        finally :     
    7870            self.closeFile() 
     
    9890                    dummyfile.close() 
    9991            except pdlparser.PDLParserError, msg :     
    100                 raise pdlparser.PDLParserError, "Unknown file format for %s (%s)" % (self.filename, msg) 
     92                raise pdlparser.PDLParserError, "Unsupported file format for %s (%s)" % (self.filename, msg) 
    10193        finally : 
    10294            self.closeFile() 
  • pkpgcounter/trunk/pkpgpdls/dvi.py

    r522 r527  
    3333    """A parser for DVI documents.""" 
    3434    totiffcommands = [ 'dvips -q -o - "%(infname)s" | gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r"%(dpi)i" -sOutputFile="%(outfname)s" -' ] 
     35    required = [ "dvips", "gs" ] 
    3536    def isValid(self) :         
    3637        """Returns True if data is DVI, else False.""" 
  • pkpgcounter/trunk/pkpgpdls/inkcoverage.py

    r520 r527  
    2525import sys 
    2626 
    27 from PIL import Image 
     27import pdlparser 
    2828 
    29 import pdlparser 
     29try : 
     30    from PIL import Image 
     31except ImportError :     
     32    sys.stderr.write("ERROR: You MUST install the Python Imaging Library (python-imaging) for pkpgcounter to work.\n") 
     33    raise pdlparser.PDLParserError, "The Python Imaging Library is missing." 
    3034 
    3135def getPercent(img, nbpix) : 
  • pkpgcounter/trunk/pkpgpdls/mscrap.py

    r525 r527  
    3232    """A parser for that MS crap thing.""" 
    3333    totiffcommands = [ 'xvfb-run -a abiword --import-extension=.doc --print="| gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r\"%(dpi)i\" -sOutputFile=\"%(outfname)s\" -" "%(infname)s"' ] 
     34    required = [ "xvfb-run", "xauth", "abiword", "gs" ] 
    3435    def isValid(self) :     
    3536        """Returns True if data is MS crap, else False. 
     
    4647           or self.firstblock[2112:].startswith("MSWordDoc") : 
    4748            self.logdebug("DEBUG: Input file seems to be in a Microsoft shitty file format.") 
    48             return True 
     49            # Here we do the missing test because all commands will be needed even in page counting mode 
     50            if self.isMissing(self.required) : 
     51                return False 
     52            else :     
     53                return True 
    4954        else :     
    5055            return False 
  • pkpgcounter/trunk/pkpgpdls/ooo.py

    r526 r527  
    3131    """A parser for OpenOffice.org documents.""" 
    3232    totiffcommands = [ 'xvfb-run -a abiword --import-extension=.odt --print="| gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r\"%(dpi)i\" -sOutputFile=\"%(outfname)s\" -" "%(infname)s"' ] 
     33    required = [ "xvfb-run", "xauth", "abiword", "gs" ] 
    3334    def isValid(self) :         
    3435        """Returns True if data is OpenDocument, else False.""" 
  • pkpgcounter/trunk/pkpgpdls/pcl345.py

    r522 r527  
    4242                       'pcl6 -sDEVICE=pswrite -r"%(dpi)i" -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -sOutputFile=- "%(infname)s" | gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r%(dpi)i -sOutputFile="%(outfname)s" -', 
    4343                     ] 
     44    required = [ "pcl6", "gs" ] 
    4445    mediasizes = {  # ESC&l####A 
    4546                    0 : "Default", 
  • pkpgcounter/trunk/pkpgpdls/pclxl.py

    r522 r527  
    3636                       'pcl6 -sDEVICE=pswrite -r"%(dpi)i" -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -sOutputFile=- "%(infname)s" | gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r"%(dpi)i" -sOutputFile="%(outfname)s" -', 
    3737                     ] 
     38    required = [ "pcl6", "gs" ] 
    3839    mediasizes = {  
    3940                    0 : "Letter", 
  • pkpgcounter/trunk/pkpgpdls/pdf.py

    r522 r527  
    4444    """A parser for PDF documents.""" 
    4545    totiffcommands = [ 'gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r"%(dpi)i" -sOutputFile="%(outfname)s" "%(infname)s"' ] 
     46    required = [ "gs" ] 
    4647    openmode = "rU" 
    4748    def isValid(self) :     
  • pkpgcounter/trunk/pkpgpdls/pdlparser.py

    r522 r527  
    2323import sys 
    2424import os 
    25 import popen2 
    2625 
    2726KILOBYTE = 1024     
     
    4140class PDLParser : 
    4241    """Generic PDL parser.""" 
    43     totiffcommands = None        # Default command to convert to TIFF 
    44     openmode = "rb"              # Default file opening mode 
     42    totiffcommands = None       # Default command to convert to TIFF 
     43    required = []               # Default list of required commands 
     44    openmode = "rb"             # Default file opening mode 
    4545    def __init__(self, parent, (firstblock, lastblock)) : 
    4646        """Initialize the generic parser.""" 
     
    7171            self.infile.close() 
    7272             
     73    def findExecutable(self, command) : 
     74        """Finds an executable in the PATH and returns True if found else False.""" 
     75        for cmd in [p.strip() for p in command.split("|")] : # | can separate alternatives for similar commands (e.g. a2ps|enscript) 
     76            for path in os.environ.get("PATH", "").split(":") : 
     77                fullname = os.path.abspath(os.path.join(os.path.expanduser(path), cmd)) 
     78                if os.path.isfile(fullname) and os.access(fullname, os.X_OK) : 
     79                    return True 
     80        return False 
     81         
     82    def isMissing(self, commands) :     
     83        """Returns True if some required commands are missing, else False."""  
     84        howmanythere = 0 
     85        for command in commands : 
     86            if not self.findExecutable(command) : 
     87                sys.stderr.write("ERROR: %(command)s is missing or not executable. You MUST install it for pkpgcounter to be able to do what you want.\n" % locals()) 
     88                sys.stderr.flush() 
     89            else :     
     90                howmanythere += 1 
     91        if howmanythere == len(commands) : 
     92            return False 
     93        else :    
     94            return True 
     95         
    7396    def logdebug(self, message) :        
    7497        """Logs a debug message if needed.""" 
     
    89112        """    
    90113        if self.totiffcommands : 
     114            if self.isMissing(self.required) : 
     115                raise PDLParserError, "At least one of the following commands is missing and should be installed for the computation of ink coverage : %s" % repr(self.required) 
    91116            infname = self.filename 
    92117            for totiffcommand in self.totiffcommands : 
  • pkpgcounter/trunk/pkpgpdls/pil.py

    r522 r527  
    2323"""This modules implements a page counter for image formats supported by the Python Imaging Library.""" 
    2424 
    25 from PIL import Image 
     25import pdlparser 
    2626 
    27 import pdlparser 
     27try : 
     28    from PIL import Image 
     29except ImportError :     
     30    sys.stderr.write("ERROR: You MUST install the Python Imaging Library (python-imaging) for pkpgcounter to work.\n") 
     31    raise pdlparser.PDLParserError, "The Python Imaging Library is missing." 
     32 
    2833import version 
    2934 
    3035class Parser(pdlparser.PDLParser) : 
    3136    """A parser for plain text documents.""" 
    32     totiffcommands = [ 'convert "%(infname)s" "%(outfname)s"', 
    33                      ]   
     37    totiffcommands = [ 'convert "%(infname)s" "%(outfname)s"' ]   
     38    required = [ "convert" ] 
    3439    def isValid(self) :     
    3540        """Returns True if data is an image format supported by PIL, else False."""    
  • pkpgcounter/trunk/pkpgpdls/plain.py

    r522 r527  
    3131                       'a2ps --borders 0 --quiet --portrait --no-header --columns 1 --output - "%(infname)s" | gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r"%(dpi)i" -sOutputFile="%(outfname)s" -', 
    3232                     ]   
     33    required = [ "a2ps | enscript", "gs" ] 
    3334    openmode = "rU"                  
    3435    def isValid(self) :     
  • pkpgcounter/trunk/pkpgpdls/postscript.py

    r522 r527  
    2525import sys 
    2626import os 
    27 import tempfile 
    28 import popen2 
    2927 
    3028import pdlparser 
     
    3432    """A parser for PostScript documents.""" 
    3533    totiffcommands = [ 'gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r"%(dpi)i" -sOutputFile="%(outfname)s" "%(infname)s"' ] 
     34    required = [ "gs" ] 
    3635    openmode = "rU" 
    3736    def isValid(self) :     
     
    5352        """Get the count through GhostScript, useful for non-DSC compliant PS files.""" 
    5453        self.logdebug("Internal parser sucks, using GhostScript instead...") 
     54        if self.isMissing(self.required) : 
     55            raise pdlparser.PDLParserError, "The gs interpreter is nowhere to be found in your PATH (%s)" % os.environ.get("PATH", "") 
    5556        infname = self.filename 
    5657        command = 'gs -sDEVICE=bbox -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET "%(infname)s" 2>&1 | grep -c "%%HiResBoundingBox:" 2>/dev/null' 
  • pkpgcounter/trunk/pkpgpdls/tiff.py

    r522 r527  
    3232class Parser(pdlparser.PDLParser) : 
    3333    """A parser for TIFF documents.""" 
    34     totiffcommands = [ '/bin/cp "%(infname)s" "%(outfname)s"' ] 
     34    totiffcommands = [ 'cp "%(infname)s" "%(outfname)s"' ] 
     35    required = [ "cp" ] 
    3536    def isValid(self) :         
    3637        """Returns True if data is TIFF, else False.""" 
  • pkpgcounter/trunk/README

    r502 r527  
    107107  3 - That's all !     
    108108   
     109DEPENDENCIES : 
     110 
     111  Depending on the file formats you plan to work with, and on the accounting 
     112  mode you want to use (pages vs ink), you may need to install some or all 
     113  of the additional software listed below. Usually, if one is needed then 
     114  pkpgcounter will complain. So your best bet is probably to not install 
     115  anything until pkpgcounter asks you to do so on its standard error 
     116  stream. Here's the list of software which may be needed for some 
     117  operations with pkpgcounter : 
     118 
     119  - GhostScript (gs) 
    109120   
    110 IMPORTANT : To compute ink coverage, pkpgcounter relies on third party 
    111 software which must be installed. These third party software are : 
     121  - The Python Imaging Library (python-imaging) 
     122   
     123  - The X Virtual Frame Buffer (xvfb) 
     124   
     125  - The X authority file utility xauth (xbase-clients) 
     126   
     127  - The dvips converter from TeX DVI to PostScript (tetex-bin) 
     128   
     129  - The ImageMagick image manipulation toolkit (imagemagick) 
     130   
     131  - The AbiWord word processor (abiword) 
    112132 
    113         - GhostScript (this one is needed for all file formats). 
    114          
    115         - The Python Imaging Library, aka PIL (this one is needed for all 
    116           file formats). 
    117          
    118         - GhostPCL (this one is needed for the PCL3/4/5 and PCLXL formats) 
    119            
    120         - The LaTeX typesetting software, in particular the dvips command 
    121           (this one is needed for the DVI file format). 
    122            
    123         - ImageMagick (this one is needed for image file formats)   
     133  - The GhostPCL/GhostPDL's pcl6 converter from PCL to PostScript 
    124134         
    125135=============================================================================