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