aboutsummaryrefslogtreecommitdiffstats
path: root/termcast.py
blob: c5495cf721604d828825b787b161b90724991702 (plain) (blame)
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
import json
import re

import vt100

class Handler(object):
    def __init__(self, rows, cols):
        self.rows = rows
        self.cols = cols
        self.buf = b''
        self.vt = vt100.vt100(rows, cols)

    def process(self, data):
        self.buf += data
        clear = self.buf.rfind(b"\033[2J")
        if clear != -1:
            self.buf = self.buf[clear + 4:]
        self.vt.process(data)

    def get_term(self):
        term = ''
        for i in range(0, self.rows):
            for j in range(0, self.cols):
                term += self.vt.cell(i, j).contents()
            term += "\n"

        return term[:-1]

class Connection(object):
    def __init__(self, client, connection_id, publisher):
        self.client = client
        self.connection_id = connection_id
        self.publisher = publisher

    def run(self):
        buf = b''
        while len(buf) < 1024 and b"\n" not in buf:
            buf += self.client.recv(1024)

        pos = buf.find(b"\n")
        if pos == -1:
            print("no authentication found")
            return

        auth = buf[:pos]
        buf = buf[pos+1:]

        auth_re = re.compile(b'^hello ([^ ]+) ([^ ]+)$')
        m = auth_re.match(auth)
        if m is None:
            print("no authentication found (%s)" % auth)
            return

        print(b"got auth: " + auth)
        self.name = m.group(1)
        self.client.send(b"hello, " + self.name + b"\n")

        extra_data = {}
        extra_data_re = re.compile(b'^\033\[H\000([^\377]*)\377\033\[H\033\[2J(.*)$')
        m = extra_data_re.match(buf)
        if m is not None:
            extra_data_json = m.group(1)
            extra_data = json.loads(extra_data_json.decode('utf-8'))
            buf = m.group(2)

        if "geometry" in extra_data:
            self.handler = Handler(extra_data["geometry"][1], extra_data["geometry"][0])
        else:
            self.handler = Handler(24, 80)

        self.handler.process(buf)
        while True:
            buf = self.client.recv(1024)
            if len(buf) > 0:
                self.publisher.notify("new_data", self.connection_id, self.handler.buf, buf)
                self.handler.process(buf)
            else:
                return

    def msg_new_viewer(self, connection_id):
        # XXX restore this once we start passing in meaningful connection ids
        # if connection_id != self.connection_id:
        #     return
        self.publisher.notify("new_data", self.connection_id, self.handler.buf, b'')

    def request_get_streamers(self):
        return {
            "name": self.name,
            "id": self.connection_id,
        }