Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#!/usr/bin/env python 

2# This file is part of Xpra. 

3# Copyright (C) 2014-2019 Antoine Martin <antoine@xpra.org> 

4# Xpra is released under the terms of the GNU GPL v2, or, at your option, any 

5# later version. See the file COPYING for details. 

6 

7import os 

8import sys 

9 

10#default implementation uses pycups 

11from xpra.util import envbool, print_nested_dict 

12from xpra.os_util import WIN32 

13from xpra.log import Logger 

14 

15log = Logger("printing") 

16 

17RAW_MODE = envbool("XPRA_PRINTER_RAW", False) 

18 

19 

20def get_printers(): 

21 return {} 

22 

23def get_printer_attributes(_name): 

24 return [] 

25 

26def get_default_printer(): 

27 return None 

28 

29def print_files(printer, filenames, title, options): 

30 raise Exception("no print implementation available") 

31 

32def printing_finished(_printpid): 

33 return True 

34 

35def init_printing(printers_modified_callback=None): #pylint: disable=unused-argument 

36 pass 

37 

38def cleanup_printing(): 

39 pass 

40 

41 

42DEFAULT_MIMETYPES = ["application/pdf", "application/postscript"] 

43 

44MIMETYPES = None 

45def get_mimetypes(): 

46 global MIMETYPES, DEFAULT_MIMETYPES 

47 if MIMETYPES is None: 

48 v = os.environ.get("XPRA_PRINTING_MIMETYPES", ) 

49 if v is not None: 

50 MIMETYPES = v.split(",") 

51 else: 

52 MIMETYPES = DEFAULT_MIMETYPES 

53 if RAW_MODE: 

54 MIMETYPES.append("raw") 

55 #make it easier to test different mimetypes: 

56 PREFERRED_MIMETYPE = os.environ.get("XPRA_PRINTING_PREFERRED_MIMETYPE") 

57 if PREFERRED_MIMETYPE: 

58 if PREFERRED_MIMETYPE in MIMETYPES: 

59 MIMETYPES.remove(PREFERRED_MIMETYPE) 

60 MIMETYPES.insert(0, PREFERRED_MIMETYPE) 

61 else: 

62 log.warn("Warning: ignoring invalid preferred printing mimetype: %s", PREFERRED_MIMETYPE) 

63 log.warn(" allowed mimetypes: %s", MIMETYPES) 

64 log("get_mimetype()=%s", MIMETYPES) 

65 return MIMETYPES 

66 

67 

68def get_info(): 

69 return default_get_info() 

70 

71def default_get_info(): 

72 return { 

73 "mimetypes" : { 

74 "" : get_mimetypes(), 

75 "default" : DEFAULT_MIMETYPES, 

76 } 

77 } 

78 

79 

80#default implementation uses pycups: 

81from xpra.platform import platform_import 

82if not WIN32: 

83 #pycups is not available on win32 

84 try: 

85 from xpra.platform.pycups_printing import ( 

86 get_printers, 

87 print_files, 

88 printing_finished, 

89 init_printing, 

90 cleanup_printing, 

91 get_info, 

92 ) 

93 assert get_printers and print_files and printing_finished and init_printing, cleanup_printing 

94 except Exception as e: 

95 log("cannot load pycups", exc_info=True) 

96 log.warn("Warning: printer forwarding disabled:") 

97 log.warn(" %s", e) 

98 del e 

99 

100platform_import(globals(), "printing", False, 

101 "init_printing", 

102 "cleanup_printing", 

103 "get_printers", 

104 "get_default_printer", 

105 "print_files", 

106 "printing_finished", 

107 "get_info", 

108 "DEFAULT_MIMETYPES") 

109 

110 

111def main(argv): 

112 if "-v" in argv or "--verbose" in argv: 

113 from xpra.log import add_debug_category, enable_debug_for 

114 add_debug_category("printing") 

115 enable_debug_for("printing") 

116 try: 

117 argv.remove("-v") 

118 except ValueError: 

119 pass 

120 try: 

121 argv.remove("--verbose") 

122 except ValueError: 

123 pass 

124 

125 from xpra.util import nonl, pver 

126 def dump_dict(d): 

127 pk = None 

128 try: 

129 for pk,pv in d.items(): 

130 try: 

131 if isinstance(pv, bytes): 

132 sv = pv.decode("utf8") 

133 else: 

134 sv = nonl(pver(pv)) 

135 except Exception as e: 

136 sv = repr(pv) 

137 print(" %s : %s" % (pk.ljust(32), sv)) 

138 except Exception as e: 

139 print(" error on %s: %s" % (pk, e)) 

140 print(" raw attributes: " % d) 

141 def dump_info(d): 

142 print("System Configuration:") 

143 print_nested_dict(d) 

144 def dump_printers(d): 

145 for k in sorted(d.keys()): 

146 v = d[k] 

147 print("Printers:") 

148 print("* %s" % k) 

149 dump_dict(v) 

150 attr = get_printer_attributes(k) 

151 if attr: 

152 print(" attributes:") 

153 for a in attr: 

154 print(" %s" % a) 

155 from xpra.platform import program_context 

156 from xpra.log import enable_color 

157 from xpra.util import csv 

158 with program_context("Printing", "Printing"): 

159 enable_color() 

160 try: 

161 init_printing() 

162 except Exception as e: 

163 print("Error: initializing the printing tool") 

164 print(" %s" % e) 

165 if len(argv)<=1: 

166 dump_printers(get_printers()) 

167 print("") 

168 dump_info(get_info()) 

169 return 0 

170 printers = get_printers() 

171 if not printers: 

172 print("Cannot print: no printers found") 

173 return 1 

174 if len(argv)==2: 

175 filename = argv[1] 

176 if not os.path.exists(filename): 

177 print("Cannot print file '%s': file does not exist" % filename) 

178 return 1 

179 printer = get_default_printer() #pylint: disable=assignment-from-none 

180 if not printer: 

181 printer = list(printers.keys())[0] 

182 if len(printers)>1: 

183 print("More than one printer found: %s", csv(printer.keys())) 

184 print("Using printer '%s'" % printer) 

185 filenames = [filename] 

186 if len(argv)>2: 

187 printer = argv[1] 

188 if printer not in printers: 

189 print("Invalid printer '%s'" % printer) 

190 return 1 

191 filenames = argv[2:] 

192 for filename in filenames: 

193 if not os.path.exists(filename): 

194 print("File '%s' does not exist" % filename) 

195 return 1 

196 print("Printing: %s" % csv(filenames)) 

197 print_files(printer, filenames, "Print Command", {}) 

198 return 0 

199 

200 

201if __name__ == "__main__": 

202 sys.exit(main(sys.argv))