Reasonably-working Kimai API data fetch'n'display

This commit is contained in:
3wc 2023-10-27 22:00:03 +01:00
parent a5eca9960e
commit 4b85921b3e
4 changed files with 127 additions and 10 deletions

View File

@ -704,7 +704,6 @@ def _import(username, mapping_path=None, output=None, category_search=None, afte
@cli.command() @cli.command()
def app(): def app():
from .app import HamsterToolsApp from .app import HamsterToolsApp
#app = HamsterToolsApp(db_cursor=c, db_connection=conn)
app = HamsterToolsApp() app = HamsterToolsApp()
app.run() app.run()

View File

@ -5,7 +5,8 @@ from textual.containers import Horizontal, Vertical
from textual.coordinate import Coordinate from textual.coordinate import Coordinate
from textual.screen import Screen from textual.screen import Screen
from .db import DatabaseManager, Category, Activity from .db import DatabaseManager, Category, Activity, KimaiProject, KimaiCustomer
from .kimai import KimaiAPI, Customer as KimaiAPICustomer, Project as KimaiAPIProject, Activity as KimaiAPIActivity
class ListScreen(Screen): class ListScreen(Screen):
@ -55,7 +56,6 @@ class ListScreen(Screen):
class ActivitiesScreen(ListScreen): class ActivitiesScreen(ListScreen):
BINDINGS = [ BINDINGS = [
("q", "quit", "Quit"),
("s", "sort", "Sort"), ("s", "sort", "Sort"),
("r", "refresh", "Refresh"), ("r", "refresh", "Refresh"),
("/", "filter", "Search"), ("/", "filter", "Search"),
@ -133,7 +133,6 @@ class ActivitiesScreen(ListScreen):
class CategoriesScreen(ListScreen): class CategoriesScreen(ListScreen):
BINDINGS = [ BINDINGS = [
("q", "quit", "Quit"),
("s", "sort", "Sort"), ("s", "sort", "Sort"),
("r", "refresh", "Refresh"), ("r", "refresh", "Refresh"),
("/", "filter", "Search"), ("/", "filter", "Search"),
@ -182,11 +181,66 @@ class CategoriesScreen(ListScreen):
self.table.remove_row(row_key) self.table.remove_row(row_key)
class KimaiScreen(ListScreen):
BINDINGS = [
("s", "sort", "Sort"),
("r", "refresh", "Refresh"),
("g", "get", "Get data"),
("/", "filter", "Search"),
Binding(key="escape", action="cancelfilter", show=False),
]
def _refresh(self, filter_query=None):
self.table.clear()
projects = KimaiProject.list(
self.db_manager
)
self.table.add_rows(
[
[
project.customer_id,
project.customer_name,
project.id,
project.name,
]
for project in projects
]
)
self.table.sort(self.sort)
def action_get(self) -> None:
api = KimaiAPI()
customers = KimaiAPICustomer.list(api)
for customer in customers:
KimaiCustomer(self.db_manager, id=customer.id, name=customer.name).save()
projects = KimaiAPIProject.list(api)
for project in projects:
KimaiProject(self.db_manager, id=project.id, name=project.name,
customer_id=project.customer.id, customer_name="").save()
self._refresh()
def on_mount(self) -> None:
self.table = self.query_one(DataTable)
self.table.cursor_type = "row"
self.columns = self.table.add_columns("customer id", "customer",
"project id", "project")
# self.sort = (self.columns[1], self.columns[3])
self.sort = self.columns[1]
self._refresh()
class HamsterToolsApp(App): class HamsterToolsApp(App):
CSS_PATH = "app.tcss" CSS_PATH = "app.tcss"
BINDINGS = [ BINDINGS = [
("a", "switch_mode('activities')", "Activities"), ("a", "switch_mode('activities')", "Activities"),
("c", "switch_mode('categories')", "Categories"), ("c", "switch_mode('categories')", "Categories"),
("k", "switch_mode('kimai')", "Kimai"),
("q", "quit", "Quit"), ("q", "quit", "Quit"),
] ]
@ -195,7 +249,8 @@ class HamsterToolsApp(App):
self.MODES = { self.MODES = {
"categories": CategoriesScreen(self.db_manager), "categories": CategoriesScreen(self.db_manager),
"activities": ActivitiesScreen(self.db_manager) "activities": ActivitiesScreen(self.db_manager),
"kimai": KimaiScreen(self.db_manager)
} }
super().__init__() super().__init__()

View File

@ -200,3 +200,69 @@ class Fact(BaseORM):
cursor.execute("SELECT * FROM facts") cursor.execute("SELECT * FROM facts")
rows = cursor.fetchall() rows = cursor.fetchall()
return [Fact(db_manager, row[0], row[1]) for row in rows] return [Fact(db_manager, row[0], row[1]) for row in rows]
class KimaiCustomer(BaseORM):
def __init__(self, db_manager, id, name):
super().__init__(db_manager, "kimai_customers", id, name=name)
def save(self):
cursor = self.db_manager.get_cursor()
cursor.execute("SELECT id FROM kimai_customers WHERE id = ?", (self.id,))
row = cursor.fetchone()
if row:
cursor.execute("""
UPDATE kimai_customers SET name = ? WHERE id = ?
""", (self.name, self.id))
else:
cursor.execute("""
INSERT INTO kimai_customers (id, name) VALUES (?, ?)
""", (self.id, self.name))
self.db_manager.get_conn().commit()
class KimaiProject(BaseORM):
def __init__(self, db_manager, id, name, customer_id, customer_name):
super().__init__(db_manager, "kimai_projects", id, name=name,
customer_id=customer_id, customer_name=customer_name)
def save(self):
cursor = self.db_manager.get_cursor()
cursor.execute("SELECT id FROM kimai_projects WHERE id = ?", (self.id,))
row = cursor.fetchone()
if row:
cursor.execute("""
UPDATE kimai_projects SET name = ?, customer_id = ? WHERE id = ?
""", (self.name, self.customer_id, self.id))
else:
cursor.execute("""
INSERT INTO kimai_projects (id, name, customer_id) VALUES (?, ?, ?)
""", (self.id, self.name, self.customer_id))
self.db_manager.get_conn().commit()
@staticmethod
def list(db_manager):
cursor = db_manager.get_cursor()
cursor.execute("""
SELECT
kimai_projects.id,
COALESCE(kimai_projects.name, ""),
kimai_customers.id,
COALESCE(kimai_customers.name, "")
FROM
kimai_projects
LEFT JOIN
kimai_customers
ON
kimai_customers.id = kimai_projects.customer_id
GROUP BY
kimai_customers.id
""")
rows = cursor.fetchall()
return [KimaiProject(db_manager, row[0], row[1], row[2], row[3]) for row in rows]
class KimaiACtivity(BaseORM):
pass

View File

@ -76,8 +76,5 @@ class Project(BaseAPI):
return f'Project (id={self.id}, name={self.name}, customer={self.customer})' return f'Project (id={self.id}, name={self.name}, customer={self.customer})'
api = KimaiAPI() class Activity():
pass
customers = Customer.list(api)
projects = Project.list(api)
from pdb import set_trace; set_trace()