Commit a700f7f2 authored by Bram Schoenmakers's avatar Bram Schoenmakers Committed by GitHub

Merge pull request #172 from mruwek/fix-139

Add possibility to trigger actions after archiving
parents dea65c34 c2d6511a
...@@ -47,6 +47,7 @@ class DeleteCommandTest(CommandTest): ...@@ -47,6 +47,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["1"], self.todolist, self.out, self.error, command = DeleteCommand(["1"], self.todolist, self.out, self.error,
_no_prompt) _no_prompt)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertTrue(self.todolist.dirty) self.assertTrue(self.todolist.dirty)
self.assertEqual(self.todolist.todo(1).source(), "Bar") self.assertEqual(self.todolist.todo(1).source(), "Bar")
...@@ -57,6 +58,7 @@ class DeleteCommandTest(CommandTest): ...@@ -57,6 +58,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["Foo"], self.todolist, self.out, self.error, command = DeleteCommand(["Foo"], self.todolist, self.out, self.error,
_no_prompt) _no_prompt)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertTrue(self.todolist.dirty) self.assertTrue(self.todolist.dirty)
self.assertEqual(self.todolist.todo(1).source(), "Bar") self.assertEqual(self.todolist.todo(1).source(), "Bar")
...@@ -67,6 +69,7 @@ class DeleteCommandTest(CommandTest): ...@@ -67,6 +69,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["1"], self.todolist, self.out, self.error, command = DeleteCommand(["1"], self.todolist, self.out, self.error,
_yes_prompt) _yes_prompt)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertTrue(self.todolist.dirty) self.assertTrue(self.todolist.dirty)
self.assertEqual(self.todolist.count(), 2) self.assertEqual(self.todolist.count(), 2)
...@@ -78,6 +81,7 @@ class DeleteCommandTest(CommandTest): ...@@ -78,6 +81,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["-f", "1"], self.todolist, self.out, command = DeleteCommand(["-f", "1"], self.todolist, self.out,
self.error, _yes_prompt) self.error, _yes_prompt)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertTrue(self.todolist.dirty) self.assertTrue(self.todolist.dirty)
self.assertEqual(self.todolist.count(), 3) # force won't delete subtasks self.assertEqual(self.todolist.count(), 3) # force won't delete subtasks
...@@ -88,6 +92,7 @@ class DeleteCommandTest(CommandTest): ...@@ -88,6 +92,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["--force", "1"], self.todolist, self.out, command = DeleteCommand(["--force", "1"], self.todolist, self.out,
self.error, _yes_prompt) self.error, _yes_prompt)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertTrue(self.todolist.dirty) self.assertTrue(self.todolist.dirty)
self.assertEqual(self.todolist.count(), 3) # force won't delete subtasks self.assertEqual(self.todolist.count(), 3) # force won't delete subtasks
...@@ -97,6 +102,7 @@ class DeleteCommandTest(CommandTest): ...@@ -97,6 +102,7 @@ class DeleteCommandTest(CommandTest):
def test_del5(self): def test_del5(self):
command = DeleteCommand(["2"], self.todolist, self.out, self.error) command = DeleteCommand(["2"], self.todolist, self.out, self.error)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertTrue(self.todolist.dirty) self.assertTrue(self.todolist.dirty)
self.assertEqual(self.todolist.todo(1).source(), "Foo") self.assertEqual(self.todolist.todo(1).source(), "Foo")
...@@ -106,6 +112,7 @@ class DeleteCommandTest(CommandTest): ...@@ -106,6 +112,7 @@ class DeleteCommandTest(CommandTest):
def test_del7(self): def test_del7(self):
command = DeleteCommand(["99"], self.todolist, self.out, self.error) command = DeleteCommand(["99"], self.todolist, self.out, self.error)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertFalse(self.todolist.dirty) self.assertFalse(self.todolist.dirty)
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
...@@ -114,6 +121,7 @@ class DeleteCommandTest(CommandTest): ...@@ -114,6 +121,7 @@ class DeleteCommandTest(CommandTest):
def test_del8(self): def test_del8(self):
command = DeleteCommand(["A"], self.todolist, self.out, self.error) command = DeleteCommand(["A"], self.todolist, self.out, self.error)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertFalse(self.todolist.dirty) self.assertFalse(self.todolist.dirty)
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
...@@ -125,6 +133,7 @@ class DeleteCommandTest(CommandTest): ...@@ -125,6 +133,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["8to"], self.todolist, self.out, self.error) command = DeleteCommand(["8to"], self.todolist, self.out, self.error)
command.execute() command.execute()
command.execute_post_archive_actions()
result = "Foo\na @test with due:2015-06-03\na @test with +project" result = "Foo\na @test with due:2015-06-03\na @test with +project"
...@@ -136,6 +145,7 @@ class DeleteCommandTest(CommandTest): ...@@ -136,6 +145,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["1", "2"], self.todolist, self.out, command = DeleteCommand(["1", "2"], self.todolist, self.out,
self.error, _no_prompt) self.error, _no_prompt)
command.execute() command.execute()
command.execute_post_archive_actions()
result = "a @test with due:2015-06-03\na @test with +project" result = "a @test with due:2015-06-03\na @test with +project"
...@@ -147,6 +157,7 @@ class DeleteCommandTest(CommandTest): ...@@ -147,6 +157,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["1", "2"], self.todolist, self.out, command = DeleteCommand(["1", "2"], self.todolist, self.out,
self.error, _yes_prompt) self.error, _yes_prompt)
command.execute() command.execute()
command.execute_post_archive_actions()
result = "a @test with due:2015-06-03\na @test with +project" result = "a @test with due:2015-06-03\na @test with +project"
...@@ -158,6 +169,7 @@ class DeleteCommandTest(CommandTest): ...@@ -158,6 +169,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["99", "2"], self.todolist, self.out, command = DeleteCommand(["99", "2"], self.todolist, self.out,
self.error, _yes_prompt) self.error, _yes_prompt)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertFalse(self.todolist.dirty) self.assertFalse(self.todolist.dirty)
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
...@@ -168,6 +180,7 @@ class DeleteCommandTest(CommandTest): ...@@ -168,6 +180,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["99", "A"], self.todolist, self.out, command = DeleteCommand(["99", "A"], self.todolist, self.out,
self.error, _yes_prompt) self.error, _yes_prompt)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertFalse(self.todolist.dirty) self.assertFalse(self.todolist.dirty)
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
...@@ -180,6 +193,7 @@ class DeleteCommandTest(CommandTest): ...@@ -180,6 +193,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand([u"Fo\u00d3B\u0105r", "Bar"], self.todolist, command = DeleteCommand([u"Fo\u00d3B\u0105r", "Bar"], self.todolist,
self.out, self.error, None) self.out, self.error, None)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertFalse(self.todolist.dirty) self.assertFalse(self.todolist.dirty)
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
...@@ -190,6 +204,7 @@ class DeleteCommandTest(CommandTest): ...@@ -190,6 +204,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["-e", "@test"], self.todolist, self.out, command = DeleteCommand(["-e", "@test"], self.todolist, self.out,
self.error, None) self.error, None)
command.execute() command.execute()
command.execute_post_archive_actions()
result = "Removed: a @test with due:2015-06-03\nRemoved: a @test with +project\n" result = "Removed: a @test with due:2015-06-03\nRemoved: a @test with +project\n"
...@@ -202,6 +217,7 @@ class DeleteCommandTest(CommandTest): ...@@ -202,6 +217,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["-e", "@test", "due:2015-06-03"], command = DeleteCommand(["-e", "@test", "due:2015-06-03"],
self.todolist, self.out, self.error, None) self.todolist, self.out, self.error, None)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertTrue(self.todolist.dirty) self.assertTrue(self.todolist.dirty)
self.assertEqual(self.output, "Removed: a @test with due:2015-06-03\n") self.assertEqual(self.output, "Removed: a @test with due:2015-06-03\n")
...@@ -211,6 +227,7 @@ class DeleteCommandTest(CommandTest): ...@@ -211,6 +227,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["-e", "@test", "due:2015-06-03", "+project"], command = DeleteCommand(["-e", "@test", "due:2015-06-03", "+project"],
self.todolist, self.out, self.error, None) self.todolist, self.out, self.error, None)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertFalse(self.todolist.dirty) self.assertFalse(self.todolist.dirty)
...@@ -219,6 +236,7 @@ class DeleteCommandTest(CommandTest): ...@@ -219,6 +236,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["-e", ""], self.todolist, self.out, command = DeleteCommand(["-e", ""], self.todolist, self.out,
self.error, None) self.error, None)
command.execute() command.execute()
command.execute_post_archive_actions()
result = "Foo" result = "Foo"
...@@ -231,6 +249,7 @@ class DeleteCommandTest(CommandTest): ...@@ -231,6 +249,7 @@ class DeleteCommandTest(CommandTest):
command = DeleteCommand(["-xe", ""], self.todolist, self.out, command = DeleteCommand(["-xe", ""], self.todolist, self.out,
self.error, _yes_prompt) self.error, _yes_prompt)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertTrue(self.todolist.dirty) self.assertTrue(self.todolist.dirty)
self.assertEqual(self.todolist.count(), 0) self.assertEqual(self.todolist.count(), 0)
...@@ -238,6 +257,7 @@ class DeleteCommandTest(CommandTest): ...@@ -238,6 +257,7 @@ class DeleteCommandTest(CommandTest):
def test_empty(self): def test_empty(self):
command = DeleteCommand([], self.todolist, self.out, self.error) command = DeleteCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertFalse(self.todolist.dirty) self.assertFalse(self.todolist.dirty)
self.assertFalse(self.output) self.assertFalse(self.output)
...@@ -251,6 +271,7 @@ class DeleteCommandTest(CommandTest): ...@@ -251,6 +271,7 @@ class DeleteCommandTest(CommandTest):
def test_help(self): def test_help(self):
command = DeleteCommand(["help"], self.todolist, self.out, self.error) command = DeleteCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.errors, self.assertEqual(self.errors,
......
This diff is collapsed.
...@@ -26,6 +26,7 @@ class ListProjectCommandTest(CommandTest): ...@@ -26,6 +26,7 @@ class ListProjectCommandTest(CommandTest):
todolist = load_file_to_todolist("test/data/TodoListTest.txt") todolist = load_file_to_todolist("test/data/TodoListTest.txt")
command = ListProjectCommand([""], todolist, self.out, self.error) command = ListProjectCommand([""], todolist, self.out, self.error)
command.execute() command.execute()
command.execute_post_archive_actions() # test default implementation of post_archive
self.assertEqual(self.output, "Project1\nProject2\n") self.assertEqual(self.output, "Project1\nProject2\n")
self.assertFalse(self.errors) self.assertFalse(self.errors)
...@@ -34,6 +35,7 @@ class ListProjectCommandTest(CommandTest): ...@@ -34,6 +35,7 @@ class ListProjectCommandTest(CommandTest):
todolist = load_file_to_todolist("test/data/TodoListTest.txt") todolist = load_file_to_todolist("test/data/TodoListTest.txt")
command = ListProjectCommand(["aaa"], todolist, self.out, self.error) command = ListProjectCommand(["aaa"], todolist, self.out, self.error)
command.execute() command.execute()
command.execute_post_archive_actions()
self.assertEqual(self.output, "Project1\nProject2\n") self.assertEqual(self.output, "Project1\nProject2\n")
self.assertFalse(self.errors) self.assertFalse(self.errors)
......
...@@ -18,7 +18,6 @@ from datetime import date ...@@ -18,7 +18,6 @@ from datetime import date
from topydo.lib.DCommand import DCommand from topydo.lib.DCommand import DCommand
from topydo.lib.printers.PrettyPrinter import PrettyPrinter from topydo.lib.printers.PrettyPrinter import PrettyPrinter
from topydo.lib.prettyprinters.Numbers import PrettyPrinterNumbers
from topydo.lib.Recurrence import NoRecurrenceException, advance_recurring_todo from topydo.lib.Recurrence import NoRecurrenceException, advance_recurring_todo
from topydo.lib.RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
from topydo.lib.Utils import date_string_to_date from topydo.lib.Utils import date_string_to_date
...@@ -67,9 +66,6 @@ class DoCommand(DCommand): ...@@ -67,9 +66,6 @@ class DoCommand(DCommand):
self.todolist.add_todo(new_todo) self.todolist.add_todo(new_todo)
printer = PrettyPrinter()
printer.add_filter(PrettyPrinterNumbers(self.todolist))
self.out(printer.print_todo(new_todo))
except NoRecurrenceException: except NoRecurrenceException:
self.error("Warning: todo item has an invalid recurrence pattern.") self.error("Warning: todo item has an invalid recurrence pattern.")
......
...@@ -90,6 +90,10 @@ class Command(object): ...@@ -90,6 +90,10 @@ class Command(object):
"""" Returns short-name of the command. """ """" Returns short-name of the command. """
return cls.__name__[:-7].lower() # strip 'Command' return cls.__name__[:-7].lower() # strip 'Command'
def execute_post_archive_actions(self):
""" Runs various hooks that should take place after archiving. """
pass
def usage(self): def usage(self):
""" Returns a one-line synopsis for this command. """ """ Returns a one-line synopsis for this command. """
raise NotImplementedError raise NotImplementedError
......
...@@ -35,9 +35,8 @@ class DCommand(MultiCommand): ...@@ -35,9 +35,8 @@ class DCommand(MultiCommand):
p_args, p_todolist, p_out, p_err, p_prompt) p_args, p_todolist, p_out, p_err, p_prompt)
self.force = False self.force = False
self._delta = []
# to determine newly activated todos
self.length = len(self.todolist.todos())
def get_flags(self): def get_flags(self):
return ("f", ["force"]) return ("f", ["force"])
...@@ -76,11 +75,10 @@ class DCommand(MultiCommand): ...@@ -76,11 +75,10 @@ class DCommand(MultiCommand):
self.execute_specific_core(child) self.execute_specific_core(child)
self.out(self.prefix() + self.printer.print_todo(child)) self.out(self.prefix() + self.printer.print_todo(child))
def _print_unlocked_todos(self, p_old, p_new): def _print_unlocked_todos(self):
delta = [todo for todo in p_new if todo not in p_old] if self._delta:
if delta:
self.out("The following todo item(s) became active:") self.out("The following todo item(s) became active:")
self._print_list(delta) self._print_list(self._delta)
def _active_todos(self): def _active_todos(self):
""" """
...@@ -92,7 +90,7 @@ class DCommand(MultiCommand): ...@@ -92,7 +90,7 @@ class DCommand(MultiCommand):
Since these todos pop up at the end of the list, we cut off the list Since these todos pop up at the end of the list, we cut off the list
just before that point. just before that point.
""" """
return [todo for todo in self.todolist.todos()[:self.length] return [todo for todo in self.todolist.todos()
if not self._uncompleted_children(todo) and todo.is_active()] if not self._uncompleted_children(todo) and todo.is_active()]
def condition(self, _): def condition(self, _):
...@@ -125,4 +123,8 @@ class DCommand(MultiCommand): ...@@ -125,4 +123,8 @@ class DCommand(MultiCommand):
self.error(self.condition_failed_text()) self.error(self.condition_failed_text())
current_active = self._active_todos() current_active = self._active_todos()
self._print_unlocked_todos(old_active, current_active) self._delta = [todo for todo in current_active
if todo not in old_active]
def execute_post_archive_actions(self):
self._print_unlocked_todos()
...@@ -27,7 +27,7 @@ from topydo.lib.TopydoString import TopydoString ...@@ -27,7 +27,7 @@ from topydo.lib.TopydoString import TopydoString
MAIN_OPTS = "ac:C:d:ht:v" MAIN_OPTS = "ac:C:d:ht:v"
MAIN_LONG_OPTS = ('version') MAIN_LONG_OPTS = ('version')
READ_ONLY_COMMANDS = ('List', 'ListContext', 'ListProject') READ_ONLY_COMMANDS = ('list', 'listcontext', 'listproject')
GENERIC_HELP="""Available commands: GENERIC_HELP="""Available commands:
...@@ -174,6 +174,7 @@ class CLIApplicationBase(object): ...@@ -174,6 +174,7 @@ class CLIApplicationBase(object):
self.todolist = TodoList.TodoList([]) self.todolist = TodoList.TodoList([])
self.todofile = None self.todofile = None
self.do_archive = True self.do_archive = True
self._post_archive_action = None
self.backup = None self.backup = None
def _usage(self): def _usage(self):
...@@ -244,9 +245,9 @@ class CLIApplicationBase(object): ...@@ -244,9 +245,9 @@ class CLIApplicationBase(object):
def is_read_only(self, p_command): def is_read_only(self, p_command):
""" Returns True when the given command class is read-only. """ """ Returns True when the given command class is read-only. """
read_only_commands = tuple(cmd + 'Command' for cmd in ('Revert', ) + read_only_commands = tuple(cmd for cmd
READ_ONLY_COMMANDS) in ('revert', ) + READ_ONLY_COMMANDS)
return p_command.__module__.endswith(read_only_commands) return p_command.name() in read_only_commands
def _backup(self, p_command, p_args=[], p_label=None): def _backup(self, p_command, p_args=[], p_label=None):
if config().backup_count() > 0 and p_command and not self.is_read_only(p_command): if config().backup_count() > 0 and p_command and not self.is_read_only(p_command):
...@@ -271,6 +272,7 @@ class CLIApplicationBase(object): ...@@ -271,6 +272,7 @@ class CLIApplicationBase(object):
input) input)
if command.execute() != False: if command.execute() != False:
self._post_archive_action = command.execute_post_archive_actions
return True return True
return False return False
...@@ -291,6 +293,8 @@ class CLIApplicationBase(object): ...@@ -291,6 +293,8 @@ class CLIApplicationBase(object):
archive = _retrieve_archive()[0] archive = _retrieve_archive()[0]
self.backup.add_archive(archive) self.backup.add_archive(archive)
self._post_archive_action()
if config().keep_sorted(): if config().keep_sorted():
from topydo.commands.SortCommand import SortCommand from topydo.commands.SortCommand import SortCommand
self._execute(SortCommand, []) self._execute(SortCommand, [])
......
...@@ -327,6 +327,8 @@ class UIApplication(CLIApplicationBase): ...@@ -327,6 +327,8 @@ class UIApplication(CLIApplicationBase):
try: try:
if transaction.execute(): if transaction.execute():
post_archive_action = transaction.execute_post_archive_actions
self._post_archive_action = post_archive_action
self._post_execute() self._post_execute()
else: else:
self._rollback() self._rollback()
......
...@@ -27,6 +27,7 @@ class Transaction(object): ...@@ -27,6 +27,7 @@ class Transaction(object):
self._cmd = lambda op: p_subcommand(op, *p_env_args) self._cmd = lambda op: p_subcommand(op, *p_env_args)
self._todo_ids = p_todo_ids self._todo_ids = p_todo_ids
self._operations = [] self._operations = []
self._post_archive_actions = []
self._cmd_name = p_subcommand.name() self._cmd_name = p_subcommand.name()
self.label = [] self.label = []
...@@ -72,5 +73,13 @@ class Transaction(object): ...@@ -72,5 +73,13 @@ class Transaction(object):
if command.execute() is False: if command.execute() is False:
return False return False
elif i == last_operation: else:
action = command.execute_post_archive_actions
self._post_archive_actions.append(action)
if i == last_operation:
return True return True
def execute_post_archive_actions(self):
for action in self._post_archive_actions:
action()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment