Start switching to peewee for cli commands, add `kimai c2v2db` command

This commit is contained in:
3wc 2023-10-28 23:40:27 +01:00
parent c68e373b18
commit ca7cd1aaa3
3 changed files with 78 additions and 89 deletions

View File

@ -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

View File

@ -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,

View File

@ -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'