Spaces:
Paused
Paused
| import asyncio | |
| import json | |
| import os | |
| import secrets | |
| import signal | |
| import subprocess | |
| import websockets | |
| import shutil | |
| #from connect4 import PLAYER1, PLAYER2, Connect4 | |
| #from user import User | |
| __all__ = ["User",] | |
| class User: | |
| """ | |
| A Connect user . | |
| """ | |
| def __init__(self): | |
| pass | |
| import requests | |
| from watchdog.observers import Observer | |
| from watchdog.events import FileSystemEventHandler | |
| class FileHandler(FileSystemEventHandler): | |
| def __init__(self, websocket,connected): | |
| super().__init__() | |
| self.websocket = websocket | |
| self.connected = connected | |
| def on_modified(self, event): | |
| if event.is_directory: | |
| return | |
| with open(event.src_path, 'r', encoding='utf-8') as file: | |
| content = file.read() | |
| # print(f'File {event.src_path} has been modified.') | |
| new_event = { | |
| "type": "file-modifie", | |
| "content": content, | |
| "path": event.src_path, | |
| } | |
| websockets.broadcast(self.connected,json.dumps(new_event)) | |
| # websockets.broadcast(self.connected,f'File {event.src_path} has been modified.') | |
| def on_created(self, event): | |
| if event.is_directory: | |
| new_event = { | |
| "type": "folder-create", | |
| "path": event.src_path, | |
| "name": event.src_path.split('/')[-1] | |
| } | |
| # print(new_event) | |
| websockets.broadcast(self.connected,json.dumps(new_event)) | |
| else: | |
| with open(event.src_path, 'r', encoding='utf-8') as file: | |
| content = file.read() | |
| # print(f'File {event.src_path} has been created.') | |
| new_event = { | |
| "type": "file-create", | |
| "content": content, | |
| "path": event.src_path, | |
| "name": event.src_path.split('/')[-1] | |
| } | |
| # print(new_event) | |
| websockets.broadcast(self.connected,json.dumps(new_event)) | |
| # websockets.broadcast(self.connected,f'File {event.src_path} has been created.') | |
| def on_deleted(self, event): | |
| if event.is_directory: | |
| new_event = { | |
| "type": "delete", | |
| "path": event.src_path, | |
| "name": event.src_path.split('/')[-1], | |
| } | |
| websockets.broadcast(self.connected,json.dumps(new_event)) | |
| else: | |
| # print(f'File {event.src_path} has been deleted.') | |
| new_event = { | |
| "type": "delete", | |
| "name": event.src_path.split('/')[-1], | |
| "path": event.src_path, | |
| } | |
| websockets.broadcast(self.connected,json.dumps(new_event)) | |
| def on_moved(self, event): | |
| if event.is_directory: | |
| new_event = { | |
| "type": "rename", | |
| "OldPath": event.src_path, | |
| "oldname": event.src_path.split('/')[-1], | |
| "NewPath": event.dest_path, | |
| "newname": event.dest_path.split('/')[-1], | |
| } | |
| websockets.broadcast(self.connected,json.dumps(new_event)) | |
| else: | |
| # print(f'File {event.src_path} has been renamed to {event.dest_path}.') | |
| new_event = { | |
| "type": "rename", | |
| "OldPath": event.src_path, | |
| "oldname": event.src_path.split('/')[-1], | |
| "NewPath": event.dest_path, | |
| "newname": event.dest_path.split('/')[-1], | |
| } | |
| websockets.broadcast(self.connected,json.dumps(new_event)) | |
| JOIN = {} | |
| WATCH = {} | |
| async def generate_file_structure(path, encoding='utf-8'): | |
| file_structure = {'name': os.path.basename(path), 'type': 'folder', 'path': path, 'children': []} | |
| try: | |
| entries = os.listdir(path) | |
| except FileNotFoundError: | |
| return file_structure # Return an empty structure for non-existing directories | |
| for entry in entries: | |
| entry_path = os.path.join(path, entry) | |
| if os.path.isdir(entry_path): | |
| child_structure =await generate_file_structure(entry_path, encoding) | |
| file_structure['children'].append(child_structure) | |
| elif os.path.isfile(entry_path): | |
| try: | |
| with open(entry_path, 'r', encoding=encoding) as file: | |
| content = file.read() | |
| except UnicodeDecodeError: | |
| content = 'Unable to read content' | |
| file_structure['children'].append({'name': entry, 'type': 'file', 'path': entry_path, 'content': content}) | |
| return file_structure | |
| async def rename_item(websocket, key,project_name, path,rpath,new_name,root, connected): | |
| old_path = os.path.join(os.getcwd(),'projects', key,project_name, rpath) | |
| new_name = new_name | |
| try: | |
| if os.path.exists(old_path): | |
| # Determine the new path | |
| new_path = os.path.join(os.path.dirname(old_path), new_name) | |
| # Rename the file or folder | |
| os.rename(old_path, new_path) | |
| websockets.broadcast(connected,'success') | |
| event = { | |
| "type": "rename-success", | |
| "data": f'{old_path}-->{new_path}', | |
| "path": path, | |
| "new_rpath":rpath, | |
| "name": new_name, | |
| "root":root, | |
| } | |
| websockets.broadcast(connected,json.dumps(event)) | |
| else: | |
| event = { | |
| "type": "rename-failed", | |
| "data": f'{old_path}-->{new_path} failed Item not found', | |
| "old_path": path, | |
| "new_name": new_name, | |
| } | |
| websockets.broadcast(connected,json.dumps(event)) | |
| except Exception as e: | |
| websockets.broadcast(connected,str(e)) | |
| async def delete_item(websocket, key,project_name, path,rpath,targetElementData, connected): | |
| try: | |
| item_path = os.path.join(os.getcwd(), 'projects', key,project_name, rpath) | |
| if os.path.exists(item_path): | |
| if os.path.isdir(item_path): | |
| shutil.rmtree(item_path) # Remove the directory and its contents | |
| elif os.path.isfile(item_path): | |
| os.remove(item_path) # Remove the file | |
| event = { | |
| "type": "delete-success", | |
| "data": path, | |
| "path":path, | |
| "targetElementData":targetElementData, | |
| } | |
| # print(event) | |
| websockets.broadcast(connected,json.dumps(event)) | |
| # websockets.broadcast(connected,'success') | |
| else: | |
| event = { | |
| "type": "delete-failed", | |
| "data": f'{item_path} Item not found', | |
| } | |
| websockets.broadcast(connected,json.dumps(event)) | |
| except Exception as e: | |
| # print(e) | |
| websockets.broadcast(connected,str(e)) | |
| async def get_file_content(websocket, key,project_name, path,rpath,name,connected): | |
| file_path = os.path.join(os.getcwd(), 'projects', key,project_name, rpath) | |
| try: | |
| with open(file_path, 'r', encoding='utf-8') as file: | |
| content = file.read() | |
| event = { | |
| "type": "content", | |
| "content": content, | |
| 'fileName':name, | |
| 'rfilePath':rpath, | |
| 'filePath':path, | |
| } | |
| await websocket.send(json.dumps(event)) | |
| except Exception as e: | |
| event = { | |
| "type": "error", | |
| "message": f"Failed to read file content: {str(e)}", | |
| } | |
| await websocket.send(json.dumps(event)) | |
| async def create_file(websocket, key,project_name, path,name,root,targetElementData,rpath, connected): | |
| file_path = os.path.join(os.getcwd(), 'projects', key,project_name, rpath,name) | |
| # Create the file | |
| with open(file_path, 'w'): | |
| pass | |
| event = { | |
| "type": "file-created", | |
| "data": file_path, | |
| "path": path, | |
| "name": name, | |
| "root":root, | |
| "targetElementData":targetElementData, | |
| } | |
| websockets.broadcast(connected,json.dumps(event)) | |
| async def create_folder(websocket, key,project_name, path,name,root,targetElementData,rpath, connected): | |
| folder_path = os.path.join(os.getcwd(), 'projects', key,project_name, rpath,name) | |
| # Create the folder | |
| os.makedirs(folder_path) | |
| event = { | |
| "type": "folder-created", | |
| "data": folder_path, | |
| "path": path, | |
| "name": name, | |
| "root":root, | |
| "targetElementData":targetElementData, | |
| } | |
| # print(folder_path,'created') | |
| websockets.broadcast(connected,json.dumps(event)) | |
| async def wirte_file(websocket, key,project_name, path, content, connected): | |
| try: | |
| file_path = os.path.join(os.getcwd(), 'projects', key,project_name, path) | |
| file_content = content | |
| with open(file_path, 'w', encoding='utf-8') as file: | |
| file.write(file_content) | |
| event = { | |
| "type": "write-success", | |
| "data": file_path, | |
| "path": path, | |
| "content": content, | |
| } | |
| # websockets.broadcast(connected,json.dumps(event)) | |
| except FileNotFoundError as e: | |
| event = { | |
| "type": "write-error", | |
| "data": e, | |
| } | |
| websockets.broadcast(connected,json.dumps(event)) | |
| async def read_process_output(process, websocket): | |
| async for line in process.stdout: | |
| # print('sending line') | |
| event = { | |
| "type": "terminal-data", | |
| "data": line.strip().decode('utf-8'), | |
| } | |
| await websocket.send(json.dumps(event)) | |
| async for line in process.stderr: | |
| # print(f'error:{line.strip()}') | |
| event = { | |
| "type": "terminal-error", | |
| "data": line.strip().decode('utf-8'), | |
| } | |
| await websocket.send(json.dumps(event)) | |
| async def handle_user_input(websocket,key, process, connected): | |
| while True: | |
| try: | |
| await asyncio.sleep(0.1) | |
| if process.returncode is not None: | |
| break | |
| # message = await websocket.recv() | |
| async for message in websocket: | |
| # user_input = json.loads(message) | |
| # print(user_input) | |
| # print(f'Received user input: {user_input["command"]["command"]}') | |
| # process_input(user_input["command"]["command"], process) | |
| event = json.loads(message) | |
| assert event["type"] == "cmd" | |
| # command = event["command"] | |
| # print(f'Received user input: {event}') | |
| try: | |
| if event["command"]["type"]=="shell": | |
| await asyncio.sleep(0.1) | |
| if process.returncode is not None: | |
| base_path = os.path.join(os.getcwd(), 'projects', key,event["project_name"]) | |
| directory_path = base_path | |
| event_handler = FileHandler(websocket,connected) | |
| observer = Observer() | |
| observer.schedule(event_handler, path=directory_path, recursive=True) | |
| observer.start() | |
| try: | |
| # await execute_command(websocket, key,event["project_name"], event["command"]["command"], connected) | |
| # base_path = os.path.join(os.getcwd(), 'projects', key,event["project_name"]) | |
| print(base_path) | |
| mod_command = f'cd {base_path} && {event["command"]["command"]}' | |
| print(mod_command) | |
| try: | |
| process = await asyncio.create_subprocess_shell( | |
| mod_command, | |
| # cwd=base_path, | |
| stdin=asyncio.subprocess.PIPE, | |
| stdout=asyncio.subprocess.PIPE, | |
| stderr=asyncio.subprocess.PIPE, | |
| # text=True, | |
| ) | |
| async def send_message(message): | |
| # print('sending msg') | |
| # await websocket.send(f'data: {message}') | |
| websockets.broadcast(connected,json.dumps(message) ) | |
| await asyncio.gather( | |
| handle_user_input(websocket,key, process, connected), | |
| read_process_output(process, websocket) | |
| ) | |
| return_code = await process.wait() | |
| if return_code == 0: | |
| # await send_message('Code executed successfully') | |
| pass | |
| else: | |
| # await send_message(f'error:Execution failed with return code {return_code}') | |
| pass | |
| except Exception as e: | |
| await error(websocket, str(e)) | |
| except KeyboardInterrupt: | |
| pass # Handle KeyboardInterrupt to gracefully stop the observer | |
| observer.stop() | |
| observer.join() | |
| else: | |
| process_input(event["command"]["command"], process) | |
| elif event["command"]["type"]=="write": | |
| await wirte_file(websocket, key,event["project_name"], event["path"], event["content"], connected) | |
| elif event["command"]["type"]=="curl": | |
| response = requests.get(event['url']) | |
| event = { | |
| "type": "web-data", | |
| "data": response.text, | |
| } | |
| await websocket.send(json.dumps(event)) | |
| elif event["command"]["type"]=="create": | |
| if event["item"]=="folder": | |
| await create_folder(websocket, key,event["project_name"], event["path"],event["name"],event['root'],event['targetElementData'],event["rpath"], connected) | |
| else: | |
| await create_file(websocket, key,event["project_name"], event["path"],event["name"],event['root'],event['targetElementData'],event["rpath"], connected) | |
| elif event["command"]["type"]=="delete": | |
| await delete_item(websocket, key,event["project_name"], event["path"],event['rpath'],event['targetElementData'], connected) | |
| elif event["command"]["type"]=="get_content": | |
| await get_file_content(websocket, key,event["project_name"],event["filePath"], event["rfilePath"],event["fileName"] ,connected) | |
| elif event["command"]["type"]=="rename": | |
| await rename_item(websocket, key,event["project_name"], event["path"],event['rpath'], event["name"], event["root"], connected) | |
| elif event["command"]["type"]=="join": | |
| await join(websocket, event["join"]) | |
| elif event["command"]["type"]=="sendDir": | |
| data=json.loads(event["file_structure"]) | |
| event = { | |
| "type": "createDir", | |
| "path": data, | |
| "root":event['root'], | |
| } | |
| # websockets.broadcast(connected,json.dumps(event)) | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="createItemUI": | |
| event = { | |
| "type": "createItemUI", | |
| 'targetElementData':event['targetElementData'], | |
| 'data':event['data'] | |
| } | |
| # websockets.broadcast(connected,json.dumps(event)) | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="renameItemInUI": | |
| event = { | |
| "type": "renameItemInUI", | |
| 'path':event['path'], | |
| 'new_path':event['new_path'], | |
| 'name':event['name'], | |
| 'new_rpath':event['new_rpath'], | |
| } | |
| # websockets.broadcast(connected,json.dumps(event)) | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="createFolderUI": | |
| event = { | |
| "type": "createFolderUI", | |
| 'targetElementData':event['targetElementData'], | |
| 'data':event['data'] | |
| } | |
| # websockets.broadcast(connected,json.dumps(event)) | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="removeItemFromUI": | |
| event = { | |
| "type": "removeItemFromUI", | |
| 'targetElementData':event['targetElementData'], | |
| 'path':event['path'] | |
| } | |
| # websockets.broadcast(connected,json.dumps(event)) | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="project": | |
| base_path = os.path.join(os.getcwd(), 'projects',key, event["project_name"]) | |
| data=json.loads(event["file_structure"]) | |
| await create_file_structure(websocket,data, base_path=base_path) | |
| # await rename_item(websocket, key,event["project_name"], event["path"], event["name"], connected) | |
| elif event["command"]["type"]=="collabration": | |
| event = { | |
| "type": "collabration", | |
| 'name': event["name"], | |
| 'line': event["cursorPos-line"], | |
| 'ch': event["cursorPos-ch"], | |
| 'file':event["file"], | |
| 'content': event["content"], | |
| 'color':event["color"] | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="cursor": | |
| event = { | |
| "type": "cursor", | |
| 'offset': event["offset"], | |
| 'userid': event["userid"], | |
| 'userlabel': event["userlabel"], | |
| 'usercolor': event["usercolor"], | |
| 'fileName':event["fileName"], | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="select": | |
| event = { | |
| "type": "select", | |
| 'id': event["id"], | |
| 'startOffset': event["startOffset"], | |
| 'endOffset': event["endOffset"], | |
| 'userid': event["userid"], | |
| 'userlabel': event["userlabel"], | |
| 'usercolor': event["usercolor"], | |
| 'fileName':event["fileName"], | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="addselection": | |
| event = { | |
| "type": "addselection", | |
| 'userid': event["userid"], | |
| 'userlabel': event["userlabel"], | |
| 'usercolor': event["usercolor"], | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="insert": | |
| event = { | |
| "type": "insert", | |
| 'index': event["index"], | |
| 'text': event["text"], | |
| 'userid': event["userid"], | |
| 'userlabel': event["userlabel"], | |
| 'usercolor': event["usercolor"], | |
| 'fileName':event["fileName"], | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="replace": | |
| event = { | |
| "type": "replace", | |
| 'index': event["index"], | |
| 'length': event["length"], | |
| 'text': event["text"], | |
| 'userid': event["userid"], | |
| 'userlabel': event["userlabel"], | |
| 'usercolor': event["usercolor"], | |
| 'fileName':event["fileName"], | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="edelelte": | |
| event = { | |
| "type": "edelelte", | |
| 'index': event["index"], | |
| 'length': event["length"], | |
| 'userid': event["userid"], | |
| 'userlabel': event["userlabel"], | |
| 'usercolor': event["usercolor"], | |
| 'fileName':event["fileName"], | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="keep-alive": | |
| event = { | |
| "type": "keep-alive", | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| else: | |
| # First player starts a new game. | |
| pass | |
| except RuntimeError as exc: | |
| # Send an "error" event if the move was illegal. | |
| await error(websocket, str(exc)) | |
| continue | |
| break | |
| except websockets.ConnectionClosed: | |
| # print("WebSocket connection closed") | |
| break | |
| except Exception as e: | |
| # print(f"Error in input thread: {str(e)}") | |
| pass | |
| def process_input(user_input, process): | |
| if process: | |
| try: | |
| if user_input=='Ctrl+C': | |
| print('process stoping') | |
| process.send_signal(signal.SIGINT) | |
| else: | |
| process.stdin.write(user_input.encode('utf-8') + b'\n') | |
| #process.stdin.flush() | |
| except Exception as e: | |
| # print(f"Error writing to process stdin: {str(e)}") | |
| pass | |
| else: | |
| # print("No process available to write to.") | |
| pass | |
| async def create_file_structure(websocket, data, base_path='.'): | |
| if data['type'] == 'folder': | |
| folder_path = os.path.join(base_path, data['name']) | |
| os.makedirs(folder_path, exist_ok=True) | |
| for child in data['children']: | |
| await create_file_structure(websocket,child, base_path=folder_path) | |
| elif data['type'] == 'file': | |
| file_path = os.path.join(base_path, data['name']) | |
| with open(file_path, 'w', encoding='utf-8') as file: | |
| file.write(data['content']) | |
| event = { | |
| "type": "msg", | |
| "message": "project created", | |
| } | |
| await websocket.send(json.dumps(event)) | |
| async def error(websocket, message): | |
| """ | |
| Send an error message. | |
| """ | |
| event = { | |
| "type": "error", | |
| "message": message, | |
| } | |
| await websocket.send(json.dumps(event)) | |
| async def exe(websocket,connected,key): | |
| """ | |
| Receive and process moves from a player. | |
| """ | |
| # print('in exe') | |
| async for message in websocket: | |
| # Parse a "play" event from the UI. | |
| # print(message) | |
| event = json.loads(message) | |
| assert event["type"] == "cmd" | |
| # command = event["command"] | |
| # print(event) | |
| try: | |
| if event["command"]["type"]=="shell": | |
| base_path = os.path.join(os.getcwd(), 'projects', key,event["project_name"]) | |
| directory_path = base_path | |
| event_handler = FileHandler(websocket,connected) | |
| observer = Observer() | |
| observer.schedule(event_handler, path=directory_path, recursive=True) | |
| observer.start() | |
| try: | |
| # await execute_command(websocket, key,event["project_name"], event["command"]["command"], connected) | |
| # base_path = os.path.join(os.getcwd(), 'projects', key,event["project_name"]) | |
| print(base_path) | |
| mod_command = f'cd {base_path} && {event["command"]["command"]}' | |
| print(mod_command) | |
| try: | |
| process = await asyncio.create_subprocess_shell( | |
| mod_command, | |
| # cwd=base_path, | |
| stdin=asyncio.subprocess.PIPE, | |
| stdout=asyncio.subprocess.PIPE, | |
| stderr=asyncio.subprocess.PIPE, | |
| # text=True, | |
| ) | |
| async def send_message(message): | |
| # print('sending msg') | |
| # await websocket.send(f'data: {message}') | |
| websockets.broadcast(connected,json.dumps(message) ) | |
| await asyncio.gather( | |
| handle_user_input(websocket,key, process, connected), | |
| read_process_output(process, websocket) | |
| ) | |
| return_code = await process.wait() | |
| if return_code == 0: | |
| # await send_message('Code executed successfully') | |
| pass | |
| else: | |
| # await send_message(f'error:Execution failed with return code {return_code}') | |
| pass | |
| except Exception as e: | |
| await error(websocket, str(e)) | |
| except KeyboardInterrupt: | |
| pass # Handle KeyboardInterrupt to gracefully stop the observer | |
| observer.stop() | |
| observer.join() | |
| elif event["command"]["type"]=="write": | |
| await wirte_file(websocket, key,event["project_name"], event["path"], event["content"], connected) | |
| elif event["command"]["type"]=="curl": | |
| response = requests.get(event['url']) | |
| event = { | |
| "type": "web-data", | |
| "data": response.text, | |
| } | |
| await websocket.send(json.dumps(event)) | |
| elif event["command"]["type"]=="create": | |
| if event["item"]=="folder": | |
| await create_folder(websocket, key,event["project_name"], event["path"],event["name"],event['root'],event['targetElementData'],event["rpath"], connected) | |
| else: | |
| await create_file(websocket, key,event["project_name"], event["path"],event["name"],event['root'],event['targetElementData'],event["rpath"], connected) | |
| elif event["command"]["type"]=="delete": | |
| await delete_item(websocket, key,event["project_name"], event["path"],event['rpath'],event['targetElementData'], connected) | |
| elif event["command"]["type"]=="get_content": | |
| await get_file_content(websocket, key,event["project_name"],event["filePath"], event["rfilePath"],event["fileName"] ,connected) | |
| elif event["command"]["type"]=="rename": | |
| await rename_item(websocket, key,event["project_name"], event["path"],event['rpath'], event["name"], event["root"], connected) | |
| elif event["command"]["type"]=="join": | |
| await join(websocket, event["join"]) | |
| elif event["command"]["type"]=="sendDir": | |
| data=json.loads(event["file_structure"]) | |
| event = { | |
| "type": "createDir", | |
| "path": data, | |
| "root":event['root'], | |
| } | |
| # websockets.broadcast(connected,json.dumps(event)) | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="createItemUI": | |
| event = { | |
| "type": "createItemUI", | |
| 'targetElementData':event['targetElementData'], | |
| 'data':event['data'] | |
| } | |
| # websockets.broadcast(connected,json.dumps(event)) | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="renameItemInUI": | |
| event = { | |
| "type": "renameItemInUI", | |
| 'path':event['path'], | |
| 'new_path':event['new_path'], | |
| 'name':event['name'], | |
| 'new_rpath':event['new_rpath'], | |
| } | |
| # websockets.broadcast(connected,json.dumps(event)) | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="createFolderUI": | |
| event = { | |
| "type": "createFolderUI", | |
| 'targetElementData':event['targetElementData'], | |
| 'data':event['data'] | |
| } | |
| # websockets.broadcast(connected,json.dumps(event)) | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="removeItemFromUI": | |
| event = { | |
| "type": "removeItemFromUI", | |
| 'targetElementData':event['targetElementData'], | |
| 'path':event['path'] | |
| } | |
| # websockets.broadcast(connected,json.dumps(event)) | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="project": | |
| base_path = os.path.join(os.getcwd(), 'projects',key, event["project_name"]) | |
| data=json.loads(event["file_structure"]) | |
| await create_file_structure(websocket,data, base_path=base_path) | |
| # await rename_item(websocket, key,event["project_name"], event["path"], event["name"], connected) | |
| elif event["command"]["type"]=="collabration": | |
| event = { | |
| "type": "collabration", | |
| 'name': event["name"], | |
| 'line': event["cursorPos-line"], | |
| 'ch': event["cursorPos-ch"], | |
| 'file':event["file"], | |
| 'content': event["content"], | |
| 'color':event["color"] | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="cursor": | |
| event = { | |
| "type": "cursor", | |
| 'offset': event["offset"], | |
| 'userid': event["userid"], | |
| 'userlabel': event["userlabel"], | |
| 'usercolor': event["usercolor"], | |
| 'fileName':event["fileName"], | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="select": | |
| event = { | |
| "type": "select", | |
| 'id': event["id"], | |
| 'startOffset': event["startOffset"], | |
| 'endOffset': event["endOffset"], | |
| 'userid': event["userid"], | |
| 'userlabel': event["userlabel"], | |
| 'usercolor': event["usercolor"], | |
| 'fileName':event["fileName"], | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="addselection": | |
| event = { | |
| "type": "addselection", | |
| 'userid': event["userid"], | |
| 'userlabel': event["userlabel"], | |
| 'usercolor': event["usercolor"], | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="insert": | |
| event = { | |
| "type": "insert", | |
| 'index': event["index"], | |
| 'text': event["text"], | |
| 'userid': event["userid"], | |
| 'userlabel': event["userlabel"], | |
| 'usercolor': event["usercolor"], | |
| 'fileName':event["fileName"], | |
| 'tabStatus':event['tabStatus'], | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="replace": | |
| event = { | |
| "type": "replace", | |
| 'index': event["index"], | |
| 'length': event["length"], | |
| 'text': event["text"], | |
| 'userid': event["userid"], | |
| 'userlabel': event["userlabel"], | |
| 'usercolor': event["usercolor"], | |
| 'fileName':event["fileName"], | |
| 'tabStatus':event['tabStatus'], | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="edelelte": | |
| event = { | |
| "type": "edelelte", | |
| 'index': event["index"], | |
| 'length': event["length"], | |
| 'userid': event["userid"], | |
| 'userlabel': event["userlabel"], | |
| 'usercolor': event["usercolor"], | |
| 'fileName':event["fileName"], | |
| } | |
| websockets.broadcast(connected, json.dumps(event)) | |
| elif event["command"]["type"]=="keep-alive": | |
| event = { | |
| "type": "keep-alive", | |
| } | |
| else: | |
| # First player starts a new game. | |
| pass | |
| except RuntimeError as exc: | |
| # Send an "error" event if the move was illegal. | |
| await error(websocket, str(exc)) | |
| continue | |
| async def start(websocket,events): | |
| user = User() | |
| connected = {websocket} | |
| join_key = secrets.token_urlsafe(12) | |
| JOIN[join_key] = user, connected | |
| try: | |
| # Send the secret access tokens to the browser of the first player, | |
| # where they'll be used for building "join" and "watch" links. | |
| event = { | |
| "type": "init", | |
| "join": join_key, | |
| } | |
| await websocket.send(json.dumps(event)) | |
| await exe(websocket,connected,join_key) | |
| finally: | |
| del JOIN[join_key] | |
| async def join(websocket, key): | |
| """ | |
| Handle a connection from the second player: join an existing game. | |
| """ | |
| # Find the Connect Four game. | |
| try: | |
| user, connected = JOIN[key] | |
| except KeyError: | |
| await error(websocket, "collabration not found.") | |
| return | |
| # Register to receive moves from this game. | |
| connected.add(websocket) | |
| try: | |
| event = { | |
| "type": "sendDir", | |
| } | |
| websockets.broadcast(connected,json.dumps(event)) | |
| await exe(websocket,connected,key) | |
| finally: | |
| connected.remove(websocket) | |
| async def handler(websocket): | |
| """ | |
| Handle a connection and dispatch it according to who is connecting. | |
| """ | |
| # Receive and parse the "init" event from the UI. | |
| message = await websocket.recv() | |
| event = json.loads(message) | |
| # print(event) | |
| # project_name = event["project_name"] | |
| # assert event["type"] == "init" | |
| if event["type"] == "init": | |
| if "join" in event: | |
| # Second player joins an existing game. | |
| await join(websocket, event["join"]) | |
| else: | |
| # First player starts a new game. | |
| await start(websocket, message) | |
| elif event["type"] == "cmd": | |
| # print('executing commad') | |
| # Execute a command in the project folder. | |
| await execute_command(websocket, event["project_name"], event["command"]) | |
| async def main(): | |
| # Set the stop condition when receiving SIGTERM. | |
| loop = asyncio.get_running_loop() | |
| stop = loop.create_future() | |
| loop.add_signal_handler(signal.SIGTERM, stop.set_result, None) | |
| port = int(os.environ.get("PORT", "7860")) | |
| async with websockets.serve(handler, "0.0.0.0", port): | |
| await stop | |
| if __name__ == "__main__": | |
| asyncio.run(main()) |