home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / lib / hplip / fax / fax.py < prev    next >
Encoding:
Python Source  |  2007-04-04  |  61.8 KB  |  1,600 lines

  1. # -*- coding: utf-8 -*-
  2. #
  3. # (c) Copyright 2003-2007 Hewlett-Packard Development Company, L.P.
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18. #
  19. # Author: Don Welch
  20. #
  21.  
  22. from __future__ import generators
  23.  
  24. # Std Lib
  25. import sys, os, os.path, mmap, struct, time, threading, Queue, socket
  26. from cStringIO import StringIO
  27.  
  28. # Local
  29. from base.g import *
  30. from base.codes import *
  31. from base import device, utils, status, pml, msg
  32. from base.kirbybase import KirbyBase
  33. from prnt import cups
  34.  
  35. try:
  36.     import coverpages
  37. except ImportError:
  38.     pass
  39.  
  40. # **************************************************************************** #
  41.  
  42. # Page flags 
  43. PAGE_FLAG_NONE = 0x00
  44. PAGE_FLAG_NEW_PAGE = 0x01
  45. PAGE_FLAG_END_PAGE = 0x02
  46. PAGE_FLAG_NEW_DOC = 0x04
  47. PAGE_FLAG_END_DOC = 0x08
  48. PAGE_FLAG_END_STREAM = 0x10
  49.  
  50. MAJOR_VER = 2
  51. MINOR_VER = 0
  52.  
  53. MFPDTF_RASTER_BITMAP  = 0 # Not used
  54. MFPDTF_RASTER_GRAYMAP = 1 # Not used
  55. MFPDTF_RASTER_MH      = 2 # OfficeJets B&W Fax
  56. MFPDTF_RASTER_MR      = 3 # Not used
  57. MFPDTF_RASTER_MMR     = 4 # LaserJets B&W Fax
  58. MFPDTF_RASTER_RGB     = 5 # Not used
  59. MFPDTF_RASTER_YCC411  = 6 # Not used
  60. MFPDTF_RASTER_JPEG    = 7 # Color Fax
  61. MFPDTF_RASTER_PCL     = 8 # Not used
  62. MFPDTF_RASTER_NOT     = 9 # Not used
  63.  
  64. # Data types for FH
  65. DT_UNKNOWN       = 0
  66. DT_FAX_IMAGES    = 1
  67. DT_SCANNED_IMAGES= 2
  68. DT_DIAL_STRINGS  = 3
  69. DT_DEMO_PAGES    = 4
  70. DT_SPEED_DIALS   = 5
  71. DT_FAX_LOGS      = 6
  72. DT_CFG_PARMS     = 7
  73. DT_LANG_STRS     = 8
  74. DT_JUNK_FAX_CSIDS= 9  
  75. DT_REPORT_STRS   = 10  
  76. DT_FONTS         = 11
  77. DT_TTI_BITMAP    = 12
  78. DT_COUNTERS      = 13
  79. DT_DEF_PARMS     = 14  
  80. DT_SCAN_OPTIONS  = 15
  81. DT_FW_JOB_TABLE  = 17
  82.  
  83. # Raster data record types
  84. RT_START_PAGE = 0
  85. RT_RASTER = 1
  86. RT_END_PAGE = 2
  87.  
  88. # FH
  89. FIXED_HEADER_SIZE = 8
  90.  
  91. # Variants
  92. IMAGE_VARIANT_HEADER_SIZE = 10
  93. DIAL_STRINGS_VARIANT_HEADER_SIZE = 6
  94. FAX_IMAGE_VARIANT_HEADER_SIZE = 74
  95.  
  96. # Data records
  97. SOP_RECORD_SIZE = 36
  98. RASTER_RECORD_SIZE = 4
  99. EOP_RECORD_SIZE = 12
  100. DIAL_STRING_RECORD_SIZE = 51
  101.  
  102. # Page flags 
  103. PAGE_FLAG_NEW_PAGE = 0x01
  104. PAGE_FLAG_END_PAGE = 0x02
  105. PAGE_FLAG_NEW_DOC = 0x04
  106. PAGE_FLAG_END_DOC = 0x08
  107. PAGE_FLAG_END_STREAM = 0x10
  108.  
  109. # Fax data variant header data source
  110. SRC_UNKNOWN = 0
  111. SRC_HOST = 2
  112. SRC_SCANNER = 5
  113. SRC_HOST_THEN_SCANNER = 6
  114. SRC_SCANNER_THEN_HOST = 7
  115.  
  116. # Fax data variant header TTI header control
  117. TTI_NONE = 0
  118. TTI_PREPENDED_TO_IMAGE = 1
  119. TTI_OVERLAYED_ON_IMAGE = 2
  120.  
  121. RASTER_DATA_SIZE = 504
  122.  
  123. # Update queue values (Send thread ==> UI)
  124. STATUS_IDLE = 0
  125. STATUS_PROCESSING_FILES = 1
  126. STATUS_DIALING = 2
  127. STATUS_CONNECTING = 3
  128. STATUS_SENDING = 4
  129. STATUS_COMPLETED = 5
  130. STATUS_CREATING_COVER_PAGE = 6
  131. STATUS_ERROR = 7
  132. STATUS_BUSY = 8
  133. STATUS_CLEANUP = 9
  134.  
  135. # Event queue values (UI ==> Send thread)
  136. EVENT_FAX_SEND_CANCELED = 1
  137. # Other values in queue are:
  138. #EVENT_FAX_RENDER_COMPLETE_BEGIN = 8010
  139. #EVENT_FAX_RENDER_COMPLETE_SENDDATA = 8011
  140. #EVENT_FAX_RENDER_COMPLETE_END = 8012
  141.  
  142. # **************************************************************************** #
  143. # HPLIP G3 Fax File Format (big endian)
  144. #
  145. # #==============================================#
  146. # # File Header: Total 28 bytes                  #
  147. # #..............................................#
  148. # # Magic bytes: 8 bytes ("hplip_g3")            #
  149. # # Format version: 8 bits (1)                   #
  150. # # Total pages in file(=p): 32 bits             #
  151. # # Hort DPI: 16 bits (200 or 300)               #
  152. # # Vert DPI: 16 bits (100, 200, or 300)         #
  153. # # Page Size: 8 bits (0=Unk, 1=Letter, 2=A4,    #
  154. # #                    3=Legal)                  #
  155. # # Resolution: 8 bits (0=Unk, 1=Std, 2=Fine,    #
  156. # #                     3=300DPI)                #
  157. # # Encoding: 8 bits (2=MH, 4=MMR, 7=JPEG)       #
  158. # # Reserved1: 32 bits (0)                       #
  159. # # Reserved2: 32 bits (0)                       #
  160. # #----------------------------------------------#
  161. # # Page 1 Header: Total 24 bytes                #
  162. # #..............................................#
  163. # # Page number: 32 bits (1 based)               #
  164. # # Pixels per row: 32 bits                      #
  165. # # Rows this page: 32 bits                      #
  166. # # Image bytes this page(=x): 32 bits           #
  167. # # Thumbnail bytes this page(=y): 32 bits       #
  168. # #  (thumbnail not present if y == 0)           #
  169. # #  (encoding?)                                 #
  170. # #     letter: 134 px wide x 173 px high        #
  171. # #     legal:  134 px wide x 221 px high        #
  172. # #     a4 :    134 px wide x 190 px high        #
  173. # # Reserved3: 32 bits (0)                       #
  174. # #..............................................#
  175. # # Image data: x bytes                          #
  176. # #..............................................#
  177. # # Thumbnail data: y bytes (if present)         #
  178. # #----------------------------------------------#
  179. # # Page 2 Header: Total 24 bytes                #
  180. # #..............................................#
  181. # # Image Data                                   #
  182. # #..............................................#
  183. # # Thumbnail data (if present)                  #
  184. # #----------------------------------------------#
  185. # # ... Pages 3 - (p-1) ...                      #
  186. # #----------------------------------------------#
  187. # # Page p Header: Total 24 bytes                #
  188. # #..............................................#
  189. # # Image Data                                   #
  190. # #..............................................#
  191. # # Thumbnail data (if present)                  #
  192. # #==============================================#
  193. #
  194.  
  195. FILE_HEADER_SIZE = 28
  196. PAGE_HEADER_SIZE = 24
  197.  
  198. # **************************************************************************** #
  199.  
  200. class FaxAddressBook(KirbyBase):
  201.     def __init__(self):
  202.         KirbyBase.__init__(self)
  203.  
  204.         # Transitional code to handle moving of db file
  205.         t = os.path.expanduser('~/.hplip.fab') # old location
  206.         self._fab = os.path.expanduser('~/hpfax/fab.db') # new location
  207.  
  208.         fax_dir = os.path.expanduser("~/hpfax")
  209.         if not os.path.exists(fax_dir):
  210.             os.mkdir(fax_dir)
  211.  
  212.         if os.path.exists(t) and not os.path.exists(self._fab):
  213.             import shutil
  214.             shutil.move(t, self._fab)
  215.  
  216.         if not os.path.exists(self._fab):
  217.             log.debug("Creating new fax address book: %s" % self._fab)
  218.             self.create()
  219.  
  220.  
  221.     def create(self):
  222.         return KirbyBase.create(self, self._fab,
  223.             ['name:str',
  224.              'title:str',
  225.              'firstname:str',
  226.              'lastname:str',
  227.              'fax:str',
  228.              'groups:str', # comma sep list of group names
  229.              'notes:str'])
  230.  
  231.  
  232.     def filename(self):
  233.         return self._fab
  234.  
  235.     def last_modification_time(self):
  236.         return os.stat(self._fab).st_mtime
  237.  
  238.     def close(self):
  239.         return KirbyBase.close(self)
  240.  
  241.     def insert(self, values):
  242.         return KirbyBase.insert(self, self._fab, values)
  243.  
  244.  
  245.     def insertBatch(self, batchRecords):
  246.         return KirbyBase.insertBatch(self, self._fab, batchRecords)
  247.  
  248.  
  249.     def update(self, fields, searchData, updates, filter=None, useRegExp=False):
  250.         return KirbyBase.update(self, self._fab, fields, searchData, updates, filter, useRegExp)
  251.  
  252.  
  253.     def delete(self, fields, searchData, useRegExp=False):
  254.         return KirbyBase.delete(self, self._fab, fields, searchData, useRegExp)
  255.  
  256.  
  257.     def select(self, fields, searchData, filter=None, useRegExp=False, sortFields=[],
  258.         sortDesc=[], returnType='list', rptSettings=[0,False]):
  259.         return KirbyBase.select(self, self._fab, fields, searchData, filter,
  260.             useRegExp, sortFields, sortDesc, returnType, rptSettings)
  261.  
  262.  
  263.     def pack(self):
  264.         return KirbyBase.pack(self, self._fab)
  265.  
  266.  
  267.     def validate(self):
  268.         return KirbyBase.validate(self, self._fab)
  269.  
  270.  
  271.     def drop(self):
  272.         return KirbyBase.drop(self, self._fab)
  273.  
  274.  
  275.     def getFieldNames(self):
  276.         return KirbyBase.getFieldNames(self, self._fab)
  277.  
  278.  
  279.     def getFieldTypes(self):
  280.         return KirbyBase.getFieldTypes(self, self._fab)
  281.  
  282.  
  283.     def len(self):
  284.         return KirbyBase.len(self, self._fab)
  285.  
  286.  
  287.     def GetEntryByRecno(self, recno):
  288.         return AddressBookEntry(self.select(['recno'], [recno])[0])
  289.  
  290.  
  291.     def AllRecords(self):
  292.         return self.select(['recno'], ['*'])
  293.  
  294.  
  295.     def AllRecordEntries(self):
  296.         return [AddressBookEntry(rec) for rec in self.select(['recno'], ['*'])]
  297.  
  298.  
  299.     def GroupEntries(self, group):
  300.         return [abe.name for abe in self.AllRecordEntries() if group in abe.group_list]
  301.  
  302.  
  303.     def AllGroups(self):
  304.         temp = {}
  305.         for abe in self.AllRecordEntries():
  306.             for g in abe.group_list:
  307.                 temp.setdefault(g)
  308.  
  309.         return temp.keys()
  310.  
  311.  
  312.     def UpdateGroupEntries(self, group_name, member_entries):
  313.         for entry in self.AllRecordEntries():
  314.  
  315.             if entry.name in member_entries: # membership indicated
  316.  
  317.                 if not group_name in entry.group_list: # entry already member of group
  318.                     # add it
  319.                     entry.group_list.append(group_name)
  320.                     self.update(['recno'], [entry.recno], [','.join(entry.group_list)], ['groups'])
  321.             else:
  322.  
  323.                 if group_name in entry.group_list: # remove from entry
  324.                     entry.group_list.remove(group_name)
  325.                     self.update(['recno'], [entry.recno], [','.join(entry.group_list)], ['groups'])
  326.  
  327.  
  328.     def DeleteGroup(self, group_name):
  329.         for entry in self.AllRecordEntries():
  330.             if group_name in entry.group_list:
  331.                 entry.group_list.remove(group_name)
  332.                 self.update(['recno'], [entry.recno], [','.join(entry.group_list)], ['groups'])
  333.  
  334.  
  335. # **************************************************************************** #
  336.  
  337. class AddressBookEntry(object):
  338.     def __init__(self, rec=None):
  339.         if rec is not None:
  340.             rec = [x or '' for x in rec]
  341.             self.recno, self.name, \
  342.             self.title, self.firstname, self.lastname, \
  343.             self.fax, self.groups, self.notes = rec
  344.             self.group_list = []
  345.  
  346.             if len(self.groups):
  347.                 for g in self.groups.split(','):
  348.                     self.group_list.append(g.strip())
  349.  
  350.     def __str__(self):
  351.         return "Recno=%d, Name=%s, Title=%s, First=%s, Last=%s, Fax=%s, Groups=%s, Notes=%s\n" % \
  352.             (self.recno, self.name, self.title, self.firstname,
  353.               self.lastname, self.fax, self.group_list, self.notes)
  354.  
  355.  
  356. # **************************************************************************** #
  357.  
  358.  
  359. # **************************************************************************** #
  360. class FaxDevice(device.Device):
  361.  
  362.     def __init__(self, device_uri=None, printer_name=None,
  363.                  hpssd_sock=None, hpiod_sock=None, callback=None):
  364.  
  365.         device.Device.__init__(self, device_uri, printer_name,
  366.                                hpssd_sock, hpiod_sock, callback)
  367.  
  368.         self.send_fax_thread = None
  369.         self.upload_log_thread = None
  370.  
  371.     def setPhoneNum(self, num):
  372.         return self.setPML(pml.OID_FAX_LOCAL_PHONE_NUM, str(num))
  373.  
  374.     def getPhoneNum(self):
  375.         return utils.printable(str(self.getPML(pml.OID_FAX_LOCAL_PHONE_NUM)[1]))
  376.  
  377.     phone_num = property(getPhoneNum, setPhoneNum, doc="OID_FAX_LOCAL_PHONE_NUM")
  378.  
  379.  
  380.     def setStationName(self, name):
  381.         return self.setPML(pml.OID_FAX_STATION_NAME, str(name))
  382.  
  383.     def getStationName(self):
  384.         return utils.printable(str(self.getPML(pml.OID_FAX_STATION_NAME)[1]))
  385.  
  386.     station_name = property(getStationName, setStationName, doc="OID_FAX_STATION_NAME")
  387.  
  388.     def setDateAndTime(self):
  389.         t = time.localtime()
  390.         p = struct.pack("BBBBBBB", t[0]-2000, t[1], t[2], t[6]+1, t[3], t[4], t[5])
  391.         log.debug(repr(p))
  392.         return self.setPML(pml.OID_DATE_AND_TIME, p)
  393.  
  394.     def uploadLog(self):
  395.         if not self.isUloadLogActive():
  396.             self.upload_log_thread = UploadLogThread(self)
  397.             self.upload_log_thread.start()
  398.             return True
  399.         else:
  400.             return False
  401.  
  402.     def isUploadLogActive(self):
  403.         if self.upload_log_thread is not None:
  404.             return self.upload_log_thread.isAlive()
  405.         else:
  406.             return False
  407.  
  408.     def waitForUploadLogThread(self):
  409.         if self.upload_log_thread is not None and \
  410.             self.upload_log_thread.isAlive():
  411.  
  412.             self.upload_log_thread.join()
  413.  
  414.  
  415.     def sendFaxes(self, phone_num_list, fax_file_list, cover_message='', cover_re='', 
  416.                   cover_func=None, printer_name='', update_queue=None, event_queue=None):
  417.  
  418.         if not self.isSendFaxActive():
  419.             self.send_fax_thread = FaxSendThread(self, phone_num_list, fax_file_list, 
  420.                                                  cover_message, cover_re, cover_func, 
  421.                                                  printer_name, update_queue, event_queue)
  422.             self.send_fax_thread.start()
  423.             return True
  424.         else:
  425.             return False
  426.  
  427.  
  428.     def isSendFaxActive(self):
  429.         if self.send_fax_thread is not None:
  430.             return self.send_fax_thread.isAlive()
  431.         else:
  432.             return False
  433.  
  434.     def waitForSendFaxThread(self):
  435.         if self.send_fax_thread is not None and \
  436.             self.send_fax_thread.isAlive():
  437.  
  438.             self.send_fax_thread.join()
  439.  
  440.  
  441. class UploadLogThread(threading.Thread):
  442.     def __init__(self, dev):
  443.         threading.Thread.__init__(self)
  444.         self.dev = dev
  445.  
  446.  
  447.     def run(self):
  448.         STATE_DONE = 0
  449.         STATE_ABORT = 10
  450.         STATE_SUCCESS = 20
  451.         STATE_BUSY = 25
  452.         STATE_DEVICE_OPEN = 28
  453.         STATE_CHECK_IDLE = 30
  454.         STATE_REQUEST_START = 40
  455.         STATE_WAIT_FOR_ACTIVE = 50
  456.         STATE_UPLOAD_DATA = 60
  457.         STATE_DEVICE_CLOSE = 70
  458.  
  459.         state = STATE_CHECK_IDLE
  460.  
  461.         while state != STATE_DONE: # --------------------------------- Log upload state machine
  462.             if state == STATE_ABORT: 
  463.                 pass
  464.             elif state == STATE_SUCCESS:
  465.                 pass
  466.             elif state == STATE_BUSY:
  467.                 pass
  468.  
  469.             elif state == STATE_DEVICE_OPEN: # --------------------------------- Open device (28)
  470.                 state = STATE_REQUEST_START
  471.                 try:
  472.                     self.dev.open()
  473.                 except Error, e:
  474.                     log.error("Unable to open device (%s)." % e.msg)
  475.                     state = STATE_ERROR
  476.                 else:
  477.                     try:
  478.                         dev.setPML(pml.OID_UPLOAD_TIMEOUT, pml.DEFAULT_UPLOAD_TIMEOUT)
  479.                     except Error:
  480.                         state = STATE_ERROR
  481.  
  482.             elif state == STATE_CHECK_IDLE: # --------------------------------- Check idle (30)
  483.                 state = STATE_REQUEST_START
  484.                 ul_state = self.getCfgUploadState()
  485.  
  486.                 if ul_state != pml.UPDN_STATE_IDLE:
  487.                     state = STATE_BUSY
  488.  
  489.  
  490.             elif state == STATE_REQUEST_START: # --------------------------------- Request start (40)
  491.                 state = STATE_WAIT_FOR_ACTIVE
  492.                 self.dev.setPML(pml.OID_FAX_CFG_UPLOAD_DATA_TYPE, pml.FAX_CFG_UPLOAD_DATA_TYPE_FAXLOGS)
  493.                 self.dev.setPML(pml.OID_DEVICE_CFG_UPLOAD, pml.UPDN_STATE_REQSTART)
  494.  
  495.             elif state == STATE_WAIT_FOR_ACTIVE: # --------------------------------- Wait for active state (50)
  496.                 state = STATE_UPLOAD_DATA
  497.  
  498.                 tries = 0
  499.                 while True:
  500.                     tries += 1
  501.                     ul_state = self.getCfgUploadState()
  502.  
  503.                     if ul_state == pml.UPDN_STATE_XFERACTIVE:
  504.                         break
  505.  
  506.                     if ul_state in (pml.UPDN_STATE_ERRORABORT, pml.UPDN_STATE_XFERDONE):
  507.                         log.error("Cfg upload aborted!")
  508.                         state = STATE_ERROR
  509.                         break
  510.  
  511.                     if tries > 10:
  512.                         state = STATE_ERROR
  513.                         log.error("Unable to get into active state!")
  514.                         break
  515.  
  516.                     time.sleep(0.5)
  517.  
  518.             elif state == STATE_UPLOAD_DATA: # --------------------------------- Upload log data (60)
  519.                 pass
  520.  
  521.             elif state == STATE_DEVICE_CLOSE: # --------------------------------- Close device (70)
  522.                 self.dev.close()
  523.  
  524.  
  525.  
  526.  
  527. class FaxSendThread(threading.Thread):
  528.     def __init__(self, dev, phone_num_list, fax_file_list, 
  529.                  cover_message='', cover_re='', cover_func=None, 
  530.                  printer_name='', update_queue=None, event_queue=None):
  531.  
  532.         threading.Thread.__init__(self)
  533.         self.dev = dev
  534.         self.phone_num_list = phone_num_list
  535.         self.fax_file_list = fax_file_list
  536.         self.update_queue = update_queue
  537.         self.event_queue = event_queue
  538.         self.cover_message = cover_message
  539.         self.cover_re = cover_re
  540.         self.cover_func = cover_func
  541.         self.current_printer = printer_name
  542.         self.stream = StringIO()  
  543.         self.prev_update = ''
  544.         self.remove_temp_file = False
  545.  
  546.  
  547.     def run(self):
  548.         results = {} # {'file' : error_code,...}
  549.  
  550.         STATE_DONE = 0
  551.         STATE_ABORTED = 10
  552.         STATE_SUCCESS = 20
  553.         STATE_BUSY = 25
  554.         STATE_READ_SENDER_INFO = 30
  555.         STATE_PRERENDER = 40
  556.         STATE_COUNT_PAGES = 50
  557.         STATE_NEXT_RECIPIENT = 60
  558.         STATE_COVER_PAGE = 70
  559.         STATE_SINGLE_FILE = 80
  560.         STATE_MERGE_FILES = 90
  561.         STATE_SINGLE_FILE = 100
  562.         STATE_SEND_FAX = 110
  563.         STATE_CLEANUP = 120
  564.         STATE_ERROR = 130
  565.  
  566.         next_recipient = self.next_recipient_gen()
  567.  
  568.         state = STATE_READ_SENDER_INFO
  569.         self.rendered_file_list = []
  570.  
  571.         while state != STATE_DONE: # --------------------------------- Fax state machine
  572.             if self.check_for_cancel():
  573.                 state = STATE_ABORTED
  574.  
  575.             log.debug("STATE=(%d, 0, 0)" % state)
  576.  
  577.             if state == STATE_ABORTED: # --------------------------------- Aborted (10, 0, 0)
  578.                 log.error("Aborted by user.")
  579.                 self.write_queue((STATUS_IDLE, 0, ''))
  580.                 state = STATE_CLEANUP
  581.  
  582.  
  583.             elif state == STATE_SUCCESS: # --------------------------------- Success (20, 0, 0)
  584.                 log.debug("Success.")
  585.                 self.write_queue((STATUS_COMPLETED, 0, ''))
  586.                 state = STATE_CLEANUP
  587.  
  588.  
  589.             elif state == STATE_ERROR: # --------------------------------- Error (130, 0, 0)
  590.                 log.error("Error, aborting.")
  591.                 self.write_queue((STATUS_ERROR, 0, ''))
  592.                 state = STATE_CLEANUP
  593.  
  594.  
  595.             elif state == STATE_BUSY: # --------------------------------- Busy (25, 0, 0)
  596.                 log.error("Device busy, aborting.")
  597.                 self.write_queue((STATUS_BUSY, 0, ''))
  598.                 state = STATE_CLEANUP
  599.  
  600.  
  601.             elif state == STATE_READ_SENDER_INFO: # --------------------------------- Get sender info (30, 0, 0)
  602.                 log.debug("%s State: Get sender info" % ("*"*20))
  603.                 state = STATE_PRERENDER
  604.                 try:
  605.                     try:
  606.                         self.dev.open()
  607.                     except Error, e:
  608.                         log.error("Unable to open device (%s)." % e.msg)
  609.                         state = STATE_ERROR
  610.                     else:
  611.                         try:
  612.                             self.sender_name = self.dev.station_name
  613.                             log.debug("Sender name=%s" % self.sender_name)
  614.                             self.sender_fax = self.dev.phone_num
  615.                             log.debug("Sender fax=%s" % self.sender_fax)
  616.                         except Error:
  617.                             log.error("PML get failed!")
  618.                             state = STATE_ERROR
  619.  
  620.                 finally:
  621.                     self.dev.close()
  622.  
  623.  
  624.             elif state == STATE_PRERENDER: # --------------------------------- Pre-render non-G3 files (40, 0, 0)
  625.                 log.debug("%s State: Pre-render non-G3 files" % ("*"*20))
  626.                 # pre-render each page that needs rendering
  627.                 # except for the cover page
  628.                 state = STATE_COUNT_PAGES
  629.                 cover_page_present = False
  630.                 log.debug(self.fax_file_list)
  631.  
  632.                 for fax_file in self.fax_file_list: # (file, type, desc, title)
  633.                     fax_file_name, fax_file_type, fax_file_desc, fax_file_title, fax_file_pages = fax_file
  634.  
  635.                     if fax_file_type == "application/hplip-fax-coverpage": # render later
  636.                         cover_page_present = True
  637.                         log.debug("Skipping coverpage")
  638.  
  639.                     #if fax_file_type == "application/hplip-fax": # already rendered
  640.                     else:
  641.                         self.rendered_file_list.append((fax_file_name, "application/hplip-fax", "HP Fax", fax_file_title))
  642.                         log.debug("Processing pre-rendered file: %s (%d pages)" % (fax_file_name, fax_file_pages))
  643.  
  644.                     if self.check_for_cancel():
  645.                         state = STATE_ABORTED
  646.  
  647.                 log.debug(self.rendered_file_list)
  648.  
  649.  
  650.             elif state == STATE_COUNT_PAGES: # --------------------------------- Get total page count (50, 0, 0)
  651.                 log.debug("%s State: Get total page count" % ("*"*20))
  652.                 state = STATE_NEXT_RECIPIENT
  653.                 recipient_file_list = self.rendered_file_list[:]
  654.                 log.debug("Counting total pages...")
  655.                 self.job_total_pages = 0
  656.                 log.debug(recipient_file_list)
  657.  
  658.                 i = 0
  659.                 for fax_file in recipient_file_list: # (file, type, desc, title)
  660.                     fax_file_name = fax_file[0]
  661.                     log.debug("Processing file (counting pages): %s..." % fax_file_name)
  662.  
  663.                     #self.write_queue((STATUS_PROCESSING_FILES, self.job_total_pages, ''))
  664.  
  665.                     if os.path.exists(fax_file_name):
  666.                         results[fax_file_name] = ERROR_SUCCESS
  667.                         fax_file_fd = file(fax_file_name, 'r')
  668.                         header = fax_file_fd.read(FILE_HEADER_SIZE)
  669.  
  670.                         magic, version, total_pages, hort_dpi, vert_dpi, page_size, \
  671.                             resolution, encoding, reserved1, reserved2 = self.decode_fax_header(header)
  672.  
  673.                         if magic != 'hplip_g3':
  674.                             log.error("Invalid file header. Bad magic.")
  675.                             results[fax_file_name] = ERROR_FAX_INVALID_FAX_FILE
  676.                             state = STATE_ERROR
  677.                             continue
  678.  
  679.                         if not i:
  680.                             job_hort_dpi, job_vert_dpi, job_page_size, job_resolution, job_encoding = \
  681.                                 hort_dpi, vert_dpi, page_size, resolution, encoding
  682.                             i += 1
  683.                         else:
  684.                             if job_hort_dpi != hort_dpi or \
  685.                                 job_vert_dpi != vert_dpi or \
  686.                                 job_page_size != page_size or \
  687.                                 job_resolution != resolution or \
  688.                                 job_encoding != encoding:
  689.  
  690.                                 log.error("Incompatible options for file: %s" % fax_file_name)
  691.                                 results[fax_file_name] = ERROR_FAX_INCOMPATIBLE_OPTIONS
  692.                                 state = STATE_ERROR
  693.  
  694.  
  695.                         log.debug("Magic=%s Ver=%d Pages=%d hDPI=%d vDPI=%d Size=%d Res=%d Enc=%d" %
  696.                                   (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding))
  697.  
  698.                         self.job_total_pages += total_pages
  699.  
  700.                         fax_file_fd.close()
  701.  
  702.                     else:
  703.                         log.error("Unable to find HP Fax file: %s" % fax_file_name)
  704.                         results[fax_file_name] = ERROR_FAX_FILE_NOT_FOUND
  705.                         state = STATE_ERROR
  706.                         break
  707.  
  708.                     if self.check_for_cancel():
  709.                         state = STATE_ABORTED
  710.                         break
  711.  
  712.  
  713.                 if cover_page_present:
  714.                     self.job_total_pages += 1 # Cover pages are truncated to 1 page
  715.  
  716.                 log.debug("Total fax pages=%d" % self.job_total_pages)                        
  717.  
  718.  
  719.             elif state == STATE_NEXT_RECIPIENT: # --------------------------------- Loop for multiple recipients (60, 0, 0)
  720.                 log.debug("%s State: Next recipient" % ("*"*20))
  721.                 state = STATE_COVER_PAGE
  722.  
  723.                 try:
  724.                     recipient = next_recipient.next()
  725.                     log.debug("Processing for recipient %s" % recipient.name)
  726.                 except StopIteration:
  727.                     state = STATE_SUCCESS
  728.                     log.debug("Last recipient.")
  729.                     continue
  730.  
  731.                 recipient_file_list = self.rendered_file_list[:]
  732.  
  733.  
  734.             elif state == STATE_COVER_PAGE: # --------------------------------- Create cover page (70, 0, 0)
  735.                 log.debug("%s State: Render cover page" % ("*"*20))
  736.  
  737.                 if self.job_total_pages > 1:
  738.                     state = STATE_MERGE_FILES
  739.                 else:
  740.                     state = STATE_SINGLE_FILE
  741.  
  742.                 if cover_page_present:
  743.                     log.debug("Creating cover page for recipient: %s" % recipient.name)
  744.                     fax_file, canceled = self.render_cover_page(recipient)
  745.  
  746.                     if canceled:
  747.                         state = STATE_ABORTED
  748.                     elif not fax_file:
  749.                         state = STATE_ERROR # timeout
  750.                     else:
  751.                         recipient_file_list.insert(0, (fax_file, "application/hplip-fax", "HP Fax", 'Cover Page'))
  752.                         log.debug("Cover page G3 file: %s" % fax_file)
  753.  
  754.                         results[fax_file] = ERROR_SUCCESS
  755.  
  756.  
  757.             elif state == STATE_SINGLE_FILE: # --------------------------------- Special case for single file (no merge) (80, 0, 0)
  758.                 log.debug("%s State: Handle single file" % ("*"*20))
  759.                 state = STATE_SEND_FAX
  760.  
  761.                 log.debug("Processing single file...")
  762.  
  763.                 f = recipient_file_list[0][0]
  764.  
  765.                 try:
  766.                     f_fd = file(f, 'r')
  767.                 except IOError:
  768.                     log.error("Unable to open fax file: %s" % f)
  769.                     state = STATE_ERROR
  770.                 else:
  771.                     header = f_fd.read(FILE_HEADER_SIZE)
  772.  
  773.                     magic, version, total_pages, hort_dpi, vert_dpi, page_size, \
  774.                         resolution, encoding, reserved1, reserved2 = self.decode_fax_header(header)
  775.  
  776.                     results[f] = ERROR_SUCCESS
  777.  
  778.                     if magic != 'hplip_g3':
  779.                         log.error("Invalid file header. Bad magic.")
  780.                         results[f] = ERROR_FAX_INVALID_FAX_FILE
  781.                         state = STATE_ERROR
  782.  
  783.                     log.debug("Magic=%s Ver=%d Pages=%d hDPI=%d vDPI=%d Size=%d Res=%d Enc=%d" %
  784.                               (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding))
  785.  
  786.                     f_fd.close()
  787.  
  788.  
  789.             elif state == STATE_MERGE_FILES: # --------------------------------- Merge multiple G3 files (90, 0, 0)
  790.                 log.debug("%s State: Merge multiple files" % ("*"*20))
  791.                 log.debug(recipient_file_list)
  792.                 log.debug("Merging g3 files...")
  793.                 state = STATE_SEND_FAX
  794.                 self.remove_temp_file = True
  795.  
  796.                 if self.job_total_pages:
  797.                     f_fd, f = utils.make_temp_file()
  798.                     log.debug("Temp file=%s" % f)
  799.  
  800.                     data = struct.pack(">8sBIHHBBBII", "hplip_g3", 1L, self.job_total_pages,  
  801.                         job_hort_dpi, job_vert_dpi, job_page_size, job_resolution, job_encoding, 
  802.                         0L, 0L)
  803.  
  804.                     os.write(f_fd, data)
  805.  
  806.                     job_page_num = 1
  807.  
  808.                     for fax_file in recipient_file_list:
  809.                         fax_file_name = fax_file[0]
  810.                         log.debug("Processing file: %s..." % fax_file_name)
  811.  
  812.                         if results[fax_file_name] == ERROR_SUCCESS:
  813.                             fax_file_fd = file(fax_file_name, 'r')
  814.                             header = fax_file_fd.read(FILE_HEADER_SIZE)
  815.  
  816.                             magic, version, total_pages, hort_dpi, vert_dpi, page_size, \
  817.                                 resolution, encoding, reserved1, reserved2 = self.decode_fax_header(header)
  818.  
  819.                             if magic != 'hplip_g3':
  820.                                 log.error("Invalid file header. Bad magic.")
  821.                                 state = STATE_ERROR
  822.                                 break
  823.  
  824.                             log.debug("Magic=%s Ver=%d Pages=%d hDPI=%d vDPI=%d Size=%d Res=%d Enc=%d" %
  825.                                       (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding))
  826.  
  827.                             for p in range(total_pages):
  828.                                 header = fax_file_fd.read(PAGE_HEADER_SIZE)
  829.  
  830.                                 page_num, ppr, rpp, bytes_to_read, thumbnail_bytes, reserved2 = \
  831.                                     self.decode_page_header(header)
  832.  
  833.                                 if page_num == -1:
  834.                                     log.error("Page header error")
  835.                                     state - STATE_ERROR
  836.                                     break
  837.  
  838.                                 header = struct.pack(">IIIIII", job_page_num, ppr, rpp, bytes_to_read, thumbnail_bytes, 0L)
  839.                                 os.write(f_fd, header)
  840.  
  841.                                 self.write_queue((STATUS_PROCESSING_FILES, job_page_num, ''))
  842.  
  843.                                 log.debug("Page=%d PPR=%d RPP=%d BPP=%d Thumb=%s" %
  844.                                           (page_num, ppr, rpp, bytes_to_read, thumbnail_bytes))                    
  845.  
  846.                                 os.write(f_fd, fax_file_fd.read(bytes_to_read))
  847.                                 job_page_num += 1
  848.  
  849.                             fax_file_fd.close()
  850.  
  851.                             if self.check_for_cancel():
  852.                                 state = STATE_ABORTED
  853.                                 break
  854.  
  855.                         else:
  856.                             log.error("Skipping file: %s" % fax_file_name)
  857.                             continue
  858.  
  859.                     os.close(f_fd)
  860.                     log.debug("Total pages=%d" % self.job_total_pages)
  861.  
  862.  
  863.             elif state == STATE_SEND_FAX: # --------------------------------- Send fax state machine (110, 0, 0)
  864.                 log.debug("%s State: Send fax" % ("*"*20))
  865.                 state = STATE_NEXT_RECIPIENT
  866.  
  867.                 FAX_SEND_STATE_DONE = 0
  868.                 FAX_SEND_STATE_ABORT = 10
  869.                 FAX_SEND_STATE_ERROR = 20
  870.                 FAX_SEND_STATE_BUSY = 25
  871.                 FAX_SEND_STATE_SUCCESS = 30
  872.                 FAX_SEND_STATE_DEVICE_OPEN = 40
  873.                 FAX_SEND_STATE_SET_TOKEN = 50
  874.                 FAX_SEND_STATE_EARLY_OPEN = 60
  875.                 FAX_SEND_STATE_SET_PARAMS = 70
  876.                 FAX_SEND_STATE_CHECK_IDLE = 80
  877.                 FAX_SEND_STATE_START_REQUEST = 90
  878.                 FAX_SEND_STATE_LATE_OPEN = 100
  879.                 FAX_SEND_STATE_SEND_DIAL_STRINGS = 110
  880.                 FAX_SEND_STATE_SEND_FAX_HEADER = 120
  881.                 FAX_SEND_STATE_SEND_PAGES = 130
  882.                 FAX_SEND_STATE_SEND_END_OF_STREAM = 140
  883.                 FAX_SEND_STATE_WAIT_FOR_COMPLETE = 150
  884.                 FAX_SEND_STATE_RESET_TOKEN = 160
  885.                 FAX_SEND_STATE_CLOSE_SESSION = 170
  886.  
  887.                 monitor_state = False
  888.                 fax_send_state = FAX_SEND_STATE_DEVICE_OPEN
  889.  
  890.                 while fax_send_state != FAX_SEND_STATE_DONE:
  891.  
  892.                     if self.check_for_cancel():
  893.                         log.error("Fax send aborted.")
  894.                         fax_send_state = FAX_SEND_STATE_ABORT
  895.  
  896.                     if monitor_state:
  897.                         fax_state = self.getFaxDownloadState() 
  898.                         if not fax_state in (pml.UPDN_STATE_XFERACTIVE, pml.UPDN_STATE_XFERDONE):
  899.                             log.error("D/L error state=%d" % fax_state)
  900.                             fax_send_state = FAX_SEND_STATE_ERROR
  901.                             state = STATE_ERROR
  902.  
  903.                     log.debug("STATE=(%d, %d, 0)" % (STATE_SEND_FAX, fax_send_state))
  904.  
  905.                     if fax_send_state == FAX_SEND_STATE_ABORT: # -------------- Abort (110, 10, 0)
  906.                         # TODO: Set D/L state to ???
  907.                         monitor_state = False
  908.                         fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  909.                         state = STATE_ABORTED
  910.  
  911.                     elif fax_send_state == FAX_SEND_STATE_ERROR: # -------------- Error (110, 20, 0)
  912.                         log.error("Fax send error.")
  913.                         monitor_state = False
  914.  
  915.                         fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  916.                         state = STATE_ERROR
  917.  
  918.                         #fax_send_state = FAX_SEND_STATE_DONE
  919.                         #state = STATE_NEXT_RECIPIENT
  920.  
  921.  
  922.                     elif fax_send_state == FAX_SEND_STATE_BUSY: # -------------- Busy (110, 25, 0)
  923.                         log.error("Fax device busy.")
  924.                         monitor_state = False
  925.                         fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  926.                         state = STATE_BUSY
  927.  
  928.                     elif fax_send_state == FAX_SEND_STATE_SUCCESS: # -------------- Success (110, 30, 0)
  929.                         log.debug("Fax send success.")
  930.                         monitor_state = False
  931.                         fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  932.                         state = STATE_NEXT_RECIPIENT
  933.  
  934.                     elif fax_send_state == FAX_SEND_STATE_DEVICE_OPEN: # -------------- Device open (110, 40, 0)
  935.                         log.debug("%s State: Open device" % ("*"*20))
  936.                         fax_send_state = FAX_SEND_STATE_SET_TOKEN
  937.                         try:
  938.                             self.dev.open()
  939.                         except Error, e:
  940.                             log.error("Unable to open device (%s)." % e.msg)
  941.                             fax_send_state = FAX_SEND_STATE_ERROR
  942.                         else:
  943.                             if self.dev.device_state == DEVICE_STATE_NOT_FOUND:
  944.                                 fax_send_state = FAX_SEND_STATE_ERROR
  945.  
  946.                     elif fax_send_state == FAX_SEND_STATE_SET_TOKEN: # -------------- Acquire fax token (110, 50, 0)
  947.                         log.debug("%s State: Acquire fax token" % ("*"*20))
  948.                         try:
  949.                             result_code, token = self.dev.getPML(pml.OID_FAX_TOKEN)
  950.                         except Error:
  951.                             log.debug("Unable to acquire fax token (1).")
  952.                             fax_send_state = FAX_SEND_STATE_EARLY_OPEN
  953.                         else:
  954.                             if result_code > pml.ERROR_MAX_OK:
  955.                                 fax_send_state = FAX_SEND_STATE_EARLY_OPEN
  956.                                 log.debug("Skipping token acquisition.")
  957.                             else:
  958.                                 token = time.strftime("%d%m%Y%H:%M:%S", time.gmtime())
  959.                                 log.debug("Setting token: %s" % token)
  960.                                 try:
  961.                                     self.dev.setPML(pml.OID_FAX_TOKEN, token)
  962.                                 except Error:
  963.                                     log.error("Unable to acquire fax token (2).")
  964.                                     fax_send_state = FAX_SEND_STATE_ERROR
  965.                                 else:
  966.                                     result_code, check_token = self.dev.getPML(pml.OID_FAX_TOKEN)
  967.  
  968.                                     if check_token == token:
  969.                                         fax_send_state = FAX_SEND_STATE_EARLY_OPEN
  970.                                     else:
  971.                                         log.error("Unable to acquire fax token (3).")
  972.                                         fax_send_state = FAX_SEND_STATE_ERROR
  973.  
  974.  
  975.                     elif fax_send_state == FAX_SEND_STATE_EARLY_OPEN: # -------------- Early open (newer models) (110, 60, 0)
  976.                         log.debug("%s State: Early open" % ("*"*20))
  977.                         fax_send_state = FAX_SEND_STATE_CHECK_IDLE
  978.  
  979.                         if self.dev.fax_type == FAX_TYPE_BLACK_SEND_EARLY_OPEN: # newer
  980.                             log.debug("Opening fax channel.")
  981.                             try:
  982.                                 self.dev.openFax()
  983.                             except Error, e:
  984.                                 log.error("Unable to open channel (%s)." % e.msg)
  985.                                 fax_send_state = FAX_SEND_STATE_ERROR
  986.                         else:
  987.                             log.debug("Skipped.")
  988.  
  989.  
  990.                     elif fax_send_state == FAX_SEND_STATE_CHECK_IDLE: # -------------- Check for initial idle (110, 80, 0)
  991.                         log.debug("%s State: Check idle" % ("*"*20))
  992.                         fax_send_state = FAX_SEND_STATE_START_REQUEST
  993.  
  994.                         dl_state = self.getFaxDownloadState()
  995.                         tx_status = self.getFaxJobTxStatus()
  996.                         rx_status = self.getFaxJobRxStatus()
  997.  
  998.                         if ((dl_state == pml.UPDN_STATE_IDLE or \
  999.                             dl_state == pml.UPDN_STATE_ERRORABORT or \
  1000.                             dl_state == pml.UPDN_STATE_XFERDONE) and \
  1001.                             (tx_status == pml.FAXJOB_TX_STATUS_IDLE or tx_status == pml.FAXJOB_TX_STATUS_DONE) and \
  1002.                             (rx_status == pml.FAXJOB_RX_STATUS_IDLE or rx_status == pml.FAXJOB_RX_STATUS_DONE)):
  1003.  
  1004.                             if state == pml.UPDN_STATE_IDLE:
  1005.                                 log.debug("Starting in idle state")
  1006.                             else:
  1007.                                 log.debug("Reseting to idle...")
  1008.                                 self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_IDLE)
  1009.                                 time.sleep(0.5)
  1010.                         else:
  1011.                             fax_send_state = FAX_SEND_STATE_BUSY
  1012.  
  1013.                     elif fax_send_state == FAX_SEND_STATE_START_REQUEST: # -------------- Request fax start (110, 90, 0) 
  1014.                         log.debug("%s State: Request start" % ("*"*20))
  1015.                         fax_send_state = FAX_SEND_STATE_SET_PARAMS
  1016.  
  1017.                         dl_state = self.getFaxDownloadState()
  1018.  
  1019.                         if dl_state == pml.UPDN_STATE_IDLE:
  1020.                             self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_REQSTART)
  1021.                             time.sleep(1)
  1022.  
  1023.                             log.debug("Waiting for active state...")
  1024.                             i = 0
  1025.  
  1026.                             while i < 10:
  1027.                                 log.debug("Try: %d" % i)
  1028.                                 try:
  1029.                                     dl_state = self.getFaxDownloadState()
  1030.                                 except Error:
  1031.                                     log.error("PML/SNMP error")
  1032.                                     fax_send_state = FAX_SEND_STATE_ERROR
  1033.                                     break
  1034.  
  1035.                                 if dl_state == pml.UPDN_STATE_XFERACTIVE:
  1036.                                     break
  1037.  
  1038.                                 time.sleep(1)
  1039.                                 self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_REQSTART)
  1040.  
  1041.                                 i += 1
  1042.  
  1043.                             else:  
  1044.                                 log.error("Could not get into active state!")
  1045.                                 fax_send_state = FAX_SEND_STATE_BUSY
  1046.  
  1047.                             monitor_state = True
  1048.  
  1049.                         else:
  1050.                             log.error("Could not get into idle state!")
  1051.                             fax_send_state = FAX_SEND_STATE_BUSY
  1052.  
  1053.  
  1054.                     elif fax_send_state == FAX_SEND_STATE_SET_PARAMS: # -------------- Set fax send params (110, 70, 0)
  1055.                         log.debug("%s State: Set params" % ("*"*20))
  1056.                         fax_send_state = FAX_SEND_STATE_LATE_OPEN
  1057.  
  1058.                         try:
  1059.                             self.dev.setPML(pml.OID_DEV_DOWNLOAD_TIMEOUT, pml.DEFAULT_DOWNLOAD_TIMEOUT)
  1060.                             self.dev.setPML(pml.OID_FAXJOB_TX_TYPE, pml.FAXJOB_TX_TYPE_HOST_ONLY)
  1061.                             log.debug("Setting date and time on device.")                            
  1062.                             self.dev.setDateAndTime() 
  1063.                         except Error, e:
  1064.                             log.error("PML/SNMP error (%s)" % e.msg)
  1065.                             fax_send_state = FAX_SEND_STATE_ERROR
  1066.  
  1067.  
  1068.                     elif fax_send_state == FAX_SEND_STATE_LATE_OPEN: # -------------- Late open (older models) (110, 100, 0)
  1069.                         log.debug("%s State: Late open" % ("*"*20))
  1070.                         fax_send_state = FAX_SEND_STATE_SEND_DIAL_STRINGS
  1071.  
  1072.                         if self.dev.fax_type == FAX_TYPE_BLACK_SEND_LATE_OPEN: # older
  1073.                             log.debug("Opening fax channel.")
  1074.                             try:
  1075.                                 self.dev.openFax()
  1076.                             except Error:
  1077.                                 log.error("Unable to open channel.")
  1078.                                 fax_send_state = FAX_SEND_STATE_ERROR
  1079.                         else:
  1080.                             log.debug("Skipped.")
  1081.  
  1082.  
  1083.                     elif fax_send_state == FAX_SEND_STATE_SEND_DIAL_STRINGS: # -------------- Dial strings (110, 110, 0)
  1084.                         log.debug("%s State: Send dial strings" % ("*"*20))
  1085.                         fax_send_state = FAX_SEND_STATE_SEND_FAX_HEADER
  1086.  
  1087.                         log.debug("Dialing: %s" % recipient.fax)
  1088.  
  1089.                         log.debug("Sending dial strings...")
  1090.                         self.create_mfpdtf_fixed_header(DT_DIAL_STRINGS, True, 
  1091.                             PAGE_FLAG_NEW_DOC | PAGE_FLAG_END_DOC | PAGE_FLAG_END_STREAM) # 0x1c on Windows, we were sending 0x0c
  1092.  
  1093.                         self.create_mfpdtf_dial_strings(recipient.fax)
  1094.  
  1095.                         try:
  1096.                             self.write_stream()
  1097.                         except Error:
  1098.                             log.error("Channel write error.")
  1099.                             fax_send_state = FAX_SEND_STATE_ERROR
  1100.  
  1101.  
  1102.                     elif fax_send_state == FAX_SEND_STATE_SEND_FAX_HEADER: # -------------- Fax header (110, 120, 0)
  1103.                         log.debug("%s State: Send fax header" % ("*"*20))
  1104.                         fax_send_state = FAX_SEND_STATE_SEND_PAGES
  1105.  
  1106.                         try:
  1107.                             ff = file(f, 'r')
  1108.                         except IOError:
  1109.                             log.error("Unable to read fax file.")
  1110.                             fax_send_state = FAX_SEND_STATE_ERROR
  1111.                             continue
  1112.  
  1113.                         try:
  1114.                             header = ff.read(FILE_HEADER_SIZE)
  1115.                         except IOError:
  1116.                             log.error("Unable to read fax file.")
  1117.                             fax_send_state = FAX_SEND_STATE_ERROR
  1118.                             continue
  1119.  
  1120.                         magic, version, total_pages, hort_dpi, vert_dpi, page_size, \
  1121.                             resolution, encoding, reserved1, reserved2 = self.decode_fax_header(header)
  1122.  
  1123.  
  1124.                         if magic != 'hplip_g3':
  1125.                             log.error("Invalid file header. Bad magic.")
  1126.                             fax_send_state = FAX_SEND_STATE_ERROR
  1127.                         else:
  1128.                             log.debug("Magic=%s Ver=%d Pages=%d hDPI=%d vDPI=%d Size=%d Res=%d Enc=%d" %
  1129.                                       (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding))
  1130.  
  1131.                             log.debug("Sending fax header...")
  1132.                             self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, True, PAGE_FLAG_NEW_DOC)
  1133.                             self.create_mfpdtf_fax_header(total_pages)
  1134.  
  1135.                             try:
  1136.                                 self.write_stream()
  1137.                             except Error:
  1138.                                 log.error("Unable to write to channel.")
  1139.                                 fax_send_state = FAX_SEND_STATE_ERROR
  1140.  
  1141.  
  1142.                     elif fax_send_state == FAX_SEND_STATE_SEND_PAGES:  # --------------------------------- Send fax pages state machine (110, 130, 0)
  1143.                         log.debug("%s State: Send pages" % ("*"*20))
  1144.                         fax_send_state = FAX_SEND_STATE_SEND_END_OF_STREAM
  1145.                         page = StringIO()
  1146.  
  1147.                         for p in range(total_pages):
  1148.  
  1149.                             if self.check_for_cancel():
  1150.                                 fax_send_state = FAX_SEND_STATE_ABORT
  1151.  
  1152.                             if fax_send_state == FAX_SEND_STATE_ABORT:
  1153.                                 break
  1154.  
  1155.                             try:
  1156.                                 header = ff.read(PAGE_HEADER_SIZE)
  1157.                             except IOError:
  1158.                                 log.error("Unable to read fax file.")
  1159.                                 fax_send_state = FAX_SEND_STATE_ERROR
  1160.                                 continue
  1161.  
  1162.                             page_num, ppr, rpp, bytes_to_read, thumbnail_bytes, reserved2 = \
  1163.                                 self.decode_page_header(header)
  1164.  
  1165.                             log.debug("Page=%d PPR=%d RPP=%d BPP=%d Thumb=%d" %
  1166.                                       (page_num, ppr, rpp, bytes_to_read, thumbnail_bytes))
  1167.  
  1168.                             page.write(ff.read(bytes_to_read))
  1169.                             thumbnail = ff.read(thumbnail_bytes) # thrown away for now (should be 0 read)
  1170.                             page.seek(0)
  1171.  
  1172.                             self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, page_flags=PAGE_FLAG_NEW_PAGE)
  1173.                             self.create_sop_record(page_num, hort_dpi, vert_dpi, ppr, rpp, encoding)
  1174.  
  1175.                             try:
  1176.                                 data = page.read(RASTER_DATA_SIZE)
  1177.                             except IOError:
  1178.                                 log.error("Unable to read fax file.")
  1179.                                 fax_send_state = FAX_SEND_STATE_ERROR
  1180.                                 continue
  1181.  
  1182.                             if data == '':
  1183.                                 log.error("No data!")
  1184.                                 fax_send_state = FAX_SEND_STATE_ERROR
  1185.                                 continue
  1186.  
  1187.                             self.create_raster_data_record(data)
  1188.                             total_read = RASTER_DATA_SIZE
  1189.  
  1190.                             while True:
  1191.                                 data = page.read(RASTER_DATA_SIZE)
  1192.                                 total_read += RASTER_DATA_SIZE
  1193.  
  1194.                                 self.getFaxDownloadState()
  1195.  
  1196.                                 if data == '':
  1197.                                     self.create_eop_record(rpp)
  1198.  
  1199.                                     try:
  1200.                                         self.write_stream()
  1201.                                     except Error:
  1202.                                         log.error("Channel write error.")
  1203.                                         fax_send_state = FAX_SEND_STATE_ERROR
  1204.                                     break
  1205.  
  1206.                                 else:
  1207.                                     try:
  1208.                                         self.write_stream()
  1209.                                     except Error:
  1210.                                         log.error("Channel write error.")
  1211.                                         fax_send_state = FAX_SEND_STATE_ERROR
  1212.                                         break
  1213.  
  1214.                                 status = self.getFaxJobTxStatus()
  1215.                                 while status  == pml.FAXJOB_TX_STATUS_DIALING:
  1216.                                     self.write_queue((STATUS_DIALING, 0, recipient.fax))
  1217.                                     time.sleep(1.0)
  1218.  
  1219.                                     if self.check_for_cancel():
  1220.                                         fax_send_state = FAX_SEND_STATE_ABORT
  1221.                                         break
  1222.  
  1223.                                     dl_state = self.getFaxDownloadState()
  1224.                                     if dl_state == pml.UPDN_STATE_ERRORABORT:
  1225.                                         fax_send_state = FAX_SEND_STATE_ERROR
  1226.                                         break
  1227.  
  1228.                                     status = self.getFaxJobTxStatus()
  1229.  
  1230.                                 if fax_send_state not in (FAX_SEND_STATE_ABORT, FAX_SEND_STATE_ERROR):
  1231.  
  1232.                                     while status  == pml.FAXJOB_TX_STATUS_CONNECTING: 
  1233.                                         self.write_queue((STATUS_CONNECTING, 0, recipient.fax))
  1234.                                         time.sleep(1.0)
  1235.  
  1236.                                         if self.check_for_cancel():
  1237.                                             fax_send_state = FAX_SEND_STATE_ABORT
  1238.                                             break
  1239.  
  1240.                                         dl_state = self.getFaxDownloadState()
  1241.                                         if dl_state == pml.UPDN_STATE_ERRORABORT:
  1242.                                             fax_send_state = FAX_SEND_STATE_ERROR
  1243.                                             break
  1244.  
  1245.                                         status = self.getFaxJobTxStatus()
  1246.  
  1247.                                 if status == pml.FAXJOB_TX_STATUS_TRANSMITTING:    
  1248.                                     self.write_queue((STATUS_SENDING, page_num, recipient.fax))
  1249.  
  1250.                                 self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, page_flags=0)
  1251.                                 self.create_raster_data_record(data)
  1252.  
  1253.                                 if fax_send_state in (FAX_SEND_STATE_ABORT, FAX_SEND_STATE_ERROR):
  1254.                                     break
  1255.  
  1256.                             page.truncate(0)
  1257.                             page.seek(0)                
  1258.  
  1259.  
  1260.                     elif fax_send_state == FAX_SEND_STATE_SEND_END_OF_STREAM: # -------------- EOS (110, 140, 0)
  1261.                         log.debug("%s State: Send EOS" % ("*"*20))
  1262.                         fax_send_state = FAX_SEND_STATE_WAIT_FOR_COMPLETE
  1263.                         log.debug("End of stream...")
  1264.                         self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, False, PAGE_FLAG_END_STREAM)
  1265.  
  1266.                         try:
  1267.                             self.write_stream()
  1268.                         except Error:
  1269.                             log.error("Channel write error.")
  1270.                             fax_send_state = FAX_SEND_STATE_ERROR
  1271.  
  1272.                         monitor_state = False
  1273.  
  1274.  
  1275.                     elif fax_send_state == FAX_SEND_STATE_WAIT_FOR_COMPLETE: # -------------- Wait for complete (110, 150, 0)
  1276.                         log.debug("%s State: Wait for completion" % ("*"*20))
  1277.  
  1278.                         fax_send_state = FAX_SEND_STATE_WAIT_FOR_COMPLETE
  1279.  
  1280.                         time.sleep(1.0)
  1281.                         status = self.getFaxJobTxStatus()
  1282.  
  1283.                         if status == pml.FAXJOB_TX_STATUS_DIALING:
  1284.                                 self.write_queue((STATUS_DIALING, 0, recipient.fax))
  1285.  
  1286.                         elif status == pml.FAXJOB_TX_STATUS_TRANSMITTING:    
  1287.                             self.write_queue((STATUS_SENDING, page_num, recipient.fax))
  1288.  
  1289.                         elif status in (pml.FAXJOB_TX_STATUS_DONE, pml.FAXJOB_RX_STATUS_IDLE):
  1290.                             fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  1291.                             state = STATE_NEXT_RECIPIENT
  1292.  
  1293.                         else:
  1294.                             self.write_queue((STATUS_SENDING, page_num, recipient.fax))
  1295.  
  1296.  
  1297.                     elif fax_send_state == FAX_SEND_STATE_RESET_TOKEN: # -------------- Release fax token (110, 160, 0)
  1298.                         self.write_queue((STATUS_CLEANUP, 0, ''))
  1299.                         log.debug("%s State: Release fax token" % ("*"*20))
  1300.  
  1301.                         try:
  1302.                             self.dev.setPML(pml.OID_FAX_TOKEN, '\x00'*16)
  1303.                         except Error:
  1304.                             log.error("Unable to release fax token.")
  1305.  
  1306.                         fax_send_state = FAX_SEND_STATE_CLOSE_SESSION
  1307.  
  1308.  
  1309.                     elif fax_send_state == FAX_SEND_STATE_CLOSE_SESSION: # -------------- Close session (110, 170, 0)
  1310.                         log.debug("%s State: Close session" % ("*"*20))
  1311.                         fax_send_state = FAX_SEND_STATE_DONE
  1312.                         log.debug("Closing session...")
  1313.  
  1314.                         try:
  1315.                             mm.close()
  1316.                         except NameError:
  1317.                             pass
  1318.  
  1319.                         try:
  1320.                             ff.close()
  1321.                         except NameError:
  1322.                             pass
  1323.  
  1324.                         if self.dev.fax_type == FAX_TYPE_BLACK_SEND_LATE_OPEN:
  1325.                             log.debug("Closing fax channel.")
  1326.                             self.dev.closeFax()
  1327.  
  1328.                         self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_IDLE)
  1329.  
  1330.                         time.sleep(1)
  1331.  
  1332.                         if self.dev.fax_type == FAX_TYPE_BLACK_SEND_EARLY_OPEN:
  1333.                             log.debug("Closing fax channel.")
  1334.                             self.dev.closeFax()
  1335.  
  1336.                         self.dev.close()
  1337.  
  1338.  
  1339.             elif state == STATE_CLEANUP: # --------------------------------- Cleanup (120, 0, 0)
  1340.                 log.debug("%s State: Cleanup" % ("*"*20))
  1341.  
  1342.                 if self.remove_temp_file:
  1343.                     log.debug("Removing merged file: %s" % f)
  1344.                     try:
  1345.                         os.remove(f)
  1346.                         log.debug("Removed")
  1347.                     except OSError:
  1348.                         log.debug("Not found")
  1349.  
  1350.                 state = STATE_DONE
  1351.  
  1352.  
  1353.  
  1354. # --------------------------------- Support functions
  1355.  
  1356.     def next_recipient_gen(self):
  1357.         for a in self.phone_num_list:
  1358.             yield a
  1359.  
  1360.  
  1361.     def render_file(self, path, title, mime_type, force_single_page=False):
  1362.         all_pages = True 
  1363.         page_range = ''
  1364.         page_set = 0
  1365.         nup = 1
  1366.  
  1367.         cups.resetOptions()
  1368.  
  1369.         if mime_type in ["application/x-cshell",
  1370.                          "application/x-perl",
  1371.                          "application/x-python",
  1372.                          "application/x-shell",
  1373.                          "text/plain",]:
  1374.  
  1375.             cups.addOption('prettyprint')
  1376.  
  1377.         if nup > 1:
  1378.             cups.addOption('number-up=%d' % nup)
  1379.  
  1380.         if force_single_page:
  1381.             cups.addOption('page-ranges=1') # Force coverpage to 1 page
  1382.  
  1383.         sent_job_id = cups.printFile(self.current_printer, path, title)
  1384.         cups.resetOptions()
  1385.  
  1386.         log.debug("Job ID=%d" % sent_job_id)    
  1387.         job_id = 0
  1388.  
  1389.         time.sleep(1)
  1390.  
  1391.         fax_file = ''
  1392.         complete = False
  1393.  
  1394.         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1395.         try:
  1396.             sock.connect((prop.hpssd_host, prop.hpssd_port))
  1397.         except socket.error:
  1398.             log.error("Unable to contact HPLIP I/O (hpssd).")
  1399.             return '', True   
  1400.  
  1401.         end_time = time.time() + 120.0 
  1402.         while time.time() < end_time:
  1403.             log.debug("Waiting for fax...")
  1404.             fields, data, result_code = \
  1405.                 msg.xmitMessage(sock, "FaxCheck", None,
  1406.                                      {"username": prop.username,
  1407.                                      })
  1408.  
  1409.             if result_code == ERROR_FAX_PROCESSING:
  1410.                 log.debug("Fax is being rendered...")
  1411.  
  1412.             elif result_code == ERROR_FAX_READY:
  1413.                 break
  1414.  
  1415.             if self.check_for_cancel():
  1416.                 log.error("Render canceled. Canceling job #%d..." % sent_job_id)
  1417.                 cups.cancelJob(sent_job_id)
  1418.                 os.close(fd)
  1419.                 sock.close()
  1420.                 return '', True
  1421.  
  1422.             time.sleep(1)
  1423.  
  1424.         else:
  1425.             log.error("Timeout waiting for rendering. Canceling job #%d..." % sent_job_id)
  1426.             cups.cancelJob(sent_job_id)
  1427.             return '', False
  1428.  
  1429.         fd, fax_file = utils.make_temp_file()
  1430.  
  1431.         while True:
  1432.             log.debug("Transfering fax data...")
  1433.             fields, data, result_code = \
  1434.                 msg.xmitMessage(sock, "FaxGetData", None,
  1435.                                      {"username": prop.username,
  1436.                                       "job-id": sent_job_id,
  1437.                                      })
  1438.  
  1439.             if data and result_code == ERROR_SUCCESS:
  1440.                 os.write(fd, data)
  1441.  
  1442.             else:
  1443.                 complete = True
  1444.                 break
  1445.  
  1446.             if self.check_for_cancel():
  1447.                 log.error("Render canceled. Canceling job #%d..." % sent_job_id)
  1448.                 cups.cancelJob(sent_job_id)
  1449.                 os.close(fd)
  1450.                 sock.close()
  1451.                 return '', True
  1452.  
  1453.  
  1454.         os.close(fd)
  1455.         sock.close()
  1456.  
  1457.         return fax_file, False
  1458.  
  1459.  
  1460.     def check_for_cancel(self):
  1461.         canceled = False
  1462.         while self.event_queue.qsize():
  1463.             try:
  1464.                 event = self.event_queue.get(0)
  1465.                 if event[0] == EVENT_FAX_SEND_CANCELED:
  1466.                     canceled = True
  1467.                     log.debug("Cancel pressed!")
  1468.             except Queue.Empty:
  1469.                 break
  1470.  
  1471.         return canceled
  1472.  
  1473.     def render_cover_page(self, a):
  1474.         log.debug("Creating cover page...")
  1475.  
  1476.         pdf = self.cover_func(page_size=coverpages.PAGE_SIZE_LETTER,
  1477.                               total_pages=self.job_total_pages, 
  1478.  
  1479.                               recipient_name=a.name, 
  1480.                               recipient_phone='', # ???
  1481.                               recipient_fax=a.fax, 
  1482.  
  1483.                               sender_name=self.sender_name, 
  1484.                               sender_phone=user_cfg.fax.voice_phone, 
  1485.                               sender_fax=self.sender_fax,
  1486.                               sender_email=user_cfg.fax.email_address, 
  1487.  
  1488.                               regarding=self.cover_re, 
  1489.                               message=self.cover_message)
  1490.  
  1491.         log.debug("PDF File=%s" % pdf)
  1492.         fax_file, canceled = self.render_file(pdf, 'Cover Page', "application/pdf", force_single_page=True) 
  1493.  
  1494.         try:
  1495.             os.remove(pdf)
  1496.         except IOError:
  1497.             pass
  1498.  
  1499.         return fax_file, canceled
  1500.  
  1501.  
  1502.     def write_queue(self, message):
  1503.         if self.update_queue is not None and message != self.prev_update:
  1504.             self.update_queue.put(message)
  1505.             time.sleep(0)
  1506.             self.prev_update = message
  1507.  
  1508.     def getFaxDownloadState(self):
  1509.         result_code, state = self.dev.getPML(pml.OID_FAX_DOWNLOAD)
  1510.         log.debug("D/L State=%d (%s)" % (state, pml.UPDN_STATE_STR.get(state, 'Unknown')))
  1511.         return state
  1512.  
  1513.     def getFaxJobTxStatus(self):
  1514.         result_code, status = self.dev.getPML(pml.OID_FAXJOB_TX_STATUS)
  1515.         log.debug("Tx Status=%d (%s)" % (status, pml.FAXJOB_TX_STATUS_STR.get(status, 'Unknown')))
  1516.         return status
  1517.  
  1518.     def getFaxJobRxStatus(self):
  1519.         result_code, status = self.dev.getPML(pml.OID_FAXJOB_RX_STATUS)
  1520.         log.debug("Rx Status=%d (%s)" % (status, pml.FAXJOB_RX_STATUS_STR.get(status, 'Unknown')))
  1521.         return status
  1522.  
  1523.     def getCfgUploadState(self):
  1524.         result_code, state = self.dev.getPML(pml.OID_DEVICE_CFG_UPLOAD)
  1525.         log.debug("Cfg Upload State = %d (%s)" % (state, pml.UPDN_STATE_STR.get(state, 'Unknown')))
  1526.         return state
  1527.  
  1528.     def create_mfpdtf_fixed_header(self, data_type, send_variant=False, page_flags=0):
  1529.         header_len = FIXED_HEADER_SIZE
  1530.  
  1531.         if send_variant:
  1532.             if data_type == DT_DIAL_STRINGS:
  1533.                     header_len += DIAL_STRINGS_VARIANT_HEADER_SIZE
  1534.  
  1535.             elif data_type == DT_FAX_IMAGES:
  1536.                 header_len += FAX_IMAGE_VARIANT_HEADER_SIZE
  1537.  
  1538.         self.stream.write(struct.pack("<IHBB", 
  1539.                           0, header_len, data_type, page_flags))
  1540.  
  1541.  
  1542.     def create_mfpdtf_dial_strings(self, number):
  1543.         self.stream.write(struct.pack("<BBHH51s", 
  1544.                           MAJOR_VER, MINOR_VER,
  1545.                           1, 51, number[:51]))
  1546.  
  1547.  
  1548.     def adjust_fixed_header_block_size(self):
  1549.         size = self.stream.tell()
  1550.         self.stream.seek(0)
  1551.         self.stream.write(struct.pack("<I", size))
  1552.  
  1553.  
  1554.     def create_sop_record(self, page_num, hort_dpi, vert_dpi, ppr, rpp, encoding, bpp=1):
  1555.         self.stream.write(struct.pack("<BBHHHIHHHHHHIHHHH",
  1556.                             RT_START_PAGE, encoding, page_num,
  1557.                             ppr, bpp,
  1558.                             rpp, 0x00, hort_dpi, 0x00, vert_dpi,
  1559.                             ppr, bpp,
  1560.                             rpp, 0x00, hort_dpi, 0x00, vert_dpi))
  1561.  
  1562.  
  1563.     def create_eop_record(self, rpp):
  1564.         self.stream.write(struct.pack("<BBBBII",
  1565.                             RT_END_PAGE, 0, 0, 0, 
  1566.                             rpp, 0,))
  1567.  
  1568.  
  1569.     def create_raster_data_record(self, data):
  1570.         assert len(data) <= RASTER_DATA_SIZE
  1571.         self.stream.write(struct.pack("<BBH",
  1572.                         RT_RASTER, 0, len(data),))
  1573.         self.stream.write(data)
  1574.  
  1575.  
  1576.     def create_mfpdtf_fax_header(self, total_pages):
  1577.         self.stream.write(struct.pack("<BBBHBI20s20s20sI", 
  1578.                             MAJOR_VER, MINOR_VER, SRC_HOST, total_pages, 
  1579.                             TTI_PREPENDED_TO_IMAGE, 0, '', '', '', 0))
  1580.  
  1581.  
  1582.     def write_stream(self):
  1583.         self.adjust_fixed_header_block_size() 
  1584.         self.dev.writeFax(self.stream.getvalue())
  1585.         self.stream.truncate(0)
  1586.         self.stream.seek(0)    
  1587.  
  1588.  
  1589.     def decode_fax_header(self, header):
  1590.         try:
  1591.             return struct.unpack(">8sBIHHBBBII", header)
  1592.         except struct.error:
  1593.             return -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
  1594.  
  1595.     def decode_page_header(self, header):
  1596.         try:
  1597.             return struct.unpack(">IIIIII", header)
  1598.         except struct.error:
  1599.             return -1, -1, -1, -1, -1, -1
  1600.