Simple accounting filter/backend (With Perl or another script language)

Nayco (.free.fr) nayco at spam.me
Thu Oct 28 03:15:12 PDT 2004


Jerome Alet wrote:
> Don't worry, PyKota doesn't handle this sort of things for PostScript.
> I just said this because I think some jobs like that are possible,
> but I've never seen one myself.

Ok, I made my code take that into account by summing up the number of copies for each page.

> For now, the PostScript parser uses max(1, max(allnumcopiesseen)) as the global number of copies, and multiplies by number of pages. This may overcharge the user, but at least not undercharge and that's what we want ;-)

I dunnit an other way, but this can be useful depending on the test results...

> PyKota's PCL parsers (3,4,5, and then XL/6) correctly handle this on a page per page basis though, excepted if the number of copies is set not in PCL but in PJL instead (this will be fixed some day)

> As you can see, it's a difficult problem... (and PJL can appear in ostScript too if I'm not mistaken)

Well, I see :( ... And worst of all, I still don't handle PCL or other languages... Anyway, for PS, it's getting better. Ok, next shot :

1  #!/usr/bin/perl -w
2
3  use strict;
4
5
6
7  sub count_pages {
8    # Get the name of the file to analyse
9    my $doc=shift;
10
11    # Declare the output vars
12    my ($page_num_pages,$page_num_copies,$copies_num_copies,$page_bbox)=(0,0,0,0);
13
14
15    open DOC, $doc;
16    while (<DOC>){
17      if( $_ =~ m/^%%Pages:\s+([0-9]+)$/ ){
18        $page_num_pages=$1;
19      }
20      if ( $_ =~ m/1\s+dict\s+dup\s+\/NumCopies\s+([0-9]+)\s+/ ){
21        $copies_num_copies=$1;
22        $page_num_copies++;
23      }
24    }
25
26    # This command is used to count the pages of $doc.
27    my $page_bbox_cmd = "/usr/bin/gs -sDEVICE=bbox -dNOPAUSE -c save pop -f ".$doc." -c quit 2>&1";
28
29    # Launch it, and process its output to get the number of pages in the job.
30    my $page_bbox_result = `$page_bbox_cmd`;
31    if (!defined $page_bbox_result || !$!){
32      die "$0: Unable to count pages with bbox method !\n";
33    }
34
35    foreach my $page_bbox_line ( $page_bbox_result ){
36      if ($page_bbox_line =~ m/%%BoundingBox/){
37        $page_bbox++;
38      }
39    }
40
41    print "Page count data:\n  page_num_pages: $page_num_pages\n  copies_num_copies: $copies_num_copies\n";
42    print "  page_num_copies: $page_num_copies\n  page_bbox: $page_bbox\n";
43  }
44
45
46  foreach my $file (@ARGV) {
47    print "* Fichier: $file\n";
48    count_pages $file;
49  }

Results with a few PS files (Web pages from konqueror or mozilla printed into a PS file)

* Fichier: 3pages-1copie-2perpage-black.ps
Page count data:
  page_num_pages: 3
  copies_num_copies: 0
  page_num_copies: 0
  page_bbox: 1
* Fichier: 3pages-1copie-2perpage-black_2.ps
Page count data:
  page_num_pages: 3
  copies_num_copies: 0
  page_num_copies: 0
  page_bbox: 1
* Fichier: 3pages-1copie-black.ps
Page count data:
  page_num_pages: 3
  copies_num_copies: 0
  page_num_copies: 0
  page_bbox: 1
* Fichier: 3pages-1copie-color.ps
Page count data:
  page_num_pages: 3
  copies_num_copies: 0
  page_num_copies: 0
  page_bbox: 1
* Fichier: 3pages-1copie-black_2.ps
Page count data:
  page_num_pages: 3
  copies_num_copies: 0
  page_num_copies: 0
  page_bbox: 1
* Fichier: 3pages-56copies-black.ps
Page count data:
  page_num_pages: 3
  copies_num_copies: 56
  page_num_copies: 1
  page_bbox: 1
* Fichier: autonomy.ps
Page count data:
  page_num_pages: 4
  copies_num_copies: 0
  page_num_copies: 0
  page_bbox: 1
* Fichier: toto.ps (37 copies - 2 pages)
Page count data:
  page_num_pages: 2
  total_num_copies: 74
  page_num_copies: 2
  page_bbox: 1

So, this seem to work with basic PS documents... Interesting things:
- bbox always fucks up, but hey!, we're not inside th Cups chain here, and the document has not been formatted for a particular printer.
- NumCopies appears in the documents for which we asked several copies... And seems reliable. Does not appear in single copies documents.
- %%Pages is always right when only one copy of the document has been requested.

Ok, now I gonna put this function in the main script, run a bunch of printings, and look at the results...





More information about the cups mailing list