Sebastiankay commited on
Commit
7b1b425
·
verified ·
1 Parent(s): f9e1e82

Create server.py

Browse files
Files changed (1) hide show
  1. server.py +155 -0
server.py ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from fastapi.responses import HTMLResponse
4
+ from fastapi.staticfiles import StaticFiles
5
+ from fastapi.templating import Jinja2Templates
6
+ import json
7
+ import uvicorn
8
+
9
+ app = FastAPI()
10
+
11
+ # Configure CORS
12
+ app.add_middleware(
13
+ CORSMiddleware,
14
+ allow_origins=["*"],
15
+ allow_credentials=True,
16
+ allow_methods=["*"],
17
+ allow_headers=["*"],
18
+ )
19
+
20
+ # Serve static files
21
+ app.mount("/static", StaticFiles(directory="static"), name="static")
22
+
23
+ # Set up Jinja2 templates
24
+ templates = Jinja2Templates(directory="templates")
25
+
26
+ with open("data.json", "r", encoding="utf8") as file:
27
+ maps_data = json.load(file)
28
+
29
+
30
+ with open("static/map.html", "r", encoding="utf-8") as f:
31
+ map_html_template = f.read()
32
+
33
+
34
+ @app.get("/api/map/{normalized_name}")
35
+ async def get_map_data(normalized_name: str):
36
+ map_entry = maps_data.get(normalized_name)
37
+ if map_entry:
38
+ return map_entry
39
+ return {"error": "Map not found"}
40
+
41
+
42
+ @app.get("/", response_class=HTMLResponse)
43
+ async def read_index(request: Request):
44
+ return templates.TemplateResponse("index.html", {"request": request, "maps": maps_data})
45
+
46
+
47
+ @app.get("/map/{normalized_name}", response_class=HTMLResponse)
48
+ async def get_map_page(normalized_name: str):
49
+ # Optional: Prüfen, ob die Map existiert
50
+ if normalized_name not in maps_data:
51
+ return HTMLResponse(content="<h1>Map not found</h1>", status_code=404)
52
+
53
+ # Gib einfach die statische HTML-Seite zurück
54
+ return HTMLResponse(content=map_html_template)
55
+
56
+
57
+ # @app.get("/map/{normalized_name}", response_class=HTMLResponse)
58
+ # async def get_map_by_normalized_name(request: Request, normalized_name: str):
59
+ # map_entry = maps_data.get(normalized_name)
60
+ # if map_entry:
61
+ # filtered_maps = [map_entry]
62
+ # else:
63
+ # filtered_maps = []
64
+ # return templates.TemplateResponse("map.html", {"request": request, "maps": filtered_maps})
65
+
66
+
67
+ class ConnectionManager:
68
+ def __init__(self):
69
+ self.groups: dict[str, set[WebSocket]] = {}
70
+ self.connections: dict[WebSocket, str] = {}
71
+
72
+ async def connect(self, websocket: WebSocket):
73
+ await websocket.accept()
74
+
75
+ def disconnect(self, websocket: WebSocket):
76
+ if websocket in self.connections:
77
+ group_name = self.connections[websocket]
78
+ self.remove_from_group(websocket, group_name)
79
+
80
+ async def join_group(self, websocket: WebSocket, group_name: str):
81
+ # Remove from previous group if exists
82
+ if websocket in self.connections:
83
+ old_group = self.connections[websocket]
84
+ self.remove_from_group(websocket, old_group)
85
+
86
+ # Add to new group
87
+ if group_name not in self.groups:
88
+ self.groups[group_name] = set()
89
+ self.groups[group_name].add(websocket)
90
+ self.connections[websocket] = group_name
91
+ print(f"Client joined group '{group_name}'")
92
+
93
+ def remove_from_group(self, websocket: WebSocket, group_name: str):
94
+ if group_name in self.groups and websocket in self.groups[group_name]:
95
+ self.groups[group_name].remove(websocket)
96
+ if len(self.groups[group_name]) == 0:
97
+ del self.groups[group_name]
98
+ print(f"Group '{group_name}' deleted (no members)")
99
+ if websocket in self.connections:
100
+ del self.connections[websocket]
101
+ print(f"Client removed from group '{group_name}'")
102
+
103
+ async def broadcast_to_group(self, message: str, group_name: str):
104
+ if group_name in self.groups:
105
+ for connection in self.groups[group_name]:
106
+ await connection.send_text(message)
107
+
108
+
109
+ manager = ConnectionManager()
110
+
111
+
112
+ @app.websocket("/ws")
113
+ async def websocket_endpoint(websocket: WebSocket):
114
+ await manager.connect(websocket)
115
+ try:
116
+ while True:
117
+ data = await websocket.receive_text()
118
+ try:
119
+ message = json.loads(data)
120
+ # Handle join messages
121
+ if message.get('type') == 'join':
122
+ group_name = message.get('group')
123
+ if group_name:
124
+ await manager.join_group(websocket, group_name)
125
+ else:
126
+ error = json.dumps({
127
+ "type": "error",
128
+ "message": "Missing group name in join request"
129
+ })
130
+ await websocket.send_text(error)
131
+
132
+ # Broadcast all other messages to the group
133
+ else:
134
+ if websocket in manager.connections:
135
+ group_name = manager.connections[websocket]
136
+ await manager.broadcast_to_group(data, group_name)
137
+ else:
138
+ error = json.dumps({
139
+ "type": "error",
140
+ "message": "Join a group before sending messages"
141
+ })
142
+ await websocket.send_text(error)
143
+
144
+ except json.JSONDecodeError:
145
+ # Handle non-JSON messages by broadcasting directly
146
+ if websocket in manager.connections:
147
+ group_name = manager.connections[websocket]
148
+ await manager.broadcast_to_group(data, group_name)
149
+
150
+ except WebSocketDisconnect:
151
+ manager.disconnect(websocket)
152
+
153
+
154
+ if __name__ == "__main__":
155
+ uvicorn.run(app, host="0.0.0.0", port=8000)