From 9d5474485951e4766539626c7f45be1c693f3f56 Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Wed, 2 Oct 2024 13:34:49 +0200 Subject: [PATCH] custom fields WIP --- favro_sync/favro_data_model.py | 40 ++++++++++++++++++++++++---------- favro_sync/favro_fuse.py | 18 ++++++++++++++- favro_sync/favro_markdown.py | 1 + test/test_client.py | 3 +++ 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/favro_sync/favro_data_model.py b/favro_sync/favro_data_model.py index a495965..85c6874 100644 --- a/favro_sync/favro_data_model.py +++ b/favro_sync/favro_data_model.py @@ -9,6 +9,12 @@ import datetime from typing import Any +def map_opt(mapper, value): + if value is not None: + return mapper(value) + return None + + @dataclasses.dataclass(frozen=True) class SeqId: raw_id: int @@ -122,6 +128,13 @@ class CustomFieldItem: custom_field_item_id: CustomFieldItemId name: str + @staticmethod + def from_json(json: dict[str, Any]) -> 'CustomFieldItem': + return CustomFieldItem( + custom_field_item_id=CustomFieldItemId(json['customFieldItemId']), + name=json['name'], + ) + @dataclasses.dataclass(frozen=True) class CustomFieldInfo: @@ -145,29 +158,40 @@ class CustomFieldInfo: enabled: bool custom_field_items: list[CustomFieldItem] + def get_field_item(self, field_item_id: CustomFieldItemId) -> CustomFieldItem | None: + for item in self.custom_field_items: + if item.custom_field_item_id == field_item_id: + return item + return None + @staticmethod def from_json(json: dict[str, Any]) -> 'CustomFieldInfo': return CustomFieldInfo( organization_id=OrganizationId(json['organizationId']), custom_field_id=CustomFieldId(json['customFieldId']), - widget_common_id=WidgetCommonId(json['widgetCommonId']), + widget_common_id=map_opt(WidgetCommonId,json.get('widgetCommonId')), type=json['type'], name=json['name'], enabled=json['enabled'], - custom_field_items=json['customFieldItems'], + custom_field_items=[CustomFieldItem.from_json(f) for f in json['customFieldItems']], ) @dataclasses.dataclass(frozen=True) class CustomField: custom_field_id: CustomFieldId - value: list[str] | str + value: list[CustomFieldItemId] | CustomFieldItemId @staticmethod def from_json(json: dict[str, Any]) -> 'CustomField': + value = json['value'] + if isinstance(value, str): + typed_value = CustomFieldItemId(value) + else: + typed_value = [CustomFieldItemId(v) for v in value] return CustomField( - CustomFieldId(json['customFieldId']), - json.get('value'), + custom_field_id = CustomFieldId(json['customFieldId']), + value = typed_value, ) @@ -261,9 +285,3 @@ class Card: ], attachments=json['attachments'], # TODO ) - - -def map_opt(mapper, value): - if value is not None: - return mapper(value) - return None diff --git a/favro_sync/favro_fuse.py b/favro_sync/favro_fuse.py index 3627e8a..05e83d2 100644 --- a/favro_sync/favro_fuse.py +++ b/favro_sync/favro_fuse.py @@ -8,7 +8,7 @@ from logging import getLogger import fuse from .favro_client import FavroClient -from .favro_data_model import Card, SeqId +from .favro_data_model import Card, SeqId, CustomFieldInfo, CustomFieldItemId from .favro_markdown import CardContents, CardFileFormatter logger = getLogger(__name__) @@ -58,6 +58,21 @@ class CardFileSystemItem(FileSystemItem): seq_id: SeqId +def to_custom_field_value(value: CustomFieldItemId | list[CustomFieldItemId], field_def: CustomFieldInfo) -> str: + if field_def.type == 'Single select': + items = [field_def.get_field_item(item_id) for item_id in value] + items = [i for i in items if i] + return items[0].name + assert False, 'Unknown type: ' + field_def.type + +def to_custom_fields(card: Card, favro_client: FavroClient) -> dict[str,str]: + custom_fields = {} + for field_assignment in card.custom_fields: + field_def = favro_client.get_custom_field(field_assignment.custom_field_id) + custom_fields[field_def.name] = to_custom_field_value(field_assignment.value, field_def) + del field_assignment + return custom_fields + def to_card_contents(card: Card, favro_client: FavroClient) -> str: tags = [favro_client.get_tag(tag_id).name for tag_id in card.tags] assignments = [ @@ -85,6 +100,7 @@ def to_card_contents(card: Card, favro_client: FavroClient) -> str: is_archived=card.is_archived, start_date=card.start_date, due_date=card.due_date, + custom_fields=to_custom_fields(card, favro_client) ) diff --git a/favro_sync/favro_markdown.py b/favro_sync/favro_markdown.py index 2667e12..2974b4e 100644 --- a/favro_sync/favro_markdown.py +++ b/favro_sync/favro_markdown.py @@ -35,6 +35,7 @@ class CardContents: is_archived: bool start_date: datetime.date | None due_date: datetime.date | None + custom_fields: dict[str,str] def format_obsidian_link(text: str) -> str: diff --git a/test/test_client.py b/test/test_client.py index 182b86b..2423842 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -42,6 +42,9 @@ def test_get_cards(): for card in client.get_cards(todo_list=True): assert_valid_card(card) + if card.seq_id == SeqId(8723): + assert card.is_archived + def create_client(): return FavroClient(