1
2
3
4 __doc__ = """GNUmed printing."""
5
6 __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
7 __license__ = 'GPL v2 or later (details at http://www.gnu.org)'
8
9 import logging
10 import sys
11 import os
12 import subprocess
13 import io
14 import time
15
16
17 if __name__ == '__main__':
18 sys.path.insert(0, '../../')
19 from Gnumed.pycommon import gmShellAPI
20 from Gnumed.pycommon import gmTools
21 from Gnumed.pycommon import gmLog2
22
23
24 _log = logging.getLogger('gm.printing')
25
26
27 known_printjob_types = [
28 'medication_list',
29 'generic_document'
30 ]
31
32 external_print_APIs = [
33 'gm-print_doc',
34 'os_startfile',
35 'gsprint',
36 'acrobat_reader',
37 'gtklp',
38 'Internet_Explorer',
39 'Mac_Preview'
40 ]
41
42
43
44
45 -def print_files(filenames=None, jobtype=None, print_api=None):
46
47 _log.debug('printing "%s": %s', jobtype, filenames)
48
49 for fname in filenames:
50 try:
51 open(fname, 'r').close()
52 except:
53 _log.exception('cannot open [%s], aborting', fname)
54 return False
55
56 if jobtype not in known_printjob_types:
57 print("unregistered print job type <%s>" % jobtype)
58 _log.warning('print job type "%s" not registered', jobtype)
59
60 if print_api not in external_print_APIs:
61 _log.warning('print API "%s" unknown, trying all', print_api)
62
63 if print_api == 'os_startfile':
64 return _print_files_by_os_startfile(filenames = filenames)
65 elif print_api == 'gm-print_doc':
66 return _print_files_by_shellscript(filenames = filenames, jobtype = jobtype)
67 elif print_api == 'gsprint':
68 return _print_files_by_gsprint_exe(filenames = filenames)
69 elif print_api == 'acrobat_reader':
70 return _print_files_by_acroread_exe(filenames = filenames)
71 elif print_api == 'gtklp':
72 return _print_files_by_gtklp(filenames = filenames)
73 elif print_api == 'Internet_Explorer':
74 return _print_files_by_IE(filenames = filenames)
75 elif print_api == 'Mac_Preview':
76 return _print_files_by_mac_preview(filenames = filenames)
77
78
79 if (sys.platform == 'darwin') or (os.name == 'mac'):
80 if _print_files_by_mac_preview(filenames = filenames):
81 return True
82 elif os.name == 'posix':
83 if _print_files_by_gtklp(filenames = filenames):
84 return True
85 elif os.name == 'nt':
86 if _print_files_by_shellscript(filenames = filenames, jobtype = jobtype):
87 return True
88 if _print_files_by_gsprint_exe(filenames = filenames):
89 return True
90 if _print_files_by_acroread_exe(filenames = filenames):
91 return True
92 if _print_files_by_os_startfile(filenames = filenames):
93 return True
94 if _print_files_by_IE(filenames = filenames):
95 return True
96 return False
97
98 if _print_files_by_shellscript(filenames = filenames, jobtype = jobtype):
99 return True
100
101 return False
102
103
104
106
107
108 if sys.platform != 'darwin':
109 _log.debug('MacOSX <open> only available under MacOSX/Darwin')
110 return False
111
112 for filename in filenames:
113 cmd_line = [
114 r'open',
115 r'-a Preview',
116 filename
117 ]
118 _log.debug('printing with %s' % cmd_line)
119 try:
120 mac_preview = subprocess.Popen(cmd_line)
121 except OSError:
122 _log.debug('cannot run <open -a Preview>')
123 return False
124 mac_preview.communicate()
125 if mac_preview.returncode != 0:
126 _log.error('<open -a Preview> returned [%s], failed to print', mac_preview.returncode)
127 return False
128
129 return True
130
132
133 if os.name != 'nt':
134 _log.debug('Internet Explorer only available under Windows')
135 return False
136
137 try:
138 from win32com import client as dde_client
139 except ImportError:
140 _log.exception('<win32com> Python module not available for use in printing')
141 return False
142
143 try:
144 i_explorer = dde_client.Dispatch("InternetExplorer.Application")
145 for filename in filenames:
146 if i_explorer.Busy:
147 time.sleep(1)
148 i_explorer.Navigate(os.path.normpath(filename))
149 if i_explorer.Busy:
150 time.sleep(1)
151 i_explorer.Document.printAll()
152 i_explorer.Quit()
153 except:
154 _log.exception('error calling IE via DDE')
155 return False
156
157 return True
158
160
161
162 if sys.platform != 'linux2':
163 _log.debug('<gtklp> only available under Linux')
164 return False
165
166 cmd_line = [
167 r'gtklp',
168 r'-i',
169 r'-# 1'
170 ]
171 cmd_line.extend(filenames)
172 _log.debug('printing with %s' % cmd_line)
173 try:
174 gtklp = subprocess.Popen(cmd_line)
175 except OSError:
176 _log.debug('cannot run <gtklp>')
177 return False
178 gtklp.communicate()
179 if gtklp.returncode != 0:
180 _log.error('<gtklp> returned [%s], failed to print', gtklp.returncode)
181 return False
182
183 return True
184
186 """Use gsprint.exe from Ghostscript tools. Windows only.
187
188 - docs: http://pages.cs.wisc.edu/~ghost/gsview/gsprint.htm
189 - download: http://www.cs.wisc.edu/~ghost/
190 """
191 if os.name != 'nt':
192 _log.debug('<gsprint.exe> only available under Windows')
193 return False
194
195 conf_filename = gmTools.get_unique_filename (
196 prefix = 'gm2gsprint-',
197 suffix = '.cfg'
198 ).encode(sys.getfilesystemencoding())
199
200 for filename in filenames:
201 conf_file = io.open(conf_filename, mode = 'wt', encoding = 'utf8')
202 conf_file.write('-color\n')
203 conf_file.write('-query\n')
204 conf_file.write('-all\n')
205 conf_file.write('-copies 1\n')
206 conf_file.write('%s\n' % os.path.normpath(filename))
207 conf_file.close()
208
209 cmd_line = [
210 r'gsprint.exe',
211 r'-config "%s"' % conf_filename
212 ]
213 _log.debug('printing with %s' % cmd_line)
214 try:
215 gsprint_process = subprocess.Popen(cmd_line)
216 except OSError:
217 _log.debug('cannot run <gsprint.exe>')
218 return False
219 gsprint_process.communicate()
220 if gsprint_process.returncode != 0:
221 _log.error('<gsprint.exe> returned [%s], failed to print', gsprint_process.returncode)
222 return False
223
224 return True
225
227 """Use Adobe Acrobat Reader. Windows only.
228
229 - docs: http://www.robvanderwoude.com/printfiles.php#PrintPDF
230 """
231 if os.name != 'nt':
232 _log.debug('Acrobat Reader only used under Windows')
233 return False
234
235 for filename in filenames:
236 cmd_line = [
237 r'AcroRd32.exe',
238 r'/s',
239 r'/o',
240 r'/h',
241 r'/p',
242 os.path.normpath(filename)
243 ]
244 _log.debug('printing with %s' % cmd_line)
245 try:
246 acroread = subprocess.Popen(cmd_line)
247 except OSError:
248 _log.debug('cannot run <AcroRd32.exe>')
249 cmd_line[0] = r'acroread.exe'
250 _log.debug('printing with %s' % cmd_line)
251 try:
252 acroread = subprocess.Popen(cmd_line)
253 except OSError:
254 _log.debug('cannot run <acroread.exe>')
255 return False
256
257 acroread.communicate()
258 if acroread.returncode != 0:
259 _log.error('Acrobat Reader returned [%s], failed to print', acroread.returncode)
260 return False
261
262 return True
263
265
266 try:
267 os.startfile
268 except AttributeError:
269 _log.error('platform does not support "os.startfile()"')
270 return False
271
272 _log.debug('printing [%s]', filenames)
273
274 for filename in filenames:
275 fname = os.path.normcase(os.path.normpath(filename))
276 _log.debug('%s -> %s', filename, fname)
277 try:
278 try:
279 os.startfile(fname, 'print')
280 except WindowsError as e:
281 _log.exception('no <print> action defined for this type of file')
282 if e.winerror == 1155:
283 os.startfile(fname)
284 except:
285 _log.exception('os.startfile() failed')
286 gmLog2.log_stack_trace()
287 return False
288
289 return True
290
292
293 paths = gmTools.gmPaths()
294 local_script = os.path.join(paths.local_base_dir, '..', 'external-tools', 'gm-print_doc')
295
296
297 candidates = ['gm-print_doc', local_script, 'gm-print_doc.bat']
298 found, binary = gmShellAPI.find_first_binary(binaries = candidates)
299 if not found:
300 binary = r'gm-print_doc.bat'
301
302 cmd_line = [
303 binary,
304 jobtype
305 ]
306 cmd_line.extend(filenames)
307 _log.debug('printing with %s', cmd_line)
308 try:
309 gm_print_doc = subprocess.Popen(cmd_line)
310 except OSError:
311 _log.debug('cannot run <gm_print_doc(.bat)>')
312 return False
313 gm_print_doc.communicate()
314 if gm_print_doc.returncode != 0:
315 _log.error('<gm_print_doc> returned [%s], failed to print', gm_print_doc.returncode)
316 return False
317
318 return True
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336 if __name__ == '__main__':
337
338 if len(sys.argv) < 2:
339 sys.exit()
340
341 if sys.argv[1] != 'test':
342 sys.exit()
343
344 from Gnumed.pycommon import gmLog2
345 from Gnumed.pycommon import gmI18N
346 gmI18N.activate_locale()
347 gmI18N.install_domain()
348
349
351 return print_files(filenames = [sys.argv[2]], jobtype = sys.argv[3])
352
354 print_files(filenames = [sys.argv[2], sys.argv[2]], jobtype = 'generic_document', print_api = 'gm-print_doc')
355
357 print_files(filenames = [sys.argv[2], sys.argv[2]], jobtype = 'generic_document', print_api = 'gtklp')
358
360 print("testing printing via Mac Preview")
361 _print_files_by_mac_preview(filenames = [sys.argv[0]])
362
363 print(test_print_files())
364
365
366
367
368