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

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

Added support for OpenOffice?.org Writer and Impress file formats

  • 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 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
25from pdlanalyzer import version, pdlparser, \
26                        postscript, pdf, pcl345, pclxl, \
27                        escp2, dvi, tiff, ooo
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                           ooo) :
121                try :               
122                    return getattr(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.