CheddahBot/scripts/feb26_tasks.py

88 lines
2.7 KiB
Python

"""Query ClickUp 'to do' tasks tagged feb26 in OPT/LINKS/Content categories."""
import os
import sys
from datetime import datetime, timezone
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from dotenv import load_dotenv
load_dotenv(os.path.join(os.path.dirname(__file__), "..", ".env"))
from cheddahbot.clickup import ClickUpClient
TOKEN = os.getenv("CLICKUP_API_TOKEN", "")
SPACE_ID = os.getenv("CLICKUP_SPACE_ID", "")
if not TOKEN or not SPACE_ID:
print("ERROR: CLICKUP_API_TOKEN and CLICKUP_SPACE_ID must be set in .env")
sys.exit(1)
CATEGORIES = {"On Page Optimization", "Content Creation", "Link Building"}
TAG_FILTER = "feb26"
client = ClickUpClient(api_token=TOKEN, workspace_id="", task_type_field_name="Work Category")
print(f"Querying ClickUp space {SPACE_ID} for 'to do' tasks...")
tasks = client.get_tasks_from_space(SPACE_ID, statuses=["to do"])
client.close()
print(f"Total 'to do' tasks found: {len(tasks)}")
# Filter by feb26 tag
tagged = [t for t in tasks if TAG_FILTER in [tag.lower() for tag in t.tags]]
print(f"Tasks with '{TAG_FILTER}' tag: {len(tagged)}")
# Filter by Work Category (OPT / LINKS / Content)
filtered = []
for t in tagged:
cat = (t.custom_fields.get("Work Category") or t.task_type or "").strip()
if cat in CATEGORIES:
filtered.append(t)
if not filtered and tagged:
# Show what categories exist so we can refine
cats_found = set()
for t in tagged:
cats_found.add(t.custom_fields.get("Work Category") or t.task_type or "(none)")
print(f"\nNo tasks matched categories {CATEGORIES}.")
print(f"Work Categories found on feb26-tagged tasks: {cats_found}")
print("\nShowing ALL feb26-tagged tasks instead:\n")
filtered = tagged
# Sort by due date (oldest first), tasks without due date go last
def sort_key(t):
if t.due_date:
return int(t.due_date)
return float("inf")
filtered.sort(key=sort_key)
# Take top 10
top = filtered[:10]
# Format table
def fmt_due(raw_due: str) -> str:
if not raw_due:
return ""
try:
ts = int(raw_due) / 1000
return datetime.fromtimestamp(ts, tz=timezone.utc).strftime("%m/%d")
except (ValueError, OSError):
return raw_due
def fmt_customer(t) -> str:
return t.custom_fields.get("Customer", "") or ""
print(f"\n{'#':<3} | {'ID':<12} | {'Keyword/Name':<45} | {'Cat':<15} | {'Due':<6} | {'Customer':<20} | Tags")
print("-" * 120)
for i, t in enumerate(top, 1):
tags_str = ", ".join(t.tags)
name = t.name[:45]
cat = t.custom_fields.get("Work Category") or t.task_type or ""
print(f"{i:<3} | {t.id:<12} | {name:<45} | {cat:<15} | {fmt_due(t.due_date):<6} | {fmt_customer(t):<20} | {tags_str}")
print(f"\nTotal shown: {len(top)} of {len(filtered)} matching tasks")