1 | #!/usr/bin/python |
---|
2 | """Debathena lpr wrapper script. |
---|
3 | |
---|
4 | A script that intelligently determines whether a command was intended |
---|
5 | for CUPS or LPRng and sends it off in the right direction |
---|
6 | """ |
---|
7 | |
---|
8 | |
---|
9 | import getopt |
---|
10 | import os |
---|
11 | import shlex |
---|
12 | import sys |
---|
13 | |
---|
14 | from debathena.printing import common |
---|
15 | |
---|
16 | |
---|
17 | opts = { |
---|
18 | common.SYSTEM_CUPS: 'EH:U:P:#:hlmo:pqrC:J:T:', |
---|
19 | common.SYSTEM_LPRNG: 'ABblC:D:F:Ghi:kJ:K:#:m:NP:rR:sT:U:Vw:X:YZ:z1:2:3:4:', |
---|
20 | } |
---|
21 | |
---|
22 | |
---|
23 | def translate_lprng_args_to_cups(args): |
---|
24 | # TODO yell at user if/when we decide that these args are deprecated |
---|
25 | |
---|
26 | # If getopt fails, something went very wrong -- _we_ generated this |
---|
27 | options, realargs = getopt.gnu_getopt(args, opts[common.SYSTEM_LPRNG]) |
---|
28 | cupsargs = [] |
---|
29 | for (o, a) in options: |
---|
30 | if o in ('-b', '-l'): |
---|
31 | cupsargs += [('-l', a)] |
---|
32 | elif o in ('-h'): |
---|
33 | cupsargs += [('-h', a)] |
---|
34 | elif o in ('-J'): |
---|
35 | cupsargs += [('-J', a)] |
---|
36 | elif o in ('-K', '-#'): |
---|
37 | cupsargs += [('-#', a)] |
---|
38 | elif o in ('-P'): |
---|
39 | cupsargs += [('-P', a)] |
---|
40 | elif o in ('-T'): |
---|
41 | cupsargs += [('-T', a)] |
---|
42 | elif o in ('-U'): |
---|
43 | cupsargs += [('-U', a)] |
---|
44 | elif o in ('-Z'): |
---|
45 | if a == 'simplex': |
---|
46 | cupsargs += [('-o', 'sides=one-sided')] |
---|
47 | elif a == 'duplex': |
---|
48 | cupsargs += [('-o', 'sides=two-sided-long-edge')] |
---|
49 | elif a == 'duplexshort': |
---|
50 | cupsargs += [('-o', 'sides=two-sided-short-edge')] |
---|
51 | # TODO attempt to deal banner=staff |
---|
52 | elif o in ('-m'): |
---|
53 | # Intentionally drop any argument to -m; zephyrs always go |
---|
54 | # to you |
---|
55 | cupsargs += [('-m', '')] |
---|
56 | else: |
---|
57 | sys.stderr.write("Warning: option %s%s not converted to CUPS\n" |
---|
58 | % (o, a)) |
---|
59 | joincupsargs = [o + a for o, a in cupsargs] + realargs |
---|
60 | return joincupsargs |
---|
61 | |
---|
62 | |
---|
63 | def _main(args): |
---|
64 | args.pop(0) |
---|
65 | |
---|
66 | queue = common.get_default_printer() |
---|
67 | argstyle = None |
---|
68 | try: |
---|
69 | # common.SYSTEMS is a canonical order of preference for |
---|
70 | # printing systems, and order matters to common.parse_args |
---|
71 | optinfos = [(s, opts[s]) for s in common.SYSTEMS] |
---|
72 | |
---|
73 | argstyle, options, arguments = common.parse_args(args, optinfos) |
---|
74 | |
---|
75 | # Find the last queue specified in the arguments |
---|
76 | queue_args, options = common.extract_opt(options, '-P') |
---|
77 | if queue_args: |
---|
78 | queue = queue_args[-1][-1] |
---|
79 | |
---|
80 | # Deal with zephyr notifications |
---|
81 | zephyr_args, options = common.extract_opt(options, '-N') |
---|
82 | if not zephyr_args and os.environ.get('ATHENA_USER'): |
---|
83 | system = common.find_queue(queue)[0] |
---|
84 | if argstyle == common.SYSTEM_LPRNG: |
---|
85 | options.append(('-m', 'zephyr%' + os.environ['ATHENA_USER'])) |
---|
86 | elif system == common.SYSTEM_CUPS: |
---|
87 | options.append(('-m', '')) |
---|
88 | elif system == common.SYSTEM_LPRNG: |
---|
89 | options.append(('-m', 'zephyr%' + os.environ['ATHENA_USER'])) |
---|
90 | |
---|
91 | # Now that we've sliced up the arguments, put them back |
---|
92 | # together |
---|
93 | args = [o + a for o, a in options] + arguments |
---|
94 | except ValueError: |
---|
95 | # parse_args returned None, so we learned nothing. We'll just |
---|
96 | # go with the default queue |
---|
97 | pass |
---|
98 | |
---|
99 | if not queue: |
---|
100 | # We tried and couldn't figure it out, so not our problem |
---|
101 | common.error(2, ("\n" |
---|
102 | "No default printer configured. Specify a -P option, or configure a\n" |
---|
103 | "default printer via e.g. System | Administration | Printing.\n" |
---|
104 | "\n")) |
---|
105 | |
---|
106 | system, server, queue = common.find_queue(queue) |
---|
107 | |
---|
108 | if server == None and common.get_cups_uri(queue) == None: |
---|
109 | # if there's no Hesiod server and no local queue, |
---|
110 | # tell the user they're wrong |
---|
111 | # But let it fall through in case the user is doing |
---|
112 | # stupid things with -h |
---|
113 | sys.stderr.write(("\nWARNING: The print queue '%s' does not appear to exist.\n" |
---|
114 | "If you're trying to print to a cluster or dorm printer,\n" |
---|
115 | "you should now be using the 'mitprint' queue instead.\n" |
---|
116 | "See http://mit.edu/printing/pharos for more information.\n\n" % queue)) |
---|
117 | |
---|
118 | args.insert(0, '-P%s' % queue) |
---|
119 | if os.environ.get('ATHENA_USER'): |
---|
120 | args.insert(0, '-U%s' % os.environ['ATHENA_USER']) |
---|
121 | if server: |
---|
122 | os.environ['CUPS_SERVER'] = server |
---|
123 | if system == common.SYSTEM_CUPS and argstyle == common.SYSTEM_LPRNG: |
---|
124 | args = translate_lprng_args_to_cups(args) |
---|
125 | |
---|
126 | if system == common.SYSTEM_CUPS and 'LPROPT' in os.environ: |
---|
127 | sys.stderr.write("Use of the $LPROPT environment variable is deprecated and\nits contents will be ignored.\nSee http://kb.mit.edu/confluence/x/awCxAQ\n") |
---|
128 | |
---|
129 | common.dispatch_command(system, 'lpr', args) |
---|
130 | |
---|
131 | |
---|
132 | def main(): |
---|
133 | sys.exit(_main(sys.argv)) # pragma: nocover |
---|
134 | |
---|
135 | |
---|
136 | if __name__ == '__main__': |
---|
137 | main() # pragma: nocover |
---|