cheap wins toward codon

master
bel 2023-03-29 21:22:09 -06:00
parent 6882b50e99
commit 22b6cf9446
1 changed files with 42 additions and 39 deletions

View File

@ -4,26 +4,10 @@ import threading
import queue import queue
import signal import signal
import sys import sys
from os import environ import os
from os import kill
import requests import requests
import yaml 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): def log(*args):
print(">", *args, file=sys.stderr) print(">", *args, file=sys.stderr)
@ -60,7 +44,7 @@ class Manager(threading.Thread):
class Reader(threading.Thread): class Reader(threading.Thread):
def __init__(self, inq, outq): def __init__(self, inq, outq):
threading.Thread.__init__(self) 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: if not self.name:
for index, name in enumerate(sr.Microphone.list_microphone_names()): 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)) 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() return not self.inq.empty()
def _run(self, mic): def _run(self, mic):
mic_timeout = int(environ.get("MIC_TIMEOUT", 5)) mic_timeout = int(os.environ.get("MIC_TIMEOUT", 5))
r = sr.Recognizer() r = sr.Recognizer()
return r.listen( return r.listen(
mic, mic,
@ -126,7 +110,7 @@ class Parser(threading.Thread):
def _run(self, clip): def _run(self, clip):
r = sr.Recognizer() 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): def load_dot_notation(v, s):
items = s.replace("[]", ".[]").split(".") items = s.replace("[]", ".[]").split(".")
@ -164,16 +148,20 @@ def _load_dot_notation(v, items):
return v return v
def test_load_dot_notation(): def test_load_dot_notation():
assert("a" == load_dot_notation("a", ".")) for i in [
assert(["a"] == load_dot_notation(["a"], ".")) "a" == load_dot_notation("a", "."),
assert("b" == load_dot_notation({"a":"b"}, ".a")) ["a"] == load_dot_notation(["a"], "."),
assert("c" == load_dot_notation({"a":{"b":"c"}}, ".a.b")) "b" == load_dot_notation({"a":"b"}, ".a"),
assert("c" == load_dot_notation({"a":{"b":["c"]}}, ".a.b.0")) "c" == load_dot_notation({"a":{"b":"c"}}, ".a.b"),
assert(["c","d"] == load_dot_notation({"a":{"b":"c"}, "a2":{"b":"d"}}, ".[].b")) "c" == load_dot_notation({"a":{"b":["c"]}}, ".a.b.0"),
assert(["c","d"] == load_dot_notation({"a":{"b":["c"], "b2":["d"]}}, ".a.[].0")) ["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")) ["c","d"] == load_dot_notation({"a":{"b":["c"], "b2":["d"]}}, ".a.[].0"),
assert(["c","d"] == load_dot_notation(["c", "d"], ".")) ["c","d"] == load_dot_notation({"a":{"b":["c"], "b2":["d"]}}, ".a[].0"),
assert(["c","d"] == load_dot_notation(["c", "d"], "[]")) ["c","d"] == load_dot_notation(["c", "d"], "."),
["c","d"] == load_dot_notation(["c", "d"], "[]"),
]:
if not i:
raise Exception(i)
test_load_dot_notation() test_load_dot_notation()
class Reactor(threading.Thread): class Reactor(threading.Thread):
@ -185,7 +173,7 @@ class Reactor(threading.Thread):
log(f"hotwords: {self.load_hotwords()}") log(f"hotwords: {self.load_hotwords()}")
def new_load_hotwords(): def new_load_hotwords():
p = environ.get("HOTWORDS", None) p = os.environ.get("HOTWORDS", None)
if not p: if not p:
def load_nothing(): def load_nothing():
return [] return []
@ -227,7 +215,7 @@ class Reactor(threading.Thread):
def handle(self, text): def handle(self, text):
hotwords = self.load_hotwords() hotwords = self.load_hotwords()
if environ.get("DEBUG", None): if os.environ.get("DEBUG", None):
log(f"seeking {hotwords} in {text}") log(f"seeking {hotwords} in {text}")
if not hotwords: if not hotwords:
log(text) log(text)
@ -243,16 +231,16 @@ class Actor(threading.Thread):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.inq = inq self.inq = inq
self.handle = self.handle_stderr self.handle = self.handle_stderr
if environ.get("STDOUT", "") == "true": if os.environ.get("STDOUT", "") == "true":
self.handle = self.handle_stdout self.handle = self.handle_stdout
elif environ.get("SIGUSR2", ""): elif os.environ.get("SIGUSR2", ""):
self.pid = int(environ["SIGUSR2"]) self.pid = int(environ["SIGUSR2"])
self.handle = self.handle_signal self.handle = self.handle_signal
elif environ.get("URL", ""): elif os.environ.get("URL", ""):
self.url = environ["URL"] self.url = environ["URL"]
self.handle = self.handle_url self.handle = self.handle_url
self.headers = [i.split("=")[:2] for i in environ.get("HEADERS", "").split("//") if i] self.headers = [i.split("=")[:2] for i in os.environ.get("HEADERS", "").split("//") if i]
self.body = environ.get("BODY", '{"hotword":"{{hotword}}","context":"{{context}}"}') self.body = os.environ.get("BODY", '{"hotword":"{{hotword}}","context":"{{context}}"}')
log(self.headers) log(self.headers)
def run(self): def run(self):
@ -273,7 +261,7 @@ class Actor(threading.Thread):
def handle_signal(self, hotword, context): def handle_signal(self, hotword, context):
self.handle_stderr(hotword, context) self.handle_stderr(hotword, context)
kill(self.pid, signal.SIGUSR2) os.kill(self.pid, signal.SIGUSR2)
def handle_url(self, hotword, context): def handle_url(self, hotword, context):
self.handle_stderr(hotword, context) self.handle_stderr(hotword, context)
@ -288,11 +276,26 @@ class Actor(threading.Thread):
body = self.body body = self.body
body = body.replace("{{hotword}}", hotword) body = body.replace("{{hotword}}", hotword)
body = body.replace("{{context}}", context) body = body.replace("{{context}}", context)
if environ.get("DEBUG", "") : if os.environ.get("DEBUG", "") :
log("POST", self.url, headers, body) log("POST", self.url, headers, body)
requests.post(self.url, headers=headers, data=body) requests.post(self.url, headers=headers, data=body)
except Exception as e: except Exception as e:
log("Actor.handle_url:", 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__": if __name__ == "__main__":
main() main()