def queue(simulate, simulated_date): try: if simulated_date: dt = arrow.get(simulated_date) else: dt = arrow.utcnow() scheduler = Scheduler() print 'getting messages' msgs = scheduler.get_messages() logging.info("Starting MessageManager") logging.info("messages = %s" % len(msgs)) if len(msgs) == 0: click.echo("No messages are ready to be queued") else: click.echo("Number of messages to be scheduled: %s" % len(msgs)) for m in msgs: if not simulate: logging.info("Getting person %s " % m.person_name) pm = PersonManager() p = pm.get_person(m.person_name) if not p: logging.warn(m.person_name + "does not have an entry in the " + "Person table") continue if p.all_available_count(dt) == 0: logging.warn('No locations available for %s' % m.person_name) click.echo('No locations available for %s' % m.person_name) continue avail_windows = p.all_available(dt) click.echo('# of locations avail: {}, last_loc={}'.format( p.all_available_count(dt), m.last_loc)) if m.last_loc == p.all_available_count(dt) - 1: click.echo('Resetting to first location') idx = 0 else: click.echo('Moving to next location') idx = m.last_loc + 1 active_window = avail_windows[int(idx)] next_exp = m.next_expiration_utc.isoformat() mm = MessageManager(LocationName=active_window.location_name) click.echo("Publishing message for person %s to location %s" % (m.person_name, active_window.location_name)) mm.publish_message(Body=m.body, UUID=m.uuid_key, PersonName=m.person_name, NoMoreOccurrences=m.no_more_occurrences, ExpirationDateTimeInUtc=next_exp) scheduler.update_queue_status(m.uuid_key, m.person_name, True) scheduler.update_last_location(m.uuid_key, m.person_name, idx) else: click.echo("Publishing message(simulated):") click.echo(str(m)) except Exception: print 'here' click.echo(traceback.print_exc()) raise
def message_reset(location_name, verbose): log = logging.getLogger('PollexyCli') if verbose: os.environ['LOG_LEVEL'] = 'DEBUG' log.setLevel(logging.DEBUG) m = MessageManager(LocationName=location_name) m.reset()
def queue_message(intent, session): card_title = intent['name'] session_attributes = {} should_end_session = False reprompt_text = 'Excuse me?' if 'person' in intent['slots'] and 'message' in intent['slots']: if 'voice' in intent['slots']: voice = str(intent['slots']['voice']['value']) else: voice = 'Joanna' person = str(intent['slots']['person']['value']).lower() name = intent['slots']['message']['value'] dt = arrow.utcnow() pm = PersonManager() p = pm.get_person(person) lm = LibraryManager() m = lm.get_message(Name=name) if not p: logging.error('{} does not have an entry in the ' 'Person table . . .'.format(person)) speech_output = "Sorry, I don't know the name {}" \ .format(person) should_end_session = True elif not m: logging.error('There is no message named {}'.format(name)) speech_output = "Sorry, I don't have a message named {}" \ .format(name) should_end_session = True elif p.all_available_count(dt) == 0: logging.error('No locations are available for {}'.format(person)) speech_output = "Sorry, there are no locations for {}" \ .format(name) should_end_session = True else: active_window = p.all_available(dt)[0] mm = MessageManager(LocationName=active_window.location_name) speech_output = "Got it. Publishing message {} to {} at " \ "location {}".format(name, person, active_window.location_name) mm.publish_message(Body=m['message'], PersonName=person, Voice=voice) should_end_session = True else: logging.error('Missing person or message') speech_output = 'Person or message name is missing. Please try again' should_end_session = True return build_response( session_attributes, build_speechlet_response(card_title, speech_output, reprompt_text, should_end_session))
def speak(person_name, location_name, ignore_motion, ignore_confirmation, voice_id, no_audio, simulate, fail_confirm): try: while True: click.echo("Checking for messages . . .") lm = LocationManager() loc = lm.get_location(location_name) if not ignore_motion and not loc.is_motion: print 'Exiting. No motion detected at ' + location_name exit(1) speaker = Speaker(NoAudio=no_audio) message_manager = MessageManager(LocationName=location_name) click.echo('getting files') cache_manager = CacheManager(BucketName='pollexy-media', CacheName='chimes') cache_manager.sync_remote_folder() print 'Writing speech' vid, speech = message_manager.write_speech(PersonName=person_name) if vid: voice_id = vid if not speech: print "I have nothing to say" message_manager.delete_sqs_msgs() else: print "Speech:\n\n%s" % speech try: pm = PersonManager() p = pm.get_person(person_name) do_speech = True if fail_confirm: logging.warning("FORCE FAILING confirmation") reason, do_speech = "NoResponse", False elif not no_audio and p.require_physical_confirmation and \ not ignore_confirmation: lv = LocationVerification(PersonName=person_name, LocationName=location_name, VoiceId=voice_id) do_speech, retry_count, timeout = \ lv.verify_person_at_location(SpeechMethod=say) if do_speech: speaker = Speaker(NoAudio=no_audio) speaker.generate_audio(Message=speech, TextType='ssml', VoiceId=voice_id) speaker.speak(IncludeChime=True) message_manager.succeed_speech(dont_delete=simulate) else: message_manager.fail_speech(Reason=reason) finally: speaker.cleanup() except Exception as exc: exc_type, exc_value, exc_traceback = sys.exc_info() print repr( traceback.format_exception(exc_type, exc_value, exc_traceback)) click.echo("Error: %s" % str(exc)) exit(2)
def handler(event, context): scheduler = Scheduler() dt = arrow.utcnow() logging.info("Getting messages") msgs = scheduler.get_messages() logging.info("messages = %s" % len(msgs)) if len(msgs) == 0: logging.info("No messages are ready to be queued") else: logging.info("Number of messages to be scheduled: %s" % len(msgs)) for m in msgs: logging.info("Getting person %s " % m.person_name) pm = PersonManager() p = pm.get_person(m.person_name) if not p: logging.warn(m.person_name + "does not have an entry in the " + "Person table . . . skipping") continue if p.all_available_count(dt) == 0: logging.warn('No locations available for %s . . . skipping' % m.person_name) continue avail_windows = p.all_available(dt) logging.info('# of locations avail: {}, last_loc={}'.format( p.all_available_count(dt), m.last_loc)) if p.all_available_count(dt) > 1 and \ m.last_loc == p.all_available_count(dt)-1: logging.info('Resetting to first location') idx = 0 else: if p.all_available_count(dt) > 1: logging.info('Moving to next location') idx = m.last_loc + 1 else: idx = 0 active_window = avail_windows[int(idx)] next_exp = m.next_expiration_utc.isoformat() mm = MessageManager(LocationName=active_window.location_name) logging.info("Publishing message for person %s to location %s" % (m.person_name, active_window.location_name)) mm.publish_message(Body=m.body, UUID=m.uuid_key, PersonName=m.person_name, NoMoreOccurrences=m.no_more_occurrences, BotNames=m.bot_names, IceBreaker=m.ice_breaker, RequiredBots=m.required_bots, ExpirationDateTimeInUtc=next_exp) scheduler.update_queue_status(m.uuid_key, m.person_name, True) scheduler.update_last_location(m.uuid_key, m.person_name, idx)
def test_can_create_missing_queue_automatically(self): device_name = 'ABCDEFG' queue = get_queue(device_name) self.assertIsNone(queue) message_manager_under_test = MessageManager(DeviceName=device_name) self.assertIsNotNone(message_manager_under_test.queue)
def test_can_read_more_than_one_message_from_queue(self): message_manager_under_test = MessageManager(DeviceName="TEST") message_manager_under_test.publish_message( UUID="test", ExpirationDateTimeInUtc="2013-01-01 11:00", Body="Hey there") message_manager_under_test.publish_message( UUID="test", ExpirationDateTimeInUtc="2013-01-01 11:00", Body="Hey there") message_manager_under_test.publish_message( UUID="test", ExpirationDateTimeInUtc="2013-01-01 11:00", Body="Hey there") message_manager_under_test.get_messages() self.assertEqual(3, len(message_manager_under_test.messages))
def test_can_prevent_deletion_of_message(self): message1 = "Hey there 1" message2 = "Hey there 2" final_speech = "<speak><p>Hey there 1</p><p>Hey there 2</p></speak>" message_manager_under_test = MessageManager(DeviceName="TEST") message_manager_under_test.publish_message( UUID="test", ExpirationDateTimeInUtc="2018-01-01 11:00", Body=message1) message_manager_under_test.publish_message( UUID="test", ExpirationDateTimeInUtc="2018-01-01 11:00", Body=message2) self.assertEqual(message_manager_under_test.write_speech(True), final_speech) self.assertEqual(message_manager_under_test.write_speech(False), final_speech)
def test_can_publish_message_with_uuid(self): body = 'hey there' message_manager_under_test = MessageManager(DeviceName="TEST") message_manager_under_test.publish_message( UUID="test_uuid", ExpirationDateTimeInUtc="2013-01-01 11:00", Body=body) message_manager_under_test.get_messages() polexa_message_under_test = message_manager_under_test.messages[0] assert polexa_message_under_test.uuid_key == "test_uuid"
def test_expired_message_is_expired(self): message_manager_under_test = MessageManager(DeviceName="TEST") expiration_date = arrow.utcnow().replace(days=-7) message_manager_under_test.publish_message( UUID='test', ExpirationDateTimeInUtc=expiration_date.isoformat(), Body="Hey there") message_manager_under_test.get_messages() polexa_message_under_test = message_manager_under_test.messages[0] self.assertTrue(polexa_message_under_test.is_expired)
def test_can_publish_message_with_expiration(self): body = 'hey there' expire_datetime_in_utc = '2016-12-31 01:00 UTC' message_manager_under_test = MessageManager(DeviceName="TEST") message_manager_under_test.publish_message( UUID='test', ExpirationDateTimeInUtc=expire_datetime_in_utc, Body=body) message_manager_under_test.get_messages() polexa_message_under_test = message_manager_under_test.messages[0] self.assertEqual( arrow.get(expire_datetime_in_utc), polexa_message_under_test.expiration_datetime_in_utc)
def test_can_parse_valid_expiration_timestamp(self): message_manager_under_test = MessageManager(DeviceName="TEST") message_manager_under_test.publish_message( UUID="test", ExpirationDateTimeInUtc="2013-01-01 11:00", Body="Hey there") message_manager_under_test.get_messages() polexa_message_under_test = message_manager_under_test.messages[0] self.assertEqual( polexa_message_under_test.expiration_datetime_in_utc.year, 2013) self.assertEqual( polexa_message_under_test.expiration_datetime_in_utc.hour, 11)
def test_empty_body_throws_value_error(self): with self.assertRaises(Exception) as context: message_manager_under_test = MessageManager(DeviceName="TEST") message_manager_under_test.publish_message(UUID='test') self.assertTrue('No message body provided' in context.exception)
def queue(simulate, simulated_date, verbose): log = logging.getLogger('PollexyCli') if verbose: os.environ['LOG_LEVEL'] = 'DEBUG' log.setLevel(logging.DEBUG) try: if simulated_date: dt = arrow.get(simulated_date) else: dt = arrow.utcnow() scheduler = Scheduler() msgs = scheduler.get_messages() if len(msgs) == 0: click.echo("No messages are ready to be queued") return log.debug("Number of messages to be scheduled: %s" % len(msgs)) for m in msgs: if not simulate: pm = PersonManager() p = pm.get_person(m.person_name) if not p: log.warn(m.person_name + "does not have an entry in the " + "Person table") continue if p.all_available_count(dt) == 0: log.debug('No locations available for %s' % m.person_name) continue avail_windows = p.all_available(dt) log.debug('# of locations avail: {}, last_loc={}' .format(p.all_available_count(dt), m.last_loc)) if m.last_loc == p.all_available_count(dt)-1: log.debug('Resetting to first location') idx = 0 else: log.debug('Moving to next location') idx = m.last_loc + 1 active_window = avail_windows[int(idx)] next_exp = m.next_expiration_utc.isoformat() mm = MessageManager(LocationName=active_window.location_name) log.debug("Publishing message for person %s to location %s" % (m.person_name, active_window.location_name)) mm.publish_message(Body=m.body, UUID=m.uuid_key, PersonName=m.person_name, NoMoreOccurrences=m.no_more_occurrences, BotNames=m.bot_names, RequiredBots=m.required_bots, IceBreaker=m.ice_breaker, Introduction=m.introduction, ExpirationDateTimeInUtc=next_exp) scheduler.update_queue_status(m.uuid_key, m.person_name, True) scheduler.update_last_location(m.uuid_key, m.person_name, idx) else: click.echo("Publishing message(simulated):") click.echo(str(m)) except Exception: print 'here' click.echo(traceback.print_exc()) raise
def speak(person_name, location_name, ignore_motion, ignore_confirmation, voice_id, no_audio, simulate, fail_confirm, verbose): log = logging.getLogger('PollexyCli') if verbose: os.environ['LOG_LEVEL'] = 'DEBUG' log.setLevel(logging.DEBUG) try: while True: lm = LocationManager() loc = lm.get_location(location_name) if not ignore_motion and not loc.is_motion: print 'Exiting. No motion detected at ' + location_name exit(1) speaker = Speaker(NoAudio=no_audio) message_manager = MessageManager(LocationName=location_name) bm = message_manager.get_messages(MessageType='Bot', PersonName=person_name) if bm and len(bm) > 0: log.debug('Bot count = {}'.format(len(bm))) for bot in bm: username = str(uuid.uuid4()) try: lp = LexPlayer( BotNames=bot.bot_names, Alias="$LATEST", Username=username, VoiceId=voice_id, IceBreaker=bot.ice_breaker, Introduction=bot.introduction, NoAudio=no_audio, BotsRequired=bot.required_bots) while (not lp.is_done): lp.get_user_input() except Exception as e: print 'Bot failed: {}'.format(e) raise message_manager.succeed_messages(dont_delete=simulate) cache_manager = CacheManager(BucketName='pollexy-media', CacheName='chimes') cache_manager.sync_remote_folder() vid, speech = message_manager.write_speech(PersonName=person_name) if vid: voice_id = vid if not speech: message_manager.succeed_messages(dont_delete=simulate) message_manager.delete_sqs_msgs() else: try: pm = PersonManager() p = pm.get_person(person_name) do_speech = True if fail_confirm: log.warn("FORCE FAILING confirmation") reason, do_speech = "NoResponse", False elif not no_audio and p.require_physical_confirmation and \ not ignore_confirmation: lv = LocationVerification(PersonName=person_name, LocationName=location_name, VoiceId=voice_id) do_speech, retry_count, timeout = \ lv.verify_person_at_location(SpeechMethod=say) log.debug('do_speech={}'.format(bool(do_speech))) if fail_confirm: message_manager.fail_messages(Reason=reason) else: if do_speech: log.debug('starting speech') speaker = Speaker(NoAudio=no_audio) speaker.generate_audio(Message=speech, TextType='ssml', VoiceId=voice_id) speaker.speak(IncludeChime=True) log.debug('Succeeding messages') message_manager.succeed_messages(dont_delete=simulate) finally: speaker.cleanup() except Exception as exc: exc_type, exc_value, exc_traceback = sys.exc_info() print repr(traceback.format_exception(exc_type, exc_value, exc_traceback)) click.echo("Error: %s" % str(exc)) exit(2)
def test_empty_uuid_throws_value_error(self): with self.assertRaises(Exception) as context: message_manager_under_test = MessageManager(DeviceName="TEST") message_manager_under_test.publish_message( Body="Test") self.assertTrue('No uuid provided' in context.exception)
def test_throw_value_error_on_missing_device_name(self): with self.assertRaises(Exception) as context: MessageManager() print context.exception self.assertTrue('Missing device name' in context.exception)