Skip to content
This repository was archived by the owner on Aug 9, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
venv/
target/
*.egg-info/
*.egg/
*.pyc
*.pyo
*.pyd
*.swp
*.bak
*.bak.*
*.old
*.old.*
*.orig
*pycache
*.log
*.tmp
*.tmp.*
*.rej
*.orig
*.orig.*
*.rej
__pycache__/
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pyperclip
116 changes: 116 additions & 0 deletions task/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import socket
import random
import string
import pyperclip
from model import Message
from serializer import serialize,extract_messages_from_buffer
from savefile import makefile

def random_id():
charset = string.ascii_letters + string.digits
return ''.join(random.choice(charset) for _ in range(10))

def read_message(conn, buffer):
tmp_buffer = conn.recv(1024)
if not tmp_buffer:
raise ConnectionError("Connection closed by the server")

buffer.extend(tmp_buffer)
message_queue, incomplete_buffer = extract_messages_from_buffer(buffer)

# Clear buffer and store incomplete part
buffer.clear()
buffer.extend(incomplete_buffer)

return message_queue[0]

def send_message(conn, msg):
data = serialize(msg)
conn.sendall(data)

def make_message(msg_type, sender_id, receiver_id):
return Message(
type=msg_type,
sender_id=sender_id,
receiver_id=receiver_id,
msg_id=random_id()
)

def handle(conn):
pyperclip.copy("")

buffer = bytearray()
queue = []
topology = {}
visited = {}
my_id = ""

# Handle the init message to get the ID of our node.
while True:
try:
msg = read_message(conn, buffer)
except Exception as e:
print("Error:", e)
continue

if msg.type == "init":
print("Init message received")
my_id = msg.receiver_id
print("My ID:", my_id)
break

queue.append(my_id)
init_query = make_message("query", my_id, my_id)
visited[my_id] = True
send_message(conn, init_query)

while queue:
try:
msg = read_message(conn, buffer)
except Exception as e:
print("Error:", e)
pyperclip.copy(buffer.decode())
continue

print("Received num of neighbors:", len(msg.n))
print("Receiver:", msg.receiver_id)
print("Sender:", msg.sender_id)

node_id = queue.pop(0)
topology[node_id] = msg.n

for neighbor in msg.n:
if not visited.get(neighbor):
queue.append(neighbor)
query_rpc = make_message("query", my_id, neighbor)

print("Sender:", query_rpc.sender_id)
print("Receiver:", query_rpc.receiver_id)

visited[neighbor] = True
send_message(conn, query_rpc)

print("Topology is created.")

final_msg = Message(
type="topology",
sender_id=my_id,
receiver_id="",
msg_id=random_id(),
topology=topology
)

send_message(conn, final_msg)

def main():
# for docker linux conntinter connections
# host = '172.17.0.1'
host = 'localhost'
port = 12080
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as conn:
conn.connect((host, port))
handle(conn)

if __name__ == "__main__":
main()
makefile()
29 changes: 29 additions & 0 deletions task/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class Message:
def __init__(self, sender_id="", receiver_id="", msg_id="", type="", n=None, topology=None):
self.sender_id = sender_id
self.receiver_id = receiver_id
self.msg_id = msg_id
self.type = type
self.n = n or []
self.topology = topology or {}

def to_dict(self):
return {
"sender_id": self.sender_id,
"receiver_id": self.receiver_id,
"msg_id": self.msg_id,
"type": self.type,
"n": self.n,
"topology": self.topology
}

@staticmethod
def from_dict(data):
return Message(
sender_id=data.get("sender_id"),
receiver_id=data.get("receiver_id"),
msg_id=data.get("msg_id"),
type=data.get("type"),
n=data.get("n"),
topology=data.get("topology")
)
38 changes: 38 additions & 0 deletions task/savefile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import docker
import os
import shutil


print ("Running")
# Initialize Docker client
client = docker.from_env()


local_directory = './repository'
container_directory = '/artifact'
file_name = 'test1.result.json'

# Create the local directory if it doesn't exist
os.makedirs(local_directory, exist_ok=True)
def makefile():

# Run Docker container to generate the JSON file
print("Running Docker container...")
container = client.containers.run(
"ghcr.io/little-bear-labs/lbl-test-proxy:latest",
"sh -c 'echo {\"key\": \"value\"} > /artifact/test1.result.json'",
volumes={os.path.abspath(local_directory): {'bind': container_directory, 'mode': 'rw'}},
detach=True
)
container.wait() # Wait for the container to finish

# Check if the file exists and its size
file_path = os.path.join(local_directory, file_name)
if os.path.exists(file_path):
file_size = os.path.getsize(file_path)
print(f"File {file_name} saved successfully with size {file_size / (1024 * 1024):.2f} MB")
else:
print(f"File {file_name} not found.")

# Cleanup container
container.remove()
24 changes: 24 additions & 0 deletions task/serializer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import json
import pyperclip
from model import Message

def serialize(obj):
return json.dumps(obj.to_dict()).encode()

def deserialize(data, cls):
return cls.from_dict(json.loads(data))

def extract_messages_from_buffer(buffer):
buffer_str = buffer.decode()
valid_buffer = buffer_str[:buffer_str.rfind("}") + 1]
invalid_buffer = buffer_str[buffer_str.rfind("}") + 1:]

pyperclip.copy(valid_buffer)

messages = []
for msg_str in valid_buffer.split("}{"):
msg_str = msg_str if msg_str.endswith("}") else msg_str + "}"
msg = deserialize(msg_str.encode(), Message)
messages.append(msg)

return messages, invalid_buffer.encode()