""" A simple example that will answer an inbound call, and receive a fax. Actions: - check the channel state - answer - receive a fax - hang up It is assumed that the name of the fax file is given in application_parameters. To this is added the application_instance_id to make it unique. """ from prosody.uas import Hangup, Error, FaxToSend, FaxToReceive __uas_identify__ = "application" __uas_version__ = "0.01b" def main(channel, application_instance_id, file_man, my_log, application_parameters): try: return_code = 0 # This outbound application is going to receive a fax, so we create # a FaxToReceive object, known as a fax document object my_fax = FaxToReceive() # Now set the name of the file to which the fax will be saved. cause = my_fax.set_file_name('{0}_{1}.tif'.format(application_parameters, application_instance_id)) # The cause will be of type FileCause and should be checked. if cause != my_fax.FileCause.NORMAL: raise Error("failed to set the file name, cause is {0}".format(cause)) # Answer the inbound call in the normal way if channel.state() == channel.State.CALL_INCOMING: channel.answer() # this can raise a Hangup exception else: raise Hangup('No inbound call') # Now we can start to receive the fax. if channel.FaxReceiver.start(fax_to_receive=my_fax) != True: cause = channel.FaxReceiver.cause() raise Error("fax receiver failed to start receiving the fax, cause is {0}.".format(cause)) # The fax endpoints will negotiate the parameters for the fax session - which modem # and the modem speed, among other things. We can wait until these have been published # and then have a look. Note that the dictionary will be empty if fax negotiation fails. negotiated_settings = channel.FaxReceiver.wait_for_negotiated_settings() if negotiated_settings == {}: cause = channel.FaxReceiver.cause() if cause == channel.FaxReceiver.Cause.NOTFAX: raise Hangup("The transmitter was not a fax machine.") else: raise Error("Fax negotiation failed with cause {0}".format(cause)) my_log.debug("Negotiated Settings") for setting, value in negotiated_settings.items(): my_log.debug("{0:>15.15} : {1}".format(setting, value)) # Now we can wait for each page to be received, we do this until we've been told # that no more pages will be received. For each page we log the page quality. # This, and more, detail is available on the fax document object. # It is important to note that the last_page flag does not indicate success, it simply # means that no more pages will be processed. while channel.FaxReceiver.Details.last_page is not True: pages = channel.FaxReceiver.wait_for_next_page() my_log.debug("Received {0} pages so far".format(pages)) my_log.debug("Last received page quality: {0}".format(my_fax.PageDetails[-1].receive_quality)) # Now we need to wait until the fax session has finished. We need to do this even though # the last page flag has been set. Remember to check the cause, the last_page indicator # may have been set, but this does not mean that every page was received. cause = channel.FaxReceiver.wait_until_finished() if cause != channel.FaxReceiver.Cause.NORMAL: raise Error("Fax receiver failed with cause {0}".format(cause)) except Hangup as exc: my_log.info("Hangup exception reports {0}".format(exc)) return_code = -101 except Error as exc: my_log.error("Error exception reports {0}".format(exc)) return_code = -100 except Exception as exc: my_log.exception("Got unexpected exception {0}".format(exc)) return_code = -102 finally: if channel.state() != channel.State.IDLE: channel.hang_up() return return_code