Exemplo n.º 1
0
    def run(self, **kwargs):
        logger = init_call_retry.get_logger()
        logger.info("TASK :: init_call_retry")
        try:
            # get callrequest which are failed
            callreq_retry_list = Callrequest.objects.filter(status=2, call_type=1)
            for callreq in callreq_retry_list:
                try:
                    # Call type => Retry Done = 3
                    callreq.call_type = 3
                    callreq.save()

                    campaign_obj = Campaign.objects.get(id=callreq.campaign_id)
                    if campaign_obj:
                        if callreq.num_attempt >= campaign_obj.maxretry:
                            logger.error("Not allowed retry")
                            break

                    dialer_set = user_dialer_setting(callreq.user)
                    if dialer_set:
                        if callreq.num_attempt >= dialer_set.maxretry:
                            logger.error("Not allowed retry")
                            break
                except:
                    # Call type =>  Can Not Retry = 2
                    callreq.call_type = 2
                    callreq.save()
                    logger.error("Can't find dialer setting for user of the campaign : %s" \
                                 % callreq.campaign_id)
                    break

                # TODO : Review Logic
                # Crete new callrequest, Assign parent_callrequest, Change callrequest_type
                # & num_attempt
                obj = Callrequest(request_uuid=uuid1(),
                                    parent_callrequest_id=callreq.id,
                                    call_type=1,
                                    num_attempt=callreq.num_attempt+1,
                                    user=callreq.user,
                                    campaign_id=callreq.campaign_id,
                                    aleg_gateway_id=callreq.aleg_gateway_id,
                                    content_type=callreq.content_type,
                                    object_id=callreq.object_id,
                                    phone_number=callreq.phone_number)
                obj.save()
                # TODO : perform retry
                init_callrequest.delay(obj.id, obj.campaign_id)
        except:
            logger.error("Can't find failed callrequest")
            return False
        return True
Exemplo n.º 2
0
def check_retrycall_completion(callrequest):
    """
    We will check if the callrequest need to be restarted
    in order to achieve completion
    """

    # Check if subscriber is not completed and check if
    # subscriber.completion_count_attempt < campaign.completion_maxretry
    if (callrequest.subscriber.status == SUBSCRIBER_STATUS.COMPLETED
            or callrequest.subscriber.completion_count_attempt >=
            callrequest.campaign.completion_maxretry
            or not callrequest.campaign.completion_maxretry
            or callrequest.campaign.completion_maxretry == 0):
        logger.debug("Subscriber completed or limit reached!")
    else:
        # Increment subscriber.completion_count_attempt
        if callrequest.subscriber.completion_count_attempt:
            callrequest.subscriber.completion_count_attempt = callrequest.subscriber.completion_count_attempt + 1
        else:
            callrequest.subscriber.completion_count_attempt = 1
        callrequest.subscriber.save()

        # TODO: Add method in models.Callrequest to create copy
        # Init new callrequest -> delay at completion_intervalretry
        new_callrequest = Callrequest(
            request_uuid=uuid1(),
            parent_callrequest_id=callrequest.id,
            call_type=CALLREQUEST_TYPE.ALLOW_RETRY,
            num_attempt=callrequest.num_attempt + 1,
            user=callrequest.user,
            campaign_id=callrequest.campaign_id,
            aleg_gateway_id=callrequest.aleg_gateway_id,
            content_type=callrequest.content_type,
            object_id=callrequest.object_id,
            phone_number=callrequest.phone_number,
            timelimit=callrequest.timelimit,
            callerid=callrequest.callerid,
            caller_name=callrequest.caller_name,
            timeout=callrequest.timeout,
            content_object=callrequest.content_object,
            subscriber=callrequest.subscriber)
        new_callrequest.save()
        # NOTE : implement a PID algorithm
        second_towait = callrequest.campaign.completion_intervalretry
        logger.info("Init Completion Retry CallRequest %d in %d seconds" %
                    (new_callrequest.id, second_towait))
        init_callrequest.apply_async(args=[
            new_callrequest.id, callrequest.campaign.id,
            callrequest.campaign.callmaxduration
        ],
                                     countdown=second_towait)
Exemplo n.º 3
0
def check_retrycall_completion(callrequest):
    """
    We will check if the callrequest need to be restarted
    in order to achieve completion
    """

    # Check if subscriber is not completed and check if
    # subscriber.completion_count_attempt < campaign.completion_maxretry
    if (
        callrequest.subscriber.status == SUBSCRIBER_STATUS.COMPLETED
        or callrequest.subscriber.completion_count_attempt >= callrequest.campaign.completion_maxretry
        or not callrequest.campaign.completion_maxretry
        or callrequest.campaign.completion_maxretry == 0
    ):
        logger.debug("Subscriber completed or limit reached!")
    else:
        # Let's Init a new callrequest

        # Increment subscriber.completion_count_attempt
        if callrequest.subscriber.completion_count_attempt:
            callrequest.subscriber.completion_count_attempt = callrequest.subscriber.completion_count_attempt + 1
        else:
            callrequest.subscriber.completion_count_attempt = 1
        callrequest.subscriber.save()

        # init_callrequest -> delay at completion_intervalretry
        new_callrequest = Callrequest(
            request_uuid=uuid1(),
            parent_callrequest_id=callrequest.id,
            call_type=CALLREQUEST_TYPE.ALLOW_RETRY,
            num_attempt=callrequest.num_attempt + 1,
            user=callrequest.user,
            campaign_id=callrequest.campaign_id,
            aleg_gateway_id=callrequest.aleg_gateway_id,
            content_type_id=callrequest.content_type_id,
            object_id=callrequest.object_id,
            phone_number=callrequest.phone_number,
            timelimit=callrequest.timelimit,
            callerid=callrequest.callerid,
            timeout=callrequest.timeout,
            content_object=callrequest.content_object,
            subscriber=callrequest.subscriber,
        )
        new_callrequest.save()
        # NOTE : implement a PID algorithm
        second_towait = callrequest.campaign.completion_intervalretry
        logger.debug("Init Completion Retry CallRequest in  %d seconds" % second_towait)
        init_callrequest.apply_async(
            args=[new_callrequest.id, callrequest.campaign.id, callrequest.campaign.callmaxduration],
            countdown=second_towait,
        )
Exemplo n.º 4
0
    def setUp(self):
        self.user = User.objects.get(username='******')
        VoipSearchForm(self.user)

        try:
            content_type_id = ContentType.objects.get(model='survey').id
        except:
            content_type_id = 1

        # Callrequest model
        self.callrequest = Callrequest(
            call_type=1,
            status=1,
            user=self.user,
            phone_number='123456',
            subscriber_id=1,
            campaign_id=1,
            aleg_gateway_id=1,
            content_type_id=content_type_id,
            object_id=1,
        )
        self.callrequest.save()

        # VoIPCall model
        self.voipcall = VoIPCall(
            user=self.user,
            used_gateway_id=1,
            callrequest=self.callrequest,
            callid='Top Gun',
            phone_number='123456',
            leg_type=1,
            duration=20,
        )
        self.voipcall.save()
        self.assertEqual(self.voipcall.__unicode__(), u'1 - Top Gun')

        # Test mgt command
        call_command("create_callrequest_cdr", "1|1")

        call_command("create_callrequest_cdr", "3|1")
Exemplo n.º 5
0
    def setUp(self):
        self.user = User.objects.get(username='******')
        VoipSearchForm(self.user)

        try:
            content_type_id = ContentType.objects.get(model='survey').id
        except:
            content_type_id = 1

        # Callrequest model
        self.callrequest = Callrequest(
            call_type=1,
            status=1,
            user=self.user,
            phone_number='123456',
            subscriber_id=1,
            campaign_id=1,
            aleg_gateway_id=1,
            content_type_id=content_type_id,
            object_id=1,
        )
        self.callrequest.save()

        # VoIPCall model
        self.voipcall = VoIPCall(
            user=self.user,
            used_gateway_id=1,
            callrequest=self.callrequest,
            callid='Top Gun',
            phone_number='123456',
            leg_type=1,
            duration=20,
        )
        self.voipcall.save()
        self.assertEqual(self.voipcall.__unicode__(), u'2 - Top Gun')

        # Test mgt command
        call_command("create_callrequest_cdr", "1|1")

        call_command("create_callrequest_cdr", "3|1")
Exemplo n.º 6
0
    def run(self, **kwargs):
        logger.info("TASK :: alarmrequest_dispatcher")

        # Select AlarmRequest where date >= now() - 60 minutes
        start_time = datetime.utcnow().replace(tzinfo=utc) + relativedelta(minutes=-60)
        alarmreq_list = AlarmRequest.objects.filter(date__gte=start_time, status=ALARMREQUEST_STATUS.PENDING)
        no_alarmreq = alarmreq_list.count()
        if no_alarmreq == 0:
            logger.error("alarmrequest_dispatcher - no alarmreq found!")
            return False

        # Set time to wait for balanced dispatching of calls
        #time_to_wait = int(60 / DIV_MIN) / no_subscriber
        time_to_wait = 6.0 / no_alarmreq
        count = 0

        # Browse all the AlarmRequest found
        for obj_alarmreq in alarmreq_list:
            # Loop on AlarmRequest and start to the initcall's task
            count = count + 1
            second_towait = floor(count * time_to_wait)
            ms_addtowait = (count * time_to_wait) - second_towait
            logger.info("Init CallRequest for AlarmRequest in %d seconds (alarmreq:%d)" % (second_towait, obj_alarmreq.id))

            if obj_alarmreq.alarm.maxretry == 0:
                call_type = CALLREQUEST_TYPE.CANNOT_RETRY
            else:
                call_type = CALLREQUEST_TYPE.ALLOW_RETRY

            try:
                caluser_profile = CalendarUserProfile.objects.get(user=obj_alarmreq.alarm.event.creator)
            except CalendarUserProfile.DoesNotExist:
                logger.error("Error retrieving CalendarUserProfile")
                return False

            #manager_profile = UserProfile.objects.get(user=caluser_profile.manager)
            # manager_profile = caluser_profile.manager.get_profile()
            # manager_profile.dialersetting
            # Use manager_profile.dialersetting to retrieve some settings

            # TODO: build settings for this
            calltimeout = caluser_profile.calendar_setting.call_timeout
            callmaxduration = 60 * 60
            callerid = caluser_profile.calendar_setting.callerid
            caller_name = caluser_profile.calendar_setting.caller_name
            aleg_gateway = caluser_profile.calendar_setting.aleg_gateway
            content_type = ContentType.objects.get(model__in=["survey"])
            object_id = caluser_profile.calendar_setting.survey_id

            # Create Callrequest to track the call task
            new_callrequest = Callrequest(
                status=CALLREQUEST_STATUS.PENDING,
                call_type=call_type,
                call_time=datetime.utcnow().replace(tzinfo=utc),
                timeout=calltimeout,
                callerid=callerid,
                caller_name=caller_name,
                phone_number=obj_alarmreq.alarm.alarm_phonenumber,
                alarm_request_id=obj_alarmreq.id,
                aleg_gateway=aleg_gateway,
                content_type=content_type,
                object_id=object_id,
                user=caluser_profile.manager,
                extra_data='',
                timelimit=callmaxduration)
            new_callrequest.save()

            init_callrequest.apply_async(
                args=[new_callrequest.id, None, callmaxduration, ms_addtowait, obj_alarmreq.id],
                countdown=second_towait)

            obj_alarmreq.callrequest = new_callrequest
            obj_alarmreq.status = ALARMREQUEST_STATUS.IN_PROCESS
            obj_alarmreq.save()
            # Increment num_attempt
            obj_alarmreq.alarm.num_attempt = obj_alarmreq.alarm.num_attempt + 1
            obj_alarmreq.alarm.save()
Exemplo n.º 7
0
def process_callevent(record):
    """
    Process the callevent, this tasks will:
        - Retrieve the callrequest using either callrequest_id or request_uuid
        - create the voipcall, and save different data
    """
    # TODO: add method in utils parse_callevent
    app_type = 'campaign'
    event_name = record[1]
    body = record[2]
    job_uuid = record[3]
    call_uuid = record[4]
    # used_gateway_id = record[5]
    callrequest_id = record[6]
    alarm_request_id = record[7]
    callerid = record[8]
    phonenumber = record[9]
    duration = record[10]
    billsec = record[11]
    hangup_cause = record[12]
    hangup_cause_q850 = record[13]
    starting_date = record[14]
    amd_status = record[17]
    leg = record[18]

    if event_name == 'BACKGROUND_JOB':
        # hangup cause come from body
        hangup_cause = body[5:]

    if hangup_cause == '':
        hangup_cause = body[5:]

    request_uuid = job_uuid
    opt_hangup_cause = hangup_cause
    debug_query(22)

    try:
        if callrequest_id == 0:
            callrequest = Callrequest.objects \
                .select_related('aleg_gateway', 'subscriber', 'campaign') \
                .get(request_uuid=request_uuid.strip(' \t\n\r'))
        else:
            # mainly coming here
            callrequest = Callrequest.objects \
                .select_related('aleg_gateway', 'subscriber', 'campaign') \
                .get(id=callrequest_id)
    except:
        logger.error("Cannot find Callrequest job_uuid : %s" % job_uuid)
        return True

    if callrequest.alarm_request_id:
        app_type = 'alarm'
        alarm_req = AlarmRequest.objects.get(pk=callrequest.alarm_request_id)
        # Overwrite alarm_request_id as this is equal to 0 when call fails
        alarm_request_id = callrequest.alarm_request_id

    logger.debug("Find Callrequest id : %d" % callrequest.id)
    debug_query(23)

    if leg == 'aleg' and app_type == 'campaign':
        # Update callrequest
        # update_callrequest.delay(callrequest, opt_hangup_cause)
        # Disabled above tasks to reduce amount of tasks

        # Only the aleg will update the subscriber status / Bleg is only recorded
        # Update Callrequest Status
        if opt_hangup_cause == 'NORMAL_CLEARING':
            callrequest.status = CALLREQUEST_STATUS.SUCCESS
            if callrequest.subscriber.status != SUBSCRIBER_STATUS.COMPLETED:
                callrequest.subscriber.status = SUBSCRIBER_STATUS.SENT
        else:
            callrequest.status = CALLREQUEST_STATUS.FAILURE
            callrequest.subscriber.status = SUBSCRIBER_STATUS.FAIL
        callrequest.hangup_cause = opt_hangup_cause
        # ...

        callrequest.save()
        callrequest.subscriber.save()
        debug_query(24)
    elif leg == 'aleg' and app_type == 'alarm':
        try:
            caluser_profile = CalendarUserProfile.objects.get(
                user=alarm_req.alarm.event.creator)
        except CalendarUserProfile.DoesNotExist:
            logger.error("Error retrieving CalendarUserProfile")
            return False

        if opt_hangup_cause == 'NORMAL_CLEARING' and \
           amd_status == 'machine' and \
           caluser_profile.calendar_setting.voicemail and \
           caluser_profile.calendar_setting.amd_behavior == AMD_BEHAVIOR.HUMAN_ONLY:
            # Call reached AMD
            callrequest.status = CALLREQUEST_STATUS.FAILURE
            alarm_req.status = ALARMREQUEST_STATUS.FAILURE
            alarm_req.alarm.status = ALARM_STATUS.FAILURE
        elif opt_hangup_cause == 'NORMAL_CLEARING':
            # Call is successful
            callrequest.status = CALLREQUEST_STATUS.SUCCESS
            alarm_req.status = ALARMREQUEST_STATUS.SUCCESS
            alarm_req.duration = duration
            alarm_req.alarm.status = ALARM_STATUS.SUCCESS
        else:
            # Call failed
            callrequest.status = CALLREQUEST_STATUS.FAILURE
            alarm_req.status = ALARMREQUEST_STATUS.FAILURE
            alarm_req.alarm.status = ALARM_STATUS.FAILURE
        callrequest.hangup_cause = opt_hangup_cause

        callrequest.save()
        alarm_req.save()
        alarm_req.alarm.save()
        debug_query(24)

    if call_uuid == '':
        call_uuid = job_uuid
    if callerid == '':
        callerid = callrequest.callerid
    if phonenumber == '':
        phonenumber = callrequest.phone_number
    # Create those in Bulk - add in a buffer until reach certain number
    # buff_voipcall.save(
    #     obj_callrequest=callrequest,
    #     request_uuid=request_uuid,
    #     leg=leg,
    #     hangup_cause=opt_hangup_cause,
    #     hangup_cause_q850=hangup_cause_q850,
    #     callerid=callerid,
    #     phonenumber=phonenumber,
    #     starting_date=starting_date,
    #     call_uuid=call_uuid,
    #     duration=duration,
    #     billsec=billsec,
    #     amd_status=amd_status)

    # debug_query(25)

    voipcall_save(callrequest=callrequest,
                  request_uuid=request_uuid,
                  leg=leg,
                  hangup_cause=opt_hangup_cause,
                  hangup_cause_q850=hangup_cause_q850,
                  callerid=callerid,
                  phonenumber=phonenumber,
                  starting_date=starting_date,
                  call_uuid=call_uuid,
                  duration=duration,
                  billsec=billsec,
                  amd_status=amd_status)

    # If the call failed we will check if we want to make a retry call
    # Add condition to retry when it s machine and we want to reach a human
    if (app_type == 'campaign' and opt_hangup_cause != 'NORMAL_CLEARING'
        and callrequest.call_type == CALLREQUEST_TYPE.ALLOW_RETRY) or \
       (app_type == 'campaign' and amd_status == 'machine' and callrequest.campaign.voicemail and
            callrequest.campaign.amd_behavior == AMD_BEHAVIOR.HUMAN_ONLY):
        # Update to Retry Done
        callrequest.call_type = CALLREQUEST_TYPE.RETRY_DONE
        callrequest.save()

        debug_query(26)

        # check if we are allowed to retry on failure
        if ((callrequest.subscriber.count_attempt - 1) >=
                callrequest.campaign.maxretry
                or not callrequest.campaign.maxretry):
            logger.error("Not allowed retry - Maxretry (%d)" %
                         callrequest.campaign.maxretry)
            # Check here if we should try for completion
            check_retrycall_completion(callrequest)
            debug_query(28)
        else:
            # Allowed Retry
            logger.error("Allowed Retry - Maxretry (%d)" %
                         callrequest.campaign.maxretry)

            # Create new callrequest, Assign parent_callrequest,
            # Change callrequest_type & num_attempt
            new_callrequest = Callrequest(
                request_uuid=uuid1(),
                parent_callrequest_id=callrequest.id,
                call_type=CALLREQUEST_TYPE.ALLOW_RETRY,
                num_attempt=callrequest.num_attempt + 1,
                user=callrequest.user,
                campaign_id=callrequest.campaign_id,
                aleg_gateway_id=callrequest.aleg_gateway_id,
                content_type=callrequest.content_type,
                object_id=callrequest.object_id,
                phone_number=callrequest.phone_number,
                timelimit=callrequest.timelimit,
                callerid=callrequest.callerid,
                timeout=callrequest.timeout,
                subscriber_id=callrequest.subscriber_id)
            new_callrequest.save()
            # NOTE : implement a PID algorithm
            second_towait = callrequest.campaign.intervalretry
            debug_query(29)

            logger.debug("Init Retry CallRequest in  %d seconds" %
                         second_towait)
            init_callrequest.apply_async(args=[
                new_callrequest.id, callrequest.campaign.id,
                callrequest.campaign.callmaxduration
            ],
                                         countdown=second_towait)

    elif app_type == 'campaign':
        # The Call is Answered and it's a campaign call
        logger.info("Check for completion call")

        # Check if we should relaunch a new call to achieve completion
        check_retrycall_completion(callrequest)

    elif (opt_hangup_cause != 'NORMAL_CLEARING' and app_type == 'alarm') or \
         (amd_status == 'machine' and app_type == 'alarm' and
          caluser_profile.calendar_setting.voicemail and
          caluser_profile.calendar_setting.amd_behavior == AMD_BEHAVIOR.HUMAN_ONLY):
        # Alarm callrequest failed or Alarm callrequest reached voicemail
        logger.info("Check to retry alarm")
        check_retry_alarm(alarm_request_id)
    else:
        logger.info("Retry: No matching conditions")
Exemplo n.º 8
0
    def run(self, campaign_id):
        """
        This task retrieves the next outbound call to be made for a given
        campaign, and will create a new callrequest and schedule a task to
        process those calls

        **Attributes**:

            * ``campaign_id`` - Campaign ID
        """
        logger = self.get_logger()
        logger.info("TASK :: pending_call_processing = %d" % campaign_id)

        debug_query(0)

        try:
            obj_campaign = Campaign.objects\
                .select_related('user__userprofile__dialersetting', 'aleg_gateway', 'content_type')\
                .get(id=campaign_id)
        except:
            logger.error("Can't find this campaign")
            return False

        # TODO : Control the Speed
        # if there is many task pending we should slow down
        frequency = obj_campaign.frequency  # default 10 calls per minutes

        debug_query(1)

        #TODO: move this logic of setting call_type after CallRequest post_save
        # Default call_type
        call_type = CALLREQUEST_TYPE.ALLOW_RETRY
        # Check campaign's maxretry
        if obj_campaign.maxretry == 0:
            call_type = CALLREQUEST_TYPE.CANNOT_RETRY

        # Check user's dialer setting maxretry
        try:
            obj_campaign.user.userprofile.dialersetting
            if obj_campaign.user.userprofile.dialersetting.maxretry == 0:
                call_type = CALLREQUEST_TYPE.CANNOT_RETRY
        except ObjectDoesNotExist:
            logger.error("Can't find user's dialersetting")
            return False

        debug_query(2)

        # Speed
        # Check if the other tasks send for this campaign finished to be ran

        # Get the subscriber of this campaign
        # get_pending_subscriber get Max 1000 records
        if settings.HEARTBEAT_MIN == 1:  # 1 task per minute
            callfrequency = frequency  # task run only once per minute, so we can assign frequency
        else:
            callfrequency = int(frequency / settings.HEARTBEAT_MIN) + 1  # 1000 per minutes
            #callfrequency = int(frequency) + 1  # 1000 per minutes

        (list_subscriber, no_subscriber) = obj_campaign\
            .get_pending_subscriber_update(callfrequency, SUBSCRIBER_STATUS.IN_PROCESS)
        logger.info("##subscriber=%d campaign_id=%d callfreq=%d freq=%d" %
                    (no_subscriber, campaign_id, callfrequency, frequency))
        debug_query(3)

        if no_subscriber == 0:
            return False

        # Set time to wait for balanced dispatching of calls
        time_to_wait = (60.0 / settings.HEARTBEAT_MIN) / no_subscriber
        count = 0
        loopnow = datetime.utcnow()
        loopnow + timedelta(seconds=1.55)

        for elem_camp_subscriber in list_subscriber:
            # Loop on Subscriber and start the initcall's task
            count = count + 1
            second_towait = floor(count * time_to_wait)
            # ms_addtowait now used anymore, replaced by async eta
            ms_addtowait = (count * time_to_wait) - second_towait

            eta_delta = loopnow + timedelta(seconds=(count * time_to_wait))
            # as we use eta_delta ms_addtowait is set to 0
            ms_addtowait = 0

            logger.info("Init CallRequest in %d seconds (cmpg:%d,subscr:%d:eta_delta:%s)" %
                        (second_towait, campaign_id, elem_camp_subscriber.id, eta_delta))

            phone_number = elem_camp_subscriber.duplicate_contact
            debug_query(4)

            #Verify that the contact is authorized
            if not obj_campaign.is_authorized_contact(obj_campaign.user.userprofile.dialersetting, phone_number):
                logger.error("Error : Contact not authorized")
                elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED
                elem_camp_subscriber.save()
                continue
            #Verify that the contact is not in the DNC list
            if obj_campaign.dnc:
                res_dnc = DNCContact.objects.filter(dnc_id=obj_campaign.dnc_id, phone_number=phone_number)
                if res_dnc:
                    logger.error("Contact (%s) in DNC list" % phone_number)
                    elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED
                    elem_camp_subscriber.save()
                    continue
                else:
                    logger.debug("Contact (%s) not in DNC list" % phone_number)

            debug_query(5)

            #TODO: idea to speed up, create bluck of 10(Y) and then send a list
            # of callrequest_id to init_callrequest

            # Create Callrequest
            new_callrequest = Callrequest(
                status=CALLREQUEST_STATUS.PENDING,
                call_type=call_type,
                call_time=datetime.utcnow().replace(tzinfo=utc),
                timeout=obj_campaign.calltimeout,
                callerid=obj_campaign.callerid,
                caller_name=obj_campaign.caller_name,
                phone_number=phone_number,
                campaign=obj_campaign,
                aleg_gateway=obj_campaign.aleg_gateway,
                content_type=obj_campaign.content_type,
                object_id=obj_campaign.object_id,
                user=obj_campaign.user,
                extra_data=obj_campaign.extra_data,
                timelimit=obj_campaign.callmaxduration,
                subscriber=elem_camp_subscriber)
            new_callrequest.save()

            debug_query(6)

            second_towait = second_towait + settings.DELAY_OUTBOUND

            init_callrequest.apply_async(
                args=[new_callrequest.id, obj_campaign.id, obj_campaign.callmaxduration, ms_addtowait],
                # countdown=second_towait)
                eta=eta_delta)

            # Shell_plus
            # from dialer_cdr.tasks import init_callrequest
            # from datetime import datetime
            # new_callrequest_id = 112
            # obj_campaign_id = 3
            # countdown = 1
            # init_callrequest.apply_async(args=[new_callrequest.id, obj_campaign.id, obj_campaign.callmaxduration, ms_addtowait], countdown=1)

        debug_query(7)
        return True
Exemplo n.º 9
0
class DialerCdrModel(TestCase):

    """Test Callrequest, VoIPCall models"""

    fixtures = ['auth_user.json', 'gateway.json', 'dialer_setting.json',
                'user_profile.json', 'phonebook.json', 'contact.json',
                'dnc_list.json', 'dnc_contact.json', 'survey.json',
                'campaign.json', 'subscriber.json', 'callrequest.json', 'voipcall.json',
                'user_profile.json']

    def setUp(self):
        self.user = User.objects.get(username='******')
        VoipSearchForm(self.user)

        try:
            content_type_id = ContentType.objects.get(model='survey').id
        except:
            content_type_id = 1

        # Callrequest model
        self.callrequest = Callrequest(
            call_type=1,
            status=1,
            user=self.user,
            phone_number='123456',
            subscriber_id=1,
            campaign_id=1,
            aleg_gateway_id=1,
            content_type_id=content_type_id,
            object_id=1,
        )
        self.callrequest.save()

        # VoIPCall model
        self.voipcall = VoIPCall(
            user=self.user,
            used_gateway_id=1,
            callrequest=self.callrequest,
            callid='Top Gun',
            phone_number='123456',
            leg_type=1,
            duration=20,
        )
        self.voipcall.save()
        self.assertEqual(self.voipcall.__unicode__(), u'2 - Top Gun')

        # Test mgt command
        call_command("create_callrequest_cdr", "1|1")

        call_command("create_callrequest_cdr", "3|1")

    def test_name(self):
        self.assertEqual(self.callrequest.phone_number, "123456")
        #self.assertEqual(self.callrequest.__unicode__(), u'Top Gun')
        self.assertEqual(self.voipcall.phone_number, "123456")

        Callrequest.objects.get_pending_callrequest()

        self.voipcall.destination_name()
        self.voipcall.duration = ''
        self.voipcall.min_duration()
        self.voipcall.duration = 12
        self.voipcall.min_duration()

    def teardown(self):
        self.callrequest.delete()
        self.voipcall.delete()
Exemplo n.º 10
0
    def create(self, request=None, **kwargs):
        """POST method of Hangupcall API"""
        logger.debug('Hangupcall API authentication called!')
        auth_result = self._meta.authentication.is_authenticated(request)
        if not auth_result is True:
            raise ImmediateHttpResponse(response=http.HttpUnauthorized())
        auth_result = self._meta.authorization.is_authorized(request, object)
        errors = self._meta.validation.is_valid(request)
        if not errors:
            opt_request_uuid = request.POST.get('RequestUUID')
            opt_hangup_cause = request.POST.get('HangupCause')
            try:
                callrequest = Callrequest.objects.get(
                    request_uuid=opt_request_uuid)
            except:
                logger.debug('Hangupcall Error cannot find the Callrequest!')
            try:
                obj_subscriber = CampaignSubscriber.objects.get(
                    id=callrequest.campaign_subscriber.id)
                if opt_hangup_cause == 'NORMAL_CLEARING':
                    obj_subscriber.status = 5  # Complete
                else:
                    obj_subscriber.status = 4  # Fail
                obj_subscriber.save()
            except:
                logger.debug('Hangupcall Error cannot find the '
                             'Campaignsubscriber!')

            # 2 / FAILURE ; 3 / RETRY ; 4 / SUCCESS
            if opt_hangup_cause == 'NORMAL_CLEARING':
                callrequest.status = 4  # Success
            else:
                callrequest.status = 2  # Failure
            callrequest.hangup_cause = opt_hangup_cause
            #save callrequest & campaignsubscriber
            callrequest.save()
            data = {}
            for element in CDR_VARIABLES:
                if not request.POST.get('variable_%s' % element):
                    data[element] = None
                else:
                    data[element] = request.POST.get('variable_%s' % element)
            from_plivo = request.POST.get('From')
            to_plivo = request.POST.get('To')

            create_voipcall(obj_callrequest=callrequest,
                            plivo_request_uuid=opt_request_uuid,
                            data=data,
                            data_prefix='',
                            leg='a',
                            hangup_cause=opt_hangup_cause,
                            from_plivo=from_plivo,
                            to_plivo=to_plivo)
            object_list = [{'result': 'OK'}]
            logger.debug('Hangupcall API : Result 200!')
            obj = CustomXmlEmitter()

            #We will manage the retry directly from the API
            if opt_hangup_cause != 'NORMAL_CLEARING'\
            and callrequest.call_type == 1:  # Allow retry
                #Update to Retry Done
                callrequest.call_type = 3
                callrequest.save()

                dialer_set = user_dialer_setting(callrequest.user)
                if callrequest.num_attempt >= callrequest.campaign.maxretry\
                or callrequest.num_attempt >= dialer_set.maxretry:
                    logger.error("Not allowed retry - Maxretry (%d)" %\
                                 callrequest.campaign.maxretry)
                else:
                    #Allowed Retry

                    # TODO : Review Logic
                    # Create new callrequest, Assign parent_callrequest,
                    # Change callrequest_type & num_attempt
                    new_callrequest = Callrequest(
                        request_uuid=uuid1(),
                        parent_callrequest_id=callrequest.id,
                        call_type=1,
                        num_attempt=callrequest.num_attempt + 1,
                        user=callrequest.user,
                        campaign_id=callrequest.campaign_id,
                        aleg_gateway_id=callrequest.aleg_gateway_id,
                        content_type=callrequest.content_type,
                        object_id=callrequest.object_id,
                        phone_number=callrequest.phone_number)
                    new_callrequest.save()
                    #Todo Check if it's a good practice
                    #implement a PID algorithm
                    second_towait = callrequest.campaign.intervalretry
                    launch_date = datetime.now() + \
                                  timedelta(seconds=second_towait)
                    logger.info("Init Retry CallRequest at %s" %\
                                (launch_date.strftime("%b %d %Y %I:%M:%S")))
                    init_callrequest.apply_async(
                        args=[new_callrequest.id, callrequest.campaign.id],
                        eta=launch_date)

            return self.create_response(request,
                                        obj.render(request, object_list))
        else:
            if len(errors):
                if request:
                    desired_format = self.determine_format(request)
                else:
                    desired_format = self._meta.default_format

                serialized = self.serialize(request, errors, desired_format)
                response = http.HttpBadRequest(content=serialized,
                                               content_type=desired_format)
                raise ImmediateHttpResponse(response=response)
Exemplo n.º 11
0
class DialerCdrModel(TestCase):
    """Test Callrequest, VoIPCall models"""

    fixtures = [
        'auth_user.json', 'gateway.json', 'dialer_setting.json',
        'contenttype.json', 'user_profile.json', 'phonebook.json',
        'contact.json', 'dnc_list.json', 'dnc_contact.json', 'campaign.json',
        'subscriber.json', 'callrequest.json', 'survey.json', 'section.json'
    ]

    def setUp(self):
        self.user = User.objects.get(username='******')
        VoipSearchForm(self.user)

        try:
            content_type_id = ContentType.objects.get(model='survey').id
        except:
            content_type_id = 1

        # Callrequest model
        self.callrequest = Callrequest(
            call_type=1,
            status=1,
            user=self.user,
            phone_number='123456',
            subscriber_id=1,
            campaign_id=1,
            aleg_gateway_id=1,
            content_type_id=content_type_id,
            object_id=1,
        )
        self.callrequest.save()

        # VoIPCall model
        self.voipcall = VoIPCall(
            user=self.user,
            used_gateway_id=1,
            callrequest=self.callrequest,
            callid='Top Gun',
            phone_number='123456',
            leg_type=1,
            duration=20,
        )
        self.voipcall.save()
        self.assertEqual(self.voipcall.__unicode__(), u'1 - Top Gun')

        # Test mgt command
        call_command("create_callrequest_cdr", "1|1")

        call_command("create_callrequest_cdr", "3|1")

    def test_name(self):
        self.assertEqual(self.callrequest.phone_number, "123456")
        #self.assertEqual(self.callrequest.__unicode__(), u'Top Gun')
        self.assertEqual(self.voipcall.phone_number, "123456")

        Callrequest.objects.get_pending_callrequest()

        self.voipcall.destination_name()
        self.voipcall.duration = ''
        self.voipcall.min_duration()
        self.voipcall.duration = 12
        self.voipcall.min_duration()

    def teardown(self):
        self.callrequest.delete()
        self.voipcall.delete()
Exemplo n.º 12
0
    def run(self, campaign_id):
        """
        This task retrieves the next outbound call to be made for a given
        campaign, and will create a new callrequest and schedule a task to
        process those calls

        **Attributes**:

            * ``campaign_id`` - Campaign ID
        """
        logger = self.get_logger()
        logger.info("TASK :: pending_call_processing = %d" % campaign_id)

        debug_query(0)

        try:
            obj_campaign = Campaign.objects\
                .select_related('user__userprofile__dialersetting', 'aleg_gateway', 'content_type')\
                .get(id=campaign_id)
        except:
            logger.error("Can't find this campaign")
            return False

        # Ensure the content_type become "survey" when campagin starts
        if not obj_campaign.has_been_started:
            # change has_been_started flag
            obj_campaign.has_been_started = True
            obj_campaign.save()

            if obj_campaign.content_type.model == 'survey_template':
                # Copy survey
                survey_template = Survey_template.objects.get(
                    user=obj_campaign.user, pk=obj_campaign.object_id)
                survey_template.copy_survey_template(obj_campaign.id)
            collect_subscriber.delay(obj_campaign.id)

        # TODO : Control the Speed
        # if there is many task pending we should slow down
        frequency = obj_campaign.frequency  # default 10 calls per minutes

        debug_query(1)

        # TODO: move this logic of setting call_type after CallRequest post_save
        # Default call_type
        call_type = CALLREQUEST_TYPE.ALLOW_RETRY
        # Check campaign's maxretry
        if obj_campaign.maxretry == 0:
            call_type = CALLREQUEST_TYPE.CANNOT_RETRY

        # Check user's dialer setting maxretry
        try:
            obj_campaign.user.userprofile.dialersetting
            if obj_campaign.user.userprofile.dialersetting.maxretry == 0:
                call_type = CALLREQUEST_TYPE.CANNOT_RETRY
        except ObjectDoesNotExist:
            logger.error("Can't find user's dialersetting")
            return False

        debug_query(2)

        # Speed
        # Check if the other tasks send for this campaign finished to be ran

        # Get the subscriber of this campaign
        # get_pending_subscriber get Max 1000 records
        if settings.HEARTBEAT_MIN == 1:  # 1 task per minute
            callfrequency = frequency  # task run only once per minute, so we can assign frequency
        else:
            callfrequency = int(
                frequency / settings.HEARTBEAT_MIN) + 1  # 1000 per minutes
            # callfrequency = int(frequency) + 1  # 1000 per minutes

        (list_subscriber, no_subscriber) = obj_campaign\
            .get_pending_subscriber_update(callfrequency, SUBSCRIBER_STATUS.IN_PROCESS)
        logger.info("##subscriber=%d campaign_id=%d callfreq=%d freq=%d" %
                    (no_subscriber, campaign_id, callfrequency, frequency))
        debug_query(3)

        if no_subscriber == 0:
            return False

        list_cr = []
        bulk_record = []
        # this is used to tag and retrieve the id that are inserted
        bulk_uuid = str(uuid1())
        for elem_camp_subscriber in list_subscriber:
            phone_number = elem_camp_subscriber.duplicate_contact
            debug_query(4)

            # Verify that the contact is authorized
            if not obj_campaign.is_authorized_contact(
                    obj_campaign.user.userprofile.dialersetting, phone_number):
                logger.error("Error : Contact not authorized")
                elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED
                elem_camp_subscriber.save()
                continue
            # Verify that the contact is not in the DNC list
            if obj_campaign.dnc:
                res_dnc = DNCContact.objects.filter(dnc_id=obj_campaign.dnc_id,
                                                    phone_number=phone_number)
                if res_dnc:
                    logger.error("Contact (%s) in DNC list" % phone_number)
                    elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED
                    elem_camp_subscriber.save()
                    continue
                else:
                    logger.debug("Contact (%s) not in DNC list" % phone_number)

            debug_query(5)

            bulk_record.append(
                Callrequest(status=CALLREQUEST_STATUS.PENDING,
                            call_type=call_type,
                            call_time=datetime.utcnow().replace(tzinfo=utc),
                            timeout=obj_campaign.calltimeout,
                            callerid=obj_campaign.callerid,
                            caller_name=obj_campaign.caller_name,
                            phone_number=phone_number,
                            campaign=obj_campaign,
                            aleg_gateway=obj_campaign.aleg_gateway,
                            content_type=obj_campaign.content_type,
                            object_id=obj_campaign.object_id,
                            user=obj_campaign.user,
                            extra_data=obj_campaign.extra_data,
                            timelimit=obj_campaign.callmaxduration,
                            subscriber=elem_camp_subscriber,
                            request_uuid=bulk_uuid))
            debug_query(6)

        # Create Callrequests in Bulk
        logger.info("Bulk Create CallRequest => %d" % (len(bulk_record)))
        Callrequest.objects.bulk_create(bulk_record)

        # Set time to wait for balanced dispatching of calls
        time_to_wait = (60.0 / settings.HEARTBEAT_MIN) / no_subscriber
        count = 0
        loopnow = datetime.utcnow()
        loopnow + timedelta(seconds=1.55)

        # Retrienve the one we just created
        list_cr = Callrequest.objects.filter(request_uuid=bulk_uuid).all()
        for cr in list_cr:
            # Loop on Subscriber and start the initcall's task
            count = count + 1
            second_towait = floor(count * time_to_wait)
            # ms_addtowait now used anymore, replaced by async eta
            ms_addtowait = (count * time_to_wait) - second_towait

            eta_delta = loopnow + timedelta(seconds=(count * time_to_wait))
            # as we use eta_delta ms_addtowait is set to 0
            ms_addtowait = 0

            logger.info(
                "Init CallRequest in %d seconds (cmpg:%d,subscr:%d:eta_delta:%s)"
                % (second_towait, campaign_id, elem_camp_subscriber.id,
                   eta_delta))

            init_callrequest.apply_async(
                args=[
                    cr.id, obj_campaign.id, obj_campaign.callmaxduration,
                    ms_addtowait
                ],
                # countdown=second_towait)
                eta=eta_delta)

            second_towait = second_towait + settings.DELAY_OUTBOUND

            # Shell_plus
            # from dialer_cdr.tasks import init_callrequest
            # from datetime import datetime
            # new_callrequest_id = 112
            # obj_campaign_id = 3
            # countdown = 1
            # init_callrequest.apply_async(
            #     args=[new_callrequest.id, obj_campaign.id, obj_campaign.callmaxduration, ms_addtowait],
            #     countdown=1)

        debug_query(7)
        return True
Exemplo n.º 13
0
def handle_callevent(record):
    """
    Handle the callevent, create the voipcall, and save different data
    """
    event_name = record[1]
    body = record[2]
    job_uuid = record[3]
    call_uuid = record[4]
    #used_gateway_id = record[5]
    callrequest_id = record[6]
    callerid = record[7]
    phonenumber = record[8]
    duration = record[9]
    billsec = record[10]
    hangup_cause = record[11]
    hangup_cause_q850 = record[12]
    starting_date = record[13]
    amd_status = record[16]
    leg = record[17]

    if event_name == 'BACKGROUND_JOB':
        #hangup cause come from body
        hangup_cause = body[5:]

    # if event_name == 'CHANNEL_HANGUP_COMPLETE':
    #     #hangup cause come from body
    #     print(event_name)

    if hangup_cause == '':
        hangup_cause = body[5:]

    request_uuid = job_uuid
    opt_hangup_cause = hangup_cause

    debug_query(22)

    try:
        if callrequest_id == 0:
            callrequest = Callrequest.objects\
                .select_related('aleg_gateway', 'subscriber', 'campaign')\
                .get(request_uuid=request_uuid.strip(' \t\n\r'))
        else:
            #mainly coming here
            callrequest = Callrequest.objects\
                .select_related('aleg_gateway', 'subscriber', 'campaign')\
                .get(id=callrequest_id)
    except:
        logger.error("Cannot find Callrequest job_uuid : %s" % job_uuid)
        return True

    logger.debug("Find Callrequest id : %d" % callrequest.id)
    debug_query(23)

    if leg == 'aleg':
        #Update callrequest
        #update_callrequest.delay(callrequest, opt_hangup_cause)
        #Disabled above tasks to reduce amount of tasks

        #Only the aleg will update the subscriber status / Bleg is only recorded
        #Update Callrequest Status
        if opt_hangup_cause == 'NORMAL_CLEARING':
            callrequest.status = CALLREQUEST_STATUS.SUCCESS
            if callrequest.subscriber.status != SUBSCRIBER_STATUS.COMPLETED:
                callrequest.subscriber.status = SUBSCRIBER_STATUS.SENT
        else:
            callrequest.status = CALLREQUEST_STATUS.FAILURE
            callrequest.subscriber.status = SUBSCRIBER_STATUS.FAIL
        callrequest.hangup_cause = opt_hangup_cause

        callrequest.save()
        callrequest.subscriber.save()
        debug_query(24)

    if call_uuid == '':
        call_uuid = job_uuid
    if callerid == '':
        callerid = callrequest.callerid
    if phonenumber == '':
        phonenumber = callrequest.phone_number

    #Create those in Bulk - add in a buffer until reach certain number
    # buff_voipcall.save(
    #     obj_callrequest=callrequest,
    #     request_uuid=request_uuid,
    #     leg=leg,
    #     hangup_cause=opt_hangup_cause,
    #     hangup_cause_q850=hangup_cause_q850,
    #     callerid=callerid,
    #     phonenumber=phonenumber,
    #     starting_date=starting_date,
    #     call_uuid=call_uuid,
    #     duration=duration,
    #     billsec=billsec,
    #     amd_status=amd_status)

    # debug_query(25)

    voipcall_save.delay(callrequest=callrequest,
                        request_uuid=request_uuid,
                        leg=leg,
                        hangup_cause=opt_hangup_cause,
                        hangup_cause_q850=hangup_cause_q850,
                        callerid=callerid,
                        phonenumber=phonenumber,
                        starting_date=starting_date,
                        call_uuid=call_uuid,
                        duration=duration,
                        billsec=billsec,
                        amd_status=amd_status)

    #TODO: Move this to tasks?

    #If the call failed we will check if we want to make a retry call
    #Add condition to retry when it s machine and we want to reach a human
    if (opt_hangup_cause != 'NORMAL_CLEARING' and callrequest.call_type == CALLREQUEST_TYPE.ALLOW_RETRY) or \
       (amd_status == 'machine' and callrequest.campaign.voicemail
       and callrequest.campaign.amd_behavior == AMD_BEHAVIOR.HUMAN_ONLY):
        #Update to Retry Done
        callrequest.call_type = CALLREQUEST_TYPE.RETRY_DONE
        callrequest.save()

        debug_query(26)

        #check if we are allowed to retry on failure
        if ((callrequest.subscriber.count_attempt - 1) >=
                callrequest.campaign.maxretry
                or not callrequest.campaign.maxretry):
            logger.error("Not allowed retry - Maxretry (%d)" %
                         callrequest.campaign.maxretry)
            #Check here if we should try for completion
            check_retrycall_completion(callrequest)
            debug_query(28)
        else:
            #Allowed Retry
            logger.error("Allowed Retry - Maxretry (%d)" %
                         callrequest.campaign.maxretry)

            # Create new callrequest, Assign parent_callrequest,
            # Change callrequest_type & num_attempt
            new_callrequest = Callrequest(
                request_uuid=uuid1(),
                parent_callrequest_id=callrequest.id,
                call_type=CALLREQUEST_TYPE.ALLOW_RETRY,
                num_attempt=callrequest.num_attempt + 1,
                user=callrequest.user,
                campaign_id=callrequest.campaign_id,
                aleg_gateway_id=callrequest.aleg_gateway_id,
                content_type=callrequest.content_type,
                object_id=callrequest.object_id,
                phone_number=callrequest.phone_number,
                timelimit=callrequest.timelimit,
                callerid=callrequest.callerid,
                timeout=callrequest.timeout,
                subscriber_id=callrequest.subscriber_id)
            new_callrequest.save()
            #NOTE : implement a PID algorithm
            second_towait = callrequest.campaign.intervalretry
            debug_query(29)

            logger.debug("Init Retry CallRequest in  %d seconds" %
                         second_towait)
            init_callrequest.apply_async(args=[
                new_callrequest.id, callrequest.campaign.id,
                callrequest.campaign.callmaxduration
            ],
                                         countdown=second_towait)
    else:
        #The Call is Answered
        logger.debug("Check for completion call")

        #Check if we should relaunch a new call to achieve completion
        check_retrycall_completion(callrequest)
Exemplo n.º 14
0
def check_campaign_pendingcall(campaign_id):
    """This will execute the outbound calls in the campaign

    **Attributes**:

        * ``campaign_id`` - Campaign ID
    """
    logger = check_campaign_pendingcall.get_logger()
    logger.info("TASK :: check_campaign_pendingcall = %s" % str(campaign_id))

    try:
        obj_campaign = Campaign.objects.get(id=campaign_id)
    except:
        logger.error('Can\'t find this campaign')
        return False

    #TODO: Control the Speed
    #if there is many task pending we should slow down
    frequency = obj_campaign.frequency  # default 10 calls per minutes

    dialer_set = user_dialer_setting(obj_campaign.user)

    # default call_type
    call_type = 1
    # Check campaign's maxretry
    if obj_campaign.maxretry == 0:
        call_type = 2

    # Check user's dialer setting maxretry
    if dialer_set:
        if dialer_set.maxretry == 0:
            call_type = 2

        # check frequency to control the Speed
        #if dialer_set.frequency:
        #    frequency = 20

    #Speed
    #check if the other tasks send for this campaign finished to be ran

    #Get the subscriber of this campaign
    # get_pending_subscriber get Max 1000 records
    list_subscriber = obj_campaign.get_pending_subscriber_update(
        frequency,
        6  # Update to In Process
    )
    if list_subscriber:
        logger.debug("Number of subscriber found : %d" % len(list_subscriber))

    try:
        no_subscriber = list_subscriber.count()
    except AttributeError:
        no_subscriber = 0

    if no_subscriber == 0:
        logger.info("No Subscriber to proceed on this campaign")
        return False

    #find how to dispatch them in the current minutes
    time_to_wait = 60.0 / no_subscriber
    count = 0

    for elem_camp_subscriber in list_subscriber:
        """Loop on Subscriber and start the initcall task"""
        count = count + 1
        logger.info("Add CallRequest for Subscriber (%s) & wait (%s) " %
                    (str(elem_camp_subscriber.id), str(time_to_wait)))

        #Check if the contact is authorized
        if not obj_campaign.is_authorized_contact(
                elem_camp_subscriber.contact.contact):
            logger.error("Error : Contact not authorized")
            elem_camp_subscriber.status = 7  # Update to Not Authorized
            elem_camp_subscriber.save()
            return True

        #Create a Callrequest Instance to track the call task
        new_callrequest = Callrequest(
            status=1,  # PENDING
            call_type=call_type,
            call_time=datetime.now(),
            timeout=obj_campaign.calltimeout,
            callerid=obj_campaign.callerid,
            phone_number=elem_camp_subscriber.contact.contact,
            campaign=obj_campaign,
            aleg_gateway=obj_campaign.aleg_gateway,
            content_type=obj_campaign.content_type,
            object_id=obj_campaign.object_id,
            user=obj_campaign.user,
            extra_data=obj_campaign.extra_data,
            timelimit=obj_campaign.callmaxduration,
            campaign_subscriber=elem_camp_subscriber)
        new_callrequest.save()

        #Todo Check if it's a good practice / implement a PID algorithm
        second_towait = ceil(count * time_to_wait)
        launch_date = datetime.now() + timedelta(seconds=second_towait)

        logger.info("Init CallRequest at %s" % \
                        (launch_date.strftime("%b %d %Y %I:%M:%S")))
        init_callrequest.apply_async(
            args=[new_callrequest.id, obj_campaign.id], eta=launch_date)
Exemplo n.º 15
0
    def run(self, **kwargs):
        logger.info("TASK :: alarmrequest_dispatcher")

        # Select AlarmRequest where date >= now() - 60 minutes
        start_time = datetime.utcnow().replace(tzinfo=utc) + relativedelta(minutes=-60)
        alarmreq_list = AlarmRequest.objects.filter(date__gte=start_time, status=ALARMREQUEST_STATUS.PENDING)
        no_alarmreq = alarmreq_list.count()
        if no_alarmreq == 0:
            logger.error("alarmrequest_dispatcher - no alarmreq found!")
            return False

        # Set time to wait for balanced dispatching of calls
        #time_to_wait = int(60 / DIV_MIN) / no_subscriber
        time_to_wait = 6.0 / no_alarmreq
        count = 0

        # Browse all the AlarmRequest found
        for obj_alarmreq in alarmreq_list:
            # Loop on AlarmRequest and start to the initcall's task
            count = count + 1
            second_towait = floor(count * time_to_wait)
            ms_addtowait = (count * time_to_wait) - second_towait
            logger.info("Init CallRequest for AlarmRequest in %d seconds (alarmreq:%d)" % (second_towait, obj_alarmreq.id))

            if obj_alarmreq.alarm.maxretry == 0:
                call_type = CALLREQUEST_TYPE.CANNOT_RETRY
            else:
                call_type = CALLREQUEST_TYPE.ALLOW_RETRY

            try:
                caluser_profile = CalendarUserProfile.objects.get(user=obj_alarmreq.alarm.event.creator)
            except CalendarUserProfile.DoesNotExist:
                logger.error("Error retrieving CalendarUserProfile")
                return False

            #manager_profile = UserProfile.objects.get(user=caluser_profile.manager)
            # manager_profile = caluser_profile.manager.get_profile()
            # manager_profile.dialersetting
            # Use manager_profile.dialersetting to retrieve some settings

            # TODO: build settings for this
            calltimeout = caluser_profile.calendar_setting.call_timeout
            callmaxduration = 60 * 60
            callerid = caluser_profile.calendar_setting.callerid
            caller_name = caluser_profile.calendar_setting.caller_name
            aleg_gateway = caluser_profile.calendar_setting.aleg_gateway
            content_type = ContentType.objects.get(model__in=["survey"])
            object_id = caluser_profile.calendar_setting.survey_id

            # Create Callrequest to track the call task
            new_callrequest = Callrequest(
                status=CALLREQUEST_STATUS.PENDING,
                call_type=call_type,
                call_time=datetime.utcnow().replace(tzinfo=utc),
                timeout=calltimeout,
                callerid=callerid,
                caller_name=caller_name,
                phone_number=obj_alarmreq.alarm.alarm_phonenumber,
                alarm_request_id=obj_alarmreq.id,
                aleg_gateway=aleg_gateway,
                content_type=content_type,
                object_id=object_id,
                user=caluser_profile.manager,
                extra_data='',
                timelimit=callmaxduration)
            new_callrequest.save()

            init_callrequest.apply_async(
                args=[new_callrequest.id, None, callmaxduration, ms_addtowait, obj_alarmreq.id],
                countdown=second_towait)

            obj_alarmreq.callrequest = new_callrequest
            obj_alarmreq.status = ALARMREQUEST_STATUS.IN_PROCESS
            obj_alarmreq.save()
            # Increment num_attempt
            obj_alarmreq.alarm.num_attempt = obj_alarmreq.alarm.num_attempt + 1
            obj_alarmreq.alarm.save()
Exemplo n.º 16
0
    def run(self, campaign_id):
        """
        This will execute the outbound calls in the campaign

        **Attributes**:

            * ``campaign_id`` - Campaign ID
        """
        logger = self.get_logger()
        logger.info("TASK :: spool_pending_call = %d" % campaign_id)

        debug_query(0)

        try:
            obj_campaign = Campaign.objects.select_related(
                'user__userprofile__dialersetting', 'aleg_gateway',
                'content_type').get(id=campaign_id)
        except:
            logger.error("Can't find this campaign")
            return False

        # TODO : Control the Speed
        # if there is many task pending we should slow down
        frequency = obj_campaign.frequency  # default 10 calls per minutes

        debug_query(1)

        # Default call_type
        call_type = CALLREQUEST_TYPE.ALLOW_RETRY
        # Check campaign's maxretry
        if obj_campaign.maxretry == 0:
            call_type = CALLREQUEST_TYPE.CANNOT_RETRY

        # Check user's dialer setting maxretry
        if obj_campaign.user.userprofile.dialersetting:
            if obj_campaign.user.userprofile.dialersetting.maxretry == 0:
                call_type = CALLREQUEST_TYPE.CANNOT_RETRY

        debug_query(2)

        # Speed
        # Check if the other tasks send for this campaign finished to be ran

        # Get the subscriber of this campaign
        # get_pending_subscriber get Max 1000 records
        if frequency >= 10:
            callfrequency = int(
                frequency / DIV_MIN) + 1  # 1000 per minutes 101
            #callfrequency = int(frequency) + 1  # 1000 per minutes 101
        else:
            callfrequency = frequency
        (list_subscriber,
         no_subscriber) = obj_campaign.get_pending_subscriber_update(
             callfrequency, SUBSCRIBER_STATUS.IN_PROCESS)
        logger.info(
            "##subscriber=%d campaign_id=%d callfrequency=%d frequency=%d" %
            (no_subscriber, campaign_id, callfrequency, frequency))
        debug_query(3)

        if no_subscriber == 0:
            return False

        # Set time to wait for balanced dispatching of calls
        #time_to_wait = int(60 / DIV_MIN) / no_subscriber
        time_to_wait = 6.0 / no_subscriber
        count = 0

        for elem_camp_subscriber in list_subscriber:
            """Loop on Subscriber and start the initcall task"""
            count = count + 1
            second_towait = floor(count * time_to_wait)
            ms_addtowait = (count * time_to_wait) - second_towait
            logger.info(
                "Init CallRequest in %d seconds (cmpg:%d,subscriber:%d)" %
                (second_towait, campaign_id, elem_camp_subscriber.id))

            phone_number = elem_camp_subscriber.duplicate_contact
            debug_query(4)

            #Verify that the contact is authorized
            if not obj_campaign.is_authorized_contact(
                    obj_campaign.user.userprofile.dialersetting, phone_number):
                logger.error("Error : Contact not authorized")
                elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED
                elem_camp_subscriber.save()
                return True
            #Verify that the contact is not in the DNC list
            if obj_campaign.dnc:
                res_dnc = DNCContact.objects.filter(dnc_id=obj_campaign.dnc_id,
                                                    phone_number=phone_number)
                if res_dnc:
                    logger.error("Contact (%s) in DNC list" % phone_number)
                    elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED
                    elem_camp_subscriber.save()
                    return True
                else:
                    logger.debug("Contact (%s) not in DNC list" % phone_number)

            debug_query(5)

            #TODO: idea to speed up, create bluck of 10(Y) and then send a list of callrequest_id to init_callrequest

            # Create a Callrequest Instance to track the call task
            new_callrequest = Callrequest(
                status=CALLREQUEST_STATUS.PENDING,
                call_type=call_type,
                call_time=datetime.now(),
                timeout=obj_campaign.calltimeout,
                callerid=obj_campaign.callerid,
                phone_number=phone_number,
                campaign=obj_campaign,
                aleg_gateway=obj_campaign.aleg_gateway,
                content_type=obj_campaign.content_type,
                object_id=obj_campaign.object_id,
                user=obj_campaign.user,
                extra_data=obj_campaign.extra_data,
                timelimit=obj_campaign.callmaxduration,
                subscriber=elem_camp_subscriber)
            new_callrequest.save()

            debug_query(6)

            init_callrequest.apply_async(args=[
                new_callrequest.id, obj_campaign.id,
                obj_campaign.callmaxduration, ms_addtowait
            ],
                                         countdown=second_towait)
            # Shell_plus
            # from dialer_cdr.tasks import init_callrequest
            # from datetime import datetime
            # new_callrequest_id = 112
            # obj_campaign_id = 3
            # countdown = 1
            # init_callrequest.apply_async(args=[new_callrequest_id, obj_campaign_id], countdown=1)

        debug_query(7)
        return True