Moved postscriptdriver RPM tagging machinery here. Fixed leading/trailing whitespace in tags as well.
This commit is contained in:
parent
92e5970e05
commit
7d3766acd5
259
postscriptdriver.prov
Executable file
259
postscriptdriver.prov
Executable file
@ -0,0 +1,259 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
## Copyright (C) 2009, 2010 Red Hat, Inc.
|
||||
## Author: Tim Waugh <twaugh@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
|
3
psdriver.attr
Normal file
3
psdriver.attr
Normal file
@ -0,0 +1,3 @@
|
||||
%__psdriver_provides %{_rpmconfigdir}/postscriptdriver.prov
|
||||
%__psdriver_path ^(/usr/lib/cups/driver/.*|%{_datadir}/cups/drv/.*\.drv)$
|
||||
%__psdriver_magic ^PPD File.*$
|
@ -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@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@redhat.com> - 1.9.53-1
|
||||
- 1.9.53 fixing a thread-local storage issue (bug #662805).
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user