From 91e1a83bf0a64dd2a8326a0704732ff17edb094e Mon Sep 17 00:00:00 2001 From: Davide Di Ruscio Date: Tue, 30 Dec 2025 12:53:42 +0100 Subject: [PATCH] Fixed tags management --- main.py | 84 +++++++++++++++++++++++++++------------------------------ 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/main.py b/main.py index be4d5e2..4e2cd9a 100644 --- a/main.py +++ b/main.py @@ -109,27 +109,6 @@ def chunks(lst: List[Any], n: int) -> Iterable[List[Any]]: yield lst[i : i + n] -def _sanitize_tags(tags: Optional[List[str]]) -> Optional[List[str]]: - if not tags: - return None - clean: List[str] = [] - for t in tags: - if t is None: - continue - s = str(t).strip() - if not s or s.lower() in ("undefined", "null", "none"): - continue - clean.append(s) - # dedup preserving order - seen = set() - out = [] - for s in clean: - if s not in seen: - seen.add(s) - out.append(s) - return out or None - - def _valid_name(x: Any) -> Optional[str]: if x is None: return None @@ -193,6 +172,28 @@ def build_tududi_description_from_todoist(task: Dict[str, Any], task_name: str) return "\n\n".join(parts).strip() + +def build_tududi_tag_objects(tag_names: List[str], tag_by_name: Dict[str, Dict[str, Any]]) -> List[Dict[str, str]]: + objs: List[Dict[str, str]] = [] + seen = set() + for n in tag_names or []: + key = str(n).strip() + if not key or key in seen: + continue + seen.add(key) + + t = tag_by_name.get(key) + if not t: + continue + uid = t.get("uid") + name = t.get("name") or key + if not uid or not name: + continue + + objs.append({"name": name, "uid": uid}) + return objs + + # ---------------------------- # Todoist client (API v1) # ---------------------------- @@ -286,7 +287,7 @@ class TududiClient: password: Optional[str] = None, timeout: int = 60, dry_run: bool = False, - request_sleep: float = 0.25, + request_sleep: float = 0.15, ) -> None: self.base_url = base_url.rstrip("/") self.timeout = timeout @@ -343,7 +344,7 @@ class TududiClient: print(f"[DRY_RUN] POST {path} payload={payload}") return {"_dry_run": True} if payload is not None and isinstance(payload, dict): - print(f"[DEBUG] POST {path} payload.Tags={payload.get('Tags')}") + print(f"[DEBUG] POST {path} payload.Tags={payload.get('Tags') if isinstance(payload, dict) else None}") r = self.s.post(url, data=json.dumps(payload or {}), timeout=self.timeout) # 429 -> retry @@ -444,7 +445,7 @@ class TududiClient: project_id: Optional[int] = None, due_date: Optional[str] = None, priority: Optional[str] = None, - tags: Optional[List[Dict[str, str]]] = None, + tag_objs: Optional[List[Dict[str, str]]] = None, description: Optional[str] = None, note: Optional[str] = None, parent_task_id: Optional[int] = None, @@ -461,24 +462,10 @@ class TududiClient: if priority: payload["priority"] = priority - tags = _sanitize_tags(tags) - if tags: - clean_tags: List[Dict[str, str]] = [] - for t in tags: - if not isinstance(t, dict): - continue - name = str(t.get("name") or "").strip() - uid = str(t.get("uid") or "").strip() - if not name or name.lower() in ("undefined", "null", "none"): - continue - if not uid or uid.lower() in ("undefined", "null", "none"): - continue - clean_tags.append({"name": name, "uid": uid}) + + if tag_objs: + payload["Tags"] = tag_objs - if clean_tags: - payload["Tags"] = clean_tags - - # Tududi spesso usa "note" (tu l’hai mostrato), non "description" if note: payload["note"] = note if description: @@ -835,6 +822,8 @@ def main() -> None: return None return project_map.get(str(pid)) + + def get_tags_for_task(task: Dict[str, Any]) -> List[Dict[str, str]]: lbls = task.get("labels") or task.get("label_ids") or task.get("labelIds") or [] names: List[str] = [] @@ -889,8 +878,7 @@ def main() -> None: due = normalize_due(task) prio = map_priority(task.get("priority")) project_uid = get_project_uid_for_task(task) - tags = get_tags_for_task(task) - + # Tududi note: Todoist link + Todoist description tududi_description = build_tududi_description_from_todoist(task, name) @@ -903,12 +891,20 @@ def main() -> None: is_completed = is_done_map.get(tid, False) completed_at = task.get("completed_at") or task.get("completedAt") + tag_objs = get_tags_for_task(task) # già [{"name":..., "uid":...}] + + if tag_objs: + print(f"[DEBUG] task={tid} tags_obj={tag_objs}") + else: + raw_lbls = task.get("labels") or task.get("label_ids") or task.get("labelIds") + print(f"[DEBUG] task={tid} NO TAGS. raw_labels={raw_lbls}") + created = tud.create_task( name=name, project_id=project_uid, due_date=due, priority=prio, - tags=tags if tags else None, + tag_objs=tag_objs if tag_objs else None, description=tududi_description, note=tududi_description, parent_task_id=tud_parent_id,