From 1145f5e806f2df35ab616b0c62215686a78ca59d Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Fri, 17 Nov 2023 22:54:25 +0000 Subject: [PATCH] API improvements --- hamstertools/app.py | 10 ++++++++++ hamstertools/kimaiapi.py | 32 +++++++++++++++++++++++++++++--- hamstertools/screens/kimai.py | 19 +++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/hamstertools/app.py b/hamstertools/app.py index 6992ae7..3e036e7 100644 --- a/hamstertools/app.py +++ b/hamstertools/app.py @@ -1,6 +1,7 @@ from textual.app import App from .db import db +from .kimaiapi import KimaiAPI from .screens.hamster import HamsterScreen from .screens.kimai import KimaiScreen @@ -8,12 +9,21 @@ from .screens.kimai import KimaiScreen class HamsterToolsApp(App): CSS_PATH = "app.tcss" + BINDINGS = [ ("h", "switch_mode('hamster')", "Hamster"), ("k", "switch_mode('kimai')", "Kimai"), ("q", "quit", "Quit"), ] + api_ = None + + @property + def api(self) -> KimaiAPI: + if self.api_ is None: + self.api_ = KimaiAPI() + return self.api_ + def __init__(self): self.MODES = { "hamster": HamsterScreen(), diff --git a/hamstertools/kimaiapi.py b/hamstertools/kimaiapi.py index 828984f..725bc5f 100644 --- a/hamstertools/kimaiapi.py +++ b/hamstertools/kimaiapi.py @@ -21,16 +21,22 @@ class KimaiAPI(object): auth_headers = {"X-AUTH-USER": KIMAI_USERNAME, "X-AUTH-TOKEN": KIMAI_API_KEY} 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.projects_json = self.get("projects", {"visible": 3, "ignoreDates": 1}) self.activities_json = self.get("activities", {"visible": 3}) self.user_json = self.get("users/me") def get(self, endpoint, params=None): - return requests.get( + result = requests.get( f"{self.KIMAI_API_URL}/{endpoint}", params=params, headers=self.auth_headers ).json() + try: + if result["code"] != 200: + raise NotFound() + except (KeyError, TypeError): + pass + return result def post(self, endpoint, data): return requests.post( @@ -133,7 +139,7 @@ class Activity(BaseAPI): api, a["id"], a["name"], - Project.get_by_id(api, a["project"]), + Project.get_by_id(api, a["project"], none), a["visible"], ) 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 def get_by_id(api, id, none=False): t = api.get( diff --git a/hamstertools/screens/kimai.py b/hamstertools/screens/kimai.py index dac5593..2b66337 100644 --- a/hamstertools/screens/kimai.py +++ b/hamstertools/screens/kimai.py @@ -1,4 +1,5 @@ from textual.app import ComposeResult +from textual.coordinate import Coordinate from textual.binding import Binding from textual.screen import Screen from textual.widgets import DataTable, TabbedContent, TabPane, Header, Footer @@ -12,6 +13,9 @@ from ..db import ( KimaiCustomer, KimaiActivity, ) +from ..kimaiapi import ( + Timesheet as KimaiAPITimesheet +) from .list import ListPane @@ -89,6 +93,7 @@ class KimaiActivityList(ListPane): ("s", "sort", "Sort"), ("r", "refresh", "Refresh"), ("g", "get", "Get data"), + ("#", "count", "Count"), ("/", "filter", "Search"), Binding(key="escape", action="cancelfilter", show=False), ] @@ -122,6 +127,7 @@ class KimaiActivityList(ListPane): activity.id, truncate(activity.name, 40), activity.visible, + '?' ] for activity in activities ] @@ -144,10 +150,23 @@ class KimaiActivityList(ListPane): "id", "name", "visible", + "times", ) self.sort = (self.columns[1], self.columns[3]) 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): BINDINGS = [