Commit 8ca31100 authored by Bram Schoenmakers's avatar Bram Schoenmakers

Merge remote-tracking branch 'mruwek/revert-subcmds' into style-fixes

parents 0ffb6869 bbd03ee4
......@@ -21,6 +21,8 @@ from datetime import date
from glob import glob
from uuid import uuid4
from freezegun import freeze_time
from topydo.commands.AddCommand import AddCommand
from topydo.commands.ArchiveCommand import ArchiveCommand
from topydo.commands.DeleteCommand import DeleteCommand
......@@ -33,7 +35,33 @@ from topydo.lib.TodoList import TodoList
from .command_testcase import CommandTest
# We're searching for 'mock'
# 'mock' was added as 'unittest.mock' in Python 3.3, but PyPy 3 is based on Python 3.2
# pylint: disable=no-name-in-module
try:
from unittest import mock
except ImportError:
import mock
class BackupSimulator(object):
def __init__(self, p_todolist, p_archive, p_timestamp, p_label):
self.backup = ChangeSet(p_todolist, p_archive, p_label)
self.backup.timestamp = p_timestamp
def save(self, p_todolist):
self.backup.save(p_todolist)
def command_executer(p_cmd, p_args, p_todolist, p_archive=None, *params):
command = p_cmd(p_args, p_todolist, *params)
command.execute()
if p_archive:
archive_command = ArchiveCommand(p_todolist, p_archive)
archive_command.execute()
@freeze_time('2015, 11, 06')
class RevertCommandTest(CommandTest):
def setUp(self):
super().setUp()
......@@ -58,14 +86,8 @@ class RevertCommandTest(CommandTest):
self.archive = TodoList([])
def test_revert01(self):
backup = ChangeSet(p_label=['do 1'])
backup.add_todolist(self.todolist)
backup.add_archive(self.archive)
backup.timestamp = '1'
command = DoCommand(["1"], self.todolist, self.out, self.error, None)
command.execute()
archive_command = ArchiveCommand(self.todolist, self.archive)
archive_command.execute()
backup = BackupSimulator(self.todolist, self.archive, '1', ['do 1'])
command_executer(DoCommand, ["1"], self.todolist, self.archive, self.out, self.error, None)
self.archive_file.write(self.archive.print_todos())
backup.save(self.todolist)
......@@ -78,26 +100,22 @@ class RevertCommandTest(CommandTest):
result = TodoList(self.archive_file.read()).print_todos()
self.assertEqual(self.errors, "")
self.assertTrue(self.output.endswith("Successfully reverted: do 1\n"))
self.assertTrue(self.output.endswith("Reverted to state before: do 1\n"))
self.assertEqual(result, "")
self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz")
def test_revert02(self):
backup = ChangeSet(self.todolist, self.archive, ['do 1'])
backup.timestamp = '1'
command1 = DoCommand(["1"], self.todolist, self.out, self.error, None)
command1.execute()
archive_command1 = ArchiveCommand(self.todolist, self.archive)
archive_command1.execute()
backup = BackupSimulator(self.todolist, self.archive, '1', ['do 1'])
command_executer(DoCommand, ["1"], self.todolist, self.archive, self.out, self.error, None)
self.archive_file.write(self.archive.print_todos())
backup.save(self.todolist)
backup = ChangeSet(self.todolist, self.archive, ['do Bar'])
# Use add_todolist and add_archive to also cover them
backup = ChangeSet(p_label=['do Bar'])
backup.add_todolist(self.todolist)
backup.add_archive(self.archive)
backup.timestamp = '2'
command2 = DoCommand(["Bar"], self.todolist, self.out, self.error, None)
command2.execute()
archive_command2 = ArchiveCommand(self.todolist, self.archive)
archive_command2.execute()
command_executer(DoCommand, ["Bar"], self.todolist, self.archive, self.out, self.error, None)
self.archive_file.write(self.archive.print_todos())
backup.save(self.todolist)
......@@ -110,7 +128,7 @@ class RevertCommandTest(CommandTest):
result = TodoList(self.archive_file.read()).print_todos()
self.assertEqual(self.errors, "")
self.assertTrue(self.output.endswith("Successfully reverted: do Bar\n"))
self.assertTrue(self.output.endswith("Reverted to state before: do Bar\n"))
self.assertEqual(result, "x {} Foo".format(self.today))
self.assertEqual(self.todolist.print_todos(), "Bar\nBaz")
......@@ -121,51 +139,39 @@ class RevertCommandTest(CommandTest):
self.assertEqual(self.errors, "No backup was found for the current state of {}\n".format(config().todotxt()))
def test_revert04(self):
@mock.patch('topydo.lib.Config._Config.archive')
def test_revert04(self, mock_archive):
""" Test trimming of the backup_file """
backup = ChangeSet(self.todolist, self.archive, ['add One'])
backup.timestamp = '1'
command1 = AddCommand(["One"], self.todolist, self.out, self.error, None)
command1.execute()
mock_archive.return_value = '' # test for empty archive setting
backup = BackupSimulator(self.todolist, self.archive, '1', ['add One'])
command_executer(AddCommand, ["One"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = ChangeSet(self.todolist, self.archive, ['add Two'])
backup.timestamp = '2'
command2 = AddCommand(["Two"], self.todolist, self.out, self.error, None)
command2.execute()
backup = BackupSimulator(self.todolist, self.archive, '2', ['add Two'])
command_executer(AddCommand, ["Two"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = ChangeSet(self.todolist, self.archive, ['add Three'])
backup.timestamp = '3'
command3 = AddCommand(["Three"], self.todolist, self.out, self.error, None)
command3.execute()
backup = BackupSimulator(self.todolist, self.archive, '3', ['add Three'])
command_executer(AddCommand, ["Three"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = ChangeSet(self.todolist, self.archive, ['add Four'])
backup.timestamp = '4'
command4 = AddCommand(["Four"], self.todolist, self.out, self.error, None)
command4.execute()
backup = BackupSimulator(self.todolist, self.archive, '4', ['add Four'])
command_executer(AddCommand, ["Four"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = ChangeSet(self.todolist, self.archive, ['add Five'])
backup.timestamp = '5'
command5 = AddCommand(["Five"], self.todolist, self.out, self.error, None)
command5.execute()
backup = BackupSimulator(self.todolist, self.archive, '5', ['add Five'])
command_executer(AddCommand, ["Five"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
result = len(ChangeSet().backup_dict.keys())
self.assertEqual(result, 6)
backup = ChangeSet(self.todolist, self.archive, ['add Six'])
backup.timestamp = '6'
command6 = AddCommand(["Six"], self.todolist, self.out, self.error, None)
command6.execute()
backup = BackupSimulator(self.todolist, self.archive, '6', ['add Six'])
command_executer(AddCommand, ["Six"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = ChangeSet(self.todolist, self.archive, ['add Seven'])
backup.timestamp = '7'
command7 = AddCommand(["Seven"], self.todolist, self.out, self.error, None)
command7.execute()
backup = BackupSimulator(self.todolist, self.archive, '7', ['add Seven'])
command_executer(AddCommand, ["Seven"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
result = len(ChangeSet().backup_dict.keys())
......@@ -183,94 +189,76 @@ class RevertCommandTest(CommandTest):
self.assertEqual(len(changesets), 4)
self.assertEqual(result, [])
self.assertEqual(self.errors, "")
self.assertTrue(self.output.endswith("Successfully reverted: add Seven\n"))
self.assertTrue(self.output.endswith("Reverted to state before: add Seven\n"))
def test_revert05(self):
""" Test for possible backup collisions """
backup = ChangeSet(self.todolist, self.archive, ['add One'])
backup.timestamp = '1'
command1 = AddCommand(["One"], self.todolist, self.out, self.error, None)
command1.execute()
backup = BackupSimulator(self.todolist, self.archive, '1', ['add One'])
command_executer(AddCommand, ["One"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = ChangeSet(self.todolist, self.archive, ['add Two'])
backup.timestamp = '2'
command2 = AddCommand(["Two"], self.todolist, self.out, self.error, None)
command2.execute()
backup = BackupSimulator(self.todolist, self.archive, '2', ['add Two'])
command_executer(AddCommand, ["Two"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = ChangeSet(self.todolist, self.archive, ['add Three'])
backup.timestamp = '3'
command3 = AddCommand(["Three"], self.todolist, self.out, self.error, None)
command3.execute()
backup = BackupSimulator(self.todolist, self.archive, '3', ['add Three'])
command_executer(AddCommand, ["Three"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = ChangeSet(self.todolist, self.archive, ['delete Three'])
backup.timestamp = '4'
command4 = DeleteCommand(["Three"], self.todolist, self.out, self.error, None)
command4.execute()
backup = BackupSimulator(self.todolist, self.archive, '4', ['delete Three'])
command_executer(DeleteCommand, ["Three"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = ChangeSet(self.todolist, self.archive, ['add Four'])
backup.timestamp = '5'
command4 = AddCommand(["Four"], self.todolist, self.out, self.error, None)
command4.execute()
backup = BackupSimulator(self.todolist, self.archive, '5', ['add Four'])
command_executer(AddCommand, ["Four"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
revert_command = RevertCommand([], self.todolist, self.out, self.error, None)
revert_command.execute()
self.assertEqual(self.errors, "")
self.assertTrue(self.output.endswith("Successfully reverted: add Four\n"))
self.assertTrue(self.output.endswith("Reverted to state before: add Four\n"))
self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz\n{t} One\n{t} Two".format(t=self.today))
revert_command = RevertCommand([], self.todolist, self.out, self.error, None)
revert_command.execute()
self.assertEqual(self.errors, "")
self.assertTrue(self.output.endswith("Successfully reverted: delete Three\n"))
self.assertTrue(self.output.endswith("Reverted to state before: delete Three\n"))
self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz\n{t} One\n{t} Two\n{t} Three".format(t=self.today))
revert_command = RevertCommand([], self.todolist, self.out, self.error, None)
revert_command.execute()
self.assertEqual(self.errors, "")
self.assertTrue(self.output.endswith("Successfully reverted: add Three\n"))
self.assertTrue(self.output.endswith("Reverted to state before: add Three\n"))
self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz\n{t} One\n{t} Two".format(t=self.today))
revert_command = RevertCommand([], self.todolist, self.out, self.error, None)
revert_command.execute()
self.assertEqual(self.errors, "")
self.assertTrue(self.output.endswith("Successfully reverted: add Two\n"))
self.assertTrue(self.output.endswith("Reverted to state before: add Two\n"))
self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz\n{t} One".format(t=self.today))
revert_command = RevertCommand([], self.todolist, self.out, self.error, None)
revert_command.execute()
self.assertEqual(self.errors, "")
self.assertTrue(self.output.endswith("Successfully reverted: add One\n"))
self.assertTrue(self.output.endswith("Reverted to state before: add One\n"))
self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz")
def test_revert06(self):
""" Test attempt of deletion with non-existing backup key"""
backup = ChangeSet(self.todolist, self.archive, ['add One'])
backup.timestamp = '1'
command1 = AddCommand(["One"], self.todolist, self.out, self.error, None)
command1.execute()
backup = BackupSimulator(self.todolist, self.archive, '1', ['add One'])
command_executer(AddCommand, ["One"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = ChangeSet(self.todolist, self.archive, ['add Two'])
backup.timestamp = '2'
command2 = AddCommand(["Two"], self.todolist, self.out, self.error, None)
command2.execute()
backup = BackupSimulator(self.todolist, self.archive, '2', ['add Two'])
command_executer(AddCommand, ["Two"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = ChangeSet(self.todolist, self.archive, ['add Three'])
backup.timestamp = '3'
command3 = AddCommand(["Three"], self.todolist, self.out, self.error, None)
command3.execute()
backup = BackupSimulator(self.todolist, self.archive, '3', ['add Three'])
command_executer(AddCommand, ["Three"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = ChangeSet(self.todolist, self.archive, ['delete Three'])
backup.timestamp = '4'
command4 = DeleteCommand(["Three"], self.todolist, self.out, self.error, None)
command4.execute()
backup = BackupSimulator(self.todolist, self.archive, '4', ['delete Three'])
command_executer(DeleteCommand, ["Three"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = ChangeSet()
......@@ -289,8 +277,7 @@ class RevertCommandTest(CommandTest):
""" Test backup when no archive file is set """
backup = ChangeSet(self.todolist, None, ['add One'])
backup.timestamp = '1'
command1 = AddCommand(["One"], self.todolist, self.out, self.error, None)
command1.execute()
command_executer(AddCommand, ["One"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
changesets = list(backup.backup_dict.keys())
......@@ -299,6 +286,99 @@ class RevertCommandTest(CommandTest):
self.assertEqual(len(changesets), 1)
self.assertEqual(self.errors, "")
def test_revert_ls(self):
backup = BackupSimulator(self.todolist, self.archive, '1', ['add One'])
command_executer(AddCommand, ["One"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = BackupSimulator(self.todolist, self.archive, '2', ['add Two'])
command_executer(AddCommand, ["Two"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = BackupSimulator(self.todolist, self.archive, '3', ['add Three'])
command_executer(AddCommand, ["Three"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = BackupSimulator(self.todolist, self.archive, '4', ['delete Three'])
command_executer(DeleteCommand, ["Three"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = BackupSimulator(self.todolist, self.archive, '5', ['add Four'])
command_executer(AddCommand, ["Four"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
command_executer(RevertCommand, ['ls'], self.todolist, None, self.out, self.error, None)
self.assertEqual(self.errors, "")
self.assertTrue(self.output.endswith(""" 1| 1970-01-01 00:00:05 | add Four
2| 1970-01-01 00:00:04 | delete Three
3| 1970-01-01 00:00:03 | add Three
4| 1970-01-01 00:00:02 | add Two
5| 1970-01-01 00:00:01 | add One\n"""))
def test_revert_08(self):
backup = BackupSimulator(self.todolist, self.archive, '1', ['add One'])
command_executer(AddCommand, ["One"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = BackupSimulator(self.todolist, self.archive, '2', ['add Two'])
command_executer(AddCommand, ["Two"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = BackupSimulator(self.todolist, self.archive, '3', ['add Three'])
command_executer(AddCommand, ["Three"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = BackupSimulator(self.todolist, self.archive, '4', ['delete Three'])
command_executer(DeleteCommand, ["Three"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = BackupSimulator(self.todolist, self.archive, '5', ['add Four'])
command_executer(AddCommand, ["Four"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
command_executer(RevertCommand, ['3'], self.todolist, None, self.out, self.error, None)
self.assertEqual(self.errors, "")
self.assertTrue(self.output.endswith("Reverted to state before: add Three\n"))
self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz\n2015-11-06 One\n2015-11-06 Two")
def test_revert_invalid(self):
""" Test invalid input for revert. """
command_executer(RevertCommand, ["foo"], self.todolist, None, self.out, self.error, None)
command_executer(RevertCommand, ["ls", "foo"], self.todolist, None, self.out, self.error, None)
command_executer(RevertCommand, ["1", "foo"], self.todolist, None, self.out, self.error, None)
usage_text = RevertCommand([], self.todolist).usage() + '\n'
self.assertEqual(self.errors, usage_text*3)
def test_revert_out_of_range(self):
command_executer(RevertCommand, ["158"], self.todolist, None, self.out, self.error, None)
self.assertEqual(self.errors, "Specified index is out range\n")
def test_revert_no_todolist(self):
""" Test attempt of revert with todolist missing """
backup = BackupSimulator(self.todolist, self.archive, '1', ['add One'])
command_executer(AddCommand, ["One"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = BackupSimulator(self.todolist, self.archive, '2', ['add Two'])
command_executer(AddCommand, ["Two"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = BackupSimulator(self.todolist, self.archive, '3', ['add Three'])
command_executer(AddCommand, ["Three"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
backup = BackupSimulator(self.todolist, self.archive, '4', ['delete Three'])
command_executer(DeleteCommand, ["Three"], self.todolist, None, self.out, self.error, None)
backup.save(self.todolist)
command_executer(RevertCommand, ['1'], None, None, self.out, self.error, None)
result = len(ChangeSet().backup_dict.keys())
self.assertEqual(result, 4)
def test_backup_config01(self):
config(p_overrides={('topydo', 'backup_count'): '1'})
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 - 2015 Bram Schoenmakers <bram@topydo.org>
# Copyright (C) 2014 - 2017 Bram Schoenmakers <bram@topydo.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -14,44 +14,119 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import arrow
from topydo.lib import TodoFile, TodoList
from topydo.lib.ChangeSet import ChangeSet
from topydo.lib.Command import Command
from topydo.lib.Command import Command, InvalidCommandArgument
from topydo.lib.Config import config
class RevertCommand(Command):
def __init__(self, p_args, p_todolist, #pragma: no branch
def __init__(self, p_args, p_todolist, # pragma: no branch
p_out=lambda a: None,
p_err=lambda a: None,
p_prompt=lambda a: None):
super().__init__(p_args, p_todolist, p_out, p_err,
p_prompt)
super().__init__(p_args, p_todolist, p_out, p_err, p_prompt)
self._backup = None
self._archive_file = None
self._archive = None
def execute(self):
if not super().execute():
return False
archive_file = TodoFile.TodoFile(config().archive())
archive = TodoList.TodoList(archive_file.read())
self._backup = ChangeSet()
archive_path = config().archive()
if archive_path:
self._archive_file = TodoFile.TodoFile(config().archive())
self._archive = TodoList.TodoList(self._archive_file.read())
if len(self.args) > 1:
self.error(self.usage())
else:
try:
arg = self.argument(0)
self._handle_args(arg)
except InvalidCommandArgument:
try:
self._revert_last()
except (ValueError, KeyError):
self.error('No backup was found for the current state of '
+ config().todotxt())
self._backup.close()
def _revert(self, p_timestamp=None):
self._backup.read_backup(self.todolist, p_timestamp)
self._backup.apply(self.todolist, self._archive)
if self._archive:
self._archive_file.write(self._archive.print_todos())
last_change = ChangeSet()
self.out("Reverted to state before: " + self._backup.label)
def _revert_last(self):
self._revert()
self._backup.delete()
def _revert_to_specific(self, p_position):
timestamps = [timestamp for timestamp, _ in self._backup]
position = int(p_position) - 1 # numbering in UI starts with 1
try:
last_change.get_backup(self.todolist)
last_change.apply(self.todolist, archive)
archive_file.write(archive.print_todos())
last_change.delete()
timestamp = timestamps[position]
self._revert(timestamp)
for timestamp in timestamps[:position + 1]:
self._backup.read_backup(p_timestamp=timestamp)
self._backup.delete()
except IndexError:
self.error('Specified index is out range')
self.out("Successfully reverted: " + last_change.label)
except (ValueError, KeyError):
self.error('No backup was found for the current state of ' + config().todotxt())
def _handle_args(self, p_arg):
try:
if p_arg == 'ls':
self._handle_ls()
elif p_arg.isdigit():
self._revert_to_specific(p_arg)
else:
raise InvalidCommandArgument
except InvalidCommandArgument:
self.error(self.usage())
last_change.close()
def _handle_ls(self):
num = 1
for timestamp, change in self._backup:
label = change[2]
time = arrow.get(timestamp).format('YYYY-MM-DD HH:mm:ss')
self.out('{0: >3}| {1} | {2}'.format(str(num), time, label))
num += 1
def usage(self):
return """Synopsis: revert"""
return """Synopsis:
revert [ls]
revert [NUMBER]"""
def help(self):
return """Reverts the last command."""
return """\
Reverts last commands.
* ls : Lists all backups ordered and numbered chronologically (starting
with 1 for latest backup).
* [NUMBER] : revert to specific point in history specified by NUMBER.
Output example for `revert ls`:
1 | 1970-01-01 00:00:02 | add Baz
2 | 1970-01-01 00:00:01 | add Bar
3 | 1970-01-01 00:00:00 | add Foo
In such example executing `revert 2` will revert todo and archive files to the
state before execution of `add Bar`.
* `revert` without any further arguments will revert to the latest backup
available, provided that this backup matches current state of the todo file.
Topydo will refuse to revert, if any changes to todo file were made by
external application after the latest backup. To force a `revert` action use
it with a NUMBER.\
"""
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 - 2015 Bram Schoenmakers <bram@topydo.org>
# Copyright (C) 2014 - 2017 Bram Schoenmakers <bram@topydo.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -46,7 +46,7 @@ class ChangeSet(object):
def __init__(self, p_todolist=None, p_archive=None, p_label=None):
self.todolist = deepcopy(p_todolist)
self.archive = deepcopy(p_archive)
self.timestamp = str(int(time.time()))
self.timestamp = str(time.time())
self.label = ' '.join(p_label if p_label else [])
try:
......@@ -56,6 +56,11 @@ class ChangeSet(object):
self._read()
def __iter__(self):
items = {key: self.backup_dict[key]
for key in self.backup_dict if key != 'index'}.items()
return iter(sorted(items, reverse=True))
def _read(self):
"""
Reads backup file from json_file property and sets backup_dict property
......@@ -158,15 +163,18 @@ class ChangeSet(object):
for changeset in index[backup_limit:]:
self.delete(changeset[0], p_write=False)
def get_backup(self, p_todolist):
def read_backup(self, p_todolist=None, p_timestamp=None):
"""
Retrieves a backup for p_todolist from backup file and sets todolist,
archive and label attributes to appropriate data from it.
Retrieves a backup for p_timestamp or p_todolist (if p_timestamp is not
specified) from backup file and sets timestamp, todolist, archive and
label attributes to appropriate data from it.
"""
change_hash = hash_todolist(p_todolist)
index = self._get_index()
self.timestamp = index[[change[1] for change in index].index(change_hash)][0]
if not p_timestamp:
change_hash = hash_todolist(p_todolist)
index = self._get_index()
self.timestamp = index[[change[1] for change in index].index(change_hash)][0]
else:
self.timestamp = p_timestamp
d = self.backup_dict[self.timestamp]
......@@ -176,10 +184,10 @@ class ChangeSet(object):
def apply(self, p_todolist, p_archive):
""" Applies backup on supplied p_todolist. """
if self.todolist:
if self.todolist and p_todolist:
p_todolist.replace(self.todolist.todos())
if self.archive:
if self.archive and p_archive:
p_archive.replace(self.archive.todos())
def close(self):
......
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