home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.5) from __future__ import generators import sys import os import os.path as os import mmap import struct import time import threading import Queue import socket from cStringIO import StringIO from base.g import * from base.codes import * from base import device, utils, status, pml, msg from base.kirbybase import KirbyBase from prnt import cups try: import coverpages except ImportError: pass PAGE_FLAG_NONE = 0 PAGE_FLAG_NEW_PAGE = 1 PAGE_FLAG_END_PAGE = 2 PAGE_FLAG_NEW_DOC = 4 PAGE_FLAG_END_DOC = 8 PAGE_FLAG_END_STREAM = 16 MAJOR_VER = 2 MINOR_VER = 0 MFPDTF_RASTER_BITMAP = 0 MFPDTF_RASTER_GRAYMAP = 1 MFPDTF_RASTER_MH = 2 MFPDTF_RASTER_MR = 3 MFPDTF_RASTER_MMR = 4 MFPDTF_RASTER_RGB = 5 MFPDTF_RASTER_YCC411 = 6 MFPDTF_RASTER_JPEG = 7 MFPDTF_RASTER_PCL = 8 MFPDTF_RASTER_NOT = 9 DT_UNKNOWN = 0 DT_FAX_IMAGES = 1 DT_SCANNED_IMAGES = 2 DT_DIAL_STRINGS = 3 DT_DEMO_PAGES = 4 DT_SPEED_DIALS = 5 DT_FAX_LOGS = 6 DT_CFG_PARMS = 7 DT_LANG_STRS = 8 DT_JUNK_FAX_CSIDS = 9 DT_REPORT_STRS = 10 DT_FONTS = 11 DT_TTI_BITMAP = 12 DT_COUNTERS = 13 DT_DEF_PARMS = 14 DT_SCAN_OPTIONS = 15 DT_FW_JOB_TABLE = 17 RT_START_PAGE = 0 RT_RASTER = 1 RT_END_PAGE = 2 FIXED_HEADER_SIZE = 8 IMAGE_VARIANT_HEADER_SIZE = 10 DIAL_STRINGS_VARIANT_HEADER_SIZE = 6 FAX_IMAGE_VARIANT_HEADER_SIZE = 74 SOP_RECORD_SIZE = 36 RASTER_RECORD_SIZE = 4 EOP_RECORD_SIZE = 12 DIAL_STRING_RECORD_SIZE = 51 PAGE_FLAG_NEW_PAGE = 1 PAGE_FLAG_END_PAGE = 2 PAGE_FLAG_NEW_DOC = 4 PAGE_FLAG_END_DOC = 8 PAGE_FLAG_END_STREAM = 16 SRC_UNKNOWN = 0 SRC_HOST = 2 SRC_SCANNER = 5 SRC_HOST_THEN_SCANNER = 6 SRC_SCANNER_THEN_HOST = 7 TTI_NONE = 0 TTI_PREPENDED_TO_IMAGE = 1 TTI_OVERLAYED_ON_IMAGE = 2 RASTER_DATA_SIZE = 504 STATUS_IDLE = 0 STATUS_PROCESSING_FILES = 1 STATUS_DIALING = 2 STATUS_CONNECTING = 3 STATUS_SENDING = 4 STATUS_COMPLETED = 5 STATUS_CREATING_COVER_PAGE = 6 STATUS_ERROR = 7 STATUS_BUSY = 8 STATUS_CLEANUP = 9 EVENT_FAX_SEND_CANCELED = 1 FILE_HEADER_SIZE = 28 PAGE_HEADER_SIZE = 24 class FaxAddressBook(KirbyBase): def __init__(self): KirbyBase.__init__(self) t = os.path.expanduser('~/.hplip.fab') self._fab = os.path.expanduser('~/hpfax/fab.db') fax_dir = os.path.expanduser('~/hpfax') if not os.path.exists(fax_dir): os.mkdir(fax_dir) if os.path.exists(t) and not os.path.exists(self._fab): import shutil shutil.move(t, self._fab) if not os.path.exists(self._fab): log.debug('Creating new fax address book: %s' % self._fab) self.create() def create(self): return KirbyBase.create(self, self._fab, [ 'name:str', 'title:str', 'firstname:str', 'lastname:str', 'fax:str', 'groups:str', 'notes:str']) def filename(self): return self._fab def last_modification_time(self): return os.stat(self._fab).st_mtime def close(self): return KirbyBase.close(self) def insert(self, values): return KirbyBase.insert(self, self._fab, values) def insertBatch(self, batchRecords): return KirbyBase.insertBatch(self, self._fab, batchRecords) def update(self, fields, searchData, updates, filter = None, useRegExp = False): return KirbyBase.update(self, self._fab, fields, searchData, updates, filter, useRegExp) def delete(self, fields, searchData, useRegExp = False): return KirbyBase.delete(self, self._fab, fields, searchData, useRegExp) def select(self, fields, searchData, filter = None, useRegExp = False, sortFields = [], sortDesc = [], returnType = 'list', rptSettings = [ 0, False]): return KirbyBase.select(self, self._fab, fields, searchData, filter, useRegExp, sortFields, sortDesc, returnType, rptSettings) def pack(self): return KirbyBase.pack(self, self._fab) def validate(self): return KirbyBase.validate(self, self._fab) def drop(self): return KirbyBase.drop(self, self._fab) def getFieldNames(self): return KirbyBase.getFieldNames(self, self._fab) def getFieldTypes(self): return KirbyBase.getFieldTypes(self, self._fab) def len(self): return KirbyBase.len(self, self._fab) def GetEntryByRecno(self, recno): return AddressBookEntry(self.select([ 'recno'], [ recno])[0]) def AllRecords(self): return self.select([ 'recno'], [ '*']) def AllRecordEntries(self): return [ AddressBookEntry(rec) for rec in self.select([ 'recno'], [ '*']) ] def GroupEntries(self, group): return _[1] def AllGroups(self): temp = { } for abe in self.AllRecordEntries(): for g in abe.group_list: temp.setdefault(g) return temp.keys() def UpdateGroupEntries(self, group_name, member_entries): for entry in self.AllRecordEntries(): if entry.name in member_entries: if group_name not in entry.group_list: entry.group_list.append(group_name) self.update([ 'recno'], [ entry.recno], [ ','.join(entry.group_list)], [ 'groups']) group_name not in entry.group_list if group_name in entry.group_list: entry.group_list.remove(group_name) self.update([ 'recno'], [ entry.recno], [ ','.join(entry.group_list)], [ 'groups']) continue def DeleteGroup(self, group_name): for entry in self.AllRecordEntries(): if group_name in entry.group_list: entry.group_list.remove(group_name) self.update([ 'recno'], [ entry.recno], [ ','.join(entry.group_list)], [ 'groups']) continue class AddressBookEntry(object): def __init__(self, rec = None): if rec is not None: rec = [ '' for x in rec ] (self.recno, self.name, self.title, self.firstname, self.lastname, self.fax, self.groups, self.notes) = rec self.group_list = [] if len(self.groups): for g in self.groups.split(','): self.group_list.append(g.strip()) def __str__(self): return 'Recno=%d, Name=%s, Title=%s, First=%s, Last=%s, Fax=%s, Groups=%s, Notes=%s\n' % (self.recno, self.name, self.title, self.firstname, self.lastname, self.fax, self.group_list, self.notes) class FaxDevice(device.Device): def __init__(self, device_uri = None, printer_name = None, hpssd_sock = None, hpiod_sock = None, callback = None): device.Device.__init__(self, device_uri, printer_name, hpssd_sock, hpiod_sock, callback) self.send_fax_thread = None self.upload_log_thread = None def setPhoneNum(self, num): return self.setPML(pml.OID_FAX_LOCAL_PHONE_NUM, str(num)) def getPhoneNum(self): return utils.printable(str(self.getPML(pml.OID_FAX_LOCAL_PHONE_NUM)[1])) phone_num = property(getPhoneNum, setPhoneNum, doc = 'OID_FAX_LOCAL_PHONE_NUM') def setStationName(self, name): return self.setPML(pml.OID_FAX_STATION_NAME, str(name)) def getStationName(self): return utils.printable(str(self.getPML(pml.OID_FAX_STATION_NAME)[1])) station_name = property(getStationName, setStationName, doc = 'OID_FAX_STATION_NAME') def setDateAndTime(self): t = time.localtime() p = struct.pack('BBBBBBB', t[0] - 2000, t[1], t[2], t[6] + 1, t[3], t[4], t[5]) log.debug(repr(p)) return self.setPML(pml.OID_DATE_AND_TIME, p) def uploadLog(self): if not self.isUloadLogActive(): self.upload_log_thread = UploadLogThread(self) self.upload_log_thread.start() return True else: return False def isUploadLogActive(self): if self.upload_log_thread is not None: return self.upload_log_thread.isAlive() else: return False def waitForUploadLogThread(self): if self.upload_log_thread is not None and self.upload_log_thread.isAlive(): self.upload_log_thread.join() def sendFaxes(self, phone_num_list, fax_file_list, cover_message = '', cover_re = '', cover_func = None, printer_name = '', update_queue = None, event_queue = None): if not self.isSendFaxActive(): self.send_fax_thread = FaxSendThread(self, phone_num_list, fax_file_list, cover_message, cover_re, cover_func, printer_name, update_queue, event_queue) self.send_fax_thread.start() return True else: return False def isSendFaxActive(self): if self.send_fax_thread is not None: return self.send_fax_thread.isAlive() else: return False def waitForSendFaxThread(self): if self.send_fax_thread is not None and self.send_fax_thread.isAlive(): self.send_fax_thread.join() class UploadLogThread(threading.Thread): def __init__(self, dev): threading.Thread.__init__(self) self.dev = dev def run(self): STATE_DONE = 0 STATE_ABORT = 10 STATE_SUCCESS = 20 STATE_BUSY = 25 STATE_DEVICE_OPEN = 28 STATE_CHECK_IDLE = 30 STATE_REQUEST_START = 40 STATE_WAIT_FOR_ACTIVE = 50 STATE_UPLOAD_DATA = 60 STATE_DEVICE_CLOSE = 70 state = STATE_CHECK_IDLE while state != STATE_DONE: if state == STATE_ABORT: continue if state == STATE_SUCCESS: continue if state == STATE_BUSY: continue if state == STATE_DEVICE_OPEN: state = STATE_REQUEST_START try: self.dev.open() except Error: e = None log.error('Unable to open device (%s).' % e.msg) state = STATE_ERROR try: dev.setPML(pml.OID_UPLOAD_TIMEOUT, pml.DEFAULT_UPLOAD_TIMEOUT) except Error: state = STATE_ERROR except: None<EXCEPTION MATCH>Error None<EXCEPTION MATCH>Error if state == STATE_CHECK_IDLE: state = STATE_REQUEST_START ul_state = self.getCfgUploadState() if ul_state != pml.UPDN_STATE_IDLE: state = STATE_BUSY ul_state != pml.UPDN_STATE_IDLE if state == STATE_REQUEST_START: state = STATE_WAIT_FOR_ACTIVE self.dev.setPML(pml.OID_FAX_CFG_UPLOAD_DATA_TYPE, pml.FAX_CFG_UPLOAD_DATA_TYPE_FAXLOGS) self.dev.setPML(pml.OID_DEVICE_CFG_UPLOAD, pml.UPDN_STATE_REQSTART) continue if state == STATE_WAIT_FOR_ACTIVE: state = STATE_UPLOAD_DATA tries = 0 while True: tries += 1 ul_state = self.getCfgUploadState() if ul_state == pml.UPDN_STATE_XFERACTIVE: break if ul_state in (pml.UPDN_STATE_ERRORABORT, pml.UPDN_STATE_XFERDONE): log.error('Cfg upload aborted!') state = STATE_ERROR break if tries > 10: state = STATE_ERROR log.error('Unable to get into active state!') break time.sleep(0.5) continue if state == STATE_UPLOAD_DATA: continue if state == STATE_DEVICE_CLOSE: self.dev.close() continue class FaxSendThread(threading.Thread): def __init__(self, dev, phone_num_list, fax_file_list, cover_message = '', cover_re = '', cover_func = None, printer_name = '', update_queue = None, event_queue = None): threading.Thread.__init__(self) self.dev = dev self.phone_num_list = phone_num_list self.fax_file_list = fax_file_list self.update_queue = update_queue self.event_queue = event_queue self.cover_message = cover_message self.cover_re = cover_re self.cover_func = cover_func self.current_printer = printer_name self.stream = StringIO() self.prev_update = '' self.remove_temp_file = False def run(self): results = { } STATE_DONE = 0 STATE_ABORTED = 10 STATE_SUCCESS = 20 STATE_BUSY = 25 STATE_READ_SENDER_INFO = 30 STATE_PRERENDER = 40 STATE_COUNT_PAGES = 50 STATE_NEXT_RECIPIENT = 60 STATE_COVER_PAGE = 70 STATE_SINGLE_FILE = 80 STATE_MERGE_FILES = 90 STATE_SINGLE_FILE = 100 STATE_SEND_FAX = 110 STATE_CLEANUP = 120 STATE_ERROR = 130 next_recipient = self.next_recipient_gen() state = STATE_READ_SENDER_INFO self.rendered_file_list = [] while state != STATE_DONE: if self.check_for_cancel(): state = STATE_ABORTED log.debug('STATE=(%d, 0, 0)' % state) if state == STATE_ABORTED: log.error('Aborted by user.') self.write_queue((STATUS_IDLE, 0, '')) state = STATE_CLEANUP continue if state == STATE_SUCCESS: log.debug('Success.') self.write_queue((STATUS_COMPLETED, 0, '')) state = STATE_CLEANUP continue if state == STATE_ERROR: log.error('Error, aborting.') self.write_queue((STATUS_ERROR, 0, '')) state = STATE_CLEANUP continue if state == STATE_BUSY: log.error('Device busy, aborting.') self.write_queue((STATUS_BUSY, 0, '')) state = STATE_CLEANUP continue if state == STATE_READ_SENDER_INFO: log.debug('%s State: Get sender info' % '********************') state = STATE_PRERENDER try: self.dev.open() except Error: e = None log.error('Unable to open device (%s).' % e.msg) state = STATE_ERROR else: try: self.sender_name = self.dev.station_name log.debug('Sender name=%s' % self.sender_name) self.sender_fax = self.dev.phone_num log.debug('Sender fax=%s' % self.sender_fax) except Error: log.error('PML get failed!') state = STATE_ERROR finally: self.dev.close() continue if state == STATE_PRERENDER: log.debug('%s State: Pre-render non-G3 files' % '********************') state = STATE_COUNT_PAGES cover_page_present = False log.debug(self.fax_file_list) for fax_file in self.fax_file_list: (fax_file_name, fax_file_type, fax_file_desc, fax_file_title, fax_file_pages) = fax_file if fax_file_type == 'application/hplip-fax-coverpage': cover_page_present = True log.debug('Skipping coverpage') else: self.rendered_file_list.append((fax_file_name, 'application/hplip-fax', 'HP Fax', fax_file_title)) log.debug('Processing pre-rendered file: %s (%d pages)' % (fax_file_name, fax_file_pages)) if self.check_for_cancel(): state = STATE_ABORTED continue log.debug(self.rendered_file_list) continue if state == STATE_COUNT_PAGES: log.debug('%s State: Get total page count' % '********************') state = STATE_NEXT_RECIPIENT recipient_file_list = self.rendered_file_list[:] log.debug('Counting total pages...') self.job_total_pages = 0 log.debug(recipient_file_list) i = 0 for fax_file in recipient_file_list: fax_file_name = fax_file[0] log.debug('Processing file (counting pages): %s...' % fax_file_name) if os.path.exists(fax_file_name): results[fax_file_name] = ERROR_SUCCESS fax_file_fd = file(fax_file_name, 'r') header = fax_file_fd.read(FILE_HEADER_SIZE) (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding, reserved1, reserved2) = self.decode_fax_header(header) if magic != 'hplip_g3': log.error('Invalid file header. Bad magic.') results[fax_file_name] = ERROR_FAX_INVALID_FAX_FILE state = STATE_ERROR continue if not i: (job_hort_dpi, job_vert_dpi, job_page_size, job_resolution, job_encoding) = (hort_dpi, vert_dpi, page_size, resolution, encoding) i += 1 elif job_hort_dpi != hort_dpi and job_vert_dpi != vert_dpi and job_page_size != page_size and job_resolution != resolution or job_encoding != encoding: log.error('Incompatible options for file: %s' % fax_file_name) results[fax_file_name] = ERROR_FAX_INCOMPATIBLE_OPTIONS state = STATE_ERROR log.debug('Magic=%s Ver=%d Pages=%d hDPI=%d vDPI=%d Size=%d Res=%d Enc=%d' % (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding)) self.job_total_pages += total_pages fax_file_fd.close() else: log.error('Unable to find HP Fax file: %s' % fax_file_name) results[fax_file_name] = ERROR_FAX_FILE_NOT_FOUND state = STATE_ERROR break if self.check_for_cancel(): state = STATE_ABORTED break continue if cover_page_present: self.job_total_pages += 1 log.debug('Total fax pages=%d' % self.job_total_pages) continue if state == STATE_NEXT_RECIPIENT: log.debug('%s State: Next recipient' % '********************') state = STATE_COVER_PAGE try: recipient = next_recipient.next() log.debug('Processing for recipient %s' % recipient.name) except StopIteration: state = STATE_SUCCESS log.debug('Last recipient.') continue recipient_file_list = self.rendered_file_list[:] continue if state == STATE_COVER_PAGE: log.debug('%s State: Render cover page' % '********************') if self.job_total_pages > 1: state = STATE_MERGE_FILES else: state = STATE_SINGLE_FILE if cover_page_present: log.debug('Creating cover page for recipient: %s' % recipient.name) (fax_file, canceled) = self.render_cover_page(recipient) if canceled: state = STATE_ABORTED elif not fax_file: state = STATE_ERROR else: recipient_file_list.insert(0, (fax_file, 'application/hplip-fax', 'HP Fax', 'Cover Page')) log.debug('Cover page G3 file: %s' % fax_file) results[fax_file] = ERROR_SUCCESS cover_page_present if state == STATE_SINGLE_FILE: log.debug('%s State: Handle single file' % '********************') state = STATE_SEND_FAX log.debug('Processing single file...') f = recipient_file_list[0][0] try: f_fd = file(f, 'r') except IOError: log.error('Unable to open fax file: %s' % f) state = STATE_ERROR header = f_fd.read(FILE_HEADER_SIZE) (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding, reserved1, reserved2) = self.decode_fax_header(header) results[f] = ERROR_SUCCESS if magic != 'hplip_g3': log.error('Invalid file header. Bad magic.') results[f] = ERROR_FAX_INVALID_FAX_FILE state = STATE_ERROR log.debug('Magic=%s Ver=%d Pages=%d hDPI=%d vDPI=%d Size=%d Res=%d Enc=%d' % (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding)) f_fd.close() continue if state == STATE_MERGE_FILES: log.debug('%s State: Merge multiple files' % '********************') log.debug(recipient_file_list) log.debug('Merging g3 files...') state = STATE_SEND_FAX self.remove_temp_file = True if self.job_total_pages: (f_fd, f) = utils.make_temp_file() log.debug('Temp file=%s' % f) data = struct.pack('>8sBIHHBBBII', 'hplip_g3', 0x1L, self.job_total_pages, job_hort_dpi, job_vert_dpi, job_page_size, job_resolution, job_encoding, 0x0L, 0x0L) os.write(f_fd, data) job_page_num = 1 for fax_file in recipient_file_list: fax_file_name = fax_file[0] log.debug('Processing file: %s...' % fax_file_name) if results[fax_file_name] == ERROR_SUCCESS: fax_file_fd = file(fax_file_name, 'r') header = fax_file_fd.read(FILE_HEADER_SIZE) (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding, reserved1, reserved2) = self.decode_fax_header(header) if magic != 'hplip_g3': log.error('Invalid file header. Bad magic.') state = STATE_ERROR break log.debug('Magic=%s Ver=%d Pages=%d hDPI=%d vDPI=%d Size=%d Res=%d Enc=%d' % (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding)) for p in range(total_pages): header = fax_file_fd.read(PAGE_HEADER_SIZE) (page_num, ppr, rpp, bytes_to_read, thumbnail_bytes, reserved2) = self.decode_page_header(header) if page_num == -1: log.error('Page header error') state - STATE_ERROR break header = struct.pack('>IIIIII', job_page_num, ppr, rpp, bytes_to_read, thumbnail_bytes, 0x0L) os.write(f_fd, header) self.write_queue((STATUS_PROCESSING_FILES, job_page_num, '')) log.debug('Page=%d PPR=%d RPP=%d BPP=%d Thumb=%s' % (page_num, ppr, rpp, bytes_to_read, thumbnail_bytes)) os.write(f_fd, fax_file_fd.read(bytes_to_read)) job_page_num += 1 fax_file_fd.close() if self.check_for_cancel(): state = STATE_ABORTED break self.check_for_cancel() log.error('Skipping file: %s' % fax_file_name) os.close(f_fd) log.debug('Total pages=%d' % self.job_total_pages) self.job_total_pages if state == STATE_SEND_FAX: log.debug('%s State: Send fax' % '********************') state = STATE_NEXT_RECIPIENT FAX_SEND_STATE_DONE = 0 FAX_SEND_STATE_ABORT = 10 FAX_SEND_STATE_ERROR = 20 FAX_SEND_STATE_BUSY = 25 FAX_SEND_STATE_SUCCESS = 30 FAX_SEND_STATE_DEVICE_OPEN = 40 FAX_SEND_STATE_SET_TOKEN = 50 FAX_SEND_STATE_EARLY_OPEN = 60 FAX_SEND_STATE_SET_PARAMS = 70 FAX_SEND_STATE_CHECK_IDLE = 80 FAX_SEND_STATE_START_REQUEST = 90 FAX_SEND_STATE_LATE_OPEN = 100 FAX_SEND_STATE_SEND_DIAL_STRINGS = 110 FAX_SEND_STATE_SEND_FAX_HEADER = 120 FAX_SEND_STATE_SEND_PAGES = 130 FAX_SEND_STATE_SEND_END_OF_STREAM = 140 FAX_SEND_STATE_WAIT_FOR_COMPLETE = 150 FAX_SEND_STATE_RESET_TOKEN = 160 FAX_SEND_STATE_CLOSE_SESSION = 170 monitor_state = False fax_send_state = FAX_SEND_STATE_DEVICE_OPEN while fax_send_state != FAX_SEND_STATE_DONE: if self.check_for_cancel(): log.error('Fax send aborted.') fax_send_state = FAX_SEND_STATE_ABORT if monitor_state: fax_state = self.getFaxDownloadState() if fax_state not in (pml.UPDN_STATE_XFERACTIVE, pml.UPDN_STATE_XFERDONE): log.error('D/L error state=%d' % fax_state) fax_send_state = FAX_SEND_STATE_ERROR state = STATE_ERROR log.debug('STATE=(%d, %d, 0)' % (STATE_SEND_FAX, fax_send_state)) if fax_send_state == FAX_SEND_STATE_ABORT: monitor_state = False fax_send_state = FAX_SEND_STATE_RESET_TOKEN state = STATE_ABORTED continue if fax_send_state == FAX_SEND_STATE_ERROR: log.error('Fax send error.') monitor_state = False fax_send_state = FAX_SEND_STATE_RESET_TOKEN state = STATE_ERROR continue if fax_send_state == FAX_SEND_STATE_BUSY: log.error('Fax device busy.') monitor_state = False fax_send_state = FAX_SEND_STATE_RESET_TOKEN state = STATE_BUSY continue if fax_send_state == FAX_SEND_STATE_SUCCESS: log.debug('Fax send success.') monitor_state = False fax_send_state = FAX_SEND_STATE_RESET_TOKEN state = STATE_NEXT_RECIPIENT continue if fax_send_state == FAX_SEND_STATE_DEVICE_OPEN: log.debug('%s State: Open device' % '********************') fax_send_state = FAX_SEND_STATE_SET_TOKEN try: self.dev.open() except Error: e = None log.error('Unable to open device (%s).' % e.msg) fax_send_state = FAX_SEND_STATE_ERROR if self.dev.device_state == DEVICE_STATE_NOT_FOUND: fax_send_state = FAX_SEND_STATE_ERROR self.dev.device_state == DEVICE_STATE_NOT_FOUND if fax_send_state == FAX_SEND_STATE_SET_TOKEN: log.debug('%s State: Acquire fax token' % '********************') try: (result_code, token) = self.dev.getPML(pml.OID_FAX_TOKEN) except Error: log.debug('Unable to acquire fax token (1).') fax_send_state = FAX_SEND_STATE_EARLY_OPEN None if result_code > pml.ERROR_MAX_OK else check_token == token if fax_send_state == FAX_SEND_STATE_EARLY_OPEN: log.debug('%s State: Early open' % '********************') fax_send_state = FAX_SEND_STATE_CHECK_IDLE if self.dev.fax_type == FAX_TYPE_BLACK_SEND_EARLY_OPEN: log.debug('Opening fax channel.') try: self.dev.openFax() except Error: e = None log.error('Unable to open channel (%s).' % e.msg) fax_send_state = FAX_SEND_STATE_ERROR except: None<EXCEPTION MATCH>Error None<EXCEPTION MATCH>Error log.debug('Skipped.') continue if fax_send_state == FAX_SEND_STATE_CHECK_IDLE: log.debug('%s State: Check idle' % '********************') fax_send_state = FAX_SEND_STATE_START_REQUEST dl_state = self.getFaxDownloadState() tx_status = self.getFaxJobTxStatus() rx_status = self.getFaxJobRxStatus() if dl_state == pml.UPDN_STATE_IDLE and dl_state == pml.UPDN_STATE_ERRORABORT or dl_state == pml.UPDN_STATE_XFERDONE: if tx_status == pml.FAXJOB_TX_STATUS_IDLE or tx_status == pml.FAXJOB_TX_STATUS_DONE: pass None if rx_status == pml.FAXJOB_RX_STATUS_IDLE or rx_status == pml.FAXJOB_RX_STATUS_DONE else state == pml.UPDN_STATE_IDLE fax_send_state = FAX_SEND_STATE_BUSY continue if fax_send_state == FAX_SEND_STATE_START_REQUEST: log.debug('%s State: Request start' % '********************') fax_send_state = FAX_SEND_STATE_SET_PARAMS dl_state = self.getFaxDownloadState() if dl_state == pml.UPDN_STATE_IDLE: self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_REQSTART) time.sleep(1) log.debug('Waiting for active state...') i = 0 while i < 10: log.debug('Try: %d' % i) try: dl_state = self.getFaxDownloadState() except Error: log.error('PML/SNMP error') fax_send_state = FAX_SEND_STATE_ERROR break if dl_state == pml.UPDN_STATE_XFERACTIVE: break time.sleep(1) self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_REQSTART) i += 1 log.error('Could not get into active state!') fax_send_state = FAX_SEND_STATE_BUSY monitor_state = True else: log.error('Could not get into idle state!') fax_send_state = FAX_SEND_STATE_BUSY dl_state == pml.UPDN_STATE_IDLE if fax_send_state == FAX_SEND_STATE_SET_PARAMS: log.debug('%s State: Set params' % '********************') fax_send_state = FAX_SEND_STATE_LATE_OPEN try: self.dev.setPML(pml.OID_DEV_DOWNLOAD_TIMEOUT, pml.DEFAULT_DOWNLOAD_TIMEOUT) self.dev.setPML(pml.OID_FAXJOB_TX_TYPE, pml.FAXJOB_TX_TYPE_HOST_ONLY) log.debug('Setting date and time on device.') self.dev.setDateAndTime() except Error: e = None log.error('PML/SNMP error (%s)' % e.msg) fax_send_state = FAX_SEND_STATE_ERROR except: None<EXCEPTION MATCH>Error None<EXCEPTION MATCH>Error if fax_send_state == FAX_SEND_STATE_LATE_OPEN: log.debug('%s State: Late open' % '********************') fax_send_state = FAX_SEND_STATE_SEND_DIAL_STRINGS if self.dev.fax_type == FAX_TYPE_BLACK_SEND_LATE_OPEN: log.debug('Opening fax channel.') try: self.dev.openFax() except Error: log.error('Unable to open channel.') fax_send_state = FAX_SEND_STATE_ERROR except: None<EXCEPTION MATCH>Error None<EXCEPTION MATCH>Error log.debug('Skipped.') continue if fax_send_state == FAX_SEND_STATE_SEND_DIAL_STRINGS: log.debug('%s State: Send dial strings' % '********************') fax_send_state = FAX_SEND_STATE_SEND_FAX_HEADER log.debug('Dialing: %s' % recipient.fax) log.debug('Sending dial strings...') self.create_mfpdtf_fixed_header(DT_DIAL_STRINGS, True, PAGE_FLAG_NEW_DOC | PAGE_FLAG_END_DOC | PAGE_FLAG_END_STREAM) self.create_mfpdtf_dial_strings(recipient.fax) try: self.write_stream() except Error: log.error('Channel write error.') fax_send_state = FAX_SEND_STATE_ERROR except: None<EXCEPTION MATCH>Error None<EXCEPTION MATCH>Error if fax_send_state == FAX_SEND_STATE_SEND_FAX_HEADER: log.debug('%s State: Send fax header' % '********************') fax_send_state = FAX_SEND_STATE_SEND_PAGES try: ff = file(f, 'r') except IOError: log.error('Unable to read fax file.') fax_send_state = FAX_SEND_STATE_ERROR continue try: header = ff.read(FILE_HEADER_SIZE) except IOError: log.error('Unable to read fax file.') fax_send_state = FAX_SEND_STATE_ERROR continue (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding, reserved1, reserved2) = self.decode_fax_header(header) None if magic != 'hplip_g3' else None<EXCEPTION MATCH>Error if fax_send_state == FAX_SEND_STATE_SEND_PAGES: log.debug('%s State: Send pages' % '********************') fax_send_state = FAX_SEND_STATE_SEND_END_OF_STREAM page = StringIO() for p in range(total_pages): if self.check_for_cancel(): fax_send_state = FAX_SEND_STATE_ABORT if fax_send_state == FAX_SEND_STATE_ABORT: break try: header = ff.read(PAGE_HEADER_SIZE) except IOError: log.error('Unable to read fax file.') fax_send_state = FAX_SEND_STATE_ERROR continue (page_num, ppr, rpp, bytes_to_read, thumbnail_bytes, reserved2) = self.decode_page_header(header) log.debug('Page=%d PPR=%d RPP=%d BPP=%d Thumb=%d' % (page_num, ppr, rpp, bytes_to_read, thumbnail_bytes)) page.write(ff.read(bytes_to_read)) thumbnail = ff.read(thumbnail_bytes) page.seek(0) self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, page_flags = PAGE_FLAG_NEW_PAGE) self.create_sop_record(page_num, hort_dpi, vert_dpi, ppr, rpp, encoding) try: data = page.read(RASTER_DATA_SIZE) except IOError: log.error('Unable to read fax file.') fax_send_state = FAX_SEND_STATE_ERROR continue if data == '': log.error('No data!') fax_send_state = FAX_SEND_STATE_ERROR continue self.create_raster_data_record(data) total_read = RASTER_DATA_SIZE while True: data = page.read(RASTER_DATA_SIZE) total_read += RASTER_DATA_SIZE self.getFaxDownloadState() if data == '': self.create_eop_record(rpp) try: self.write_stream() except Error: log.error('Channel write error.') fax_send_state = FAX_SEND_STATE_ERROR break else: try: self.write_stream() except Error: log.error('Channel write error.') fax_send_state = FAX_SEND_STATE_ERROR break status = self.getFaxJobTxStatus() while status == pml.FAXJOB_TX_STATUS_DIALING: self.write_queue((STATUS_DIALING, 0, recipient.fax)) time.sleep(1) if self.check_for_cancel(): fax_send_state = FAX_SEND_STATE_ABORT break dl_state = self.getFaxDownloadState() if dl_state == pml.UPDN_STATE_ERRORABORT: fax_send_state = FAX_SEND_STATE_ERROR break status = self.getFaxJobTxStatus() if fax_send_state not in (FAX_SEND_STATE_ABORT, FAX_SEND_STATE_ERROR): while status == pml.FAXJOB_TX_STATUS_CONNECTING: self.write_queue((STATUS_CONNECTING, 0, recipient.fax)) time.sleep(1) if self.check_for_cancel(): fax_send_state = FAX_SEND_STATE_ABORT break dl_state = self.getFaxDownloadState() if dl_state == pml.UPDN_STATE_ERRORABORT: fax_send_state = FAX_SEND_STATE_ERROR break status = self.getFaxJobTxStatus() if status == pml.FAXJOB_TX_STATUS_TRANSMITTING: self.write_queue((STATUS_SENDING, page_num, recipient.fax)) self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, page_flags = 0) self.create_raster_data_record(data) if fax_send_state in (FAX_SEND_STATE_ABORT, FAX_SEND_STATE_ERROR): break continue page.truncate(0) page.seek(0) if fax_send_state == FAX_SEND_STATE_SEND_END_OF_STREAM: log.debug('%s State: Send EOS' % '********************') fax_send_state = FAX_SEND_STATE_WAIT_FOR_COMPLETE log.debug('End of stream...') self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, False, PAGE_FLAG_END_STREAM) try: self.write_stream() except Error: log.error('Channel write error.') fax_send_state = FAX_SEND_STATE_ERROR monitor_state = False continue if fax_send_state == FAX_SEND_STATE_WAIT_FOR_COMPLETE: log.debug('%s State: Wait for completion' % '********************') fax_send_state = FAX_SEND_STATE_WAIT_FOR_COMPLETE time.sleep(1) status = self.getFaxJobTxStatus() if status == pml.FAXJOB_TX_STATUS_DIALING: self.write_queue((STATUS_DIALING, 0, recipient.fax)) elif status == pml.FAXJOB_TX_STATUS_TRANSMITTING: self.write_queue((STATUS_SENDING, page_num, recipient.fax)) elif status in (pml.FAXJOB_TX_STATUS_DONE, pml.FAXJOB_RX_STATUS_IDLE): fax_send_state = FAX_SEND_STATE_RESET_TOKEN state = STATE_NEXT_RECIPIENT else: self.write_queue((STATUS_SENDING, page_num, recipient.fax)) status == pml.FAXJOB_TX_STATUS_DIALING if fax_send_state == FAX_SEND_STATE_RESET_TOKEN: self.write_queue((STATUS_CLEANUP, 0, '')) log.debug('%s State: Release fax token' % '********************') try: self.dev.setPML(pml.OID_FAX_TOKEN, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') except Error: log.error('Unable to release fax token.') fax_send_state = FAX_SEND_STATE_CLOSE_SESSION continue if fax_send_state == FAX_SEND_STATE_CLOSE_SESSION: log.debug('%s State: Close session' % '********************') fax_send_state = FAX_SEND_STATE_DONE log.debug('Closing session...') try: mm.close() except NameError: pass try: ff.close() except NameError: pass if self.dev.fax_type == FAX_TYPE_BLACK_SEND_LATE_OPEN: log.debug('Closing fax channel.') self.dev.closeFax() self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_IDLE) time.sleep(1) if self.dev.fax_type == FAX_TYPE_BLACK_SEND_EARLY_OPEN: log.debug('Closing fax channel.') self.dev.closeFax() self.dev.close() continue continue if state == STATE_CLEANUP: log.debug('%s State: Cleanup' % '********************') if self.remove_temp_file: log.debug('Removing merged file: %s' % f) try: os.remove(f) log.debug('Removed') except OSError: log.debug('Not found') except: None<EXCEPTION MATCH>OSError None<EXCEPTION MATCH>OSError state = STATE_DONE continue def next_recipient_gen(self): for a in self.phone_num_list: yield a def render_file(self, path, title, mime_type, force_single_page = False): all_pages = True page_range = '' page_set = 0 nup = 1 cups.resetOptions() if mime_type in ('application/x-cshell', 'application/x-perl', 'application/x-python', 'application/x-shell', 'text/plain'): cups.addOption('prettyprint') if nup > 1: cups.addOption('number-up=%d' % nup) if force_single_page: cups.addOption('page-ranges=1') sent_job_id = cups.printFile(self.current_printer, path, title) cups.resetOptions() log.debug('Job ID=%d' % sent_job_id) job_id = 0 time.sleep(1) fax_file = '' complete = False sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.connect((prop.hpssd_host, prop.hpssd_port)) except socket.error: log.error('Unable to contact HPLIP I/O (hpssd).') return ('', True) end_time = time.time() + 120 while time.time() < end_time: log.debug('Waiting for fax...') (fields, data, result_code) = msg.xmitMessage(sock, 'FaxCheck', None, { 'username': prop.username }) if result_code == ERROR_FAX_PROCESSING: log.debug('Fax is being rendered...') elif result_code == ERROR_FAX_READY: break if self.check_for_cancel(): log.error('Render canceled. Canceling job #%d...' % sent_job_id) cups.cancelJob(sent_job_id) os.close(fd) sock.close() return ('', True) time.sleep(1) log.error('Timeout waiting for rendering. Canceling job #%d...' % sent_job_id) cups.cancelJob(sent_job_id) return ('', False) (fd, fax_file) = utils.make_temp_file() while True: log.debug('Transfering fax data...') (fields, data, result_code) = msg.xmitMessage(sock, 'FaxGetData', None, { 'username': prop.username, 'job-id': sent_job_id }) if data and result_code == ERROR_SUCCESS: os.write(fd, data) else: complete = True break if self.check_for_cancel(): log.error('Render canceled. Canceling job #%d...' % sent_job_id) cups.cancelJob(sent_job_id) os.close(fd) sock.close() return ('', True) continue os.close(fd) sock.close() return (fax_file, False) def check_for_cancel(self): canceled = False while self.event_queue.qsize(): try: event = self.event_queue.get(0) if event[0] == EVENT_FAX_SEND_CANCELED: canceled = True log.debug('Cancel pressed!') continue except Queue.Empty: break continue None<EXCEPTION MATCH>Queue.Empty return canceled def render_cover_page(self, a): log.debug('Creating cover page...') pdf = self.cover_func(page_size = coverpages.PAGE_SIZE_LETTER, total_pages = self.job_total_pages, recipient_name = a.name, recipient_phone = '', recipient_fax = a.fax, sender_name = self.sender_name, sender_phone = user_cfg.fax.voice_phone, sender_fax = self.sender_fax, sender_email = user_cfg.fax.email_address, regarding = self.cover_re, message = self.cover_message) log.debug('PDF File=%s' % pdf) (fax_file, canceled) = self.render_file(pdf, 'Cover Page', 'application/pdf', force_single_page = True) try: os.remove(pdf) except IOError: pass return (fax_file, canceled) def write_queue(self, message): if self.update_queue is not None and message != self.prev_update: self.update_queue.put(message) time.sleep(0) self.prev_update = message def getFaxDownloadState(self): (result_code, state) = self.dev.getPML(pml.OID_FAX_DOWNLOAD) log.debug('D/L State=%d (%s)' % (state, pml.UPDN_STATE_STR.get(state, 'Unknown'))) return state def getFaxJobTxStatus(self): (result_code, status) = self.dev.getPML(pml.OID_FAXJOB_TX_STATUS) log.debug('Tx Status=%d (%s)' % (status, pml.FAXJOB_TX_STATUS_STR.get(status, 'Unknown'))) return status def getFaxJobRxStatus(self): (result_code, status) = self.dev.getPML(pml.OID_FAXJOB_RX_STATUS) log.debug('Rx Status=%d (%s)' % (status, pml.FAXJOB_RX_STATUS_STR.get(status, 'Unknown'))) return status def getCfgUploadState(self): (result_code, state) = self.dev.getPML(pml.OID_DEVICE_CFG_UPLOAD) log.debug('Cfg Upload State = %d (%s)' % (state, pml.UPDN_STATE_STR.get(state, 'Unknown'))) return state def create_mfpdtf_fixed_header(self, data_type, send_variant = False, page_flags = 0): header_len = FIXED_HEADER_SIZE if send_variant: if data_type == DT_DIAL_STRINGS: header_len += DIAL_STRINGS_VARIANT_HEADER_SIZE elif data_type == DT_FAX_IMAGES: header_len += FAX_IMAGE_VARIANT_HEADER_SIZE self.stream.write(struct.pack('<IHBB', 0, header_len, data_type, page_flags)) def create_mfpdtf_dial_strings(self, number): self.stream.write(struct.pack('<BBHH51s', MAJOR_VER, MINOR_VER, 1, 51, number[:51])) def adjust_fixed_header_block_size(self): size = self.stream.tell() self.stream.seek(0) self.stream.write(struct.pack('<I', size)) def create_sop_record(self, page_num, hort_dpi, vert_dpi, ppr, rpp, encoding, bpp = 1): self.stream.write(struct.pack('<BBHHHIHHHHHHIHHHH', RT_START_PAGE, encoding, page_num, ppr, bpp, rpp, 0, hort_dpi, 0, vert_dpi, ppr, bpp, rpp, 0, hort_dpi, 0, vert_dpi)) def create_eop_record(self, rpp): self.stream.write(struct.pack('<BBBBII', RT_END_PAGE, 0, 0, 0, rpp, 0)) def create_raster_data_record(self, data): if not len(data) <= RASTER_DATA_SIZE: raise AssertionError self.stream.write(struct.pack('<BBH', RT_RASTER, 0, len(data))) self.stream.write(data) def create_mfpdtf_fax_header(self, total_pages): self.stream.write(struct.pack('<BBBHBI20s20s20sI', MAJOR_VER, MINOR_VER, SRC_HOST, total_pages, TTI_PREPENDED_TO_IMAGE, 0, '', '', '', 0)) def write_stream(self): self.adjust_fixed_header_block_size() self.dev.writeFax(self.stream.getvalue()) self.stream.truncate(0) self.stream.seek(0) def decode_fax_header(self, header): try: return struct.unpack('>8sBIHHBBBII', header) except struct.error: return (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1) def decode_page_header(self, header): try: return struct.unpack('>IIIIII', header) except struct.error: return (-1, -1, -1, -1, -1, -1)