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

Revision 429, 5.5 kB (checked in by jerome, 17 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
Line 
1#
2# pkpgcounter : a generic Page Description Language parser
3#
4# (c) 2003, 2004, 2005, 2006 Jerome Alet <alet@librelogiciel.com>
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
17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18#
19# $Id$
20#
21
22"""This module defines the base class for all Page Description Language parsers."""
23
24import sys
25import os
26import popen2
27
28KILOBYTE = 1024   
29MEGABYTE = 1024 * KILOBYTE   
30FIRSTBLOCKSIZE = 16 * KILOBYTE
31LASTBLOCKSIZE = int(KILOBYTE / 4)
32
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       
42class PDLParser :
43    """Generic PDL parser."""
44    totiffcommands = None        # Default command to convert to TIFF
45    def __init__(self, infile, debug=0, firstblock=None, lastblock=None) :
46        """Initialize the generic parser."""
47        self.infile = infile
48        self.debug = debug
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           
75    def logdebug(self, message) :       
76        """Logs a debug message if needed."""
77        if self.debug :
78            sys.stderr.write("%s\n" % message)
79           
80    def isValid(self) :   
81        """Returns True if data is in the expected format, else False."""
82        raise RuntimeError, "Not implemented !"
83       
84    def getJobSize(self) :   
85        """Counts pages in a document."""
86        raise RuntimeError, "Not implemented !"
87       
88    def convertToTiffMultiPage24NC(self, fname, dpi) :
89        """Converts the input file to TIFF format, X dpi, 24 bits per pixel, uncompressed.
90           Writes TIFF datas to the file named by fname.
91        """   
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)
98                try :
99                    try :
100                        data = self.infile.read(MEGABYTE)   
101                        while data :
102                            child.tochild.write(data)
103                            child.tochild.flush()
104                            data = self.infile.read(MEGABYTE)
105                    except (IOError, OSError) :   
106                        error = True
107                finally :   
108                    child.tochild.close()   
109                    dummy = child.fromchild.read()
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."
126        else :       
127            raise PDLParserError, "Impossible to compute ink coverage for this file format."
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.