1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
from transcribe_pipeline import StreamingPlugin, TranscriptCommit
from urllib.parse import urlparse
import copy
import json
import http.server
import os
import socketserver
import threading
import time
import transcribe_pipeline
import typing
class HTTPServer:
def __init__(self, port: int):
self.port = port
self.route_map = {}
self.httpd = None
def register_file_handler(self, http_method: str, path: str, file_path: str):
print(f"File handler registered at {os.getcwd()}")
def handler():
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
return 200, f.read().replace('%PORT%', str(self.port)), 'text/html'
else:
return 404, {'error': 'file not found'}, 'application/json'
self.route_map[(http_method, path)] = handler
def register_json_handler(self, http_method: str, path: str, handler):
self.route_map[(http_method, path)] = handler
def run(self):
def handler(*args, **kwargs):
MyHandler(http_server_instance=self, *args, **kwargs)
with socketserver.TCPServer(("", self.port), handler) as httpd:
self.httpd = httpd
print(f"Webserver running at port {self.port}")
httpd.serve_forever()
print(f"Webserver exiting")
self.httpd = None
def stop(self):
if self.httpd:
self.httpd.shutdown()
class MyHandler(http.server.BaseHTTPRequestHandler):
def __init__(self, *args, http_server_instance=None, **kwargs):
self.http_server_instance = http_server_instance
super().__init__(*args, **kwargs)
def log_message(self, format, *args):
# TODO log if cfg["debug_mode_enabled"] is set
return
def do_GET(self):
self.handle_request('GET')
def handle_request(self, method: str):
parsed_path = urlparse(self.path)
if (method, parsed_path.path) in self.http_server_instance.route_map:
status_code, response_content, content_type = \
self.http_server_instance.route_map[(method, parsed_path.path)]()
self.send_response(status_code)
self.send_header('Content-Type', content_type)
self.end_headers()
if content_type == 'application/json':
self.wfile.write(json.dumps(response_content).encode('utf-8'))
else:
self.wfile.write(response_content.encode('utf-8'))
else:
self.send_response(404)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({'error': 'not found'}).encode('utf-8'))
class BrowserSource(StreamingPlugin):
def __init__(self, cfg: typing.Dict):
port = cfg["browser_src_port"]
print(f"Browser source running on port {port}")
self.commits = []
self.preview_commit = None
self.http_server = HTTPServer(port)
self.http_server.register_json_handler('GET', '/api/v0/transcript', self.get_transcript_json)
index_html_path = os.path.join("Resources", "BrowserSource", "index.html")
self.http_server.register_file_handler('GET', '/', index_html_path)
self.http_server.register_file_handler('GET', '/index.html', index_html_path)
# Start the HTTP server in a new thread
self.server_thread = threading.Thread(target=self.run)
self.server_thread.start()
def transform(self, commit: TranscriptCommit) -> TranscriptCommit:
original_commit = commit
commit = copy.deepcopy(original_commit)
del commit.audio
if commit.delta:
self.commits.append(commit)
# Limit commits to last N.
now = time.time()
self.commits = [commit for commit in self.commits]
max_commits = 10
if len(self.commits) > max_commits:
self.commits = self.commits[-int(max_commits/2):]
self.preview_commit = commit
return original_commit
# return (http_code, body, content_type)
def get_transcript_json(self) -> typing.Tuple[int, str, str]:
processed_commits = [vars(commit) for commit in self.commits]
transcript_data = {
'commits': processed_commits,
'preview': vars(self.preview_commit) if self.preview_commit else None,
'ts': time.time()
}
return 200, json.dumps(transcript_data), 'text/json'
def run(self):
self.http_server.run()
def stop(self):
self.http_server.stop()
self.server_thread.join()
# Example usage
def my_callback() -> typing.Tuple[int, typing.Dict[str, str]]:
return 200, {'message': 'Hello, world!'}, 'text/json'
if __name__ == '__main__':
server = HTTPServer(port=8080)
server.register_json_handler('GET', '/api/v0/transcript', my_callback)
server.run()
|