gutenprint-foomaticppdupdate 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #!/usr/bin/python
  2. ## gutenprint-foomaticppdupdate
  3. ## A utility for updating foomatic-generated PPDs so that they work with
  4. ## a newly-installed gutenprint package.
  5. ## Copyright (C) 2007, 2009 Red Hat, Inc.
  6. ## Copyright (C) 2007, 2009 Tim Waugh <twaugh@redhat.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. ## This program is distributed in the hope that it will be useful,
  12. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ## GNU General Public License for more details.
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. import sys
  19. import glob
  20. import os
  21. import subprocess
  22. import tempfile
  23. import cups
  24. if len (sys.argv) < 2 or sys.argv[1] == "--help":
  25. print "Usage: gutenprint-foomaticppdupdate <version>"
  26. sys.exit (1)
  27. gutenprint_version = sys.argv[1]
  28. dry_run = True
  29. def generate_ppd (ppdfile, printer, driver):
  30. p = subprocess.Popen (["foomatic-ppdfile", "-p", printer, "-d", driver],
  31. stdin=file ("/dev/null"),
  32. stdout=subprocess.PIPE,
  33. stderr=subprocess.PIPE)
  34. (ppd, stderr) = p.communicate ()
  35. fname = ppdfile + ".tmp"
  36. try:
  37. file(fname, "w").write (ppd)
  38. except IOError, e:
  39. print e
  40. raise
  41. ppdobj = cups.PPD (fname)
  42. os.remove (fname)
  43. return ppdobj
  44. def update_ppdfile (ppdfile):
  45. try:
  46. ppd = cups.PPD (ppdfile)
  47. except RuntimeError:
  48. # Invalid PPD in some way.
  49. return
  50. attr = ppd.findAttr ("FoomaticIDs")
  51. if not attr:
  52. return
  53. IDs = attr.value.split (" ")
  54. if len (IDs) != 2:
  55. print "Don't understand FoomaticIDs: %s" % IDs
  56. return
  57. if not IDs[1].startswith ("gutenprint"):
  58. return
  59. attr = ppd.findAttr ("FoomaticRIPCommandLine")
  60. if not attr:
  61. return
  62. cmdline = attr.value
  63. STP_VERSION="STP_VERSION="
  64. i = cmdline.find (STP_VERSION)
  65. if i == -1:
  66. return
  67. i += len (STP_VERSION)
  68. j = i + 1
  69. end = len (cmdline)
  70. while j < end:
  71. ch = cmdline[j]
  72. if ch != '.' and not ch.isdigit ():
  73. break
  74. j += 1
  75. version = cmdline[i:j]
  76. if gutenprint_version == version:
  77. return
  78. # Needs updating.
  79. firstdot = gutenprint_version.find ('.')
  80. seconddot = firstdot + 1 + gutenprint_version[1 + firstdot:].find ('.')
  81. major = gutenprint_version[:seconddot]
  82. driver = IDs[1]
  83. dot = driver.find ('.')
  84. driver = driver[:dot] + "." + major
  85. try:
  86. genppd = generate_ppd (ppdfile, IDs[0], driver)
  87. except:
  88. return
  89. os.environ['FILE'] = ppdfile
  90. os.system ('cp -af "$FILE" "$FILE".bak')
  91. def update_options (options, newppd, origppd):
  92. for newopt in options:
  93. origopt = origppd.findOption (newopt.keyword)
  94. if origopt:
  95. newppd.markOption (newopt.keyword, origopt.defchoice)
  96. genppd.markDefaults ()
  97. for group in genppd.optionGroups:
  98. update_options (group.options, genppd, ppd)
  99. for subgroup in group.subgroups:
  100. update_options (subgroup.options, genppd, ppd)
  101. ps = genppd.findOption ("PageSize")
  102. if ps:
  103. update_options ([ps], genppd, ppd)
  104. f = file (ppdfile, "w")
  105. genppd.writeFd (f.fileno ())
  106. print "Updated PPD file %s" % ppdfile
  107. for ppdfile in glob.glob ("/etc/cups/ppd/*.ppd"):
  108. update_ppdfile (ppdfile)