API improvements

This commit is contained in:
3wc 2023-11-17 22:54:25 +00:00
parent a01652f301
commit 1145f5e806
3 changed files with 58 additions and 3 deletions

View File

@ -1,6 +1,7 @@
from textual.app import App from textual.app import App
from .db import db from .db import db
from .kimaiapi import KimaiAPI
from .screens.hamster import HamsterScreen from .screens.hamster import HamsterScreen
from .screens.kimai import KimaiScreen from .screens.kimai import KimaiScreen
@ -8,12 +9,21 @@ from .screens.kimai import KimaiScreen
class HamsterToolsApp(App): class HamsterToolsApp(App):
CSS_PATH = "app.tcss" CSS_PATH = "app.tcss"
BINDINGS = [ BINDINGS = [
("h", "switch_mode('hamster')", "Hamster"), ("h", "switch_mode('hamster')", "Hamster"),
("k", "switch_mode('kimai')", "Kimai"), ("k", "switch_mode('kimai')", "Kimai"),
("q", "quit", "Quit"), ("q", "quit", "Quit"),
] ]
api_ = None
@property
def api(self) -> KimaiAPI:
if self.api_ is None:
self.api_ = KimaiAPI()
return self.api_
def __init__(self): def __init__(self):
self.MODES = { self.MODES = {
"hamster": HamsterScreen(), "hamster": HamsterScreen(),

View File

@ -21,16 +21,22 @@ class KimaiAPI(object):
auth_headers = {"X-AUTH-USER": KIMAI_USERNAME, "X-AUTH-TOKEN": KIMAI_API_KEY} auth_headers = {"X-AUTH-USER": KIMAI_USERNAME, "X-AUTH-TOKEN": KIMAI_API_KEY}
def __init__(self): def __init__(self):
requests_cache.install_cache("kimai", backend="sqlite", expire_after=1800) # requests_cache.install_cache("kimai", backend="sqlite", expire_after=1800)
self.customers_json = self.get("customers", {"visible": 3}) self.customers_json = self.get("customers", {"visible": 3})
self.projects_json = self.get("projects", {"visible": 3, "ignoreDates": 1}) self.projects_json = self.get("projects", {"visible": 3, "ignoreDates": 1})
self.activities_json = self.get("activities", {"visible": 3}) self.activities_json = self.get("activities", {"visible": 3})
self.user_json = self.get("users/me") self.user_json = self.get("users/me")
def get(self, endpoint, params=None): def get(self, endpoint, params=None):
return requests.get( result = requests.get(
f"{self.KIMAI_API_URL}/{endpoint}", params=params, headers=self.auth_headers f"{self.KIMAI_API_URL}/{endpoint}", params=params, headers=self.auth_headers
).json() ).json()
try:
if result["code"] != 200:
raise NotFound()
except (KeyError, TypeError):
pass
return result
def post(self, endpoint, data): def post(self, endpoint, data):
return requests.post( return requests.post(
@ -133,7 +139,7 @@ class Activity(BaseAPI):
api, api,
a["id"], a["id"],
a["name"], a["name"],
Project.get_by_id(api, a["project"]), Project.get_by_id(api, a["project"], none),
a["visible"], a["visible"],
) )
if not none: if not none:
@ -169,6 +175,26 @@ class Timesheet(BaseAPI):
) )
] ]
@staticmethod
def list_by(api, **kwargs):
kwargs['size'] = 10000
return [
Timesheet(
api,
Activity.get_by_id(api, t["activity"], none=True),
Project.get_by_id(api, t["project"], none=True),
t["begin"],
t["end"],
t["id"],
t["description"],
t["tags"],
)
for t in api.get(
"timesheets",
params=kwargs
)
]
@staticmethod @staticmethod
def get_by_id(api, id, none=False): def get_by_id(api, id, none=False):
t = api.get( t = api.get(

View File

@ -1,4 +1,5 @@
from textual.app import ComposeResult from textual.app import ComposeResult
from textual.coordinate import Coordinate
from textual.binding import Binding from textual.binding import Binding
from textual.screen import Screen from textual.screen import Screen
from textual.widgets import DataTable, TabbedContent, TabPane, Header, Footer from textual.widgets import DataTable, TabbedContent, TabPane, Header, Footer
@ -12,6 +13,9 @@ from ..db import (
KimaiCustomer, KimaiCustomer,
KimaiActivity, KimaiActivity,
) )
from ..kimaiapi import (
Timesheet as KimaiAPITimesheet
)
from .list import ListPane from .list import ListPane
@ -89,6 +93,7 @@ class KimaiActivityList(ListPane):
("s", "sort", "Sort"), ("s", "sort", "Sort"),
("r", "refresh", "Refresh"), ("r", "refresh", "Refresh"),
("g", "get", "Get data"), ("g", "get", "Get data"),
("#", "count", "Count"),
("/", "filter", "Search"), ("/", "filter", "Search"),
Binding(key="escape", action="cancelfilter", show=False), Binding(key="escape", action="cancelfilter", show=False),
] ]
@ -122,6 +127,7 @@ class KimaiActivityList(ListPane):
activity.id, activity.id,
truncate(activity.name, 40), truncate(activity.name, 40),
activity.visible, activity.visible,
'?'
] ]
for activity in activities for activity in activities
] ]
@ -144,10 +150,23 @@ class KimaiActivityList(ListPane):
"id", "id",
"name", "name",
"visible", "visible",
"times",
) )
self.sort = (self.columns[1], self.columns[3]) self.sort = (self.columns[1], self.columns[3])
self._refresh() self._refresh()
def action_count(self) -> None:
row_idx: int = self.table.cursor_row
row_cells = self.table.get_row_at(row_idx)
activity_id = row_cells[2]
count = len(KimaiAPITimesheet.list_by(self.app.api, activity=activity_id))
self.table.update_cell_at(
Coordinate(row_idx, 5),
count
)
class KimaiScreen(Screen): class KimaiScreen(Screen):
BINDINGS = [ BINDINGS = [