%PDF- %PDF-
| Direktori : /usr/share/hplip/fax/ |
| Current File : //usr/share/hplip/fax/cdmfax.py |
# -*- coding: utf-8 -*-
#
# (c) Copyright 2003-2015 HP Development Company, L.P.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Author: k,shunmugaraj
# Date Created: 10/10/2010
from __future__ import division
from pickle import NONE
import cupsext
# Std Lib
import sys
import os
import time
from base.sixext import BytesIO, to_bytes_utf8, to_unicode
import re
import threading
import struct
import time
import xml.parsers.expat as expat
from stat import *
# Local
from base.g import *
from base.codes import *
from base import device, utils, codes, dime, status
from base.sixext import to_bytes_utf8
from .fax import *
# StdLib
import time
import io
import binascii
import xml.parsers.expat
from string import *
import json
import ast
# Local
from base import device, utils
from base.sixext import PY3, to_bytes_utf8, to_unicode, to_string_latin, to_string_utf8, xStringIO
from base.sixext.moves import http_client
import json
import ast
import sys
import time
from prnt import cups
# **************************************************************************** #
CDM_AUTH_REQ = "/cdm/oauth2/v1/token"
CDM_FAX_MODEM_CONF = "/cdm/faxModem/v1/configuration"
REQ_NO_TOKEN = """%s %s HTTP/1.1\r\nContent-Type: application/json\r\nUser-Agent: hplip\r\nAccept: */*\r\nCache-Control: no-cache\r\nHost:%s\r\nConnection: keep-alive\r\nContent-Length: %s\r\n\r\n"""
REQ_WITH_TOKEN = """%s %s HTTP/1.1\r\nContent-Type: application/json\r\nUser-Agent: hplip\r\nAccept: */*\r\nCache-Control: no-cache\r\nHost:%s\r\nConnection: keep-alive\r\nContent-Length: %s\r\nAuthorization: Bearer %s\r\n\r\n"""
HTTP_UNAUTHORIZED = 401
HTTP_OK = 200
HTTP_ACCEPTED = 202
HTTP_CREATED = 201
HTTP_ERROR = 500
HTTP_SERVICE_UNAVALIABLE = 503
class CDMFaxDevice(FaxDevice):
def __init__(self, device_uri=None, printer_name=None,
callback=None,
fax_type=FAX_TYPE_NONE,
disable_dbus=False):
FaxDevice.__init__(self, device_uri,
printer_name,
callback, fax_type,
disable_dbus)
self.token = ""
self.send_fax_thread = None
self.upload_log_thread = None
self.device_uri = device_uri
self.printer_name = printer_name
if self.bus == 'net':
self.http_host = self.host
else:
self.http_host = 'localhost'
def isAuthRequired(self):
if self.mq['wifi-config'] == WIFI_CONFIG_CDM_AUTH:
return True
else:
return False
def __flushThePort(self):
response = io.BytesIO()
# self.openEWS_LEDM()
try:
self.readLEDMAllData(self.readEWS_LEDM, response, 1)
except Error:
log.debug("Unable to read LEDM Channel")
finally:
self.closeLEDM()
# Patch Request
def __usb_reqeust(self, request_type, url, data_json=None, WithToken=False):
if data_json == None:
contentLen = len(url)
else:
contentLen = len(data_json)
if WithToken == True:
self.writeEWS_LEDM(REQ_WITH_TOKEN %
(request_type, url, self.http_host, contentLen, self.token))
else:
self.writeEWS_LEDM(REQ_NO_TOKEN %
(request_type, url, self.http_host, contentLen))
if data_json != None:
self.writeEWS_LEDM(data_json)
reply = xStringIO()
try:
self.readLEDMData(self.readEWS_LEDM, reply)
reply.seek(0)
response = http_client.HTTPResponse(reply)
response.begin()
respcode = response.getcode()
data = response.read()
return respcode, data
except Error:
self.closeEWS_LEDM()
log.debug("Unable to read EWS_LEDM Channel")
def getCDMToken(self, uname, password):
# self.__flushThePort()
data = {}
data['grant_type'] = "password"
data['username'] = uname
data['password'] = password
data = json.dumps(data)
respcode, data = self.__do_request('POST', CDM_AUTH_REQ, data)
if not(respcode == HTTP_OK):
log.debug(
"Request Failed With Response Code %d, enter correct credentials" % respcode)
return respcode, ""
else:
data = json.loads(data.strip())
data = ast.literal_eval(json.dumps(data))
self.token = data['access_token']
return respcode
def __do_request(self, request_type, url, data=None, WithToken=False):
try:
if self.bus == 'net':
respcode, data = self.__network_reqeust(
request_type, url, data, WithToken)
return respcode, data
else:
respcode, data = self.__usb_reqeust(
request_type, url, data, WithToken)
return respcode, data
except:
log.debug("IO Error")
return 400, ""
def __network_reqeust(self, request_type, url, data=None, WithToken=False):
import http.client
import ssl
header = {'Content-Type': 'application/json', 'User-Agent': 'hplip',
'Cache-Control': 'no-cache', 'Connection': 'keep-alive'}
header['Host'] = self.host
if WithToken == True:
header['Authorization'] = 'Bearer %s' % self.token
try:
connection = http.client.HTTPSConnection(
self.host, context=ssl._create_unverified_context())
if data != None:
connection.request(method=request_type,
url=url, body=data, headers=header)
else:
connection.request(method=request_type,
url=url, headers=header)
except:
log.debug("Error while connecting the device")
return 400, ""
response = connection.getresponse()
respcode = response.status
data = response.read()
return respcode, data
def setPhoneNum(self, num):
rtn = False
data = {}
dataFaxNum = {}
dataFaxNum['faxNumber'] = str(num)
data['analogFaxSetup'] = dataFaxNum
data = json.dumps(data)
log.debug(data)
try:
respcode, data = self.__do_request(
"PATCH", CDM_FAX_MODEM_CONF, data, WithToken=True)
rtn = True
except:
log.debug("SetPhoneNum response is ", respcode)
return rtn
def getPhoneNum(self):
try:
fax_modem_details = cupsext.getFaxModemAttributes(
self.device_uri, self.printer_name)
log.dbg(fax_modem_details)
except:
return ''
return (fax_modem_details.get('printer-fax-modem-number')).replace('tel:', '')
phone_num = property(getPhoneNum, setPhoneNum)
def setStationName(self, name):
rtn = False
#self.token = token
data = {}
dataComName = {}
dataComName['companyName'] = str(name)
data['analogFaxSetup'] = dataComName
data = json.dumps(data)
try:
respcode, data = self.__do_request(
"PATCH", CDM_FAX_MODEM_CONF, data, WithToken=True)
rtn = True
except:
log.debug("setStationName response is ", respcode)
return rtn
def getStationName(self):
try:
fax_modem_details = cupsext.getFaxModemAttributes(
self.device_uri, self.printer_name)
log.dbg(fax_modem_details)
except:
return ''
return fax_modem_details.get('printer-fax-modem-name')
station_name = property(getStationName, setStationName)
def setDateAndTime(self):
t = time.localtime()
date_buf = "%4d-%02d-%02dT%02d:%02d:%02d" % (
t[0], t[1], t[2], t[3], t[4], t[5])
return True
def sendFaxes(self, phone_num_list, fax_file_list, cover_message='', cover_re='',
cover_func=None, preserve_formatting=False, printer_name='',
update_queue=None, event_queue=None):
if not self.isSendFaxActive():
self.send_fax_thread = CDMFaxSendThread(self, self.service, self.device_uri, self.printer_name,
phone_num_list, fax_file_list,
cover_message, cover_re, cover_func,
preserve_formatting,
update_queue,
event_queue)
self.send_fax_thread.start()
return True
else:
return False
# **************************************************************************** #
class CDMFaxSendThread(FaxSendThread):
def __init__(self, dev, service, device_uri, printer_name, phone_num_list, fax_file_list,
cover_message='', cover_re='', cover_func=None, preserve_formatting=False,
update_queue=None, event_queue=None):
FaxSendThread.__init__(self, dev, service, phone_num_list, fax_file_list,
cover_message, cover_re, cover_func, preserve_formatting,
printer_name, update_queue, event_queue)
self.device_uri = device_uri
self.printer_name = printer_name
if dev.bus == 'net':
self.http_host = "%s:8080" % self.dev.host
else:
self.http_host = 'localhost:8080'
print(fax_file_list)
def run(self):
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
error_state = STATUS_ERROR
self.rendered_file_list = []
num_tries = 0
while state != STATE_DONE: # --------------------------------- Fax state machine
if self.check_for_cancel():
state = STATE_ABORTED
log.debug("STATE=(%d, 0, 0)" % state)
# ----------------------------- Aborted (10, 0, 0)
if state == STATE_ABORTED:
log.error("Aborted by user.")
self.write_queue((STATUS_IDLE, 0, ''))
state = STATE_CLEANUP
# --------------------------- Success (20, 0, 0)
elif state == STATE_SUCCESS:
log.debug("Success.")
self.write_queue((STATUS_COMPLETED, 0, ''))
state = STATE_CLEANUP
# ----------------------------- Error (130, 0, 0)
elif state == STATE_ERROR:
log.error("Error, aborting.")
self.write_queue((error_state, 0, ''))
state = STATE_CLEANUP
# ------------------------------ Busy (25, 0, 0)
elif state == STATE_BUSY:
log.error("Device busy, aborting.")
self.write_queue((STATUS_BUSY, 0, ''))
state = STATE_CLEANUP
elif state == STATE_READ_SENDER_INFO: # ------------------ Get sender info (30, 0, 0)
log.debug("%s State: Get sender info" % ("*"*20))
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("CDM ipp request failed!")
state = STATE_ERROR
state = STATE_PRERENDER
elif state == STATE_PRERENDER: # --------------------------------- Pre-render non-G4 files (40, 0, 0)
log.debug("%s State: Pre-render non-G4 files" % ("*"*20))
state = self.pre_render(STATE_COUNT_PAGES)
elif state == STATE_COUNT_PAGES: # -------------------------------- Get total page count (50, 0, 0)
log.debug("%s State: Get total page count" % ("*"*20))
#state = self.count_pages(STATE_NEXT_RECIPIENT)
self.recipient_file_list = self.rendered_file_list[:]
self.job_total_pages = len(self.fax_file_list)
state = STATE_NEXT_RECIPIENT
elif state == STATE_NEXT_RECIPIENT: # ----------------------------- Loop for multiple recipients (60, 0, 0)
log.debug("%s State: Next recipient" % ("*"*20))
state = STATE_COVER_PAGE
try:
recipient = next(next_recipient)
log.debug("Processing for recipient %s" % recipient['name'])
self.write_queue((STATUS_SENDING_TO_RECIPIENT, 0, recipient['name']))
except StopIteration:
state = STATE_SUCCESS
log.debug("Last recipient.")
continue
recipient_file_list = self.rendered_file_list[:]
elif state == STATE_COVER_PAGE: # ---------------------------------- Create cover page (70, 0, 0)
log.debug("%s State: Render cover page" % ("*"*20))
state = self.cover_page(recipient)
elif state == STATE_SINGLE_FILE: # --------------------------------- Special case for single file (no merge) (80, 0, 0)
log.debug("%s State: Handle single file" % ("*"*20))
#state = self.single_file(STATE_SEND_FAX)
state = self.merge_cdm_fax_files(STATE_SEND_FAX)
#self.f = self.recipient_file_list[0][0]
log.error(self.f)
#state = STATE_SEND_FAX
elif state == STATE_MERGE_FILES: # --------------------------------- Merge multiple G4 files (90, 0, 0)
log.debug("%s State: Merge multiple files" % ("*"*20))
state = self.merge_cdm_fax_files(STATE_SEND_FAX)
elif state == STATE_SEND_FAX: # ------------------------------------ Send fax state machine (110, 0, 0)
log.debug("%s State: Send fax" % ("*"*20))
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_BEGINJOB = 50
FAX_SEND_STATE_DOWNLOADPAGES = 60
FAX_SEND_STATE_ENDJOB = 70
FAX_SEND_STATE_CANCELJOB = 80
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
log.debug("STATE=(%d, %d, 0)" % (STATE_SEND_FAX, fax_send_state))
if fax_send_state == FAX_SEND_STATE_ABORT: # ----------------- Abort (110, 10, 0)
monitor_state = False
fax_send_state = FAX_SEND_STATE_CANCELJOB
state = STATE_ABORTED
elif fax_send_state == FAX_SEND_STATE_ERROR: # --------------- Error (110, 20, 0)
log.error("Fax send error.")
monitor_state = False
fax_send_state = FAX_SEND_STATE_CLOSE_SESSION
state = STATE_ERROR
elif fax_send_state == FAX_SEND_STATE_BUSY: # ---------------- Busy (110, 25, 0)
log.error("Fax device busy.")
monitor_state = False
fax_send_state = FAX_SEND_STATE_CLOSE_SESSION
state = STATE_BUSY
elif fax_send_state == FAX_SEND_STATE_SUCCESS: # ------------- Success (110, 30, 0)
log.debug("Fax send success.")
monitor_state = False
fax_send_state = FAX_SEND_STATE_CLOSE_SESSION
state = STATE_NEXT_RECIPIENT
elif fax_send_state == FAX_SEND_STATE_DEVICE_OPEN: # --------- Device open (110, 40, 0)
log.debug("%s State: Open device" % ("*"*20))
fax_send_state = FAX_SEND_STATE_BEGINJOB
elif fax_send_state == FAX_SEND_STATE_BEGINJOB: # -------------- BeginJob (110, 50, 0)
faxnum = recipient['fax']
aJobID = cupsext.sendFaxOutJob(self.device_uri,self.printer_name,self.f,faxnum)
fax_send_state = FAX_SEND_STATE_ENDJOB
elif fax_send_state == FAX_SEND_STATE_ENDJOB: # -------------- EndJob (110, 70, 0)
fax_send_state = FAX_SEND_STATE_SUCCESS
elif fax_send_state == FAX_SEND_STATE_CANCELJOB: # -------------- CancelJob (110, 80, 0)
log.debug("%s State: CancelJob" % ("*"*20))
if aJobID > 0:
cups.cancelJob(aJobID)
fax_send_state = FAX_SEND_STATE_CLOSE_SESSION
elif fax_send_state == FAX_SEND_STATE_CLOSE_SESSION: # -------------- Close session (110, 170, 0)
log.debug("%s State: Close session" % ("*"*20))
log.debug("Closing session...")
fax_send_state = FAX_SEND_STATE_DONE # Exit inner state machine
elif state == STATE_CLEANUP: # --------------------------------- Cleanup (120, 0, 0)
log.debug("%s State: Cleanup" % ("*"*20))
if self.remove_temp_file:
log.debug("Removing merged file: %s" % self.f)
try:
os.remove(self.f)
log.debug("Removed")
except OSError:
log.debug("Not found")
state = STATE_DONE # Exit outer state machine