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

Revision 428, 5.4 kB (checked in by jerome, 18 years ago)

Improved ink accounting by allowing several commands to be launch to convert to TIFF in case one of them fails.

  • 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                            data = self.infile.read(MEGABYTE)
104                    except (IOError, OSError) :   
105                        error = True
106                finally :   
107                    child.tochild.close()   
108                    child.fromchild.close()
109                   
110                try :
111                    child.wait()
112                except OSError :   
113                    error = True
114                   
115                if not os.path.exists(fname) :
116                    error = True
117                elif not os.stat(fname).st_size :
118                    error = True
119                else :       
120                    break       # Conversion worked fine it seems.
121                self.logdebug("Command failed : %s" % repr(commandline))
122            if error :
123                raise PDLParserError, "Problem during conversion to TIFF."
124        else :       
125            raise PDLParserError, "Impossible to compute ink coverage for this file format."
126           
127def test(parserclass) :       
128    """Test function."""
129    if (len(sys.argv) < 2) or ((not sys.stdin.isatty()) and ("-" not in sys.argv[1:])) :
130        sys.argv.append("-")
131    totalsize = 0   
132    for arg in sys.argv[1:] :
133        if arg == "-" :
134            infile = sys.stdin
135            mustclose = 0
136        else :   
137            infile = open(arg, "rb")
138            mustclose = 1
139        try :
140            parser = parserclass(infile, debug=1)
141            totalsize += parser.getJobSize()
142        except PDLParserError, msg :   
143            sys.stderr.write("ERROR: %s\n" % msg)
144            sys.stderr.flush()
145        if mustclose :   
146            infile.close()
147    print "%s" % totalsize
148   
Note: See TracBrowser for help on using the browser.