Пример #1
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
Пример #2
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()
Пример #3
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)
Пример #4
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
Пример #5
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)
Пример #6
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
Пример #7
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()
Пример #8
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 :: CheckPendingcall = %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
        list_subscriber = obj_campaign.get_pending_subscriber_update(
            frequency,
            SUBSCRIBER_STATUS.IN_PROCESS
        )
        if list_subscriber:
            no_subscriber = list_subscriber.count()
        else:
            no_subscriber = 0
        logger.info("campaign_id=%d #Subscriber: %d" % (campaign_id, no_subscriber))

        debug_query(3)

        if no_subscriber == 0:
            return False

        if no_subscriber == 1:
            # Not many subscriber do a fast dial
            time_to_wait = 1.0
        elif no_subscriber <= 10:
            # Not many subscriber do a fast dial
            time_to_wait = 6.0
        else:
            # Set time to wait for balanced dispatching of calls
            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 (%d) & wait (%s) " %
                       (elem_camp_subscriber.id, str(time_to_wait)))
            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:
                try:
                    DNCContact.objects.get(dnc_id=obj_campaign.dnc_id, phone_number=phone_number)
                    logger.error("Contact (%s) in DNC list" % phone_number)
                    elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED
                    elem_camp_subscriber.save()
                    return True
                except DNCContact.DoesNotExist:
                    logger.debug("Contact (%s) not in DNC list" % phone_number)

            debug_query(5)

            # 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)

            second_towait = ceil(count * time_to_wait)
            logger.info("Init CallRequest in %d seconds (cmpg:%d)" % (second_towait, campaign_id))
            init_callrequest.apply_async(
                args=[new_callrequest.id, obj_campaign.id, obj_campaign.callmaxduration],
                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
Пример #9
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)
Пример #10
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
Пример #11
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)