#!/usr/bin/env python3.7 import sqlite3 import click from pathlib import Path HAMSTER_FILE = Path.home() / '.local/share/hamster-applet/hamster.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): 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) results = c.execute(sql, args) results = c.fetchall() return results @click.group() def cli(): pass @cli.group() def categories(): pass @categories.command('list') @click.option('--search', help='Search string') def list_categories(search): results = get_categories(search=search) for r in results: click.echo('@{0[0]}: {0[1]}'.format(r)) @categories.command() @click.argument('ids', nargs=-1) def delete(ids): click.secho('Deleting:', fg='red') results = get_categories(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)) click.confirm('Do you want to continue?', abort=True) 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') @categories.command('activities') @click.argument('ids', nargs=-1) def list_category_activities(ids): sql = ''' SELECT activities.id, activities.name, categories.name FROM activities LEFT JOIN categories ON activities.category_id = categories.id WHERE categories.id IN ({seq}) '''.format( seq=','.join(['?'] * len(ids)) ) results = c.execute(sql, ids) for r in results: click.echo('@{0[0]}: {0[2]} » {0[1]}'.format(r)) @cli.group() def activities(): pass @activities.command('list') @click.option('--search', help='Search string') def list_activities(search): results = get_activities(search=search) for r in results: click.echo('@{0[0]}: {0[2]} » {0[1]}'.format(r)) @activities.command() @click.argument('ids', nargs=-1) def delete_activities(ids): results = get_activities(ids) click.secho('Deleting:', fg='red') for r in results: click.echo('@{0[0]}: {0[2]} » {0[1]}'.format(r)) click.confirm('Do you want to continue?', abort=True) @activities.command() @click.argument('category_id') @click.argument('ids', nargs=-1) def move(category_id, ids): category = get_categories((category_id,))[0] results = get_activities(ids) click.secho('Moving to "@{0[0]}: {0[1]}":'.format(category), fg='green') for r in results: click.secho('@{0[3]}: {0[2]} » @{0[0]}: {0[1]}'.format(r), fg='blue') click.confirm('Do you want to continue?', abort=True) sql = ''' UPDATE activities SET category_id = ? ''' sql = sql + 'WHERE id IN ({seq})'.format( seq=','.join(['?'] * len(ids)) ) c.execute(sql, (category[0], *ids)) conn.commit() click.secho('Moved {0} activities'.format(len(ids)), fg='green') if __name__ == "__main__": cli()