|
|
a6bd2b8 |
#!/usr/bin/python
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
## gutenprint-foomaticppdupdate
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
## A utility for updating foomatic-generated PPDs so that they work with
|
|
|
a6bd2b8 |
## a newly-installed gutenprint package.
|
|
|
a6bd2b8 |
|
|
|
4e06115 |
## Copyright (C) 2007, 2009 Red Hat, Inc.
|
|
|
4e06115 |
## Copyright (C) 2007, 2009 Tim Waugh
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
## This program is free software; you can redistribute it and/or modify
|
|
|
a6bd2b8 |
## it under the terms of the GNU General Public License as published by
|
|
|
a6bd2b8 |
## the Free Software Foundation; either version 2 of the License, or
|
|
|
a6bd2b8 |
## (at your option) any later version.
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
## This program is distributed in the hope that it will be useful,
|
|
|
a6bd2b8 |
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
a6bd2b8 |
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
a6bd2b8 |
## GNU General Public License for more details.
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
## You should have received a copy of the GNU General Public License
|
|
|
a6bd2b8 |
## along with this program; if not, write to the Free Software
|
|
|
a6bd2b8 |
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
import sys
|
|
|
a6bd2b8 |
import glob
|
|
|
a6bd2b8 |
import os
|
|
|
54d7644 |
import subprocess
|
|
|
a6bd2b8 |
import tempfile
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
import cups
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
if len (sys.argv) < 2 or sys.argv[1] == "--help":
|
|
|
a6bd2b8 |
print "Usage: gutenprint-foomaticppdupdate <version>"
|
|
|
a6bd2b8 |
sys.exit (1)
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
gutenprint_version = sys.argv[1]
|
|
|
a6bd2b8 |
dry_run = True
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
def generate_ppd (ppdfile, printer, driver):
|
|
|
54d7644 |
p = subprocess.Popen (["foomatic-ppdfile", "-p", printer, "-d", driver],
|
|
|
54d7644 |
stdin=file ("/dev/null"),
|
|
|
54d7644 |
stdout=subprocess.PIPE,
|
|
|
54d7644 |
stderr=subprocess.PIPE)
|
|
|
54d7644 |
(ppd, stderr) = p.communicate ()
|
|
|
a6bd2b8 |
fname = ppdfile + ".tmp"
|
|
|
a6bd2b8 |
try:
|
|
|
54d7644 |
file(fname, "w").write (ppd)
|
|
|
a6bd2b8 |
except IOError, e:
|
|
|
a6bd2b8 |
print e
|
|
|
a6bd2b8 |
raise
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
ppdobj = cups.PPD (fname)
|
|
|
a6bd2b8 |
os.remove (fname)
|
|
|
a6bd2b8 |
return ppdobj
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
def update_ppdfile (ppdfile):
|
|
|
cb7a209 |
try:
|
|
|
cb7a209 |
ppd = cups.PPD (ppdfile)
|
|
|
cb7a209 |
except RuntimeError:
|
|
|
cb7a209 |
# Invalid PPD in some way.
|
|
|
cb7a209 |
return
|
|
|
cb7a209 |
|
|
|
a6bd2b8 |
attr = ppd.findAttr ("FoomaticIDs")
|
|
|
a6bd2b8 |
if not attr:
|
|
|
a6bd2b8 |
return
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
IDs = attr.value.split (" ")
|
|
|
a6bd2b8 |
if len (IDs) != 2:
|
|
|
a6bd2b8 |
print "Don't understand FoomaticIDs: %s" % IDs
|
|
|
a6bd2b8 |
return
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
if not IDs[1].startswith ("gutenprint"):
|
|
|
a6bd2b8 |
return
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
attr = ppd.findAttr ("FoomaticRIPCommandLine")
|
|
|
a6bd2b8 |
if not attr:
|
|
|
a6bd2b8 |
return
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
cmdline = attr.value
|
|
|
a6bd2b8 |
STP_VERSION="STP_VERSION="
|
|
|
a6bd2b8 |
i = cmdline.find (STP_VERSION)
|
|
|
a6bd2b8 |
if i == -1:
|
|
|
a6bd2b8 |
return
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
i += len (STP_VERSION)
|
|
|
a6bd2b8 |
j = i + 1
|
|
|
a6bd2b8 |
end = len (cmdline)
|
|
|
a6bd2b8 |
while j < end:
|
|
|
a6bd2b8 |
ch = cmdline[j]
|
|
|
a6bd2b8 |
if ch != '.' and not ch.isdigit ():
|
|
|
a6bd2b8 |
break
|
|
|
a6bd2b8 |
j += 1
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
version = cmdline[i:j]
|
|
|
a6bd2b8 |
if gutenprint_version == version:
|
|
|
a6bd2b8 |
return
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
# Needs updating.
|
|
|
4e06115 |
firstdot = gutenprint_version.find ('.')
|
|
|
4e06115 |
seconddot = firstdot + 1 + gutenprint_version[1 + firstdot:].find ('.')
|
|
|
4e06115 |
major = gutenprint_version[:seconddot]
|
|
|
4e06115 |
|
|
|
4e06115 |
driver = IDs[1]
|
|
|
4e06115 |
dot = driver.find ('.')
|
|
|
4e06115 |
driver = driver[:dot] + "." + major
|
|
|
a6bd2b8 |
try:
|
|
|
4e06115 |
genppd = generate_ppd (ppdfile, IDs[0], driver)
|
|
|
a6bd2b8 |
except:
|
|
|
a6bd2b8 |
return
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
os.environ['FILE'] = ppdfile
|
|
|
a6bd2b8 |
os.system ('cp -af "$FILE" "$FILE".bak')
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
def update_options (options, newppd, origppd):
|
|
|
a6bd2b8 |
for newopt in options:
|
|
|
a6bd2b8 |
origopt = origppd.findOption (newopt.keyword)
|
|
|
a6bd2b8 |
if origopt:
|
|
|
a6bd2b8 |
newppd.markOption (newopt.keyword, origopt.defchoice)
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
genppd.markDefaults ()
|
|
|
a6bd2b8 |
for group in genppd.optionGroups:
|
|
|
a6bd2b8 |
update_options (group.options, genppd, ppd)
|
|
|
a6bd2b8 |
for subgroup in group.subgroups:
|
|
|
a6bd2b8 |
update_options (subgroup.options, genppd, ppd)
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
ps = genppd.findOption ("PageSize")
|
|
|
a6bd2b8 |
if ps:
|
|
|
a6bd2b8 |
update_options ([ps], genppd, ppd)
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
f = file (ppdfile, "w")
|
|
|
a6bd2b8 |
genppd.writeFd (f.fileno ())
|
|
|
a6bd2b8 |
print "Updated PPD file %s" % ppdfile
|
|
|
a6bd2b8 |
|
|
|
a6bd2b8 |
for ppdfile in glob.glob ("/etc/cups/ppd/*.ppd"):
|
|
|
a6bd2b8 |
update_ppdfile (ppdfile)
|