def sendfax(config, user, capi, faxfile, outgoing_num, dialstring, stationID=None, headline=None): """ Send a fax out via the capi. Returns a tuple ((result, resultB3), faxinfo) """ import capisuite.core as core controller = config.getint('GLOBAL', "send_controller") timeout = int(config.getUser(user, "outgoing_timeout")) # get defaults for stationID and headline from config if not stationID: stationID = config.getUser(user, "fax_stationID") if not stationID: core.error("Warning: fax_stationID for user %s not set" %user) if not headline: headline = config.getUser(user, "fax_headline") try: call, result = capi.call_faxG3(controller, outgoing_num, dialstring, timeout, stationID, headline) core.log('result from capi.call_faxG3: %s' % result, 2) if result: # an errror occured return (result, 0), None faxinfo = call.fax_send(faxfile) return call.disconnect(), faxinfo except core.CallGoneError: return call.disconnect(), None
def _getAction(config, user, action_name, allowed_actions): action = config.getUser(user, action_name, "").lower() if action not in allowed_actions: action = allowed_actions[0] core.error("Warning: No valid %s definition found for user %s -> " "assuming %s" % action_name, user, action) return action
def _getAction(config, user, action_name, allowed_actions): action = config.getUser(user, action_name, "").lower() if action not in allowed_actions: action = allowed_actions[0] core.error( "Warning: No valid %s definition found for user %s -> " "assuming %s" % action_name, user, action) return action
def idle(capi): capi = capisuite.core.Capi(capi) config = capisuite.config.readGlobalConfig() try: spool = config.get('GLOBAL', "spool_dir") max_tries = config.getint('GLOBAL', "send_tries") delays = config.getList('GLOBAL', "send_delays") except NoOptionError, err: core.error("global option %s not found." % err.option) return
def sendfax(config, user, capi, faxfile, outgoing_num, dialstring, stationID=None, headline=None): """ Send a fax out via the capi. Returns a tuple ((result, resultB3), faxinfo) """ import capisuite.core as core controller = config.getint('GLOBAL', "send_controller") timeout = int(config.getUser(user, "outgoing_timeout")) # get defaults for stationID and headline from config if not stationID: stationID = config.getUser(user, "fax_stationID") if not stationID: core.error("Warning: fax_stationID for user %s not set" % user) if not headline: headline = config.getUser(user, "fax_headline") try: call, result = capi.call_faxG3(controller, outgoing_num, dialstring, timeout, stationID, headline) core.log('result from capi.call_faxG3: %s' % result, 2) if result: # an errror occured return (result, 0), None faxinfo = call.fax_send(faxfile) return call.disconnect(), faxinfo except core.CallGoneError: return call.disconnect(), None
def callIncoming(call, service, call_from, call_to): """ Main function called by CapiSuite when an incoming call is received. It will decide if this call should be accepted, with which service and for which user. The real call handling is done in faxIncoming and voiceIncoming. 'call' reference to the call. Needed by all capisuite functions 'service' one of SERVICE_FAXG3, SERVICE_VOICE, SERVICE_OTHER 'call_from' string containing the number of the calling party 'call_to' string containing the number of the called party """ # convert into a python call handle # TODO-gh: can't we get rid of this line? call = core.Call(call, service, call_from, call_to) # read config file and search for call.to_nr in the user sections try: config = capisuite.config.readGlobalConfig() except IOError, e: core.error("Error occured during config file reading: %s " "Disconnecting..." % e) call.reject(0x34A9) return
def faxIncoming(config, user, call, already_connected): """ Called by callIncoming when an incoming fax call is received 'call' a python Call handle referencing to the call 'user' name of the user who is responsible for this 'config' ConfigParser instance holding the config data 'already_connected' ture if we're already connected (that means we must switch to fax mode) """ # todo: use config.getQueueFiles + _mkdir here receivedQ = fileutils._mkuserdir(user, config.get('GLOBAL', "fax_user_dir"), user, "received") # assure these variables are defined filename = faxInfo = None stationID = config.getUser(user, "fax_stationID", default="") if not stationID: core.error("Warning: fax_stationID not found for user %s " "-> using empty string" % user) # empty string is no problem for headline headline = config.getUser(user, "fax_headline", default="") call.log("call from %s to %s for %s connecting with fax" % \ (call.from_nr, call.to_nr, user), 1) try: if already_connected: faxInfo = call.switch_to_faxG3(stationID, headline) else: faxInfo = call.connect_faxG3(stationID, headline) filename = fileutils.uniqueName(receivedQ, "fax", faxInfo.format)[1] call.fax_receive(filename) causes = call.disconnect() call.log("connection finished with cause 0x%x, 0x%x" % causes, 1) except core.CallGoneError: # catch this here to get the cause info into the mail causes = call.disconnect() call.log("connection lost with cause 0x%x, 0x%x" % causes, 1) # todo: send error mail here? Don't think it makes sense to send # a mail on each try, which would mean sending 10 mails for one fax... # If the user wants to know the current status he should use "capisuitefax -l" else: assert filename if os.access(filename, os.R_OK): faxInfo = faxInfo.as_dict() faxInfo.update({ 'filename' : filename, 'call_from': call.from_nr, 'call_to' : call.to_nr, 'causes' : causes, 'hostname' : os.uname()[1] }) capisuite.fax.createReceivedJob(user, **faxInfo) action = _getAction(config, user, "fax_action", ("saveonly", "mailandsave")) if action == "mailandsave": fromaddress = config.getUser(user, "fax_email_from", user) mailaddress = config.getUser(user, "fax_email", user) helpers.sendMIMEMail( fromaddress, mailaddress, config.get('MailFaxReceived', 'subject') % faxInfo, faxInfo['format'], config.get('MailFaxReceived', 'text') % faxInfo, filename)
def voiceIncoming(config, user, call): """ Called by callIncoming when an incoming voice call is received 'call' a python Call handle referencing to the call 'user' name of the user who is responsible for this 'config' ConfigParser instance holding the config data """ try: if not config.has_option(user, 'voice_delay'): core.error("voice_delay not found for user %s! -> " "rejecting call" % user) call.reject(0x34A9) return delay = config.getint(user, "voice_delay") call.log("call from %s to %s for %s connecting with voice" % \ (call.from_nr, call.to_nr, user), 1) call.connect_voice(delay) userdir = config.get('GLOBAL', "voice_user_dir") action = _getAction(config, user, "voice_action", ("saveonly", "mailandsave", "none")) receivedQ = fileutils._mkuserdir(user, userdir, user, "received") userannouncement = os.path.join( userdir, user, config.getUser(user, "announcement", "announcement.la")) pin = config.getUser(user, "pin", "") filename = None # assure it's defined call.enable_DTMF() if os.access(userannouncement, os.R_OK): call.audio_send(userannouncement, 1) else: if call.to_nr != "-": say(config, user, call, "anrufbeantworter-von.la") capisuite.voice.sayNumber(config, user, call, call.to_nr) say(config, user, call, "bitte-nachricht.la") if action != "none": say(config, user, call, "beep.la") length = config.getUser(user, "record_length", 60) # todo: put this into voice.getNameForRecord filename = fileutils.uniqueName(receivedQ, "voice", 'la')[1] silence_timeout = config.getUser(user, "record_silence_timeout", 5) msg_length = call.audio_receive(filename, int(length), int(silence_timeout), 1) dtmf_list = call.read_DTMF(0) if dtmf_list == "X": if os.access(filename, os.R_OK): os.unlink(filename) faxIncoming(config, user, call, 1) elif dtmf_list and pin: # wait 5 seconds for input dtmf_list += call.read_DTMF(3) count = 1 # allow three tries while count < 3 and pin != dtmf_list: call.log("wrong PIN entered...", 1) say(config, user, call, "beep.la") dtmf_list = call.read_DTMF(3) count += 1 else: # failed three time # todo: hang up? # gh: Yes. pass if pin == dtmf_list: if os.access(filename, os.R_OK): os.unlink(filename) call.log("Starting remote inquiry...", 1) remoteInquiry(config, user, call, receivedQ) except core.CallGoneError: # catch this here to get the cause info in the mail causes = call.disconnect() call.log("connection lost with cause 0x%x, 0x%x" % causes, 1) else: causes = call.disconnect() call.log("connection finished with cause 0x%x, 0x%x" % causes, 1) if (filename and os.access(filename, os.R_OK)): info = capisuite.voice.createReceivedJob(user, filename, call.from_nr, call.to_nr, causes) fromaddress = config.getUser(user, "voice_email_from", user) mailaddress = config.getUser(user, "voice_email", user) if action == "mailandsave": info['hostname'] = os.uname()[1] info['msg_length'] = msg_length helpers.sendMIMEMail( fromaddress, mailaddress, config.get('MailVoiceReceived', 'subject') % info, "la", config.get('MailVoiceReceived', 'text') % info, filename)
else: # no matching entry found (no users as this number) call.log("call from %s to %s ignoring" % (call.from_nr, call.to_nr), 1) call.reject(1) return # answer the call with the right service try: if service == core.SERVICE_VOICE: voiceIncoming(config, user, call) elif service == core.SERVICE_FAXG3: faxIncoming(config, user, call, 0) else: raise RuntimeError except NoOptionError, err: core.error("global option %s not found -> rejecting call" % err.option) call.reject(0x34A9) except fileutils.UnknownUserError: core.error("user %s is not a valid system user. Disconnecting." % user, call) call.reject(0x34A9) except core.CallGoneError: causes = call.disconnect() call.log("connection lost with cause 0x%x, 0x%x" % causes, 1) def faxIncoming(config, user, call, already_connected): """ Called by callIncoming when an incoming fax call is received 'call' a python Call handle referencing to the call
capi = capisuite.core.Capi(capi) config = capisuite.config.readGlobalConfig() try: spool = config.get('GLOBAL', "spool_dir") max_tries = config.getint('GLOBAL', "send_tries") delays = config.getList('GLOBAL', "send_delays") except NoOptionError, err: core.error("global option %s not found." % err.option) return # todo: implement config.getQueue(queue,user=None) doneQ = os.path.join(spool, "done") failedQ = os.path.join(spool, "failed") if not os.access(doneQ, os.W_OK) or not os.access(failedQ, os.W_OK): core.error("Can't read/write to the necessary spool dirs below %s" % spool) return # search in all user-specified sendq's for user in config.listUsers(): outgoing_num = config.getUser(user, "outgoing_msn") if not outgoing_num: incoming_nums = config.getUser(user, "fax_numbers") if not incoming_nums: continue outgoing_num = incoming_nums.split(',')[0].strip() mailaddress = config.getUser(user, "fax_email", user) fromaddress = config.getUser(user, "fax_email_from", user) for jobnum, controlfile in capisuite.fax.getQueueFiles(config, user):
def faxIncoming(config, user, call, already_connected): """ Called by callIncoming when an incoming fax call is received 'call' a python Call handle referencing to the call 'user' name of the user who is responsible for this 'config' ConfigParser instance holding the config data 'already_connected' ture if we're already connected (that means we must switch to fax mode) """ # todo: use config.getQueueFiles + _mkdir here receivedQ = fileutils._mkuserdir(user, config.get('GLOBAL', "fax_user_dir"), user, "received") # assure these variables are defined filename = faxInfo = None stationID = config.getUser(user, "fax_stationID", default="") if not stationID: core.error("Warning: fax_stationID not found for user %s " "-> using empty string" % user) # empty string is no problem for headline headline = config.getUser(user, "fax_headline", default="") call.log("call from %s to %s for %s connecting with fax" % \ (call.from_nr, call.to_nr, user), 1) try: if already_connected: faxInfo = call.switch_to_faxG3(stationID, headline) else: faxInfo = call.connect_faxG3(stationID, headline) filename = fileutils.uniqueName(receivedQ, "fax", faxInfo.format)[1] call.fax_receive(filename) causes = call.disconnect() call.log("connection finished with cause 0x%x, 0x%x" % causes, 1) except core.CallGoneError: # catch this here to get the cause info into the mail causes = call.disconnect() call.log("connection lost with cause 0x%x, 0x%x" % causes, 1) # todo: send error mail here? Don't think it makes sense to send # a mail on each try, which would mean sending 10 mails for one fax... # If the user wants to know the current status he should use "capisuitefax -l" else: assert filename if os.access(filename, os.R_OK): faxInfo = faxInfo.as_dict() faxInfo.update({ 'filename': filename, 'call_from': call.from_nr, 'call_to': call.to_nr, 'causes': causes, 'hostname': os.uname()[1] }) capisuite.fax.createReceivedJob(user, **faxInfo) action = _getAction(config, user, "fax_action", ("saveonly", "mailandsave")) if action == "mailandsave": fromaddress = config.getUser(user, "fax_email_from", user) mailaddress = config.getUser(user, "fax_email", user) helpers.sendMIMEMail( fromaddress, mailaddress, config.get('MailFaxReceived', 'subject') % faxInfo, faxInfo['format'], config.get('MailFaxReceived', 'text') % faxInfo, filename)
capi = capisuite.core.Capi(capi) config = capisuite.config.readGlobalConfig() try: spool = config.get('GLOBAL', "spool_dir") max_tries = config.getint('GLOBAL', "send_tries") delays = config.getList('GLOBAL', "send_delays") except NoOptionError, err: core.error("global option %s not found." % err.option) return # todo: implement config.getQueue(queue,user=None) doneQ = os.path.join(spool, "done") failedQ = os.path.join(spool, "failed") if not os.access(doneQ, os.W_OK) or not os.access(failedQ, os.W_OK): core.error("Can't read/write to the necessary spool dirs") return # search in all user-specified sendq's for user in config.listUsers(): outgoing_num = config.getUser(user, "outgoing_msn") if not outgoing_num: incoming_nums = config.getUser(user, "fax_numbers") if not incoming_nums: continue outgoing_num = incoming_nums.split(',')[0].strip() mailaddress = config.getUser(user, "fax_email", user) fromaddress = config.getUser(user, "fax_email_from", user) for jobnum, controlfile in capisuite.fax.getQueueFiles(config, user):