コード例 #1
0
def analyze_with_plot(filename):
	'''Analyze a single voice file and plot its volume, pitch, end_point.

	Example:
		python analyze 'myfile'
	'''
	#print 'Analyzing %s'%filename

	m = Voice()
	m.analyze(filename)
	t = np.linspace(0,len(m.y)*1.0/m.fs,len(m.frames))
	mul = len(m.y)*1.0/m.fs/len(m.frames)
	pl.subplot(311)
	pl.plot(t, m.volume)
	print m.speech_segment
	print mul
	for s in m.speech_segment:
		print s[0]*mul,s[1]*mul
		pl.plot([s[0]*mul,s[0]*mul],[0,max(m.volume)],color='red')
		pl.plot([s[1]*mul,s[1]*mul],[0,max(m.volume)],color='blue')
	pl.subplot(312)
	pl.plot(t, m.pitch)
	pl.subplot(313)
	pl.plot(t, m.energyBelow250)
	pl.show()
	'''
コード例 #2
0
ファイル: robot.py プロジェクト: gcd0318/robot
class Robot(GCAI):
    def __init__(self, name):
        self.name = name
        self.ai = GCAI(qad={
            '你是谁': '我是' + self.name,
            self.name: '干什么',
        })
        self.voice = Voice(VOICE_REGS)
        self.nlp = NLP(NLP_REGS)

    def chat(self):
        res = '听不懂'
        stop = False

        while not stop:
            rec_filename = self.voice.listen()
            r = self.voice.stt(rec_filename)
            os.remove(rec_filename)
            if 0 == r.get('err_no'):
                txt = r.get('result')
                if (txt is not None) and (0 < len(r)):
                    t = txt[0]
                else:
                    t = ''
                print(t)
                res = self.ai.answer(t)
            res = res.strip()
            if '' == res:
                res = default_res
            reply_filename = self.voice.tts(res,
                                            'reply_' + timestamp() + '.wav')
            Player.play(reply_filename)
            os.remove(reply_filename)

            stop = ('再见' == res)
コード例 #3
0
 def __init__(self):
     self.ascii_banner = pyfiglet.figlet_format("Hello!!")
     self.ascii_banner2 = pyfiglet.figlet_format("1337 Alarm")
     self.AWAKE_TIME = "06:30"
     self.CLASS_TIME = "09:25"
     self.music = Music()
     self.voice = Voice()
コード例 #4
0
ファイル: timer.py プロジェクト: merzod/mirror
 def processCommandByMyself(self, cmd):
     global timer, canceled
     if timer is not None and timer.isAlive():
         logging.info('Cancel timer')
         timer.cancel()
         canceled = time.time()
         Voice.getInstance().say('Таймер остановлен')
コード例 #5
0
ファイル: controller.py プロジェクト: merzod/mirror
 def process(self, code):
     logging.debug('Processing code: %s' % code)
     if code == Controller.MOVE_FORWARD:
         self.walle.move(Base.FORWARD)
     elif code == Controller.MOVE_BACKWARD:
         self.walle.move(Base.BACKWARD)
     elif code == Controller.TURN_LEFT:
         self.walle.turn(Base.TURN_LEFT)
     elif code == Controller.TURN_RIGHT:
         self.walle.turn(Base.TURN_RIGHT)
     elif code == Controller.HEAD_LEFT:
         self.walle.move_head(Base.TURN_LEFT)
     elif code == Controller.HEAD_RIGHT:
         self.walle.move_head(Base.TURN_RIGHT)
     elif code == Controller.LEFT_ARM_UP:
         self.walle.move_arm(Base.LEFT_ARM, Base.UP)
     elif code == Controller.LEFT_ARM_DOWN:
         self.walle.move_arm(Base.LEFT_ARM, Base.DOWN)
     elif code == Controller.RIGHT_ARM_UP:
         self.walle.move_arm(Base.RIGHT_ARM, Base.UP)
     elif code == Controller.RIGHT_ARM_DOWN:
         self.walle.move_arm(Base.RIGHT_ARM, Base.DOWN)
     elif code == Controller.SOUND_1:
         Voice.getInstance().playFile('../resources/wall-e.ogg')
     elif code == Controller.SOUND_2:
         Voice.getInstance().playFile('../resources/eve.ogg')
コード例 #6
0
ファイル: model.py プロジェクト: merzod/mirror
 def processCommand(self, cmd):
     logging.debug('Core processing: %s' % cmd)
     res = self.processors.processCommand(cmd)
     if res == 0:
         Voice.getInstance().sayCachedNotClear()
     if res == 0:
         logging.warn('Failed to find any suitable processor for: %s' % cmd)
     screen.ScreenWrapper.getInstance().draw_walle_state()
コード例 #7
0
ファイル: unitTests.py プロジェクト: shuwenyue/Terminal_talk
 def test_space(self):
     v = Voice('test')
     result = v.remSpace('test 4space removal. here with _ too.'.split())
     assert ('test4space removal.here with_too.'.split() == result)
     result2 = v.remSpace('5 at begin _'.split())
     assert ('5 at begin_'.split() == result2)
     result3 = v.remSpace('remove at. end'.split())
     assert ('remove at.end'.split() == result3)
コード例 #8
0
ファイル: robot.py プロジェクト: gcd0318/robot
 def __init__(self, name):
     self.name = name
     self.ai = GCAI(qad={
         '你是谁': '我是' + self.name,
         self.name: '干什么',
     })
     self.voice = Voice(VOICE_REGS)
     self.nlp = NLP(NLP_REGS)
コード例 #9
0
 def __init__(self):
     self.vc = Voice()
     command = []
     command = self.vc.load_word()
     decoder = self.vc.speak_config()
     self.speak_queue = self.vc.get_speak_queue()
     p = threading.Thread(target=self.vc.speak_monitor,
                          args=(self.speak_queue, decoder, command))
     p.start()
コード例 #10
0
ファイル: block.py プロジェクト: ansharlubis/numusic
def beats_to_voice(beats):
    result = Voice()
    for beat in beats:
        cur_beat = Beat()
        tones = re.findall(r'(\\|/)?([0-7\*])(\,|\')*', beat)
        for group_digit in tones:
            cur_beat.add_tone(digit_to_tone(group_digit))
        result.add_beat(cur_beat)
    return result
コード例 #11
0
class VoiceFeatureGenerator:
    def __init__(self):
        self.vc = Voice()
        command = []
        command = self.vc.load_word()
        decoder = self.vc.speak_config()
        self.speak_queue = self.vc.get_speak_queue()
        p = threading.Thread(target=self.vc.speak_monitor,
                             args=(self.speak_queue, decoder, command))
        p.start()

    def generate_voice_feature(self):
        ft = Feature()
        ft.type = 20
        ft.received_time = int(
            (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds() * 1000)
        ft.timeout = int(random.uniform(100, 5000))

        try:
            # pass
            voice_data = self.speak_queue.get(block=False)
        except:
            return None

        if voice_data['word'] == "WALK":
            return None

        if voice_data['word'] == '':
            return None

        if ft is not None:
            ft.data = voice_data
        return ft

    def simulate_data_flow_forever(self):
        while True:

            ft = self.generate_voice_feature()
            if ft is not None:
                # FIXME: cannot put connect() outside loop ?
                # FIXME: sendall() throws exception BrokenPipeError: [Errno 32] Broken pipe
                while True:
                    try:
                        sock = socket.socket(socket.AF_INET,
                                             socket.SOCK_STREAM)
                        sock.connect((common.HOST, common.PORT))
                        break
                    except ConnectionRefusedError:
                        time.sleep(1)
                        continue

                sock.sendall(bytes(ft.to_json() + "\n", "utf-8"))
                print("SEND: " + ft.to_json())
                received = str(sock.recv(1024), "utf-8")
                print("RECV: " + received)
                sock.close()
コード例 #12
0
ファイル: main.py プロジェクト: evalentini/phonity
	def post(self):
		#check if logged in 
		admin_pwd=self.request.cookies.get("admin_pwd")
		if admin_pwd==VALID_PWD:
			#send dummy text 
			voice=Voice()
			voice.login("*****@*****.**", "robots25")
			voice.send_sms(7865533061, "I am a machine")
			self.response.out.write("message sent")		
		else:
			self.redirect('/login')
コード例 #13
0
ファイル: timer.py プロジェクト: merzod/mirror
 def processCommandByMyself(self, cmd):
     global timer
     global started
     global canceled
     preTag = None
     total = 0
     for tag in cmd.tags:
         if tag.lower().startswith('час') and preTag is not None:
             try:
                 hour = int(preTag)
             except ValueError:
                 hour = 1
             logging.debug('Hour: %d' % hour)
             total += hour * 3600
         if tag.lower().startswith('минут') and preTag is not None:
             try:
                 min = int(preTag)
             except ValueError:
                 min = 1
             logging.debug('Min: %d' % min)
             total += min * 60
         elif tag.lower().startswith('секунд') and preTag is not None:
             try:
                 sec = int(preTag)
             except ValueError:
                 logging.error('Can\'t cast \'%s\' to int' % preTag)
                 return
             logging.debug('Sec: %d' % sec)
             total += sec
         preTag = tag
     if total > 0:
         if timer is not None and timer.isAlive():
             timer.cancel()
         timer = threading.Timer(total, action, args=[self])
         started = time.time()
         canceled = None
         timer.start()
         tick()
         logging.info('Start timer for %s' % secToString(total))
         Voice.getInstance().say('Таймер на %s запущен' % secToString(total))
     else:
         logging.debug('NOTHING')
コード例 #14
0
ファイル: vbox.py プロジェクト: mergansing/pt-voicebox
 def addVoiceFromFile(self, filename, voicename=''):
     if voicename == '':
         voicename = filename
     voicenumber = str(len(self.voices) + 1) + ". "
     voicename = voicenumber + voicename
     D = self.makeDict('', filename)
     if filename[0:12] == 'transcripts/':  # cleans up the filename
         filename = filename[12:]
     self.voices[voicename] = Voice(filename, D)
     self.voiceWeights[voicename] = 1
     return self.voices[voicename]
コード例 #15
0
ファイル: deepstory.py プロジェクト: AvatarWorld/deepstory
 def synthesize_wavs(self):
     # clear model from vram to revent out of memory error
     if self.current_gpt2:
         del self.gpt2
         self.gpt2 = None
         torch.cuda.empty_cache()
     for speaker, sentence_ids in self.speaker_dict.items():
         with Voice(speaker) as voice:
             for i in sentence_ids:
                 self.sentence_dicts[i]['wav'] = voice.synthesize(
                     self.sentence_dicts[i]['text'])
コード例 #16
0
class Alarm:
    def __init__(self):
        self.ascii_banner = pyfiglet.figlet_format("Hello!!")
        self.ascii_banner2 = pyfiglet.figlet_format("1337 Alarm")
        self.AWAKE_TIME = "06:30"
        self.CLASS_TIME = "09:25"
        self.music = Music()
        self.voice = Voice()

    def run(self):
        os.system('resize -s 12 55')  # Resize terminal window on mac

        # Print Hello in ascii art in blue color
        print(f"{bcolors.OKBLUE}{self.ascii_banner}")
        time.sleep(3)
        while True:
            # Print "1336 Alarm" ascii banner in blue
            print(f"{bcolors.OKBLUE}{self.ascii_banner2}")

            # Get & store H&M of local time as a string
            current_time = strftime("%H:%M", time.localtime())
            # Get and store local time fully as in Day, Mnth, Hours, mins, etc.
            full_time = time.asctime(time.localtime())

            if current_time == self.AWAKE_TIME:
                print(f"Time to wake up! {bcolors.WARNING}{current_time}\n")
                print(f"{bcolors.OKGREEN}{full_time}")

                # Call voice & music functions
                self.voice.play_voice_awake()
                self.music.play_music()
            elif current_time == self.CLASS_TIME:
                print(f"Time for class!{bcolors.WARNING}{current_time}\n")
                print(f"{full_time}")

                self.voice.play_voice_class()
            else:
                print(f"{bcolors.OKGREEN}{full_time}")
            time.sleep(1)  # To stop console flickering
            os.system("clear")  # Clear the console ('cls') for windwows
コード例 #17
0
ファイル: weather.py プロジェクト: zhifeiji/tutorial
 def closed(self, reason):
     self.weatherStr = self.time + self.dingzhi + self.sk2d + self.liveStr
     print self.weatherStr
     voice = Voice()
     access_token = voice.getAccessToken()
     print access_token
     txt = self.weatherStr
     voiceFile = voice.text2audio(access_token,txt)
     voice.playVoice(voiceFile)
コード例 #18
0
 def update_voice(self, user_list=None, force=False, token_list=token_list):
   if user_list is None:
     user_list = self._get_all_user()
   album = Album()
   voice = Voice()
   for user in user_list:
     album.update(token_list, user, force)
     voice.update(token_list, user, force)
     voice.update_data(user)
   return True
コード例 #19
0
ファイル: part.py プロジェクト: Philomelos/xml2ly
def filter_by_voice_name(measure_list, voice_name):
    from copy import deepcopy
    from measure.measure import Measure
    result = []
    for measure in measure_list:
        elts = measure.elements
        new_measure = measure.copy()
        new_measure.elements = []
        for elt in elts:
            if is_note_or_chord(elt):
                if elt.lily_voice == voice_name:
                    new_measure.elements.append(elt)
            # else:
            #     new_measure.elements.append(elt)
        result.append(new_measure)
    voice = Voice(name=voice_name, measures=result)
    return voice
コード例 #20
0
ファイル: jarvis.py プロジェクト: 0x1001/jarvis
    def __init__(self):
        from neural import LookUpTableBrain
        from body import Body
        from voice import Voice
        from neural import InnerVoice
        import threading

        self._brain = LookUpTableBrain()
        self._body = Body()
        self._voice = Voice()
        self._inner_voices = InnerVoice()
        self._inner_voices.jarvis(self)

        self._word_db = None
        self._traning_db = None

        self._stop_event = threading.Event()
コード例 #21
0
ファイル: sms.py プロジェクト: mixedup4x4/GVSMS
  def __init__(self, username, password):
    print "Initializing..."
    self.voice = Voice()
    print "Logging in..."
    try:
      self.voice.login(username, password)
    except:
      print "Error logging in"
#      print "Going to retry from the beginning"
#      Sms(username, password)
    print "Updating SMS..."
    self.id = None
    self.number = None
    self.fails = 0
    self.voice.sms()
    self.msgs = util.extractsms(self.voice.sms.html)
    threading.Timer(10, self.update).start()
    while True:
      self.prompt()
コード例 #22
0
    def synthesize_wavs(self):
        # clear model from vram to prevent out of memory error
        if self.current_gpt2:
            del self.gpt2
            self.gpt2 = None
            torch.cuda.empty_cache()

        speaker_dict_mapped = {}
        for speaker, sentence_ids in self.speaker_dict.items():
            mapped_speaker = self.speaker_map_dict.get(speaker, speaker)
            if mapped_speaker in speaker_dict_mapped:
                speaker_dict_mapped[mapped_speaker].extend(sentence_ids)
            else:
                speaker_dict_mapped[mapped_speaker] = sentence_ids

        for speaker, sentence_ids in speaker_dict_mapped.items():
            with Voice(speaker) as voice:
                for i in sentence_ids:
                    self.sentence_dicts[i]['wav'] = voice.synthesize(
                        self.sentence_dicts[i]['text'])
コード例 #23
0
ファイル: timer.py プロジェクト: merzod/mirror
 def processCommandByMyself(self, cmd):
     global timer
     logging.debug('Checking timer state')
     if timer is None:
         logging.info('Timer not run')
         Voice.getInstance().say('Таймер не запущен')
     elif timer.isAlive():
         passed = time.time() - started
         logging.info('Timer is run for %d sec, left %d sec' % (timer.interval, timer.interval - passed))
         Voice.getInstance().say('Осталось %s' % secToString(timer.interval - passed))
     else:
         if canceled is None:
             logging.info('Timer not run. Last was scheduled for %d sec, and finished %d sec ago' % (
                 timer.interval, time.time() - started - timer.interval))
             screen.ScreenWrapper.getInstance().write(secToFormat(time.time() - started), size=25)
             Voice.getInstance().say('Таймер на %s завершился %s назад' % (
                 secToString(timer.interval), secToString(time.time() - started - timer.interval)))
         else:
             logging.info('Timer not run. Last was scheduled for %d sec, and canceled %d sec ago' % (
                 timer.interval, time.time() - canceled))
             Voice.getInstance().say('Таймер на %s был отменен %s назад' % (
                 secToString(timer.interval), secToString(time.time() - canceled)))
コード例 #24
0
ファイル: robot.py プロジェクト: patlican23/robot_eup
    def build(self, robot_type):
        """Builds a robot object.

        Returns: Robot. A robot object.
        """

        # Interface
        interface = Interface(robot_type)

        # Navigation
        tf_listener = tf.TransformListener()
        location_db = LocationDb('location_db', tf_listener)
        navigation = Navigation(robot_type, location_db, tf_listener)

        # Speech and sounds
        sound_db = SoundDb('sound_db')
        for i in range(10):
            sound_db.set('sound' + str(i + 1))
        voice = Voice(sound_db)

        command_db = CommandDb('command_db')
        speech_monitor = SpeechMonitor(command_db)

        # Head
        # TODO: Head action database?
        if robot_type == RobotType.PR2:
            head = Head()
        else:
            head = None

        # Arms
        # TODO: Arm action database?
        # TODO: Arm action execution
        #arms = Arms()

        robot = Robot(robot_type, interface, navigation, voice, head,
                      speech_monitor, tf_listener)

        return robot
コード例 #25
0
class ChatRobot(object):
    def __init__(self):
        self.__tools = Tools()
        self.__baiduSTT = BaiduSTT()  # 语音转文字模块
        self.__baiduTTS = BaiduTTS()  # 文字转语音模块
        self.__voice = Voice()  # 音频抓取模块
        self.__tuling = TulingRobot()  # 图灵机器人

    def textchat(self):
        print("Now u can type in something & input q to quit\n")
        while True:
            """"文字聊天"""
            request = raw_input("Master:")
            if request == 'q':
                exit("u r quit the chat !")  # 设定输入q,退出聊天。
            else:
                response = self.__tuling.chat(request)
                print "Robot:%s" % (response)
                speechFile = self.__baiduTTS.TTS(response)
                if os.path.exists(speechFile):
                    self.__tools.play_mp3(speechFile)
                    os.remove(speechFile)

    def voicechat(self):
        print("Now u can talk to me\n")
        while True:
            """"语音聊天"""
            speechFile = self.__voice.get_voice()
            if os.path.exists(speechFile):
                request = self.__baiduSTT.STT(speechFile)
                print request
                response = self.__tuling.chat(request)
                print response
                speechFile = self.__baiduTTS.TTS(response)
                if os.path.exists(speechFile):
                    self.__tools.play_mp3(speechFile)
                    os.remove(speechFile)
コード例 #26
0
ファイル: info.py プロジェクト: curtis-penner/bac
 def __init__(self):
     self.area = Single()
     self.book = Single()
     self.composer = Composers()
     self.discography = Single()
     self.layout_parameter = LayoutParams()
     self.file_name = Single(True)
     self.group = Single()
     self.history = History()
     self.key_clef = Key()
     self.default_note_length = DefaultLength()
     self.meter = Meter()
     self.notes = Single(True)
     self.origin = Single()
     self.parts = Parts()
     self.tempo = Tempo()
     self.rhythm = Single()
     self.source = Single()
     self.titles = Titles()
     self.voice = Voice()
     self.lyrics = Lyrics()
     self.words = Words()
     self.xref = XRef()
     self.transciptoin_note = Single()
コード例 #27
0
ファイル: core.py プロジェクト: Sreyas-Sreelal/Voca
class Core:
    def __init__(self):
        self.voice = Voice()
        self.brain = AI()
        self.recognizer = Recognizer()

    def run(self):
        while True:
            try:
                heard = self.recognizer.listen_and_understand().lower()

                if "shutdown" in heard:
                    self.voice.emit("Ok   I will turn OFF myself")
                    exit()

                for cmd in voca_commands.keys():
                    if heard.startswith(cmd):
                        if heard.strip() == cmd:
                            print("hear")
                            voca_commands[cmd].execute(
                                self.voice.emit,
                                self.recognizer.listen_and_understand)
                        else:
                            print(heard[len(cmd):])
                            voca_commands[cmd].execute(
                                self.voice.emit,
                                self.recognizer.listen_and_understand,
                                heard[len(cmd):])
                        continue

                response = self.brain.generate_response(heard)
                self.voice.emit(response)

            except UnknownValueError:
                #voca_say("What you mean  I dont really understood that")
                continue

            except RequestError:
                self.voice.emit(
                    "Seems like there is an issue with my internet connection")
コード例 #28
0
ファイル: voicetest.py プロジェクト: 0x1001/jarvis
    def setUp(self):
        from voice import Voice

        self.voice = Voice()
コード例 #29
0
ファイル: demo.py プロジェクト: merzod/mirror
    time.sleep(0.5)

    # move forward
    walle.move(Base.FORWARD)
    time.sleep(1)
    walle.move_arm(Base.LEFT_ARM, Base.DOWN)
    walle.move_arm(Base.RIGHT_ARM, Base.DOWN)
    time.sleep(1)

    # shake hand twice
    direction = Base.DOWN
    for i in range(0, 4):
        direction = not direction
        walle.move_arm(Base.RIGHT_ARM, direction)
        time.sleep(0.3)
    Voice.getInstance().playFile('../resources/wall-e.ogg')

    # screen demo
    frames = [["../resources/anim1/sc0.png", 1],
           ["../resources/anim1/sc1.png", 0.1],
           ["../resources/anim1/sc2.png", 0.5],
           ["../resources/anim1/sc1.png", 0.1],
           ["../resources/anim1/sc0.png", 1]]
    screen.ScreenWrapper.getInstance().play(frames)
    screen.ScreenWrapper.getInstance().draw_walle_state()

    # turn left
    walle.head.move(0)
    walle.turn(Base.TURN_LEFT, 0.5)
    time.sleep(0.2)
    walle.head.move(90)
コード例 #30
0
ファイル: weather.py プロジェクト: merzod/mirror
 def checkWeather(self, day):
     page = requests.get('http://www.meteoprog.ua/ru/weather/Odesa/#detail')
     tree = html.fromstring(page.text)
     s = self.prepareString(tree, day)
     logging.info(s)
     Voice.getInstance().say(s)
コード例 #31
0
ファイル: timer.py プロジェクト: merzod/mirror
def action(processor):
    logging.info('Time!!!: %s' % processor)
    screen.ScreenWrapper.getInstance().write('Timeout', size=30)
    Voice.getInstance().sayCachedTimeout()
コード例 #32
0
ファイル: client.py プロジェクト: telecmi/piopiy_python
 def make(self, to, piopiy_no, answer_url):
     return Voice(self.appid, self.secret).make(to, piopiy_no, answer_url)
コード例 #33
0
from ..exceptions import ImpossibleMoveException, NoMovesToUndoException

from voice import Voice

import screen
from screen import RenderState
import strings

import os

setlocale(locale.LC_ALL, '')

config = json.loads(str(open("./settings.json").read()))
game = GamePresenter(Game(config))
renderer = render_state = RenderState(game)
voice = Voice()


def main(curses_screen):
    #FIXME extract object from screen module
    screen.verify(renderer, curses_screen)
    screen.configure(curses_screen)
    voice.say(
        random.choice(strings.TITLE_SCREEN_MESSAGES) %
        (game.player_one()["name"], game.player_one()["symbol"],
         game.player_two()["name"], game.player_two()["symbol"]))
    screen.show_title(curses_screen)
    game_loop(curses_screen)
    voice.say("Goodbye")

コード例 #34
0
ファイル: openallure.py プロジェクト: mak1e/Open-Allure-DS
def main():
    """Initialization and event loop"""

    # provide instructions and other useful information

    # initialize pyGame screen
    textRect = pygame.rect.Rect(0, 0, 640, 480)
    screenRect = pygame.rect.Rect(0, 0, 640, 480)
    pygame.init()
    pygame.display.set_caption(u"Open Allure")
    screen = pygame.display.set_mode(screenRect.size)
    if sys.platform != 'darwin':
        pygame.scrap.init()

    config = ConfigObj('openallure.cfg')

    # determine what language to use for string translations
    # this can be overridden in scripts
    gettext.install(domain='openallure', localedir='locale', unicode=True)
    try:
        language = config['Options']['language']
    except KeyError:
        language = 'en'
    if len(language) > 0 and language != 'en':
        mytrans = gettext.translation(u"openallure",
                                      localedir='locale',
                                      languages=[language], fallback=True)
        mytrans.install(unicode=True) # must set explicitly here for Mac
    # language also determines which default systemVoice to use (Mac only)
    openallure.systemVoice = ''
    try:
        openallure.systemVoice = config['Voice'][language]
    except KeyError:
        pass

    # load initial question sequence from url specified in openallure.cfg file
    url = unicode(config['Source']['url'])
    if len(sys.argv) > 1 and 0 != len(sys.argv[1]):
        url = unicode(sys.argv[1])
    backgroundColor = eval(config['Colors']['background'])
    seq = QSequence(filename = url)
    try:
        openallure.systemVoice = config['Voice'][seq.language]
    except KeyError:
        pass

    # open database to track progress

    oadb = config['Data']['oadb']
    try:
        openallure.db = Base(oadb).open()
    except IOError:
        openallure.db = Base(oadb)
        openallure.db.create(('time',float), ('url',unicode), \
        ('q',int), ('a',int), ('cmd',unicode))

    # read configuration options
    delayTime = int(config['Options']['delayTime'])
    openallure.allowNext = int(config['Options']['allowNext'])

    # initialize chatbot
    openallure_chatbot = Chat(responses, reflections)
    chatHistory = []
    onChatHistory = -1

    # track when Open Allure has gained mouse focus
    openallure.gain = 1
    # mouse focus only matters when stickyBrowser is true (see openallure.cfg)
    openallure.stickBrowser = eval(config['Options']['stickyBrowser'])

    voice = Voice()

    margins = eval(config['Font']['margins'])
    text = OpenAllureText(margins)

    # start on first question of sequence
    # TODO: have parameter file track position in sequence at quit
    # and resume there on restart
    openallure.onQuestion = 0

    # initialize mode flags
    # Has new question from sequence been prepared?
    openallure.ready = False
    # Has question been openallure.stated (read aloud)?
    openallure.stated = False
    # Which question in sequence has been read aloud (to avoid re-reading it)?
    # Note: -1 indicates no question as valid questions start with 0
    openallure.statedq = -1
    # What choice (if any) has been highlighted by gesture or keyboard?
    highlight = 0
    # When was the statement of the question complete?
    delayStartTime = 0
    # Do we have an answer? what number is it (with 0 being first answer)?
    answer = -1
    # What questions have been shown (list)?
    # Note: This list is also checked to avoid re-stating a question
    openallure.questions = []
    # What has been typed in so far
    openallure.currentString = u""

    # Subprocesses
#    graphViz = None
#    openallure.showResponses = eval(config['GraphViz']['showResponses'])
#    openallure.showText = eval(config['GraphViz']['showText'])
#    openallure.showLabels = eval(config['GraphViz']['showLabels'])
#    graphVizPath = config['GraphViz']['path']
    #if eval(config['GraphViz']['autoStart']):
    #    oagraph(seq,openallure.db,url,openallure.showText,openallure.showResponses,openallure.showLabels)
    #    graphViz = subprocess.Popen([graphVizPath,'oagraph.dot'])

    # Greetings
    #voice.speak('Hello')

    WELCOME_TEXT = ["",
    _(u"       Welcome to the Open Allure Dialog System."),
    "",
    _(u"       Keys:"),
    _(u"           Escape quits"),
    _(u"           Ctrl+I force input"),
    _(u"           Ctrl+R refresh"),
    _(u"           Ctrl+V paste"),
    "",
    _(u"       Commands:"),
    _(u"           exit"),
    _(u"           open <filename or url>"),
    _(u"           quit"),
    _(u"           return (resumes at last question)"),
    _(u"           show source (Mac only)"),
    ""]

    for line in WELCOME_TEXT:
        print line

    runFlag = True;
    while runFlag:

        if not openallure.ready:
            # prepare for question display
            openallure.question = seq.sequence[openallure.onQuestion]
            choiceCount, \
            questionText, \
            justQuestionText = text.buildQuestionText(openallure.question)
#            if graphViz:
#                # Create .dot file for new sequence
#                graphViz.kill()
#                oagraph(seq,openallure.db,url,openallure.showText,openallure.showResponses,openallure.showLabels)
#                graphViz = subprocess.Popen([graphVizPath, 'oagraph.dot'])

            textRegions = text.writewrap(None, text.font, text.boundingRectangle, text.unreadColor, questionText[-1])

            # initialize pointers - no part of the question text
            # and none of the answers have been read aloud.
            # Note that question text is numbered from 0
            # while answers are numbered from 1.
            action = 0
            onAnswer = 0
            onText = 0
            openallure.stated = False
            if openallure.onQuestion in openallure.questions:
                openallure.stated = True

            # initialize selections - nothing has been highlighted
            # or previously selected as an answer
            answer = -1
            choice = (- 1, 0)
            colorLevel = colorLevels = 12
            highlight = 0

            # initialize typed input
            openallure.currentString = u''

            # clear screen of last question
            screen.fill(backgroundColor, rect=textRect)

            # wait for prior speaking to finish
            if voice.pid_status > 0:
                try:
                    os.waitpid(voice.pid_status, 0)[1]
                except:
                    pass
                voice.pid_status = 0
            openallure.ready = True

            # clear any previous response
            nltkResponse = ''

            # start with gain
            openallure.gain = 1

            # arrival record for new question
            record_id = openallure.db.insert(time = time.time(), \
            url = unicode(url), q = openallure.onQuestion)

        # make sure currentString has been added to questionText
        if openallure.currentString:
            questionText[choiceCount] = questionText[choiceCount - 1] + \
                                          "\n" + openallure.currentString

        # get keyboard and mouse input
        mouseButtonDownEvent = False
        mouseButtonDownEventY = 0
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONDOWN:
                mouseButtonDownEvent = True
                YCOORDINATE = 1
                mouseButtonDownEventY = event.pos[YCOORDINATE]
            if event.type == pygame.QUIT   \
               or (event.type == pygame.KEYDOWN and    \
                   event.key == pygame.K_ESCAPE):
#               if graphViz:
#                   graphViz.kill()
                runFlag = False

            # Trap and quit on Ctrl + C
            elif (event.type == pygame.KEYDOWN and
                  event.key == pygame.K_c and
                  pygame.key.get_mods() & pygame.KMOD_CTRL):
                return

            # Trap Ctrl + I to force input
            elif (event.type == pygame.KEYDOWN and
                  event.key == pygame.K_i and
                  pygame.key.get_mods() & pygame.KMOD_CTRL):
                # Note: This kills the entire current sequence.
                # The return command gives a way to back to it.
                seq.inputs = [_(u"Input"),
                         _(u"[input];")]
                seq.sequence = seq.regroup(seq.inputs, \
                               seq.classify(seq.inputs))
                openallure.onQuestion = 0
                url = _(u'[input]')
                # record call to input
                record_id = openallure.db.insert(time = time.time(), \
                            url = unicode(url), q = 0)
                openallure.ready = False

            # Trap and paste clipboard on Ctrl + V for Mac
            elif (event.type == pygame.KEYDOWN and
                  event.key == pygame.K_v and
                  pygame.key.get_mods() & pygame.KMOD_CTRL):
                if sys.platform == 'darwin':
                    os.system('pbpaste > clipboard')
                    clipboard = open('clipboard').readlines()
                    if clipboard[0].startswith(u"http://") or \
                       clipboard[0].find(u"http://"):
                        openallure.currentString += clipboard[0]
                else:
                    clipboard = pygame.scrap.get(pygame.SCRAP_TEXT)
                    if clipboard.startswith(u"http://") or \
                       clipboard.find(u"http://"):
                        openallure.currentString += clipboard

            # Trap Ctrl + - (minus) to decrease font size
            elif (event.type == pygame.KEYDOWN and
                  event.key == pygame.K_MINUS and
                  pygame.key.get_mods() & pygame.KMOD_CTRL):
                text.fontSize -= 5
                text.font = pygame.font.SysFont( text.fontName, \
                text.fontSize )

            # Trap Ctrl + + (plus) to increase font size
            elif (event.type == pygame.KEYDOWN and
                  event.key == pygame.K_EQUALS and
                  pygame.key.get_mods() & pygame.KMOD_CTRL):
                text.fontSize += 5
                text.font = pygame.font.SysFont( text.fontName, \
                text.fontSize )

            # Trap Ctrl + R to refresh from url without changing question number
            elif (event.type == pygame.KEYDOWN and
                  event.key == pygame.K_r and
                  pygame.key.get_mods() & pygame.KMOD_CTRL):
                # if url is nltkRespose.txt, look back for something else
                # worth refreshing
                if url == u'nltkResponse.txt':
                    for id in range(record_id - 1,-1,-1):
                        record = openallure.db[id]
                        if not record.url in (url, \
                                              u'nltkResponse.txt', \
                                              _(u'[input]')):
                            url = record.url
                            break
                seq = QSequence(filename = url)
                try:
                    openallure.systemVoice = config['Voice'][seq.language]
                except KeyError:
                    pass
                openallure.ready = False

            # Define toggle keys and capture string inputs
            elif event.type == pygame.KEYDOWN:
                # Keys 1 through 6 select choices 1 through 6
                if event.key in range(pygame.K_1, pygame.K_6) and \
                    (not openallure.question[INPUTFLAG][choiceCount - 1] == 1 or
                    (openallure.question[INPUTFLAG][choiceCount - 1] == 1 and
                    openallure.currentString == u'')):
                        answer = event.key - pygame.K_1
                        if answer < choiceCount:
                            # Record choice along with destination, if any
                            record_id = openallure.db.insert(time = time.time(), \
                            url = unicode(url), q = openallure.onQuestion, \
                            a = answer, cmd = unicode(openallure.question[DESTINATION][answer]))
#                            if graphViz:
#                                graphViz.kill()
#                                oagraph(seq,openallure.db,url,openallure.showText,openallure.showResponses,openallure.showLabels)
#                                graphViz = subprocess.Popen([graphVizPath, 'oagraph.dot'])
                            choice = (answer + 1, 0)
                            colorLevel = 0
                            # Update screen to reflect choice
                            text.paintText(screen,
                                           justQuestionText, onText,
                                           questionText, onAnswer,
                                           highlight,
                                           openallure.stated,
                                           choice,
                                           colorLevel, colorLevels)
                            pygame.display.flip()
                        else:
                            answer = -1

                elif event.key == pygame.K_F6:
                    # reveal all the attributes of openallure
                    print "\nCurrent values of openallure object variables:\n"
                    for item in openallure.__dict__:
                        print item + ":", openallure.__dict__[item]
                    # drop into interpreter for debugging
                    print "\n   Press Ctrl+D to close console and resume. " + \
                    "Enter exit() to exit.\n"
                    import code
                    code.interact(local=locals())

                # Allow space to silence reading of question
                # unless there is an input (which might require a space)
                elif event.key == pygame.K_SPACE and \
                not openallure.question[INPUTFLAG][choiceCount - 1] == 1:
                    # Silence reading of question
                    openallure.stated = True
                    
                elif event.key == pygame.K_RIGHT and openallure.allowNext:
                    # Choice is first non-zero entry
                    # in openallure.question[ACTION]
                    onChoice = 0
                    for i in openallure.question[ACTION]:
                        onChoice += 1
                        if not i == 0:
                            answer = onChoice - 1
                            record_id = openallure.db.insert(time = time.time(), \
                            url = unicode(url), q = openallure.onQuestion, \
                            a = answer, cmd = unicode(openallure.question[DESTINATION][answer]))
#                            if graphViz:
#                                graphViz.kill()
#                                oagraph(seq,openallure.db,url,openallure.showText,openallure.showResponses,openallure.showLabels)
#                                graphViz = subprocess.Popen([graphVizPath, 'oagraph.dot'])
                            choice = (onChoice, 0)
                            break
                    del onChoice

                elif event.key == pygame.K_LEFT:
                    if len(openallure.questions) > 0:
                        openallure.onQuestion = openallure.questions.pop()
                        openallure.ready = False
                    else:
                        openallure.onQuestion = 0

                elif event.key == pygame.K_UP:
                    if len(chatHistory) > 0 and onChatHistory > 0:
                        onChatHistory -= 1
                        openallure.currentString = chatHistory[onChatHistory]
                elif event.key == pygame.K_DOWN:
                    if len(chatHistory) > 0 and \
                    onChatHistory < len(chatHistory) - 1:
                        onChatHistory += 1
                        openallure.currentString = chatHistory[onChatHistory]

                elif event.key == pygame.K_RETURN:
                    if openallure.currentString:
                        # add to history
                        chatHistory.append(openallure.currentString)
                        onChatHistory = len(chatHistory)
                        # record input string
                        record_id = openallure.db.insert(time = time.time(), \
                                    url = unicode(url), q = openallure.onQuestion, \
                                    a = answer, cmd = openallure.currentString)
                        # Check for rules from script at end of question 0
                        if len(seq.sequence[0]) > 9:
                            scriptRules = seq.sequence[0][RULE]
                        else:
                            scriptRules = None
                        nltkResponse, \
                        nltkType, \
                        nltkName = \
                        openallure_chatbot.respond(openallure.currentString, \
                                                   scriptRules)

                        # Act on commands
                        if nltkType == 'goto' or \
                          (nltkType == 'text' and nltkName == 'what now'):
                            # find question with goto tag = ruleName or
                            # currentString (if it didn't match anything else)
                            if openallure.question[QUESTION] == [_(u"Input")]:
                                # Back up to first non-Input, non-Sorry question
                                for id in range(record_id - 1,-1,-1):
                                    try:
                                        record = openallure.db[id]
                                        if not record.url in (url, u'nltkResponse.txt', _(u'[input]')):
                                            seq = QSequence(filename = record.url, \
                                                    path = seq.path, \
                                                    nltkResponse = nltkResponse)
                                            try:
                                                openallure.systemVoice = config['Voice'][seq.language]
                                            except KeyError:
                                                pass
                                            url = record.url
                                            openallure.onQuestion = record.q
                                            openallure.ready = False
                                            break
                                    except:
                                        pass                             
                            tags = [ question[TAG] for question in seq.sequence ]
                            if nltkName in tags:
                                openallure.onQuestion = tags.index(nltkName)
                                openallure.ready = False
                            if nltkName== 'what now' and \
                               openallure.currentString.lower() in tags:
                                if openallure.onQuestion != \
                                        tags.index(openallure.currentString):
                                    openallure.questions.append(openallure.onQuestion) 
                                    openallure.onQuestion = \
                                        tags.index(openallure.currentString)
                                    openallure.ready = False
                            # If still no luck finding a match, use currentString
                            # to search all through the text of all the questions
                            if openallure.ready:
                                for qnum, question in enumerate(seq.sequence):
                                    # search in question text and non-Input answer text
                                    nonInputAnswerText = [answer for answer,input in \
                                                          itertools.izip(question[ANSWER],
                                                                         question[INPUTFLAG]) if not input]
                                    qtext = " ".join(question[QUESTION]) + " " + \
                                            " ".join(nonInputAnswerText)
                                    if qtext.lower().find(openallure.currentString.lower()) > -1:
                                        if openallure.onQuestion != qnum:
                                            openallure.questions.append(openallure.onQuestion)
                                            openallure.onQuestion = qnum
                                            openallure.ready = False
                                            break
                                    

                        if nltkType == 'quit':
                            #TODO: Make this more polite
#                            if graphViz:
#                                graphViz.kill()
                            raise SystemExit

                        if nltkType == 'return':
                            # Find first different sequence in db, walking back
                            for id in range(record_id - 1,-1,-1):
                                try:
                                    record = openallure.db[id]
                                    if not record.url in (url, u'nltkResponse.txt', _(u'[input]')):
                                        seq = QSequence(filename = record.url, \
                                                path = seq.path, \
                                                nltkResponse = nltkResponse)
                                        try:
                                            openallure.systemVoice = config['Voice'][seq.language]
                                        except KeyError:
                                            pass
                                        url = record.url
                                        openallure.onQuestion = record.q
                                        openallure.ready = False
#                                        if graphViz:
#                                            # Fall through into graphing
#                                            nltkType = 'graph'
#                                            nltkName = 'show'
                                        break
                                except:
                                    pass
                            nltkResponse = u''
                            openallure.currentString = u''

                        if nltkType == 'open':
                            # Reset stated question pointer for new sequence
                            openallure.statedq = -1
                            path = seq.path
                            linkStart = nltkResponse.find(u'[')
                            linkEnd = nltkResponse.find(u']', linkStart)
                            url = nltkResponse[linkStart + 1:linkEnd]
                            seq = QSequence(filename = url,
                                            path = path,
                                            nltkResponse = nltkResponse)
                            try:
                                openallure.systemVoice = config['Voice'][seq.language]
                            except KeyError:
                                pass
                            openallure.questions = []
                            openallure.onQuestion = 0
                            openallure.ready = False
#                            if graphViz:
#                                # Fall through into graphing
#                                nltkType = 'graph'
#                                nltkName = 'show'
                            nltkResponse = u''
                            openallure.currentString = u''

                        if nltkType == 'show':
                            # use open (Mac only) to view source
                            if sys.platform == 'darwin':
                                # Find first non-[input] sequence in db, walking back
                                for id in range(record_id - 1,-1,-1):
                                    record = openallure.db[id]
                                    if record.url.find('.txt') > 0 or \
                                       record.url.find('http:') == 0 :
                                        if not record.url == 'nltkResponse.txt':
                                            url = record.url
                                            break
                                os.system("open "+url)

                        # if nltkResponse is one line containing a semicolon,
                        # replace the semicolon with \n
                        if nltkResponse.find('\n') == -1:
                            nltkResponse = nltkResponse.replace(';', '\n')

                        if nltkResponse:
                            answer = choiceCount - 1
                            choice = (choiceCount, 0)
                    else:
                        # This takes last response
                        answer = choiceCount - 1
                        choice = (choiceCount, 0)

                elif event.key == pygame.K_BACKSPACE and \
                openallure.question[INPUTFLAG][choiceCount - 1] == 1:
                    openallure.currentString = openallure.currentString[0:-1]
                    openallure.question[ANSWER][choiceCount - 1] = \
                    openallure.currentString
                    questionText[choiceCount] = \
                    questionText[choiceCount - 1] + \
                    u"\n" + openallure.currentString
                    screen.fill(backgroundColor, rect=textRect)

                elif event.key <= 127 and \
                openallure.question[INPUTFLAG][-1] == 1:
                    # p rint event.key
                    mods = pygame.key.get_mods()
                    if mods & pygame.KMOD_SHIFT:
                        if event.key in range(47, 60):
                            openallure.currentString += \
                            (u'?', u')', u'!', u'@', u'#', u'$', u'%', u'^', \
                            u'&', u'*', u'(', u'', u':')[range(47, 60).index(event.key)]
                        elif event.key == 45:
                            openallure.currentString += u"_"
                        elif event.key == 61:
                            openallure.currentString += u"+"
                        elif event.key == 96:
                            openallure.currentString += u"~"
                        else:
                            openallure.currentString += \
                                unicode(chr(event.key).upper())
                    else:
                        openallure.currentString += unicode(chr(event.key))
#                    openallure.question[ANSWER][choiceCount - 1] = \
#                        openallure.currentString
                    # Add currentString to text being displayed
                    questionText[choiceCount] = \
                        questionText[choiceCount - 1] + \
                        u"\n" + openallure.currentString
                    screen.fill(backgroundColor, rect=textRect)

        # check for automatic page turn
        if openallure.ready and \
           openallure.stated == True and \
           not openallure.currentString and \
           openallure.question[ANSWER][-1] == _(u'[next]') and \
           pygame.time.get_ticks() - delayStartTime > delayTime:
            # This takes last response
            answer = choiceCount - 1
            choice = (choiceCount, 0)

        if openallure.statedq == openallure.onQuestion:
            openallure.stated = True

        if openallure.ready and not openallure.stated:
            # work through statement of question
            # speaking each part of the question and each of the answers
            # (unless the process is cut short by other events)
            if onText == 0:
                screen.fill(backgroundColor, rect=textRect)
                pygame.display.flip()

            # Stop when onAnswer pointer is beyond length of answer list
            if onAnswer > len(openallure.question[ANSWER]):
                openallure.stated = True
                openallure.statedq = openallure.onQuestion

            else:
                # Speak each answer
                #(but only after speaking the full question below)
                if onAnswer > 0 and onAnswer < len(openallure.question[ANSWER]) + 1:
                    answerText = openallure.question[ANSWER][onAnswer - 1]
                    if not (answerText.startswith(_('[input]')) or
                             answerText.startswith(_('[next]')) or
                             answerText.endswith( '...]' ) or
                             answerText.endswith( '...' )):
                        if len(answerText) > 0:
                            # Check for answer with "A. "
                            if answerText[1:3] == '. ':
                                voice.speak(answerText[3:].strip(),openallure.systemVoice)
                            else:
                                voice.speak(answerText.strip(),openallure.systemVoice)
                        del answerText

                # Speak each part of the question using onText pointer
                # to step through parts of question list
                if onText < len(openallure.question[QUESTION]):
                    if not (openallure.question[QUESTION][onText].endswith( '...' )):
                        if len(openallure.question[QUESTION][onText]) > 0:
                            # speak the current part of the question
                            voice.speak(openallure.question[QUESTION][onText],openallure.systemVoice)

        if answer < 0 and openallure.ready:

            # Trap mouse click on text region
            textRegions = text.writewrap(None, \
                                         text.font, \
                                         text.boundingRectangle, \
                                         text.unreadColor, \
                                         questionText[-1])

            # Create list where each element indicates with 1 or 0
            # whether Y coordinate is in the region
            regions = [inRegion(region, mouseButtonDownEventY) for region in textRegions]

            # Find which region has a 1, if any
            if 1 in regions:
                onRegion = regions.index(1)
            else:
                onRegion = 0

            if onRegion > 0:
                if mouseButtonDownEvent:
                    answer = onRegion - 1
                    if answer < choiceCount:
                        # record selection of answer
                        record_id = openallure.db.insert(time = time.time(), \
                        url = unicode(url), q = openallure.onQuestion, \
                        a = answer)
#                        if graphViz and openallure.question[ACTION][answer] == 0:
#                            # Create .dot file for one sequence in response to answer in place
#                            graphViz.kill()
#                            oagraph(seq,openallure.db,url,openallure.showText,openallure.showResponses,openallure.showLabels)
#                            graphViz = subprocess.Popen([graphVizPath, 'oagraph.dot'])
                        choice = (answer + 1, 0)
                        colorLevel = 0
                        # Update screen to reflect choice
#                         text.paintText(screen,
#                                        justQuestionText, onText,
#                                        questionText, onAnswer,
#                                        highlight,
#                                        openallure.stated,
#                                        choice,
#                                        colorLevel, colorLevels)
#                         pygame.display.flip()
                    else:
                        answer = -1
                else:
                    highlight = onRegion
                    # Update screen to reflect highlight
#                     text.paintText(screen,
#                                    justQuestionText, onText,
#                                    questionText, onAnswer,
#                                    highlight,
#                                    openallure.stated,
#                                    choice,
#                                    colorLevel, colorLevels)
#                     pygame.display.flip()
                    colorLevel -= 1
                    colorLevel = max(colorLevel, 0)
            else:
                highlight = 0
                colorLevel = colorLevels

            # block non-choices
            if choice[0] < 0 or choice[0] > len(questionText) - 1:
                choice = (-1, 0)

            screen.fill(backgroundColor, rect=textRect)
            text.paintText(screen,
                           justQuestionText, onText,
                           questionText, onAnswer,
                           highlight,
                           openallure.stated,
                           choice,
                           colorLevel, colorLevels)
            # and move on to the next part
            # (which needs to be displayed while being spoken)
            onText += 1
            # once all the parts of the question are done,
            # start working through answers
            if onAnswer > 0:
                onAnswer += 1
            if onText == len(openallure.question[QUESTION]):
                onAnswer = 1
                # Take note of time for automatic page turns
                delayStartTime = pygame.time.get_ticks()

            pygame.display.flip()

        elif not choice == (- 1, 0) and openallure.ready:

            openallure.stated = True

            # respond to choice when something has been typed and entered
            if openallure.currentString:
                if len(nltkResponse) == 0:
                    choice = (-1, 0)
                    answer = -1
                    voice.speak(_("Try again"),openallure.systemVoice)
                else:
                    voice.speak(_(u"You entered ") + openallure.currentString,openallure.systemVoice)
                # Reset string
                openallure.currentString = u''

            # check whether a link is associated with this answer and,
            # if so, follow it
            if len(openallure.question[LINK]) and openallure.question[LINK][answer]:
                webbrowser.open_new_tab(openallure.question[LINK][answer])
                # wait in loop until window (re)gains focus
                if openallure.stickBrowser:
                    openallure.gain = 0
                    while not openallure.gain:
                        for event in pygame.event.get():
                            if event.type == pygame.ACTIVEEVENT:
                                openallure.gain = event.gain

            #check that response exists for answer
            if len(openallure.question[RESPONSE]) and \
               answer < len(openallure.question[RESPONSE]) and \
                (isinstance(openallure.question[RESPONSE][answer], str) or \
                isinstance(openallure.question[RESPONSE][answer], unicode)):
                    #speak response to answer
                    voice.speak(openallure.question[RESPONSE][answer].strip(),openallure.systemVoice)

            #check that next sequence exists as integer for answer
            if len(openallure.question[ACTION]) and \
            answer < len(openallure.question[ACTION]) and \
            isinstance(openallure.question[ACTION][answer], int):
                #get new sequence or advance in sequence
                action = openallure.question[ACTION][answer]
                if len(openallure.question[DESTINATION][answer]) > 0 and \
                not openallure.question[ANSWER][answer] == _(u'[next]'):
                    # speak("New source of questions")
                    # Reset stated question pointer for new sequence
                    openallure.statedq = -1
                    path = seq.path
                    url = openallure.question[DESTINATION][answer]
                    seq = QSequence(filename = url,
                                    path = path,
                                    nltkResponse = nltkResponse)
                    try:
                        openallure.systemVoice = config['Voice'][seq.language]
                    except KeyError:
                        pass
                    openallure.onQuestion = 0
                    openallure.questions = []
                else:
                    # Add last question to stack (if not duplicate) and move on
                    if action > 0:
                        openallure.questions.append(openallure.onQuestion)
                        openallure.onQuestion = openallure.onQuestion + action

                    elif action < 0:
                        openallure.onQuestion = max( 0, openallure.onQuestion + action )

                    # Quit if advance goes beyond end of sequence
                    if openallure.onQuestion >= len(seq.sequence):
                        voice.speak(_("You have reached the end. Goodbye."),openallure.systemVoice)
                        return

                openallure.ready = False
コード例 #35
0
ファイル: main.py プロジェクト: komodo108/voice-bot
# Register the bot
bot = commands.Bot(command_prefix=commands.when_mentioned_or("!"), description="Bot for adding voice roles")

# Print when ready
@bot.event
async def on_ready():
    # Print we're connected
    print("Connected as {0} ({0.id})".format(bot.user))

    # Change the bot
    await bot.change_presence(activity=discord.Game("donald108.com"))
    print("Playing donald108.com")

# Add cogs
bot.add_cog(Voice(bot))
bot.add_cog(Text(bot))

# Job for the worker
def job():
    data = { 'google' : 0 }
    with open("config/usage.json", "w") as f:
        json.dump(data, f)
        print("Cleared usage.json file")

# Call the worker function every day
cron = BackgroundScheduler(deamon=True)
cron.add_job(func=job, trigger='interval', days=1)
cron.start()

# Register scheduler to shutdown
コード例 #36
0
ファイル: voice_test.py プロジェクト: bugbiteme/alarmclock
from voice import Voice

voice = Voice()
voice.say_cl('fortune')
voice.say("This is a super long sentence and I just want to see how it goes. Is it fast or is it slow? Nobody knows. Do you? Probabaly not! You moron! Take that!")
voice.say()
voice.say_cl()
voice.say_cl('ls')
コード例 #37
0
ファイル: blind_runner.py プロジェクト: saigalamatya/DeepWay
import datetime
from stop import Stop
model_name = 'blind_with_regularization.model'
COM = 'COM9'
camera = 1
baudrate = 9600
width = 64
height = 64
prob = 0
label = ''

print("loading model .....")
model = load_model(model_name)
print("model loaded")
ard = Arduino(baudrate, COM)  ##movleft(),movright()
vce = Voice()  #left(),right()
st = Stop()
fac = detect()
current = datetime.datetime.now()
flag = None
cap = cv2.VideoCapture(camera)
ret = True
prev = None
while ret:
    ret, frame = cap.read()
    frame = cv2.resize(frame, (640, 480))

    faces = fac.faceDetect(frame)

    ##stop on left
コード例 #38
0
ファイル: sms.py プロジェクト: mixedup4x4/GVSMS
class Sms:
  
  def __init__(self, username, password):
    print "Initializing..."
    self.voice = Voice()
    print "Logging in..."
    try:
      self.voice.login(username, password)
    except:
      print "Error logging in"
#      print "Going to retry from the beginning"
#      Sms(username, password)
    print "Updating SMS..."
    self.id = None
    self.number = None
    self.fails = 0
    self.voice.sms()
    self.msgs = util.extractsms(self.voice.sms.html)
    threading.Timer(10, self.update).start()
    while True:
      self.prompt()
    
  
  def update(self):
    try:
      self.voice.sms()
      oldmsgs = self.msgs
      self.msgs = util.extractsms(self.voice.sms.html)
      if len(self.msgs) != len(oldmsgs):
        sys.stdout.write('\a')
        sys.stdout.flush()
        self.fails = 0
    except:
      #Fail silently, but keep a running tab of the number of failures.
      self.fails += 1
      if self.fails > 5:
        print "Error Updating"
    
    t = threading.Timer(10, self.update)
    t.daemon = True
    t.start()
    
      
  def prompt(self):
    for i in range(50):
      print ""
    if self.id == None:
      self.setId()
    for msg in self.msgs:
      if msg['id'] == self.id:
        if msg['from'] == 'Me:':
          print ">>>" + msg['text']
        else:
          print msg['text']
    try:
      usr_in = str(raw_input(">>>"))
      if usr_in == "--conversation" or usr_in == "-c":
        self.setId()
      elif usr_in == "--number" or usr_in =="-n":
        self.setNumber()
      elif usr_in[:2] == "--":
        print "I don't think that is what you meant..."
      else:
        self.voice.send_sms(self.number, usr_in)
    except SyntaxError:
      print "Error on Send"
      
  def setId(self):
    ids = []
    for msg in self.msgs:
      if msg['id'] not in ids:
        ids.append(msg['id'])
    if self.id != None:
      print "Current conversation: ", ids.index(self.id)
    d = json.loads(self.voice.sms.json)['messages']
    for i in range(len(ids)):
      print i, " ", d[ids[i]]['displayNumber']
    inp = raw_input("id: ")
    if inp == "" and self.id == None:
      print "You must enter an id"
      self.setId()
    if inp != "":
      try:
        self.id = ids[int(inp)]
        self.number = d[self.id]['displayNumber']
      except:
        print "Invalid id"
        self.setId()
    
  def setNumber(self):
    print "Current number: ", self.number
    inp = raw_input("Number: ")
    if inp != "":
      try:
        self.number = str(inp)
      except:
        print "Invalid number"
        self.setNumber()
コード例 #39
0
ファイル: test.py プロジェクト: willsongrui/voice
from voice import Voice
import pylab as pl

m = Voice()
m.analyze('../luyin/moni-2.wav')

print m.speech_segment
pl.subplot(311)
pl.plot(m.volume)
pl.subplot(312)
pl.plot(m.zcr)
pl.subplot(313)
pl.plot(m.acf)
pl.show()
'''
m.calFeatures()
m.mood_predict()
m.callInfo()
m.report()
'''
コード例 #40
0
ファイル: test.py プロジェクト: limingli0707/voice
from voice import Voice 
import pylab as pl
m = Voice()
m.analyze('../luyin/moni-2.wav')

print m.speech_segment
pl.subplot(311)
pl.plot(m.volume)
pl.subplot(312)
pl.plot(m.zcr)
pl.subplot(313)
pl.plot(m.acf)
pl.show()
'''
m.calFeatures()
m.mood_predict()
m.callInfo()
m.report()
'''
コード例 #41
0
        recog = Hosts().getLocalAttr('recog')
        if recog['enabled']:
            hasPhrase = recog['phrase'] != ""
            if recog['engine']:
                from recogHandler import RecogHandler
                ThreadMgr().start(RecogHandler())

        if hasPhrase:
            phr = Hosts().getLocalAttr("phrase")

            if phr["enabled"]:
                ThreadMgr().start(PhraseHandler())

                if phr['voice']:
                    ThreadMgr().start(Voice())
            else:
                print("Warning: phrase requested but not enabled")

        midi = Hosts().getLocalAttr('midi')
        if midi['enabled']:
            Debug().p("%s: starting up midi %s" % (pname, midi))
            ThreadMgr().start(MidiHandler())

        while True:
            time.sleep(1)

    except ServiceExit:
        print("%s got signal" % pname)
        ThreadMgr().stopAll()
        gardenExit = 5
コード例 #42
0
ファイル: voicetest.py プロジェクト: 0x1001/jarvis
class VoiceTest(unittest.TestCase):
    def setUp(self):
        from voice import Voice

        self.voice = Voice()

    def test_sentence(self):
        from voice import VoiceException

        self.voice.speak("Hello how are you")
        self.voice.speak(["hello","how","are","you"])

        with self.assertRaises(VoiceException):
            self.voice.speak(None)

    def test_volume(self):
        self.voice.volume(0.1)
        self.voice.speak("dummy dummy")
        self.voice.volume(0.5)
        self.voice.speak("dummy dummy")
        self.voice.volume(1.0)
        self.voice.speak("dummy dummy")

    def test_volume_exception(self):
        from voice import VoiceException

        with self.assertRaises(VoiceException):
            self.voice.volume(None)

        with self.assertRaises(VoiceException):
            self.voice.volume(-1)

        with self.assertRaises(VoiceException):
            self.voice.volume(2)

        with self.assertRaises(VoiceException):
            self.voice.volume(2.0)

    def test_rate(self):
        self.voice.rate(200)
        self.voice.speak("Hello how are you")

    def test_rate_exception(self):
        from voice import VoiceException

        with self.assertRaises(VoiceException):
            self.voice.rate(-1)

        with self.assertRaises(VoiceException):
            self.voice.rate(None)
コード例 #43
0
ファイル: jarvis.py プロジェクト: 0x1001/jarvis
class Jarvis(object):
    """
        Main Jarivs class

        Attributes:
        _brain          - Brain object
        _body           - Body object
        _word_db        - Words database
        _traning_db     - Training database
        _stop_event     - Stop event
    """
    def __init__(self):
        from neural import LookUpTableBrain
        from body import Body
        from voice import Voice
        from neural import InnerVoice
        import threading

        self._brain = LookUpTableBrain()
        self._body = Body()
        self._voice = Voice()
        self._inner_voices = InnerVoice()
        self._inner_voices.jarvis(self)

        self._word_db = None
        self._traning_db = None

        self._stop_event = threading.Event()

    def respond(self,request):
        """
            This method responds to request

            Input:
            request     - Request (string)

            Returns:
            answer
        """
        from database import DataBaseException
        from database import WordParser
        from body import BodyException
        from neural import BrainException

        if self._word_db == None: raise JarvisException("Don't have dictionary.")

        try:
            request_coded = tuple(self._word_db.multipleWordId(WordParser(request).wordsList()))
        except DataBaseException as error: raise JarvisException("Don't understand: " + request + " . Error: " + str(error))

        try:
            thought_coded = self._brain.think(request_coded)
        except BrainException as error: raise JarvisException("Cannot replay to this request: " + request + " . Error: " + str(error))

        try:
            thought_tuple = self._word_db.multipleIdWord(thought_coded)
        except DataBaseException as error: raise JarvisException("Cannot replay to this request: " + request + " . Error: " + str(error))

        try:
            answer_tuple = self._body.do(thought_tuple)
        except BodyException as error: raise JarvisException("Cannot do this request: " + request + " . Error: " + str(error))

        answer = " ".join([word.getValue() for word in answer_tuple])

        self._voice.speak(answer)

        return answer

    def createWordsDataBase(self,builder):
        """
            This method sets words database

            Input:
            builder         - Word database builder

            Returns:
            Nothing
        """
        self._word_db = builder.generateDataBase()

    def createTrainingDataBase(self,builder):
        """
            This method builds traning database

            Input:
            builder         - Traning database builder

            Returns:
            Nothing
        """
        self._traning_db = builder.generateDataBase()

    def createInnerVoiceDatabase(self,builder):
        """
            This method builds internal voice database

            Input:
            builder     - Database builder

            Returns:
            Nothing
        """
        self._inner_voices.innerVoices(builder.generateDataBase())

    def createAbilitiesDataBase(self,builder):
        """
            This method builds abilities database

            Input:
            builder     - Abilities builder

            Returns:
            Nothing
        """
        builder.jarvis(self)
        self._body.abilitiesDataBase(builder.generateDataBase())

    def train(self):
        """
            Trains Jarvis brain

            Input:
            Nothing

            Returns:
            Nothing
        """
        from trainer import Trainer

        if self._word_db == None: raise JarvisException("Don't have dictionary.")
        if self._traning_db == None: raise JarvisException("Don't have traning database.")

        trainer = Trainer(self._word_db,self._traning_db)
        trainer.train(self._brain)

    def start(self):
        """
            This method starts Jarvis internals

            Input:
            Nothing

            Returns:
            Nothing
        """
        from neural import InnerVoiceException

        try: self._inner_voices.start()
        except InnerVoiceException as error: raise JarvisException(str(error))

        self._stop_event.wait()

    def stop(self):
        """
            This method stops Jarvis internals

            Input:
            Nothing

            Returns:
            Nothing
        """
        self._inner_voices.stop()
        self._stop_event.set()
コード例 #44
0
ファイル: train.py プロジェクト: limingli0707/voice
def train(diretory = config.root_dir):
	'''Train all the files in diretory 'luyin'

	The diretory is made up of two subdiretories named 'normal' and 'abnormal'.
	
	As a result , the script will generate 3 files:
	(1)scale : used for scale data by the svm command 'svm-scale -s filename > scale'
	(2)dataset_scaled : the scaled dataset for training
	(3)model : the svm model file 
	'''
	files = os.listdir(config.normal)
	dataset = config.dataset
	dataset_scaled = config.dataset_scaled
	scale = config.scale

	#fs = open(dataset,'a')

	for f in files:
		f = config.normal + f
		voice = Voice()
		voice.analyze(f)
		voice.calFeatures()
		voice.learn(dataset,'+1')
	files = os.listdir(config.abnormal)
	
	for f in files:
		f = config.abnormal + f
		voice = Voice()
		voice.analyze(f)
		voice.calFeatures()
		voice.learn(dataset,'-1')

	os.system('svm-scale -s %s %s > %s'%(scale,dataset,dataset_scaled))
	y,x = svm_read_problem(dataset_scaled)
	m = svm_train(y,x)
	svm_save_model(config.model,m)
コード例 #45
0
ファイル: sms.py プロジェクト: evalentini/phonity
	def send():
		voice=Voice()
		voice.login("*****@*****.**", "robots25")
		voice.send_sms(5512062642, "I am a machine")
コード例 #46
0
ファイル: sapi5.py プロジェクト: SeaRecluse/MinStore
 def _toVoice(self, attr):
     return Voice(attr.Id, attr.GetDescription())
コード例 #47
0
ファイル: main.py プロジェクト: G07cha/FMForBlind
#!/usr/bin/python

from voice import Voice
import keylogger
from fs import FS

v = Voice()
""" Mounting output to file system """
fs = FS(v.voiceOutput)

selectedItem = ''
""" Main loop """
while True:
    key = keylogger.getkey()

    if key == 'l':
        """ ls """
        fs.getOutput()(fs.scanDir())
    elif key == 'p':
        """ pwd """
        fs.getOutput()(fs.currentDir)
    elif key == 'n':
        """ cd """
        v.voiceOutput('Select folder to navigate')
        folder = v.selectFrom(['..'] + fs.scanDir(True))
        if folder:
            fs.navigate(folder)
    elif key == 'm':
        """ mkdir """
        while True:
            v.voiceOutput("Enter name for new folder")
コード例 #48
0
ファイル: train.py プロジェクト: willsongrui/voice
def train(diretory=config.root_dir):
    '''Train all the files in diretory 'luyin'

	The diretory is made up of two subdiretories named 'normal' and 'abnormal'.
	
	As a result , the script will generate 3 files:
	(1)scale : used for scale data by the svm command 'svm-scale -s filename > scale'
	(2)dataset_scaled : the scaled dataset for training
	(3)model : the svm model file 
	'''
    files = os.listdir(config.normal)
    dataset = config.dataset
    dataset_scaled = config.dataset_scaled
    scale = config.scale

    #fs = open(dataset,'a')

    for f in files:
        f = config.normal + f
        voice = Voice()
        voice.analyze(f)
        voice.calFeatures()
        voice.learn(dataset, '+1')
    files = os.listdir(config.abnormal)

    for f in files:
        f = config.abnormal + f
        voice = Voice()
        voice.analyze(f)
        voice.calFeatures()
        voice.learn(dataset, '-1')

    os.system('svm-scale -s %s %s > %s' % (scale, dataset, dataset_scaled))
    y, x = svm_read_problem(dataset_scaled)
    m = svm_train(y, x)
    svm_save_model(config.model, m)
コード例 #49
0
ファイル: robot.py プロジェクト: AneGithub/robot
def main():
    voice = Voice()
    baiduAPI = voiceAPI.BaiDuAPI()
    turlingAPI = voiceAPI.TurLingAPI()
    baiduAPI.getToken()

    while True:
        voice.recordVoice()
        recognition_result = baiduAPI.voiceRecognition()
        if recognition_result:
            if "退出对话" in recognition_result:
                break

            reply_result = turlingAPI.turlingReply(recognition_result)
            if reply_result:
                url = baiduAPI.voiceSynthesis(reply_result)
                voice.playVoice(url)
            else:
                url = baiduAPI.voiceSynthesis("对不起,获取回复失败")
                voice.playVoice(url)
                continue
        else:
            url = baiduAPI.voiceSynthesis("对不起,识别失败")
            voice.playVoice(url)
            continue

    url = baiduAPI.voiceSynthesis("退出成功")
    voice.playVoice(url)
コード例 #50
0
def analyze(filename):
	'''Analyze a voice file.

	Example:
		python analyze 'myfile'
	Return:
		The detailed infomation and the mood prediction result if success.
	The file should use its full path, and will be mood_predict by our program.
	The prediction is processed by svm-machine , model file and scale file should
	be generated by the script train.py, and no need to indicate. All you need is 
	to tell us which file or directory you want to predict.'''
	#print 'Analyzing %s'%filename
	m = Voice()
	try:
		m.analyze(filename)
		m.calFeatures()
		m.mood_predict()
		m.callInfo()
		m.report()
		print 'Analyze success'
	except Exception as e:
		print 'Analyze failed:'+ repr(e)
コード例 #51
0
ファイル: openallure.py プロジェクト: mak1e/Open-Allure-DS
def main():
    """Initialization and event loop"""

    # provide instructions and other useful information

    # initialize pyGame screen
    textRect = pygame.rect.Rect(0, 0, 640, 480)
    screenRect = pygame.rect.Rect(0, 0, 640, 480)
    pygame.init()
    pygame.display.set_caption(u"Open Allure")
    screen = pygame.display.set_mode(screenRect.size)
    if sys.platform != 'darwin':
        pygame.scrap.init()

    config = ConfigObj('openallure.cfg')

    # determine what language to use for string translations
    # this can be overridden in scripts
    gettext.install(domain='openallure', localedir='locale', unicode=True)
    try:
        language = config['Options']['language']
    except KeyError:
        language = 'en'
    if len(language) > 0 and language != 'en':
        mytrans = gettext.translation(u"openallure",
                                      localedir='locale',
                                      languages=[language],
                                      fallback=True)
        mytrans.install(unicode=True)  # must set explicitly here for Mac
    # language also determines which default systemVoice to use (Mac only)
    openallure.systemVoice = ''
    try:
        openallure.systemVoice = config['Voice'][language]
    except KeyError:
        pass

    # load initial question sequence from url specified in openallure.cfg file
    url = unicode(config['Source']['url'])
    if len(sys.argv) > 1 and 0 != len(sys.argv[1]):
        url = unicode(sys.argv[1])
    backgroundColor = eval(config['Colors']['background'])
    seq = QSequence(filename=url)
    try:
        openallure.systemVoice = config['Voice'][seq.language]
    except KeyError:
        pass

    # open database to track progress

    oadb = config['Data']['oadb']
    try:
        openallure.db = Base(oadb).open()
    except IOError:
        openallure.db = Base(oadb)
        openallure.db.create(('time',float), ('url',unicode), \
        ('q',int), ('a',int), ('cmd',unicode))

    # read configuration options
    delayTime = int(config['Options']['delayTime'])
    openallure.allowNext = int(config['Options']['allowNext'])

    # initialize chatbot
    openallure_chatbot = Chat(responses, reflections)
    chatHistory = []
    onChatHistory = -1

    # track when Open Allure has gained mouse focus
    openallure.gain = 1
    # mouse focus only matters when stickyBrowser is true (see openallure.cfg)
    openallure.stickBrowser = eval(config['Options']['stickyBrowser'])

    voice = Voice()

    margins = eval(config['Font']['margins'])
    text = OpenAllureText(margins)

    # start on first question of sequence
    # TODO: have parameter file track position in sequence at quit
    # and resume there on restart
    openallure.onQuestion = 0

    # initialize mode flags
    # Has new question from sequence been prepared?
    openallure.ready = False
    # Has question been openallure.stated (read aloud)?
    openallure.stated = False
    # Which question in sequence has been read aloud (to avoid re-reading it)?
    # Note: -1 indicates no question as valid questions start with 0
    openallure.statedq = -1
    # What choice (if any) has been highlighted by gesture or keyboard?
    highlight = 0
    # When was the statement of the question complete?
    delayStartTime = 0
    # Do we have an answer? what number is it (with 0 being first answer)?
    answer = -1
    # What questions have been shown (list)?
    # Note: This list is also checked to avoid re-stating a question
    openallure.questions = []
    # What has been typed in so far
    openallure.currentString = u""

    # Subprocesses
    #    graphViz = None
    #    openallure.showResponses = eval(config['GraphViz']['showResponses'])
    #    openallure.showText = eval(config['GraphViz']['showText'])
    #    openallure.showLabels = eval(config['GraphViz']['showLabels'])
    #    graphVizPath = config['GraphViz']['path']
    #if eval(config['GraphViz']['autoStart']):
    #    oagraph(seq,openallure.db,url,openallure.showText,openallure.showResponses,openallure.showLabels)
    #    graphViz = subprocess.Popen([graphVizPath,'oagraph.dot'])

    # Greetings
    #voice.speak('Hello')

    WELCOME_TEXT = [
        "",
        _(u"       Welcome to the Open Allure Dialog System."), "",
        _(u"       Keys:"),
        _(u"           Escape quits"),
        _(u"           Ctrl+I force input"),
        _(u"           Ctrl+R refresh"),
        _(u"           Ctrl+V paste"), "",
        _(u"       Commands:"),
        _(u"           exit"),
        _(u"           open <filename or url>"),
        _(u"           quit"),
        _(u"           return (resumes at last question)"),
        _(u"           show source (Mac only)"), ""
    ]

    for line in WELCOME_TEXT:
        print line

    runFlag = True
    while runFlag:

        if not openallure.ready:
            # prepare for question display
            openallure.question = seq.sequence[openallure.onQuestion]
            choiceCount, \
            questionText, \
            justQuestionText = text.buildQuestionText(openallure.question)
            #            if graphViz:
            #                # Create .dot file for new sequence
            #                graphViz.kill()
            #                oagraph(seq,openallure.db,url,openallure.showText,openallure.showResponses,openallure.showLabels)
            #                graphViz = subprocess.Popen([graphVizPath, 'oagraph.dot'])

            textRegions = text.writewrap(None, text.font,
                                         text.boundingRectangle,
                                         text.unreadColor, questionText[-1])

            # initialize pointers - no part of the question text
            # and none of the answers have been read aloud.
            # Note that question text is numbered from 0
            # while answers are numbered from 1.
            action = 0
            onAnswer = 0
            onText = 0
            openallure.stated = False
            if openallure.onQuestion in openallure.questions:
                openallure.stated = True

            # initialize selections - nothing has been highlighted
            # or previously selected as an answer
            answer = -1
            choice = (-1, 0)
            colorLevel = colorLevels = 12
            highlight = 0

            # initialize typed input
            openallure.currentString = u''

            # clear screen of last question
            screen.fill(backgroundColor, rect=textRect)

            # wait for prior speaking to finish
            if voice.pid_status > 0:
                try:
                    os.waitpid(voice.pid_status, 0)[1]
                except:
                    pass
                voice.pid_status = 0
            openallure.ready = True

            # clear any previous response
            nltkResponse = ''

            # start with gain
            openallure.gain = 1

            # arrival record for new question
            record_id = openallure.db.insert(time = time.time(), \
            url = unicode(url), q = openallure.onQuestion)

        # make sure currentString has been added to questionText
        if openallure.currentString:
            questionText[choiceCount] = questionText[choiceCount - 1] + \
                                          "\n" + openallure.currentString

        # get keyboard and mouse input
        mouseButtonDownEvent = False
        mouseButtonDownEventY = 0
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONDOWN:
                mouseButtonDownEvent = True
                YCOORDINATE = 1
                mouseButtonDownEventY = event.pos[YCOORDINATE]
            if event.type == pygame.QUIT   \
               or (event.type == pygame.KEYDOWN and    \
                   event.key == pygame.K_ESCAPE):
                #               if graphViz:
                #                   graphViz.kill()
                runFlag = False

            # Trap and quit on Ctrl + C
            elif (event.type == pygame.KEYDOWN and event.key == pygame.K_c
                  and pygame.key.get_mods() & pygame.KMOD_CTRL):
                return

            # Trap Ctrl + I to force input
            elif (event.type == pygame.KEYDOWN and event.key == pygame.K_i
                  and pygame.key.get_mods() & pygame.KMOD_CTRL):
                # Note: This kills the entire current sequence.
                # The return command gives a way to back to it.
                seq.inputs = [_(u"Input"), _(u"[input];")]
                seq.sequence = seq.regroup(seq.inputs, \
                               seq.classify(seq.inputs))
                openallure.onQuestion = 0
                url = _(u'[input]')
                # record call to input
                record_id = openallure.db.insert(time = time.time(), \
                            url = unicode(url), q = 0)
                openallure.ready = False

            # Trap and paste clipboard on Ctrl + V for Mac
            elif (event.type == pygame.KEYDOWN and event.key == pygame.K_v
                  and pygame.key.get_mods() & pygame.KMOD_CTRL):
                if sys.platform == 'darwin':
                    os.system('pbpaste > clipboard')
                    clipboard = open('clipboard').readlines()
                    if clipboard[0].startswith(u"http://") or \
                       clipboard[0].find(u"http://"):
                        openallure.currentString += clipboard[0]
                else:
                    clipboard = pygame.scrap.get(pygame.SCRAP_TEXT)
                    if clipboard.startswith(u"http://") or \
                       clipboard.find(u"http://"):
                        openallure.currentString += clipboard

            # Trap Ctrl + - (minus) to decrease font size
            elif (event.type == pygame.KEYDOWN and event.key == pygame.K_MINUS
                  and pygame.key.get_mods() & pygame.KMOD_CTRL):
                text.fontSize -= 5
                text.font = pygame.font.SysFont( text.fontName, \
                text.fontSize )

            # Trap Ctrl + + (plus) to increase font size
            elif (event.type == pygame.KEYDOWN and event.key == pygame.K_EQUALS
                  and pygame.key.get_mods() & pygame.KMOD_CTRL):
                text.fontSize += 5
                text.font = pygame.font.SysFont( text.fontName, \
                text.fontSize )

            # Trap Ctrl + R to refresh from url without changing question number
            elif (event.type == pygame.KEYDOWN and event.key == pygame.K_r
                  and pygame.key.get_mods() & pygame.KMOD_CTRL):
                # if url is nltkRespose.txt, look back for something else
                # worth refreshing
                if url == u'nltkResponse.txt':
                    for id in range(record_id - 1, -1, -1):
                        record = openallure.db[id]
                        if not record.url in (url, \
                                              u'nltkResponse.txt', \
                                              _(u'[input]')):
                            url = record.url
                            break
                seq = QSequence(filename=url)
                try:
                    openallure.systemVoice = config['Voice'][seq.language]
                except KeyError:
                    pass
                openallure.ready = False

            # Define toggle keys and capture string inputs
            elif event.type == pygame.KEYDOWN:
                # Keys 1 through 6 select choices 1 through 6
                if event.key in range(pygame.K_1, pygame.K_6) and \
                    (not openallure.question[INPUTFLAG][choiceCount - 1] == 1 or
                    (openallure.question[INPUTFLAG][choiceCount - 1] == 1 and
                    openallure.currentString == u'')):
                    answer = event.key - pygame.K_1
                    if answer < choiceCount:
                        # Record choice along with destination, if any
                        record_id = openallure.db.insert(time = time.time(), \
                        url = unicode(url), q = openallure.onQuestion, \
                        a = answer, cmd = unicode(openallure.question[DESTINATION][answer]))
                        #                            if graphViz:
                        #                                graphViz.kill()
                        #                                oagraph(seq,openallure.db,url,openallure.showText,openallure.showResponses,openallure.showLabels)
                        #                                graphViz = subprocess.Popen([graphVizPath, 'oagraph.dot'])
                        choice = (answer + 1, 0)
                        colorLevel = 0
                        # Update screen to reflect choice
                        text.paintText(screen, justQuestionText, onText,
                                       questionText, onAnswer, highlight,
                                       openallure.stated, choice, colorLevel,
                                       colorLevels)
                        pygame.display.flip()
                    else:
                        answer = -1

                elif event.key == pygame.K_F6:
                    # reveal all the attributes of openallure
                    print "\nCurrent values of openallure object variables:\n"
                    for item in openallure.__dict__:
                        print item + ":", openallure.__dict__[item]
                    # drop into interpreter for debugging
                    print "\n   Press Ctrl+D to close console and resume. " + \
                    "Enter exit() to exit.\n"
                    import code
                    code.interact(local=locals())

                # Allow space to silence reading of question
                # unless there is an input (which might require a space)
                elif event.key == pygame.K_SPACE and \
                not openallure.question[INPUTFLAG][choiceCount - 1] == 1:
                    # Silence reading of question
                    openallure.stated = True

                elif event.key == pygame.K_RIGHT and openallure.allowNext:
                    # Choice is first non-zero entry
                    # in openallure.question[ACTION]
                    onChoice = 0
                    for i in openallure.question[ACTION]:
                        onChoice += 1
                        if not i == 0:
                            answer = onChoice - 1
                            record_id = openallure.db.insert(time = time.time(), \
                            url = unicode(url), q = openallure.onQuestion, \
                            a = answer, cmd = unicode(openallure.question[DESTINATION][answer]))
                            #                            if graphViz:
                            #                                graphViz.kill()
                            #                                oagraph(seq,openallure.db,url,openallure.showText,openallure.showResponses,openallure.showLabels)
                            #                                graphViz = subprocess.Popen([graphVizPath, 'oagraph.dot'])
                            choice = (onChoice, 0)
                            break
                    del onChoice

                elif event.key == pygame.K_LEFT:
                    if len(openallure.questions) > 0:
                        openallure.onQuestion = openallure.questions.pop()
                        openallure.ready = False
                    else:
                        openallure.onQuestion = 0

                elif event.key == pygame.K_UP:
                    if len(chatHistory) > 0 and onChatHistory > 0:
                        onChatHistory -= 1
                        openallure.currentString = chatHistory[onChatHistory]
                elif event.key == pygame.K_DOWN:
                    if len(chatHistory) > 0 and \
                    onChatHistory < len(chatHistory) - 1:
                        onChatHistory += 1
                        openallure.currentString = chatHistory[onChatHistory]

                elif event.key == pygame.K_RETURN:
                    if openallure.currentString:
                        # add to history
                        chatHistory.append(openallure.currentString)
                        onChatHistory = len(chatHistory)
                        # record input string
                        record_id = openallure.db.insert(time = time.time(), \
                                    url = unicode(url), q = openallure.onQuestion, \
                                    a = answer, cmd = openallure.currentString)
                        # Check for rules from script at end of question 0
                        if len(seq.sequence[0]) > 9:
                            scriptRules = seq.sequence[0][RULE]
                        else:
                            scriptRules = None
                        nltkResponse, \
                        nltkType, \
                        nltkName = \
                        openallure_chatbot.respond(openallure.currentString, \
                                                   scriptRules)

                        # Act on commands
                        if nltkType == 'goto' or \
                          (nltkType == 'text' and nltkName == 'what now'):
                            # find question with goto tag = ruleName or
                            # currentString (if it didn't match anything else)
                            if openallure.question[QUESTION] == [_(u"Input")]:
                                # Back up to first non-Input, non-Sorry question
                                for id in range(record_id - 1, -1, -1):
                                    try:
                                        record = openallure.db[id]
                                        if not record.url in (
                                                url, u'nltkResponse.txt',
                                                _(u'[input]')):
                                            seq = QSequence(filename = record.url, \
                                                    path = seq.path, \
                                                    nltkResponse = nltkResponse)
                                            try:
                                                openallure.systemVoice = config[
                                                    'Voice'][seq.language]
                                            except KeyError:
                                                pass
                                            url = record.url
                                            openallure.onQuestion = record.q
                                            openallure.ready = False
                                            break
                                    except:
                                        pass
                            tags = [question[TAG] for question in seq.sequence]
                            if nltkName in tags:
                                openallure.onQuestion = tags.index(nltkName)
                                openallure.ready = False
                            if nltkName== 'what now' and \
                               openallure.currentString.lower() in tags:
                                if openallure.onQuestion != \
                                        tags.index(openallure.currentString):
                                    openallure.questions.append(
                                        openallure.onQuestion)
                                    openallure.onQuestion = \
                                        tags.index(openallure.currentString)
                                    openallure.ready = False
                            # If still no luck finding a match, use currentString
                            # to search all through the text of all the questions
                            if openallure.ready:
                                for qnum, question in enumerate(seq.sequence):
                                    # search in question text and non-Input answer text
                                    nonInputAnswerText = [answer for answer,input in \
                                                          itertools.izip(question[ANSWER],
                                                                         question[INPUTFLAG]) if not input]
                                    qtext = " ".join(question[QUESTION]) + " " + \
                                            " ".join(nonInputAnswerText)
                                    if qtext.lower().find(
                                            openallure.currentString.lower(
                                            )) > -1:
                                        if openallure.onQuestion != qnum:
                                            openallure.questions.append(
                                                openallure.onQuestion)
                                            openallure.onQuestion = qnum
                                            openallure.ready = False
                                            break

                        if nltkType == 'quit':
                            #TODO: Make this more polite
                            #                            if graphViz:
                            #                                graphViz.kill()
                            raise SystemExit

                        if nltkType == 'return':
                            # Find first different sequence in db, walking back
                            for id in range(record_id - 1, -1, -1):
                                try:
                                    record = openallure.db[id]
                                    if not record.url in (url,
                                                          u'nltkResponse.txt',
                                                          _(u'[input]')):
                                        seq = QSequence(filename = record.url, \
                                                path = seq.path, \
                                                nltkResponse = nltkResponse)
                                        try:
                                            openallure.systemVoice = config[
                                                'Voice'][seq.language]
                                        except KeyError:
                                            pass
                                        url = record.url
                                        openallure.onQuestion = record.q
                                        openallure.ready = False
                                        #                                        if graphViz:
                                        #                                            # Fall through into graphing
                                        #                                            nltkType = 'graph'
                                        #                                            nltkName = 'show'
                                        break
                                except:
                                    pass
                            nltkResponse = u''
                            openallure.currentString = u''

                        if nltkType == 'open':
                            # Reset stated question pointer for new sequence
                            openallure.statedq = -1
                            path = seq.path
                            linkStart = nltkResponse.find(u'[')
                            linkEnd = nltkResponse.find(u']', linkStart)
                            url = nltkResponse[linkStart + 1:linkEnd]
                            seq = QSequence(filename=url,
                                            path=path,
                                            nltkResponse=nltkResponse)
                            try:
                                openallure.systemVoice = config['Voice'][
                                    seq.language]
                            except KeyError:
                                pass
                            openallure.questions = []
                            openallure.onQuestion = 0
                            openallure.ready = False
                            #                            if graphViz:
                            #                                # Fall through into graphing
                            #                                nltkType = 'graph'
                            #                                nltkName = 'show'
                            nltkResponse = u''
                            openallure.currentString = u''

                        if nltkType == 'show':
                            # use open (Mac only) to view source
                            if sys.platform == 'darwin':
                                # Find first non-[input] sequence in db, walking back
                                for id in range(record_id - 1, -1, -1):
                                    record = openallure.db[id]
                                    if record.url.find('.txt') > 0 or \
                                       record.url.find('http:') == 0 :
                                        if not record.url == 'nltkResponse.txt':
                                            url = record.url
                                            break
                                os.system("open " + url)

                        # if nltkResponse is one line containing a semicolon,
                        # replace the semicolon with \n
                        if nltkResponse.find('\n') == -1:
                            nltkResponse = nltkResponse.replace(';', '\n')

                        if nltkResponse:
                            answer = choiceCount - 1
                            choice = (choiceCount, 0)
                    else:
                        # This takes last response
                        answer = choiceCount - 1
                        choice = (choiceCount, 0)

                elif event.key == pygame.K_BACKSPACE and \
                openallure.question[INPUTFLAG][choiceCount - 1] == 1:
                    openallure.currentString = openallure.currentString[0:-1]
                    openallure.question[ANSWER][choiceCount - 1] = \
                    openallure.currentString
                    questionText[choiceCount] = \
                    questionText[choiceCount - 1] + \
                    u"\n" + openallure.currentString
                    screen.fill(backgroundColor, rect=textRect)

                elif event.key <= 127 and \
                openallure.question[INPUTFLAG][-1] == 1:
                    # p rint event.key
                    mods = pygame.key.get_mods()
                    if mods & pygame.KMOD_SHIFT:
                        if event.key in range(47, 60):
                            openallure.currentString += \
                            (u'?', u')', u'!', u'@', u'#', u'$', u'%', u'^', \
                            u'&', u'*', u'(', u'', u':')[range(47, 60).index(event.key)]
                        elif event.key == 45:
                            openallure.currentString += u"_"
                        elif event.key == 61:
                            openallure.currentString += u"+"
                        elif event.key == 96:
                            openallure.currentString += u"~"
                        else:
                            openallure.currentString += \
                                unicode(chr(event.key).upper())
                    else:
                        openallure.currentString += unicode(chr(event.key))
#                    openallure.question[ANSWER][choiceCount - 1] = \
#                        openallure.currentString
# Add currentString to text being displayed
                    questionText[choiceCount] = \
                        questionText[choiceCount - 1] + \
                        u"\n" + openallure.currentString
                    screen.fill(backgroundColor, rect=textRect)

        # check for automatic page turn
        if openallure.ready and \
           openallure.stated == True and \
           not openallure.currentString and \
           openallure.question[ANSWER][-1] == _(u'[next]') and \
           pygame.time.get_ticks() - delayStartTime > delayTime:
            # This takes last response
            answer = choiceCount - 1
            choice = (choiceCount, 0)

        if openallure.statedq == openallure.onQuestion:
            openallure.stated = True

        if openallure.ready and not openallure.stated:
            # work through statement of question
            # speaking each part of the question and each of the answers
            # (unless the process is cut short by other events)
            if onText == 0:
                screen.fill(backgroundColor, rect=textRect)
                pygame.display.flip()

            # Stop when onAnswer pointer is beyond length of answer list
            if onAnswer > len(openallure.question[ANSWER]):
                openallure.stated = True
                openallure.statedq = openallure.onQuestion

            else:
                # Speak each answer
                #(but only after speaking the full question below)
                if onAnswer > 0 and onAnswer < len(
                        openallure.question[ANSWER]) + 1:
                    answerText = openallure.question[ANSWER][onAnswer - 1]
                    if not (answerText.startswith(_('[input]'))
                            or answerText.startswith(_('[next]'))
                            or answerText.endswith('...]')
                            or answerText.endswith('...')):
                        if len(answerText) > 0:
                            # Check for answer with "A. "
                            if answerText[1:3] == '. ':
                                voice.speak(answerText[3:].strip(),
                                            openallure.systemVoice)
                            else:
                                voice.speak(answerText.strip(),
                                            openallure.systemVoice)
                        del answerText

                # Speak each part of the question using onText pointer
                # to step through parts of question list
                if onText < len(openallure.question[QUESTION]):
                    if not (openallure.question[QUESTION][onText].endswith(
                            '...')):
                        if len(openallure.question[QUESTION][onText]) > 0:
                            # speak the current part of the question
                            voice.speak(openallure.question[QUESTION][onText],
                                        openallure.systemVoice)

        if answer < 0 and openallure.ready:

            # Trap mouse click on text region
            textRegions = text.writewrap(None, \
                                         text.font, \
                                         text.boundingRectangle, \
                                         text.unreadColor, \
                                         questionText[-1])

            # Create list where each element indicates with 1 or 0
            # whether Y coordinate is in the region
            regions = [
                inRegion(region, mouseButtonDownEventY)
                for region in textRegions
            ]

            # Find which region has a 1, if any
            if 1 in regions:
                onRegion = regions.index(1)
            else:
                onRegion = 0

            if onRegion > 0:
                if mouseButtonDownEvent:
                    answer = onRegion - 1
                    if answer < choiceCount:
                        # record selection of answer
                        record_id = openallure.db.insert(time = time.time(), \
                        url = unicode(url), q = openallure.onQuestion, \
                        a = answer)
                        #                        if graphViz and openallure.question[ACTION][answer] == 0:
                        #                            # Create .dot file for one sequence in response to answer in place
                        #                            graphViz.kill()
                        #                            oagraph(seq,openallure.db,url,openallure.showText,openallure.showResponses,openallure.showLabels)
                        #                            graphViz = subprocess.Popen([graphVizPath, 'oagraph.dot'])
                        choice = (answer + 1, 0)
                        colorLevel = 0
                        # Update screen to reflect choice


#                         text.paintText(screen,
#                                        justQuestionText, onText,
#                                        questionText, onAnswer,
#                                        highlight,
#                                        openallure.stated,
#                                        choice,
#                                        colorLevel, colorLevels)
#                         pygame.display.flip()
                    else:
                        answer = -1
                else:
                    highlight = onRegion
                    # Update screen to reflect highlight
                    #                     text.paintText(screen,
                    #                                    justQuestionText, onText,
                    #                                    questionText, onAnswer,
                    #                                    highlight,
                    #                                    openallure.stated,
                    #                                    choice,
                    #                                    colorLevel, colorLevels)
                    #                     pygame.display.flip()
                    colorLevel -= 1
                    colorLevel = max(colorLevel, 0)
            else:
                highlight = 0
                colorLevel = colorLevels

            # block non-choices
            if choice[0] < 0 or choice[0] > len(questionText) - 1:
                choice = (-1, 0)

            screen.fill(backgroundColor, rect=textRect)
            text.paintText(screen, justQuestionText, onText, questionText,
                           onAnswer, highlight, openallure.stated, choice,
                           colorLevel, colorLevels)
            # and move on to the next part
            # (which needs to be displayed while being spoken)
            onText += 1
            # once all the parts of the question are done,
            # start working through answers
            if onAnswer > 0:
                onAnswer += 1
            if onText == len(openallure.question[QUESTION]):
                onAnswer = 1
                # Take note of time for automatic page turns
                delayStartTime = pygame.time.get_ticks()

            pygame.display.flip()

        elif not choice == (-1, 0) and openallure.ready:

            openallure.stated = True

            # respond to choice when something has been typed and entered
            if openallure.currentString:
                if len(nltkResponse) == 0:
                    choice = (-1, 0)
                    answer = -1
                    voice.speak(_("Try again"), openallure.systemVoice)
                else:
                    voice.speak(
                        _(u"You entered ") + openallure.currentString,
                        openallure.systemVoice)
                # Reset string
                openallure.currentString = u''

            # check whether a link is associated with this answer and,
            # if so, follow it
            if len(openallure.question[LINK]
                   ) and openallure.question[LINK][answer]:
                webbrowser.open_new_tab(openallure.question[LINK][answer])
                # wait in loop until window (re)gains focus
                if openallure.stickBrowser:
                    openallure.gain = 0
                    while not openallure.gain:
                        for event in pygame.event.get():
                            if event.type == pygame.ACTIVEEVENT:
                                openallure.gain = event.gain

            #check that response exists for answer
            if len(openallure.question[RESPONSE]) and \
               answer < len(openallure.question[RESPONSE]) and \
                (isinstance(openallure.question[RESPONSE][answer], str) or \
                isinstance(openallure.question[RESPONSE][answer], unicode)):
                #speak response to answer
                voice.speak(openallure.question[RESPONSE][answer].strip(),
                            openallure.systemVoice)

            #check that next sequence exists as integer for answer
            if len(openallure.question[ACTION]) and \
            answer < len(openallure.question[ACTION]) and \
            isinstance(openallure.question[ACTION][answer], int):
                #get new sequence or advance in sequence
                action = openallure.question[ACTION][answer]
                if len(openallure.question[DESTINATION][answer]) > 0 and \
                not openallure.question[ANSWER][answer] == _(u'[next]'):
                    # speak("New source of questions")
                    # Reset stated question pointer for new sequence
                    openallure.statedq = -1
                    path = seq.path
                    url = openallure.question[DESTINATION][answer]
                    seq = QSequence(filename=url,
                                    path=path,
                                    nltkResponse=nltkResponse)
                    try:
                        openallure.systemVoice = config['Voice'][seq.language]
                    except KeyError:
                        pass
                    openallure.onQuestion = 0
                    openallure.questions = []
                else:
                    # Add last question to stack (if not duplicate) and move on
                    if action > 0:
                        openallure.questions.append(openallure.onQuestion)
                        openallure.onQuestion = openallure.onQuestion + action

                    elif action < 0:
                        openallure.onQuestion = max(
                            0, openallure.onQuestion + action)

                    # Quit if advance goes beyond end of sequence
                    if openallure.onQuestion >= len(seq.sequence):
                        voice.speak(_("You have reached the end. Goodbye."),
                                    openallure.systemVoice)
                        return

                openallure.ready = False