This repository was archived by the owner on Mar 5, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNetworking.py
More file actions
120 lines (94 loc) · 3.8 KB
/
Copy pathNetworking.py
File metadata and controls
120 lines (94 loc) · 3.8 KB
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
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import json, os
from autobahn.websocket import WebSocketServerFactory, WebSocketServerProtocol
from autobahn.websocket import listenWS
from twisted.internet.protocol import Factory, Protocol
from twisted.protocols.basic import LineReceiver
from collections import Mapping
API_KEY = os.environ['SYDROID_API_KEY']
def diffed(original, challenger):
result = challenger.copy()
for k in challenger:
if k in original:
if isinstance(challenger[k], Mapping):
result[k] = diffed(original[k], challenger[k])
if not len(result[k]):
del result[k]
else:
if original[k] == challenger[k]:
del result[k]
return result
class SydroidWebsocketBroadcaster(WebSocketServerProtocol):
def __init__(self):
self.api_key = ""
self.cache = {}
self.throttler = 0
def is_authenticated(self):
return self.api_key == API_KEY
def onOpen(self):
self.factory.clients.append(self)
def connectionLost(self, reason=None):
WebSocketServerProtocol.connectionLost(self, reason)
if self in self.factory.clients:
self.factory.clients.remove(self)
def onMessage(self, data, binary):
if binary:
return
if self.is_authenticated():
if self.factory.on_receive is not None:
self.factory.on_receive(data)
else:
if data.startswith("LOGIN="):
self.api_key = data[6:]
if not self.is_authenticated():
self.sendMessage({"type": "error", "reason": "Wrong API key."})
self.failConnection(WebSocketServerProtocol.CLOSE_STATUS_CODE_INVALID_PAYLOAD)
else:
print " ! Wrong packet received, closing (api_key = " + self.api_key + ")"
self.failConnection(WebSocketServerProtocol.CLOSE_STATUS_CODE_UNSUPPORTED_DATA)
def smart_send(self, message):
if self.throttler % 10:
diff = diffed(self.cache, message)
diff["type"] = "diff_status"
self.sendMessage(json.dumps(diff).strip('\n').encode('utf-8'))
else:
self.sendMessage(json.dumps(message).strip('\n').encode('utf-8'))
self.cache = message
self.throttler += 1
pass
class SydroidWebsocketFactory(WebSocketServerFactory):
protocol = SydroidWebsocketBroadcaster
def __init__(self, url, debug=None, debug_code_path=None,
on_receive=None):
WebSocketServerFactory.__init__(self, url, debug, debug_code_path)
self.setProtocolOptions(allowHixie76=True)
self.clients = []
self.on_receive = on_receive
def broadcast(self, message):
for client in self.clients:
if client.is_authenticated():
client.sendMessage(message.strip('\n').encode('utf-8'))
def smart_broadcast(self, message):
for client in self.clients:
if client.is_authenticated():
client.smart_send(message)
pass
class SydroidLiquidsoapProtocol(LineReceiver):
delimiter = '\n'
def __init__(self, transport):
LineReceiver(self, transport)
self.factory.presence.append(self)
def connectionLost(self, reason=None):
self.factory.presence.remove(self)
def lineReceived(self, line):
if self.factory.on_receive is not None:
self.factory.on_receive(line)
class SydroidLiquidsoapFactory(Factory):
protocol = SydroidLiquidsoapProtocol
def __init__(self, on_receive=None):
self.on_receive = on_receive
self.presence = []
def broadcast(self, mesg):
for handler in self.presence:
handler.transport.write(mesg.strip('\n').encode('utf-8'))