[client]: Pagination and additional card info
This commit is contained in:
parent
7cd847ce64
commit
c98946cacb
|
@ -102,8 +102,13 @@ class FavroClient:
|
|||
seq_id: SeqId | None = None,
|
||||
todo_list=False,
|
||||
) -> Iterator[Card]:
|
||||
page = 0
|
||||
request_id = None
|
||||
num_pages = 1
|
||||
|
||||
while page < num_pages:
|
||||
# Determine params for get_cards
|
||||
request = self._get_cards_request(seq_id, todo_list)
|
||||
request = self._get_cards_request(seq_id, todo_list, page=page, request_id=request_id)
|
||||
|
||||
# Run query
|
||||
logger.warning('Sending request: %s', request.url)
|
||||
|
@ -111,23 +116,33 @@ class FavroClient:
|
|||
response.raise_for_status()
|
||||
json = response.json()
|
||||
|
||||
# TODO: Add support for pageination
|
||||
for entity_json in json['entities']:
|
||||
card = Card.from_json(entity_json)
|
||||
self.cache.add_card(card)
|
||||
yield card
|
||||
del entity_json
|
||||
|
||||
# Pagination bookkeeping
|
||||
page = json['page'] + 1
|
||||
request_id = json['requestId']
|
||||
num_pages = json['pages']
|
||||
|
||||
def _get_cards_request(
|
||||
self,
|
||||
seq_id: SeqId | None = None,
|
||||
todo_list=False,
|
||||
todo_list: bool=False,
|
||||
request_id: None | str = None,
|
||||
page: None | int = None,
|
||||
) -> requests.PreparedRequest:
|
||||
params = {'descriptionFormat': 'markdown'}
|
||||
if seq_id is not None:
|
||||
params['cardSequentialId'] = str(seq_id.raw_id)
|
||||
if todo_list is True:
|
||||
params['todoList'] = 'true'
|
||||
if request_id:
|
||||
params['requestId'] = request_id
|
||||
if page:
|
||||
params['page'] = page
|
||||
|
||||
request = requests.Request('GET', URL_GET_ALL_CARDS, params=params)
|
||||
return self.session.prepare_request(request)
|
||||
|
@ -192,6 +207,7 @@ class FavroClient:
|
|||
'name': card_contents.name,
|
||||
'detailedDescription': card_contents.description,
|
||||
'descriptionFormat': 'markdown',
|
||||
'archived': card_contents.archived,
|
||||
}
|
||||
|
||||
url = URL_UPDATE_CARD.format(card_id=card_id.raw_id)
|
||||
|
|
|
@ -94,13 +94,13 @@ class TagInfo:
|
|||
@dataclasses.dataclass(frozen=True)
|
||||
class CustomField:
|
||||
custom_field_id: CustomFieldId
|
||||
value: list[str] # TODO
|
||||
value: list[str] | str
|
||||
|
||||
@staticmethod
|
||||
def from_json(json: dict[str, Any]) -> 'CustomField':
|
||||
return CustomField(
|
||||
CustomFieldId(json['customFieldId']),
|
||||
json['value'], # TODO
|
||||
json.get('value'),
|
||||
)
|
||||
|
||||
|
||||
|
@ -137,14 +137,14 @@ class Card:
|
|||
todo_list_completed: bool | None
|
||||
creator_user_id: UserId
|
||||
creation_date: datetime.datetime
|
||||
start_date: datetime.date | None
|
||||
due_date: datetime.date | None
|
||||
attachments: list[dict]
|
||||
detailed_description: str | None
|
||||
archived: bool
|
||||
|
||||
@staticmethod
|
||||
def from_json(json: dict[str, Any]) -> 'Card':
|
||||
todo_list_user_id = (
|
||||
UserId(json['todoListUserId']) if 'todoListUserId' in json else None
|
||||
)
|
||||
return Card(
|
||||
card_id=CardId(json['cardId']),
|
||||
seq_id=SeqId(json['sequentialId']),
|
||||
|
@ -153,17 +153,25 @@ class Card:
|
|||
is_archived=json['archived'],
|
||||
organization_id=OrganizationId(json['organizationId']),
|
||||
name=json['name'],
|
||||
todo_list_user_id=todo_list_user_id,
|
||||
todo_list_user_id=map_opt(UserId, json.get('todoListUserId')),
|
||||
todo_list_completed=json.get('todoListCompleted'),
|
||||
dependencies=[
|
||||
CardDependency.from_json(dep) for dep in json['dependencies']
|
||||
],
|
||||
tags=[TagId(tag) for tag in json['tags']],
|
||||
creator_user_id=UserId(json['createdByUserId']),
|
||||
creation_date=datetime.datetime.fromisoformat(json['createdAt']),
|
||||
creation_date=map_opt(datetime.datetime.fromisoformat,json.get('createdAt')),
|
||||
start_date=map_opt(datetime.datetime.fromisoformat,json.get('startDate')),
|
||||
due_date=map_opt(datetime.datetime.fromisoformat,json.get('dueDate')),
|
||||
assignments=[CardAssignment.from_json(ass) for ass in json['assignments']],
|
||||
custom_fields=[
|
||||
CustomField.from_json(field) for field in json['customFields']
|
||||
],
|
||||
archived=json['archived'],
|
||||
attachments=json['attachments'], # TODO
|
||||
)
|
||||
|
||||
def map_opt(mapper, value):
|
||||
if value is not None:
|
||||
return mapper(value)
|
||||
return None
|
||||
|
|
|
@ -201,6 +201,8 @@ class FavroFuse(fuse.Fuse):
|
|||
seq_id=card.seq_id.raw_id,
|
||||
),
|
||||
todo_list_completed = card.todo_list_completed,
|
||||
start_date= card.start_date,
|
||||
due_date= card.due_date,
|
||||
)
|
||||
return self.formatter.format_card_contents(card_contents)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import dataclasses
|
||||
import re
|
||||
import datetime
|
||||
|
||||
import frontmatter
|
||||
import marko
|
||||
|
@ -14,6 +15,9 @@ FM_KEY_ASSIGNMENTS = 'assignments'
|
|||
FM_KEY_DEPENDENCIES = 'dependencies'
|
||||
FM_KEY_URL = 'url'
|
||||
FM_KEY_ALIASES = 'aliases'
|
||||
FM_KEY_ARCHIVED = 'archived'
|
||||
FM_KEY_DUE_DATE = 'due'
|
||||
FM_KEY_START_DATE = 'start-date'
|
||||
|
||||
################################################################################
|
||||
|
||||
|
@ -27,6 +31,9 @@ class CardContents:
|
|||
card_dependencies: list[str]
|
||||
url: str
|
||||
todo_list_completed: bool | None
|
||||
archived: bool
|
||||
start_date: datetime.date | None
|
||||
due_date: datetime.date | None
|
||||
|
||||
|
||||
def format_obsidian_link(text: str) -> str:
|
||||
|
@ -87,6 +94,12 @@ class CardFileFormatter:
|
|||
]
|
||||
if card.todo_list_completed:
|
||||
frontmatter_data[FM_KEY_TODO_LIST_COMPLETED] = card.todo_list_completed
|
||||
if card.archived:
|
||||
frontmatter_data[FM_KEY_ARCHIVED] = card.archived
|
||||
if card.due_date:
|
||||
frontmatter_data[FM_KEY_DUE_DATE] = card.due_date
|
||||
if card.start_date:
|
||||
frontmatter_data[FM_KEY_DUE_DATE] = card.start_date
|
||||
|
||||
# Card name
|
||||
ls = []
|
||||
|
@ -134,6 +147,10 @@ class CardFileFormatter:
|
|||
|
||||
url: list[str] = fm.metadata.get(FM_KEY_URL)
|
||||
todo_list_completed: bool | None = fm.metadata.get(FM_KEY_TODO_LIST_COMPLETED)
|
||||
archived: bool = fm.metadata.get(FM_KEY_ARCHIVED)
|
||||
|
||||
start_date: datetime.date = fm.metadata.get(FM_KEY_START_DATE)
|
||||
due_date: datetime.date = fm.metadata.get(FM_KEY_DUE_DATE)
|
||||
|
||||
description = self.renderer.render_children(document).strip()
|
||||
return CardContents(
|
||||
|
@ -145,4 +162,7 @@ class CardFileFormatter:
|
|||
card_dependencies=card_dependencies,
|
||||
url=url,
|
||||
todo_list_completed=todo_list_completed,
|
||||
archived=archived,
|
||||
start_date=start_date,
|
||||
due_date=due_date,
|
||||
)
|
||||
|
|
|
@ -20,15 +20,19 @@ def test_create_client():
|
|||
def test_get_card():
|
||||
client = create_client()
|
||||
card = client.get_card(SeqId(11368))
|
||||
print(card)
|
||||
|
||||
assert card is not None
|
||||
assert card.name is not None
|
||||
assert_valid_card(card)
|
||||
|
||||
assert card.detailed_description is not None
|
||||
assert len(card.dependencies) == 1
|
||||
assert len(card.attachments) == 0
|
||||
assert len(card.custom_fields) == 2
|
||||
|
||||
@needs_secrets
|
||||
def test_get_cards():
|
||||
client = create_client()
|
||||
for card in client.get_cards(todo_list=True):
|
||||
assert_valid_card(card)
|
||||
|
||||
def create_client():
|
||||
return FavroClient(
|
||||
|
@ -37,3 +41,7 @@ def create_client():
|
|||
favro_password=secrets.favro_password(),
|
||||
read_only=True,
|
||||
)
|
||||
|
||||
def assert_valid_card(card):
|
||||
assert card is not None
|
||||
assert card.name is not None
|
||||
|
|
Loading…
Reference in New Issue
Block a user