import os, sys, time, subprocess
import speech_recognition
from optparse import OptionParser
import google.cloud.translate
import threading

class Diplomatist():
    def __init__(self):
        if "GOOGLE_APPLICATION_CREDENTIALS" in os.environ:
            self.translate_client = google.cloud.translate.Client()
    
    def transcribe(self, api=0, audio_file=None, cred=None, language="en-US"):
        recognizer = speech_recognition.Recognizer()
        with speech_recognition.AudioFile(audio_file) as source:
            audio = recognizer.record(source)
        try:
            if api == 0:
                return recognizer.recognize_sphinx(audio, language)
            elif api == 1:
                return recognizer.recognize_google_cloud(audio, cred, language)
            elif api == 2:
                return recognizer.recognize_bing(audio, cred, language)
            elif api == 3:
                return recognizer.recognize_houndify(audio, cred.split(",")[0], cred.split(",")[1])
        except speech_recognition.UnknownValueError:
            print "Could Not Understand"
            return False
        except speech_recognition.RequestError as e:
            print "Request Error: {0}".format(e)
            return False
    
    def record(self, audio_file=None):
        recognizer = speech_recognition.Recognizer()
        with speech_recognition.Microphone() as source:
            print "Say something!"
            audio = recognizer.listen(source)
        if audio_file is None:
            audio_file = "record.wav"
        with open(audio_file, "wb") as f:
            f.write(audio.get_wav_data())
    
    def capture_loopback(self, audio_file, milliseconds):
        if "LOOPBACK_CAPTURE" not in os.environ:
            print "Please set the %LOOPBACK_CAPTURE% before you start to capture."
        Loopback_Capture_Path = os.environ["LOOPBACK_CAPTURE"]
        process = subprocess.Popen("{} {} {}".format(Loopback_Capture_Path, audio_file, milliseconds), stdout=subprocess.PIPE)
        exit_code = process.wait()
        return exit_code
    
    def translate(self, text, language):
        if "GOOGLE_APPLICATION_CREDENTIALS" in os.environ:
            return self.translate_client.translate(text, target_language=language)['translatedText']
    
    def async_transcribe(self, api=0, audio_file=None, cred=None, language="en-US"):
        transc = self.transcribe(api, audio_file, cred, language)
        if transc == False:
            transc = "Cannot Be Transcribed!"
        print transc

    def async_transcribe_translate(self, api=0, audio_file=None, cred=None, transc_lan="en-US", transl_lan="zh"):
        transc = self.transcribe(api, audio_file, cred, transc_lan)
        if transc == False:
            transc = "Cannot Be Transcribed!"
        print transc
        transl = self.translate(transc, transl_lan)
        print transl

def get_options():
    parser = OptionParser()
    parser.add_option("-m", "--mic", dest="use_mic", action="store_true", default=False, 
                help="record sounds from microphone")
    parser.add_option("-f", "--file", dest="audio_file", default=None, 
                help="audio file which to be transcribed and translated")
    parser.add_option("-s", "--slice", dest="time_slice", default=10000, type="int", 
                help="time slice of each wave file")
    parser.add_option("-a", "--api", dest="api", default=0, type="int",
                help="0 - CMU Sphinx, 1 - Google Cloud, 2 - Bing API, 3 - Houndify API")
    parser.add_option("-c", "--cred", dest="credential", default=None,
                help="credential file if is API required")
    parser.add_option("-l", "--lan", dest="language", default="en-US",
                help="language which to be transcribed")
    parser.add_option("-t", "--tran", dest="translate", default=None,
                help="translate to another language")
    (options, args) = parser.parse_args()
    return options


if __name__ == "__main__":
    os.environ["LOOPBACK_CAPTURE"] = r"LoopbackCapture\win32\csharp\LoopbackCapture\LoopbackCapture\bin\Debug\LoopbackCapture.exe"
    opt = get_options()
    if opt.credential:
        if os.path.isfile(opt.credential):
            cred = open(opt.credential, "r").read()
        else:
            cred = opt.credential
        if opt.translate:
            os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = opt.credential
        else:
            cred = None
    diplomatist = Diplomatist()
    if opt.audio_file:
        if opt.translate:
            diplomatist.async_transcribe_translate(opt.api, opt.audio_file, cred, opt.language, opt.translate)
        else:
            diplomatist.async_transcribe(opt.api, opt.audio_file, cred, opt.language)
        sys.exit()
    init_time = 0
    records_folder = "records"
    if not os.path.isdir(records_folder):
        os.mkdir(records_folder)
    while True:
        start_time = time.time()
        if opt.use_mic:
            diplomatist.record("record.wav")
        else:
            diplomatist.capture_loopback("record.wav", opt.time_slice)
        end_time = time.time()
        print "{} -> {}".format(time.strftime("%H:%M:%S", time.gmtime(init_time)), time.strftime("%H:%M:%S", time.gmtime(end_time - start_time + init_time)))
        init_time = end_time - start_time + init_time
        saved_file_name = str(time.time()) + ".wav"
        saved_audio_file = os.path.join(records_folder, saved_file_name)
        os.rename("record.wav", saved_audio_file)
        if opt.translate:
            thr = threading.Thread(target=diplomatist.async_transcribe_translate, args=([opt.api, saved_audio_file, cred, opt.language, opt.translate]), kwargs={})
            thr.start()
        else:
            thr = threading.Thread(target=diplomatist.async_transcribe, args=([opt.api, saved_audio_file, cred, opt.language]), kwargs={})
            thr.start()
@@ -4883,16 +4883,47 @@
 folder)%0A
+    record_file = %22record.wav%22%0A
     whil
@@ -5018,28 +5018,27 @@
 .record(
-%22
 record
-.wav%22
+_file
 )%0A      
@@ -5086,28 +5086,27 @@
 oopback(
-%22
 record
-.wav%22
+_file
 , opt.ti
@@ -5501,28 +5501,27 @@
 .rename(
-%22
 record
-.wav%22
+_file
 , saved_

use variable to replace hardcode file name