def test04_schedule_participant_dialogue(self): config = self.simple_config dialogue = self.dialogue_annoucement participant = {'phone': '06'} mytimezone = self.program_settings[2]['value'] dNow = datetime.utcnow().replace(tzinfo=pytz.utc).astimezone(pytz.timezone(mytimezone)) dNow = dNow.replace(tzinfo=None) self.collections['dialogues'].save(dialogue) self.collections['participants'].save(participant) for program_setting in self.program_settings: self.collections['program_settings'].save(program_setting) self.worker.load_data() self.worker.schedule_participant_dialogue( participant, dialogue) schedules_count = self.collections['schedules'].count() self.assertEqual(schedules_count, 2) schedules = self.collections['schedules'].find() #assert time calculation self.assertTrue( time_from_vusion_format(schedules[0]['date-time']) < dNow + timedelta(minutes=1)) self.assertTrue( time_from_vusion_format(schedules[1]['date-time']) < dNow + timedelta(minutes=61)) self.assertTrue( time_from_vusion_format(schedules[1]['date-time']) > dNow + timedelta(minutes=59)) #assert schedule links self.assertEqual(schedules[0]['participant-phone'], '06') self.assertEqual(schedules[0]['dialogue-id'], '0') self.assertEqual(schedules[0]['interaction-id'], '0') self.assertEqual(schedules[1]['interaction-id'], '1')
def test04_schedule_participant_dialogue(self): config = self.simple_config dialogue = self.dialogue_annoucement participant = {'phone': '06'} mytimezone = self.program_settings[2]['value'] dNow = datetime.utcnow().replace(tzinfo=pytz.utc).astimezone( pytz.timezone(mytimezone)) dNow = dNow.replace(tzinfo=None) self.collections['dialogues'].save(dialogue) self.collections['participants'].save(participant) for program_setting in self.program_settings: self.collections['program_settings'].save(program_setting) self.worker.load_data() self.worker.schedule_participant_dialogue(participant, dialogue) schedules_count = self.collections['schedules'].count() self.assertEqual(schedules_count, 2) schedules = self.collections['schedules'].find() #assert time calculation self.assertTrue( time_from_vusion_format(schedules[0]['date-time']) < dNow + timedelta(minutes=1)) self.assertTrue( time_from_vusion_format(schedules[1]['date-time']) < dNow + timedelta(minutes=61)) self.assertTrue( time_from_vusion_format(schedules[1]['date-time']) > dNow + timedelta(minutes=59)) #assert schedule links self.assertEqual(schedules[0]['participant-phone'], '06') self.assertEqual(schedules[0]['dialogue-id'], '0') self.assertEqual(schedules[0]['interaction-id'], '0') self.assertEqual(schedules[1]['interaction-id'], '1')
def send_scheduled(self): self.log('Checking the schedule list...') local_time = self.get_local_time() toSends = self.collections['schedules'].find( spec={'date-time': {'$lt': time_to_vusion_format(local_time)}}, sort=[('date-time', 1)]) for toSend in toSends: self.collections['schedules'].remove( {'_id': toSend['_id']}) message_content = None try: interaction, reference_metadata = self.from_schedule_to_message(toSend) if not interaction: continue message_content = self.generate_message(interaction) message_content = self.customize_message( toSend['participant-phone'], message_content) if (time_from_vusion_format(toSend['date-time']) < (local_time - timedelta(minutes=15))): raise SendingDatePassed( "Message should have been send at %s" % (toSend['date-time'],)) message = TransportUserMessage(**{ 'from_addr': self.properties['shortcode'], 'to_addr': toSend['participant-phone'], 'transport_name': self.transport_name, 'transport_type': self.transport_type, 'transport_metadata': '', 'content': message_content}) yield self.transport_publisher.publish_message(message) self.log( "Message has been send to %s '%s'" % (message['to_addr'], message['content'])) self.save_history( message_content=message['content'], participant_phone=message['to_addr'], message_type='sent', message_status='pending', message_id=message['message_id'], reference_metadata=reference_metadata) except VusionError as e: self.save_history( message_content='', participant_phone=toSend['participant-phone'], message_type=None, failure_reason=('%s' % (e,)), reference_metadata=reference_metadata) except: exc_type, exc_value, exc_traceback = sys.exc_info() self.log( "Error during consume user message: %r" % traceback.format_exception(exc_type, exc_value, exc_traceback)) self.save_history( participant_phone=toSend['participant-phone'], message_content='', message_type='system-failed', failure_reason=('%s - %s') % (sys.exc_info()[0], sys.exc_info()[1]), reference_metadata=reference_metadata)
def schedule_participant_dialogue(self, participant, dialogue): try: previousSendDateTime = None if not 'interactions' in dialogue: return for interaction in dialogue['interactions']: schedule = self.collections['schedules'].find_one({ "participant-phone": participant['phone'], "dialogue-id": dialogue["dialogue-id"], "interaction-id": interaction["interaction-id"]}) status = self.collections['history'].find_one( {"participant-phone": participant['phone'], "dialogue-id": dialogue["dialogue-id"], "interaction-id": interaction["interaction-id"]}, sort=[("datetime", pymongo.ASCENDING)]) if status: previousSendDateTime = time_from_vusion_format(status["timestamp"]) continue if (interaction['type-schedule'] == 'immediately'): if (schedule): sendingDateTime = time_from_vusion_format(schedule['date-time']) else: sendingDateTime = self.get_local_time() elif (interaction['type-schedule'] == 'wait'): if (previousSendDateTime is None): previousSendDateTime = self.get_local_time() sendingDateTime = previousSendDateTime + timedelta(minutes=int(interaction['minutes'])) elif (interaction['type-schedule'] == 'fixed-time'): sendingDateTime = time_from_vusion_format(interaction['date-time']) #Scheduling a date already in the past is forbidden. if (sendingDateTime + timedelta(minutes=10) < self.get_local_time()): self.save_history( message_content='Not generated yet', participant_phone=participant['phone'], message_type='sent', message_status='fail: date in the past', reference_metadata={ 'dialogue-id': dialogue['dialogue-id'], 'interaction-id': interaction["interaction-id"]}) if (schedule): self.collections['schedules'].remove(schedule['_id']) continue if (not schedule): schedule = { "participant-phone": participant['phone'], "dialogue-id": dialogue['dialogue-id'], "interaction-id": interaction["interaction-id"]} schedule['date-time'] = self.to_vusion_format(sendingDateTime) previousSendDateTime = sendingDateTime self.collections['schedules'].save(schedule) self.log("Schedule has been saved: %s" % schedule) except: self.log("Scheduling exception: %s" % interaction) exc_type, exc_value, exc_traceback = sys.exc_info() self.log( "Error during schedule message: %r" % traceback.format_exception(exc_type, exc_value, exc_traceback))
def send_scheduled(self): self.log('Checking the schedule list...') local_time = self.get_local_time() toSends = self.collections['schedules'].find( spec={'date-time': { '$lt': time_to_vusion_format(local_time) }}, sort=[('date-time', 1)]) for toSend in toSends: self.collections['schedules'].remove({'_id': toSend['_id']}) message_content = None try: interaction, reference_metadata = self.from_schedule_to_message( toSend) if not interaction: continue message_content = self.generate_message(interaction) message_content = self.customize_message( toSend['participant-phone'], message_content) if (time_from_vusion_format(toSend['date-time']) < (local_time - timedelta(minutes=15))): raise SendingDatePassed( "Message should have been send at %s" % (toSend['date-time'], )) message = TransportUserMessage( **{ 'from_addr': self.properties['shortcode'], 'to_addr': toSend['participant-phone'], 'transport_name': self.transport_name, 'transport_type': self.transport_type, 'transport_metadata': '', 'content': message_content }) yield self.transport_publisher.publish_message(message) self.log("Message has been send to %s '%s'" % (message['to_addr'], message['content'])) self.save_history(message_content=message['content'], participant_phone=message['to_addr'], message_type='sent', message_status='pending', message_id=message['message_id'], reference_metadata=reference_metadata) except VusionError as e: self.save_history( message_content='', participant_phone=toSend['participant-phone'], message_type=None, failure_reason=('%s' % (e, )), reference_metadata=reference_metadata) except: exc_type, exc_value, exc_traceback = sys.exc_info() self.log("Error during consume user message: %r" % traceback.format_exception(exc_type, exc_value, exc_traceback)) self.save_history( participant_phone=toSend['participant-phone'], message_content='', message_type='system-failed', failure_reason=('%s - %s') % (sys.exc_info()[0], sys.exc_info()[1]), reference_metadata=reference_metadata)
def schedule_participant_dialogue(self, participant, dialogue): try: previousSendDateTime = None if not 'interactions' in dialogue: return for interaction in dialogue['interactions']: schedule = self.collections['schedules'].find_one({ "participant-phone": participant['phone'], "dialogue-id": dialogue["dialogue-id"], "interaction-id": interaction["interaction-id"] }) status = self.collections['history'].find_one( { "participant-phone": participant['phone'], "dialogue-id": dialogue["dialogue-id"], "interaction-id": interaction["interaction-id"] }, sort=[("datetime", pymongo.ASCENDING)]) if status: previousSendDateTime = time_from_vusion_format( status["timestamp"]) continue if (interaction['type-schedule'] == 'immediately'): if (schedule): sendingDateTime = time_from_vusion_format( schedule['date-time']) else: sendingDateTime = self.get_local_time() elif (interaction['type-schedule'] == 'wait'): if (previousSendDateTime is None): previousSendDateTime = self.get_local_time() sendingDateTime = previousSendDateTime + timedelta( minutes=int(interaction['minutes'])) elif (interaction['type-schedule'] == 'fixed-time'): sendingDateTime = time_from_vusion_format( interaction['date-time']) #Scheduling a date already in the past is forbidden. if (sendingDateTime + timedelta(minutes=10) < self.get_local_time()): self.save_history(message_content='Not generated yet', participant_phone=participant['phone'], message_type='sent', message_status='fail: date in the past', reference_metadata={ 'dialogue-id': dialogue['dialogue-id'], 'interaction-id': interaction["interaction-id"] }) if (schedule): self.collections['schedules'].remove(schedule['_id']) continue if (not schedule): schedule = { "participant-phone": participant['phone'], "dialogue-id": dialogue['dialogue-id'], "interaction-id": interaction["interaction-id"] } schedule['date-time'] = self.to_vusion_format(sendingDateTime) previousSendDateTime = sendingDateTime self.collections['schedules'].save(schedule) self.log("Schedule has been saved: %s" % schedule) except: self.log("Scheduling exception: %s" % interaction) exc_type, exc_value, exc_traceback = sys.exc_info() self.log( "Error during schedule message: %r" % traceback.format_exception(exc_type, exc_value, exc_traceback))