Module Gnumed.pycommon.gmPrinting
GNUmed printing.
Expand source code
"""GNUmed printing."""
__author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
__license__ = 'GPL v2 or later (details at https://www.gnu.org)'
# =======================================================================
import logging
import sys
import os
import time
if __name__ == '__main__':
sys.path.insert(0, '../../')
from Gnumed.pycommon import gmShellAPI
from Gnumed.pycommon import gmTools
from Gnumed.pycommon import gmLog2
_log = logging.getLogger('gm.printing')
KNOWN_PRINTJOB_TYPES = [
'medication_list',
'generic_document'
]
external_print_APIs = [
'gm-print_doc', # locally provided script
'os_startfile', # win, mostly
'gsprint', # win
'acrobat_reader', # win
'gtklp', # Linux
'Internet_Explorer', # win
'Mac_Preview' # MacOSX
]
#=======================================================================
# internal print API
#-----------------------------------------------------------------------
def print_files(filenames:list=None, jobtype:str=None, print_api:str=None, verbose:bool=False) -> bool:
"""Print files.
Args:
filenames: list of files to print
jobtype: type of print job, passed on to print backends
print_api: the print backend to use, will try all backends if None or unknown backend
Returns:
status
"""
_log.debug('printing "%s": %s', jobtype, filenames)
for fname in filenames:
try:
open(fname, 'r').close()
except Exception:
_log.exception('cannot open [%s], aborting', fname)
return False
if jobtype not in KNOWN_PRINTJOB_TYPES:
print("unregistered print job type <%s>" % jobtype)
_log.warning('print job type "%s" not registered', jobtype)
if print_api not in external_print_APIs:
_log.warning('print API "%s" unknown, trying all', print_api)
if print_api == 'os_startfile':
return _print_files_by_os_startfile(filenames = filenames)
if print_api == 'gm-print_doc':
return _print_files_by_shellscript(filenames = filenames, jobtype = jobtype, verbose = verbose)
if print_api == 'gsprint':
return _print_files_by_gsprint_exe(filenames = filenames, verbose = verbose)
if print_api == 'acrobat_reader':
return _print_files_by_acroread_exe(filenames = filenames, verbose = verbose)
if print_api == 'gtklp':
return _print_files_by_gtklp(filenames = filenames, verbose = verbose)
if print_api == 'Internet_Explorer':
return _print_files_by_IE(filenames = filenames)
if print_api == 'Mac_Preview':
return _print_files_by_mac_preview(filenames = filenames, verbose = verbose)
# not any single print_api explicitely requested, so try all, per-platform
if (sys.platform == 'darwin') or (os.name == 'mac'):
if _print_files_by_mac_preview(filenames = filenames, verbose = verbose):
return True
elif os.name == 'posix':
if _print_files_by_gtklp(filenames = filenames, verbose = verbose):
return True
elif os.name == 'nt':
if _print_files_by_shellscript(filenames = filenames, jobtype = jobtype, verbose = verbose):
return True
if _print_files_by_gsprint_exe(filenames = filenames, verbose = verbose):
return True
if _print_files_by_acroread_exe(filenames = filenames, verbose = verbose):
return True
if _print_files_by_os_startfile(filenames = filenames):
return True
if _print_files_by_IE(filenames = filenames):
return True
return False
# unknown platform, or platform default list failed, so try generic script
return _print_files_by_shellscript(filenames = filenames, jobtype = jobtype, verbose = verbose)
#=======================================================================
# external print APIs
#-----------------------------------------------------------------------
def _print_files_by_mac_preview(filenames=None, verbose=False):
# if os.name != 'mac': # does not work
if sys.platform != 'darwin':
_log.debug('MacOSX <open> only available under MacOSX/Darwin')
return False
for filename in filenames:
cmd_line = [
'open', # "open" must be in the PATH
'-a Preview', # action = Preview
filename
]
success, returncode, stdout = gmShellAPI.run_process(cmd_line = cmd_line, verbose = verbose)
if not success:
return False
return True
#-----------------------------------------------------------------------
def _print_files_by_IE(filenames=None):
if os.name != 'nt':
_log.debug('Internet Explorer only available under Windows')
return False
try:
from win32com import client as dde_client
except ImportError:
_log.exception('<win32com> Python module not available for use in printing')
return False
try:
i_explorer = dde_client.Dispatch("InternetExplorer.Application")
for filename in filenames:
if i_explorer.Busy:
time.sleep(1)
i_explorer.Navigate(os.path.normpath(filename))
if i_explorer.Busy:
time.sleep(1)
i_explorer.Document.printAll()
i_explorer.Quit()
except Exception:
_log.exception('error calling IE via DDE')
return False
return True
#-----------------------------------------------------------------------
def _print_files_by_gtklp(filenames=None, verbose=False):
# if os.name != 'posix':
if sys.platform != 'linux':
_log.debug('<gtklp> only available under Linux')
return False
cmd_line = ['gtklp', '-i', '-# 1']
cmd_line.extend(filenames)
success, returncode, stdout = gmShellAPI.run_process(cmd_line = cmd_line, verbose = verbose)
if not success:
return False
return True
#-----------------------------------------------------------------------
def _print_files_by_gsprint_exe(filenames=None, verbose=False):
"""Use gsprint.exe from Ghostscript tools. Windows only.
- docs: http://pages.cs.wisc.edu/~ghost/gsview/gsprint.htm
- download: http://www.cs.wisc.edu/~ghost/
"""
if os.name != 'nt':
_log.debug('<gsprint.exe> only available under Windows')
return False
conf_filename = gmTools.get_unique_filename (
prefix = 'gm2gsprint-',
suffix = '.cfg'
).encode(sys.getfilesystemencoding())
for filename in filenames:
conf_file = open(conf_filename, mode = 'wt', encoding = 'utf8')
conf_file.write('-color\n')
conf_file.write('-query\n') # printer setup dialog
conf_file.write('-all\n') # all pages
conf_file.write('-copies 1\n')
conf_file.write('%s\n' % os.path.normpath(filename))
conf_file.close()
cmd_line = ['gsprint.exe', '-config', conf_filename] # "gsprint.exe" must be in the PATH
success, returncode, stdout = gmShellAPI.run_process(cmd_line = cmd_line, verbose = verbose)
if not success:
return False
return True
#-----------------------------------------------------------------------
def _print_files_by_acroread_exe(filenames, verbose=False):
"""Use Adobe Acrobat Reader. Windows only.
- docs: http://www.robvanderwoude.com/printfiles.php#PrintPDF
"""
if os.name != 'nt':
_log.debug('Acrobat Reader only used under Windows')
return False
for filename in filenames:
cmd_line = [
'AcroRd32.exe', # "AcroRd32.exe" must be in the PATH
'/s', # no splash
'/o', # no open-file dialog
'/h', # minimized
'/p', # go straight to printing dialog
os.path.normpath(filename)
]
success, returncode, stdout = gmShellAPI.run_process(cmd_line = cmd_line, verbose = verbose)
if not success:
# retry with "acroread.exe"
cmd_line[0] = r'acroread.exe' # "acroread.exe" must be in the PATH
success, returncode, stdout = gmShellAPI.run_process(cmd_line = cmd_line, verbose = verbose)
if not success:
return False
return True
#-----------------------------------------------------------------------
def _print_files_by_os_startfile(filenames=None):
try:
os.startfile
except AttributeError:
_log.error('platform does not support "os.startfile()"')
return False
for filename in filenames:
fname = os.path.normcase(os.path.normpath(filename))
_log.debug('%s -> %s', filename, fname)
try:
try:
os.startfile(fname, 'print') # pylint: disable=no-member
except WindowsError as e: # pylint: disable=undefined-variable
_log.exception('no <print> action defined for this type of file')
if e.winerror == 1155:
# try (default) <view> action
os.startfile(fname) # pylint: disable=no-member
except Exception:
_log.exception('os.startfile() failed')
gmLog2.log_stack_trace()
return False
return True
#-----------------------------------------------------------------------
def _print_files_by_shellscript(filenames=None, jobtype=None, verbose=False):
paths = gmTools.gmPaths()
local_script = os.path.join(paths.local_base_dir, '..', 'external-tools', 'gm-print_doc')
candidates = ['gm-print_doc', local_script, 'gm-print_doc.bat']
found, binary = gmShellAPI.find_first_binary(binaries = candidates)
if not found:
binary = r'gm-print_doc.bat'
cmd_line = [binary, jobtype]
cmd_line.extend(filenames)
success, returncode, stdout = gmShellAPI.run_process(cmd_line = cmd_line, verbose = verbose)
if not success:
_log.debug('gm-print_doc(.bat) arguments: "DOCUMENT_TYPE LIST-OF-FILES-TO-PRINT"')
_log.debug('gm-print_doc(.bat): call printing app, perhaps based on DOCUMENT_TYPE, and pass in LIST-OF-FILES-TO-PRINT')
_log.debug('gm-print_doc(.bat): return 0 on success')
_log.debug('gm-print_doc(.bat): DOCUMENT_TYPE - can be used to decide which way to process a particular print job (Example: medication_list)')
_log.debug('gm-print_doc(.bat): LIST-OF-FILES-TO-PRINT - can be of any mimetype so the script needs to be able to process them, typically PDF though')
return False
return True
#=======================================================================
# main
#-----------------------------------------------------------------------
if __name__ == '__main__':
if len(sys.argv) < 2:
sys.exit()
if sys.argv[1] != 'test':
sys.exit()
from Gnumed.pycommon import gmI18N
gmI18N.activate_locale()
gmI18N.install_domain()
#--------------------------------------------------------------------
def test_print_files():
return print_files(filenames = [sys.argv[2]], jobtype = sys.argv[3])
#--------------------------------------------------------------------
def test_print_files_by_shellscript():
print_files(filenames = [sys.argv[2], sys.argv[2]], jobtype = 'generic_document', print_api = 'gm-print_doc')
#--------------------------------------------------------------------
def test_print_files_by_gtklp():
print_files(filenames = [sys.argv[2], sys.argv[2]], jobtype = 'generic_document', print_api = 'gtklp')
#--------------------------------------------------------------------
def test_print_files_by_mac_preview():
print("testing printing via Mac Preview")
_print_files_by_mac_preview(filenames = [sys.argv[0]])
#--------------------------------------------------------------------
print(test_print_files())
#test_print_files_by_gtklp()
#test_print_files_by_mac_preview()
Functions
def print_files(filenames: list = None, jobtype: str = None, print_api: str = None, verbose: bool = False) ‑> bool
-
Print files.
Args
filenames
- list of files to print
jobtype
- type of print job, passed on to print backends
print_api
- the print backend to use, will try all backends if None or unknown backend
Returns
status
Expand source code
def print_files(filenames:list=None, jobtype:str=None, print_api:str=None, verbose:bool=False) -> bool: """Print files. Args: filenames: list of files to print jobtype: type of print job, passed on to print backends print_api: the print backend to use, will try all backends if None or unknown backend Returns: status """ _log.debug('printing "%s": %s', jobtype, filenames) for fname in filenames: try: open(fname, 'r').close() except Exception: _log.exception('cannot open [%s], aborting', fname) return False if jobtype not in KNOWN_PRINTJOB_TYPES: print("unregistered print job type <%s>" % jobtype) _log.warning('print job type "%s" not registered', jobtype) if print_api not in external_print_APIs: _log.warning('print API "%s" unknown, trying all', print_api) if print_api == 'os_startfile': return _print_files_by_os_startfile(filenames = filenames) if print_api == 'gm-print_doc': return _print_files_by_shellscript(filenames = filenames, jobtype = jobtype, verbose = verbose) if print_api == 'gsprint': return _print_files_by_gsprint_exe(filenames = filenames, verbose = verbose) if print_api == 'acrobat_reader': return _print_files_by_acroread_exe(filenames = filenames, verbose = verbose) if print_api == 'gtklp': return _print_files_by_gtklp(filenames = filenames, verbose = verbose) if print_api == 'Internet_Explorer': return _print_files_by_IE(filenames = filenames) if print_api == 'Mac_Preview': return _print_files_by_mac_preview(filenames = filenames, verbose = verbose) # not any single print_api explicitely requested, so try all, per-platform if (sys.platform == 'darwin') or (os.name == 'mac'): if _print_files_by_mac_preview(filenames = filenames, verbose = verbose): return True elif os.name == 'posix': if _print_files_by_gtklp(filenames = filenames, verbose = verbose): return True elif os.name == 'nt': if _print_files_by_shellscript(filenames = filenames, jobtype = jobtype, verbose = verbose): return True if _print_files_by_gsprint_exe(filenames = filenames, verbose = verbose): return True if _print_files_by_acroread_exe(filenames = filenames, verbose = verbose): return True if _print_files_by_os_startfile(filenames = filenames): return True if _print_files_by_IE(filenames = filenames): return True return False # unknown platform, or platform default list failed, so try generic script return _print_files_by_shellscript(filenames = filenames, jobtype = jobtype, verbose = verbose)