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

Revision 348, 5.9 kB (checked in by jerome, 18 years ago)

Now uses optparse for easier extensibility.

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