root / pkpgcounter / trunk / pkpgpdls / analyzer.py @ 342

Revision 328, 5.7 kB (checked in by jerome, 19 years ago)

Added preliminary support for the ZjStream? Page Description Language.

  • 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
22import sys
23import tempfile
24
25import version, pdlparser, postscript, pdf, pcl345, pclxl, \
26       escp2, dvi, tiff, ooo, zjstream
27
28class PDLAnalyzer :   
29    """Class for PDL autodetection."""
30    def __init__(self, filename, debug=0) :
31        """Initializes the PDL analyzer.
32       
33           filename is the name of the file or '-' for stdin.
34           filename can also be a file-like object which
35           supports read() and seek().
36        """
37        self.debug = debug
38        self.filename = filename
39       
40    def getJobSize(self) :   
41        """Returns the job's size."""
42        self.openFile()
43        try :
44            pdlhandler = self.detectPDLHandler()
45        except pdlparser.PDLParserError, msg :   
46            self.closeFile()
47            raise pdlparser.PDLParserError, "Unknown file format for %s (%s)" % (self.filename, msg)
48        else :
49            try :
50                size = pdlhandler.getJobSize()
51            finally :   
52                self.closeFile()
53            return size
54       
55    def openFile(self) :   
56        """Opens the job's data stream for reading."""
57        self.mustclose = 0  # by default we don't want to close the file when finished
58        if hasattr(self.filename, "read") and hasattr(self.filename, "seek") :
59            # filename is in fact a file-like object
60            infile = self.filename
61        elif self.filename == "-" :
62            # we must read from stdin
63            infile = sys.stdin
64        else :   
65            # normal file
66            self.infile = open(self.filename, "rb")
67            self.mustclose = 1
68            return
69           
70        # Use a temporary file, always seekable contrary to standard input.
71        self.infile = tempfile.TemporaryFile(mode="w+b")
72        while 1 :
73            data = infile.read(pdlparser.MEGABYTE) 
74            if not data :
75                break
76            self.infile.write(data)
77        self.infile.flush()   
78        self.infile.seek(0)
79           
80    def closeFile(self) :       
81        """Closes the job's data stream if we can close it."""
82        if self.mustclose :
83            self.infile.close()   
84        else :   
85            # if we don't have to close the file, then
86            # ensure the file pointer is reset to the
87            # start of the file in case the process wants
88            # to read the file again.
89            try :
90                self.infile.seek(0)
91            except :   
92                pass    # probably stdin, which is not seekable
93       
94    def detectPDLHandler(self) :   
95        """Tries to autodetect the document format.
96       
97           Returns the correct PDL handler class or None if format is unknown
98        """   
99        # Try to detect file type by reading first and last blocks of datas   
100        # Each parser can read them automatically, but here we do this only once.
101        self.infile.seek(0)
102        firstblock = self.infile.read(pdlparser.FIRSTBLOCKSIZE)
103        try :
104            self.infile.seek(-pdlparser.LASTBLOCKSIZE, 2)
105            lastblock = self.infile.read(pdlparser.LASTBLOCKSIZE)
106        except IOError :   
107            lastblock = ""
108        self.infile.seek(0)
109        if not firstblock :
110            raise pdlparser.PDLParserError, "input file %s is empty !" % str(self.filename)
111        else :   
112            for module in (postscript, \
113                           pclxl, \
114                           pdf, \
115                           pcl345, \
116                           escp2, \
117                           dvi, \
118                           tiff, \
119                           zjstream, \
120                           ooo) :
121                try :               
122                    return module.Parser(self.infile, self.debug, firstblock, lastblock)
123                except pdlparser.PDLParserError :
124                    pass # try next parser
125        raise pdlparser.PDLParserError, "Analysis of first data block failed."
126           
127def main() :   
128    """Entry point for PDL Analyzer."""
129    if (len(sys.argv) < 2) or ((not sys.stdin.isatty()) and ("-" not in sys.argv[1:])) :
130        sys.argv.append("-")
131       
132    if ("-h" in sys.argv[1:]) or ("--help" in sys.argv[1:]) :
133        print "usage : pkpgcounter file1 file2 ... fileN"
134    elif ("-v" in sys.argv[1:]) or ("--version" in sys.argv[1:]) :
135        print "%s" % version.__version__
136    else :
137        totalsize = 0   
138        debug = 0
139        minindex = 1
140        if sys.argv[1] in ("-d", "--debug") :
141            minindex = 2
142            debug = 1
143        for arg in sys.argv[minindex:] :
144            try :
145                parser = PDLAnalyzer(arg, debug)
146                totalsize += parser.getJobSize()
147            except pdlparser.PDLParserError, msg :   
148                sys.stderr.write("ERROR: %s\n" % msg)
149                sys.stderr.flush()
150        print "%s" % totalsize
151   
152if __name__ == "__main__" :   
153    main()
Note: See TracBrowser for help on using the browser.