root / pkpgcounter / trunk / pkpgpdls / newpcl345.py @ 392

Revision 392, 34.0 kB (checked in by jerome, 18 years ago)

Finally began to rewrite the PCL3/4/5 parser. Don't use it yet !

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
Line 
1#! /usr/bin/env python
2# -*- coding: ISO-8859-15 -*-
3#
4# pkpgcounter : a generic Page Description Language parser
5#
6# (c) 2003, 2004, 2005, 2006 Jerome Alet <alet@librelogiciel.com>
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20#
21# $Id$
22#
23
24"""This modules implements a page counter for PCL3/4/5 documents."""
25
26import sys
27import os
28import mmap
29from struct import unpack
30
31import pdlparser
32import pjl
33
34ESCAPE = chr(27)
35
36class Parser(pdlparser.PDLParser) :
37    """A parser for PCL3, PCL4, PCL5 documents."""
38    totiffcommand = 'pcl6 -sDEVICE=pdfwrite -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -sOutputFile=- - | gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r%(dpi)i -sOutputFile="%(fname)s" -'
39    mediasizes = {  # ESC&l####A
40                    0 : "Default",
41                    1 : "Executive",
42                    2 : "Letter",
43                    3 : "Legal",
44                    6 : "Ledger", 
45                    25 : "A5",
46                    26 : "A4",
47                    27 : "A3",
48                    45 : "JB5",
49                    46 : "JB4",
50                    71 : "HagakiPostcard",
51                    72 : "OufukuHagakiPostcard",
52                    80 : "MonarchEnvelope",
53                    81 : "COM10Envelope",
54                    90 : "DLEnvelope",
55                    91 : "C5Envelope",
56                    100 : "B5Envelope",
57                    101 : "Custom",
58                 }   
59                 
60    mediasources = { # ESC&l####H
61                     0 : "Default",
62                     1 : "Main",
63                     2 : "Manual",
64                     3 : "ManualEnvelope",
65                     4 : "Alternate",
66                     5 : "OptionalLarge",
67                     6 : "EnvelopeFeeder",
68                     7 : "Auto",
69                     8 : "Tray1",
70                   }
71                   
72    orientations = { # ESC&l####O
73                     0 : "Portrait",
74                     1 : "Landscape",
75                     2 : "ReversePortrait",
76                     3 : "ReverseLandscape",
77                   }
78                   
79    mediatypes = { # ESC&l####M
80                     0 : "Plain",
81                     1 : "Bond",
82                     2 : "Special",
83                     3 : "Glossy",
84                     4 : "Transparent",
85                   }
86       
87    def isValid(self) :   
88        """Returns True if data is PCL3/4/5, else False."""
89        if self.firstblock.startswith("\033E\033") or \
90           (self.firstblock.startswith("\033*rbC") and (not self.lastblock[-3:] == "\f\033@")) or \
91           self.firstblock.startswith("\033%8\033") or \
92           (self.firstblock.find("\033%-12345X") != -1) or \
93           (self.firstblock.find("@PJL ENTER LANGUAGE=PCL\012\015\033") != -1) or \
94           (self.firstblock.startswith(chr(0xcd)+chr(0xca)) and self.firstblock.find("\033E\033")) :
95            self.logdebug("DEBUG: Input file is in the PCL3/4/5 format.")
96            return True
97        else :   
98            return False
99       
100    def setPageDict(self, pages, number, attribute, value) :
101        """Initializes a page dictionnary."""
102        dic = pages.setdefault(number, { "copies" : 1, "mediasource" : "Main", "mediasize" : "Default", "mediatype" : "Plain", "orientation" : "Portrait", "escaped" : "", "duplex": 0})
103        dic[attribute] = value
104       
105    def endPage(self) :   
106        """Handle the FF marker."""
107        self.pagecount += 1
108        self.logdebug("ENDPAGE %i" % self.pagecount)
109       
110    def escPercent(self) :   
111        """Handles the ESC% sequence."""
112        if self.minfile[self.pos : self.pos+7] == r"-12345X" :
113            self.logdebug("Generic ESCAPE sequence at %08x" % self.pos)
114            self.pos += 7
115       
116    def handleTag(self, tagtable) :   
117        """Handles tags."""
118        tag = ord(self.minfile[self.pos])
119        self.pos += 1
120        tagtable[tag]()
121       
122    def escape(self) :   
123        """Handles the ESC character."""
124        self.logdebug("ESCAPE")
125        self.handleTag(self.esctags)
126       
127    def escAmp(self) :   
128        """Handles the ESC& sequence."""
129        self.logdebug("AMP")
130        self.handleTag(self.escamptags)
131       
132    def escStar(self) :   
133        """Handles the ESC* sequence."""
134        self.logdebug("STAR")
135        self.handleTag(self.escstartags)
136       
137    def escLeftPar(self) :   
138        """Handles the ESC( sequence."""
139        self.logdebug("LEFTPAR")
140        self.handleTag(self.escleftpartags)
141       
142    def escRightPar(self) :   
143        """Handles the ESC( sequence."""
144        self.logdebug("RIGHTPAR")
145        self.handleTag(self.escrightpartags)
146       
147    def escE(self) :   
148        """Handles the ESCE sequence."""
149        self.logdebug("RESET")
150        self.resets += 1
151       
152    def escAmpl(self) :   
153        """Handles the ESC&l sequence."""
154        self.logdebug("l")
155        while 1 :
156            (value, end) = self.getInteger()
157            if value is None :
158                return
159            if end in ('h', 'H') :
160                mediasource = self.mediasources.get(value, str(value))
161                self.mediasourcesvalues.append(mediasource)
162                self.logdebug("MEDIASOURCE %s" % mediasource)
163            elif end in ('a', 'A') :
164                mediasize = self.mediasizes.get(value, str(value))
165                self.mediasizesvalues.append(mediasize)
166                self.logdebug("MEDIASIZE %s" % mediasize)
167            elif end in ('o', 'O') :
168                orientation = self.orientations.get(value, str(value))
169                self.orientationsvalues.append(orientation)
170                self.logdebug("ORIENTATION %s" % orientation)
171            elif end in ('m', 'M') :
172                mediatype = self.mediatypes.get(value, str(value))
173                self.mediatypesvalues.append(mediatype)
174                self.logdebug("MEDIATYPE %s" % mediatype)
175            elif end == 'X' :
176                self.copies.append(value)
177                self.logdebug("COPIES %i" % value)
178            elif end == 'L' :   
179                self.logdebug("ESC&l%iL" % value)
180               
181    def escStarb(self) :   
182        """Handles the ESC*b sequence."""
183        self.logdebug("b")
184        while 1 :
185            (value, end) = self.getInteger()
186            self.logdebug("%s === %s" % (value, end))
187            if (end is None) and (value is None) :
188                return
189            if end in ('V', 'W', 'v', 'w') :   
190                self.pos += (value or 0)
191                self.logdebug("SKIPTO %08x" % self.pos)
192               
193    def escStaro(self) :   
194        """Handles the ESC*o sequence."""
195        self.logdebug("o")
196        while 1 :
197            (value, end) = self.getInteger()
198            if value is None :
199                return
200            if end == 'M' :
201                self.logdebug("ESC*o%iM" % value)
202               
203    def escStarp(self) :   
204        """Handles the ESC*p sequence."""
205        self.logdebug("p")
206        while 1 :
207            (value, end) = self.getInteger()
208            if value is None :
209                return
210            if end in ('X', 'Y') :   
211                self.logdebug("ESC*p%i%s" % (value, end))
212               
213    def escStarr(self) :   
214        """Handles the ESC*r sequence."""
215        self.logdebug("r")
216        while 1 :
217            (value, end) = self.getInteger()
218            if value is None :
219                if end is None :
220                    return
221                elif end == 'b' :
222                    if self.minfile[self.pos] == 'C' :
223                        self.logdebug("Looks like it's PCL3.")
224                        self.ispcl3 = True
225                        self.pos += 1
226                elif end == 'C' :       
227                    self.logdebug("EndGFX")
228                    if not self.startgfx :
229                        self.logdebug("EndGFX found before StartGFX, ignored.")
230                    else :   
231                        self.endgfx.append(1)
232            if end == 'A' and (0 <= value <= 3) :
233                self.logdebug("StartGFX %i" % value)
234                self.startgfx.append(value)
235            elif end == 'U' :   
236                self.logdebug("ESC*r%iU" % value)
237            elif end == 'S' :   
238                self.logdebug("ESC*r%iS" % value)
239               
240    def escStart(self) :   
241        """Handles the ESC*t sequence."""
242        self.logdebug("t")
243        while 1 :
244            (value, end) = self.getInteger()
245            if value is None :
246                return
247            if end == 'R' :   
248                self.logdebug("ESC*t%iR" % value)
249               
250    def escAmpu(self) :   
251        """Handles the ESC&u sequence."""
252        self.logdebug("u")
253        while 1 :
254            (value, end) = self.getInteger()
255            if value is None :
256                return
257            if end == 'D' :   
258                self.logdebug("ESC&u%iD" % value)
259               
260       
261    def getInteger(self) :   
262        """Returns an integer value and the end character."""
263        sign = 1
264        value = None
265        while 1 :
266            char = self.minfile[self.pos]
267            if char == ESCAPE :
268                return (None, None)
269            self.pos += 1
270            if char == '-' :
271                sign = -1
272            elif not char.isdigit() :
273                if value is not None :
274                    return (sign*value, char)
275                else :
276                    return (value, char)
277            else :   
278                value = ((value or 0) * 10) + int(char)   
279       
280    def getJobSize(self) :     
281        """Count pages in a PCL5 document.
282         
283           Should also work for PCL3 and PCL4 documents.
284           
285           Algorithm from pclcount
286           (c) 2003, by Eduardo Gielamo Oliveira & Rodolfo Broco Manin
287           published under the terms of the GNU General Public Licence v2.
288         
289           Backported from C to Python by Jerome Alet, then enhanced
290           with more PCL tags detected. I think all the necessary PCL tags
291           are recognized to correctly handle PCL5 files wrt their number
292           of pages. The documentation used for this was :
293         
294           HP PCL/PJL Reference Set
295           PCL5 Printer Language Technical Quick Reference Guide
296           http://h20000.www2.hp.com/bc/docs/support/SupportManual/bpl13205/bpl13205.pdf
297        """
298        infileno = self.infile.fileno()
299        self.minfile = minfile = mmap.mmap(infileno, os.fstat(infileno)[6], prot=mmap.PROT_READ, flags=mmap.MAP_SHARED)
300        self.ispcl3 = False
301        self.pagecount = 0
302        self.resets = 0
303        self.copies = []
304        self.mediasourcesvalues = []
305        self.mediasizesvalues = []
306        self.orientationsvalues = []
307        self.mediatypesvalues = []
308        self.startgfx = []
309        self.endgfx = []
310       
311        tags = [ lambda : None] * 256
312        tags[0x0c] = self.endPage
313        tags[0x1b] = self.escape
314       
315        self.esctags = [ lambda : None ] * 256
316        self.esctags[ord('%')] = self.escPercent
317        self.esctags[ord('*')] = self.escStar
318        self.esctags[ord('&')] = self.escAmp
319        self.esctags[ord('(')] = self.escLeftPar
320        self.esctags[ord(')')] = self.escRightPar
321        self.esctags[ord('E')] = self.escE
322       
323        self.escamptags = [lambda : None ] * 256
324        self.escamptags[ord('l')] = self.escAmpl
325        self.escamptags[ord('u')] = self.escAmpu
326       
327        self.escstartags = [ lambda : None ] * 256
328        self.escstartags[ord('b')] = self.escStarb
329        self.escstartags[ord('o')] = self.escStaro
330        self.escstartags[ord('p')] = self.escStarp
331        self.escstartags[ord('r')] = self.escStarr
332        self.escstartags[ord('t')] = self.escStart
333       
334        self.pos = 0
335        try :
336            try :
337                while 1 :
338                    tag = ord(minfile[self.pos])
339                    self.logdebug("%08x ===> %02x" % (self.pos, tag))
340                    self.pos += 1
341                    tags[tag]()
342            except IndexError : # EOF ?           
343                pass
344        finally :
345            self.minfile.close()
346       
347            self.logdebug("Pagecount : \t\t%i" % self.pagecount)
348            self.logdebug("Resets : \t\t%i" % self.resets)
349            self.logdebug("Copies : \t\t%s" % self.copies)
350            self.logdebug("MediaTypes : \t\t%s" % self.mediatypesvalues)
351            self.logdebug("MediaSizes : \t\t%s" % self.mediasizesvalues)
352            self.logdebug("MediaSources : \t\t%s" % self.mediasourcesvalues)
353            self.logdebug("Orientations : \t\t%s" % self.orientationsvalues)
354            self.logdebug("StartGfx : \t\t%s" % len(self.startgfx))
355            self.logdebug("EndGfx : \t\t%s" % len(self.endgfx))
356       
357        return self.pagecount
358       
359       
360       
361        """
362        tagsends = { "&n" : "W",
363                     "&b" : "W",
364                     "*i" : "W",
365                     "*l" : "W",
366                     "*m" : "W",
367                     "*v" : "W",
368                     "*c" : "W",
369                     "(f" : "W",
370                     "(s" : "W",
371                     ")s" : "W",
372                     "&p" : "X",
373                     # "&l" : "XHAOM",  # treated specially
374                     "&a" : "G", # TODO : 0 means next side, 1 front side, 2 back side
375                     "*g" : "W",
376                     "*r" : "sbABC",
377                     "*t" : "R",
378                     # "*b" : "VW", # treated specially because it occurs very often
379                   } 
380        irmarker = chr(0xcd) + chr(0xca) # Marker for Canon ImageRunner printers
381        irmarker2 = chr(0x10) + chr(0x02)
382        wasirmarker = 0
383        hasirmarker = (minfile[:2] == (irmarker))
384        pagecount = resets = ejects = backsides = startgfx = endgfx = 0
385        starb = ampl = ispcl3 = escstart = 0
386        mediasourcecount = mediasizecount = orientationcount = mediatypecount = 0
387        tag = None
388        endmark = chr(0x1b) + chr(0x0c) + chr(0x00)
389        asciilimit = chr(0x80)
390        pages = {}
391        pos = 0
392        try :
393            try :
394                while 1 :
395                    if hasirmarker and (minfile[pos:pos+2] == irmarker) :
396                        codop = minfile[pos+2:pos+4]
397                        # self.logdebug("Marker at 0x%08x     (%s)" % (pos, wasirmarker))
398                        length = unpack(">H", minfile[pos+8:pos+10])[0]
399                        pos += 20
400                        if codop != irmarker2 :
401                            pos += length
402                        wasirmarker = 1   
403                    else :       
404                        wasirmarker = 0
405                        elif char == "\033" :   
406                            starb = ampl = 0
407                            if minfile[pos : pos+8] == r"%-12345X" :
408                                endpos = pos + 9
409                                quotes = 0
410                                while (minfile[endpos] not in endmark) and \
411                                      ((minfile[endpos] < asciilimit) or (quotes % 2)) :
412                                    if minfile[endpos] == '"' :
413                                        quotes += 1
414                                    endpos += 1
415                                self.setPageDict(pages, pagecount, "escaped", minfile[pos : endpos])
416                                pos += (endpos - pos)
417                            else :
418                                #
419                                #     <ESC>*b###y#m###v###w... -> PCL3 raster graphics
420                                #     <ESC>*b###W -> Start of a raster data row/block
421                                #     <ESC>*b###V -> Start of a raster data plane
422                                #     <ESC>*c###W -> Start of a user defined pattern
423                                #     <ESC>*i###W -> Start of a viewing illuminant block
424                                #     <ESC>*l###W -> Start of a color lookup table
425                                #     <ESC>*m###W -> Start of a download dither matrix block
426                                #     <ESC>*v###W -> Start of a configure image data block
427                                #     <ESC>*r1A -> Start Gfx
428                                #     <ESC>(s###W -> Start of a characters description block
429                                #     <ESC>)s###W -> Start of a fonts description block
430                                #     <ESC>(f###W -> Start of a symbol set block
431                                #     <ESC>&b###W -> Start of configuration data block
432                                #     <ESC>&l###X -> Number of copies for current page
433                                #     <ESC>&n###W -> Starts an alphanumeric string ID block
434                                #     <ESC>&p###X -> Start of a non printable characters block
435                                #     <ESC>&a2G -> Back side when duplex mode as generated by rastertohp
436                                #     <ESC>*g###W -> Needed for planes in PCL3 output
437                                #     <ESC>&l###H (or only 0 ?) -> Eject if NumPlanes > 1, as generated by rastertohp. Also defines mediasource
438                                #     <ESC>&l###A -> mediasize
439                                #     <ESC>&l###O -> orientation
440                                #     <ESC>&l###M -> mediatype
441                                #     <ESC>*t###R -> gfx resolution
442                                #
443                                tagstart = minfile[pos] ; pos += 1
444                                if tagstart in "E9=YZ" : # one byte PCL tag
445                                    if tagstart == "E" :
446                                        resets += 1
447                                    continue             # skip to next tag
448                                tag = tagstart + minfile[pos] ; pos += 1
449                                if tag == "*b" :
450                                    starb = 1
451                                    tagend = "VW"
452                                elif tag == "&l" :   
453                                    ampl = 1
454                                    tagend = "XHAOM"
455                                else :   
456                                    try :
457                                        tagend = tagsends[tag]
458                                    except KeyError :   
459                                        continue # Unsupported PCL tag
460                                # Now read the numeric argument
461                                size = 0
462                                while 1 :
463                                    char = minfile[pos] ; pos += 1
464                                    if not char.isdigit() :
465                                        break
466                                    size = (size * 10) + int(char)   
467                                if char in tagend :   
468                                    if tag == "&l" :
469                                        if char == "X" :
470                                            self.setPageDict(pages, pagecount, "copies", size)
471                                        elif char == "H" :
472                                            self.setPageDict(pages, pagecount, "mediasource", self.mediasources.get(size, str(size)))
473                                            mediasourcecount += 1
474                                            ejects += 1
475                                        elif char == "A" :
476                                            self.setPageDict(pages, pagecount, "mediasize", self.mediasizes.get(size, str(size)))
477                                            mediasizecount += 1
478                                        elif char == "O" :
479                                            self.setPageDict(pages, pagecount, "orientation", self.orientations.get(size, str(size)))
480                                            orientationcount += 1
481                                        elif char == "M" :
482                                            self.setPageDict(pages, pagecount, "mediatype", self.mediatypes.get(size, str(size)))
483                                            mediatypecount += 1
484                                    elif tag == "*r" :
485                                        # Special tests for PCL3
486                                        if (char == "s") and size :
487                                            while 1 :
488                                                char = minfile[pos] ; pos += 1
489                                                if char == "A" :
490                                                    break
491                                        elif (char == "b") and (minfile[pos] == "C") and not size :
492                                            ispcl3 = 1 # Certainely a PCL3 file
493                                        startgfx += (char == "A") and (minfile[pos - 2] in ("0", "1", "2", "3")) # Start Gfx
494                                        endgfx += (not size) and (char in ("C", "B")) # End Gfx
495                                    elif tag == "*t" :   
496                                        escstart += 1
497                                    elif (tag == "&a") and (size == 2) :
498                                        # We are on the backside, so mark current page as duplex
499                                        self.setPageDict(pages, pagecount, "duplex", 1)
500                                        backsides += 1      # Back side in duplex mode
501                                    else :   
502                                        # we just ignore the block.
503                                        if tag == "&n" :
504                                            # we have to take care of the operation id byte
505                                            # which is before the string itself
506                                            size += 1
507                                        pos += size   
508                        else :                           
509                            if starb :
510                                # special handling of PCL3 in which
511                                # *b introduces combined ESCape sequences
512                                size = 0
513                                while 1 :
514                                    char = minfile[pos] ; pos += 1
515                                    if not char.isdigit() :
516                                        break
517                                    size = (size * 10) + int(char)   
518                                if char in ("w", "v") :   
519                                    ispcl3 = 1  # certainely a PCL3 document
520                                    pos += size - 1
521                                elif char in ("y", "m") :   
522                                    ispcl3 = 1  # certainely a PCL3 document
523                                    pos -= 1    # fix position : we were ahead
524                            elif ampl :       
525                                # special handling of PCL3 in which
526                                # &l introduces combined ESCape sequences
527                                size = 0
528                                while 1 :
529                                    char = minfile[pos] ; pos += 1
530                                    if not char.isdigit() :
531                                        break
532                                    size = (size * 10) + int(char)   
533                                if char in ("a", "o", "h", "m") :   
534                                    ispcl3 = 1  # certainely a PCL3 document
535                                    pos -= 1    # fix position : we were ahead
536                                    if char == "h" :
537                                        self.setPageDict(pages, pagecount, "mediasource", self.mediasources.get(size, str(size)))
538                                        mediasourcecount += 1
539                                    elif char == "a" :
540                                        self.setPageDict(pages, pagecount, "mediasize", self.mediasizes.get(size, str(size)))
541                                        mediasizecount += 1
542                                    elif char == "o" :
543                                        self.setPageDict(pages, pagecount, "orientation", self.orientations.get(size, str(size)))
544                                        orientationcount += 1
545                                    elif char == "m" :
546                                        self.setPageDict(pages, pagecount, "mediatype", self.mediatypes.get(size, str(size)))
547                                        mediatypecount += 1
548            except IndexError : # EOF ?
549                pass
550        finally :
551            minfile.close()
552                           
553        # if pagecount is still 0, we will use the number
554        # of resets instead of the number of form feed characters.
555        # but the number of resets is always at least 2 with a valid
556        # pcl file : one at the very start and one at the very end
557        # of the job's data. So we substract 2 from the number of
558        # resets. And since on our test data we needed to substract
559        # 1 more, we finally substract 3, and will test several
560        # PCL files with this. If resets < 2, then the file is
561        # probably not a valid PCL file, so we use 0
562       
563        if self.debug :
564            sys.stderr.write("pagecount : %s\n" % pagecount)
565            sys.stderr.write("resets : %s\n" % resets)
566            sys.stderr.write("ejects : %s\n" % ejects)
567            sys.stderr.write("backsides : %s\n" % backsides)
568            sys.stderr.write("startgfx : %s\n" % startgfx)
569            sys.stderr.write("endgfx : %s\n" % endgfx)
570            sys.stderr.write("mediasourcecount : %s\n" % mediasourcecount)
571            sys.stderr.write("mediasizecount : %s\n" % mediasizecount)
572            sys.stderr.write("orientationcount : %s\n" % orientationcount)
573            sys.stderr.write("mediatypecount : %s\n" % mediatypecount)
574            sys.stderr.write("escstart : %s\n" % escstart)
575            sys.stderr.write("hasirmarker : %s\n" % hasirmarker)
576       
577        if hasirmarker :
578            self.logdebug("Rule #20 (probably a Canon ImageRunner)")
579            pagecount += 1
580        elif (orientationcount == (pagecount - 1)) and (resets == 1) :
581            if resets == ejects == startgfx == mediasourcecount == escstart == 1 :
582                self.logdebug("Rule #19")
583            else :   
584                self.logdebug("Rule #1")
585                pagecount -= 1
586        elif pagecount and (pagecount == orientationcount) :
587            self.logdebug("Rule #2")
588        elif resets == ejects == mediasourcecount == mediasizecount == escstart == 1 :
589            #if ((startgfx and endgfx) and (startgfx != endgfx)) or (startgfx == endgfx == 0) :
590            if (startgfx and endgfx) or (startgfx == endgfx == 0) :
591                self.logdebug("Rule #3")
592                pagecount = orientationcount
593            elif (endgfx and not startgfx) and (pagecount > orientationcount) :   
594                self.logdebug("Rule #4")
595                pagecount = orientationcount
596            else :     
597                self.logdebug("Rule #5")
598                pagecount += 1
599        elif (ejects == mediasourcecount == orientationcount) and (startgfx == endgfx) :     
600            if (resets == 2) and (orientationcount == (pagecount - 1)) and (orientationcount > 1) :
601                self.logdebug("Rule #6")
602                pagecount = orientationcount
603        elif pagecount == mediasourcecount == escstart :
604            self.logdebug("Rule #7")
605        elif resets == startgfx == endgfx == mediasizecount == orientationcount == escstart == 1 :     
606            self.logdebug("Rule #8")
607        elif resets == startgfx == endgfx == (pagecount - 1) :   
608            self.logdebug("Rule #9")
609        elif (not startgfx) and (not endgfx) :
610            self.logdebug("Rule #10")
611        elif (resets == 2) and (startgfx == endgfx) and (mediasourcecount == 1) :
612            if orientationcount == (pagecount - 1) :
613                self.logdebug("Rule #11")
614                pagecount = orientationcount
615            elif not pagecount :   
616                self.logdebug("Rule #17")
617                pagecount = ejects
618        elif (resets == 1) and (startgfx == endgfx) and (mediasourcecount == 0) :
619            if (startgfx > 1) and (startgfx != (pagecount - 1)) :
620                self.logdebug("Rule #12")
621                pagecount -= 1
622            else :   
623                self.logdebug("Rule #18")
624        elif startgfx == endgfx :   
625            self.logdebug("Rule #13")
626            pagecount = startgfx
627        elif startgfx == (endgfx - 1) :   
628            self.logdebug("Rule #14")
629            pagecount = startgfx
630        elif (startgfx == 1) and not endgfx :   
631            self.logdebug("Rule #15")
632            pass
633        else :   
634            self.logdebug("Rule #16")
635            pagecount = abs(startgfx - endgfx)
636           
637        defaultpjlcopies = 1   
638        defaultduplexmode = "Simplex"
639        defaultpapersize = ""
640        oldpjlcopies = -1
641        oldduplexmode = ""
642        oldpapersize = ""
643        for pnum in range(pagecount) :
644            # if no number of copies defined, take the preceding one else the one set before any page else 1.
645            page = pages.get(pnum, pages.get(pnum - 1, pages.get(0, { "copies" : 1, "mediasource" : "Main", "mediasize" : "Default", "mediatype" : "Plain", "orientation" : "Portrait", "escaped" : "", "duplex": 0})))
646            pjlstuff = page["escaped"]
647            if pjlstuff :
648                pjlparser = pjl.PJLParser(pjlstuff)
649                nbdefaultcopies = int(pjlparser.default_variables.get("COPIES", -1))
650                nbcopies = int(pjlparser.environment_variables.get("COPIES", -1))
651                nbdefaultqty = int(pjlparser.default_variables.get("QTY", -1))
652                nbqty = int(pjlparser.environment_variables.get("QTY", -1))
653                if nbdefaultcopies > -1 :
654                    defaultpjlcopies = nbdefaultcopies
655                if nbdefaultqty > -1 :
656                    defaultpjlcopies = nbdefaultqty
657                if nbcopies > -1 :
658                    pjlcopies = nbcopies
659                elif nbqty > -1 :
660                    pjlcopies = nbqty
661                else :
662                    if oldpjlcopies == -1 :   
663                        pjlcopies = defaultpjlcopies
664                    else :   
665                        pjlcopies = oldpjlcopies   
666                if page["duplex"] :       
667                    duplexmode = "Duplex"
668                else :   
669                    defaultdm = pjlparser.default_variables.get("DUPLEX", "")
670                    if defaultdm :
671                        if defaultdm.upper() == "ON" :
672                            defaultduplexmode = "Duplex"
673                        else :   
674                            defaultduplexmode = "Simplex"
675                    envdm = pjlparser.environment_variables.get("DUPLEX", "")
676                    if envdm :
677                        if envdm.upper() == "ON" :
678                            duplexmode = "Duplex"
679                        else :   
680                            duplexmode = "Simplex"
681                    else :       
682                        duplexmode = oldduplexmode or defaultduplexmode
683                defaultps = pjlparser.default_variables.get("PAPER", "")
684                if defaultps :
685                    defaultpapersize = defaultps
686                envps = pjlparser.environment_variables.get("PAPER", "")
687                if envps :
688                    papersize = envps
689                else :   
690                    if not oldpapersize :
691                        papersize = defaultpapersize
692                    else :   
693                        papersize = oldpapersize
694            else :       
695                if oldpjlcopies == -1 :
696                    pjlcopies = defaultpjlcopies
697                else :   
698                    pjlcopies = oldpjlcopies
699               
700                duplexmode = (page["duplex"] and "Duplex") or oldduplexmode or defaultduplexmode
701                if not oldpapersize :   
702                    papersize = defaultpapersize
703                else :   
704                    papersize = oldpapersize
705                papersize = oldpapersize or page["mediasize"]
706            if page["mediasize"] != "Default" :
707                papersize = page["mediasize"]
708            if not duplexmode :   
709                duplexmode = oldduplexmode or defaultduplexmode
710            oldpjlcopies = pjlcopies   
711            oldduplexmode = duplexmode
712            oldpapersize = papersize
713            copies = pjlcopies * page["copies"]       
714            pagecount += (copies - 1)
715            self.logdebug("%s*%s*%s*%s*%s*%s*BW" % (copies, \
716                                              page["mediatype"], \
717                                              papersize, \
718                                              page["orientation"], \
719                                              page["mediasource"], \
720                                              duplexmode))
721               
722        return pagecount
723        """
724       
725def test() :       
726    """Test function."""
727    if (len(sys.argv) < 2) or ((not sys.stdin.isatty()) and ("-" not in sys.argv[1:])) :
728        sys.argv.append("-")
729    totalsize = 0   
730    for arg in sys.argv[1:] :
731        if arg == "-" :
732            infile = sys.stdin
733            mustclose = 0
734        else :   
735            infile = open(arg, "rb")
736            mustclose = 1
737        try :
738            parser = Parser(infile, debug=1)
739            totalsize += parser.getJobSize()
740        except pdlparser.PDLParserError, msg :   
741            sys.stderr.write("ERROR: %s\n" % msg)
742            sys.stderr.flush()
743        if mustclose :   
744            infile.close()
745    print "%s" % totalsize
746   
747if __name__ == "__main__" :   
748    test()
Note: See TracBrowser for help on using the browser.