261 lines
8.9 KiB
Python
261 lines
8.9 KiB
Python
# kanboard_utils.py
|
|
|
|
import requests
|
|
from requests.auth import HTTPBasicAuth
|
|
import random
|
|
|
|
|
|
def listar_proyectos(api_url: str, usuario: str, token: str) -> list[dict]:
|
|
"""
|
|
Devuelve la lista completa de proyectos disponibles en Kanboard.
|
|
"""
|
|
auth = HTTPBasicAuth(usuario, token)
|
|
payload = {"jsonrpc": "2.0", "method": "getAllProjects", "id": 1}
|
|
|
|
response = requests.post(api_url, json=payload, auth=auth,
|
|
headers={"Content-Type": "application/json"}, timeout=10)
|
|
data = response.json()
|
|
if "error" in data:
|
|
raise Exception(f"❌ Error al obtener proyectos: {data['error']}")
|
|
return data.get("result", [])
|
|
|
|
|
|
def listar_usuarios(api_url: str, usuario: str, token: str) -> list[dict]:
|
|
"""
|
|
Devuelve la lista completa de usuarios disponibles en Kanboard.
|
|
"""
|
|
auth = HTTPBasicAuth(usuario, token)
|
|
payload = {"jsonrpc": "2.0", "method": "getAllUsers", "id": 1}
|
|
|
|
response = requests.post(api_url, json=payload, auth=auth,
|
|
headers={"Content-Type": "application/json"}, timeout=10)
|
|
data = response.json()
|
|
if "error" in data:
|
|
raise Exception(f"❌ Error al obtener usuarios: {data['error']}")
|
|
return data.get("result", [])
|
|
|
|
|
|
def listar_tareas(api_url: str, usuario: str, token: str, project_id: int) -> list[dict]:
|
|
"""
|
|
Lista todas las tareas de un proyecto en Kanboard.
|
|
"""
|
|
auth = HTTPBasicAuth(usuario, token)
|
|
payload = {
|
|
"jsonrpc": "2.0",
|
|
"method": "getAllTasks",
|
|
"id": 1,
|
|
"params": {"project_id": project_id}
|
|
}
|
|
|
|
response = requests.post(api_url, json=payload, auth=auth,
|
|
headers={"Content-Type": "application/json"})
|
|
data = response.json()
|
|
if "error" in data:
|
|
print("❌ Error al obtener tareas:", data["error"])
|
|
return []
|
|
return data.get("result", [])
|
|
|
|
|
|
def listar_subtareas(api_url: str, usuario: str, token: str, task_id: int) -> list[dict]:
|
|
"""
|
|
Lista todas las subtareas de una tarea principal.
|
|
"""
|
|
auth = HTTPBasicAuth(usuario, token)
|
|
payload = {
|
|
"jsonrpc": "2.0",
|
|
"method": "getAllSubtasks",
|
|
"id": 1,
|
|
"params": {"task_id": task_id}
|
|
}
|
|
|
|
response = requests.post(api_url, json=payload, auth=auth,
|
|
headers={"Content-Type": "application/json"})
|
|
data = response.json()
|
|
if "error" in data:
|
|
print("❌ Error al obtener subtareas:", data["error"])
|
|
return []
|
|
return data.get("result", [])
|
|
|
|
|
|
def listar_tareas_por_columna(api_url: str, usuario: str, token: str, project_id: int) -> dict:
|
|
"""
|
|
Devuelve todas las tareas agrupadas por columna dentro de un proyecto Kanboard.
|
|
"""
|
|
auth = HTTPBasicAuth(usuario, token)
|
|
payload = {
|
|
"jsonrpc": "2.0",
|
|
"method": "getBoard",
|
|
"id": 1,
|
|
"params": {"project_id": project_id}
|
|
}
|
|
|
|
response = requests.post(api_url, json=payload, auth=auth,
|
|
headers={"Content-Type": "application/json"})
|
|
data = response.json()
|
|
if "error" in data:
|
|
print("❌ Error al obtener el tablero:", data["error"])
|
|
return {}
|
|
|
|
board = data.get("result", [])
|
|
tareas_por_columna = {}
|
|
for swimlane in board:
|
|
for columna in swimlane.get("columns", []):
|
|
nombre_columna = columna["title"]
|
|
tareas_por_columna[nombre_columna] = columna.get("tasks", [])
|
|
return tareas_por_columna
|
|
|
|
|
|
def mover_tarea_columna(api_url: str, usuario: str, token: str,
|
|
project_id: int, task_id: int, column_id: int,
|
|
position: int = 1, swimlane_id: int = 0) -> bool:
|
|
"""
|
|
Mueve una tarea a otra columna dentro de un proyecto Kanboard.
|
|
"""
|
|
auth = HTTPBasicAuth(usuario, token)
|
|
payload = {
|
|
"jsonrpc": "2.0",
|
|
"method": "moveTaskPosition",
|
|
"id": 1,
|
|
"params": {
|
|
"project_id": project_id,
|
|
"task_id": task_id,
|
|
"column_id": column_id,
|
|
"position": position,
|
|
"swimlane_id": swimlane_id
|
|
}
|
|
}
|
|
|
|
response = requests.post(api_url, json=payload, auth=auth,
|
|
headers={"Content-Type": "application/json"}, timeout=10)
|
|
data = response.json()
|
|
if "error" in data:
|
|
print("❌ Error al mover tarea:", data["error"])
|
|
return False
|
|
|
|
result = data.get("result", False)
|
|
if result:
|
|
print(f"✅ Tarea {task_id} movida correctamente a la columna {column_id}.")
|
|
else:
|
|
print(f"⚠️ No se pudo mover la tarea {task_id}.")
|
|
return result
|
|
|
|
|
|
def crear_tarea(api_url: str, usuario: str, token: str, project_id: int,
|
|
titulo: str, descripcion: str = "", swimlane_id: int | None = None,
|
|
assignee_id: int | None = None, tags: list[str] | None = None,
|
|
priority: int | None = None) -> dict:
|
|
"""
|
|
Crea una nueva tarea en un proyecto Kanboard.
|
|
"""
|
|
auth = HTTPBasicAuth(usuario, token)
|
|
colores = ["yellow", "blue", "green", "purple", "red", "orange",
|
|
"grey", "brown", "deep_orange", "dark_grey", "lime", "cyan"]
|
|
color_aleatorio = random.choice(colores)
|
|
|
|
payload = {
|
|
"jsonrpc": "2.0",
|
|
"method": "createTask",
|
|
"id": 1,
|
|
"params": {
|
|
"title": titulo,
|
|
"description": descripcion,
|
|
"project_id": project_id,
|
|
"color_id": color_aleatorio
|
|
}
|
|
}
|
|
|
|
if swimlane_id is not None:
|
|
payload["params"]["swimlane_id"] = swimlane_id
|
|
if assignee_id is not None:
|
|
payload["params"]["owner_id"] = assignee_id
|
|
if priority is not None:
|
|
payload["params"]["priority"] = priority
|
|
|
|
headers = {"Content-Type": "application/json"}
|
|
response = requests.post(api_url, json=payload, auth=auth, headers=headers, timeout=10)
|
|
data = response.json()
|
|
if "error" in data:
|
|
print("❌ Error al crear tarea:", data["error"])
|
|
return data
|
|
|
|
task_id = data.get("result")
|
|
print(f"✅ Tarea creada correctamente (ID {task_id}) en el proyecto {project_id}")
|
|
|
|
if tags:
|
|
tag_payload = {
|
|
"jsonrpc": "2.0",
|
|
"method": "setTaskTags",
|
|
"id": 1,
|
|
"params": {"project_id": project_id, "task_id": task_id, "tags": tags}
|
|
}
|
|
tag_response = requests.post(api_url, json=tag_payload, auth=auth, headers=headers, timeout=10)
|
|
tag_data = tag_response.json()
|
|
if "error" in tag_data:
|
|
print("⚠️ Error al añadir etiquetas:", tag_data["error"])
|
|
else:
|
|
print(f"🏷️ Etiquetas añadidas: {', '.join(tags)}")
|
|
|
|
return data
|
|
|
|
|
|
def editar_tarea(api_url: str, usuario: str, token: str, task_id: int,
|
|
titulo: str | None = None, descripcion: str | None = None,
|
|
swimlane_id: int | None = None, assignee_id: int | None = None,
|
|
tags: list[str] | None = None, priority: int | None = None) -> dict:
|
|
"""
|
|
Edita una tarea existente en Kanboard. Solo modifica los campos proporcionados.
|
|
"""
|
|
auth = HTTPBasicAuth(usuario, token)
|
|
headers = {"Content-Type": "application/json"}
|
|
|
|
params = {"id": task_id}
|
|
if titulo is not None:
|
|
params["title"] = titulo
|
|
if descripcion is not None:
|
|
params["description"] = descripcion
|
|
if swimlane_id is not None:
|
|
params["swimlane_id"] = swimlane_id
|
|
if assignee_id is not None:
|
|
params["owner_id"] = assignee_id
|
|
if priority is not None:
|
|
params["priority"] = priority
|
|
|
|
if len(params) == 1:
|
|
print("⚠️ No se proporcionaron campos a modificar.")
|
|
return {"warning": "sin cambios"}
|
|
|
|
payload = {"jsonrpc": "2.0", "method": "updateTask", "id": 1, "params": params}
|
|
response = requests.post(api_url, json=payload, auth=auth, headers=headers, timeout=10)
|
|
data = response.json()
|
|
|
|
if "error" in data:
|
|
print("❌ Error al editar tarea:", data["error"])
|
|
return data
|
|
|
|
print(f"✅ Tarea {task_id} actualizada correctamente en Kanboard.")
|
|
|
|
if tags:
|
|
get_task_payload = {
|
|
"jsonrpc": "2.0", "method": "getTask", "id": 1,
|
|
"params": {"task_id": task_id}
|
|
}
|
|
task_response = requests.post(api_url, json=get_task_payload,
|
|
auth=auth, headers=headers, timeout=10)
|
|
project_id = task_response.json().get("result", {}).get("project_id")
|
|
|
|
if project_id:
|
|
tag_payload = {
|
|
"jsonrpc": "2.0",
|
|
"method": "setTaskTags",
|
|
"id": 1,
|
|
"params": {"project_id": project_id, "task_id": task_id, "tags": tags}
|
|
}
|
|
tag_response = requests.post(api_url, json=tag_payload, auth=auth, headers=headers, timeout=10)
|
|
tag_data = tag_response.json()
|
|
if "error" in tag_data:
|
|
print("⚠️ Error al actualizar etiquetas:", tag_data["error"])
|
|
else:
|
|
print(f"🏷️ Etiquetas actualizadas: {', '.join(tags)}")
|
|
|
|
return data
|