From 7288560c5678991527c7b2c2ed0d7f3979f70c67 Mon Sep 17 00:00:00 2001 From: zlg Date: Sat, 29 Sep 2018 23:27:05 -0700 Subject: cli: Add pretty printing to 'list' command Also add the "--width" option to specify the maximum width of the table. --- src/vgstash/__init__.py | 24 ++++++++++---------- src/vgstash/test_vgstash_cli.py | 50 ++++++++++++++++++++++++++++++++++++++++- src/vgstash_cli.py | 50 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 107 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/vgstash/__init__.py b/src/vgstash/__init__.py index 71b5981..798a062 100755 --- a/src/vgstash/__init__.py +++ b/src/vgstash/__init__.py @@ -33,18 +33,18 @@ DEFAULT_CONFIG = { } FILTERS = { - 'allgames': "SELECT * FROM games ORDER BY system, title", - 'backlog': "SELECT * FROM games WHERE ownership > 0 AND progress < 3 ORDER BY system, title ASC", - 'borrowing': "SELECT * FROM games WHERE ownership = 0 AND progress = 2 ORDER BY system, title ASC", - 'complete': "SELECT * FROM games WHERE progress = 4 ORDER BY system, title ASC", - 'digital': "SELECT * FROM games WHERE ownership = 2 ORDER BY system, title ASC", - 'done': "SELECT * FROM games WHERE progress > 2 ORDER BY system, title ASC", - 'incomplete': "SELECT * FROM games WHERE progress = 3 AND ownership > 0 ORDER BY system, title ASC", - 'new': "SELECT * FROM games WHERE progress = 1 ORDER BY system, title ASC", - 'owned': "SELECT * FROM games WHERE ownership > 0 ORDER BY system, title ASC", - 'physical': "SELECT * FROM games WHERE ownership = 1 ORDER BY system, title ASC", - 'playlog': "SELECT * FROM games WHERE ownership > 0 AND progress = 2 ORDER BY system, title ASC", - 'unowned': "SELECT * FROM games WHERE ownership = 0 ORDER BY system, title ASC", + 'allgames': "SELECT rowid,* FROM games ORDER BY system, title", + 'backlog': "SELECT rowid,* FROM games WHERE ownership > 0 AND progress < 3 ORDER BY system, title ASC", + 'borrowing': "SELECT rowid,* FROM games WHERE ownership = 0 AND progress = 2 ORDER BY system, title ASC", + 'complete': "SELECT rowid,* FROM games WHERE progress = 4 ORDER BY system, title ASC", + 'digital': "SELECT rowid,* FROM games WHERE ownership = 2 ORDER BY system, title ASC", + 'done': "SELECT rowid,* FROM games WHERE progress > 2 ORDER BY system, title ASC", + 'incomplete': "SELECT rowid,* FROM games WHERE progress = 3 AND ownership > 0 ORDER BY system, title ASC", + 'new': "SELECT rowid,* FROM games WHERE progress = 1 ORDER BY system, title ASC", + 'owned': "SELECT rowid,* FROM games WHERE ownership > 0 ORDER BY system, title ASC", + 'physical': "SELECT rowid,* FROM games WHERE ownership = 1 ORDER BY system, title ASC", + 'playlog': "SELECT rowid,* FROM games WHERE ownership > 0 AND progress = 2 ORDER BY system, title ASC", + 'unowned': "SELECT rowid,* FROM games WHERE ownership = 0 ORDER BY system, title ASC", } def kvmatch(arg, dict_map, fallback): diff --git a/src/vgstash/test_vgstash_cli.py b/src/vgstash/test_vgstash_cli.py index 3ad661d..d0def8b 100644 --- a/src/vgstash/test_vgstash_cli.py +++ b/src/vgstash/test_vgstash_cli.py @@ -6,7 +6,7 @@ import vgstash_cli from click.testing import CliRunner -verbose = False +verbose = True def test_init(): runner = CliRunner() @@ -81,3 +81,51 @@ def test_list_filter(): 'Super Mario Bros.|NES|1|2|', 'The Legend of Zelda|NES|2|2|\n', )) + +def test_list_pretty(): + runner = CliRunner() + result = runner.invoke(vgstash_cli.cli, ['list', '-w', '80']) + if verbose: + print(result.output) + assert result.exit_code == 0 + assert result.output == '\n'.join(( + ' ID | Title | System | Own | Status ', + '--------------------------------------------------------------------------------', + ' 3 | Sonic the Hedgehog 2 | Genesis | | C', + ' 4 | Vectorman | Genesis | | C', + ' 5 | Vectorman 2 | Genesis | P | B ', + ' 1 | Super Mario Bros. | NES | P | B ', + ' 2 | The Legend of Zelda | NES | D | B \n' + )) + +def test_list_pretty_smaller(): + runner = CliRunner() + result = runner.invoke(vgstash_cli.cli, ['list', '-w', '60']) + if verbose: + print(result.output) + assert result.exit_code == 0 + assert result.output == '\n'.join(( + ' ID | Title | System | Own | Status ', + '------------------------------------------------------------', + ' 3 | Sonic the Hedgehog 2 | Genesis | | C', + ' 4 | Vectorman | Genesis | | C', + ' 5 | Vectorman 2 | Genesis | P | B ', + ' 1 | Super Mario Bros. | NES | P | B ', + ' 2 | The Legend of Zelda | NES | D | B \n' + )) + +def test_list_pretty_tiny(): + runner = CliRunner() + result = runner.invoke(vgstash_cli.cli, ['list', '-w', '50']) + if verbose: + print(result.output) + assert result.exit_code == 0 + assert result.output == '\n'.join(( + ' ID | Title | System | Own | Status ', + '--------------------------------------------------', + ' 3 | Sonic the Hedge | Genesis | | C', + ' 4 | Vectorman | Genesis | | C', + ' 5 | Vectorman 2 | Genesis | P | B ', + ' 1 | Super Mario Bro | NES | P | B ', + ' 2 | The Legend of Z | NES | D | B \n' + )) diff --git a/src/vgstash_cli.py b/src/vgstash_cli.py index 3d1d1db..e4d1a32 100644 --- a/src/vgstash_cli.py +++ b/src/vgstash_cli.py @@ -1,8 +1,11 @@ import vgstash import sqlite3 import click +import os import sys +from shutil import get_terminal_size + def get_db(): """Fetch a vgstash DB object from the default location. @@ -25,6 +28,43 @@ def init(): else: raise sqlite3.OperationalError("Cannot create schema.") +def row_format(row, width, header): + """ + TODO + """ + # There's another way to do this, involving gathering the entire results and + # *then* formatting them. That is incredibly wasteful of resources imo, so + # it may need some testing to see if it's better. Ideally, we'd only make + # the table as wide as needed; that can't happen unless we know the longest + # title's length... + + twidth = int(width) - 35 + if header == True: + click.echo("{:^4s} | {:<{w}s} | {:<8s} | {:^3s} | {:<7s}".format( + "ID", + "Title", + "System", + "Own", + "Status", + w=twidth) + ) + click.echo("-" * int(width)) + + gidstr = "{: >4d}".format(row['rowid']) + titlestr = "{: <{w}s}".format(row['title'][:twidth], w=twidth) + systemstr = "{: ^8s}".format(row['system'][:8]) + # unowned, physical, digital, both + ownltr = [' ', 'P', ' D', 'P D'] + ownstr = "{: <3s}".format(ownltr[row['ownership']]) + statltr = { + -1: 'U', + 0: 'N', + 1: 'P', + 2: 'B', + 3: 'C' + } + statstr = "{: <7s}".format((" " * row['progress'] * 2) + statltr[row['progress']]) + print(" | ".join((gidstr, titlestr, systemstr, ownstr, statstr))) @cli.command('add') @click.argument('title', type=str) @@ -66,9 +106,11 @@ def add(title, system, ownership, progress, notes): @cli.command('list') @click.argument('filter', required=False, default="allgames") @click.option('--raw', '-r', is_flag=True, show_default=True, default=False, help="Output raw, pipe-delimited lines") -def list_games(filter, raw): +@click.option('--width', '-w', type=str, required=False, default=get_terminal_size(fallback=(80,24)).columns, help="The width of the table to output, in characters.") +def list_games(filter, raw, width): db = get_db() res = db.list_games(filter) + first_pass = True for r in res: if 'notes' in r.keys() and len(r['notes']) > 0: notes = r['notes'].replace('\n', '\\n') @@ -83,8 +125,8 @@ def list_games(filter, raw): str(r['ownership']), str(r['progress']), notes - ) )) + ) else: - pass - #pretty_print(r) + row_format(r, width, first_pass) + first_pass = False -- cgit v1.2.3-54-g00ecf