Compare commits

..

3 Commits

Author SHA1 Message Date
3wc
be1a8a7f7a Tweak kimai check command 2023-11-01 21:56:08 +00:00
3wc
21fc28a14e Break out sync to separate file 2023-11-01 21:11:21 +00:00
3wc
77f87e5299 Move debugging output to -d option 2023-11-01 20:56:04 +00:00
5 changed files with 96 additions and 72 deletions

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python3.7 #!/usr/bin/env python3.7
import csv import csv
import logging
from datetime import datetime from datetime import datetime
from itertools import chain from itertools import chain
from pathlib import Path from pathlib import Path
@ -8,6 +9,7 @@ import sys
import click import click
import requests import requests
from peewee import fn, JOIN from peewee import fn, JOIN
from textual.logging import TextualHandler
from .db import ( from .db import (
db, db,
@ -20,6 +22,7 @@ from .db import (
HamsterActivityKimaiMapping, HamsterActivityKimaiMapping,
HamsterFactKimaiImport, HamsterFactKimaiImport,
) )
from .sync import sync
HAMSTER_DIR = Path.home() / ".local/share/hamster" HAMSTER_DIR = Path.home() / ".local/share/hamster"
# HAMSTER_FILE = HAMSTER_DIR / 'hamster.db' # HAMSTER_FILE = HAMSTER_DIR / 'hamster.db'
@ -29,8 +32,19 @@ db.init(HAMSTER_FILE)
@click.group() @click.group()
def cli(): @click.option("-d", "--debug", is_flag=True)
pass def cli(debug):
if debug:
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
peewee_logger = logging.getLogger("peewee")
peewee_logger.addHandler(TextualHandler())
peewee_logger.setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
@cli.group() @cli.group()
@ -340,28 +354,29 @@ def _get_kimai_mapping_file(path, category_search=None):
multiple=True, multiple=True,
) )
@click.argument("username") @click.argument("username")
@click.argument("api_key") @click.argument("api_key", envvar="KIMAI_API_KEY")
@click.option("--just-errors", "just_errors", is_flag=True, help="Only display errors") @click.option("--just-errors", "just_errors", is_flag=True, help="Only display errors")
@click.option("--ignore-activities", is_flag=True, help="Ignore missing activities") @click.option("--ignore-activities", is_flag=True, help="Ignore missing activities")
def sync(username, api_key, just_errors, ignore_activities, mapping_path=None): def check(username, api_key, just_errors, ignore_activities, mapping_path=None):
""" """
Download customer / project / activity data from Kimai Check customer / project / activity data from Kimai
""" """
kimai_api_url = "https://kimai.autonomic.zone/api" kimai_api_url = "https://kimai.autonomic.zone/api"
if type(mapping_path) == tuple: if len(mapping_path) == 0:
mapping_files = [] mapping_path = (HAMSTER_DIR / "mapping.kimai.csv",)
for mapping_path_item in mapping_path:
mapping_file = _get_kimai_mapping_file(mapping_path_item) mapping_files = []
next(mapping_file) for mapping_path_item in mapping_path:
mapping_files.append(mapping_file) if not Path(mapping_path_item).exists():
mapping_reader = csv.reader(chain(*mapping_files)) raise click.UsageError(f'{mapping_path_item} does not exist')
else:
if mapping_path is None: mapping_file = _get_kimai_mapping_file(mapping_path_item)
mapping_path = HAMSTER_DIR / "mapping.kimai.csv" next(mapping_file)
mapping_file = _get_kimai_mapping_file(mapping_path) mapping_files.append(mapping_file)
mapping_reader = csv.reader(mapping_file)
mapping_reader = csv.reader(chain(*mapping_files))
next(mapping_reader) next(mapping_reader)
@ -387,7 +402,6 @@ def sync(username, api_key, just_errors, ignore_activities, mapping_path=None):
for row in mapping_data: for row in mapping_data:
# Check if each mapping still exists in Kimai # Check if each mapping still exists in Kimai
matching_customers = list(filter(lambda x: x["name"] == row[0], customers)) matching_customers = list(filter(lambda x: x["name"] == row[0], customers))
if row[0] in found_customers: if row[0] in found_customers:
just_errors or click.secho( just_errors or click.secho(
@ -647,6 +661,11 @@ def reset():
HamsterActivityKimaiMapping.delete().execute() HamsterActivityKimaiMapping.delete().execute()
@db_.command("sync")
def kimai_db_sync():
sync()
@db_.command() @db_.command()
@click.option( @click.option(
"-g", "-g",

View File

@ -30,6 +30,7 @@ from .kimai import (
Project as KimaiAPIProject, Project as KimaiAPIProject,
Activity as KimaiAPIActivity, Activity as KimaiAPIActivity,
) )
from .sync import sync
class ListScreen(Screen): class ListScreen(Screen):
@ -601,47 +602,7 @@ class KimaiProjectListScreen(ListScreen):
self.table.sort(self.sort) self.table.sort(self.sort)
def action_get(self) -> None: def action_get(self) -> None:
api = KimaiAPI() sync()
KimaiCustomer.delete().execute()
KimaiProject.delete().execute()
KimaiActivity.delete().execute()
customers = KimaiAPICustomer.list(api)
with db.atomic():
KimaiCustomer.insert_many(
[{"id": customer.id, "name": customer.name} for customer in customers]
).execute()
projects = KimaiAPIProject.list(api)
with db.atomic():
KimaiProject.insert_many(
[
{
"id": project.id,
"name": project.name,
"customer_id": project.customer.id,
"allow_global_activities": project.allow_global_activities,
}
for project in projects
]
).execute()
activities = KimaiAPIActivity.list(api)
with db.atomic():
KimaiActivity.insert_many(
[
{
"id": activity.id,
"name": activity.name,
"project_id": (
activity.project and activity.project.id or None
),
}
for activity in activities
]
).execute()
self._refresh() self._refresh()
def on_mount(self) -> None: def on_mount(self) -> None:

View File

@ -1,5 +1,4 @@
from datetime import datetime from datetime import datetime
import logging
from peewee import ( from peewee import (
SqliteDatabase, SqliteDatabase,
Model, Model,
@ -10,11 +9,6 @@ from peewee import (
BooleanField, BooleanField,
) )
from textual.logging import TextualHandler
# logger = logging.getLogger("peewee")
# logger.addHandler(TextualHandler())
# logger.setLevel(logging.DEBUG)
db = SqliteDatabase(None) db = SqliteDatabase(None)

57
hamstertools/sync.py Normal file
View File

@ -0,0 +1,57 @@
from .kimai import (
KimaiAPI,
Customer as KimaiAPICustomer,
Project as KimaiAPIProject,
Activity as KimaiAPIActivity,
)
from .db import (
db,
HamsterCategory,
HamsterActivity,
HamsterFact,
KimaiProject,
KimaiCustomer,
KimaiActivity,
HamsterActivityKimaiMapping,
)
def sync() -> None:
api = KimaiAPI()
KimaiCustomer.delete().execute()
KimaiProject.delete().execute()
KimaiActivity.delete().execute()
customers = KimaiAPICustomer.list(api)
with db.atomic():
KimaiCustomer.insert_many(
[{"id": customer.id, "name": customer.name} for customer in customers]
).execute()
projects = KimaiAPIProject.list(api)
with db.atomic():
KimaiProject.insert_many(
[
{
"id": project.id,
"name": project.name,
"customer_id": project.customer.id,
"allow_global_activities": project.allow_global_activities,
}
for project in projects
]
).execute()
activities = KimaiAPIActivity.list(api)
with db.atomic():
KimaiActivity.insert_many(
[
{
"id": activity.id,
"name": activity.name,
"project_id": (activity.project and activity.project.id or None),
}
for activity in activities
]
).execute()

View File

@ -4,16 +4,9 @@ import sys
sys.path.append(os.path.join(os.path.dirname(__file__), "..")) sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
from datetime import datetime, timedelta from datetime import datetime, timedelta
import logging
from hamstertools.kimai import KimaiAPI, Timesheet, Project, Activity from hamstertools.kimai import KimaiAPI, Timesheet, Project, Activity
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
api = KimaiAPI() api = KimaiAPI()
# print(Timesheet.list(api)) # print(Timesheet.list(api))