summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchangiinlee <changjin9792@gmail.com>2024-02-05 20:47:55 +0900
committerchangiinlee <changjin9792@gmail.com>2024-02-05 20:47:55 +0900
commit26e135d5a4ae1dead6dde98b32e925e452563c34 (patch)
treea204dcd3cc1cdd5493ac573dc16e4b9677459a25
parent4f98ae2687a5fd9b330dc11a8416e83215273c7d (diff)
♻️ refact: Refactor uptask commandrefactor-v2
-rw-r--r--girok/api/task.py85
-rw-r--r--girok/commands/task/command.py169
2 files changed, 251 insertions, 3 deletions
diff --git a/girok/api/task.py b/girok/api/task.py
index fdfd8a0..5ff513d 100644
--- a/girok/api/task.py
+++ b/girok/api/task.py
@@ -27,12 +27,14 @@ def create_task(
# Resolve target category id
category_id = None
- if category_path:
- resp = get_category_id_by_path(category_path.split("/"))
+ if category_path is not None:
+ category_path_list = category_path.split("/")
+ if category_path == '':
+ category_path_list = []
+ resp = get_category_id_by_path(category_path_list)
if not resp.is_success:
return resp
category_id = resp.body["categoryId"]
-
request_body = {
"categoryId": category_id,
"name": name,
@@ -60,6 +62,83 @@ def create_task(
return APIResponse(is_success=False, error_message=error_message)
+def update_task(
+ event_id: int,
+ name: str,
+ start_date: str,
+ start_time: Optional[str],
+ end_date: Optional[str],
+ end_time: Optional[str],
+ repetition_type: Optional[str],
+ repetition_end_date: Optional[str],
+ category_path: Optional[str],
+ tags: Optional[List[str]],
+ priority: Optional[str],
+ memo: Optional[str],
+) -> APIResponse:
+ access_token = AuthHandler.get_access_token()
+
+ # Resolve target category id
+ category_id = None
+ if category_path is not None:
+ category_path_list = category_path.split("/")
+ if category_path == '':
+ category_path_list = []
+ resp = get_category_id_by_path(category_path_list)
+ if not resp.is_success:
+ return resp
+ category_id = resp.body["categoryId"]
+
+ request_body = {
+ "categoryId": category_id,
+ "name": name,
+ "eventDate": {"startDate": start_date, "startTime": start_time, "endDate": end_date, "endTime": end_time},
+ "repetition": {"repetitionType": repetition_type, "repetitionEndDate": repetition_end_date},
+ "tags": tags,
+ "priority": priority,
+ "memo": memo,
+ }
+
+ resp = requests.put(
+ url=urljoin(BASE_URL, f"events/{event_id}"),
+ headers={"Authorization": "Bearer " + access_token},
+ json=request_body
+ )
+
+ try:
+ resp.raise_for_status()
+ return APIResponse(is_success=True)
+ except HTTPError:
+ try:
+ error_body = resp.json()
+ error_message = error_body["message"]
+ except:
+ error_message = "Failed to create a new task"
+
+ return APIResponse(is_success=False, error_message=error_message)
+
+
+
+def get_single_event(event_id: int) -> APIResponse:
+ access_token = AuthHandler.get_access_token()
+ resp = requests.get(
+ url=urljoin(BASE_URL, f"events/{event_id}"),
+ headers={"Authorization": "Bearer " + access_token}
+ )
+
+ try:
+ resp.raise_for_status()
+ return APIResponse(is_success=True, body=resp.json())
+ except HTTPError:
+ try:
+ error_body = resp.json()
+ error_message = error_body["message"]
+ except:
+ error_message = "Failed to retrieve a task"
+
+ return APIResponse(is_success=False, error_message=error_message)
+
+
def get_all_tasks(
start_date: Optional[str] = "2000-01-01",
end_date: Optional[str] = "2050-01-01",
diff --git a/girok/commands/task/command.py b/girok/commands/task/command.py
index 143a171..55d0551 100644
--- a/girok/commands/task/command.py
+++ b/girok/commands/task/command.py
@@ -470,3 +470,172 @@ def map_to_event_entities(events: List[dict]) -> List[Event]:
event_entities.sort(key=sort_key)
return event_entities
+
+@app.command(
+ "uptask",
+ help="[yellow]Update[/yellow] a new task",
+ rich_help_panel=":fire: [bold yellow1]Task Commands[/bold yellow1]",
+)
+def update_task(
+ event_id: Annotated[
+ int,
+ typer.Argument(
+ help="[yellow]Task ID[/yellow]"
+ )
+ ],
+ name: Annotated[
+ Optional[str],
+ typer.Option(
+ '-n', '--name',
+ help="Task name"
+ )
+ ] = None,
+ start_datetime: Annotated[
+ Optional[str],
+ typer.Option("-d", "--date", help="[yellow]Task start datetime[/yellow]", callback=datetime_callback)
+ ] = None,
+ end_datetime: Annotated[
+ Optional[str],
+ typer.Option("-e", "--end", help="[yellow]Task end datetime[/yellow]", callback=datetime_callback),
+ ] = None,
+ repetition: Annotated[
+ Optional[str],
+ typer.Option(
+ "-r",
+ "--repetition",
+ help="[yellow]Task repetition type. One of 'daily', 'weekly', 'monthly', 'yearly'[/yellow]",
+ ),
+ ] = None,
+ category_path: Annotated[
+ Optional[str],
+ typer.Option(
+ "-c",
+ "--category",
+ help="[yellow]Category path - xx/yy/zz..[/yellow]",
+ callback=allow_empty_category_callback,
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[str],
+ typer.Option(
+ "-t",
+ "--tag",
+ help="[yellow]Tags[/yellow]. Multiple tags must be provided in 'A,B,C' format.",
+ callback=tags_callback,
+ ),
+ ] = None,
+ priority: Annotated[
+ Optional[str], typer.Option("-p", "--priority", help="[yellow]Priority[/yellow]", callback=priority_callback)
+ ] = None,
+ memo: Annotated[Optional[str], typer.Option("-m", "--memo", help="[yellow]Memo[/yellow]")] = None,
+):
+ try:
+ cache = read_json(EVENT_IDS_CACHE_PATH)
+ except:
+ center_print("First type 'showtask' command to retrieve task ids", DisplayBoxType.ERROR)
+ raise typer.Exit()
+
+ if str(event_id) not in cache:
+ center_print(f"Task id {event_id} is not found. Please enter 'showtask' command to view task ids.", DisplayBoxType.ERROR)
+ raise typer.Exit()
+ cached_event = cache[str(event_id)]
+
+ target_event_id = cached_event["id"]
+
+ """
+ Validate time combination. The possible combinations are:
+ 1. start_date
+ 2. start_date, start_time
+ 3. start_date, end_date
+ 4. start_date, start_time, end_date, end_time
+ """
+ start_date, start_time = None, None
+ if start_datetime:
+ start_date, start_time = start_datetime
+
+ end_date, end_time = None, None
+ if end_datetime:
+ end_date, end_time = end_datetime
+
+ if start_date or start_time or end_date or end_time:
+ valid, err_msg = validate_start_end_window(start_date, start_time, end_date, end_time)
+ if not valid:
+ raise typer.BadParameter(err_msg)
+
+ # Convert tags to list
+ if tags:
+ tags = tags.split(",")
+
+ # Validate repetition
+ repetition_type = None
+ repetition_end_date = None
+ if repetition:
+ # Repetition is only allowed for single-day event
+ if (start_date and end_date) and (start_date != end_date):
+ raise typer.BadParameter("Repetition is only allowed for single-day event")
+
+ if "@" not in repetition: # daily
+ if repetition not in REPETITION_TYPE:
+ raise typer.BadParameter("Repetition type must be one of 'daily', 'weekly', 'monthly', 'yearly'")
+ repetition_type = repetition
+ else: # daily@5/14
+ repetition_items = repetition.split("@")
+ if len(repetition_items) != 2:
+ raise typer.BadParameter("Invalid repetition input format")
+
+ repetition_type, repetition_end_date_str = repetition_items
+ if repetition_type not in REPETITION_TYPE:
+ raise typer.BadParameter("Repetition type must be one of 'daily', 'weekly', 'monthly', 'yearly'")
+
+ valid, iso_date_str = decode_date_format(repetition_end_date_str)
+ if not valid:
+ raise typer.BadParameter("Invalid repetition end date format")
+
+ repetition_end_date = iso_date_str
+
+ # Repetition end date must be greater than start_date
+ repetition_end_date_obj = datetime.strptime(repetition_end_date, "%Y-%m-%d").date()
+ start_date_obj = datetime.strptime(start_date, "%Y-%m-%d").date()
+ if repetition_end_date_obj <= start_date_obj:
+ raise typer.BadParameter("Repetition end date must be greater than start date")
+
+ repetition_type = REPETITION_TYPE[repetition_type]
+
+
+ # Get the target event
+ resp = task_api.get_single_event(target_event_id)
+ if not resp.is_success:
+ center_print(resp.error_message, DisplayBoxType.ERROR)
+ raise typer.Exit()
+ event = resp.body
+
+ if category_path is None:
+ category_path = '/'.join([c['categoryName'] for c in event['categoryPath']])
+
+ resp = task_api.update_task(
+ event_id=target_event_id,
+ name=name if name else event['name'],
+ start_date=start_date if start_date else event['eventDate']['startDate'],
+ start_time=start_time if start_time else event['eventDate']['startTime'],
+ end_date=end_date if end_date else event['eventDate']['endDate'],
+ end_time=end_time if end_time else event['eventDate']['endTime'],
+ repetition_type=repetition_type if repetition_type else event['repetition']['repetitionType'],
+ repetition_end_date=repetition_end_date if repetition_end_date else event['repetition']['repetitionEndDate'],
+ category_path=category_path,
+ tags=tags if tags else event['tags'],
+ priority=priority if priority else event['priority'],
+ memo=memo if memo else event['memo'],
+ )
+ if not resp.is_success:
+ center_print(resp.error_message, DisplayBoxType.ERROR)
+ raise typer.Exit()
+
+ # Display Tasks
+ resp = task_api.get_all_tasks()
+ if not resp.is_success:
+ center_print(resp.error_message, DisplayBoxType.ERROR)
+ raise typer.Exit()
+
+ events = resp.body["events"]
+ event_entities = map_to_event_entities(events)
+ display_events_by_list(event_entities, highlight_event_id=target_event_id, highlight_action="highlight")