diff --git a/dev_session.py b/dev_session.py index 852fcdbac..b772bbc4b 100644 --- a/dev_session.py +++ b/dev_session.py @@ -394,6 +394,9 @@ def select_project(token: str) -> Optional[Tuple[Dict, Optional[str]]]: print("Keine Projekte in der Datenbank gefunden.") return None, None + # Sortiere Projekte alphabetisch nach Titel + projects.sort(key=lambda p: get_page_title(p).lower()) + print("\nAn welchem Projekt möchtest du arbeiten?") for i, project in enumerate(projects): print(f"[{i+1}] {get_page_title(project)}") @@ -428,6 +431,7 @@ def select_task(token: str, project_id: str, tasks_db_id: str) -> Optional[Dict] print(f"[{i+1}] {get_page_title(task)}") print(f"[{len(tasks)+1}] Neuen Task für dieses Projekt erstellen") + print("[0] Zurück zur Projektauswahl") while True: try: @@ -436,6 +440,8 @@ def select_task(token: str, project_id: str, tasks_db_id: str) -> Optional[Dict] return tasks[choice - 1] elif choice == len(tasks) + 1: return {"id": "new_task"} # Signal + elif choice == 0: + return {"id": "go_back"} # Signal else: print("Ungültige Auswahl.") except ValueError: @@ -450,34 +456,6 @@ BERLIN_TZ = ZoneInfo("Europe/Berlin") # --- Git Summary Generation --- -def generate_git_summary() -> Tuple[str, str]: - """Generiert eine Zusammenfassung der Git-Änderungen und Commit-Nachrichten seit dem letzten Push zum Main-Branch.""" - try: - # Finde den aktuellen Main-Branch Namen (master oder main) - try: - main_branch = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).decode("utf-8").strip() - if main_branch not in ["main", "master"]: - # Versuche, den Remote-Tracking-Branch für main/master zu finden - result = subprocess.run(["git", "branch", "-r"], capture_output=True, text=True) - if "origin/main" in result.stdout: - main_branch = "origin/main" - elif "origin/master" in result.stdout: - main_branch = "origin/master" - else: - print("Warnung: Konnte keinen 'main' oder 'master' Branch finden. Git-Zusammenfassung wird möglicherweise unvollständig sein.") - main_branch = "HEAD~1" # Fallback zum letzten Commit, falls kein Main-Branch gefunden wird - except subprocess.CalledProcessError: - main_branch = "HEAD~1" # Fallback, falls gar kein Branch gefunden wird - - # Git log --pretty - commit_log_cmd = ["git", "log", "--pretty=format:- %s", f"{main_branch}...HEAD"] - commit_messages = subprocess.check_output(commit_log_cmd).decode("utf-8").strip() - - return "", commit_messages - except subprocess.CalledProcessError as e: - print(f"❌ FEHLER beim Generieren der Git-Zusammenfassung: {e}") - return "", "" - def git_push_with_retry() -> bool: """Versucht, Änderungen zu pushen, und führt bei einem non-fast-forward-Fehler einen Rebase und erneuten Push durch.""" print("\n--- Führe git push aus ---") @@ -527,7 +505,9 @@ def report_status_to_notion( session_data = json.load(f) task_id = session_data.get("task_id") token = session_data.get("token") - readme_path = session_data.get("readme_path", "readme.md") # Lade den Readme-Pfad + readme_path = session_data.get("readme_path") # Lade den Readme-Pfad + if readme_path is None: + readme_path = "readme.md" if not (task_id and token): print("❌ FEHLER: Session-Daten unvollständig. Kann keinen Statusbericht erstellen.") @@ -560,22 +540,13 @@ def report_status_to_notion( except requests.exceptions.RequestException as e: print(f"❌ FEHLER beim Abrufen der Task-Details für die Zeiterfassung: {e}") - print(f"--- Erstelle automatischen Statusbericht für Task {task_id} ---") + print(f"--- Erstelle Statusbericht für Task {task_id} ---") - # Git-Zusammenfassung generieren - print("Generiere Git-Zusammenfassung...") - _, commit_log = generate_git_summary() - actual_commit_messages = commit_log - - # Summary automatisch aus Commit-Nachrichten erstellen actual_summary = summary_override or "Keine Zusammenfassung angegeben." - if not summary_override: - _, commit_log = generate_git_summary() - summary_from_commits = commit_log.replace("- ", "✦ ").strip() - if summary_from_commits: - actual_summary = summary_from_commits - else: - actual_summary = "Keine neuen Commits in dieser Session." + + # Bessere Lesbarkeit für Notion durch explizite Zeilenumbrüche vor nummerierten Listen + # Formatiert " 1. " zu einem Zeilenumbruch und einer Einrückung + formatted_summary = re.sub(r'\s+(\d+\.)\s', r'\n\n \1 ', actual_summary) # Kommentar zusammenstellen report_lines = [] @@ -584,7 +555,7 @@ def report_status_to_notion( report_lines.append(f"Investierte Zeit in dieser Session: {elapsed_hhmm}") report_lines.append("\nArbeitszusammenfassung:") - report_lines.append(actual_summary) + report_lines.append(formatted_summary) report_content = "\n".join(report_lines) @@ -598,6 +569,19 @@ def report_status_to_notion( # Notion aktualisieren (nur Kommentar/Block, kein Status) append_blocks_to_notion_page(token, task_id, notion_blocks) + # Update der Readme.md Datei + if readme_path and os.path.exists(readme_path): + print(f"Hänge Status-Update an {readme_path} an...") + try: + with open(readme_path, "a", encoding="utf-8") as rf: + rf.write(f"\n\n## 🤖 Status-Update ({timestamp} Berlin Time)\n") + rf.write(f"```yaml\n{report_content}\n```\n") + print(f"✅ Status-Update an '{readme_path}' angehängt.") + except Exception as e: + print(f"❌ FEHLER beim Anhängen an '{readme_path}': {e}") + else: + print(f"⚠️ Readme-Pfad '{readme_path}' nicht gefunden. Überspringe lokales Doku-Update.") + # --- Doku & Git Operationen --- print("\n--- Führe Git-Operationen aus ---") try: @@ -652,7 +636,8 @@ def generate_cli_context(project_title: str, task_title: str, task_id: str, read description_part = "" if task_description: description_part = ( - f"\n**Aufgabenbeschreibung:**\n" + f"\n**Aufgabenbeschreibung (inkl. Historie):**\n" + f"*(Hinweis: Bei längeren Tasks befinden sich die aktuellsten und relevantesten Status-Updates am Ende dieser Beschreibung. Ursprüngliche Probleme sind möglicherweise bereits gelöst. Priorisiere immer die jüngsten Informationen!)*\n" f"```\n{task_description}\n```\n" ) @@ -748,30 +733,37 @@ def start_interactive_session(): print("Kein Token angegeben. Abbruch.") return - selected_project, readme_path = select_project(token) - if not selected_project: - return - - project_title = get_page_title(selected_project) - print(f"\nProjekt '{project_title}' ausgewählt.") - - tasks_db_id = find_database_by_title(token, "Tasks [UT]") - if not tasks_db_id: - return - - user_choice = select_task(token, selected_project["id"], tasks_db_id) - - if not user_choice: - print("Kein Task ausgewählt. Abbruch.") - return - - selected_task = None - if user_choice.get("id") == "new_task": - selected_task = create_new_notion_task(token, selected_project["id"], tasks_db_id) - if not selected_task: + while True: + selected_project, readme_path = select_project(token) + if not selected_project: return - else: - selected_task = user_choice + + project_title = get_page_title(selected_project) + print(f"\nProjekt '{project_title}' ausgewählt.") + + tasks_db_id = find_database_by_title(token, "Tasks [UT]") + if not tasks_db_id: + return + + user_choice = select_task(token, selected_project["id"], tasks_db_id) + + if not user_choice: + print("Kein Task ausgewählt. Abbruch.") + return + + if user_choice.get("id") == "go_back": + print("\nGehe zurück zur Projektauswahl...") + continue + + selected_task = None + if user_choice.get("id") == "new_task": + selected_task = create_new_notion_task(token, selected_project["id"], tasks_db_id) + if not selected_task: + return + else: + selected_task = user_choice + + break # Exit the loop once a valid task is selected task_title = get_page_title(selected_task) task_id = selected_task["id"]