Detailed card objects
This commit is contained in:
parent
8c3c0eda45
commit
58232b081a
|
@ -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,11 +12,14 @@ 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)
|
|
||||||
|
|
||||||
|
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)
|
start_favro_fuse(client)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -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."""
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user