Package Gnumed :: Package pycommon :: Module gmPrinting |
[frames] | no frames]

# Source Code for Module Gnumed.pycommon.gmPrinting

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