summaryrefslogtreecommitdiffstats
path: root/Scripts/browser_src.py
blob: befb2db709ec3514936b717bfd0a17c8fbd04c19 (plain)
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
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 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)
        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()