コード例 #1
0
    def received_plist(self, plist):
        self.logger.debug("Got packet with class: {0}".format(plist['class']))
        self.logger.debug("packet with content:\n{0}".format(pprint.pformat(plist, width=40)))
        
        # first handle speech stuff
        
        if 'refId' in plist:
            # if the following holds, this packet is an answer to a request by a plugin
            if plist['refId'] == self.plugin_lastAceId and self.current_running_plugin != None:
                if self.current_running_plugin.waitForResponse != None:
                    # just forward the object to the 
                    # don't change it's refId, further requests must reference last FinishSpeech
                    self.logger.debug("Forwarding object to plugin")
                    self.plugin_lastAceId = None
                    self.current_running_plugin.response = plist if plist['class'] != "StartRequest" else plist['properties']['utterance']
                    self.current_running_plugin.waitForResponse.set()
                    return
        
        if ObjectIsCommand(plist, StartSpeechRequest) or ObjectIsCommand(plist, StartSpeechDictation):
            self.logger.debug("New start of speech received")
            startSpeech = None
            if ObjectIsCommand(plist, StartSpeechDictation):
                dictation = True
                startSpeech = StartSpeechDictation(plist)
            else:
                dictation = False
                startSpeech = StartSpeechRequest(plist)
    
            decoder = speex.Decoder()
            encoder = flac.Encoder()
            speexUsed = False
            if startSpeech.codec == StartSpeech.CodecSpeex_WB_Quality8Value:
                decoder.initialize(mode=speex.SPEEX_MODEID_WB)
                encoder.initialize(16000, 1, 16)
                speexUsed = True
            elif startSpeech.codec == StartSpeech.CodecSpeex_NB_Quality7Value:
                decoder.initialize(mode=speex.SPEEX_MODEID_NB)
                encoder.initialize(16000, 1, 16)
                speexUsed = True
            elif startSpeech.codec == StartSpeech.CodecPCM_Mono_16Bit_8000HzValue:
                encoder.initialize(8000, 1, 16)
            elif startSpeech.codec == StartSpeech.CodecPCM_Mono_16Bit_11025HzValue:
                encoder.initialize(11025, 1, 16)
            elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_16000HzValue:
                encoder.initialize(16000, 1, 16)
            elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_22050HzValue:
                encoder.initialize(22050, 1, 16)
            elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_32000HzValue:
                encoder.initialize(32000, 1, 16)
            # we probably need resampling for sample rates other than 16kHz...
            
            self.speech[startSpeech.aceId] = (decoder if speexUsed else None, encoder, dictation)
        
        elif ObjectIsCommand(plist, SpeechPacket):
            self.logger.debug("Decoding speech packet")
            speechPacket = SpeechPacket(plist)
            if speechPacket.refId in self.speech:
                (decoder, encoder, dictation) = self.speech[speechPacket.refId]
                if decoder:
                    pcm = decoder.decode(speechPacket.packets)
                else:
                    pcm = SpeechPacket.data # <- probably data... if pcm
                encoder.encode(pcm)
            else:
                self.logger.debug("Got a speech packet that did not match any current request")
                
        elif plist['class'] == 'StartCorrectedSpeechRequest':
            self.process_recognized_speech({u'hypotheses': [{'confidence': 1.0, 'utterance': plist['properties']['utterance']}]}, plist['aceId'], False)
    
        elif ObjectIsCommand(plist, FinishSpeech):
            self.logger.debug("End of speech received")
            finishSpeech = FinishSpeech(plist)
            if finishSpeech.refId in self.speech:
                (decoder, encoder, dictation) = self.speech[finishSpeech.refId]
                if decoder:
                    decoder.destroy()
                flacBin = None
                if encoder:
                    encoder.finish()
                    flacBin = encoder.getBinary()
                    encoder.destroy()
                del self.speech[finishSpeech.refId]
                if flacBin != None:
                    self.logger.info("Sending flac to google for recognition")
                    try:
                        self.current_google_request = self.httpClient.make_google_request(flacBin, finishSpeech.refId, dictation, language=self.assistant.language, allowCurses=True)
                    except (AttributeError, TypeError):
                        self.logger.warning("Unable to find language record for this assistant. Try turning Siri off and then back on.")
                else:
                    self.logger.info("There was no speech")
            else:
                self.logger.debug("Got a finish speech packet that did not match any current request")
                
        elif ObjectIsCommand(plist, CancelRequest):
            # this is probably called when we need to kill a plugin
            # wait for thread to finish a send
            self.logger.debug("Should cancel current request")
            cancelRequest = CancelRequest(plist)
            if cancelRequest.refId in self.speech:
                (decoder, encoder, dictation) = self.speech[cancelRequest.refId]
                if decoder:
                    decoder.destroy()
                if encoder:
                    encoder.finish()
                    encoder.destroy()
                del self.speech[cancelRequest.refId]
            if self.current_google_request != None:
                self.current_google_request.cancel()
                # if a google request is running (follow up listening..., plugin might get killed there by user)
                if self.current_running_plugin != None:
                    if self.current_running_plugin.waitForResponse != None:
                        self.current_running_plugin._abortPluginRun()
                        self.current_running_plugin.waitForResponse.set()
                        
            # if a plugin is running (processing, but not waiting for data from the device we kill it)   
            if self.current_running_plugin != None:
                if self.current_running_plugin.waitForResponse == None:
                    self.current_running_plugin._abortPluginRun()     
            
            self.send_object(CancelSucceeded(cancelRequest.aceId))
            
        elif ObjectIsCommand(plist, RollbackRequest):
            pass
        
        elif ObjectIsCommand(plist, SyncChunk):
            chunk = SyncChunk(plist)
            previous = self.syncAnchors[chunk.key] if chunk.key in self.syncAnchors else None
            if previous != None:
                if previous.generation != chunk.preGen:
                    chunkDenied = SyncChunkDenied(chunk.aceId)
                    self.send_object(chunkDenied)
                    return 
            current = SyncAnchor()
            current.generation = chunk.postGen
            current.value = chunk.postGen
            current.validity = chunk.validity
            current.key = chunk.key
            self.syncAnchors[current.key] = current
            chunkAccepted = SyncChunkAccepted(chunk.aceId)
            chunkAccepted.current = current
            self.send_object(chunkAccepted)
            pass

        elif ObjectIsCommand(plist, GetSessionCertificate):
            getSessionCertificate = GetSessionCertificate(plist)
            sessionCA_DER = crypto.dump_certificate(crypto.FILETYPE_ASN1, self.server.sessionCACert)
            sessionCert_DER = crypto.dump_certificate(crypto.FILETYPE_ASN1, self.server.sessionCert)
            response = GetSessionCertificateResponse(getSessionCertificate.aceId, sessionCA_DER, sessionCert_DER)
            self.send_object(response)

        elif ObjectIsCommand(plist, CreateSessionInfoRequest):
            # how does a positive answer look like?
            createSessionInfoRequest = CreateSessionInfoRequest(plist)
            
            #success = CreateSessionInfoResponse(createSessionInfoRequest.aceId)
            #success.sessionInfo = biplist.Data("\x01\x02BLABLABLBALBALBALBALBALBALBALBA")
            #success.validityDuration = 9600
            
            #self.send_object(success)
            fail = CommandFailed(createSessionInfoRequest.aceId)
            fail.reason = "Not authenticated"
            fail.errorCode = 0
            self.send_object(fail)

            ##self.send_plist({"class":"SessionValidationFailed", "properties":{"errorCode":"UnsupportedHardwareVersion"}, "aceId": str(uuid.uuid4()), "refId":plist['aceId'], "group":"com.apple.ace.system"})
            
        elif ObjectIsCommand(plist, CreateAssistant):
            createAssistant = CreateAssistant(plist)
            #create a new assistant
            helper = Assistant()     
            helper.assistantId = str.upper(str(uuid.uuid4()))
            helper.language = createAssistant.language
            helper.activationToken = createAssistant.activationToken
            helper.connectionType = createAssistant.connectionType
            helper.validationData = createAssistant.validationData
            c = self.dbConnection.cursor()
            noError = True
            try:
                c.execute("insert into assistants(assistantId, assistant) values (?,?)", (helper.assistantId, helper))
                self.dbConnection.commit()
            except sqlite3.Error: 
                noError = False
            c.close()
            if noError:
                self.assistant = helper
                assiCreatedCMD = AssistantCreated(createAssistant.aceId)
                assiCreatedCMD.assistantId = helper.assistantId
                assiCreatedCMD.speechId = str(uuid.uuid4())
                self.send_object(assiCreatedCMD)
            else:
                cmdFailed = CommandFailed(createAssistant.aceId)
                cmdFailed.reason = "Database Error"
                cmdFailed.errorCode = 2
                self.send_object(cmdFailed)
            
        elif ObjectIsCommand(plist, SetAssistantData):
            setAssistantData = SetAssistantData(plist)
            # fill assistant 
            if self.assistant != None:
                try:
                    c = self.dbConnection.cursor()
                    assi_id = self.assistant.assistantId
                    self.assistant.initializeFromPlist(setAssistantData.to_plist())
                    self.assistant.assistantId = assi_id
                    #Record the user firstName and nickName                    
                    try:                        
                        self.assistant.firstName = self.assistant.meCards[0].firstName.encode("utf-8")
                    except:
                        self.assistant.firstName = u''                        
                    try:                        
                        self.assistant.nickName = self.assistant.meCards[0].nickName.encode("utf-8")       
                    except:
                        self.assistant.nickName = u''
                    #Done recording
                    c.execute("update assistants set assistant = ? where assistantId = ?", (self.assistant, self.assistant.assistantId))
                    self.dbConnection.commit()
                    c.close()
                except:
                    cmdFailed = CommandFailed(setAssistantData.aceId)
                    cmdFailed.reason = "Database Error"
                    cmdFailed.errorCode = 2
                    self.send_object(cmdFailed)
                    self.logger.exception("Database Error on setting assistant data")
            else:
                cmdFailed = CommandFailed(setAssistantData.aceId)
                cmdFailed.reason = "Assistant to set data not found"
                cmdFailed.errorCode = 2
                self.send_object(cmdFailed)
                self.logger.warning("Trying to set assistant data without having a valid assistant")
                
        elif ObjectIsCommand(plist, LoadAssistant):
            loadAssistant = LoadAssistant(plist)
            try:
                c = self.dbConnection.cursor()
                c.execute("select assistant from assistants where assistantId = ?", (loadAssistant.assistantId,))
                self.dbConnection.commit()
                result = c.fetchone()
                if result == None:
                    self.send_object(AssistantNotFound(loadAssistant.aceId))
                    self.logger.warning("Assistant not found in database!!")                        
                else:
                    self.assistant = result[0]
                    #update assistant from LoadAssistant
                    self.assistant.language = loadAssistant.language
                    self.assistant.connectionType = loadAssistant.connectionType
                    
                    if self.assistant.language == '' or self.assistant.language == None:
                        self.logger.error ("No language is set for this assistant")                        
                        c.execute("delete from assistants where assistantId = ?", (plist['properties']['assistantId'],))
                        self.dbConnection.commit()
                        cmdFailed = CommandFailed(loadAssistant.aceId)
                        cmdFailed.reason = "Database error Assistant not found or language settings"
                        cmdFailed.errorCode = 2
                        self.send_object(cmdFailed)
                    else:                        
                        loaded = AssistantLoaded(loadAssistant.aceId)
                        loaded.version = "20111216-32234-branches/telluride?cnxn=293552c2-8e11-4920-9131-5f5651ce244e"
                        loaded.requestSync = 0
                        try:
                            loaded.dataAnchor = self.assistant.anchor
                        except:
                            loaded.dataAnchor = "removed"
                        self.send_object(loaded)
                c.close()
            except:
                self.send_object(AssistantNotFound(loadAssistant.aceId))
                self.logger.warning("Database error on fetching assistant")
                
        elif ObjectIsCommand(plist, DestroyAssistant):
            destroyAssistant = DestroyAssistant(plist)
            try:
                c = self.dbConnection.cursor()
                c.execute("delete from assistants where assistantId = ?", (plist['properties']['assistantId'],))
                self.dbConnection.commit()
                c.close()
                destroyed = AssistantDestroyed(destroyAssistant.aceId)
                destroyed.assistantId = destroyAssistant.assistantId
                self.send_object(destroyed)
            except:
                self.send_object(AssistantNotFound(destroyAssistant.aceId))
                self.logger.error("Database error on deleting assistant")
                
        elif ObjectIsCommand(plist, StartRequest):
            startRequest = StartRequest(plist)
            #this should also be handeled by special plugins, so lets call the plugin handling stuff
            self.process_recognized_speech({'hypotheses': [{'utterance': startRequest.utterance, 'confidence': 1.0}]}, startRequest.aceId, False)
        pass
コード例 #2
0
ファイル: siriServer.py プロジェクト: alexandred/SiriServer
    def process_compressed_data(self):
        self.unzipped_input += self.decompressor.decompress(self.data)
        self.data = ""
        while self.hasNextObj():
            reqObject = self.read_next_object_from_unzipped()
            if reqObject != None:
                self.logger.debug("Packet with class: {0}".format(reqObject['class']))
                self.logger.debug("packet with content:\n{0}".format(pprint.pformat(reqObject, width=40)))
                
                # first handle speech stuff
                
                if 'refId' in reqObject:
                    # if the following holds, this packet is an answer to a request by a plugin
                    if reqObject['refId'] == self.plugin_lastAceId and self.current_running_plugin != None:
                        if self.current_running_plugin.waitForResponse != None:
                            # just forward the object to the 
                            # don't change it's refId, further requests must reference last FinishSpeech
                            self.logger.info("Forwarding object to plugin")
                            self.plugin_lastAceId = None
                            self.current_running_plugin.response = reqObject
                            self.current_running_plugin.waitForResponse.set()
                
                if ObjectIsCommand(reqObject, StartSpeechRequest) or ObjectIsCommand(reqObject, StartSpeechDictation):
                    self.logger.info("New start of speech received")
                    startSpeech = None
                    if ObjectIsCommand(reqObject, StartSpeechDictation):
                        dictation = True
                        startSpeech = StartSpeechDictation(reqObject)
                    else:
                        dictation = False
                        startSpeech = StartSpeechRequest(reqObject)
            
                    decoder = speex.Decoder()
                    encoder = flac.Encoder()
                    speexUsed = False
                    if startSpeech.codec == StartSpeech.CodecSpeex_WB_Quality8Value:
                        decoder.initialize(mode=speex.SPEEX_MODEID_WB)
                        encoder.initialize(16000, 1, 16)
                        speexUsed = True
                    elif startSpeech.codec == StartSpeech.CodecSpeex_NB_Quality7Value:
                        decoder.initialize(mode=speex.SPEEX_MODEID_NB)
                        encoder.initialize(16000, 1, 16)
                        speexUsed = True
                    elif startSpeech.codec == StartSpeech.CodecPCM_Mono_16Bit_8000HzValue:
                        encoder.initialize(8000, 1, 16)
                    elif startSpeech.codec == StartSpeech.CodecPCM_Mono_16Bit_11025HzValue:
                        encoder.initialize(11025, 1, 16)
                    elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_16000HzValue:
                        encoder.initialize(16000, 1, 16)
                    elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_22050HzValue:
                        encoder.initialize(22050, 1, 16)
                    elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_32000HzValue:
                        encoder.initialize(32000, 1, 16)
                    # we probably need resampling for sample rates other than 16kHz...
                    
                    self.speech[startSpeech.aceId] = (decoder if speexUsed else None, encoder, dictation)
                
                elif ObjectIsCommand(reqObject, SpeechPacket):
                    self.logger.info("Decoding speech packet")
                    speechPacket = SpeechPacket(reqObject)
                    (decoder, encoder, dictation) = self.speech[speechPacket.refId]
                    if decoder:
                        pcm = decoder.decode(speechPacket.packets)
                    else:
                        pcm = SpeechPacket.data # <- probably data... if pcm
                    encoder.encode(pcm)
                        
                elif reqObject['class'] == 'StartCorrectedSpeechRequest':
                    self.process_recognized_speech({u'hypotheses': [{'confidence': 1.0, 'utterance': str.lower(reqObject['properties']['utterance'])}]}, reqObject['aceId'], False)
            
                elif ObjectIsCommand(reqObject, FinishSpeech):
                    self.logger.info("End of speech received")
                    finishSpeech = FinishSpeech(reqObject)
                    (decoder, encoder, dictation) = self.speech[finishSpeech.refId]
                    if decoder:
                        decoder.destroy()
                    encoder.finish()
                    flacBin = encoder.getBinary()
                    encoder.destroy()
                    del self.speech[finishSpeech.refId]
                    
                    self.logger.info("Sending flac to google for recognition")
                    self.httpClient.make_google_request(flacBin, finishSpeech.refId, dictation, language=self.assistant.language, allowCurses=True)
                        
                        
                elif ObjectIsCommand(reqObject, CancelRequest):
                        # this is probably called when we need to kill a plugin
                        # wait for thread to finish a send
                        cancelRequest = CancelRequest(reqObject)
                        if cancelRequest.refId in self.speech:
                            del self.speech[cancelRequest.refId]
                        
                        self.send_object(CancelSucceeded(cancelRequest.aceId))

                elif ObjectIsCommand(reqObject, GetSessionCertificate):
                    getSessionCertificate = GetSessionCertificate(reqObject)
                    response = GetSessionCertificateResponse(getSessionCertificate.aceId)
                    response.caCert = caCert.as_der()
                    response.sessionCert = serverCert.as_der()
                    self.send_object(response)

                elif ObjectIsCommand(reqObject, CreateSessionInfoRequest):
                    # how does a positive answer look like?
                    createSessionInfoRequest = CreateSessionInfoRequest(reqObject)
                    fail = CommandFailed(createSessionInfoRequest.aceId)
                    fail.reason = "Not authenticated"
                    fail.errorCode = 0
                    self.send_object(fail)

                    #self.send_plist({"class":"SessionValidationFailed", "properties":{"errorCode":"UnsupportedHardwareVersion"}, "aceId": str(uuid.uuid4()), "refId":reqObject['aceId'], "group":"com.apple.ace.system"})
                    
                elif reqObject['class'] == 'CreateAssistant':
                    #create a new assistant
                    helper = Assistant()
                    c = self.dbConnection.cursor()
                    noError = True
                    try:
                        c.execute("insert into assistants(assistantId, assistant) values (?,?)", (helper.assistantId, helper))
                        self.dbConnection.commit()
                    except sqlite3.Error, e: 
                        noError = False
                    c.close()
                    if noError:
                        self.assistant = helper
                        self.send_plist({"class": "AssistantCreated", "properties": {"speechId": str(uuid.uuid4()), "assistantId": helper.assistantId}, "group":"com.apple.ace.system", "callbacks":[], "aceId": str(uuid.uuid4()), "refId": reqObject['aceId']})
                    else:
                        self.send_plist({"class":"CommandFailed", "properties": {"reason":"Database error", "errorCode":2, "callbacks":[]}, "aceId": str(uuid.uuid4()), "refId": reqObject['aceId'], "group":"com.apple.ace.system"})
            
                elif reqObject['class'] == 'SetAssistantData':
                    # fill assistant 
                    if self.assistant != None:
                        c = self.dbConnection.cursor()
                        objProperties = reqObject['properties'] 
                        self.assistant.censorSpeech = objProperties['censorSpeech']
                        self.assistant.timeZoneId = objProperties['timeZoneId']
                        self.assistant.language = objProperties['language']
                        self.assistant.region = objProperties['region']
                        c.execute("update assistants set assistant = ? where assistantId = ?", (self.assistant, self.assistant.assistantId))
                        self.dbConnection.commit()
                        c.close()

            
                elif reqObject['class'] == 'LoadAssistant':
                    c = self.dbConnection.cursor()
                    c.execute("select assistant from assistants where assistantId = ?", (reqObject['properties']['assistantId'],))
                    self.dbConnection.commit()
                    result = c.fetchone()
                    if result == None:
                        self.send_plist({"class": "AssistantNotFound", "aceId":str(uuid.uuid4()), "refId":reqObject['aceId'], "group":"com.apple.ace.system"})
                    else:
                        self.assistant = result[0]
                        self.send_plist({"class": "AssistantLoaded", "properties": {"version": "20111216-32234-branches/telluride?cnxn=293552c2-8e11-4920-9131-5f5651ce244e", "requestSync":False, "dataAnchor":"removed"}, "aceId":str(uuid.uuid4()), "refId":reqObject['aceId'], "group":"com.apple.ace.system"})
                    c.close()

                elif reqObject['class'] == 'DestroyAssistant':
                    c = self.dbConnection.cursor()
                    c.execute("delete from assistants where assistantId = ?", (reqObject['properties']['assistantId'],))
                    self.dbConnection.commit()
                    c.close()
                    self.send_plist({"class": "AssistantDestroyed", "properties": {"assistantId": reqObject['properties']['assistantId']}, "aceId":str(uuid.uuid4()), "refId":reqObject['aceId'], "group":"com.apple.ace.system"})
                elif reqObject['class'] == 'StartRequest':
                    #this should also be handeled by special plugins, so lets call the plugin handling stuff
                    self.process_recognized_speech({'hypotheses': [{'utterance': reqObject['properties']['utterance'], 'confidence': 1.0}]}, reqObject['aceId'], False)
コード例 #3
0
                    del self.speech[cancelRequest.refId]
                if self.current_google_request != None:
                    self.current_google_request.cancel()
                self.send_object(CancelSucceeded(cancelRequest.aceId))

        elif ObjectIsCommand(plist, GetSessionCertificate):
            getSessionCertificate = GetSessionCertificate(plist)
            sessionCA_DER = crypto.dump_certificate(crypto.FILETYPE_ASN1, self.server.sessionCACert)
            sessionCert_DER = crypto.dump_certificate(crypto.FILETYPE_ASN1, self.server.sessionCert)
            response = GetSessionCertificateResponse(getSessionCertificate.aceId, sessionCA_DER, sessionCert_DER)
            self.send_object(response)

        elif ObjectIsCommand(plist, CreateSessionInfoRequest):
            # how does a positive answer look like?
            createSessionInfoRequest = CreateSessionInfoRequest(plist)
            fail = CommandFailed(createSessionInfoRequest.aceId)
            fail.reason = "Not authenticated"
            fail.errorCode = 0
            self.send_object(fail)

            #self.send_plist({"class":"SessionValidationFailed", "properties":{"errorCode":"UnsupportedHardwareVersion"}, "aceId": str(uuid.uuid4()), "refId":plist['aceId'], "group":"com.apple.ace.system"})
            
        elif plist['class'] == 'CreateAssistant':
            #create a new assistant
            helper = Assistant()     
            helper.assistantId=str.upper(str(uuid.uuid4())) 
            c = self.dbConnection.cursor()
            noError = True
            try:
                c.execute("insert into assistants(assistantId, assistant) values (?,?)", (helper.assistantId, helper))
                self.dbConnection.commit()
コード例 #4
0
    def received_plist(self, plist):
        self.logger.debug("Got packet with class: {0}".format(plist['class']))
        self.logger.debug("packet with content:\n{0}".format(pprint.pformat(plist, width=40)))
        
        # first handle speech stuff
        
        if 'refId' in plist:
            # if the following holds, this packet is an answer to a request by a plugin
            if plist['refId'] == self.plugin_lastAceId and self.current_running_plugin != None:
                if self.current_running_plugin.waitForResponse != None:
                    # just forward the object to the 
                    # don't change it's refId, further requests must reference last FinishSpeech
                    self.logger.debug("Forwarding object to plugin")
                    self.plugin_lastAceId = None
                    self.current_running_plugin.response = plist if plist['class'] != "StartRequest" else plist['properties']['utterance']
                    self.current_running_plugin.waitForResponse.set()
                    return
        
        if ObjectIsCommand(plist, StartSpeechRequest) or ObjectIsCommand(plist, StartSpeechDictation):
            self.logger.debug("New start of speech received")
            startSpeech = None
            if ObjectIsCommand(plist, StartSpeechDictation):
                dictation = True
                startSpeech = StartSpeechDictation(plist)
            else:
                dictation = False
                startSpeech = StartSpeechRequest(plist)
    
            decoder = speex.Decoder()
            encoder = flac.Encoder()
            speexUsed = False
            if startSpeech.codec == StartSpeech.CodecSpeex_WB_Quality8Value:
                decoder.initialize(mode=speex.SPEEX_MODEID_WB)
                encoder.initialize(16000, 1, 16)
                speexUsed = True
            elif startSpeech.codec == StartSpeech.CodecSpeex_NB_Quality7Value:
                decoder.initialize(mode=speex.SPEEX_MODEID_NB)
                encoder.initialize(16000, 1, 16)
                speexUsed = True
            elif startSpeech.codec == StartSpeech.CodecPCM_Mono_16Bit_8000HzValue:
                encoder.initialize(8000, 1, 16)
            elif startSpeech.codec == StartSpeech.CodecPCM_Mono_16Bit_11025HzValue:
                encoder.initialize(11025, 1, 16)
            elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_16000HzValue:
                encoder.initialize(16000, 1, 16)
            elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_22050HzValue:
                encoder.initialize(22050, 1, 16)
            elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_32000HzValue:
                encoder.initialize(32000, 1, 16)
            # we probably need resampling for sample rates other than 16kHz...
            
            self.speech[startSpeech.aceId] = (decoder if speexUsed else None, encoder, dictation)
        
        elif ObjectIsCommand(plist, SpeechPacket):
            self.logger.debug("Decoding speech packet")
            speechPacket = SpeechPacket(plist)
            if speechPacket.refId in self.speech:
                (decoder, encoder, dictation) = self.speech[speechPacket.refId]
                if decoder:
                    pcm = decoder.decode(speechPacket.packets)
                else:
                    pcm = SpeechPacket.data # <- probably data... if pcm
                encoder.encode(pcm)
            else:
                self.logger.debug("Got a speech packet that did not match any current request")
                
        elif plist['class'] == 'StartCorrectedSpeechRequest':
            self.process_recognized_speech({u'hypotheses': [{'confidence': 1.0, 'utterance': plist['properties']['utterance']}]}, plist['aceId'], False)
    
        elif ObjectIsCommand(plist, FinishSpeech):
            self.logger.debug("End of speech received")
            finishSpeech = FinishSpeech(plist)
            if finishSpeech.refId in self.speech:
                (decoder, encoder, dictation) = self.speech[finishSpeech.refId]
                if decoder:
                    decoder.destroy()
                flacBin = None
                if encoder:
                    encoder.finish()
                    flacBin = encoder.getBinary()
                    encoder.destroy()
                del self.speech[finishSpeech.refId]
                if flacBin != None:
                    self.logger.info("Sending flac to google for recognition")
                    try:
                        self.current_google_request = self.httpClient.make_google_request(flacBin, finishSpeech.refId, dictation, language=self.assistant.language, allowCurses=True)
                    except (AttributeError, TypeError):
                        self.logger.warning("Unable to find language record for this assistant. Try turning Siri off and then back on.")
                else:
                    self.logger.info("There was no speech")
            else:
                self.logger.debug("Got a finish speech packet that did not match any current request")
                
        elif ObjectIsCommand(plist, CancelRequest):
            # this is probably called when we need to kill a plugin
            # wait for thread to finish a send
            self.logger.debug("Should cancel current request")
            cancelRequest = CancelRequest(plist)
            if cancelRequest.refId in self.speech:
                (decoder, encoder, dictation) = self.speech[cancelRequest.refId]
                if decoder:
                    decoder.destroy()
                if encoder:
                    encoder.finish()
                    encoder.destory()
                del self.speech[cancelRequest.refId]
            if self.current_google_request != None:
                self.current_google_request.cancel()
                # if a google request is running (follow up listening..., plugin might get killed there by user)
                if self.current_running_plugin != None:
                    if self.current_running_plugin.waitForResponse != None:
                        self.current_running_plugin._abortPluginRun()
                        self.current_running_plugin.waitForResponse.set()
                        
            # if a plugin is running (processing, but not waiting for data from the device we kill it)   
            if self.current_running_plugin != None:
                if self.current_running_plugin.waitForResponse == None:
                    self.current_running_plugin._abortPluginRun()     
            
            self.send_object(CancelSucceeded(cancelRequest.aceId))
            
        elif ObjectIsCommand(plist, RollbackRequest):
            pass

        elif ObjectIsCommand(plist, GetSessionCertificate):
            getSessionCertificate = GetSessionCertificate(plist)
            sessionCA_DER = crypto.dump_certificate(crypto.FILETYPE_ASN1, self.server.sessionCACert)
            sessionCert_DER = crypto.dump_certificate(crypto.FILETYPE_ASN1, self.server.sessionCert)
            response = GetSessionCertificateResponse(getSessionCertificate.aceId, sessionCA_DER, sessionCert_DER)
            self.send_object(response)

        elif ObjectIsCommand(plist, CreateSessionInfoRequest):
            # how does a positive answer look like?
            createSessionInfoRequest = CreateSessionInfoRequest(plist)
            fail = CommandFailed(createSessionInfoRequest.aceId)
            fail.reason = "Not authenticated"
            fail.errorCode = 0
            self.send_object(fail)

            #self.send_plist({"class":"SessionValidationFailed", "properties":{"errorCode":"UnsupportedHardwareVersion"}, "aceId": str(uuid.uuid4()), "refId":plist['aceId'], "group":"com.apple.ace.system"})
            
        elif plist['class'] == 'CreateAssistant':
            #create a new assistant
            helper = Assistant()     
            helper.assistantId = str.upper(str(uuid.uuid4())) 
            c = self.dbConnection.cursor()
            noError = True
            try:
                c.execute("insert into assistants(assistantId, assistant) values (?,?)", (helper.assistantId, helper))
                self.dbConnection.commit()
            except sqlite3.Error: 
                noError = False
            c.close()
            if noError:
                self.assistant = helper
                self.send_plist({"class": "AssistantCreated", "properties": {"speechId": str(uuid.uuid4()), "assistantId": helper.assistantId}, "group":"com.apple.ace.system", "callbacks":[], "aceId": str(uuid.uuid4()), "refId": plist['aceId']})
            else:
                self.send_plist({"class":"CommandFailed", "properties": {"reason":"Database error", "errorCode":2, "callbacks":[]}, "aceId": str(uuid.uuid4()), "refId": plist['aceId'], "group":"com.apple.ace.system"})
            
        elif plist['class'] == 'SetAssistantData':
            # fill assistant 
            if self.assistant != None:
                try:
                    c = self.dbConnection.cursor()
                    objProperties = plist['properties'] 
                    self.assistant.censorSpeech = objProperties['censorSpeech']
                    self.assistant.timeZoneId = objProperties['timeZoneId']
                    self.assistant.language = objProperties['language']
                    self.assistant.region = objProperties['region']
                    #Here it is possible to support more languages combined with anyvoice package
                    #We can make assumption that the region will define the language.                     
                    if config.forcelanguage==True:                   
                        #Chinese Example
                        if self.assistant.region=="zh-CN":
                            self.assistant.language = "zh-CN"                        
                            self.logger.debug("Forced language to {0}".format(self.assistant.language))
                            
                    #Record the user firstName and nickName                    
                    try:                        
                        self.assistant.firstName = objProperties["meCards"][0]["properties"]["firstName"].encode("utf-8")
                    except KeyError:
                        self.assistant.firstName = u''                        
                    try:                        
                        self.assistant.nickName = objProperties["meCards"][0]["properties"]["nickName"].encode("utf-8")       
                    except KeyError:
                        self.assistant.nickName = u''
                    #Done recording
                    c.execute("update assistants set assistant = ? where assistantId = ?", (self.assistant, self.assistant.assistantId))
                    self.dbConnection.commit()
                    c.close()
                except:
                    self.send_plist({"class":"CommandFailed", "properties": {"reason":"Database error", "errorCode":2, "callbacks":[]}, "aceId": str(uuid.uuid4()), "refId": plist['aceId'], "group":"com.apple.ace.system"})
                    self.logger.error("Error on setting assistant data")
            else:
                self.send_plist({"class":"CommandFailed", "properties": {"reason":"Assistant to set data not found", "errorCode":2, "callbacks":[]}, "aceId": str(uuid.uuid4()), "refId": plist['aceId'], "group":"com.apple.ace.system"})
                self.logger.warning("Trying to set assistant data without having a valid assistant")
        elif plist['class'] == 'LoadAssistant':
            try:
                c = self.dbConnection.cursor()
                c.execute("select assistant from assistants where assistantId = ?", (plist['properties']['assistantId'],))
                self.dbConnection.commit()
                result = c.fetchone()
                if result == None:
                    self.send_plist({"class": "AssistantNotFound", "aceId":str(uuid.uuid4()), "refId":plist['aceId'], "group":"com.apple.ace.system"})
                    self.logger.warning("Assistant not found in database!!")                        
                else:
                    self.assistant = result[0]
                    if self.assistant.language == '' or self.assistant.language == None:
                        self.logger.error ("No language is set for this assistant")                        
                        c.execute("delete from assistants where assistantId = ?", (plist['properties']['assistantId'],))
                        self.dbConnection.commit()
                        self.send_plist({"class":"CommandFailed", "properties": {"reason":"Database error Assistant not found or language settings ", "errorCode":2, "callbacks":[]}, "aceId": str(uuid.uuid4()), "refId": plist['aceId'], "group":"com.apple.ace.system"})
                    else:                        
                        self.send_plist({"class": "AssistantLoaded", "properties": {"version": "20111216-32234-branches/telluride?cnxn=293552c2-8e11-4920-9131-5f5651ce244e", "requestSync":False, "dataAnchor":"removed"}, "aceId":str(uuid.uuid4()), "refId":plist['aceId'], "group":"com.apple.ace.system"})
                c.close()
            except:
                self.send_plist({"class": "AssistantNotFound", "aceId":str(uuid.uuid4()), "refId":plist['aceId'], "group":"com.apple.ace.system"})
                self.logger.warning("Database error on fetching assistant")
                
        elif plist['class'] == 'DestroyAssistant':
            try:
                c = self.dbConnection.cursor()
                c.execute("delete from assistants where assistantId = ?", (plist['properties']['assistantId'],))
                self.dbConnection.commit()
                c.close()
                self.send_plist({"class": "AssistantDestroyed", "properties": {"assistantId": plist['properties']['assistantId']}, "aceId":str(uuid.uuid4()), "refId":plist['aceId'], "group":"com.apple.ace.system"})
            except:
                self.send_plist({"class": "AssistantNotFound", "aceId":str(uuid.uuid4()), "refId":plist['aceId'], "group":"com.apple.ace.system"})
                self.logger.error("Database error on deleting assistant")
                
        elif plist['class'] == 'StartRequest':
            #this should also be handeled by special plugins, so lets call the plugin handling stuff
            self.process_recognized_speech({'hypotheses': [{'utterance': plist['properties']['utterance'], 'confidence': 1.0}]}, plist['aceId'], False)
        pass
コード例 #5
0
ファイル: siriServer.py プロジェクト: trYYY/SiriServer
    def process_compressed_data(self):
        self.unzipped_input += self.decompressor.decompress(self.data)
        self.data = ""
        while self.hasNextObj():
            reqObject = self.read_next_object_from_unzipped()
            if reqObject != None:
                self.logger.debug("Packet with class: {0}".format(reqObject['class']))
                self.logger.debug("packet with content:\n{0}".format(pprint.pformat(reqObject, width=40)))
                
                # first handle speech stuff
                
                if 'refId' in reqObject:
                    # if the following holds, this packet is an answer to a request by a plugin
                    if reqObject['refId'] == self.plugin_lastAceId and self.current_running_plugin != None:
                        if self.current_running_plugin.waitForResponse != None:
                            # just forward the object to the 
                            # don't change it's refId, further requests must reference last FinishSpeech
                            self.logger.info("Forwarding object to plugin")
                            self.plugin_lastAceId = None
                            self.current_running_plugin.response = reqObject if reqObject['class'] != "StartRequest" else reqObject['properties']['utterance']
                            self.current_running_plugin.waitForResponse.set()
                            continue
                
                if ObjectIsCommand(reqObject, StartSpeechRequest) or ObjectIsCommand(reqObject, StartSpeechDictation):
                    self.logger.info("New start of speech received")
                    startSpeech = None
                    if ObjectIsCommand(reqObject, StartSpeechDictation):
                        dictation = True
                        startSpeech = StartSpeechDictation(reqObject)
                    else:
                        dictation = False
                        startSpeech = StartSpeechRequest(reqObject)
            
                    decoder = speex.Decoder()
                    encoder = flac.Encoder()
                    speexUsed = False
                    if startSpeech.codec == StartSpeech.CodecSpeex_WB_Quality8Value:
                        decoder.initialize(mode=speex.SPEEX_MODEID_WB)
                        encoder.initialize(16000, 1, 16)
                        speexUsed = True
                    elif startSpeech.codec == StartSpeech.CodecSpeex_NB_Quality7Value:
                        decoder.initialize(mode=speex.SPEEX_MODEID_NB)
                        encoder.initialize(16000, 1, 16)
                        speexUsed = True
                    elif startSpeech.codec == StartSpeech.CodecPCM_Mono_16Bit_8000HzValue:
                        encoder.initialize(8000, 1, 16)
                    elif startSpeech.codec == StartSpeech.CodecPCM_Mono_16Bit_11025HzValue:
                        encoder.initialize(11025, 1, 16)
                    elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_16000HzValue:
                        encoder.initialize(16000, 1, 16)
                    elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_22050HzValue:
                        encoder.initialize(22050, 1, 16)
                    elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_32000HzValue:
                        encoder.initialize(32000, 1, 16)
                    # we probably need resampling for sample rates other than 16kHz...
                    
                    self.speech[startSpeech.aceId] = (decoder if speexUsed else None, encoder, dictation)
                
                elif ObjectIsCommand(reqObject, SpeechPacket):
                    self.logger.info("Decoding speech packet")
                    speechPacket = SpeechPacket(reqObject)
                    (decoder, encoder, dictation) = self.speech[speechPacket.refId]
                    if decoder:
                        pcm = decoder.decode(speechPacket.packets)
                    else:
                        pcm = SpeechPacket.data # <- probably data... if pcm
                    encoder.encode(pcm)
                        
                elif reqObject['class'] == 'StartCorrectedSpeechRequest':
                    self.process_recognized_speech({u'hypotheses': [{'confidence': 1.0, 'utterance': str.lower(reqObject['properties']['utterance'])}]}, reqObject['aceId'], False)
            
                elif ObjectIsCommand(reqObject, FinishSpeech):
                    self.logger.info("End of speech received")
                    finishSpeech = FinishSpeech(reqObject)
                    (decoder, encoder, dictation) = self.speech[finishSpeech.refId]
                    if decoder:
                        decoder.destroy()
                    encoder.finish()
                    flacBin = encoder.getBinary()
                    encoder.destroy()
                    del self.speech[finishSpeech.refId]
                    
                    self.logger.info("Sending flac to google for recognition")
                    try:
                        self.httpClient.make_google_request(flacBin, finishSpeech.refId, dictation, language=self.assistant.language, allowCurses=True)
                    except AttributeError, TypeError:
                        self.logger.info("Unable to find language record for this assistant. Try turning Siri off and then back on.")
                        
                elif ObjectIsCommand(reqObject, CancelRequest):
                        # this is probably called when we need to kill a plugin
                        # wait for thread to finish a send
                        cancelRequest = CancelRequest(reqObject)
                        if cancelRequest.refId in self.speech:
                            del self.speech[cancelRequest.refId]
                        
                        self.send_object(CancelSucceeded(cancelRequest.aceId))

                elif ObjectIsCommand(reqObject, GetSessionCertificate):
                    getSessionCertificate = GetSessionCertificate(reqObject)
                    response = GetSessionCertificateResponse(getSessionCertificate.aceId, caCert.as_der(), serverCert.as_der())
                    self.send_object(response)

                elif ObjectIsCommand(reqObject, CreateSessionInfoRequest):
                    # how does a positive answer look like?
                    createSessionInfoRequest = CreateSessionInfoRequest(reqObject)
                    fail = CommandFailed(createSessionInfoRequest.aceId)
                    fail.reason = "Not authenticated"
                    fail.errorCode = 0
                    self.send_object(fail)

                    #self.send_plist({"class":"SessionValidationFailed", "properties":{"errorCode":"UnsupportedHardwareVersion"}, "aceId": str(uuid.uuid4()), "refId":reqObject['aceId'], "group":"com.apple.ace.system"})
                    
                elif reqObject['class'] == 'CreateAssistant':
                    #create a new assistant
                    helper = Assistant()
                    c = self.dbConnection.cursor()
                    noError = True
                    try:
                        c.execute("INSERT INTO `assistants` (assistantId,speechId,censorSpeech,timeZoneId,language,region,date_created) values (%s,%s,%s,%s,%s,%s,NOW())", (helper.assistantId, helper.speechId,"","","",""))
                        self.dbConnection.commit()
                    except mdb.Error, e: 
                        noError = False
                    c.close()
                    if noError:
                        self.assistant = helper
                        self.send_plist({"class": "AssistantCreated", "properties": {"speechId": helper.speechId, "assistantId": helper.assistantId}, "group":"com.apple.ace.system", "callbacks":[], "aceId": str(uuid.uuid4()), "refId": reqObject['aceId']})
                    else:
                        self.send_plist({"class":"CommandFailed", "properties": {"reason":"Database error", "errorCode":2, "callbacks":[]}, "aceId": str(uuid.uuid4()), "refId": reqObject['aceId'], "group":"com.apple.ace.system"})
            
                elif reqObject['class'] == 'SetAssistantData':
                    # fill assistant 
                    if self.assistant != None:
                        c = self.dbConnection.cursor()
                        objProperties = reqObject['properties'] 
                        self.assistant.censorSpeech = objProperties['censorSpeech']
                        self.assistant.timeZoneId = objProperties['timeZoneId']
                        self.assistant.language = objProperties['language']
                        self.assistant.region = objProperties['region']
                        c.execute("UPDATE `assistants` set censorSpeech=%s,timeZoneId=%s,language=%s,region=%s  where assistantId = %s", (self.assistant.censorSpeech,self.assistant.timeZoneId, self.assistant.language,self.assistant.region,self.assistant.assistantId))
                        self.dbConnection.commit()
                        c.close()
コード例 #6
0
ファイル: siriServer.py プロジェクト: waynesg511/SiriServer-1
    def process_compressed_data(self):
        self.unzipped_input += self.decompressor.decompress(self.data)
        self.data = ""
        while self.hasNextObj():
            reqObject = self.read_next_object_from_unzipped()
            if reqObject != None:
                self.logger.debug("Packet with class: {0}".format(
                    reqObject['class']))
                self.logger.debug("packet with content:\n{0}".format(
                    pprint.pformat(reqObject, width=40)))

                # first handle speech stuff

                if 'refId' in reqObject:
                    # if the following holds, this packet is an answer to a request by a plugin
                    if reqObject[
                            'refId'] == self.plugin_lastAceId and self.current_running_plugin != None:
                        if self.current_running_plugin.waitForResponse != None:
                            # just forward the object to the
                            # don't change it's refId, further requests must reference last FinishSpeech
                            self.logger.info("Forwarding object to plugin")
                            self.plugin_lastAceId = None
                            self.current_running_plugin.response = reqObject
                            self.current_running_plugin.waitForResponse.set()

                if ObjectIsCommand(reqObject,
                                   StartSpeechRequest) or ObjectIsCommand(
                                       reqObject, StartSpeechDictation):
                    self.logger.info("New start of speech received")
                    startSpeech = None
                    if ObjectIsCommand(reqObject, StartSpeechDictation):
                        dictation = True
                        startSpeech = StartSpeechDictation(reqObject)
                    else:
                        dictation = False
                        startSpeech = StartSpeechRequest(reqObject)

                    decoder = speex.Decoder()
                    encoder = flac.Encoder()
                    speexUsed = False
                    if startSpeech.codec == StartSpeech.CodecSpeex_WB_Quality8Value:
                        decoder.initialize(mode=speex.SPEEX_MODEID_WB)
                        encoder.initialize(16000, 1, 16)
                        speexUsed = True
                    elif startSpeech.codec == StartSpeech.CodecSpeex_NB_Quality7Value:
                        decoder.initialize(mode=speex.SPEEX_MODEID_NB)
                        encoder.initialize(16000, 1, 16)
                        speexUsed = True
                    elif startSpeech.codec == StartSpeech.CodecPCM_Mono_16Bit_8000HzValue:
                        encoder.initialize(8000, 1, 16)
                    elif startSpeech.codec == StartSpeech.CodecPCM_Mono_16Bit_11025HzValue:
                        encoder.initialize(11025, 1, 16)
                    elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_16000HzValue:
                        encoder.initialize(16000, 1, 16)
                    elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_22050HzValue:
                        encoder.initialize(22050, 1, 16)
                    elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_32000HzValue:
                        encoder.initialize(32000, 1, 16)
                    # we probably need resampling for sample rates other than 16kHz...

                    self.speech[startSpeech.aceId] = (decoder if speexUsed else
                                                      None, encoder, dictation)

                elif ObjectIsCommand(reqObject, SpeechPacket):
                    self.logger.info("Decoding speech packet")
                    speechPacket = SpeechPacket(reqObject)
                    (decoder, encoder,
                     dictation) = self.speech[speechPacket.refId]
                    if decoder:
                        pcm = decoder.decode(speechPacket.packets)
                    else:
                        pcm = SpeechPacket.data  # <- probably data... if pcm
                    encoder.encode(pcm)

                elif reqObject['class'] == 'StartCorrectedSpeechRequest':
                    self.process_recognized_speech(
                        {
                            u'hypotheses': [{
                                'confidence':
                                1.0,
                                'utterance':
                                str.lower(reqObject['properties']['utterance'])
                            }]
                        }, reqObject['aceId'], False)

                elif ObjectIsCommand(reqObject, FinishSpeech):
                    self.logger.info("End of speech received")
                    finishSpeech = FinishSpeech(reqObject)
                    (decoder, encoder,
                     dictation) = self.speech[finishSpeech.refId]
                    if decoder:
                        decoder.destroy()
                    encoder.finish()
                    flacBin = encoder.getBinary()
                    encoder.destroy()
                    del self.speech[finishSpeech.refId]

                    self.logger.info("Sending flac to google for recognition")
                    self.httpClient.make_google_request(
                        flacBin,
                        finishSpeech.refId,
                        dictation,
                        language=self.assistant.language,
                        allowCurses=True)

                elif ObjectIsCommand(reqObject, CancelRequest):
                    # this is probably called when we need to kill a plugin
                    # wait for thread to finish a send
                    cancelRequest = CancelRequest(reqObject)
                    if cancelRequest.refId in self.speech:
                        del self.speech[cancelRequest.refId]

                    self.send_object(CancelSucceeded(cancelRequest.aceId))

                elif ObjectIsCommand(reqObject, GetSessionCertificate):
                    getSessionCertificate = GetSessionCertificate(reqObject)
                    response = GetSessionCertificateResponse(
                        getSessionCertificate.aceId)
                    response.caCert = caCert.as_der()
                    response.sessionCert = serverCert.as_der()
                    self.send_object(response)

                elif ObjectIsCommand(reqObject, CreateSessionInfoRequest):
                    # how does a positive answer look like?
                    createSessionInfoRequest = CreateSessionInfoRequest(
                        reqObject)
                    fail = CommandFailed(createSessionInfoRequest.aceId)
                    fail.reason = "Not authenticated"
                    fail.errorCode = 0
                    self.send_object(fail)

                    #self.send_plist({"class":"SessionValidationFailed", "properties":{"errorCode":"UnsupportedHardwareVersion"}, "aceId": str(uuid.uuid4()), "refId":reqObject['aceId'], "group":"com.apple.ace.system"})

                elif reqObject['class'] == 'CreateAssistant':
                    #create a new assistant
                    helper = Assistant()
                    c = self.dbConnection.cursor()
                    noError = True
                    try:
                        c.execute(
                            "insert into assistants(assistantId, assistant) values (?,?)",
                            (helper.assistantId, helper))
                        self.dbConnection.commit()
                    except sqlite3.Error, e:
                        noError = False
                    c.close()
                    if noError:
                        self.assistant = helper
                        self.send_plist({
                            "class": "AssistantCreated",
                            "properties": {
                                "speechId": str(uuid.uuid4()),
                                "assistantId": helper.assistantId
                            },
                            "group": "com.apple.ace.system",
                            "callbacks": [],
                            "aceId": str(uuid.uuid4()),
                            "refId": reqObject['aceId']
                        })
                    else:
                        self.send_plist({
                            "class": "CommandFailed",
                            "properties": {
                                "reason": "Database error",
                                "errorCode": 2,
                                "callbacks": []
                            },
                            "aceId": str(uuid.uuid4()),
                            "refId": reqObject['aceId'],
                            "group": "com.apple.ace.system"
                        })

                elif reqObject['class'] == 'SetAssistantData':
                    # fill assistant
                    if self.assistant != None:
                        c = self.dbConnection.cursor()
                        objProperties = reqObject['properties']
                        self.assistant.censorSpeech = objProperties[
                            'censorSpeech']
                        self.assistant.timeZoneId = objProperties['timeZoneId']
                        #self.assistant.language = objProperties['language']
                        if self.lang != None:
                            self.assistant.language = self.lang
                        else:
                            self.assistant.language = objProperties['language']
                        self.assistant.region = objProperties['region']
                        c.execute(
                            "update assistants set assistant = ? where assistantId = ?",
                            (self.assistant, self.assistant.assistantId))
                        self.dbConnection.commit()
                        c.close()

                elif reqObject['class'] == 'LoadAssistant':
                    c = self.dbConnection.cursor()
                    c.execute(
                        "select assistant from assistants where assistantId = ?",
                        (reqObject['properties']['assistantId'], ))
                    self.dbConnection.commit()
                    result = c.fetchone()
                    if result == None:
                        self.send_plist({
                            "class": "AssistantNotFound",
                            "aceId": str(uuid.uuid4()),
                            "refId": reqObject['aceId'],
                            "group": "com.apple.ace.system"
                        })
                    else:
                        self.assistant = result[0]
                        self.send_plist({
                            "class": "AssistantLoaded",
                            "properties": {
                                "version":
                                "20111216-32234-branches/telluride?cnxn=293552c2-8e11-4920-9131-5f5651ce244e",
                                "requestSync": False,
                                "dataAnchor": "removed"
                            },
                            "aceId": str(uuid.uuid4()),
                            "refId": reqObject['aceId'],
                            "group": "com.apple.ace.system"
                        })
                    c.close()

                elif reqObject['class'] == 'DestroyAssistant':
                    c = self.dbConnection.cursor()
                    c.execute("delete from assistants where assistantId = ?",
                              (reqObject['properties']['assistantId'], ))
                    self.dbConnection.commit()
                    c.close()
                    self.send_plist({
                        "class": "AssistantDestroyed",
                        "properties": {
                            "assistantId":
                            reqObject['properties']['assistantId']
                        },
                        "aceId": str(uuid.uuid4()),
                        "refId": reqObject['aceId'],
                        "group": "com.apple.ace.system"
                    })
                elif reqObject['class'] == 'StartRequest':
                    #this should also be handeled by special plugins, so lets call the plugin handling stuff
                    self.process_recognized_speech(
                        {
                            'hypotheses': [{
                                'utterance':
                                reqObject['properties']['utterance'],
                                'confidence':
                                1.0
                            }]
                        }, reqObject['aceId'], False)
コード例 #7
0
    def received_plist(self, plist):
        self.logger.debug("Got packet with class: {0}".format(plist['class']))
        self.logger.debug("packet with content:\n{0}".format(
            pprint.pformat(plist, width=40)))

        # first handle speech stuff

        if 'refId' in plist:
            # if the following holds, this packet is an answer to a request by a plugin
            if plist[
                    'refId'] == self.plugin_lastAceId and self.current_running_plugin != None:
                if self.current_running_plugin.waitForResponse != None:
                    # just forward the object to the
                    # don't change it's refId, further requests must reference last FinishSpeech
                    self.logger.debug("Forwarding object to plugin")
                    self.plugin_lastAceId = None
                    self.current_running_plugin.response = plist if plist[
                        'class'] != "StartRequest" else plist['properties'][
                            'utterance']
                    self.current_running_plugin.waitForResponse.set()
                    return

        if ObjectIsCommand(plist, StartSpeechRequest) or ObjectIsCommand(
                plist, StartSpeechDictation):
            self.logger.debug("New start of speech received")
            startSpeech = None
            if ObjectIsCommand(plist, StartSpeechDictation):
                dictation = True
                startSpeech = StartSpeechDictation(plist)
            else:
                dictation = False
                startSpeech = StartSpeechRequest(plist)

            decoder = speex.Decoder()
            encoder = flac.Encoder()
            speexUsed = False
            if startSpeech.codec == StartSpeech.CodecSpeex_WB_Quality8Value:
                decoder.initialize(mode=speex.SPEEX_MODEID_WB)
                encoder.initialize(16000, 1, 16)
                speexUsed = True
            elif startSpeech.codec == StartSpeech.CodecSpeex_NB_Quality7Value:
                decoder.initialize(mode=speex.SPEEX_MODEID_NB)
                encoder.initialize(16000, 1, 16)
                speexUsed = True
            elif startSpeech.codec == StartSpeech.CodecPCM_Mono_16Bit_8000HzValue:
                encoder.initialize(8000, 1, 16)
            elif startSpeech.codec == StartSpeech.CodecPCM_Mono_16Bit_11025HzValue:
                encoder.initialize(11025, 1, 16)
            elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_16000HzValue:
                encoder.initialize(16000, 1, 16)
            elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_22050HzValue:
                encoder.initialize(22050, 1, 16)
            elif startSpeech.coded == StartSpeech.CodecPCM_Mono_16Bit_32000HzValue:
                encoder.initialize(32000, 1, 16)
            # we probably need resampling for sample rates other than 16kHz...

            self.speech[startSpeech.aceId] = (decoder if speexUsed else None,
                                              encoder, dictation)

        elif ObjectIsCommand(plist, SpeechPacket):
            self.logger.debug("Decoding speech packet")
            speechPacket = SpeechPacket(plist)
            if speechPacket.refId in self.speech:
                (decoder, encoder, dictation) = self.speech[speechPacket.refId]
                if decoder:
                    pcm = decoder.decode(speechPacket.packets)
                else:
                    pcm = SpeechPacket.data  # <- probably data... if pcm
                encoder.encode(pcm)
            else:
                self.logger.debug(
                    "Got a speech packet that did not match any current request"
                )

        elif plist['class'] == 'StartCorrectedSpeechRequest':
            self.process_recognized_speech(
                {
                    u'hypotheses':
                    [{
                        'confidence': 1.0,
                        'utterance': plist['properties']['utterance']
                    }]
                }, plist['aceId'], False)

        elif ObjectIsCommand(plist, FinishSpeech):
            self.logger.debug("End of speech received")
            finishSpeech = FinishSpeech(plist)
            if finishSpeech.refId in self.speech:
                (decoder, encoder, dictation) = self.speech[finishSpeech.refId]
                if decoder:
                    decoder.destroy()
                flacBin = None
                if encoder:
                    encoder.finish()
                    flacBin = encoder.getBinary()
                    encoder.destroy()
                del self.speech[finishSpeech.refId]
                if flacBin != None:
                    self.logger.info("Sending flac to google for recognition")
                    try:
                        self.current_google_request = self.httpClient.make_google_request(
                            flacBin,
                            finishSpeech.refId,
                            dictation,
                            language=self.assistant.language,
                            allowCurses=True)
                    except (AttributeError, TypeError):
                        self.logger.warning(
                            "Unable to find language record for this assistant. Try turning Siri off and then back on."
                        )
                else:
                    self.logger.info("There was no speech")
            else:
                self.logger.debug(
                    "Got a finish speech packet that did not match any current request"
                )

        elif ObjectIsCommand(plist, CancelRequest):
            # this is probably called when we need to kill a plugin
            # wait for thread to finish a send
            self.logger.debug("Should cancel current request")
            cancelRequest = CancelRequest(plist)
            if cancelRequest.refId in self.speech:
                (decoder, encoder,
                 dictation) = self.speech[cancelRequest.refId]
                if decoder:
                    decoder.destroy()
                if encoder:
                    encoder.finish()
                    encoder.destroy()
                del self.speech[cancelRequest.refId]
            if self.current_google_request != None:
                self.current_google_request.cancel()
                # if a google request is running (follow up listening..., plugin might get killed there by user)
                if self.current_running_plugin != None:
                    if self.current_running_plugin.waitForResponse != None:
                        self.current_running_plugin._abortPluginRun()
                        self.current_running_plugin.waitForResponse.set()

            # if a plugin is running (processing, but not waiting for data from the device we kill it)
            if self.current_running_plugin != None:
                if self.current_running_plugin.waitForResponse == None:
                    self.current_running_plugin._abortPluginRun()

            self.send_object(CancelSucceeded(cancelRequest.aceId))

        elif ObjectIsCommand(plist, RollbackRequest):
            pass

        elif ObjectIsCommand(plist, SyncChunk):
            chunk = SyncChunk(plist)
            previous = self.syncAnchors[
                chunk.key] if chunk.key in self.syncAnchors else None
            if previous != None:
                if previous.generation != chunk.preGen:
                    chunkDenied = SyncChunkDenied(chunk.aceId)
                    self.send_object(chunkDenied)
                    return
            current = SyncAnchor()
            current.generation = chunk.postGen
            current.value = chunk.postGen
            current.validity = chunk.validity
            current.key = chunk.key
            self.syncAnchors[current.key] = current
            chunkAccepted = SyncChunkAccepted(chunk.aceId)
            chunkAccepted.current = current
            self.send_object(chunkAccepted)
            pass

        elif ObjectIsCommand(plist, GetSessionCertificate):
            getSessionCertificate = GetSessionCertificate(plist)
            sessionCA_DER = crypto.dump_certificate(crypto.FILETYPE_ASN1,
                                                    self.server.sessionCACert)
            sessionCert_DER = crypto.dump_certificate(crypto.FILETYPE_ASN1,
                                                      self.server.sessionCert)
            response = GetSessionCertificateResponse(
                getSessionCertificate.aceId, sessionCA_DER, sessionCert_DER)
            self.send_object(response)

        elif ObjectIsCommand(plist, CreateSessionInfoRequest):
            # how does a positive answer look like?
            createSessionInfoRequest = CreateSessionInfoRequest(plist)

            #success = CreateSessionInfoResponse(createSessionInfoRequest.aceId)
            #success.sessionInfo = biplist.Data("\x01\x02BLABLABLBALBALBALBALBALBALBALBA")
            #success.validityDuration = 9600

            #self.send_object(success)
            fail = CommandFailed(createSessionInfoRequest.aceId)
            fail.reason = "Not authenticated"
            fail.errorCode = 0
            self.send_object(fail)

            ##self.send_plist({"class":"SessionValidationFailed", "properties":{"errorCode":"UnsupportedHardwareVersion"}, "aceId": str(uuid.uuid4()), "refId":plist['aceId'], "group":"com.apple.ace.system"})

        elif ObjectIsCommand(plist, CreateAssistant):
            createAssistant = CreateAssistant(plist)
            #create a new assistant
            helper = Assistant()
            helper.assistantId = str.upper(str(uuid.uuid4()))
            helper.language = createAssistant.language
            helper.activationToken = createAssistant.activationToken
            helper.connectionType = createAssistant.connectionType
            helper.validationData = createAssistant.validationData
            c = self.dbConnection.cursor()
            noError = True
            try:
                c.execute(
                    "insert into assistants(assistantId, assistant) values (?,?)",
                    (helper.assistantId, helper))
                self.dbConnection.commit()
            except sqlite3.Error:
                noError = False
            c.close()
            if noError:
                self.assistant = helper
                assiCreatedCMD = AssistantCreated(createAssistant.aceId)
                assiCreatedCMD.assistantId = helper.assistantId
                assiCreatedCMD.speechId = str(uuid.uuid4())
                self.send_object(assiCreatedCMD)
            else:
                cmdFailed = CommandFailed(createAssistant.aceId)
                cmdFailed.reason = "Database Error"
                cmdFailed.errorCode = 2
                self.send_object(cmdFailed)

        elif ObjectIsCommand(plist, SetAssistantData):
            setAssistantData = SetAssistantData(plist)
            # fill assistant
            if self.assistant != None:
                try:
                    c = self.dbConnection.cursor()
                    assi_id = self.assistant.assistantId
                    self.assistant.initializeFromPlist(
                        setAssistantData.to_plist())
                    self.assistant.assistantId = assi_id
                    #Record the user firstName and nickName
                    try:
                        self.assistant.firstName = self.assistant.meCards[
                            0].firstName.encode("utf-8")
                    except:
                        self.assistant.firstName = u''
                    try:
                        self.assistant.nickName = self.assistant.meCards[
                            0].nickName.encode("utf-8")
                    except:
                        self.assistant.nickName = u''
                    #Done recording
                    c.execute(
                        "update assistants set assistant = ? where assistantId = ?",
                        (self.assistant, self.assistant.assistantId))
                    self.dbConnection.commit()
                    c.close()
                except:
                    cmdFailed = CommandFailed(setAssistantData.aceId)
                    cmdFailed.reason = "Database Error"
                    cmdFailed.errorCode = 2
                    self.send_object(cmdFailed)
                    self.logger.exception(
                        "Database Error on setting assistant data")
            else:
                cmdFailed = CommandFailed(setAssistantData.aceId)
                cmdFailed.reason = "Assistant to set data not found"
                cmdFailed.errorCode = 2
                self.send_object(cmdFailed)
                self.logger.warning(
                    "Trying to set assistant data without having a valid assistant"
                )

        elif ObjectIsCommand(plist, LoadAssistant):
            loadAssistant = LoadAssistant(plist)
            try:
                c = self.dbConnection.cursor()
                c.execute(
                    "select assistant from assistants where assistantId = ?",
                    (loadAssistant.assistantId, ))
                self.dbConnection.commit()
                result = c.fetchone()
                if result == None:
                    self.send_object(AssistantNotFound(loadAssistant.aceId))
                    self.logger.warning("Assistant not found in database!!")
                else:
                    self.assistant = result[0]
                    #update assistant from LoadAssistant
                    self.assistant.language = loadAssistant.language
                    self.assistant.connectionType = loadAssistant.connectionType

                    if self.assistant.language == '' or self.assistant.language == None:
                        self.logger.error(
                            "No language is set for this assistant")
                        c.execute(
                            "delete from assistants where assistantId = ?",
                            (plist['properties']['assistantId'], ))
                        self.dbConnection.commit()
                        cmdFailed = CommandFailed(loadAssistant.aceId)
                        cmdFailed.reason = "Database error Assistant not found or language settings"
                        cmdFailed.errorCode = 2
                        self.send_object(cmdFailed)
                    else:
                        loaded = AssistantLoaded(loadAssistant.aceId)
                        loaded.version = "20111216-32234-branches/telluride?cnxn=293552c2-8e11-4920-9131-5f5651ce244e"
                        loaded.requestSync = 0
                        try:
                            loaded.dataAnchor = self.assistant.anchor
                        except:
                            loaded.dataAnchor = "removed"
                        self.send_object(loaded)
                c.close()
            except:
                self.send_object(AssistantNotFound(loadAssistant.aceId))
                self.logger.warning("Database error on fetching assistant")

        elif ObjectIsCommand(plist, DestroyAssistant):
            destroyAssistant = DestroyAssistant(plist)
            try:
                c = self.dbConnection.cursor()
                c.execute("delete from assistants where assistantId = ?",
                          (plist['properties']['assistantId'], ))
                self.dbConnection.commit()
                c.close()
                destroyed = AssistantDestroyed(destroyAssistant.aceId)
                destroyed.assistantId = destroyAssistant.assistantId
                self.send_object(destroyed)
            except:
                self.send_object(AssistantNotFound(destroyAssistant.aceId))
                self.logger.error("Database error on deleting assistant")

        elif ObjectIsCommand(plist, StartRequest):
            startRequest = StartRequest(plist)
            #this should also be handeled by special plugins, so lets call the plugin handling stuff
            self.process_recognized_speech(
                {
                    'hypotheses': [{
                        'utterance': startRequest.utterance,
                        'confidence': 1.0
                    }]
                }, startRequest.aceId, False)
        pass