[python-cups] Moved postscriptdriver RPM tagging machinery here. Fixed leading/trailing whitespace in tags as wel

Tim Waugh twaugh at fedoraproject.org
Thu Jan 20 10:56:55 UTC 2011


commit 7d3766acd5693ad1577bff2775bcebd134fa1282
Author: Tim Waugh <twaugh at redhat.com>
Date:   Thu Jan 20 10:46:14 2011 +0000

    Moved postscriptdriver RPM tagging machinery here.  Fixed leading/trailing whitespace in tags as well.

 postscriptdriver.prov |  259 +++++++++++++++++++++++++++++++++++++++++++++++++
 psdriver.attr         |    3 +
 python-cups.spec      |   16 +++-
 3 files changed, 277 insertions(+), 1 deletions(-)
---
diff --git a/postscriptdriver.prov b/postscriptdriver.prov
new file mode 100755
index 0000000..1e6ccad
--- /dev/null
+++ b/postscriptdriver.prov
@@ -0,0 +1,259 @@
+#!/usr/bin/python
+
+## Copyright (C) 2009, 2010 Red Hat, Inc.
+## Author: Tim Waugh <twaugh at redhat.com>
+
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sys
+
+try:
+    import cups
+    CAN_EXAMINE_PPDS = True
+except:
+    CAN_EXAMINE_PPDS = False
+
+from getopt import getopt
+import errno
+import os
+import posix
+import re
+import shlex
+import signal
+import subprocess
+import sys
+import tempfile
+
+if len (sys.argv) > 1:
+    RPM_BUILD_ROOT = sys.argv[1]
+else:
+    RPM_BUILD_ROOT = None
+
+class TimedOut(Exception):
+    def __init__ (self):
+        Exception.__init__ (self, "Timed out")
+
+class DeviceIDs:
+    def __init__ (self):
+        self.ids = dict()
+
+    def get_dict (self):
+        return self.ids
+
+    def get_tags (self):
+        ret = []
+        for mfg, mdlset in self.ids.iteritems ():
+            mfgl = mfg.lower ().replace (" ", "_")
+            for mdl in mdlset:
+                mdll = mdl.lower ().replace (" ", "_")
+                ret.append ("postscriptdriver(%s;%s;)" % (mfgl,
+                                                          mdll))
+
+        return ret
+
+    def __add__ (self, other):
+        if isinstance(other, DeviceIDs):
+            for omfg, omdlset in other.ids.iteritems ():
+                try:
+                    mdlset = self.ids[omfg]
+                except KeyError:
+                    mdlset = set()
+                    self.ids[omfg] = mdlset
+
+                mdlset.update (omdlset)
+
+            return self
+
+        pieces = other.split (';')
+        mfg = mdl = None
+        for piece in pieces:
+            s = piece.split (":")
+            if len (s) != 2:
+                continue
+            key, value = s
+            key = key.upper ().strip ()
+            if key in ["MFG", "MANUFACTURER"]:
+                mfg = value.strip ()
+            elif key in ["MDL", "MODEL"]:
+                mdl = value.strip ()
+
+        if mfg and mdl:
+            try:
+                mdlset = self.ids[mfg]
+            except KeyError:
+                mdlset = set()
+                self.ids[mfg] = mdlset
+
+            mdlset.add (mdl)
+
+        return self
+
+class Driver:
+    def __init__ (self):
+        self.ids = DeviceIDs()
+
+    def list (self):
+        return self.ids
+
+class PPDDriver(Driver):
+    def __init__ (self, pathname=None):
+        Driver.__init__ (self)
+        self.pathname = pathname
+
+    def list (self):
+        if self.pathname != None:
+            self.examine_file (self.pathname)
+
+        return Driver.list (self)
+
+    def examine_file (self, path):
+        try:
+            ppd = cups.PPD (path)
+        except RuntimeError, e:
+            # Not a PPD file.  Perhaps it's a drv file.
+            drv = DrvDriver (path)
+            self.ids += drv.list ()
+            return
+
+        attr = ppd.findAttr ('1284DeviceID')
+        while attr:
+            self.ids += attr.value
+            attr = ppd.findNextAttr ('1284DeviceID')
+
+class DynamicDriver(Driver):
+    def __init__ (self, driver):
+        Driver.__init__ (self)
+        self.driver = driver
+        signal.signal (signal.SIGALRM, self._alarm)
+
+    def _alarm (self, sig, stack):
+        raise TimedOut
+
+    def list (self):
+        signal.alarm (60)
+        env = os.environ.copy ()
+        if RPM_BUILD_ROOT:
+            buildroot = RPM_BUILD_ROOT
+            if not buildroot.endswith (os.path.sep):
+                buildroot += os.path.sep
+
+            env["DESTDIR"] = RPM_BUILD_ROOT
+            env["LD_LIBRARY_PATH"] = "%susr/lib64:%susr/lib" % (buildroot,
+                                                                buildroot)
+
+        p = subprocess.Popen ([self.driver, "list"],
+                              stdout=subprocess.PIPE,
+                              stderr=subprocess.PIPE,
+                              env=env)
+        try:
+            (stdout, stderr) = p.communicate ()
+            signal.alarm (0)
+        except TimedOut:
+            posix.kill (p.pid, signal.SIGKILL)
+            raise
+
+	if stderr:
+		print >> sys.stderr, stderr
+
+	ppds = []
+	lines = stdout.split ('\n')
+	for line in lines:
+		l = shlex.split (line)
+		if len (l) < 5:
+                    continue
+                self.ids += l[4]
+
+        return Driver.list (self)
+
+class DrvDriver(PPDDriver):
+    def __init__ (self, pathname):
+        PPDDriver.__init__ (self)
+        self.drv = pathname
+
+    def _alarm (self, sig, stack):
+        raise TimedOut
+
+    def list (self):
+        tmpdir = os.environ.get ("TMPDIR", "/tmp") + os.path.sep
+        outputdir = tempfile.mkdtemp (dir=tmpdir)
+        
+        argv = [ "ppdc",
+                 "-d", outputdir,
+                 "-I", "/usr/share/cups/ppdc",
+                 self.drv ]
+
+        signal.alarm (60)
+        try:
+            p = subprocess.Popen (argv,
+                                  stdout=subprocess.PIPE,
+                                  stderr=subprocess.PIPE)
+        except OSError:
+            # ppdc not available.
+            os.rmdir (outputdir)
+            return Driver.list (self)
+
+        try:
+            (stdout, stderr) = p.communicate ()
+            signal.alarm (0)
+        except TimedOut:
+            posix.kill (p.pid, signal.SIGKILL)
+            raise
+
+        os.path.walk (outputdir, self.examine_directory, None)
+        os.rmdir (outputdir)
+        return Driver.list (self)
+
+    def examine_directory (self, unused, dirname, fnames):
+        for fname in fnames:
+            path = dirname + os.path.sep + fname
+            self.examine_file (path)
+            os.unlink (path)
+
+class TagBuilder:
+    def __init__ (self, filelist=None):
+        if filelist == None:
+            filelist = sys.stdin
+
+        paths = map (lambda x: x.rstrip (), filelist.readlines ())
+        self.ids = DeviceIDs ()
+
+        for path in paths:
+            if path.find ("/usr/lib/cups/driver/") != -1:
+                try:
+                    self.ids += DynamicDriver (path).list ()
+                except TimedOut:
+                    pass
+                except OSError, (e, s):
+                    if e == errno.EACCES or e == errno.ENOENT:
+                        # Not executable
+                        pass
+                    else:
+                        raise
+
+        if CAN_EXAMINE_PPDS:
+            for path in paths:
+                try:
+                    self.ids += PPDDriver (path).list ()
+                except TimedOut:
+                    pass
+
+    def get_tags (self):
+        return self.ids.get_tags ()
+
+if __name__ == "__main__":
+    builder = TagBuilder ()
+    tags = builder.get_tags ()
+    for tag in tags:
+        print tag
diff --git a/psdriver.attr b/psdriver.attr
new file mode 100644
index 0000000..66e4037
--- /dev/null
+++ b/psdriver.attr
@@ -0,0 +1,3 @@
+%__psdriver_provides	%{_rpmconfigdir}/postscriptdriver.prov
+%__psdriver_path	^(/usr/lib/cups/driver/.*|%{_datadir}/cups/drv/.*\.drv)$
+%__psdriver_magic	^PPD File.*$
diff --git a/python-cups.spec b/python-cups.spec
index 30ca6db..67df92d 100644
--- a/python-cups.spec
+++ b/python-cups.spec
@@ -6,15 +6,19 @@
 Summary:       Python bindings for CUPS
 Name:          python-cups
 Version:       1.9.53
-Release:       1%{?dist}
+Release:       2%{?dist}
 URL:           http://cyberelk.net/tim/software/pycups/
 Source:        http://cyberelk.net/tim/data/pycups/pycups-%{version}.tar.bz2
+Source2:       psdriver.attr
+Source3:       postscriptdriver.prov
 License:       GPLv2+
 Group:         Development/Languages
 BuildRequires: cups-devel
 BuildRequires: python2-devel
 BuildRequires: epydoc
 
+Conflicts: rpm-build < 4.9.0
+
 %description
 This package provides Python bindings for the CUPS API,
 known as pycups. It was written for use with
@@ -40,17 +44,27 @@ epydoc -o html --html build/lib*/cups.so
 %{__python} setup.py install -O1 --skip-build --root %{buildroot}
 chmod 755 %{buildroot}%{python_sitearch}/cups.so
 
+mkdir -p %{buildroot}%{_rpmconfigdir}/fileattrs
+install -m644 %{SOURCE2} %{buildroot}%{_rpmconfigdir}/fileattrs/
+install -m755 %{SOURCE3} %{buildroot}%{_rpmconfigdir}
+
 %files
 %defattr(-,root,root,-)
 %doc COPYING ChangeLog README NEWS TODO
 %{python_sitearch}/cups.so
 %{python_sitearch}/pycups*.egg-info
+/usr/lib/rpm/fileattrs/psdriver.attr
+%{_rpmconfigdir}/postscriptdriver.prov
 
 %files doc
 %defattr(-,root,root,-)
 %doc examples html
 
 %changelog
+* Thu Jan 20 2011 Tim Waugh <twaugh at redhat.com> - 1.9.53-2
+- Moved postscriptdriver RPM tagging machinery here.  Fixed
+  leading/trailing whitespace in tags as well.
+
 * Wed Dec 15 2010 Tim Waugh <twaugh at redhat.com> - 1.9.53-1
 - 1.9.53 fixing a thread-local storage issue (bug #662805).
 


More information about the scm-commits mailing list