Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
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
Exemple #5
0
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
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
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
Exemple #9
0
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)
Exemple #10
0
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)
Exemple #11
0
    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
Exemple #12
0
    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):
Exemple #13
0
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)
Exemple #14
0
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)
Exemple #15
0
    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
Exemple #16
0
    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):