Compare commits
3 Commits
19e230932f
...
be1a8a7f7a
Author | SHA1 | Date | |
---|---|---|---|
be1a8a7f7a | |||
21fc28a14e | |||
77f87e5299 |
@ -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_path = (HAMSTER_DIR / "mapping.kimai.csv",)
|
||||||
|
|
||||||
mapping_files = []
|
mapping_files = []
|
||||||
for mapping_path_item in mapping_path:
|
for mapping_path_item in mapping_path:
|
||||||
|
if not Path(mapping_path_item).exists():
|
||||||
|
raise click.UsageError(f'{mapping_path_item} does not exist')
|
||||||
|
|
||||||
mapping_file = _get_kimai_mapping_file(mapping_path_item)
|
mapping_file = _get_kimai_mapping_file(mapping_path_item)
|
||||||
next(mapping_file)
|
next(mapping_file)
|
||||||
mapping_files.append(mapping_file)
|
mapping_files.append(mapping_file)
|
||||||
|
|
||||||
mapping_reader = csv.reader(chain(*mapping_files))
|
mapping_reader = csv.reader(chain(*mapping_files))
|
||||||
else:
|
|
||||||
if mapping_path is None:
|
|
||||||
mapping_path = HAMSTER_DIR / "mapping.kimai.csv"
|
|
||||||
mapping_file = _get_kimai_mapping_file(mapping_path)
|
|
||||||
mapping_reader = csv.reader(mapping_file)
|
|
||||||
|
|
||||||
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",
|
||||||
|
@ -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:
|
||||||
|
@ -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
57
hamstertools/sync.py
Normal 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()
|
@ -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))
|
||||||
|
Reference in New Issue
Block a user