[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