Preliminary clockify support
This commit is contained in:
@ -9,6 +9,7 @@ import sys
|
||||
import tomllib
|
||||
|
||||
import click
|
||||
from clockify_sdk import Clockify
|
||||
import requests
|
||||
from peewee import fn, JOIN
|
||||
from textual.logging import TextualHandler
|
||||
@ -28,6 +29,9 @@ from .db import (
|
||||
HamsterActivityKimaiMapping,
|
||||
HamsterFactKimaiImport,
|
||||
HamsterFactTag,
|
||||
ClockifyProject,
|
||||
HamsterClockifyMapping,
|
||||
HamsterFactClockifyImport
|
||||
)
|
||||
from .kimaiapi import KimaiAPI, Timesheet
|
||||
from .sync import sync
|
||||
@ -43,11 +47,8 @@ db.init(HAMSTER_FILE)
|
||||
@click.group(context_settings={"auto_envvar_prefix": "HAMSTERTOOL"})
|
||||
@click.option("-d", "--debug", is_flag=True)
|
||||
@click.option("--config", default=CONFIG_FILE, type=click.Path())
|
||||
@click.option("--kimai-api-url", envvar="KIMAI_API_URL")
|
||||
@click.option("--kimai-username", envvar="KIMAI_USERNAME")
|
||||
@click.option("--kimai-api-key", envvar="KIMAI_API_KEY")
|
||||
@click.pass_context
|
||||
def cli(ctx, config, debug, kimai_api_url=None, kimai_username=None, kimai_api_key=None):
|
||||
def cli(ctx, config, debug):
|
||||
file_config = {}
|
||||
if os.path.exists(config):
|
||||
with open(config, "rb") as f:
|
||||
@ -64,11 +65,8 @@ def cli(ctx, config, debug, kimai_api_url=None, kimai_username=None, kimai_api_k
|
||||
requests_log.setLevel(logging.DEBUG)
|
||||
requests_log.propagate = True
|
||||
|
||||
ctx.obj = KimaiAPI(
|
||||
kimai_username if kimai_username is not None else file_config.get("kimai_username"),
|
||||
kimai_api_key if kimai_api_key is not None else file_config.get("kimai_api_key"),
|
||||
kimai_api_url if kimai_api_url is not None else file_config.get("kimai_api_url"),
|
||||
)
|
||||
ctx.ensure_object(dict)
|
||||
ctx.obj['config'] = file_config
|
||||
|
||||
|
||||
@cli.group()
|
||||
@ -334,7 +332,17 @@ def find_duplicates():
|
||||
|
||||
|
||||
@cli.group()
|
||||
def kimai():
|
||||
@click.option("--kimai-api-url", envvar="KIMAI_API_URL")
|
||||
@click.option("--kimai-username", envvar="KIMAI_USERNAME")
|
||||
@click.option("--kimai-api-key", envvar="KIMAI_API_KEY")
|
||||
@click.pass_context
|
||||
def kimai(ctx, kimai_api_url, kimai_username, kimai_api_key):
|
||||
file_config = ctx.obj['config']
|
||||
ctx.obj['kimai'] = KimaiAPI(
|
||||
kimai_username if kimai_username is not None else file_config.get("kimai_username"),
|
||||
kimai_api_key if kimai_api_key is not None else file_config.get("kimai_api_key"),
|
||||
kimai_api_url if kimai_api_url is not None else file_config.get("kimai_api_url"),
|
||||
)
|
||||
pass
|
||||
|
||||
|
||||
@ -535,7 +543,7 @@ def _csv(
|
||||
timestamp = datetime.now().strftime("%F")
|
||||
output = f"kimai_{timestamp}.csv"
|
||||
|
||||
if type(mapping_path) == tuple:
|
||||
if isinstance(mapping_path, tuple):
|
||||
mapping_files = []
|
||||
for mapping_path_item in mapping_path:
|
||||
mapping_file = _get_kimai_mapping_file(mapping_path_item, category_search)
|
||||
@ -552,7 +560,7 @@ def _csv(
|
||||
for row in mapping_reader
|
||||
}
|
||||
|
||||
if type(mapping_path) == tuple:
|
||||
if isinstance(mapping_path, tuple):
|
||||
for mapping_file in mapping_files:
|
||||
mapping_file.close()
|
||||
else:
|
||||
@ -561,25 +569,13 @@ def _csv(
|
||||
output_file = open(output, "w")
|
||||
output_writer = csv.writer(output_file)
|
||||
|
||||
args = []
|
||||
|
||||
facts = (
|
||||
HamsterFact.select(HamsterFact, HamsterActivity, HamsterCategory)
|
||||
.join(HamsterActivity)
|
||||
.join(HamsterCategory, JOIN.LEFT_OUTER)
|
||||
)
|
||||
|
||||
sql = """
|
||||
SELECT
|
||||
facts.id, facts.start_time, facts.end_time, facts.description,
|
||||
activities.id, activities.name,
|
||||
categories.name, categories.id
|
||||
FROM
|
||||
facts
|
||||
LEFT JOIN
|
||||
activities ON facts.activity_id = activities.id
|
||||
LEFT JOIN
|
||||
categories ON activities.category_id = categories.id """
|
||||
|
||||
|
||||
if category_search is not None:
|
||||
facts = facts.where(HamsterCategory.name.contains(category_search))
|
||||
@ -665,8 +661,9 @@ def _csv(
|
||||
@click.argument("search")
|
||||
@click.argument("after")
|
||||
@click.argument("before")
|
||||
def _import(search, after, before):
|
||||
api = KimaiAPI(username=KIMAI_USERNAME, api_key=KIMAI_API_KEY)
|
||||
@click.pass_context
|
||||
def _import(ctx, search, after, before):
|
||||
api = ctx.obj
|
||||
|
||||
SEARCH = "auto"
|
||||
|
||||
@ -760,11 +757,11 @@ def _import(search, after, before):
|
||||
|
||||
|
||||
@kimai.group("db")
|
||||
def db_():
|
||||
def kimai_db():
|
||||
pass
|
||||
|
||||
|
||||
@db_.command()
|
||||
@kimai_db.command()
|
||||
def init():
|
||||
db.create_tables(
|
||||
[
|
||||
@ -778,20 +775,20 @@ def init():
|
||||
)
|
||||
|
||||
|
||||
@db_.command()
|
||||
@kimai_db.command()
|
||||
def reset():
|
||||
HamsterActivityKimaiMapping.delete().execute()
|
||||
|
||||
|
||||
@db_.command("sync")
|
||||
@click.pass_obj
|
||||
def kimai_db_sync(api):
|
||||
@kimai_db.command("sync")
|
||||
@click.pass_context
|
||||
def kimai_db_sync(ctx):
|
||||
sync(
|
||||
api
|
||||
ctx.obj['kimai']
|
||||
)
|
||||
|
||||
|
||||
@db_.command()
|
||||
@kimai_db.command()
|
||||
@click.option(
|
||||
"-g",
|
||||
"--global",
|
||||
@ -828,14 +825,63 @@ def mapping2db(mapping_path=None, global_=False):
|
||||
)
|
||||
|
||||
|
||||
@cli.group()
|
||||
@click.option("--api-key", envvar="CLOCKIFY_API_KEY", help="Clockify API key")
|
||||
@click.option("--workspace-id", envvar="CLOCKIFY_WORKSPACE_ID", help="Clockify workspace ID")
|
||||
@click.pass_context
|
||||
def clockify(ctx, api_key, workspace_id):
|
||||
file_config = ctx.obj['config']
|
||||
ctx.obj['clockify'] = Clockify(
|
||||
api_key=api_key if api_key is not None else file_config.get("clockify_api_key"),
|
||||
workspace_id=workspace_id if workspace_id is not None else file_config.get("clockify_workspace_id")
|
||||
)
|
||||
|
||||
|
||||
@clockify.group("db")
|
||||
def clockify_db():
|
||||
pass
|
||||
|
||||
|
||||
@clockify_db.command("sync")
|
||||
@click.pass_context
|
||||
def clockify_db_sync(ctx):
|
||||
from .clockify import sync_projects
|
||||
count = sync_projects(ctx.obj['clockify'], db)
|
||||
click.echo(f"Synced {count} Clockify projects")
|
||||
|
||||
|
||||
@clockify_db.command("init")
|
||||
def clockify_db_init():
|
||||
db.create_tables(
|
||||
[
|
||||
ClockifyProject,
|
||||
HamsterClockifyMapping,
|
||||
HamsterFactClockifyImport,
|
||||
]
|
||||
)
|
||||
|
||||
@clockify.command("app")
|
||||
@click.pass_context
|
||||
def clockify_app(ctx):
|
||||
from .app import HamsterToolsAppClockify
|
||||
|
||||
app = HamsterToolsAppClockify(ctx.obj['clockify'])
|
||||
app.run()
|
||||
|
||||
@kimai.command("app")
|
||||
@click.pass_context
|
||||
def kimai_app(ctx):
|
||||
from .app import HamsterToolsAppKimai
|
||||
|
||||
app = HamsterToolsAppKimai(ctx.obj['kimai'])
|
||||
app.run()
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.pass_obj
|
||||
def app(kimai_api):
|
||||
def app():
|
||||
from .app import HamsterToolsApp
|
||||
|
||||
app = HamsterToolsApp(
|
||||
kimai_api
|
||||
)
|
||||
app = HamsterToolsApp()
|
||||
app.run()
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user