aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzlg <zlg@zlg.space>2018-10-09 04:33:52 -0700
committerzlg <zlg@zlg.space>2018-10-09 04:33:52 -0700
commitac3e84c9438ef964a08f2acf40ab58fe1c04675e (patch)
tree40ff1c2bb952695cb07b0b3f5ec6bb694a2ba2b8
parentcli: Add "delete" command (diff)
downloadvgstash-ac3e84c9438ef964a08f2acf40ab58fe1c04675e.tar.gz
vgstash-ac3e84c9438ef964a08f2acf40ab58fe1c04675e.tar.bz2
vgstash-ac3e84c9438ef964a08f2acf40ab58fe1c04675e.tar.xz
vgstash-ac3e84c9438ef964a08f2acf40ab58fe1c04675e.zip
cli: add 'update' command
Two helper functions were also added to the vgstash package to ease client workflows. This commit marks the final core function necessary to manipulate a vgstash DB on the command line.
-rwxr-xr-xsrc/vgstash/__init__.py25
-rw-r--r--src/vgstash/test_vgstash_cli.py58
-rw-r--r--src/vgstash_cli.py29
3 files changed, 92 insertions, 20 deletions
diff --git a/src/vgstash/__init__.py b/src/vgstash/__init__.py
index 71b5981..ee07c78 100755
--- a/src/vgstash/__init__.py
+++ b/src/vgstash/__init__.py
@@ -79,6 +79,22 @@ def kvmatch(arg, dict_map, fallback):
return ret
+def vtok(arg, dict_map):
+ """
+ Match an integer value to a key name in the mapping dictionary. Returns a
+ string (the key name) if found, False if not found.
+ """
+ if isinstance(arg, int):
+ for k, v in dict_map.items():
+ if arg == v:
+ return k
+ elif isinstance(arg, str):
+ for k, v in dict_map.items():
+ if k.startswith(arg):
+ return k
+ return False
+
+
class DB(object):
"""
The central class of vgstash. It handles everything relating to storing the
@@ -208,6 +224,15 @@ class DB(object):
else:
return False
+ def get_game(self, title, system):
+ """
+ Fetches a game's information from the database. Returns a Game object.
+ """
+ stmt = "SELECT * FROM games WHERE title=? AND system=?"
+ res = self.conn.execute(stmt, (title, system)).fetchone()
+ if bool(res):
+ return Game(res['title'], res['system'], res['ownership'], res['progress'], res['notes'])
+
def has_game(self, game, fuzzy=False):
"""
Returns whether or not the game is in the database.
diff --git a/src/vgstash/test_vgstash_cli.py b/src/vgstash/test_vgstash_cli.py
index cbbd151..5ba7d30 100644
--- a/src/vgstash/test_vgstash_cli.py
+++ b/src/vgstash/test_vgstash_cli.py
@@ -98,13 +98,13 @@ def test_list_pretty():
print(result.output)
assert result.exit_code == 0
assert result.output == '\n'.join((
- 'Title | System | Own | Progress ',
+ 'Title | System | Own | Progress',
'--------------------------------------------------------------------------------',
- 'Sonic the Hedgehog 2 | Genesis | | B',
- 'Vectorman | Genesis | | B',
- 'Vectorman 2 | Genesis | P | P ',
- 'Super Mario Bros. | NES | P | P ',
- 'The Legend of Zelda | NES | D | P \n',
+ 'Sonic the Hedgehog 2 | Genesis | | B',
+ 'Vectorman | Genesis | | B',
+ 'Vectorman 2 | Genesis | P | P',
+ 'Super Mario Bros. | NES | P | P',
+ 'The Legend of Zelda | NES | D | P\n',
))
@@ -116,13 +116,13 @@ def test_list_pretty_smaller():
print(result.output)
assert result.exit_code == 0
assert result.output == '\n'.join((
- 'Title | System | Own | Progress ',
+ 'Title | System | Own | Progress',
'------------------------------------------------------------',
- 'Sonic the Hedgehog 2 | Genesis | | B',
- 'Vectorman | Genesis | | B',
- 'Vectorman 2 | Genesis | P | P ',
- 'Super Mario Bros. | NES | P | P ',
- 'The Legend of Zelda | NES | D | P \n'
+ 'Sonic the Hedgehog 2 | Genesis | | B',
+ 'Vectorman | Genesis | | B',
+ 'Vectorman 2 | Genesis | P | P',
+ 'Super Mario Bros. | NES | P | P',
+ 'The Legend of Zelda | NES | D | P\n'
))
@@ -134,13 +134,13 @@ def test_list_pretty_tiny():
print(result.output)
assert result.exit_code == 0
assert result.output == '\n'.join((
- 'Title | System | Own | Progress ',
+ 'Title | System | Own | Progress',
'--------------------------------------------------',
- 'Sonic the Hedgehog 2 | Genesis | | B',
- 'Vectorman | Genesis | | B',
- 'Vectorman 2 | Genesis | P | P ',
- 'Super Mario Bros. | NES | P | P ',
- 'The Legend of Zelda | NES | D | P \n'
+ 'Sonic the Hedgehog 2 | Genesis | | B',
+ 'Vectorman | Genesis | | B',
+ 'Vectorman 2 | Genesis | P | P',
+ 'Super Mario Bros. | NES | P | P',
+ 'The Legend of Zelda | NES | D | P\n'
))
@@ -151,3 +151,25 @@ def test_delete():
print(result.output)
assert result.exit_code == 0
assert result.output == "Removed Vectorman 2 for Genesis from your collection.\n"
+
+
+def test_update():
+ runner = CliRunner()
+ result = runner.invoke(vgstash_cli.cli, ['update', 'Super Mario Bros.', 'NES', 'progress', 'c'])
+ if verbose:
+ print(result.output)
+ assert result.exit_code == 0
+ assert result.output == 'Updated Super Mario Bros. for NES. Its progress is now complete.\n'
+
+ list_result = runner.invoke(vgstash_cli.cli, ['list', '-w', '40'])
+ if verbose:
+ print(list_result.output)
+ assert list_result.exit_code == 0
+ assert list_result.output == "\n".join((
+ 'Title | System | Own | Progress',
+ '----------------------------------------',
+ 'Sonic the H | Genesis | | B',
+ 'Vectorman | Genesis | | B',
+ 'Super Mario | NES | P | C',
+ 'The Legend | NES | D | P\n'
+ ))
diff --git a/src/vgstash_cli.py b/src/vgstash_cli.py
index f88187c..29c1de8 100644
--- a/src/vgstash_cli.py
+++ b/src/vgstash_cli.py
@@ -40,7 +40,7 @@ def row_format(row, width, header):
# progress (9)
twidth = int(width) - 29
if header == True:
- click.echo("{:<{w}s} | {:<8s} | {:^3s} | {:<9s}".format(
+ click.echo("{:<{w}s} | {:<8s} | {:^3s} | {}".format(
"Title",
"System",
"Own",
@@ -61,7 +61,7 @@ def row_format(row, width, header):
3: 'B',
4: 'C'
}
- progstr = "{: <7s}".format((" " * row['progress'] * 2) + progltr[row['progress']])
+ progstr = "{}".format((" " * (row['progress'] - 1) * 2) + progltr[row['progress']])
print(" | ".join((titlestr, systemstr, ownstr, progstr)))
@@ -139,3 +139,28 @@ def delete_game(title, system):
target_game = vgstash.Game(title, system)
if db.delete_game(target_game):
click.echo("Removed {} for {} from your collection.".format(title, system))
+
+
+@cli.command('update')
+@click.argument('title', required=True)
+@click.argument('system', required=True)
+@click.argument('attr', type=click.Choice(['title', 'system', 'ownership', 'progress']), required=True)
+@click.argument('val', required=True)
+def update_game(title, system, attr, val):
+ # TODO: Consider namedtuple as a solution
+ db = get_db()
+ target_game = db.get_game(title, system)
+ if attr == 'ownership':
+ val = vgstash.vtok(val, vgstash.OWNERSHIP)
+ if attr == 'progress':
+ val = vgstash.vtok(val, vgstash.PROGRESS)
+ updated_game = vgstash.Game(
+ val if attr == 'title' else target_game.title,
+ val if attr == 'system' else target_game.system,
+ val if attr == 'ownership' else target_game.ownership,
+ val if attr == 'progress' else target_game.progress,
+ target_game.notes
+ )
+ if db.update_game(target_game, updated_game):
+ click.echo("Updated {} for {}. Its {} is now {}.".format(title, system, attr, val))
+ pass