1
0

Detailed card objects

This commit is contained in:
Jon Michael Aanes 2024-09-26 19:16:53 +02:00
parent 8c3c0eda45
commit 58232b081a
Signed by: Jmaa
SSH Key Fingerprint: SHA256:Ab0GfHGCblESJx7JRE4fj4bFy/KRpeLhi41y4pF3sNA
3 changed files with 86 additions and 22 deletions

View File

@ -1,9 +1,10 @@
import secret_loader import secret_loader
import requests_cache
import tempfile
from .favro_client import FavroClient, SeqId from .favro_client import FavroClient, SeqId, OrganizationId
from .favro_fuse import start_favro_fuse from .favro_fuse import start_favro_fuse
# Authentication
def main(): def main():
secrets = secret_loader.SecretLoader() secrets = secret_loader.SecretLoader()
@ -11,12 +12,15 @@ def main():
favro_username = secrets.load_or_fail('FAVRO_USERNAME') favro_username = secrets.load_or_fail('FAVRO_USERNAME')
favro_password = secrets.load_or_fail('FAVRO_PASSWORD') favro_password = secrets.load_or_fail('FAVRO_PASSWORD')
client = FavroClient(favro_org_id=favro_org_id, favro_username=favro_username, favro_password=favro_password) with tempfile.TemporaryDirectory(prefix='favro_sync-') as tmpdirname:
#card_id = client.get_card_id(SeqId(4714)) session = requests_cache.CachedSession(tmpdirname + '/http-cache.sqlite', expire_after=360)
#description = 'TEST'
#client.update_card_description(card_id, description)
start_favro_fuse(client) client = FavroClient(favro_org_id=OrganizationId(favro_org_id),
favro_username=favro_username,
favro_password=favro_password, session=session)
client.check_logged_in()
start_favro_fuse(client)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -1,5 +1,6 @@
import requests import requests
import dataclasses import dataclasses
import datetime
from typing import Any from typing import Any
import functools import functools
from collections.abc import Iterator from collections.abc import Iterator
@ -16,21 +17,73 @@ class SeqId:
class CardId: class CardId:
raw_id: str raw_id: str
@dataclasses.dataclass(frozen=True)
class CommonId:
raw_id: str
@dataclasses.dataclass(frozen=True)
class UserId:
raw_id: str
@dataclasses.dataclass(frozen=True)
class OrganizationId:
raw_id: str
@dataclasses.dataclass(frozen=True) @dataclasses.dataclass(frozen=True)
class Card: class Card:
card_id: CardId card_id: CardId
seq_id: SeqId seq_id: SeqId
common_id: CommonId
organization_id: OrganizationId
is_archived: bool
name: str
dependencies: list[None] # TODO
tags: list[None] # TODO
todo_list_user_id: UserId | None
todo_list_completed: bool | None
creator_user_id: UserId
creation_date: datetime.datetime
detailed_description: str | None
# Derived
seq_id_with_prefix: str seq_id_with_prefix: str
detailed_description: str
''' TODO, fieds:
'position': -399
'listPosition': -399
'isLane': False
'assignments': [{'userId': 'Faieomp8fuS8DrnyP' 'completed': True}]
'tasksTotal': 0
'tasksDone': 0
'attachments': []
'customFields':
'timeOnBoard': None
'timeOnColumns': None
'favroAttachments': []
'''
@staticmethod @staticmethod
def from_json(json: dict[str, Any]) -> 'Card': def from_json(json: dict[str, Any]) -> 'Card':
print(json)
return Card( return Card(
card_id = CardId(json['cardId']), card_id = CardId(json['cardId']),
seq_id = SeqId(json['cardSequentialId']), seq_id = SeqId(json['sequentialId']),
seq_id_with_prefix = PREFIX + json['cardSequentialId'], common_id = CommonId(json['cardCommonId']),
detailed_description = json['detailedDescription'], detailed_description = json.get('detailedDescription'),
is_archived = json['archived'],
organization_id = OrganizationId(json['organizationId']),
name = json['name'],
todo_list_user_id = UserId(json['todoListUserId']),
todo_list_completed = json['todoListCompleted'],
dependencies = json['dependencies'],
tags = json['tags'],
creator_user_id = UserId(json['createdByUserId']),
creation_date = datetime.datetime.fromisoformat(json['createdAt']),
seq_id_with_prefix = PREFIX + str(json['sequentialId']),
) )
# Endpoints # Endpoints
@ -40,27 +93,35 @@ URL_UPDATE_CARD = URL_API_ROOT+'/cards/{card_id}'
class FavroClient: class FavroClient:
def __init__(self, *, favro_org_id: str, favro_username: str, favro_password: str, def __init__(self, *, favro_org_id: OrganizationId, favro_username: str, favro_password: str,
session: requests.Session | None = None): session: requests.Session | None = None):
assert favro_org_id is not None
assert favro_username is not None
assert favro_password is not None
# Setup session # Setup session
self.session = session or requests.Session() self.session = session or requests.Session()
self.session.auth = (favro_username, favro_username) self.session.auth = (favro_username, favro_password)
self.session.headers.update({ self.session.headers.update({
'organizationId': favro_org_id, 'organizationId': favro_org_id.raw_id,
'content-type': 'application/json', 'content-type': 'application/json',
}) })
def check_logged_in(self) -> None:
next(self.get_todo_list_cards())
def get_todo_list_cards(self) -> Iterator[Card]: def get_todo_list_cards(self) -> Iterator[Card]:
yield from self.get_cards(todo_list=True) yield from self.get_cards(todo_list=True)
def get_cards(self, *, seqid: SeqId | None = None, todo_list=True) -> Iterator[Card]: def get_cards(self, *, seqid: SeqId | None = None, todo_list=True) -> Iterator[Card]:
# Determine params for get_cards # Determine params for get_cards
params = {} params = {'descriptionFormat': 'markdown'}
if seqid: if seqid:
params['cardSequentialId']= seqid.raw_id params['cardSequentialId']= str(seqid.raw_id)
if todo_list: if todo_list:
params['todoList'] = True params['todoList'] = 'true'
# Run query # Run query
response = self.session.get(URL_GET_ALL_CARDS, params = params) response = self.session.get(URL_GET_ALL_CARDS, params = params)
@ -75,10 +136,9 @@ class FavroClient:
def get_card(self, seqid: SeqId) -> Card: def get_card(self, seqid: SeqId) -> Card:
return next(self.get_cards(seqid=seqid)) return next(self.get_cards(seqid=seqid))
@functools.cache
def get_card_id(self, seqid: SeqId) -> CardId: def get_card_id(self, seqid: SeqId) -> CardId:
json = self.get_card_json(seqid) first_card = next(self.get_cards(seqid = seqid))
return CardId(json['cardId']) return first_card.card_id
def update_card_description(self, card_id: CardId, description: str) -> Card: def update_card_description(self, card_id: CardId, description: str) -> Card:
"""Returns updated Card.""" """Returns updated Card."""

View File

@ -46,7 +46,7 @@ class FavroFuse(fuse.Fuse):
yield fuse.Direntry('..') yield fuse.Direntry('..')
for card in self.favro_client.get_todo_list_cards(): for card in self.favro_client.get_todo_list_cards():
yield fuse.Direntry(card.seqid_with_prefix) yield fuse.Direntry(card.seq_id_with_prefix)
def open(self, path: str, flags) -> int: def open(self, path: str, flags) -> int:
if path != hello_path: if path != hello_path: