diff --git a/whisper-2023/hotwords.py b/whisper-2023/hotwords.py index 5256d84..71b7a64 100644 --- a/whisper-2023/hotwords.py +++ b/whisper-2023/hotwords.py @@ -4,26 +4,10 @@ import threading import queue import signal import sys -from os import environ -from os import kill +import os import requests import yaml -def main(): - managerToParserQ = queue.Queue(maxsize=1) - readerToParserQ = queue.Queue(maxsize=10) - parserToReactorQ = queue.Queue(maxsize=10) - reactorToActorQ = queue.Queue(maxsize=10) - threads = [ - Manager(managerToParserQ), - Reader(managerToParserQ, readerToParserQ), - Parser(readerToParserQ, parserToReactorQ), - Reactor(parserToReactorQ, reactorToActorQ), - Actor(reactorToActorQ), - ] - [t.start() for t in threads] - [t.join() for t in threads] - def log(*args): print(">", *args, file=sys.stderr) @@ -60,7 +44,7 @@ class Manager(threading.Thread): class Reader(threading.Thread): def __init__(self, inq, outq): threading.Thread.__init__(self) - self.name = environ.get("MIC_NAME", "pulse_monitor") + self.name = os.environ.get("MIC_NAME", "pulse_monitor") if not self.name: for index, name in enumerate(sr.Microphone.list_microphone_names()): print("[{0}] Microphone with name \"{1}\" found for `Microphone(device_index={0})`".format(index, name)) @@ -94,7 +78,7 @@ class Reader(threading.Thread): return not self.inq.empty() def _run(self, mic): - mic_timeout = int(environ.get("MIC_TIMEOUT", 5)) + mic_timeout = int(os.environ.get("MIC_TIMEOUT", 5)) r = sr.Recognizer() return r.listen( mic, @@ -126,7 +110,7 @@ class Parser(threading.Thread): def _run(self, clip): r = sr.Recognizer() - return r.recognize_whisper(clip, language="english", model=environ.get("MODEL", "small.en")) # tiny.en=32x, base.en=16x, small.en=6x, medium.en=x2 + return r.recognize_whisper(clip, language="english", model=os.environ.get("MODEL", "small.en")) # tiny.en=32x, base.en=16x, small.en=6x, medium.en=x2 def load_dot_notation(v, s): items = s.replace("[]", ".[]").split(".") @@ -164,16 +148,20 @@ def _load_dot_notation(v, items): return v def test_load_dot_notation(): - assert("a" == load_dot_notation("a", ".")) - assert(["a"] == load_dot_notation(["a"], ".")) - assert("b" == load_dot_notation({"a":"b"}, ".a")) - assert("c" == load_dot_notation({"a":{"b":"c"}}, ".a.b")) - assert("c" == load_dot_notation({"a":{"b":["c"]}}, ".a.b.0")) - assert(["c","d"] == load_dot_notation({"a":{"b":"c"}, "a2":{"b":"d"}}, ".[].b")) - assert(["c","d"] == load_dot_notation({"a":{"b":["c"], "b2":["d"]}}, ".a.[].0")) - assert(["c","d"] == load_dot_notation({"a":{"b":["c"], "b2":["d"]}}, ".a[].0")) - assert(["c","d"] == load_dot_notation(["c", "d"], ".")) - assert(["c","d"] == load_dot_notation(["c", "d"], "[]")) + for i in [ + "a" == load_dot_notation("a", "."), + ["a"] == load_dot_notation(["a"], "."), + "b" == load_dot_notation({"a":"b"}, ".a"), + "c" == load_dot_notation({"a":{"b":"c"}}, ".a.b"), + "c" == load_dot_notation({"a":{"b":["c"]}}, ".a.b.0"), + ["c","d"] == load_dot_notation({"a":{"b":"c"}, "a2":{"b":"d"}}, ".[].b"), + ["c","d"] == load_dot_notation({"a":{"b":["c"], "b2":["d"]}}, ".a.[].0"), + ["c","d"] == load_dot_notation({"a":{"b":["c"], "b2":["d"]}}, ".a[].0"), + ["c","d"] == load_dot_notation(["c", "d"], "."), + ["c","d"] == load_dot_notation(["c", "d"], "[]"), + ]: + if not i: + raise Exception(i) test_load_dot_notation() class Reactor(threading.Thread): @@ -185,7 +173,7 @@ class Reactor(threading.Thread): log(f"hotwords: {self.load_hotwords()}") def new_load_hotwords(): - p = environ.get("HOTWORDS", None) + p = os.environ.get("HOTWORDS", None) if not p: def load_nothing(): return [] @@ -227,7 +215,7 @@ class Reactor(threading.Thread): def handle(self, text): hotwords = self.load_hotwords() - if environ.get("DEBUG", None): + if os.environ.get("DEBUG", None): log(f"seeking {hotwords} in {text}") if not hotwords: log(text) @@ -243,16 +231,16 @@ class Actor(threading.Thread): threading.Thread.__init__(self) self.inq = inq self.handle = self.handle_stderr - if environ.get("STDOUT", "") == "true": + if os.environ.get("STDOUT", "") == "true": self.handle = self.handle_stdout - elif environ.get("SIGUSR2", ""): + elif os.environ.get("SIGUSR2", ""): self.pid = int(environ["SIGUSR2"]) self.handle = self.handle_signal - elif environ.get("URL", ""): + elif os.environ.get("URL", ""): self.url = environ["URL"] self.handle = self.handle_url - self.headers = [i.split("=")[:2] for i in environ.get("HEADERS", "").split("//") if i] - self.body = environ.get("BODY", '{"hotword":"{{hotword}}","context":"{{context}}"}') + self.headers = [i.split("=")[:2] for i in os.environ.get("HEADERS", "").split("//") if i] + self.body = os.environ.get("BODY", '{"hotword":"{{hotword}}","context":"{{context}}"}') log(self.headers) def run(self): @@ -273,7 +261,7 @@ class Actor(threading.Thread): def handle_signal(self, hotword, context): self.handle_stderr(hotword, context) - kill(self.pid, signal.SIGUSR2) + os.kill(self.pid, signal.SIGUSR2) def handle_url(self, hotword, context): self.handle_stderr(hotword, context) @@ -288,11 +276,26 @@ class Actor(threading.Thread): body = self.body body = body.replace("{{hotword}}", hotword) body = body.replace("{{context}}", context) - if environ.get("DEBUG", "") : + if os.environ.get("DEBUG", "") : log("POST", self.url, headers, body) requests.post(self.url, headers=headers, data=body) except Exception as e: log("Actor.handle_url:", e) +def main(): + managerToParserQ = queue.Queue(maxsize=1) + readerToParserQ = queue.Queue(maxsize=10) + parserToReactorQ = queue.Queue(maxsize=10) + reactorToActorQ = queue.Queue(maxsize=10) + threads = [ + Manager(managerToParserQ), + Reader(managerToParserQ, readerToParserQ), + Parser(readerToParserQ, parserToReactorQ), + Reactor(parserToReactorQ, reactorToActorQ), + Actor(reactorToActorQ), + ] + [t.start() for t in threads] + [t.join() for t in threads] + if __name__ == "__main__": main()