diff --git a/hamstertools/__init__.py b/hamstertools/__init__.py index 6b042cf..06a2264 100755 --- a/hamstertools/__init__.py +++ b/hamstertools/__init__.py @@ -22,6 +22,7 @@ from .db import ( HamsterActivityKimaiMapping, HamsterFactKimaiImport, ) +from .kimaiapi import KimaiAPI, Timesheet from .sync import sync HAMSTER_DIR = Path.home() / ".local/share/hamster" @@ -481,7 +482,7 @@ def check(username, api_key, just_errors, ignore_activities, mapping_path=None): found_activities.append(activity_str) -@kimai.command("import") +@kimai.command("csv") @click.option( "--mapping-path", help="Mapping file (default ~/.local/share/hamster/mapping.kimai.csv)", @@ -492,7 +493,7 @@ def check(username, api_key, just_errors, ignore_activities, mapping_path=None): @click.option("--after", help="Only show time entries after this date") @click.option("--show-missing", help="Just report on the missing entries", is_flag=True) @click.argument("username") -def _import( +def _csv( username, mapping_path=None, output=None, @@ -637,6 +638,99 @@ def _import( output_file.close() +@kimai.command("import") +@click.argument("search") +@click.argument("after") +@click.argument("before") +def _import(search, after, before): + api = KimaiAPI() + + SEARCH = "auto" + + facts = ( + HamsterFact.select(HamsterFact, HamsterActivity, HamsterCategory) + .join(HamsterActivity, JOIN.LEFT_OUTER) + .join(HamsterCategory, JOIN.LEFT_OUTER) + .where( + (HamsterFact.start_time > datetime.strptime(after, "%Y-%m-%d")) + & (HamsterFact.start_time < datetime.strptime(before, "%Y-%m-%d")) + & HamsterCategory.name.contains(SEARCH) + ) + ) + + has_errors = False + + # check data + for f in facts: + mappings = f.activity.mappings + if len(mappings) == 0: + print( + f"fact {f.id}: @{f.activity.category.id} {f.activity.category.name} » @{f.activity.id} {f.activity.name} has no mapping" + ) + has_errors = True + continue + if len(mappings) > 1: + print( + f"fact {f.id}: activity @{f.activity.id} {f.activity.name} has multiple mappings" + ) + has_errors = True + continue + if ( + mappings[0].kimai_activity.project is None + and not mappings[0].kimai_project.allow_global_activities + ): + click.secho( + f"fact {f.id}: project @{mappings[0].kimai_project.id} {mappings[0].kimai_project.name} does not allow global activity {mappings[0].kimai_activity}", + fg="red" + ) + has_errors = True + continue + if f.imports.count() > 0: + click.secho( + f"fact {f.id}: activity @{f.activity.id} {f.activity.name} was already imported {f.imports.count()} time(s)", + fg="yellow" + ) + continue + + if has_errors: + sys.exit(1) + + # upload data + for f in facts: + try: + mapping = f.activity.mappings[0] + except IndexError: + print( + f"no mapping, skipping {f.id} ({f.activity.category.name} » {f.activity.name})" + ) + continue + + if f.imports.count() > 0: + print( + f"already imported, skipping {f.id} ({f.activity.category.name} » {f.activity.name})" + ) + continue + + t = Timesheet( + api, + activity=mapping.kimai_activity, + project=mapping.kimai_project, + begin=f.start_time, + end=f.end_time, + description=f.description if f.description != "" else mapping.kimai_description, + # tags=f.tags if f.tags != '' else mapping.kimai_tags + ) + r = t.upload().json() + if r.get("code", 200) != 200: + print(r) + print(f"{f.id} ({f.activity.category.name} » {f.activity.name})") + from pdb import set_trace + set_trace() + + else: + HamsterFactKimaiImport.create(hamster_fact=f, kimai_id=r["id"]).save() + print(f'Created Kimai timesheet {r["id"]}') + @kimai.group("db") def db_(): pass diff --git a/scripts/upload.py b/scripts/upload.py deleted file mode 100644 index b107566..0000000 --- a/scripts/upload.py +++ /dev/null @@ -1,107 +0,0 @@ -import os -import sys - -sys.path.append(os.path.join(os.path.dirname(__file__), "..")) - -from datetime import datetime - -from peewee import JOIN - -from hamstertools.db import ( - HamsterCategory, - HamsterActivity, - HamsterFact, - HamsterFactKimaiImport, -) -from hamstertools.kimaiapi import KimaiAPI, Timesheet, Project, Activity - -api = KimaiAPI() - -DATE_FROM = "2023-10-01" -DATE_TO = "2023-11-01" -SEARCH = "auto" - -facts = ( - HamsterFact.select(HamsterFact, HamsterActivity, HamsterCategory) - .join(HamsterActivity, JOIN.LEFT_OUTER) - .join(HamsterCategory, JOIN.LEFT_OUTER) - .where( - (HamsterFact.start_time > datetime.strptime(DATE_FROM, "%Y-%m-%d")) - & (HamsterFact.start_time < datetime.strptime(DATE_TO, "%Y-%m-%d")) - & HamsterCategory.name.contains(SEARCH) - ) -) - -has_errors = False - -# check data -for f in facts: - mappings = f.activity.mappings - if len(mappings) == 0: - print( - f"fact {f.id}: @{f.activity.category.id} {f.activity.category.name} » @{f.activity.id} {f.activity.name} has no mapping" - ) - has_errors = True - continue - if len(mappings) > 1: - print( - f"fact {f.id}: activity @{f.activity.id} {f.activity.name} has multiple mappings" - ) - has_errors = True - continue - if ( - mappings[0].kimai_activity.project is None - and not mappings[0].kimai_project.allow_global_activities - ): - print( - f"fact {f.id}: project @{mappings[0].kimai_project.id} {mappings[0].kimai_project.name} does not allow global activity {mappings[0].kimai_activity}" - ) - has_errors = True - continue - if f.imports.count() > 0: - print( - f"fact {f.id}: activity @{f.activity.id} {f.activity.name} was already imported {f.imports.count()} time(s)" - ) - has_errors = True - continue - - -# if has_errors: -# sys.exit(1) - -# upload data -for f in facts: - try: - mapping = f.activity.mappings[0] - except IndexError: - print( - f"no mapping, skipping {f.id} ({f.activity.category.name} » {f.activity.name})" - ) - continue - - if f.imports.count() > 0: - print( - f"already imported, skipping {f.id} ({f.activity.category.name} » {f.activity.name})" - ) - continue - - t = Timesheet( - api, - activity=mapping.kimai_activity, - project=mapping.kimai_project, - begin=f.start_time, - end=f.end_time, - description=f.description if f.description != "" else mapping.kimai_description, - # tags=f.tags if f.tags != '' else mapping.kimai_tags - ) - r = t.upload().json() - if r.get("code", 200) != 200: - print(r) - print(f"{f.id} ({f.activity.category.name} » {f.activity.name})") - from pdb import set_trace - - set_trace() - - else: - HamsterFactKimaiImport.create(hamster_fact=f, kimai_id=r["id"]).save() - print(f'Created Kimai timesheet {r["id"]}')