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

Revision 450, 5.6 kB (checked in by jerome, 16 years ago)

Now uses Python's universal newline detection to read input files,
and also uses file objects directly instead of calling their xreadlines()
method.
Fixed an accounting problem in the PDF parser for some type of files.

  • 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, 2007 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            psyco.bind(self.getJobSize)
71           
72    def logdebug(self, message) :       
73        """Logs a debug message if needed."""
74        if self.debug :
75            sys.stderr.write("%s\n" % message)
76           
77    def isValid(self) :   
78        """Returns True if data is in the expected format, else False."""
79        raise RuntimeError, "Not implemented !"
80       
81    def getJobSize(self) :   
82        """Counts pages in a document."""
83        raise RuntimeError, "Not implemented !"
84       
85    def convertToTiffMultiPage24NC(self, fname, dpi) :
86        """Converts the input file to TIFF format, X dpi, 24 bits per pixel, uncompressed.
87           Writes TIFF datas to the file named by fname.
88        """   
89        if self.totiffcommands :
90            for totiffcommand in self.totiffcommands :
91                self.infile.seek(0)
92                error = False
93                commandline = totiffcommand % locals()
94                child = popen2.Popen4(commandline)
95                try :
96                    try :
97                        data = self.infile.read(MEGABYTE)   
98                        while data :
99                            child.tochild.write(data)
100                            child.tochild.flush()
101                            data = self.infile.read(MEGABYTE)
102                    except (IOError, OSError) :   
103                        error = True
104                finally :   
105                    child.tochild.close()   
106                    dummy = child.fromchild.read()
107                    child.fromchild.close()
108                   
109                try :
110                    status = child.wait()
111                except OSError :   
112                    error = True
113                else :   
114                    if os.WIFEXITED(status) :
115                        if os.WEXITSTATUS(status) :
116                            error = True
117                    else :       
118                        error = True
119                   
120                if not os.path.exists(fname) :
121                    error = True
122                elif not os.stat(fname).st_size :
123                    error = True
124                else :       
125                    break       # Conversion worked fine it seems.
126                self.logdebug("Command failed : %s" % repr(commandline))
127            if error :
128                raise PDLParserError, "Problem during conversion to TIFF."
129        else :       
130            raise PDLParserError, "Impossible to compute ink coverage for this file format."
131           
132def test(parserclass) :       
133    """Test function."""
134    if (len(sys.argv) < 2) or ((not sys.stdin.isatty()) and ("-" not in sys.argv[1:])) :
135        sys.argv.append("-")
136    totalsize = 0   
137    for arg in sys.argv[1:] :
138        if arg == "-" :
139            infile = sys.stdin
140            mustclose = 0
141        else :   
142            infile = open(arg, "rbU")
143            mustclose = 1
144        try :
145            parser = parserclass(infile, debug=1)
146            totalsize += parser.getJobSize()
147        except PDLParserError, msg :   
148            sys.stderr.write("ERROR: %s\n" % msg)
149            sys.stderr.flush()
150        if mustclose :   
151            infile.close()
152    print "%s" % totalsize
153   
Note: See TracBrowser for help on using the browser.