Merged Routing.py, constants for everything, encoding fixes for js port
Routing.py is no more! The split made sense when ESock was used for all networking, now it's really just a hassle to import from two different files. CONSTANTS_FOR_EVERYTHING = 1 In case of mangled utf8 chars that throw encoding errors there is now a "last resort". If that fails too, the data conversion behaves just like before.
This commit is contained in:
parent
c2c36efd0a
commit
0c88b7c161
1 changed files with 52 additions and 8 deletions
|
@ -1,6 +1,5 @@
|
||||||
import Logging
|
import Logging
|
||||||
import gzip
|
import gzip
|
||||||
import Routing
|
|
||||||
import struct
|
import struct
|
||||||
import json
|
import json
|
||||||
from Utils import capture_trace
|
from Utils import capture_trace
|
||||||
|
@ -35,12 +34,53 @@ PACK_FORMAT = "BH"
|
||||||
METADATA_LENGTH = struct.calcsize(PACK_FORMAT)
|
METADATA_LENGTH = struct.calcsize(PACK_FORMAT)
|
||||||
|
|
||||||
|
|
||||||
|
class Route:
|
||||||
|
def run(self, data, handler):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def start(self, handler):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def create_routes(routes):
|
||||||
|
routes = routes.copy()
|
||||||
|
for prefix in routes:
|
||||||
|
if type(routes[prefix]) is tuple or type(routes[prefix]) is list:
|
||||||
|
routes[prefix] = routes[prefix][0](**routes[prefix][1])
|
||||||
|
return routes
|
||||||
|
|
||||||
|
|
||||||
|
def launch_routes(created_routes, handler):
|
||||||
|
for prefix in created_routes:
|
||||||
|
try:
|
||||||
|
created_routes[prefix].start(handler)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def create_exchange_map(routes):
|
||||||
|
exchange_map = {0 : "meta"}
|
||||||
|
exchange_id = 1
|
||||||
|
for route in routes:
|
||||||
|
if route != "meta":
|
||||||
|
exchange_map[exchange_id] = route
|
||||||
|
exchange_id += 1
|
||||||
|
return exchange_map
|
||||||
|
|
||||||
|
|
||||||
|
def validate_exchange_map(routes):
|
||||||
|
for key in routes:
|
||||||
|
if not type(key) is int and type(routes[key]) is str:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class ConvertFailedError(ValueError):
|
class ConvertFailedError(ValueError):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(ValueError, self).__init__("conversion failed (invalid data type supplied)")
|
super(ValueError, self).__init__("conversion failed (invalid data type supplied)")
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta(Route):
|
||||||
def run(self, data, handler):
|
def run(self, data, handler):
|
||||||
if type(data) is dict:
|
if type(data) is dict:
|
||||||
handler.peer_exchange_routes = data
|
handler.peer_exchange_routes = data
|
||||||
|
@ -55,7 +95,7 @@ class Meta:
|
||||||
pass
|
pass
|
||||||
if handler.debug:
|
if handler.debug:
|
||||||
Logging.info("Launching routes.")
|
Logging.info("Launching routes.")
|
||||||
Routing.launch_routes(handler.routes, handler)
|
launch_routes(handler.routes, handler)
|
||||||
if handler.debug:
|
if handler.debug:
|
||||||
Logging.info("Routes launched.")
|
Logging.info("Routes launched.")
|
||||||
if type(data) is int:
|
if type(data) is int:
|
||||||
|
@ -97,14 +137,19 @@ def pack_message(data, exchange_route,
|
||||||
|
|
||||||
|
|
||||||
def parse_metadata(message):
|
def parse_metadata(message):
|
||||||
metadata = struct.unpack(PACK_FORMAT, message[:4])
|
metadata = struct.unpack(PACK_FORMAT, message[:METADATA_LENGTH])
|
||||||
return REVERSE_DATA_TYPES[metadata[0]], metadata[1]
|
return REVERSE_DATA_TYPES[metadata[0]], metadata[1]
|
||||||
|
|
||||||
|
|
||||||
def convert_data(data, data_type, debug=False):
|
def convert_data(data, data_type, debug=False):
|
||||||
try:
|
try:
|
||||||
if data_type == str:
|
if data_type == str:
|
||||||
|
try:
|
||||||
data = data.decode()
|
data = data.decode()
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
Logging.warning("Unicode characters are not properly encoded. "
|
||||||
|
"Falling back to unicode_escape.")
|
||||||
|
data = data.decode("unicode_escape")
|
||||||
elif data_type == int:
|
elif data_type == int:
|
||||||
data = int(data.decode())
|
data = int(data.decode())
|
||||||
elif data_type == float:
|
elif data_type == float:
|
||||||
|
@ -130,9 +175,9 @@ class Shared:
|
||||||
def setup(self, routes, debug=False):
|
def setup(self, routes, debug=False):
|
||||||
self.routes = routes
|
self.routes = routes
|
||||||
self.routes["meta"] = Meta()
|
self.routes["meta"] = Meta()
|
||||||
self.routes = Routing.create_routes(self.routes)
|
self.routes = create_routes(self.routes)
|
||||||
self.reverse_routes = reverse_dict(self.routes)
|
self.reverse_routes = reverse_dict(self.routes)
|
||||||
self.exchange_routes = Routing.create_exchange_map(self.routes)
|
self.exchange_routes = create_exchange_map(self.routes)
|
||||||
self.reverse_exchange_routes = reverse_dict(self.exchange_routes)
|
self.reverse_exchange_routes = reverse_dict(self.exchange_routes)
|
||||||
# Peer routes have not been received yet. As per convention the meta route
|
# Peer routes have not been received yet. As per convention the meta route
|
||||||
# has to exist and we need it for our first send to succeed (otherwise it
|
# has to exist and we need it for our first send to succeed (otherwise it
|
||||||
|
@ -159,7 +204,6 @@ class Shared:
|
||||||
|
|
||||||
def patched_received_message(self, message):
|
def patched_received_message(self, message):
|
||||||
message = message.data
|
message = message.data
|
||||||
print(message)
|
|
||||||
data_type, m_route = parse_metadata(message)
|
data_type, m_route = parse_metadata(message)
|
||||||
try:
|
try:
|
||||||
route = self.exchange_routes[m_route]
|
route = self.exchange_routes[m_route]
|
||||||
|
|
Reference in a new issue