From 830b8a584925f3152c7efac2009a69fe83f4c5f0 Mon Sep 17 00:00:00 2001 From: Till Kamppeter Date: Mon, 20 Jan 2003 02:48:22 +0000 Subject: Improve association of printers with database entries (preparation for non-interactive print queue generation): - Make use of device ID strings in the Foomatic database - Association of generic printers when PDL (PCL, PCL-XL, PostScript) could be auto-detected - Cleaned up entries from manufacturer-supplied PPDs for PostScript printers to try to match model names of Foomatic entries - Bug fixes on previous association mechanism --- perl-install/printer/main.pm | 59 +++++++++++++- perl-install/printer/printerdrake.pm | 145 +++++++++++++++++++++++++++++------ 2 files changed, 176 insertions(+), 28 deletions(-) (limited to 'perl-install/printer') diff --git a/perl-install/printer/main.pm b/perl-install/printer/main.pm index b45e1f7da..a94f577ab 100644 --- a/perl-install/printer/main.pm +++ b/perl-install/printer/main.pm @@ -383,6 +383,7 @@ sub read_printer_db(;$) { my $inentry = 0; my $indrivers = 0; my $inautodetect = 0; + my $autodetecttype = ""; local $_; while () { chomp; @@ -399,9 +400,31 @@ sub read_printer_db(;$) { } elsif ($inautodetect) { # We are inside the autodetect block of a printers entry # All entries inside this block will be ignored - if (m!^.*\s*$!) { - # End of autodetect block - $inautodetect = 0; + if ($autodetecttype) { + if (m!^.*\s*$!) { + # End of parallel, USB, or SNMP section + $autodetecttype = ""; + } elsif (m!^\s*\s*([^<>]+)\s*\s*$!) { + # Manufacturer + $entry->{devidmake} = $1; + } elsif (m!^\s*\s*([^<>]+)\s*\s*$!) { + # Model + $entry->{devidmodel} = $1; + } elsif (m!^\s*\s*([^<>]+)\s*\s*$!) { + # Description + $entry->{deviddesc} = $1; + } elsif (m!^\s*\s*([^<>]+)\s*\s*$!) { + # Command set + $entry->{devidcmdset} = $1; + } + } else { + if (m!^.*\s*$!) { + # End of autodetect block + $inautodetect = 0; + } elsif (m!^\s*<(parallel|usb|snmp)>\s*$!) { + # Beginning of parallel, USB, or SNMP section + $autodetecttype = $1; + } } } else { if (m!^\s*\s*$!) { @@ -422,6 +445,9 @@ sub read_printer_db(;$) { $driverstr .= " (recommended)"; } $entry->{ENTRY} = "$entry->{make}|$entry->{model}|$driverstr"; + $entry->{ENTRY} =~ s/^CITOH/C.ITOH/i; + $entry->{ENTRY} =~ + s/^KYOCERA[\s\-]*MITA/KYOCERA/i; $entry->{driver} = $driver; # Duplicate contents of $entry because it is multiply entered to the database map { $thedb{$entry->{ENTRY}}{$_} = $entry->{$_} } keys %$entry; @@ -431,6 +457,9 @@ sub read_printer_db(;$) { # Make one entry per printer, with the recommended # driver (manufacturerer|model) $entry->{ENTRY} = "$entry->{make}|$entry->{model}"; + $entry->{ENTRY} =~ s/^CITOH/C.ITOH/i; + $entry->{ENTRY} =~ + s/^KYOCERA[\s\-]*MITA/KYOCERA/i; if ($entry->{defaultdriver}) { $entry->{driver} = $entry->{defaultdriver}; map { $thedb{$entry->{ENTRY}}{$_} = $entry->{$_} } keys %$entry; @@ -1459,9 +1488,30 @@ sub poll_ppd_base { if ($ppd eq "raw") { next } my ($model, $driver); if ($descr) { - if ($descr =~ /^([^,]+), (.*)$/) { + $descr =~ s/\s*Series//i; + $descr =~ s/\((.*?(PostScript|PS).*?)\)/$1/i; + if (($descr =~ /^([^,]+[^,\s])\s+(PS.*)$/i) || + ($descr =~ /^([^,]+[^,\s])\s*(PostScript.*)$/i) || + ($descr =~ + /^([^,]+[^,\s])\s*(\(\d\d\d\d\.\d\d\d\).*)$/i) || + ($descr =~ + /^([^,]+[^,\s])\s*(v\d+\.\d+.*)$/i) || + ($descr =~ /^([^,]+), (.*)$/)) { $model = $1; $driver = $2; + $model =~ s/[\-\s,]+$//; + $driver =~ + s/\b(PS|PostScript\b)/PostScript/gi; + $driver =~ + s/(PostScript)(.*)(PostScript)/$1$2/i; + $driver =~ + s/^\s*(\(\d\d\d\d\.\d\d\d\)|v\d+\.\d+)([,\s]*)(.*)/$3$2$1/; + $driver =~ s/[\-\s,]+$//; + $driver =~ s/^[\-\s,]+//; + if ($driver !~ /[a-z]/i) { + $driver = "PostScript " . $driver; + $driver =~ s/ $//; + } } else { # Some PPDs do not have the ", " part. $model = $descr; @@ -1475,6 +1525,7 @@ sub poll_ppd_base { } $ppd && $mf && $descr and do { my $key = "$mf|$model|$driver" . ($lang && " ($lang)"); + $key =~ s/^KYOCERA[\s\-]*MITA/KYOCERA/i; $thedb{$key}{ppd} = $ppd; $thedb{$key}{driver} = $driver; $thedb{$key}{make} = $mf; diff --git a/perl-install/printer/printerdrake.pm b/perl-install/printer/printerdrake.pm index 81b570ff3..1ad34fbaa 100644 --- a/perl-install/printer/printerdrake.pm +++ b/perl-install/printer/printerdrake.pm @@ -1515,31 +1515,114 @@ sub setup_common { my $descr = ""; foreach (@autodetected) { $device eq $_->{port} or next; - if ($_->{val}{MANUFACTURER} && $_->{val}{MODEL}) { - $descr = "$_->{val}{MANUFACTURER}|$_->{val}{MODEL}"; + my ($automake, $automodel, $autodescr, $autocmdset, $autosku) = + ($_->{val}{MANUFACTURER}, $_->{val}{MODEL}, + $_->{val}{DESCRIPTION}, $_->{val}{'COMMAND SET'}, + $_->{val}{SKU}); + if ($automake && $autosku) { + $descr = "$automake|$autosku"; + } elsif ($automake && $automodel) { + $descr = "$automake|$automodel"; } else { - $descr = $_->{val}{DESCRIPTION}; + $descr = $autodescr; $descr =~ s/ /\|/; } + $descr =~ s/^$automake\|\s*$automake\s*/$automake\|/; # Clean up the description from noise which makes the best match # difficult - $descr =~ s/Seiko\s+Epson/Epson/; - $descr =~ s/\s+Inc\.//; - $descr =~ s/\s+Corp\.//; - $descr =~ s/\s+SA\.//; - $descr =~ s/\s+S\.\s*A\.//; - $descr =~ s/\s+Ltd\.//; - $descr =~ s/\s+International//; - $descr =~ s/\s+Int\.//; - $descr =~ s/\s+[Ss]eries//; - $descr =~ s/\s+\(?[Pp]rinter\)?$//; + $descr =~ s/Seiko\s+Epson/Epson/i; + $descr =~ s/Kyocera[\s\-]*Mita/Kyocera/i; + $descr =~ s/\s+Inc\.//i; + $descr =~ s/\s+Corp\.//i; + $descr =~ s/\s+SA\.//i; + $descr =~ s/\s+S\.\s*A\.//i; + $descr =~ s/\s+Ltd\.//i; + $descr =~ s/\s+International//i; + $descr =~ s/\s+Int\.//i; + $descr =~ s/\s+[Ss]eries//i; + $descr =~ s/\s+\(?[Pp]rinter\)?$//i; $printer->{DBENTRY} = ""; # Try to find an exact match, check both whether the detected # make|model is in the make|model of the database entry and vice versa # If there is more than one matching database entry, the longest match # counts. - my $matchlength = 0; + my $matchlength = -100; foreach my $entry (keys %printer::main::thedb) { + # Try to match the device ID string of the auto-detection + if ($printer::main::thedb{$entry}{make} =~ /Generic/i) { + # Database entry for generic printer, check printer + # languages (command set) + my $cmd = $printer::main::thedb{$entry}{devidcmd}; + if ($printer::main::thedb{$entry}{model} =~ + m!PCL\s*5/5e!i) { + # Generic PCL 5/5e Printer + if ($autocmdset =~ + /(^|[:,])PCL\s*\-*\s*(5|)([,;]|$)/i) { + if ($matchlength < -50) { + $matchlength = -50; + $printer->{DBENTRY} = $entry; + next; + } + } + } elsif ($printer::main::thedb{$entry}{model} =~ + m!PCL\s*(6|XL)!i) { + # Generic PCL 6/XL Printer + if ($autocmdset =~ + /(^|[:,])PCL\s*\-*\s*(6|XL)([,;]|$)/i) { + if ($matchlength < -40) { + $matchlength = -40; + $printer->{DBENTRY} = $entry; + next; + } + } + } elsif ($printer::main::thedb{$entry}{model} =~ + m!(PostScript)!i) { + # Generic PostScript Printer + if ($autocmdset =~ + /(^|[:,])(PS|POSTSCRIPT)[^:;,]*([,;]|$)/i) { + if ($matchlength < -10) { + $matchlength = -10; + $printer->{DBENTRY} = $entry; + next; + } + } + } + } else { + # "Real" manufacturer, check manufacturer, model, and/or + # description + my $matched = 1; + my ($mfg, $mdl, $des); + if ($mfg = $printer::main::thedb{$entry}{devidmake}) { + $mfg =~ s/Hewlett[-\s_]Packard/HP/; + $mfg =~ s/HEWLETT[-\s_]PACKARD/HP/; + if ($mfg ne $automake) { + $matched = 0; + } + } + if ($mdl = $printer::main::thedb{$entry}{devidmodel}) { + if ($mdl ne $automodel) { + $matched = 0; + } + } + if ($des = $printer::main::thedb{$entry}{deviddesc}) { + $des =~ s/Hewlett[-\s_]Packard/HP/; + $des =~ s/HEWLETT[-\s_]PACKARD/HP/; + if ($des ne $autodescr) { + $matched = 0; + } + } + if ($matched && ($des || ($mfg && $mdl))) { + # Full match to known auto-detection data + $printer->{DBENTRY} = $entry; + $matchlength = 1000; + last; + } + } + # Do not search human-readable make and model names if we had an + # exact match or a match to the auto-detection ID string + next if $matchlength >= 100; + # Try to match the (human-readable) make and model of the + # Foomatic database or of thr PPD file my $dbmakemodel; if ($::expert) { $entry =~ m/^(.*)\|[^\|]*$/; @@ -1547,29 +1630,42 @@ sub setup_common { } else { $dbmakemodel = $entry; } + # Don't try to match if the database entry does not provide + # make and model next unless $dbmakemodel; - $dbmakemodel =~ s/\|/\\\|/; + # If make and model match exactly, we have found the correct + # entry and we can stop searching human-readable makes and + # models + if ($dbmakemodel eq $descr) { + $printer->{DBENTRY} = $entry; + $matchlength = 100; + next; + } my $searchterm = $descr; - $searchterm =~ s/\|/\\\|/; my $lsearchterm = length($searchterm); + $searchterm =~ s/([\\\/\(\)\[\]\|\.\$\@\%\*\?])/\\$1/g; if ($lsearchterm > $matchlength && - $entry =~ m!$searchterm!i) { + $dbmakemodel =~ m!$searchterm!i) { $matchlength = $lsearchterm; $printer->{DBENTRY} = $entry; } - my $ldbmakemodel = length($dbmakemodel); - if ($ldbmakemodel > $matchlength && - $descr =~ m!$dbmakemodel!i) { - $matchlength = $ldbmakemodel; + $searchterm = $dbmakemodel; + $lsearchterm = length($searchterm); + $searchterm =~ s/([\\\/\(\)\[\]\|\.\$\@\%\*\?])/\\$1/g; + if ($lsearchterm > $matchlength && + $descr =~ m!$searchterm!i) { + $matchlength = $lsearchterm; $printer->{DBENTRY} = $entry; } } - $printer->{DBENTRY} ||= bestMatchSentence($descr, keys %printer::main::thedb); + # No matching printer found, try a best match as last mean + $printer->{DBENTRY} ||= bestMatchSentence($descr, keys %printer::main::thedb); # If the manufacturer was not guessed correctly, discard the # guess. $printer->{DBENTRY} =~ /^([^\|]+)\|/; my $guessedmake = lc($1); - if ($descr !~ /$guessedmake/i && + if ($guessedmake !~ /Generic/i && + $descr !~ /$guessedmake/i && ($guessedmake ne "hp" || $descr !~ /Hewlett[\s-]+Packard/i)) { $printer->{DBENTRY} = "" }; @@ -3180,7 +3276,8 @@ sub main { next; }; undef $::Wizard_no_previous; - eval { + eval { + #do { # eval to catch wizard cancel. The wizard stuff should # be in a separate function with steps. see dragw. # (dams) -- cgit v1.2.1