root / pkpgcounter / trunk / pkpgpdls / pdlparser.py @ 429

Revision 429, 5.5 kB (checked in by jerome, 18 years ago)

Ensure no data remains in the pipe.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Auth Date Id Rev
RevLine 
[192]1#
2# pkpgcounter : a generic Page Description Language parser
3#
[303]4# (c) 2003, 2004, 2005, 2006 Jerome Alet <alet@librelogiciel.com>
[192]5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
[211]17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
[192]18#
19# $Id$
20#
21
[360]22"""This module defines the base class for all Page Description Language parsers."""
23
[199]24import sys
[428]25import os
[371]26import popen2
[199]27
[220]28KILOBYTE = 1024   
29MEGABYTE = 1024 * KILOBYTE   
30FIRSTBLOCKSIZE = 16 * KILOBYTE
31LASTBLOCKSIZE = int(KILOBYTE / 4)
32
[193]33class PDLParserError(Exception):
34    """An exception for PDLParser related stuff."""
35    def __init__(self, message = ""):
36        self.message = message
37        Exception.__init__(self, message)
38    def __repr__(self):
39        return self.message
40    __str__ = __repr__
41       
[192]42class PDLParser :
43    """Generic PDL parser."""
[428]44    totiffcommands = None        # Default command to convert to TIFF
[220]45    def __init__(self, infile, debug=0, firstblock=None, lastblock=None) :
[192]46        """Initialize the generic parser."""
[220]47        self.infile = infile
[192]48        self.debug = debug
[220]49        if firstblock is None :
50            self.infile.seek(0)
51            firstblock = self.infile.read(FIRSTBLOCKSIZE)
52            try :
53                self.infile.seek(-LASTBLOCKSIZE, 2)
54                lastblock = self.infile.read(LASTBLOCKSIZE)
55            except IOError :   
56                lastblock = ""
57            self.infile.seek(0)
58        self.firstblock = firstblock
59        self.lastblock = lastblock
60        if not self.isValid() :
61            raise PDLParserError, "Invalid file format !"
62        try :
63            import psyco 
64        except ImportError :   
65            pass # Psyco is not installed
66        else :   
67            # Psyco is installed, tell it to compile
68            # the CPU intensive methods : PCL and PCLXL
69            # parsing will greatly benefit from this,
70            # for PostScript and PDF the difference is
71            # barely noticeable since they are already
72            # almost optimal, and much more speedy anyway.
73            psyco.bind(self.getJobSize)
74           
[252]75    def logdebug(self, message) :       
76        """Logs a debug message if needed."""
77        if self.debug :
78            sys.stderr.write("%s\n" % message)
79           
[220]80    def isValid(self) :   
[387]81        """Returns True if data is in the expected format, else False."""
[192]82        raise RuntimeError, "Not implemented !"
[220]83       
84    def getJobSize(self) :   
85        """Counts pages in a document."""
86        raise RuntimeError, "Not implemented !"
[362]87       
[363]88    def convertToTiffMultiPage24NC(self, fname, dpi) :
[362]89        """Converts the input file to TIFF format, X dpi, 24 bits per pixel, uncompressed.
[363]90           Writes TIFF datas to the file named by fname.
[362]91        """   
[428]92        if self.totiffcommands :
93            for totiffcommand in self.totiffcommands :
94                self.infile.seek(0)
95                error = False
96                commandline = totiffcommand % locals()
97                child = popen2.Popen4(commandline)
[371]98                try :
[428]99                    try :
100                        data = self.infile.read(MEGABYTE)   
101                        while data :
102                            child.tochild.write(data)
[429]103                            child.tochild.flush()
[428]104                            data = self.infile.read(MEGABYTE)
105                    except (IOError, OSError) :   
106                        error = True
107                finally :   
108                    child.tochild.close()   
[429]109                    dummy = child.fromchild.read()
[428]110                    child.fromchild.close()
111                   
112                try :
113                    child.wait()
114                except OSError :   
115                    error = True
116                   
117                if not os.path.exists(fname) :
118                    error = True
119                elif not os.stat(fname).st_size :
120                    error = True
121                else :       
122                    break       # Conversion worked fine it seems.
123                self.logdebug("Command failed : %s" % repr(commandline))
124            if error :
125                raise PDLParserError, "Problem during conversion to TIFF."
[371]126        else :       
127            raise PDLParserError, "Impossible to compute ink coverage for this file format."
[415]128           
129def test(parserclass) :       
130    """Test function."""
131    if (len(sys.argv) < 2) or ((not sys.stdin.isatty()) and ("-" not in sys.argv[1:])) :
132        sys.argv.append("-")
133    totalsize = 0   
134    for arg in sys.argv[1:] :
135        if arg == "-" :
136            infile = sys.stdin
137            mustclose = 0
138        else :   
139            infile = open(arg, "rb")
140            mustclose = 1
141        try :
142            parser = parserclass(infile, debug=1)
143            totalsize += parser.getJobSize()
144        except PDLParserError, msg :   
145            sys.stderr.write("ERROR: %s\n" % msg)
146            sys.stderr.flush()
147        if mustclose :   
148            infile.close()
149    print "%s" % totalsize
150   
Note: See TracBrowser for help on using the browser.