home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / hplip / sendfax < prev    next >
Encoding:
Text File  |  2006-08-30  |  9.5 KB  |  331 lines

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # (c) Copyright 2003-2006 Hewlett-Packard Development Company, L.P.
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; if not, write to the Free Software
  18. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  19. #
  20. # Author: Don Welch
  21. #
  22. # Thanks to Henrique M. Holschuh <hmh@debian.org> for various security patches
  23. #
  24.  
  25. __version__ = '2.1'
  26. __title__ = 'PC Sendfax Utility'
  27. __doc__ = "Allows for sending faxes from the PC using HPLIP supported multifunction printers. The utility can be invoked directly, or by printing to the appropriate fax CUPS printer." 
  28.  
  29. # Std Lib
  30. import sys, socket, os, os.path, getopt, signal, atexit
  31. import ConfigParser, pwd, socket
  32.  
  33. # Local
  34. from base.g import *
  35. from base.msg import *
  36. import base.utils as utils
  37. import base.async_qt as async
  38. from base import service, device
  39.  
  40. app = None
  41. sendfax = None
  42. client = None
  43.  
  44. # PyQt
  45. if not utils.checkPyQtImport():
  46.     sys.exit(0)
  47.  
  48. from qt import *
  49.  
  50. # UI Forms
  51. from ui.faxsendjobform import FaxSendJobForm
  52.  
  53.  
  54. USAGE = [(__doc__, "", "name", True),
  55.          ("Usage: hp-sendfax [PRINTER|DEVICE-URI] [OPTIONS] [FILES]", "", "summary", True),
  56.          utils.USAGE_ARGS,
  57.          utils.USAGE_DEVICE,
  58.          utils.USAGE_PRINTER,
  59.          utils.USAGE_SPACE,
  60.          utils.USAGE_OPTIONS,
  61.          utils.USAGE_BUS1, utils.USAGE_BUS2,         
  62.          utils.USAGE_LOGGING1, utils.USAGE_LOGGING2, utils.USAGE_LOGGING3,
  63.          utils.USAGE_HELP,
  64.          ("[FILES]", "", "header", False),
  65.          ("An optional list of files to add to the fax job.", "", "option", True),
  66.          utils.USAGE_NOTES,
  67.          utils.USAGE_STD_NOTES1,
  68.          utils.USAGE_STD_NOTES2,
  69.          utils.USAGE_SPACE,
  70.          utils.USAGE_SEEALSO,
  71.          ("hp-fab", "", "seealso", False),
  72.         ]
  73.  
  74. def usage(typ='text'):
  75.     if typ == 'text':
  76.         utils.log_title(__title__, __version__)
  77.         
  78.     utils.format_text(USAGE, typ, __title__, 'hp-sendfax', __version__)
  79.     sys.exit(0)
  80.  
  81.  
  82.  
  83. class fax_client(async.dispatcher):
  84.  
  85.     def __init__(self, username):
  86.         async.dispatcher.__init__(self)
  87.         self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
  88.         self.connect((prop.hpssd_host, prop.hpssd_port)) 
  89.         self.in_buffer = ""
  90.         self.out_buffer = ""
  91.         self.fields = {}
  92.         self.data = ''
  93.         self.error_dialog = None
  94.         self.signal_exit = False
  95.  
  96.         # handlers for all the messages we expect to receive
  97.         self.handlers = {
  98.                         'eventgui'         : self.handle_eventgui,
  99.                         'unknown'          : self.handle_unknown,
  100.                         'exitguievent'     : self.handle_exitguievent,
  101.                         }
  102.  
  103.         self.register_gui(username)
  104.  
  105.     def handle_read(self):
  106.         log.debug("Reading data on channel (%d)" % self._fileno)
  107.  
  108.         self.in_buffer = self.recv(prop.max_message_len)
  109.         log.debug(repr(self.in_buffer))
  110.  
  111.         if self.in_buffer == '':
  112.             return False
  113.  
  114.         remaining_msg = self.in_buffer
  115.  
  116.         while True:
  117.             try:
  118.                 self.fields, self.data, remaining_msg = parseMessage(remaining_msg)
  119.             except Error, e:
  120.                 #log.debug(repr(self.in_buffer))
  121.                 log.warn("Message parsing error: %s (%d)" % (e.opt, e.msg))
  122.                 self.out_buffer = self.handle_unknown()
  123.                 log.debug(self.out_buffer)
  124.                 return True
  125.  
  126.             msg_type = self.fields.get('msg', 'unknown')
  127.             log.debug("%s %s %s" % ("*"*40, msg_type, "*"*40))
  128.             log.debug(repr(self.in_buffer))
  129.  
  130.             try:
  131.                 self.out_buffer = self.handlers.get(msg_type, self.handle_unknown)()
  132.             except Error:
  133.                 log.error("Unhandled exception during processing")
  134.  
  135.             if len(self.out_buffer): # data is ready for send
  136.                 self.sock_write_notifier.setEnabled(True)
  137.  
  138.             if not remaining_msg:
  139.                 break
  140.  
  141.         return True
  142.  
  143.     def handle_write(self):
  144.         if not len(self.out_buffer):
  145.             return
  146.  
  147.         log.debug("Sending data on channel (%d)" % self._fileno)
  148.         log.debug(repr(self.out_buffer))
  149.         
  150.         try:
  151.             sent = self.send(self.out_buffer)
  152.         except:
  153.             log.error("send() failed.")
  154.  
  155.         self.out_buffer = self.out_buffer[sent:]
  156.         
  157.  
  158.     def writable(self):
  159.         return not ((len(self.out_buffer) == 0)
  160.                      and self.connected)
  161.  
  162.     def handle_exitguievent(self):
  163.         self.signal_exit = True
  164.         if self.signal_exit:
  165.             if sendfax is not None:
  166.                 sendfax.close()
  167.             qApp.quit()
  168.  
  169.         return ''
  170.  
  171.     #def handle_faxgetdataresult(self):
  172.     #    pass
  173.     
  174.     # EVENT (GUI)
  175.     def handle_eventgui(self):
  176.         if sendfax is not None:
  177.             try:
  178.                 job_id = self.fields.get('job-id', 0)
  179.                 event_code = self.fields.get('event-code', 0)
  180.                 event_type = self.fields.get('event-type', 'event')
  181.                 retry_timeout = self.fields.get('retry-timeout', 0)
  182.                 
  183.                 lines = self.data.splitlines()
  184.                 try:
  185.                     error_string_short, error_string_long = lines[0], lines[1]
  186.                 except IndexError:
  187.                     error_string_short, error_string_long = '', ''
  188.                 
  189.                 device_uri = self.fields.get('device-uri', '')
  190.                 printer_name = self.fields.get('printer', '')
  191.                 title = self.fields.get('title', '')
  192.                 job_size = self.fields.get('job-size', 0)
  193.     
  194.                 log.debug("Event: %d '%s'" % (event_code, event_type))
  195.     
  196.                 sendfax.EventUI(event_code, event_type, error_string_short,
  197.                                 error_string_long, retry_timeout, job_id,
  198.                                 device_uri, printer_name, title, job_size)
  199.     
  200.             except:
  201.                 log.exception()
  202.     
  203.         return ''
  204.  
  205.     def handle_unknown(self):
  206.         return ''
  207.  
  208.     def handle_messageerror(self):
  209.         return ''
  210.  
  211.     def handle_close(self):
  212.         log.debug("closing channel (%d)" % self._fileno)
  213.         self.connected = False
  214.         async.dispatcher.close(self)
  215.  
  216.     def register_gui(self, username):
  217.         out_buffer = buildMessage("RegisterGUIEvent", None, 
  218.                                   {'type': 'fax', 
  219.                                    'username': username})
  220.         self.send(out_buffer)
  221.  
  222.  
  223.  
  224.  
  225.  
  226. def main(args):
  227.     prop.prog = sys.argv[0]
  228.     
  229.     device_uri = None
  230.     printer_name = None
  231.     username = prop.username
  232.  
  233.     try:
  234.         opts, args = getopt.getopt(sys.argv[1:],'l:hz:d:p:b:g', 
  235.             ['device=', 'printer=', 'level=', 
  236.              'help', 'help-rest', 
  237.              'help-man', 'logfile=', 'bus='])
  238.  
  239.     except getopt.GetoptError, e:
  240.         log.error(e)
  241.         sys.exit(1)
  242.         
  243.  
  244.     if os.getenv("HPLIP_DEBUG"):
  245.         log.set_level('debug')
  246.  
  247.     for o, a in opts:
  248.         if o in ('-l', '--logging'):
  249.             log_level = a.lower().strip()
  250.             if not log.set_level(log_level):
  251.                 usage()
  252.                 
  253.         elif o == '-g':
  254.             log.set_level('debug')
  255.                 
  256.         elif o in ('-z', '--logfile'):
  257.             log.set_logfile(a)
  258.             log.set_where(log.LOG_TO_CONSOLE_AND_FILE)
  259.  
  260.         elif o in ('-h', '--help'):
  261.             usage()
  262.             
  263.         elif o == '--help-rest':
  264.             usage('rest')
  265.             
  266.         elif o == '--help-man':
  267.             usage('man')
  268.             
  269.         elif o in ('-d', '--device'):
  270.             device_uri = a
  271.  
  272.         elif o in ('-p', '--printer'):
  273.             printer_name = a
  274.             
  275.         elif o in ('-b', '--bus'):
  276.             bus = a.lower().strip()
  277.             if not device.validateBusList(bus):
  278.                 usage()
  279.             
  280.             
  281.     utils.log_title(__title__, __version__)
  282.     
  283.     # Security: Do *not* create files that other users can muck around with
  284.     os.umask (0077)
  285.     log.set_module('sendfax')
  286.  
  287.     global client
  288.     try:
  289.         client = fax_client(username)
  290.     except Error:
  291.         log.error("Unable to create client object.")
  292.         sys.exit(1)
  293.     except socket.error:
  294.         log.error("Unable to connect to HPLIP I/O. Please (re)start HPLIP and try again.")
  295.         sys.exit(1)
  296.         
  297.     # create the main application object
  298.     global app
  299.     app = QApplication(sys.argv)
  300.  
  301.     global sendfax
  302.     sendfax = FaxSendJobForm(client.socket,
  303.                              device_uri,  
  304.                              printer_name, 
  305.                              args) 
  306.                              
  307.     app.setMainWidget(sendfax)
  308.  
  309.     pid = os.getpid()
  310.     log.debug('pid=%d' % pid)
  311.  
  312.     sendfax.show()
  313.     
  314.     signal.signal(signal.SIGPIPE, signal.SIG_IGN)
  315.  
  316.     user_config = os.path.expanduser('~/.hplip.conf')
  317.     loc = utils.loadTranslators(app, user_config)
  318.  
  319.     try:
  320.         log.debug("Starting GUI loop...")
  321.         app.exec_loop()
  322.     except KeyboardInterrupt:
  323.         pass
  324.     except:
  325.         log.exception()
  326.  
  327.     return 0
  328.  
  329. if __name__ == "__main__":
  330.     sys.exit(main(sys.argv[1:]))
  331.