diff --git a/hamstertools/__init__.py b/hamstertools/__init__.py index 882fa6d..60e4785 100755 --- a/hamstertools/__init__.py +++ b/hamstertools/__init__.py @@ -7,76 +7,15 @@ import sys import click import requests -import sqlite3 +from peewee import fn, JOIN + +from .db import db, HamsterCategory, HamsterActivity, HamsterFact, KimaiCustomer, KimaiProject, KimaiActivity, HamsterKimaiMapping # HAMSTER_DIR = Path.home() / '.local/share/hamster' # HAMSTER_FILE = HAMSTER_DIR / 'hamster.db' HAMSTER_FILE = 'hamster-testing.db' -conn = sqlite3.connect(HAMSTER_FILE) -c = conn.cursor() - - -def get_categories(ids=None, search=None): - sql = ''' - SELECT - id, name - FROM - categories ''' - - args = [] - - if ids is not None: - sql = sql + 'WHERE id IN ({seq})'.format( - seq=','.join(['?'] * len(ids)) - ) - args = args + list(ids) - - if search is not None: - sql = sql + " WHERE name LIKE ?" - search = '%{0}%'.format(search) - args.append(search) - - results = c.execute(sql, args) - - results = c.fetchall() - - return results - - -def get_activities(ids=None, search=None, category_search=None): - sql = ''' - SELECT - activities.id, activities.name, categories.name, categories.id - FROM - activities - LEFT JOIN - categories - ON - activities.category_id = categories.id ''' - - args = [] - - if ids is not None: - sql = sql + 'WHERE activities.id IN ({seq})'.format( - seq=','.join(['?'] * len(ids)) - ) - args = args + list(ids) - - if search is not None: - sql = sql + " WHERE activities.name LIKE ?" - search = '%{0}%'.format(search) - args.append(search) - - if category_search is not None: - sql = sql + " WHERE categories.name LIKE ?" - category_search = '%{0}%'.format(category_search) - args.append(category_search) - - results = c.execute(sql, args) - results = c.fetchall() - - return results +db.init(HAMSTER_FILE) @click.group() @@ -93,10 +32,13 @@ def categories(): @click.option('--search', help='Search string') def list_categories(search): """ List / search categories """ - results = get_categories(search=search) + categories = HamsterCategory.select() - for r in results: - click.echo('@{0[0]}: {0[1]}'.format(r)) + if search is not None: + categories = categories.where(HamsterCategory.name.contains(search)) + + for c in categories: + click.echo(f'@{c.id}: {c.name}') @categories.command('delete') @@ -105,29 +47,19 @@ def delete_categories(ids): """ Delete categories specified by IDS """ click.secho('Deleting:', fg='red') - results = get_categories(ids) + categories = HamsterCategory.select( + HamsterCategory, + fn.Count(HamsterActivity.id).alias("activities_count") + ).join(HamsterActivity, JOIN.LEFT_OUTER).group_by(HamsterActivity).where(HamsterCategory.id.in_(ids)) - for r in results: - sql = 'select count(id) from activities where category_id = ?' - count = c.execute(sql, (r[0],)).fetchone()[0] - click.echo('@{0[0]}: {0[1]} ({1} activities)'.format(r, count)) + for c in categories: + click.echo(f'@{c.id}: {c.name} ({c.activities_count} activities)') click.confirm('Do you want to continue?', abort=True) - for r in results: - sql = 'DELETE FROM activities WHERE category_id = ?' - c.execute(sql, (r[0],)) + count = HamsterCategory.delete().where(HamsterCategory.id.in_(ids)).execute() - sql = 'DELETE FROM categories ' - - sql = sql + 'WHERE id IN ({seq})'.format( - seq=','.join(['?'] * len(ids)) - ) - - c.execute(sql, ids) - conn.commit() - - click.secho('Deleted {0} categories'.format(len(ids)), fg='green') + click.secho('Deleted {0} categories'.format(count), fg='green') @categories.command('rename') @@ -701,6 +633,50 @@ def _import(username, mapping_path=None, output=None, category_search=None, afte output_file.close() +@kimai.command() +def dbinit(): + db.create_tables([KimaiCustomer, KimaiProject, KimaiActivity, + HamsterKimaiMapping]) + + +@kimai.command() +def dbreset(): + HamsterKimaiMapping.delete().execute() + + +@kimai.command() +@click.option('-g', '--global', 'global_', help='Does this file contain mappings to global activties', is_flag=True) +@click.option('--mapping-path', help='Mapping file') +def csv2db(mapping_path=None, global_=False): + mapping_file = _get_kimai_mapping_file(mapping_path, None) + next(mapping_file) + mapping_reader = csv.reader(mapping_file) + + for row in mapping_reader: + hamster_category = HamsterCategory.get(name=row[0]) + hamster_activity = HamsterActivity.get(name=row[1]) + kimai_customer = KimaiCustomer.get(name=row[2]) + kimai_project = KimaiProject.get(name=row[3], + customer_id=kimai_customer.id) + try: + kimai_activity = KimaiActivity.get( + name=row[4], + project_id=kimai_project.id + ) + except KimaiActivity.DoesNotExist: + kimai_activity = KimaiActivity.get( + name=row[4], + ) + + HamsterKimaiMapping.create( + hamster_activity=hamster_activity, + kimai_customer=kimai_customer, + kimai_project=kimai_project, + kimai_activity=kimai_activity, + kimai_description=row[6], + kimai_tags=row[5] + ) + @cli.command() def app(): from .app import HamsterToolsApp diff --git a/hamstertools/app.py b/hamstertools/app.py index 5e64149..d9153e7 100644 --- a/hamstertools/app.py +++ b/hamstertools/app.py @@ -99,8 +99,8 @@ class ActivitiesScreen(ListScreen): self.table.add_rows( [ [ - activity.category.id, - activity.category.name, + activity.category_id, + (activity.category.name if (activity.category_id != -1) else ""), activity.id, activity.name, activity.facts_count, diff --git a/hamstertools/db.py b/hamstertools/db.py index fad193b..a1e3452 100644 --- a/hamstertools/db.py +++ b/hamstertools/db.py @@ -54,8 +54,21 @@ class KimaiProject(Model): class KimaiActivity(Model): name = CharField() - project = ForeignKeyField(KimaiProject, backref='activities') + project = ForeignKeyField(KimaiProject, backref='activities', null=True) class Meta: database = db table_name = 'kimai_activities' + + +class HamsterKimaiMapping(Model): + hamster_activity = ForeignKeyField(HamsterActivity, backref='mappings') + kimai_customer = ForeignKeyField(KimaiCustomer, backref='mappings') + kimai_project = ForeignKeyField(KimaiProject, backref='mappings') + kimai_activity = ForeignKeyField(KimaiActivity, backref='mappings') + kimai_description = CharField() + kimai_tags = CharField() + + class Meta: + database = db + table_name = 'hamster_kimai_mappings'