Skip to content

Commit

Permalink
Put labelfile handling for commands in decorators
Browse files Browse the repository at this point in the history
Instead of defining the label file opening, and possibly saving, logic
in each single command, put them in decorators so they can easily be
added to each command.

This lets us define a centralized point where loading and saving of
label files occur.

Also move the ‘dry-run’ flag to the write_labels decorator since that
is currently the only place that uses it. This again takes
responsibility away from each individual command.

I’ve opted to have the decorators add parameters to the ‘run’ method
since that seems fairly clear, and doesn’t start adding instance
variables out of nowhere.

Remove the option to create a label file when generating passphrases.
  • Loading branch information
ryuslash committed Dec 24, 2016
1 parent 4c88268 commit 54c37d7
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 123 deletions.
18 changes: 3 additions & 15 deletions dispass/commands/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
from dispass import algos
from dispass.dispass import settings
from dispass.cli import CLI
from dispass.filehandler import Filehandler
from dispass.interactive_editor import InteractiveEditor
from dispass.commands.decorators import write_labels


@write_labels
class Command(CommandBase):
'''Add a new label to the labelfile and generate passphrase.'''
usagestr = (
Expand All @@ -40,11 +41,10 @@ class Command(CommandBase):
('generate', ('g', False,
'immediately generate passphrase after adding it')),
('help', ('h', False, 'show this help information')),
('dry-run', ('n', False, 'do not actually add label to labelfile')),
('silent', ('s', False, 'do not print success message')),
)

def run(self):
def run(self, lf):
'''Parse labels and add them using `FileHandler.add`.
When the -i flag is passed, add them using `InteractiveEditor.add`
Expand All @@ -53,15 +53,6 @@ def run(self):
newlabels = []
'''A list of labelnames that have been added.'''

if self.parentFlags['file']:
lf = Filehandler(settings, file_location=self.parentFlags['file'])
else:
lf = Filehandler(settings)

if not lf.file_found:
if not lf.promptForCreation(silent=self.flags['silent']):
return 1

if self.flags['interactive']:
intedit = InteractiveEditor(settings, lf, interactive=False)
newlabels.append(intedit.add())
Expand Down Expand Up @@ -107,9 +98,6 @@ def run(self):
print("Label '{name}' already exists in labelfile"
.format(name=labelspec[0]))

if not self.flags['dry-run']:
lf.save()

if self.flags['generate'] and newlabels:
console = CLI(lf)
console.verifyPassword = True
Expand Down
4 changes: 4 additions & 0 deletions dispass/commands/decorators/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .read_labels import read_labels
from .write_labels import write_labels

__all__ = [read_labels, write_labels]
51 changes: 51 additions & 0 deletions dispass/commands/decorators/read_labels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'''Decorator for commands that read labels'''

# Copyright (c) 2012-2016 Tom Willemse <tom@ryuslash.org>
# Copyright (c) 2011-2016 Benjamin Althues <benjamin@althu.es>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

from dispass.dispass import settings
from dispass.filehandler import Filehandler


def _run_with_labelfile(func, optional):
def run(inst, *args, **kwargs):
if inst.parentFlags['file']:
lf = Filehandler(settings, file_location=inst.parentFlags['file'])
else:
lf = Filehandler(settings)

if not lf.file_found and not optional:
print('error: could not load labelfile at "{loc}"'
.format(loc=lf.file_location))
return 1

func(inst, lf, *args, **kwargs)

return run


def read_labels(optional=False):
'''Decorate the `run` method of CLS.
An instance of dispass.labelfile.Filehandler is added to the front
of the argument list of the `run` method, after self. This file is
ready for reading.
'''
def func(cls):
cls.run = _run_with_labelfile(cls.run, optional)
return cls

return func
57 changes: 57 additions & 0 deletions dispass/commands/decorators/write_labels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'''Decorator for commands that write labels'''

# Copyright (c) 2012-2016 Tom Willemse <tom@ryuslash.org>
# Copyright (c) 2011-2016 Benjamin Althues <benjamin@althu.es>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

from dispass.dispass import settings
from dispass.filehandler import Filehandler


def _run_with_labelfile(func):
def run(inst, *args, **kwargs):
if inst.parentFlags['file']:
lf = Filehandler(settings, file_location=inst.parentFlags['file'])
else:
lf = Filehandler(settings)

if not lf.file_found:
if not lf.promptForCreation(silent=inst.flags['silent']):
return 1

func(inst, lf, *args, **kwargs)

if not inst.flags['dry-run']:
lf.save()

return run


def write_labels(cls):
'''Decorate the `run` method of CLS.
An instance of dispass.labelfile.Filehandler is added to the front
of the argument list of the `run` method, after self. This file is
ready for writing. After the `run` method is finished, the label
file is automatically saved. A `dry-run` flag is also added to the
command indicating that the labelfile should not actually be
saved.
'''
cls.run = _run_with_labelfile(cls.run)
cls.optionList += (
('dry-run', ('n', False, 'do not actually add label to labelfile')),
)

return cls
19 changes: 3 additions & 16 deletions dispass/commands/disable.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

from pycommand import CommandBase

from dispass.dispass import settings
from dispass.filehandler import Filehandler
from dispass.commands.decorators import write_labels


@write_labels
class Command(CommandBase):
'''Disable a label without throwing it away'''

Expand All @@ -34,26 +34,16 @@ class Command(CommandBase):

optionList = (
('help', ('h', False, 'show this help information')),
('dry-run', ('n', False, 'do not actually update label in labelfile')),
('silent', ('s', False, 'do not print success message')),
)

def run(self):
def run(self, lf):
'''Parse the arguments and disable using `Filehandler.disable`.'''

if self.parentFlags['file']:
lf = Filehandler(settings, file_location=self.parentFlags['file'])
else:
lf = Filehandler(settings)

if not len(self.args) == 1 or self.flags['help']:
print self.usage
return

if not lf.file_found:
# File not found? No possible label to disable.
return 1

labelname = self.args[0]

if lf.disable(labelname):
Expand All @@ -63,6 +53,3 @@ def run(self):
if not self.flags['silent']:
print("Label '{name}' could not be disabled"
.format(name=labelname))

if not self.flags['dry-run']:
lf.save()
19 changes: 3 additions & 16 deletions dispass/commands/enable.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

from pycommand import CommandBase

from dispass.dispass import settings
from dispass.filehandler import Filehandler
from dispass.commands.decorators import write_labels


@write_labels
class Command(CommandBase):
'''Enable a label'''

Expand All @@ -34,26 +34,16 @@ class Command(CommandBase):

optionList = (
('help', ('h', False, 'show this help information')),
('dry-run', ('n', False, 'do not actually update label in labelfile')),
('silent', ('s', False, 'do not print success message')),
)

def run(self):
def run(self, lf):
'''Parse the arguments and enable using `Filehandler.disable`.'''

if self.parentFlags['file']:
lf = Filehandler(settings, file_location=self.parentFlags['file'])
else:
lf = Filehandler(settings)

if not len(self.args) == 1 or self.flags['help']:
print self.usage
return

if not lf.file_found:
# File not found? No possible label to enable.
return 1

labelname = self.args[0]

if lf.disable(labelname, False):
Expand All @@ -63,6 +53,3 @@ def run(self):
if not self.flags['silent']:
print("Label '{name}' could not be enabled"
.format(name=labelname))

if not self.flags['dry-run']:
lf.save()
14 changes: 3 additions & 11 deletions dispass/commands/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
from dispass.algos import algorithms
from dispass.cli import CLI
from dispass.dispass import settings
from dispass.filehandler import Filehandler
from dispass.commands.decorators import read_labels


@read_labels(optional=True)
class Command(CommandBase):
'''Generate passphrases for one or more labels'''

Expand All @@ -44,7 +45,7 @@ class Command(CommandBase):
('silent', ('', False, 'do not show a prompt when errors occur')),
)

def run(self):
def run(self, lf):
'''Parse the various arguments and output passphrases for each label
Each positional argument is a label. For each label, it will try to
Expand All @@ -53,15 +54,6 @@ def run(self):
settings object defined as `dispass.dispass.settings` will be used. The
parameters can be overridden through the various optargs.
'''
if self.parentFlags['file']:
lf = Filehandler(settings, file_location=self.parentFlags['file'])
else:
lf = Filehandler(settings)

if not lf.file_found:
if not lf.promptForCreation(silent=self.flags['silent']):
return 1

if not self.args or self.flags['help']:
print(self.usage)
return 1
Expand Down
11 changes: 3 additions & 8 deletions dispass/commands/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,24 @@
from pycommand import CommandBase

from dispass.dispass import settings
from dispass.filehandler import Filehandler
from dispass.commands.decorators import read_labels


@read_labels(optional=True)
class Command(CommandBase):
'''Start the graphical version of DisPass'''

usagestr = 'usage: dispass gui [-h]'
description = 'Start the graphical version of DisPass.'
optionList = (('help', ('h', False, 'show this help information')),)

def run(self):
def run(self, lf):
'''Entry point and handler of command options and arguments'''

if self.flags['help']:
print(self.usage)
return

if self.parentFlags['file']:
lf = Filehandler(settings,
file_location=self.parentFlags['file'])
else:
lf = Filehandler(settings)

try:
from dispass.gui import GUI
g = GUI(settings, lf)
Expand Down
17 changes: 3 additions & 14 deletions dispass/commands/increment.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@

from dispass.dispass import settings
from dispass.filehandler import Filehandler
from dispass.commands.decorators import write_labels


@write_labels
class Command(CommandBase):
'''Increment the sequence number of a label'''

Expand All @@ -35,26 +37,16 @@ class Command(CommandBase):

optionList = (
('help', ('h', False, 'show this help information')),
('dry-run', ('n', False, 'do not actually update label in labelfile')),
('silent', ('s', False, 'do not print success message')),
)

def run(self):
def run(self, lf):
'''Parse the arguments and increment using `FileHandler.increment`.'''

if self.parentFlags['file']:
lf = Filehandler(settings, file_location=self.parentFlags['file'])
else:
lf = Filehandler(settings)

if not len(self.args) == 1 or self.flags['help']:
print(self.usage)
return

if not lf.file_found:
# File not found? No possible label to increment.
return 1

labelname = self.args[0]

if lf.increment(labelname):
Expand All @@ -64,6 +56,3 @@ def run(self):
if not self.flags['silent']:
print("Label '{name}' could not be incremented"
.format(name=labelname))

if not self.flags['dry-run']:
lf.save()

0 comments on commit 54c37d7

Please sign in to comment.