From cbb0cba076f69e1774bd0e3d1e17dcf1d40bf367 Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Thu, 10 Oct 2024 14:02:02 +0200 Subject: [PATCH] Ruff --- favro_sync/favro_client.py | 31 ++++++++++++------ favro_sync/favro_data_model.py | 40 +++++++++++++---------- favro_sync/favro_fuse.py | 34 ++++++++++++++----- favro_sync/favro_markdown.py | 4 +-- test/test_client.py | 4 ++- test/test_integration_api_to_formatter.py | 3 +- 6 files changed, 76 insertions(+), 40 deletions(-) diff --git a/favro_sync/favro_client.py b/favro_sync/favro_client.py index 80ad53f..8b81962 100644 --- a/favro_sync/favro_client.py +++ b/favro_sync/favro_client.py @@ -4,21 +4,21 @@ Implements methods for interacting with the [Favro API](https://favro.com/devel """ import dataclasses +import datetime from collections.abc import Iterator from logging import getLogger -import datetime -import requests_util import requests +import requests_util from .favro_data_model import ( Card, CardId, Collection, + CollectionId, CustomFieldId, CustomFieldInfo, OrganizationId, - CollectionId, SeqId, TagId, TagInfo, @@ -107,9 +107,15 @@ class FavroClient: self.card_cache = CardCache() # Setup caching - requests_util.setup_limiter(self.session, URL_API_ROOT, datetime.timedelta(days=7)) - requests_util.setup_limiter(self.session, URL_GET_CARDS, datetime.timedelta(minutes=10)) - requests_util.setup_limiter(self.session, URL_GET_TASKS, datetime.timedelta(minutes=10)) + requests_util.setup_limiter( + self.session, URL_API_ROOT, datetime.timedelta(days=7), + ) + requests_util.setup_limiter( + self.session, URL_GET_CARDS, datetime.timedelta(minutes=10), + ) + requests_util.setup_limiter( + self.session, URL_GET_TASKS, datetime.timedelta(minutes=10), + ) def check_logged_in(self) -> None: next(self.get_todo_list_cards()) @@ -124,7 +130,9 @@ class FavroClient: collection_id: CollectionId | None = None, todo_list=False, ) -> Iterator[Card]: - request = self._get_cards_request(seq_id=seq_id,todo_list=todo_list,collection_id=collection_id) + request = self._get_cards_request( + seq_id=seq_id, todo_list=todo_list, collection_id=collection_id, + ) for card in self._get_paginated(request, Card.from_json): self.card_cache.add_card(card) yield card @@ -134,9 +142,10 @@ class FavroClient: yield from self._get_paginated(request, Collection.from_json) def _get_cards_prepared_request( - self, **kwargs, + self, + **kwargs, ) -> requests.PreparedRequest: - request = self._get_cards_request(**kwargs) + request = self._get_cards_request(**kwargs) return self.session.prepare_request(request) def _get_cards_request( @@ -234,7 +243,9 @@ class FavroClient: self._invalidate_cache(card_id) return self.update_card_contents_locally(card_id, card_contents) - def _get_paginated(self, base_request: requests.Request, entity_from_json) -> Iterator: + def _get_paginated( + self, base_request: requests.Request, entity_from_json, + ) -> Iterator: page = 0 request_id = None num_pages = 1 diff --git a/favro_sync/favro_data_model.py b/favro_sync/favro_data_model.py index 4346a41..f06505b 100644 --- a/favro_sync/favro_data_model.py +++ b/favro_sync/favro_data_model.py @@ -136,8 +136,8 @@ class CustomFieldItem: @staticmethod def from_json(json: dict[str, Any]) -> 'CustomFieldItem': return CustomFieldItem( - custom_field_item_id=CustomFieldItemId(json['customFieldItemId']), - name=json['name'], + custom_field_item_id=CustomFieldItemId(json['customFieldItemId']), + name=json['name'], ) @@ -163,7 +163,9 @@ class CustomFieldInfo: enabled: bool custom_field_items: list[CustomFieldItem] - def get_field_item(self, field_item_id: CustomFieldItemId) -> CustomFieldItem | None: + 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 @@ -174,11 +176,13 @@ class CustomFieldInfo: return CustomFieldInfo( organization_id=OrganizationId(json['organizationId']), custom_field_id=CustomFieldId(json['customFieldId']), - widget_common_id=map_opt(WidgetCommonId,json.get('widgetCommonId')), + widget_common_id=map_opt(WidgetCommonId, json.get('widgetCommonId')), type=json['type'], name=json['name'], enabled=json['enabled'], - custom_field_items=[CustomFieldItem.from_json(f) for f in json.get('customFieldItems', [])], + custom_field_items=[ + CustomFieldItem.from_json(f) for f in json.get('customFieldItems', []) + ], ) @@ -198,9 +202,9 @@ class CustomField: else: typed_value = [CustomFieldItemId(v) for v in value] return CustomField( - custom_field_id = CustomFieldId(json['customFieldId']), - value = typed_value, - color = json.get('color'), + custom_field_id=CustomFieldId(json['customFieldId']), + value=typed_value, + color=json.get('color'), ) @@ -243,12 +247,13 @@ class Task: position=json['position'], ) + @dataclasses.dataclass(frozen=True) class Collection: collection_id: CollectionId organization_id: OrganizationId name: str - shared_to_users: list[dict[str,str]] # TODO + shared_to_users: list[dict[str, str]] # TODO public_sharing: str background: str is_archived: bool @@ -257,16 +262,17 @@ class Collection: @staticmethod def from_json(json: dict[str, Any]) -> 'Collection': return Collection( - collection_id=CollectionId(json['collectionId']), - organization_id=OrganizationId(json['collectionId']), - name=json['name'], - shared_to_users=json['sharedToUsers'], - public_sharing=json['publicSharing'], - background=json['background'], - is_archived=json['archived'], - widget_common_id=map_opt(WidgetCommonId,json.get('widgetCommonId')), + collection_id=CollectionId(json['collectionId']), + organization_id=OrganizationId(json['collectionId']), + name=json['name'], + shared_to_users=json['sharedToUsers'], + public_sharing=json['publicSharing'], + background=json['background'], + is_archived=json['archived'], + widget_common_id=map_opt(WidgetCommonId, json.get('widgetCommonId')), ) + @dataclasses.dataclass(frozen=True) class Card: card_id: CardId diff --git a/favro_sync/favro_fuse.py b/favro_sync/favro_fuse.py index e1e4e65..2ac3029 100644 --- a/favro_sync/favro_fuse.py +++ b/favro_sync/favro_fuse.py @@ -8,7 +8,13 @@ from logging import getLogger import fuse from .favro_client import FavroClient -from .favro_data_model import Card, SeqId, CustomFieldInfo, CustomFieldItemId, CustomField +from .favro_data_model import ( + Card, + CustomField, + CustomFieldInfo, + CustomFieldItemId, + SeqId, +) from .favro_markdown import CardContents, CardFileFormatter ################################################################################ @@ -26,9 +32,12 @@ CARD_FILENAME_REGEX = r'^PAR\-(\d+)\.md$' ################################################################################ # Formatting -def to_custom_field_value(custom_field: CustomField, field_def: CustomFieldInfo) -> str | None: + +def to_custom_field_value( + custom_field: CustomField, field_def: CustomFieldInfo, +) -> str | None: value: CustomFieldItemId | list[CustomFieldItemId] = custom_field.value - if field_def.type in {'Single select','Multiple select'}: + if field_def.type in {'Single select', 'Multiple 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 @@ -36,7 +45,8 @@ def to_custom_field_value(custom_field: CustomField, field_def: CustomFieldInfo) return custom_field.color return None -def to_custom_fields(card: Card, favro_client: FavroClient) -> dict[str,str]: + +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) @@ -46,6 +56,7 @@ def to_custom_fields(card: Card, favro_client: FavroClient) -> dict[str,str]: del field_assignment, str_value return custom_fields + def to_card_contents(card: Card, favro_client: FavroClient) -> CardContents: tags = [favro_client.get_tag(tag_id).name for tag_id in card.tags] assignments = [ @@ -80,6 +91,7 @@ def to_card_contents(card: Card, favro_client: FavroClient) -> CardContents: ################################################################################ # FUSE + class FavroStat(fuse.Stat): def __init__(self): self.st_mode = 0 @@ -101,7 +113,6 @@ class FileSystemItem: @dataclasses.dataclass(frozen=True) class RootFileSystemItem(FileSystemItem): - @staticmethod def from_path_segment(_segment: str) -> 'RootFileSystemItem': return RootFileSystemItem() @@ -109,6 +120,7 @@ class RootFileSystemItem(FileSystemItem): def __str__(self): return '/' + @dataclasses.dataclass(frozen=True) class CollectionFileSystemItem(FileSystemItem): collection_name: str @@ -123,6 +135,7 @@ class CollectionFileSystemItem(FileSystemItem): def __str__(self): return self.collection_name + @dataclasses.dataclass(frozen=True) class CardFileSystemItem(FileSystemItem): seq_id: SeqId @@ -137,7 +150,9 @@ class CardFileSystemItem(FileSystemItem): return CARD_FILENAME_FORMAT.format(seq_id=self.seq_id.raw_id) -def path_to_file_system_item(path_str: str, path_components: list[type[FileSystemItem]]) -> FileSystemItem | None: +def path_to_file_system_item( + path_str: str, path_components: list[type[FileSystemItem]], +) -> FileSystemItem | None: path = re.findall(r'[^/]+', path_str) component = path_components[len(path)] return component.from_path_segment(path[-1] if path else None) @@ -155,7 +170,11 @@ class FavroFuse(fuse.Fuse): self.favro_client = favro_client self.formatter = formatter self.wiped_cards = set() - self.path_components = [RootFileSystemItem, CollectionFileSystemItem, CardFileSystemItem] + self.path_components = [ + RootFileSystemItem, + CollectionFileSystemItem, + CardFileSystemItem, + ] super().__init__(**kwargs) def getattr(self, path: str) -> FavroStat | int: @@ -190,7 +209,6 @@ class FavroFuse(fuse.Fuse): del collection elif isinstance(file_system_item, CollectionFileSystemItem): - # TODO: move into own function for collection in self.favro_client.get_collections(): if collection.name.replace('/', '') == file_system_item.collection_name: diff --git a/favro_sync/favro_markdown.py b/favro_sync/favro_markdown.py index 4b464ea..062597a 100644 --- a/favro_sync/favro_markdown.py +++ b/favro_sync/favro_markdown.py @@ -35,7 +35,7 @@ class CardContents: is_archived: bool start_date: datetime.date | None due_date: datetime.date | None - custom_fields: dict[str,str] + custom_fields: dict[str, str] def format_obsidian_link(text: str) -> str: @@ -173,5 +173,5 @@ class CardFileFormatter: is_archived=is_archived, start_date=start_date, due_date=due_date, - custom_fields={}, # TODO + custom_fields={}, # TODO ) diff --git a/test/test_client.py b/test/test_client.py index 6cacdd0..b06f7cb 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -1,6 +1,6 @@ import pytest - import requests_cache + from favro_sync import secrets from favro_sync.favro_client import FavroClient, OrganizationId, SeqId @@ -50,6 +50,7 @@ def test_get_cards(): for card in client.get_cards(todo_list=True): assert_valid_card(card) + @needs_secrets def test_get_collections(): client = create_client() @@ -62,6 +63,7 @@ def test_get_collections(): assert collection.is_archived is not None assert collection.widget_common_id is None + def create_client(): session = requests_cache.CachedSession('output/test-http-cache.sqlite') return FavroClient( diff --git a/test/test_integration_api_to_formatter.py b/test/test_integration_api_to_formatter.py index 474985f..f8543e6 100644 --- a/test/test_integration_api_to_formatter.py +++ b/test/test_integration_api_to_formatter.py @@ -1,9 +1,8 @@ -from favro_sync.favro_client import SeqId from favro_sync.favro_fuse import to_card_contents -from favro_sync.favro_markdown import CardFileFormatter from .test_client import create_client, needs_secrets + @needs_secrets def test_format_all_cards(): client = create_client()