~ubuntu-branches/ubuntu/vivid/system-config-printer/vivid

« back to all changes in this revision

Viewing changes to postscriptdriver.prov

  • Committer: Package Import Robot
  • Author(s): Till Kamppeter
  • Date: 2014-07-06 09:41:43 UTC
  • mfrom: (1.1.81)
  • Revision ID: package-import@ubuntu.com-20140706094143-yvp3kzo7ti1ghih8
Tags: 1.4.5+20140706-0ubuntu1
* New upstream release
   o GIT 1.4.x snapshot from 6 July 2014
   o Some codec fixes
   o Traceback fixes
   o IPv6 address entry fix
   o Auth info saving improvement
   o Some loop/hang bug fixes
   o Use LockButton for fewer auth dialogs
* 30_newprinter-driver-download-override-false-error-alarm.patch,
  33_dont-use-hp-makeuri-with-non-hp-printers.patch:
  Removed, included upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/bin/bash
 
2
shopt -s execfail
 
3
exec -a "$0" python -- "$@" <(tail -n +4 -- "$0") || exit 0 # -*- python -*-
 
4
 
 
5
## Copyright (C) 2009 Red Hat, Inc.
 
6
## Author: Tim Waugh <twaugh@redhat.com>
 
7
 
 
8
## This program is free software; you can redistribute it and/or modify
 
9
## it under the terms of the GNU General Public License as published by
 
10
## the Free Software Foundation; either version 2 of the License, or
 
11
## (at your option) any later version.
 
12
 
 
13
## This program is distributed in the hope that it will be useful,
 
14
## but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
## GNU General Public License for more details.
 
17
 
 
18
## You should have received a copy of the GNU General Public License
 
19
## along with this program; if not, write to the Free Software
 
20
## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
21
 
 
22
import sys
 
23
 
 
24
try:
 
25
    import cups
 
26
    CAN_EXAMINE_PPDS=True
 
27
except:
 
28
    CAN_EXAMINE_PPDS=False
 
29
 
 
30
from getopt import getopt
 
31
import os
 
32
import posix
 
33
import re
 
34
import shlex
 
35
import signal
 
36
import stat
 
37
import subprocess
 
38
import sys
 
39
import tempfile
 
40
 
 
41
class TimedOut(Exception):
 
42
    def __init__ (self):
 
43
        Exception.__init__ (self, "Timed out")
 
44
 
 
45
class DeviceIDs:
 
46
    def __init__ (self):
 
47
        self.ids = dict()
 
48
 
 
49
    def get_dict (self):
 
50
        return self.ids
 
51
 
 
52
    def get_tags (self):
 
53
        ret = []
 
54
        def squash(x):
 
55
            r = x.lower ()
 
56
            for a in [' ', '(', ')']:
 
57
                r = r.replace (a, '_')
 
58
 
 
59
            return r
 
60
 
 
61
        for mfg, mdlset in self.ids.iteritems ():
 
62
            mfgsquash = squash (mfg)
 
63
            for mdl in mdlset:
 
64
                mdlsquash = squash (mdl)
 
65
                ret.append ("postscriptdriver(%s;%s;)" % (mfgsquash,
 
66
                                                          mdlsquash))
 
67
 
 
68
        return ret
 
69
 
 
70
    def __add__ (self, other):
 
71
        if isinstance(other, DeviceIDs):
 
72
            for omfg, omdlset in other.ids.iteritems ():
 
73
                try:
 
74
                    mdlset = self.ids[omfg]
 
75
                except KeyError:
 
76
                    mdlset = set()
 
77
                    self.ids[omfg] = mdlset
 
78
 
 
79
                mdlset.update (omdlset)
 
80
 
 
81
            return self
 
82
 
 
83
        pieces = other.split (';')
 
84
        mfg = mdl = None
 
85
        for piece in pieces:
 
86
            s = piece.split (":")
 
87
            if len (s) != 2:
 
88
                continue
 
89
            key, value = s
 
90
            key = key.upper ()
 
91
            if key in ["MFG", "MANUFACTURER"]:
 
92
                mfg = value
 
93
            elif key in ["MDL", "MODEL"]:
 
94
                mdl = value
 
95
 
 
96
        if mfg and mdl:
 
97
            try:
 
98
                mdlset = self.ids[mfg]
 
99
            except KeyError:
 
100
                mdlset = set()
 
101
                self.ids[mfg] = mdlset
 
102
 
 
103
            mdlset.add (mdl)
 
104
 
 
105
        return self
 
106
 
 
107
class Driver:
 
108
    def __init__ (self):
 
109
        self.ids = DeviceIDs()
 
110
 
 
111
    def list (self):
 
112
        return self.ids
 
113
 
 
114
class PPDDriver(Driver):
 
115
    def __init__ (self, pathname=None):
 
116
        Driver.__init__ (self)
 
117
        self.pathname = pathname
 
118
 
 
119
    def list (self):
 
120
        if self.pathname != None:
 
121
            self.examine_file (self.pathname)
 
122
 
 
123
        return Driver.list (self)
 
124
 
 
125
    def examine_file (self, path):
 
126
        try:
 
127
            ppd = cups.PPD (path)
 
128
        except RuntimeError:
 
129
            # Not a PPD file.  Perhaps it's a drv file.
 
130
            drv = DrvDriver (path)
 
131
            self.ids += drv.list ()
 
132
            return
 
133
 
 
134
        attr = ppd.findAttr ('1284DeviceID')
 
135
        if attr:
 
136
            self.ids += attr.value
 
137
 
 
138
class DynamicDriver(Driver):
 
139
    def __init__ (self, driver):
 
140
        Driver.__init__ (self)
 
141
        self.driver = driver
 
142
        signal.signal (signal.SIGALRM, self._alarm)
 
143
 
 
144
    def _alarm (self, sig, stack):
 
145
        raise TimedOut
 
146
 
 
147
    def list (self):
 
148
        signal.alarm (60)
 
149
        p = subprocess.Popen ([self.driver, "list"],
 
150
                              stdout=subprocess.PIPE,
 
151
                              stderr=subprocess.PIPE)
 
152
        try:
 
153
            (stdout, stderr) = p.communicate ()
 
154
            signal.alarm (0)
 
155
        except TimedOut:
 
156
            posix.kill (p.pid, signal.SIGKILL)
 
157
            raise
 
158
 
 
159
        if stderr:
 
160
                print >> sys.stderr, stderr
 
161
 
 
162
        ppds = []
 
163
        lines = stdout.split ('\n')
 
164
        for line in lines:
 
165
                l = shlex.split (line)
 
166
                if len (l) < 5:
 
167
                    continue
 
168
                self.ids += l[4]
 
169
 
 
170
        return Driver.list (self)
 
171
 
 
172
class DrvDriver(PPDDriver):
 
173
    def __init__ (self, pathname):
 
174
        PPDDriver.__init__ (self)
 
175
        self.drv = pathname
 
176
 
 
177
    def _alarm (self, sig, stack):
 
178
        raise TimedOut
 
179
 
 
180
    def list (self):
 
181
        tmpdir = os.environ.get ("TMPDIR", "/tmp") + os.path.sep
 
182
        outputdir = tempfile.mkdtemp (dir=tmpdir)
 
183
        
 
184
        argv = [ "ppdc",
 
185
                 "-d", outputdir,
 
186
                 "-I", "/usr/share/cups/ppdc",
 
187
                 self.drv ]
 
188
 
 
189
        signal.alarm (60)
 
190
        p = subprocess.Popen (argv,
 
191
                              stdout=subprocess.PIPE,
 
192
                              stderr=subprocess.PIPE)
 
193
        try:
 
194
            (stdout, stderr) = p.communicate ()
 
195
            signal.alarm (0)
 
196
        except TimedOut:
 
197
            posix.kill (p.pid, signal.SIGKILL)
 
198
            raise
 
199
 
 
200
        os.path.walk (outputdir, self.examine_directory, None)
 
201
        os.rmdir (outputdir)
 
202
        return Driver.list (self)
 
203
 
 
204
    def examine_directory (self, unused, dirname, fnames):
 
205
        for fname in fnames:
 
206
            path = dirname + os.path.sep + fname
 
207
            self.examine_file (path)
 
208
            os.unlink (path)
 
209
 
 
210
class TagBuilder:
 
211
    def __init__ (self, filelist=None):
 
212
        if filelist == None:
 
213
            filelist = sys.stdin
 
214
 
 
215
        paths = map (lambda x: x.rstrip (), filelist.readlines ())
 
216
        self.ids = DeviceIDs ()
 
217
 
 
218
        for path in paths:
 
219
            if path.find ("/usr/lib/cups/driver/") != -1:
 
220
                try:
 
221
                    self.ids += DynamicDriver (path).list ()
 
222
                except TimedOut:
 
223
                    pass
 
224
 
 
225
        if CAN_EXAMINE_PPDS:
 
226
            candidates = set()
 
227
            symlinks = set()
 
228
            for searchpath in ["/usr/share/cups/model/",
 
229
                               "/usr/share/ppd/",
 
230
                               "/usr/share/cups/drv/"]:
 
231
                for path in paths:
 
232
                    if path.find (searchpath) != -1:
 
233
                        st = os.lstat (path)
 
234
                        if stat.S_ISLNK (st.st_mode):
 
235
                            symlinks.add (path)
 
236
                        elif stat.S_ISREG (st.st_mode):
 
237
                            candidates.add (path)
 
238
 
 
239
            # Now check for symlinks (just one level)
 
240
            for each in symlinks:
 
241
                target = os.path.realpath (each)
 
242
                if target in candidates:
 
243
                    continue
 
244
 
 
245
                try:
 
246
                    st = os.lstat (target)
 
247
                except OSError:
 
248
                    continue
 
249
 
 
250
                if stat.S_ISREG (st.st_mode):
 
251
                    candidates.add (target)
 
252
                elif stat.S_ISDIR (st.st_mode):
 
253
                    if not target.endswith (os.path.sep):
 
254
                        target += os.path.sep
 
255
 
 
256
                    for path in paths:
 
257
                        if path.find (target) != -1:
 
258
                            st = os.lstat (path)
 
259
                            if stat.S_ISREG (st.st_mode):
 
260
                                candidates.add (path)
 
261
 
 
262
            for path in candidates:
 
263
                try:
 
264
                    self.ids += PPDDriver (path).list ()
 
265
                except TimedOut:
 
266
                    pass
 
267
 
 
268
    def get_tags (self):
 
269
        return self.ids.get_tags ()
 
270
 
 
271
if __name__ == "__main__":
 
272
    builder = TagBuilder ()
 
273
    tags = builder.get_tags ()
 
274
    for tag in tags:
 
275
        print tag