How to parse content from a dashboard export

jsolas5
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
December 18, 2024

I need to extract from an export of a Trello board the name of each card, its creation date, last activity, current list to which it belongs and the date of the last time it was moved from the list, that is, when it was moved to the current list For this I am creating a script in python and I almost have it, I am only missing the last part "the date of the last time the list was moved", in some cards I can't get the date, in others I can but I don't understand the reason, for That's why I attached the script to see if someone can tell me why this error occurred.

------- Script -------

 

import json
import datetime
import sys
import csv
import os
from pytz import timezone, utc

# Zona horaria española
zona_horaria_es = timezone('Europe/Madrid')

# Verificar si se proporcionó el archivo JSON como argumento
if len(sys.argv) < 2:
    print("Uso: python analizar_trello.py <archivo_json>")
    sys.exit(1)

# Obtener el nombre del archivo desde los argumentos
archivo_json = sys.argv[1]

try:
    # Cargar el archivo JSON exportado de Trello con la codificación adecuada
    with open(archivo_json, 'r', encoding='utf-8') as file:
        data = json.load(file)
except FileNotFoundError:
    print(f"Error: No se encontró el archivo '{archivo_json}'.")
    sys.exit(1)
except json.JSONDecodeError as e:
    print(f"Error: El archivo '{archivo_json}' no es un JSON válido. Detalle: {e}")
    sys.exit(1)
except UnicodeDecodeError as e:
    print(f"Error: Problema de codificación al leer el archivo '{archivo_json}'. Detalle: {e}")
    sys.exit(1)

# Procesar las tarjetas del archivo
if "cards" not in data or "lists" not in data or "actions" not in data:
    print("El archivo no contiene las secciones necesarias ('cards', 'lists' o 'actions').")
    sys.exit(1)

# Crear un diccionario para mapear IDs de listas con sus nombres
id_to_list_name = {list_item["id"]: list_item["name"] for list_item in data.get("lists", [])}

# Crear un diccionario para registrar la última fecha de movimiento de cada tarjeta
last_movement_date = {}

for action in data.get("actions", []):
    if action["type"] == "updateCard" and "listAfter" in action.get("data", {}):
        card_id = action["data"]["card"]["id"]
        movement_date = datetime.datetime.fromisoformat(action["date"].replace("Z", "+00:00"))
        movement_date_es = movement_date.astimezone(zona_horaria_es)
        last_movement_date[card_id] = movement_date_es.strftime('%Y-%m-%d %H:%M:%S')

# Crear una lista para almacenar los datos procesados
tarjetas_procesadas = []

for card in data.get("cards", []):
    # Fecha de creación a partir de la ID (convertida a hora española)
    card_id = card["id"]
    timestamp_hex = card_id[:8]
    creation_timestamp = int(timestamp_hex, 16)
    creation_date_utc = datetime.datetime.utcfromtimestamp(creation_timestamp).replace(tzinfo=utc)
    creation_date_es = creation_date_utc.astimezone(zona_horaria_es)

    # Fecha de última actividad (convertida a hora española)
    last_activity = card.get("dateLastActivity", None)
    if last_activity:
        last_activity_utc = datetime.datetime.fromisoformat(last_activity.replace("Z", "+00:00"))
        last_activity_es = last_activity_utc.astimezone(zona_horaria_es)
        last_activity_es_str = last_activity_es.strftime('%Y-%m-%d %H:%M:%S')
    else:
        last_activity_es_str = "No registrada"

    # Obtener la lista actual de la tarjeta
    lista_actual = id_to_list_name.get(card.get("idList", ""), "No especificada")

    # Obtener la fecha de último movimiento
    fecha_ultimo_movimiento = last_movement_date.get(card_id, "No registrada")

    # Agregar los datos de la tarjeta a la lista
    tarjetas_procesadas.append({
        "Tarjeta": card["name"],
        "Fecha de creación": creation_date_es.strftime('%Y-%m-%d %H:%M:%S'),
        "Última actividad": last_activity_es_str,
        "Lista actual": lista_actual,
        "Fecha último movimiento": fecha_ultimo_movimiento
    })

# Determinar la ruta del directorio donde se encuentra el script
ruta_script = os.path.dirname(os.path.abspath(__file__))

# Nombre del archivo CSV
archivo_salida = os.path.join(ruta_script, "tarjetas_trello.csv")

# Guardar los datos procesados en el archivo CSV
with open(archivo_salida, mode='w', newline='', encoding='utf-8-sig') as csvfile:  # Cambiar a utf-8-sig
    campos = ["Tarjeta", "Fecha de creación", "Última actividad", "Lista actual", "Fecha último movimiento"]
    writer = csv.DictWriter(csvfile, fieldnames=campos, delimiter=';')

    writer.writeheader()  # Escribir encabezados
    writer.writerows(tarjetas_procesadas)  # Escribir las filas

print(f"Archivo CSV generado en la ubicación del script: {archivo_salida}")

1 answer

1 accepted

0 votes
Answer accepted
Bo Wang December 18, 2024
for action in data.get("actions", []):
    if action["type"] == "updateCard" and "listAfter" in action.get("data", {}):
        card_id = action["data"]["card"]["id"]
        movement_date = datetime.datetime.fromisoformat(action["date"].replace("Z", "+00:00"))
        movement_date_es = movement_date.astimezone(zona_horaria_es)
        last_movement_date[card_id] = movement_date_es.strftime('%Y-%m-%d %H:%M:%S')
From this section, we can see the last movement date is from actions section in the json file. you can get the wired card id which didn't contain move date from card name, and to see if there are action section contains both type: "updateCard" and date : { listAfter : }, if not, the card haven't been moved from lists.
jsolas5
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
December 19, 2024

I have continued testing and it seems to be in order, I leave the script that I put previously in case someone is in the same situation as me

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
CLOUD
PRODUCT PLAN
FREE
TAGS
AUG Leaders

Atlassian Community Events