From 2fad4b705166d8bd8cd9783c16856d07c470d3e0 Mon Sep 17 00:00:00 2001 From: zlg Date: Tue, 9 Oct 2018 23:32:23 -0700 Subject: cli: Add "notes" command The "notes" command will show the user what their notes for a particular game are. The output can be piped anywhere the user wants, such as a pager or a file. If "notes" is passed with the "--edit" or "-e" flag, vgstash will open a temporary file with the game's notes already inside and edit it using the program pointed to by the EDITOR environment variable. When the editor is closed (with a successful exit status), vgstash updates the game's notes and exits. The defaults for the testing environment ("cat" for non-interactive, "vim" for interactive) may need tweaking on other operating systems. Patches for these platforms are very welcome. --- src/vgstash/test_vgstash_cli.py | 46 +++++++++++++++++++++++++++++++++++++---- src/vgstash_cli.py | 32 ++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/vgstash/test_vgstash_cli.py b/src/vgstash/test_vgstash_cli.py index 5ba7d30..ecb23c1 100644 --- a/src/vgstash/test_vgstash_cli.py +++ b/src/vgstash/test_vgstash_cli.py @@ -6,7 +6,15 @@ import vgstash_cli from click.testing import CliRunner -verbose = True +verbose = False +interactive = False + +# Change this to suit your testing environment +if not interactive: + os.environ['EDITOR'] = "cat" +else: + if not os.getenv("EDITOR"): + os.environ['EDITOR'] = "vim" def test_init(): runner = CliRunner() @@ -146,11 +154,11 @@ def test_list_pretty_tiny(): def test_delete(): runner = CliRunner() - result = runner.invoke(vgstash_cli.cli, ['delete', 'Vectorman 2', 'Genesis']) + result = runner.invoke(vgstash_cli.cli, ['delete', 'Vectorman', 'Genesis']) if verbose: print(result.output) assert result.exit_code == 0 - assert result.output == "Removed Vectorman 2 for Genesis from your collection.\n" + assert result.output == "Removed Vectorman for Genesis from your collection.\n" def test_update(): @@ -169,7 +177,37 @@ def test_update(): 'Title | System | Own | Progress', '----------------------------------------', 'Sonic the H | Genesis | | B', - 'Vectorman | Genesis | | B', + 'Vectorman 2 | Genesis | P | P', 'Super Mario | NES | P | C', 'The Legend | NES | D | P\n' )) + +def test_notes(): + runner = CliRunner() + result = runner.invoke(vgstash_cli.cli, ['notes', 'Vectorman 2', 'Genesis']) + if verbose: + print(result.output) + assert result.exit_code == 0 + assert result.output == "\n".join(( + 'Notes for Vectorman 2 on Genesis:', + '', + 'beep', + 'boop\n' + )) + +def test_notes_edit(): + if not interactive: + return + runner = CliRunner() + result = runner.invoke(vgstash_cli.cli, ['notes', 'Vectorman 2', 'Genesis', '-e']) + if verbose: + print(result.output) + assert result.exit_code == 0 + assert result.output == "Notes for Vectorman 2 on Genesis have been updated!\n" + + # List the results to make sure they match what the editor has. + list_runner = CliRunner() + list_result = runner.invoke(vgstash_cli.cli, ['list', '-r']) + if verbose: + print(list_result.output) + assert list_result.exit_code == 0 diff --git a/src/vgstash_cli.py b/src/vgstash_cli.py index 29c1de8..6289dba 100644 --- a/src/vgstash_cli.py +++ b/src/vgstash_cli.py @@ -2,8 +2,11 @@ import vgstash import sqlite3 import click import os +import subprocess import sys +import tempfile +# Click also has this, but it doesn't support a fallback value. from shutil import get_terminal_size def get_db(): @@ -164,3 +167,32 @@ def update_game(title, system, attr, val): if db.update_game(target_game, updated_game): click.echo("Updated {} for {}. Its {} is now {}.".format(title, system, attr, val)) pass + + +@cli.command('notes') +@click.argument('title', required=True) +@click.argument('system', required=True) +@click.option('--edit', '-e', is_flag=True, default=False) +def notes(title, system, edit): + db = get_db() + target_game = db.get_game(title, system) + if edit: + with tempfile.NamedTemporaryFile() as tmpfile: + tmpfile.write(target_game.notes.encode("UTF-8")) + tmpfile.flush() + process = subprocess.run([os.getenv("EDITOR", "vim"), tmpfile.name]) + tmpfile.flush() + tmpfile.seek(0) + note_arr = [] + for line in tmpfile: + note_arr.append(line.decode("UTF-8").rstrip("\r\n")) + target_game.notes = "\n".join(note_arr) + db.update_game(target_game, target_game) + if process.returncode == 0: + click.echo("Notes for {} on {} have been updated!".format(target_game.title, target_game.system)) + else: + click.echo("Couldn't find an editor for notes. Check the EDITOR environment variable and try again.") + else: + click.echo("Notes for {} on {}:".format(target_game.title, target_game.system)) + click.echo() + click.echo(target_game.notes) -- cgit v1.2.3-54-g00ecf