дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 11:15:40 +02:00
Initial open-source release
Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
Цей коміт міститься в:
коміт
9a2025b76e
2034 files changed
+243381
No files matched your search
@@ -0,0 +1,5 @@
|
||||
"""A tiny task tracker used as an OpenIDEA QA fixture."""
|
||||
|
||||
from .models import Priority, Task, TaskList
|
||||
|
||||
__all__ = ["Priority", "Task", "TaskList"]
|
||||
@@ -0,0 +1,33 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from datetime import date, timedelta
|
||||
|
||||
from .models import Priority, TaskList
|
||||
|
||||
|
||||
def build_demo() -> TaskList:
|
||||
today = date.today()
|
||||
tasks = TaskList()
|
||||
tasks.add("Write release notes", Priority.HIGH, today + timedelta(days=1), "docs")
|
||||
tasks.add("Fix flaky test", Priority.HIGH, today - timedelta(days=2), "ci")
|
||||
tasks.add("Update dependencies", Priority.LOW, None, "chore")
|
||||
return tasks
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(prog="tasks")
|
||||
parser.add_argument("--overdue", action="store_true", help="only show overdue tasks")
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
tasks = build_demo()
|
||||
# Set a breakpoint here (QA: debugger) and inspect `tasks`.
|
||||
shown = tasks.overdue(date.today()) if args.overdue else tasks.pending()
|
||||
for task in shown:
|
||||
flag = "!" if task.priority is Priority.HIGH else " "
|
||||
print(f"{flag} {task.title} ({', '.join(sorted(task.tags))})")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,57 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import date
|
||||
from enum import IntEnum
|
||||
|
||||
|
||||
class Priority(IntEnum):
|
||||
LOW = 1
|
||||
NORMAL = 2
|
||||
HIGH = 3
|
||||
|
||||
|
||||
@dataclass
|
||||
class Task:
|
||||
title: str
|
||||
priority: Priority = Priority.NORMAL
|
||||
due: date | None = None
|
||||
done: bool = False
|
||||
tags: set[str] = field(default_factory=set)
|
||||
|
||||
def is_overdue(self, today: date) -> bool:
|
||||
return not self.done and self.due is not None and self.due < today
|
||||
|
||||
|
||||
class TaskList:
|
||||
def __init__(self) -> None:
|
||||
self._tasks: list[Task] = []
|
||||
|
||||
def add(self, title: str, priority: Priority = Priority.NORMAL, due: date | None = None, *tags: str) -> Task:
|
||||
if not title.strip():
|
||||
raise ValueError("title must not be empty")
|
||||
task = Task(title.strip(), priority, due, tags=set(tags))
|
||||
self._tasks.append(task)
|
||||
return task
|
||||
|
||||
def complete(self, title: str) -> Task:
|
||||
for task in self._tasks:
|
||||
if task.title == title:
|
||||
task.done = True
|
||||
return task
|
||||
raise KeyError(title)
|
||||
|
||||
def pending(self) -> list[Task]:
|
||||
# TODO: stable ordering for equal priorities (by due date)
|
||||
return sorted((t for t in self._tasks if not t.done), key=lambda t: -t.priority)
|
||||
|
||||
def overdue(self, today: date) -> list[Task]:
|
||||
return [t for t in self._tasks if t.is_overdue(today)]
|
||||
|
||||
def by_tag(self, tag: str) -> list[Task]:
|
||||
return [t for t in self._tasks if tag in t.tags]
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self._tasks)
|
||||
Reference in new issue
Заблокувати користувача