Javier-Jimenez99 commited on
Commit
b3ea2a5
·
1 Parent(s): f230787

Agregar funciones de prueba y herramientas para la interfaz de OBR

Browse files
Files changed (4) hide show
  1. app.py +5 -21
  2. tools.py → tools/general.py +1 -58
  3. tools/obr.py +255 -0
  4. tools/test.py +129 -0
app.py CHANGED
@@ -18,39 +18,23 @@ from tools.obr import (
18
  insert_map,
19
  clean_map
20
  )
 
21
  from dotenv import load_dotenv
22
  import os
23
 
24
  load_dotenv()
25
 
26
- # === FUNCIÓN DE PRUEBA ===
27
- def test_function(text_input, number_input):
28
- """Función de prueba que combina varias funcionalidades para testing"""
29
- result = {
30
- "text_analysis": letter_counter(text_input, "a"),
31
- "dice_roll": roll_dice(6, number_input),
32
- "coin_flip": coin_flip(number_input),
33
- "input_received": {
34
- "text": text_input,
35
- "number": number_input
36
- }
37
- }
38
- return result
39
-
40
  # === GRADIO INTERFACE ===
41
  demo = gr.TabbedInterface(
42
- [
43
- # Pestaña de pruebas (sin api_name)
44
  gr.Interface(
45
  test_function,
46
  [
47
- gr.Textbox(label="Texto de prueba", placeholder="Escribe algo aquí..."),
48
- gr.Number(label="Número de prueba", value=3, minimum=1, maximum=10)
49
  ],
50
  gr.JSON(label="Resultados de la prueba"),
51
- title="Ventana de Pruebas",
52
- description="Esta ventana es solo para hacer pruebas y no sirve como endpoint.",
53
- api_name=False
54
  ),
55
  gr.Interface(letter_counter, [gr.Textbox(), gr.Textbox()], gr.Textbox(), api_name="letter_counter"),
56
  gr.Interface(prime_factors, gr.Number(), gr.JSON(), api_name="prime_factors"),
 
18
  insert_map,
19
  clean_map
20
  )
21
+ from tools.test import test_function
22
  from dotenv import load_dotenv
23
  import os
24
 
25
  load_dotenv()
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  # === GRADIO INTERFACE ===
28
  demo = gr.TabbedInterface(
29
+ [ # Pestaña de pruebas (sin api_name)
 
30
  gr.Interface(
31
  test_function,
32
  [
33
+ gr.Textbox(label="Tab ID"),
 
34
  ],
35
  gr.JSON(label="Resultados de la prueba"),
36
+ title="Ventana de Pruebas de OBR",
37
+ description="Esta ventana demuestra todas las funcionalidades de OwlBear Rodeo disponibles.",
 
38
  ),
39
  gr.Interface(letter_counter, [gr.Textbox(), gr.Textbox()], gr.Textbox(), api_name="letter_counter"),
40
  gr.Interface(prime_factors, gr.Number(), gr.JSON(), api_name="prime_factors"),
tools.py → tools/general.py RENAMED
@@ -1,10 +1,3 @@
1
- import requests as request
2
- import os
3
- import urllib3
4
-
5
- # Suprimir advertencias sobre conexiones SSL inseguras
6
- urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
7
-
8
  # === TOOLS ===
9
  def letter_counter(word, letter):
10
  """
@@ -78,54 +71,4 @@ def coin_flip(flips):
78
  List[str]: A list of results from each flip ("Heads" or "Tails").
79
  """
80
  import random
81
- return ["Heads" if random.randint(0, 1) == 0 else "Tails" for _ in range(flips)]
82
-
83
- def execute_action(tab_id, action, params):
84
- """
85
- Execute an action on a specific tab.
86
-
87
- Args:
88
- tab_id (str): The ID of the tab where the action will be executed.
89
- action (str): The action to perform (e.g., "createShape", "createText").
90
- params (json): Parameters required for the action.
91
-
92
- Returns:
93
- dict: A dictionary containing the result of the action.
94
- """
95
- payload = {
96
- "action": action,
97
- "args": params
98
- }
99
- url = f"{os.getenv('FRONTEND_SERVER')}/execute/{tab_id}"
100
-
101
- response = request.post(
102
- url,
103
- json=payload,
104
- headers={'Content-Type': 'application/json'},
105
- verify=False
106
- )
107
-
108
- return response
109
-
110
- def create_shape(width:int, height:int, shape_type:str, fill_color:str, tab_id:str):
111
- """
112
- Create a shape item with specified properties.
113
-
114
- Args:
115
- width (int): Width of the shape. Minimum value is 100.
116
- height (int): Height of the shape. Minimum value is 100.
117
- shape_type (str): Type of the shape. It can be "RECTANGLE" | "CIRCLE" | "TRIANGLE" | "HEXAGON".
118
- fill_color (str): Fill color in hex format (e.g., "#ff0000").
119
- tab_id (str): The ID of the tab where the shape will be created. This is the most important parameter.
120
-
121
- Returns:
122
- dict: A dictionary representing the created shape item.
123
- """
124
- params = {
125
- "width": width,
126
- "height": height,
127
- "shapeType": shape_type.upper(),
128
- "fillColor": fill_color
129
- }
130
-
131
- return execute_action(tab_id=tab_id, action="createShape", params=params)
 
 
 
 
 
 
 
 
1
  # === TOOLS ===
2
  def letter_counter(word, letter):
3
  """
 
71
  List[str]: A list of results from each flip ("Heads" or "Tails").
72
  """
73
  import random
74
+ return ["Heads" if random.randint(0, 1) == 0 else "Tails" for _ in range(flips)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tools/obr.py ADDED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests as request
2
+ import os
3
+ import urllib3
4
+
5
+ # Suprimir advertencias sobre conexiones SSL inseguras
6
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
7
+
8
+ ASSETS_NAMES = {
9
+ "BOOK": "book.png",
10
+ "CHEST": "chest.png",
11
+ "SWORD": "sword.png",
12
+ "TORCH": "torch.png",
13
+ "ARCHER": "halfElfBard.png",
14
+ "HUMAN": "human.png",
15
+ "ORC": "halfOrcFighter2.png",
16
+ "KNIGHT": "knight1.png",
17
+ "DRAGON": "redDragon.png",
18
+ "GOBLIN": "goblin.png",
19
+ "GOLEM": "rockGolem.png",
20
+ "FOREST": "battleMap.jpg",
21
+ }
22
+
23
+ def execute_action(tab_id, action, params={}):
24
+ """
25
+ Execute an action on a specific tab.
26
+
27
+ Args:
28
+ tab_id (str): The ID of the tab where the action will be executed.
29
+ action (str): The action to perform (e.g., "createShape", "createText").
30
+ params (json): Parameters required for the action.
31
+
32
+ Returns:
33
+ dict: A dictionary containing the game state.
34
+ """
35
+ payload = {
36
+ "action": action,
37
+ "args": params
38
+ }
39
+ url = f"{os.getenv('FRONTEND_SERVER')}/execute/{tab_id}"
40
+
41
+ response = request.post(
42
+ url,
43
+ json=payload,
44
+ headers={'Content-Type': 'application/json'},
45
+ verify=False
46
+ )
47
+
48
+ if action != "getGameState" and response.status_code == 200 and response.json()["success"]:
49
+ return execute_action(tab_id=tab_id, action="getGameState")
50
+ else:
51
+ return response.json()
52
+
53
+ def create_token(name:str, type:str, x:int, y:int, size:int, tab_id:str)->dict:
54
+ """
55
+ Create a token with specified properties, they can be items or characters.
56
+
57
+ Args:
58
+ name (str): Name of the token.
59
+ type (str): Type of the token. It can be "BOOK" | "CHEST" | "SWORD" | "TORCH" | "ARCHER" | "HUMAN" | "ORC" | "KNIGHT" | "DRAGON" | "GOBLIN" | "GOLEM".
60
+ x (int): X coordinate of the token in cells.
61
+ y (int): Y coordinate of the token in cells.
62
+ size (int): Width of the token in cells.
63
+ tab_id (str): The ID of the tab where the token will be created. This is the most important parameter.
64
+
65
+ Returns:
66
+ dict: A dictionary containing the game state.
67
+ """
68
+
69
+ asset_url = f"{os.getenv('ASSETS_URL')}/{ASSETS_NAMES[type.upper()]}"
70
+
71
+ params = {
72
+ "name": name,
73
+ "imageUrl": asset_url,
74
+ "x": x,
75
+ "y": y,
76
+ "size": size
77
+ }
78
+
79
+ return execute_action(tab_id=tab_id, action="createToken", params=params)
80
+
81
+ def create_shape(width:int, height:int, x:int, y:int, shape_type:str, fill_color:str, stroke_color:str, tab_id:str) -> dict:
82
+ """
83
+ Create a shape item with specified properties.
84
+
85
+ Args:
86
+ width (int): Width of the shape in cells.
87
+ height (int): Height of the shape in cells.
88
+ x (int): X coordinate of the shape in cells.
89
+ y (int): Y coordinate of the shape in cells.
90
+ shape_type (str): Type of the shape. It can be "RECTANGLE" | "CIRCLE" | "TRIANGLE" | "HEXAGON".
91
+ fill_color (str): Fill color in hex format (e.g., "#ff0000").
92
+ stroke_color (str): Stroke color in hex format (e.g., "#ff0000").
93
+ tab_id (str): The ID of the tab where the shape will be created. This is the most important parameter.
94
+
95
+ Returns:
96
+ dict: A dictionary containing the game state.
97
+ """
98
+ params = {
99
+ "width": width,
100
+ "height": height,
101
+ "x": x,
102
+ "y": y,
103
+ "shapeType": shape_type.upper(),
104
+ "strokeColor": stroke_color,
105
+ "fillColor": fill_color
106
+ }
107
+
108
+ return execute_action(tab_id=tab_id, action="createShape", params=params)
109
+
110
+ def game_state(tab_id:str) -> dict:
111
+ """
112
+ Get the current game state.
113
+
114
+ Args:
115
+ tab_id (str): The ID of the tab to retrieve the game state for.
116
+
117
+ Returns:
118
+ dict: A dictionary containing the game state.
119
+ """
120
+ return execute_action(tab_id=tab_id, action="getGameState")
121
+
122
+ def move_item(tab_id:str, item_id:str, x:int, y:int) -> dict:
123
+ """
124
+ Move an item to a new position.
125
+
126
+ Args:
127
+ tab_id (str): The ID of the tab where the item is located.
128
+ item_id (str): The ID of the item to move.
129
+ x (int): New X coordinate in cells.
130
+ y (int): New Y coordinate in cells.
131
+
132
+ Returns:
133
+ dict: A dictionary confirming the moved item.
134
+ """
135
+ params = {
136
+ "id": item_id,
137
+ "x": x,
138
+ "y": y
139
+ }
140
+
141
+ return execute_action(tab_id=tab_id, action="moveItem", params=params)
142
+
143
+ def delete_item(tab_id:str, item_id:str) -> dict:
144
+ """
145
+ Delete an item from the game.
146
+
147
+ Args:
148
+ tab_id (str): The ID of the tab where the item is located.
149
+ item_id (str): The ID of the item to delete.
150
+
151
+ Returns:
152
+ dict: A dictionary containing the game state.
153
+ """
154
+ params = {
155
+ "id": item_id
156
+ }
157
+
158
+ return execute_action(tab_id=tab_id, action="deleteItem", params=params)
159
+
160
+ def fill_fog(tab_id:str) -> dict:
161
+ """
162
+ Fill the entire map with fog of war.
163
+
164
+ Args:
165
+ tab_id (str): The ID of the tab where the fog will be applied.
166
+
167
+ Returns:
168
+ dict: A dictionary containing the game state.
169
+ """
170
+
171
+ return execute_action(tab_id=tab_id, action="fillFog")
172
+
173
+ def clear_fog(tab_id:str) -> dict:
174
+ """
175
+ Clear the fog of war from the entire map.
176
+
177
+ Args:
178
+ tab_id (str): The ID of the tab where the fog will be cleared.
179
+
180
+ Returns:
181
+ dict: A dictionary containing the game state.
182
+ """
183
+
184
+ return execute_action(tab_id=tab_id, action="removeFog")
185
+
186
+ def add_token_light(tab_id:str, item_id:str, light_radius:int) -> dict:
187
+ """
188
+ Add light to a token. This will allow to show it inside the fog of war.
189
+ It can be used to add light to items like torches or characters.
190
+ It will be attached so that the light moves with the token.
191
+
192
+ Args:
193
+ tab_id (str): The ID of the tab where the item is located.
194
+ item_id (str): The ID of the item to add light to.
195
+ light_radius (int): The radius of the light in cells.
196
+
197
+ Returns:
198
+ dict: A dictionary containing the game state.
199
+ """
200
+ params = {
201
+ "targetId": item_id,
202
+ "radiusCells": light_radius
203
+ }
204
+
205
+ return execute_action(tab_id=tab_id, action="addLightSource", params=params)
206
+
207
+ def animate_token_viewport(tab_id:str, item_id:str) -> dict:
208
+ """
209
+ Animate the viewport to focus on a specific token.
210
+
211
+ Args:
212
+ tab_id (str): The ID of the tab where the item is located.
213
+ item_id (str): The ID of the item to focus on.
214
+
215
+ Returns:
216
+ dict: A dictionary containing the game state.
217
+ """
218
+ params = {
219
+ "itemsId": item_id
220
+ }
221
+
222
+ return execute_action(tab_id=tab_id, action="animateViewport", params=params)
223
+
224
+ def insert_map(tab_id:str, map_type:str="FOREST") -> dict:
225
+ """
226
+ Insert a map into the game.
227
+
228
+ Args:
229
+ tab_id (str): The ID of the tab where the map will be inserted.
230
+ map_type (str): The type of the map to insert. It can be only "FOREST".
231
+
232
+ Returns:
233
+ dict: A dictionary containing the game state.
234
+ """
235
+ map_type = map_type.upper()
236
+ map_type = "FOREST"
237
+ asset_url = f"{os.getenv('ASSETS_URL')}/{ASSETS_NAMES[map_type]}"
238
+ params = {
239
+ "mapUrl": asset_url,
240
+ }
241
+
242
+ return execute_action(tab_id=tab_id, action="insertMap", params=params)
243
+
244
+ def clean_map(tab_id:str) -> dict:
245
+ """
246
+ Clean the map by removing all items and shapes.
247
+
248
+ Args:
249
+ tab_id (str): The ID of the tab where the map will be cleaned.
250
+
251
+ Returns:
252
+ dict: A dictionary confirming the map cleaning.
253
+ """
254
+
255
+ return execute_action(tab_id=tab_id, action="emptyAll")
tools/test.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from tools.obr import (
2
+ create_shape,
3
+ create_token,
4
+ game_state,
5
+ move_item,
6
+ delete_item,
7
+ fill_fog,
8
+ clear_fog,
9
+ add_token_light,
10
+ animate_token_viewport,
11
+ insert_map,
12
+ clean_map
13
+ )
14
+ import time
15
+
16
+ # === FUNCIÓN DE PRUEBA ===
17
+ def test_function(tab_id):
18
+ """Función de prueba que demuestra todas las funcionalidades de OBR"""
19
+ results = []
20
+
21
+ try:
22
+ # 1. Limpiar el mapa
23
+ results.append({"step": "1. Limpiando mapa", "result": clean_map(tab_id)})
24
+ time.sleep(1)
25
+
26
+ # 2. Limpiar niebla
27
+ results.append({"step": "2. Limpiando niebla", "result": clear_fog(tab_id)})
28
+ time.sleep(1)
29
+
30
+ # 3. Insertar mapa
31
+ results.append({"step": "3. Insertando mapa", "result": insert_map(tab_id, "FOREST")})
32
+ time.sleep(1)
33
+
34
+ # 4. Crear formas geométricas (círculos rojos en diagonal)
35
+ for i in range(0, 30, 6):
36
+ shape_result = create_shape(
37
+ width=2,
38
+ height=2,
39
+ x=i,
40
+ y=i,
41
+ shape_type="CIRCLE",
42
+ fill_color="#FF0000",
43
+ stroke_color="#FF0000",
44
+ tab_id=tab_id
45
+ )
46
+ results.append({"step": f"4. Creando círculo en ({i},{i})", "result": shape_result})
47
+ time.sleep(0.5)
48
+
49
+ # 5. Crear token principal (Knight)
50
+ knight_result = create_token(
51
+ name="Knight",
52
+ type="KNIGHT",
53
+ x=0,
54
+ y=0,
55
+ size=1,
56
+ tab_id=tab_id
57
+ )
58
+ knight_id = [i for i in knight_result['result']["gameState"]['images'] if i["name"] == "Knight"][0]["id"]
59
+
60
+ results.append({"step": "5. Creando Knight", "result": knight_result, "token_id": knight_id})
61
+ time.sleep(1)
62
+
63
+ # 6. Mover el knight a posición intermedia
64
+ if knight_id:
65
+ results.append({"step": "6. Moviendo Knight a (14,14)", "result": move_item(tab_id, knight_id, 14, 14)})
66
+ time.sleep(1)
67
+
68
+ # 7. Mover el knight a posición final
69
+ results.append({"step": "7. Moviendo Knight a (29,29)", "result": move_item(tab_id, knight_id, 29, 29)})
70
+ time.sleep(1)
71
+
72
+ # 8. Crear token dragón
73
+ dragon_result = create_token(
74
+ name="Red Dragon",
75
+ type="DRAGON",
76
+ x=14,
77
+ y=14,
78
+ size=3,
79
+ tab_id=tab_id
80
+ )
81
+ dragon_id = [i for i in dragon_result['result']["gameState"]['images'] if i["name"] == "Red Dragon"][0]["id"]
82
+ results.append({"step": "8. Creando Red Dragon", "result": dragon_result, "token_id": dragon_id})
83
+ time.sleep(1)
84
+
85
+ # 9. Animar viewport al dragón
86
+ if dragon_id:
87
+ results.append({"step": "9. Animando viewport al dragón", "result": animate_token_viewport(tab_id, dragon_id)})
88
+ time.sleep(1)
89
+
90
+ # 10. Llenar con niebla
91
+ results.append({"step": "10. Llenando con niebla", "result": fill_fog(tab_id)})
92
+ time.sleep(1)
93
+
94
+ # 11. Añadir luz al knight
95
+ if knight_id:
96
+ results.append({"step": "11. Añadiendo luz al Knight", "result": add_token_light(tab_id, knight_id, 5)})
97
+ time.sleep(1)
98
+
99
+ # 12. Mover knight de vuelta al centro
100
+ results.append({"step": "12. Moviendo Knight de vuelta a (14,14)", "result": move_item(tab_id, knight_id, 14, 14)})
101
+ time.sleep(1)
102
+
103
+ # 13. Animar viewport al knight
104
+ results.append({"step": "13. Animando viewport al Knight", "result": animate_token_viewport(tab_id, knight_id)})
105
+ time.sleep(1)
106
+
107
+ # 14. Obtener estado final del juego
108
+ final_state = game_state(tab_id)
109
+ results.append({"step": "14. Estado final del juego", "result": final_state})
110
+ time.sleep(5)
111
+
112
+ #15. Limpiar mapa al final
113
+ results.append({"step": "15. Limpiando mapa", "result": clean_map(tab_id)})
114
+
115
+
116
+ return {
117
+ "success": True,
118
+ "message": "Prueba completada exitosamente",
119
+ "total_steps": len(results),
120
+ "results": results
121
+ }
122
+
123
+ except Exception as e:
124
+ return {
125
+ "success": False,
126
+ "error": str(e),
127
+ "completed_steps": len(results),
128
+ "results": results
129
+ }