Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
topydo
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
topydo
Commits
c6e098e3
Commit
c6e098e3
authored
Aug 13, 2017
by
Bram Schoenmakers
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'style-fixes'
parents
486aa7be
8ca31100
Changes
73
Show whitespace changes
Inline
Side-by-side
Showing
73 changed files
with
661 additions
and
472 deletions
+661
-472
.isort.cfg
.isort.cfg
+3
-0
.travis.yml
.travis.yml
+2
-0
setup.py
setup.py
+19
-19
test/command_testcase.py
test/command_testcase.py
+3
-1
test/test_add_command.py
test/test_add_command.py
+2
-1
test/test_append_command.py
test/test_append_command.py
+2
-1
test/test_archive_command.py
test/test_archive_command.py
+3
-2
test/test_colors.py
test/test_colors.py
+1
-1
test/test_config.py
test/test_config.py
+3
-3
test/test_delete_command.py
test/test_delete_command.py
+2
-1
test/test_dep_command.py
test/test_dep_command.py
+2
-1
test/test_depri_command.py
test/test_depri_command.py
+2
-1
test/test_do_command.py
test/test_do_command.py
+10
-11
test/test_edit_command.py
test/test_edit_command.py
+2
-1
test/test_filter.py
test/test_filter.py
+3
-3
test/test_get_sub_command.py
test/test_get_sub_command.py
+6
-4
test/test_graph.py
test/test_graph.py
+2
-1
test/test_importance.py
test/test_importance.py
+4
-2
test/test_json_printer.py
test/test_json_printer.py
+2
-1
test/test_list_command.py
test/test_list_command.py
+5
-3
test/test_list_context_command.py
test/test_list_context_command.py
+3
-2
test/test_list_format.py
test/test_list_format.py
+4
-3
test/test_list_project_command.py
test/test_list_project_command.py
+3
-2
test/test_postpone_command.py
test/test_postpone_command.py
+2
-1
test/test_priority_command.py
test/test_priority_command.py
+2
-1
test/test_progress_color.py
test/test_progress_color.py
+5
-2
test/test_recurrence.py
test/test_recurrence.py
+2
-1
test/test_relative_date.py
test/test_relative_date.py
+3
-1
test/test_revert_command.py
test/test_revert_command.py
+177
-96
test/test_sort_command.py
test/test_sort_command.py
+3
-2
test/test_sorter.py
test/test_sorter.py
+6
-4
test/test_tag_command.py
test/test_tag_command.py
+4
-2
test/test_todo.py
test/test_todo.py
+2
-1
test/test_todo_base.py
test/test_todo_base.py
+2
-1
test/test_todo_file.py
test/test_todo_file.py
+2
-2
test/test_todo_list.py
test/test_todo_list.py
+2
-1
test/test_utils.py
test/test_utils.py
+2
-1
test/test_view.py
test/test_view.py
+3
-2
topydo/Commands.py
topydo/Commands.py
+1
-1
topydo/commands/AddCommand.py
topydo/commands/AddCommand.py
+1
-1
topydo/commands/AppendCommand.py
topydo/commands/AppendCommand.py
+3
-2
topydo/commands/DoCommand.py
topydo/commands/DoCommand.py
+3
-9
topydo/commands/EditCommand.py
topydo/commands/EditCommand.py
+11
-9
topydo/commands/ListCommand.py
topydo/commands/ListCommand.py
+8
-7
topydo/commands/PostponeCommand.py
topydo/commands/PostponeCommand.py
+2
-2
topydo/commands/RevertCommand.py
topydo/commands/RevertCommand.py
+95
-20
topydo/lib/ChangeSet.py
topydo/lib/ChangeSet.py
+22
-14
topydo/lib/Config.py
topydo/lib/Config.py
+2
-2
topydo/lib/DCommand.py
topydo/lib/DCommand.py
+6
-14
topydo/lib/ExpressionCommand.py
topydo/lib/ExpressionCommand.py
+0
-2
topydo/lib/ListFormat.py
topydo/lib/ListFormat.py
+4
-3
topydo/lib/MultiCommand.py
topydo/lib/MultiCommand.py
+1
-0
topydo/lib/ProgressColor.py
topydo/lib/ProgressColor.py
+0
-1
topydo/lib/Sorter.py
topydo/lib/Sorter.py
+77
-79
topydo/lib/TodoFileWatched.py
topydo/lib/TodoFileWatched.py
+3
-1
topydo/lib/TodoList.py
topydo/lib/TodoList.py
+1
-1
topydo/lib/TopydoString.py
topydo/lib/TopydoString.py
+1
-1
topydo/lib/Utils.py
topydo/lib/Utils.py
+9
-12
topydo/lib/prettyprinters/Colors.py
topydo/lib/prettyprinters/Colors.py
+0
-1
topydo/lib/prettyprinters/Format.py
topydo/lib/prettyprinters/Format.py
+1
-1
topydo/lib/prettyprinters/Numbers.py
topydo/lib/prettyprinters/Numbers.py
+0
-1
topydo/ui/CLIApplicationBase.py
topydo/ui/CLIApplicationBase.py
+9
-12
topydo/ui/CompleterBase.py
topydo/ui/CompleterBase.py
+0
-1
topydo/ui/UILoader.py
topydo/ui/UILoader.py
+1
-1
topydo/ui/cli/CLI.py
topydo/ui/cli/CLI.py
+4
-5
topydo/ui/columns/ColumnLayout.py
topydo/ui/columns/ColumnLayout.py
+2
-2
topydo/ui/columns/CommandLineWidget.py
topydo/ui/columns/CommandLineWidget.py
+2
-2
topydo/ui/columns/Main.py
topydo/ui/columns/Main.py
+67
-65
topydo/ui/columns/TodoListWidget.py
topydo/ui/columns/TodoListWidget.py
+1
-0
topydo/ui/columns/TodoWidget.py
topydo/ui/columns/TodoWidget.py
+4
-3
topydo/ui/columns/ViewWidget.py
topydo/ui/columns/ViewWidget.py
+1
-0
topydo/ui/prompt/Prompt.py
topydo/ui/prompt/Prompt.py
+7
-8
topydo/ui/prompt/PromptCompleter.py
topydo/ui/prompt/PromptCompleter.py
+7
-7
No files found.
.isort.cfg
0 → 100644
View file @
c6e098e3
[settings]
skip=topydo/ui/CLIApplicationBase.py
known_first_party=topydo
.travis.yml
View file @
c6e098e3
...
...
@@ -22,9 +22,11 @@ install:
-
"
pip
install
.[test]"
-
"
pip
install
pylint"
-
"
pip
install
codecov"
-
"
pip
install
isort"
script
:
-
"
green
-vvr
$GREEN_OPTS"
-
"
python
-m
pylint
--errors-only
topydo
test"
-
"
isort
-c
-rc
."
# Cache Dependencies
after_script
:
-
codecov
...
...
setup.py
View file @
c6e098e3
from
setuptools
import
setup
,
find_package
s
import
codec
s
import
os
import
re
import
codecs
import
sys
here
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
__file__
))
from
setuptools
import
find_packages
,
setup
_HERE
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
__file__
))
def
read
(
*
parts
):
# intentionally *not* adding an encoding option to open
return
codecs
.
open
(
os
.
path
.
join
(
here
,
*
parts
),
'r'
).
read
()
return
codecs
.
open
(
os
.
path
.
join
(
_HERE
,
*
parts
),
'r'
).
read
()
def
find_version
(
*
file_paths
):
...
...
@@ -24,17 +24,17 @@ WATCHDOG = 'watchdog >= 0.8.3'
ICALENDAR
=
'icalendar'
setup
(
name
=
"topydo"
,
packages
=
find_packages
(
exclude
=
[
"test"
]),
version
=
find_version
(
'topydo'
,
'lib'
,
'Version.py'
),
description
=
"A powerful todo.txt application for the console"
,
author
=
"Bram Schoenmakers"
,
author_email
=
"bram@topydo.org"
,
url
=
"https://www.topydo.org"
,
install_requires
=
[
name
=
"topydo"
,
packages
=
find_packages
(
exclude
=
[
"test"
]),
version
=
find_version
(
'topydo'
,
'lib'
,
'Version.py'
),
description
=
"A powerful todo.txt application for the console"
,
author
=
"Bram Schoenmakers"
,
author_email
=
"bram@topydo.org"
,
url
=
"https://www.topydo.org"
,
install_requires
=
[
'arrow >= 0.7.0'
,
],
extras_require
=
{
extras_require
=
{
':sys_platform=="win32"'
:
[
'colorama>=0.2.5'
],
':python_version=="3.2"'
:
[
'backports.shutil_get_terminal_size>=1.0.0'
],
'columns'
:
[
'urwid >= 1.3.0'
,
WATCHDOG
],
...
...
@@ -43,10 +43,10 @@ setup(
'test'
:
[
'coverage>=4.3'
,
'freezegun'
,
'green'
,
ICALENDAR
,
'pylint>=1.7.1'
],
'test:python_version=="3.2"'
:
[
'mock'
],
},
entry_points
=
{
'console_scripts'
:
[
'topydo
=
topydo.ui.UILoader:main'
],
entry_points
=
{
'console_scripts'
:
[
'topydo
=
topydo.ui.UILoader:main'
],
},
classifiers
=
[
classifiers
=
[
"Development Status :: 5 - Production/Stable"
,
"Environment :: Console"
,
"Intended Audience :: End Users/Desktop"
,
...
...
@@ -60,7 +60,7 @@ setup(
"Programming Language :: Python :: Implementation :: PyPy"
,
"Topic :: Utilities"
,
],
long_description
=
"""
\
long_description
=
"""
\
topydo is a powerful and customizable todo.txt application for the console, inspired by the todo.txt CLI by Gina Trapani.
Highlights of the additional features it provides:
...
...
@@ -74,5 +74,5 @@ Highlights of the additional features it provides:
* Some conveniences when adding new items (e.g. adding creation date and use relative dates)
"""
,
test_suite
=
"test"
,
test_suite
=
"test"
,
)
test/command_testcase.py
View file @
c6e098e3
...
...
@@ -15,9 +15,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import
os
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib.Utils
import
escape_ansi
from
.topydo_testcase
import
TopydoTest
class
CommandTest
(
TopydoTest
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
...
...
test/test_add_command.py
View file @
c6e098e3
...
...
@@ -18,11 +18,12 @@ import unittest
from
datetime
import
date
from
io
import
StringIO
from
test.command_testcase
import
CommandTest
from
topydo.commands
import
AddCommand
,
ListCommand
from
topydo.lib
import
TodoList
from
topydo.lib.Config
import
config
from
.command_testcase
import
CommandTest
# We're searching for 'mock'
# pylint: disable=no-name-in-module
try
:
...
...
test/test_append_command.py
View file @
c6e098e3
...
...
@@ -17,10 +17,11 @@
import
unittest
from
datetime
import
date
from
test.command_testcase
import
CommandTest
from
topydo.commands.AppendCommand
import
AppendCommand
from
topydo.lib.TodoList
import
TodoList
from
.command_testcase
import
CommandTest
class
AppendCommandTest
(
CommandTest
):
def
setUp
(
self
):
...
...
test/test_archive_command.py
View file @
c6e098e3
...
...
@@ -16,11 +16,12 @@
import
unittest
from
test.command_testcase
import
CommandTest
from
test.facilities
import
load_file_to_todolist
from
topydo.commands.ArchiveCommand
import
ArchiveCommand
from
topydo.lib.TodoList
import
TodoList
from
.command_testcase
import
CommandTest
from
.facilities
import
load_file_to_todolist
class
ArchiveCommandTest
(
CommandTest
):
def
test_archive
(
self
):
...
...
test/test_colors.py
View file @
c6e098e3
...
...
@@ -18,11 +18,11 @@
import
unittest
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib.Color
import
Color
from
topydo.lib.Config
import
config
from
topydo.lib.Todo
import
Todo
from
.topydo_testcase
import
TopydoTest
NEUTRAL_COLOR
=
'
\
033
[0m'
...
...
test/test_config.py
View file @
c6e098e3
...
...
@@ -15,11 +15,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import
unittest
from
unittest
import
skip
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib.Config
import
config
from
.topydo_testcase
import
TopydoTest
class
ConfigTest
(
TopydoTest
):
def
test_config01
(
self
):
...
...
@@ -167,7 +167,7 @@ class ConfigTest(TopydoTest):
def
test_config28
(
self
):
""" test duplicates. """
keymap
,
keystates
=
config
(
"test/data/ConfigTest7.conf"
).
column_keymap
()
keymap
,
_
=
config
(
"test/data/ConfigTest7.conf"
).
column_keymap
()
self
.
assertEqual
(
keymap
[
'k'
],
'bar'
)
self
.
assertEqual
(
keymap
[
'z'
],
'foobar'
)
...
...
test/test_delete_command.py
View file @
c6e098e3
...
...
@@ -16,12 +16,13 @@
import
unittest
from
test.command_testcase
import
CommandTest
from
topydo.commands.DeleteCommand
import
DeleteCommand
from
topydo.lib.Config
import
config
from
topydo.lib.TodoList
import
TodoList
from
topydo.lib.TodoListBase
import
InvalidTodoException
from
.command_testcase
import
CommandTest
def
_yes_prompt
(
self
):
return
"y"
...
...
test/test_dep_command.py
View file @
c6e098e3
...
...
@@ -16,10 +16,11 @@
import
unittest
from
test.command_testcase
import
CommandTest
from
topydo.commands.DepCommand
import
DepCommand
from
topydo.lib.TodoList
import
TodoList
from
.command_testcase
import
CommandTest
class
DepCommandTest
(
CommandTest
):
def
setUp
(
self
):
...
...
test/test_depri_command.py
View file @
c6e098e3
...
...
@@ -16,10 +16,11 @@
import
unittest
from
test.command_testcase
import
CommandTest
from
topydo.commands.DepriCommand
import
DepriCommand
from
topydo.lib.TodoList
import
TodoList
from
.command_testcase
import
CommandTest
class
DepriCommandTest
(
CommandTest
):
def
setUp
(
self
):
...
...
test/test_do_command.py
View file @
c6e098e3
...
...
@@ -17,10 +17,11 @@
import
unittest
from
datetime
import
date
,
timedelta
from
test.command_testcase
import
CommandTest
from
topydo.commands.DoCommand
import
DoCommand
from
topydo.lib.TodoList
import
TodoList
from
.command_testcase
import
CommandTest
def
_yes_prompt
(
self
):
return
"y"
...
...
@@ -100,34 +101,32 @@ class DoCommandTest(CommandTest):
self
.
assertEqual
(
self
.
errors
,
""
)
def
test_do_subtasks_force1
(
self
):
prompt_shown
=
False
def
prompt
(
p_prompt
):
global
prompt_shown
prompt_shown
=
True
prompt
.
prompt_shown
=
True
prompt
.
prompt_shown
=
False
command
=
DoCommand
([
"-f"
,
"1"
],
self
.
todolist
,
self
.
out
,
self
.
error
,
prompt
)
command
.
execute
()
command
.
execute_post_archive_actions
()
self
.
assertFalse
(
prompt_shown
)
self
.
assertFalse
(
prompt
.
prompt
_shown
)
self
.
assertEqual
(
self
.
errors
,
""
)
self
.
assertFalse
(
self
.
todolist
.
todo
(
2
).
is_completed
())
def
test_do_subtasks_force2
(
self
):
prompt_shown
=
False
def
prompt
(
p_prompt
):
global
prompt_shown
prompt_shown
=
True
prompt
.
prompt_shown
=
True
prompt
.
prompt_shown
=
False
command
=
DoCommand
([
"--force"
,
"1"
],
self
.
todolist
,
self
.
out
,
self
.
error
,
prompt
)
command
.
execute
()
command
.
execute_post_archive_actions
()
self
.
assertFalse
(
prompt_shown
)
self
.
assertFalse
(
prompt
.
prompt
_shown
)
self
.
assertEqual
(
self
.
errors
,
""
)
self
.
assertFalse
(
self
.
todolist
.
todo
(
2
).
is_completed
())
...
...
test/test_edit_command.py
View file @
c6e098e3
...
...
@@ -17,12 +17,13 @@
import
os
import
unittest
from
test.command_testcase
import
CommandTest
from
topydo.commands.EditCommand
import
EditCommand
from
topydo.lib.Config
import
config
from
topydo.lib.Todo
import
Todo
from
topydo.lib.TodoList
import
TodoList
from
.command_testcase
import
CommandTest
# We're searching for 'mock'
# pylint: disable=no-name-in-module
try
:
...
...
test/test_filter.py
View file @
c6e098e3
...
...
@@ -19,12 +19,12 @@
import
unittest
from
datetime
import
date
,
timedelta
from
test.facilities
import
(
load_file
,
load_file_to_todolist
,
todolist_to_string
)
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib
import
Filter
from
topydo.lib.Todo
import
Todo
from
.facilities
import
load_file
,
load_file_to_todolist
,
todolist_to_string
from
.topydo_testcase
import
TopydoTest
class
FilterTest
(
TopydoTest
):
def
test_filter03
(
self
):
...
...
test/test_get_sub_command.py
View file @
c6e098e3
...
...
@@ -16,18 +16,20 @@
import
unittest
from
test.topydo_testcase
import
TopydoTest
from
topydo.Commands
import
get_subcommand
from
topydo.commands.AddCommand
import
AddCommand
from
topydo.commands.DeleteCommand
import
DeleteCommand
from
topydo.commands.ListCommand
import
ListCommand
from
topydo.commands.TagCommand
import
TagCommand
from
topydo.lib.Config
import
config
,
ConfigError
from
topydo.lib.Config
import
ConfigError
,
config
from
.topydo_testcase
import
TopydoTest
class
GetSubcommandTest
(
TopydoTest
):
def
test_normal_cmd
(
self
):
args
=
[
"add"
]
real_cmd
,
final_args
=
get_subcommand
(
args
)
real_cmd
,
_
=
get_subcommand
(
args
)
self
.
assertTrue
(
issubclass
(
real_cmd
,
AddCommand
))
def
test_cmd_help
(
self
):
...
...
@@ -116,7 +118,7 @@ class GetSubcommandTest(TopydoTest):
config
(
"test/data/aliases.conf"
)
args
=
[
"baz"
]
real_cmd
,
final_args
=
get_subcommand
(
args
)
real_cmd
,
_
=
get_subcommand
(
args
)
self
.
assertEqual
(
real_cmd
,
None
)
def
test_alias_quotation
(
self
):
...
...
test/test_graph.py
View file @
c6e098e3
...
...
@@ -16,9 +16,10 @@
import
unittest
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib.Graph
import
DirectedGraph
from
.topydo_testcase
import
TopydoTest
class
GraphTest
(
TopydoTest
):
def
setUp
(
self
):
...
...
test/test_importance.py
View file @
c6e098e3
...
...
@@ -15,14 +15,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import
unittest
from
datetime
import
date
,
timedelta
from
datetime
import
date
from
freezegun
import
freeze_time
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib.Config
import
config
from
topydo.lib.Importance
import
importance
from
topydo.lib.Todo
import
Todo
from
.topydo_testcase
import
TopydoTest
@
freeze_time
(
"2015, 11, 06"
)
class
ImportanceTest
(
TopydoTest
):
...
...
test/test_json_printer.py
View file @
c6e098e3
...
...
@@ -16,10 +16,11 @@
import
unittest
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib.printers.Json
import
JsonPrinter
from
topydo.lib.Todo
import
Todo
from
.topydo_testcase
import
TopydoTest
class
JsonPrinterTest
(
TopydoTest
):
"""
...
...
test/test_list_command.py
View file @
c6e098e3
...
...
@@ -15,19 +15,21 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import
codecs
import
re
import
os
import
re
import
sys
import
unittest
from
collections
import
namedtuple
from
freezegun
import
freeze_time
from
test.command_testcase
import
CommandTest
from
test.facilities
import
load_file_to_todolist
from
topydo.commands.ListCommand
import
ListCommand
from
topydo.lib.Config
import
config
from
topydo.lib.TodoList
import
TodoList
from
.command_testcase
import
CommandTest
from
.facilities
import
load_file_to_todolist
# 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
...
...
test/test_list_context_command.py
View file @
c6e098e3
...
...
@@ -16,10 +16,11 @@
import
unittest
from
test.command_testcase
import
CommandTest
from
test.facilities
import
load_file_to_todolist
from
topydo.commands.ListContextCommand
import
ListContextCommand
from
.command_testcase
import
CommandTest
from
.facilities
import
load_file_to_todolist
class
ListContextCommandTest
(
CommandTest
):
def
test_contexts1
(
self
):
...
...
test/test_list_format.py
View file @
c6e098e3
...
...
@@ -15,16 +15,17 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import
unittest
from
collections
import
namedtuple
from
freezegun
import
freeze_time
from
test.command_testcase
import
CommandTest
from
test.facilities
import
load_file_to_todolist
from
topydo.commands.ListCommand
import
ListCommand
from
topydo.lib.Config
import
config
from
topydo.lib.TodoListBase
import
TodoListBase
from
.command_testcase
import
CommandTest
from
.facilities
import
load_file_to_todolist
# 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
...
...
test/test_list_project_command.py
View file @
c6e098e3
...
...
@@ -16,10 +16,11 @@
import
unittest
from
test.command_testcase
import
CommandTest
from
test.facilities
import
load_file_to_todolist
from
topydo.commands.ListProjectCommand
import
ListProjectCommand
from
.command_testcase
import
CommandTest
from
.facilities
import
load_file_to_todolist
class
ListProjectCommandTest
(
CommandTest
):
def
test_projects1
(
self
):
...
...
test/test_postpone_command.py
View file @
c6e098e3
...
...
@@ -17,10 +17,11 @@
import
unittest
from
datetime
import
date
,
timedelta
from
test.command_testcase
import
CommandTest
from
topydo.commands.PostponeCommand
import
PostponeCommand
from
topydo.lib.TodoList
import
TodoList
from
.command_testcase
import
CommandTest
class
PostponeCommandTest
(
CommandTest
):
def
setUp
(
self
):
...
...
test/test_priority_command.py
View file @
c6e098e3
...
...
@@ -16,10 +16,11 @@
import
unittest
from
test.command_testcase
import
CommandTest
from
topydo.commands.PriorityCommand
import
PriorityCommand
from
topydo.lib.TodoList
import
TodoList
from
.command_testcase
import
CommandTest
class
PriorityCommandTest
(
CommandTest
):
def
setUp
(
self
):
...
...
test/test_progress_color.py
View file @
c6e098e3
...
...
@@ -14,15 +14,18 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from
freezegun
import
freeze_time
import
unittest
from
test.topydo_testcase
import
TopydoTest
from
freezegun
import
freeze_time
from
topydo.lib.Config
import
config
from
topydo.lib.ProgressColor
import
progress_color
from
topydo.lib.Todo
import
Todo
from
topydo.lib.TodoList
import
TodoList
from
.topydo_testcase
import
TopydoTest
def
set_256_colors
():
config
(
p_overrides
=
{(
'topydo'
,
'colors'
):
'256'
})
...
...
test/test_recurrence.py
View file @
c6e098e3
...
...
@@ -17,11 +17,12 @@
import
unittest
from
datetime
import
date
,
timedelta
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib.Config
import
config
from
topydo.lib.Recurrence
import
NoRecurrenceException
,
advance_recurring_todo
from
topydo.lib.Todo
import
Todo
from
.topydo_testcase
import
TopydoTest
class
RecurrenceTest
(
TopydoTest
):
def
setUp
(
self
):
...
...
test/test_relative_date.py
View file @
c6e098e3
...
...
@@ -16,11 +16,13 @@
import
unittest
from
datetime
import
date
from
freezegun
import
freeze_time
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib.RelativeDate
import
relative_date_to_date
from
.topydo_testcase
import
TopydoTest
@
freeze_time
(
'2015, 11, 06'
)
class
RelativeDateTester
(
TopydoTest
):
...
...
test/test_revert_command.py
View file @
c6e098e3
...
...
@@ -17,12 +17,12 @@
import
os
import
tempfile
import
unittest
from
datetime
import
date
from
glob
import
glob
from
uuid
import
uuid4
from
test.command_testcase
import
CommandTest
from
freezegun
import
freeze_time
from
topydo.commands.AddCommand
import
AddCommand
from
topydo.commands.ArchiveCommand
import
ArchiveCommand
from
topydo.commands.DeleteCommand
import
DeleteCommand
...
...
@@ -33,6 +33,35 @@ from topydo.lib.Config import config
from
topydo.lib.TodoFile
import
TodoFile
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
()
...
...
@@ -57,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
)
...
...
@@ -77,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
\
n
Bar
\
n
Baz"
)
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
)
...
...
@@ -109,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
\
n
Baz"
)
...
...
@@ -120,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
())
...
...
@@ -182,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
\
n
Bar
\
n
Baz
\
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
\
n
Bar
\
n
Baz
\
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
\
n
Bar
\
n
Baz
\
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
\
n
Bar
\
n
Baz
\
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
\
n
Bar
\
n
Baz"
)
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
()
...
...
@@ -288,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
())
...
...
@@ -298,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
\
n
Bar
\
n
Baz
\
n
2015-11-06 One
\
n
2015-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'
})
...
...
test/test_sort_command.py
View file @
c6e098e3
...
...
@@ -16,11 +16,12 @@
import
unittest
from
test.command_testcase
import
CommandTest
from
test.facilities
import
load_file_to_todolist
from
topydo.commands.SortCommand
import
SortCommand
from
topydo.lib.Config
import
config
from
.command_testcase
import
CommandTest
from
.facilities
import
load_file_to_todolist
class
SortCommandTest
(
CommandTest
):
def
setUp
(
self
):
...
...
test/test_sorter.py
View file @
c6e098e3
...
...
@@ -14,15 +14,17 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from
freezegun
import
freeze_time
import
unittest
from
test.facilities
import
(
load_file
,
load_file_to_todolist
,
print_view
,
todolist_to_string
)
from
test.topydo_testcase
import
TopydoTest
from
freezegun
import
freeze_time
from
topydo.lib.Config
import
config
from
topydo.lib.Sorter
import
Sorter
from
.facilities
import
(
load_file
,
load_file_to_todolist
,
print_view
,
todolist_to_string
)
from
.topydo_testcase
import
TopydoTest
@
freeze_time
(
"2016, 04, 25"
)
class
SorterTest
(
TopydoTest
):
...
...
test/test_tag_command.py
View file @
c6e098e3
...
...
@@ -14,13 +14,15 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from
freezegun
import
freeze_time
import
unittest
from
test.command_testcase
import
CommandTest
from
freezegun
import
freeze_time
from
topydo.commands.TagCommand
import
TagCommand
from
topydo.lib.TodoList
import
TodoList
from
.command_testcase
import
CommandTest
class
TagCommandTest
(
CommandTest
):
def
setUp
(
self
):
...
...
test/test_todo.py
View file @
c6e098e3
...
...
@@ -17,9 +17,10 @@
import
unittest
from
datetime
import
date
,
timedelta
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib.Todo
import
Todo
from
.topydo_testcase
import
TopydoTest
def
today_date
():
today
=
date
.
today
()
...
...
test/test_todo_base.py
View file @
c6e098e3
...
...
@@ -20,9 +20,10 @@ import re
import
unittest
from
datetime
import
date
,
timedelta
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib.TodoBase
import
TodoBase
from
.topydo_testcase
import
TopydoTest
class
TodoBaseTester
(
TopydoTest
):
def
test_parse_tag
(
self
):
...
...
test/test_todo_file.py
View file @
c6e098e3
...
...
@@ -16,8 +16,8 @@
import
unittest
from
test
.facilities
import
load_file
from
test
.topydo_testcase
import
TopydoTest
from
.facilities
import
load_file
from
.topydo_testcase
import
TopydoTest
class
TodoFileTest
(
TopydoTest
):
...
...
test/test_todo_list.py
View file @
c6e098e3
...
...
@@ -19,13 +19,14 @@
import
re
import
unittest
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib.Config
import
config
from
topydo.lib.Todo
import
Todo
from
topydo.lib.TodoFile
import
TodoFile
from
topydo.lib.TodoList
import
TodoList
from
topydo.lib.TodoListBase
import
InvalidTodoException
,
TodoListBase
from
.topydo_testcase
import
TopydoTest
class
TodoListTester
(
TopydoTest
):
def
setUp
(
self
):
...
...
test/test_utils.py
View file @
c6e098e3
...
...
@@ -16,9 +16,10 @@
import
unittest
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib.Utils
import
translate_key_to_config
from
.topydo_testcase
import
TopydoTest
class
UtilsTest
(
TopydoTest
):
def
test_key_to_cfg
(
self
):
...
...
test/test_view.py
View file @
c6e098e3
...
...
@@ -16,13 +16,14 @@
import
unittest
from
test.facilities
import
load_file
,
print_view
,
todolist_to_string
from
test.topydo_testcase
import
TopydoTest
from
topydo.lib
import
Filter
from
topydo.lib.Sorter
import
Sorter
from
topydo.lib.TodoFile
import
TodoFile
from
topydo.lib.TodoList
import
TodoList
from
.facilities
import
load_file
,
print_view
,
todolist_to_string
from
.topydo_testcase
import
TopydoTest
class
ViewTest
(
TopydoTest
):
def
test_view
(
self
):
...
...
topydo/Commands.py
View file @
c6e098e3
...
...
@@ -21,7 +21,7 @@ instance based on an argument list.
import
sys
from
topydo.lib.Config
import
config
,
ConfigError
from
topydo.lib.Config
import
ConfigError
,
config
SUBCOMMAND_MAP
=
{
'add'
:
'AddCommand'
,
...
...
topydo/commands/AddCommand.py
View file @
c6e098e3
...
...
@@ -22,9 +22,9 @@ from datetime import date
from
os.path
import
expanduser
from
sys
import
stdin
from
topydo.lib.WriteCommand
import
WriteCommand
from
topydo.lib.Config
import
config
from
topydo.lib.prettyprinters.Numbers
import
PrettyPrinterNumbers
from
topydo.lib.WriteCommand
import
WriteCommand
class
AddCommand
(
WriteCommand
):
...
...
topydo/commands/AppendCommand.py
View file @
c6e098e3
...
...
@@ -14,12 +14,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from
topydo.lib.Config
import
config
from
topydo.lib.Command
import
InvalidCommandArgument
from
topydo.lib.
WriteCommand
import
WriteCommand
from
topydo.lib.
Config
import
config
from
topydo.lib.prettyprinters.Numbers
import
PrettyPrinterNumbers
from
topydo.lib.TodoListBase
import
InvalidTodoException
from
topydo.lib.TodoParser
import
parse_line
from
topydo.lib.WriteCommand
import
WriteCommand
class
AppendCommand
(
WriteCommand
):
def
__init__
(
self
,
p_args
,
p_todolist
,
#pragma: no branch
...
...
topydo/commands/DoCommand.py
View file @
c6e098e3
...
...
@@ -35,6 +35,9 @@ class DoCommand(DCommand):
super
().
__init__
(
p_args
,
p_todolist
,
p_out
,
p_err
,
p_prompt
)
self
.
condition
=
lambda
todo
:
not
todo
.
is_completed
()
self
.
condition_failed_text
=
"Todo has already been completed."
def
get_flags
(
self
):
""" Additional flags. """
opts
,
long_opts
=
super
().
get_flags
()
...
...
@@ -75,15 +78,6 @@ class DoCommand(DCommand):
def
prefix
(
self
):
return
"Completed: "
def
condition
(
self
,
p_todo
):
"""
An additional condition whether execute_specific should be executed.
"""
return
not
p_todo
.
is_completed
()
def
condition_failed_text
(
self
):
return
"Todo has already been completed."
def
execute_specific
(
self
,
p_todo
):
""" Actions specific to this command. """
self
.
_handle_recurrence
(
p_todo
)
...
...
topydo/commands/EditCommand.py
View file @
c6e098e3
...
...
@@ -14,10 +14,10 @@
# 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
os
import
codecs
import
tempfile
import
os
import
shlex
import
tempfile
from
subprocess
import
CalledProcessError
,
check_call
from
topydo.lib.Config
import
config
...
...
@@ -25,6 +25,7 @@ from topydo.lib.MultiCommand import MultiCommand
from
topydo.lib.prettyprinters.Numbers
import
PrettyPrinterNumbers
from
topydo.lib.Todo
import
Todo
def
_get_file_mtime
(
p_file
):
return
os
.
stat
(
p_file
.
name
).
st_mtime
...
...
@@ -44,11 +45,11 @@ class EditCommand(MultiCommand):
def
get_flags
(
self
):
return
(
"dE:"
,
[])
def
process_flag
(
self
,
p_opt
,
p_value
):
if
p_opt
==
'-d'
:
def
process_flag
(
self
,
p_opt
ion
,
p_value
):
if
p_opt
ion
==
'-d'
:
self
.
edit_archive
=
True
self
.
multi_mode
=
False
elif
p_opt
==
'-E'
:
elif
p_opt
ion
==
'-E'
:
self
.
editor
=
shlex
.
split
(
p_value
)
def
_process_flags
(
self
):
...
...
@@ -71,9 +72,10 @@ class EditCommand(MultiCommand):
return
f
def
_todos_from_temp
(
self
,
p_temp_file
):
f
=
codecs
.
open
(
p_temp_file
.
name
,
encoding
=
'utf-8'
)
todos
=
f
.
read
().
splitlines
()
@
staticmethod
def
_todos_from_temp
(
p_temp_file
):
with
codecs
.
open
(
p_temp_file
.
name
,
encoding
=
'utf-8'
)
as
temp
:
todos
=
temp
.
read
().
splitlines
()
todo_objs
=
[]
for
todo
in
todos
:
...
...
@@ -112,7 +114,7 @@ class EditCommand(MultiCommand):
orig_mtime
=
_get_file_mtime
(
temp_todos
)
if
not
self
.
_open_in_editor
(
temp_todos
.
name
):
new_todos
=
self
.
_todos_from_temp
(
temp_todos
)
new_todos
=
EditCommand
.
_todos_from_temp
(
temp_todos
)
if
_is_edited
(
orig_mtime
,
temp_todos
):
for
todo
in
self
.
todos
:
...
...
topydo/commands/ListCommand.py
View file @
c6e098e3
...
...
@@ -14,18 +14,18 @@
# 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
os
import
re
import
sys
import
os
from
topydo.lib.Config
import
config
from
topydo.lib.ExpressionCommand
import
ExpressionCommand
from
topydo.lib.Filter
import
HiddenTagFilter
,
InstanceFilter
from
topydo.lib.ListFormat
import
ListFormatError
from
topydo.lib.printers.PrettyPrinter
import
pretty_printer_factory
from
topydo.lib.prettyprinters.Format
import
PrettyPrinterFormatFilter
from
topydo.lib.
TodoListBase
import
InvalidTodoException
from
topydo.lib.
printers.PrettyPrinter
import
pretty_printer_factory
from
topydo.lib.Sorter
import
Sorter
from
topydo.lib.TodoListBase
import
InvalidTodoException
from
topydo.lib.Utils
import
get_terminal_size
from
topydo.lib.View
import
View
...
...
@@ -90,7 +90,7 @@ class ListCommand(ExpressionCommand):
elif
opt
==
'-N'
:
# 2 lines are assumed to be taken up by printing the next prompt
# display at least one item
self
.
limit
=
self
.
_N_lines
()
self
.
limit
=
ListCommand
.
_N_lines
()
elif
opt
==
'-n'
:
try
:
self
.
limit
=
int
(
value
)
...
...
@@ -164,7 +164,8 @@ class ListCommand(ExpressionCommand):
return
View
(
sorter
,
filters
,
self
.
todolist
)
def
_N_lines
(
self
):
@
staticmethod
def
_N_lines
():
''' Determine how many lines to print, such that the number of items
displayed will fit on the terminal (i.e one 'screen-ful' of items)
...
...
@@ -182,7 +183,7 @@ class ListCommand(ExpressionCommand):
if
"win32"
in
sys
.
platform
:
lines_in_prompt
+=
1
# Windows will typically print a free line after
# the program output
a
=
re
.
findall
(
'
\
$_
'
, os.getenv('
PROMPT
', ''))
a
=
re
.
findall
(
r
'\
$_
', os.getenv('
PROMPT
', ''))
lines_in_prompt += len(a)
else:
a = re.findall('
\\
n
', os.getenv('
PS1
', ''))
...
...
topydo/commands/PostponeCommand.py
View file @
c6e098e3
...
...
@@ -37,8 +37,8 @@ class PostponeCommand(MultiCommand):
def
get_flags
(
self
):
return
(
"s"
,
[])
def
process_flag
(
self
,
p_opt
,
p_value
):
if
p_opt
==
'-s'
:
def
process_flag
(
self
,
p_opt
ion
,
p_value
):
if
p_opt
ion
==
'-s'
:
self
.
move_start_date
=
True
def
_execute_multi_specific
(
self
):
...
...
topydo/commands/RevertCommand.py
View file @
c6e098e3
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 - 201
5
Bram Schoenmakers <bram@topydo.org>
# Copyright (C) 2014 - 201
7
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/>.
from
topydo.lib.Command
import
Command
import
arrow
from
topydo.lib
import
TodoFile
,
TodoList
from
topydo.lib.ChangeSet
import
ChangeSet
from
topydo.lib
import
TodoFile
from
topydo.lib
import
TodoList
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
)
last_change
=
ChangeSet
()
if
self
.
_archive
:
self
.
_archive_file
.
write
(
self
.
_archive
.
print_todos
())
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/lib/ChangeSet.py
View file @
c6e098e3
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 - 201
5
Bram Schoenmakers <bram@topydo.org>
# Copyright (C) 2014 - 201
7
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
...
...
@@ -19,7 +19,6 @@
import
json
import
time
import
zlib
from
copy
import
deepcopy
from
hashlib
import
sha1
from
os
import
path
...
...
@@ -27,6 +26,7 @@ from os import path
from
topydo.lib.Config
import
config
from
topydo.lib.TodoList
import
TodoList
def
hash_todolist
(
p_todolist
):
""" Calculates hash for TodoList.TodoList object. """
todolist_hash
=
sha1
(
p_todolist
.
print_todos
().
encode
(
'utf-8'
)).
hexdigest
()
...
...
@@ -43,11 +43,11 @@ def get_backup_path():
class
ChangeSet
(
object
):
""" Class for operations related with backup management. """
def
__init__
(
self
,
p_todolist
=
None
,
p_archive
=
None
,
p_label
=
[]
):
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
.
label
=
' '
.
join
(
p_label
)
self
.
timestamp
=
str
(
time
.
time
(
))
self
.
label
=
' '
.
join
(
p_label
if
p_label
else
[]
)
try
:
self
.
json_file
=
open
(
get_backup_path
(),
'r+b'
)
...
...
@@ -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.
"""
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
):
...
...
topydo/lib/Config.py
View file @
c6e098e3
...
...
@@ -15,17 +15,17 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import
configparser
from
functools
import
lru_cache
import
os
import
re
import
shlex
from
collections
import
OrderedDict
from
functools
import
lru_cache
from
itertools
import
accumulate
from
string
import
ascii_lowercase
from
topydo.lib.Color
import
Color
def
home_config_path
(
p_filename
):
return
os
.
path
.
join
(
os
.
path
.
expanduser
(
'~'
),
p_filename
)
...
...
topydo/lib/DCommand.py
View file @
c6e098e3
...
...
@@ -17,8 +17,8 @@
import
re
from
topydo.lib.MultiCommand
import
MultiCommand
from
topydo.lib.printers.PrettyPrinter
import
PrettyPrinter
from
topydo.lib.prettyprinters.Numbers
import
PrettyPrinterNumbers
from
topydo.lib.printers.PrettyPrinter
import
PrettyPrinter
class
DCommand
(
MultiCommand
):
...
...
@@ -36,13 +36,14 @@ class DCommand(MultiCommand):
self
.
force
=
False
self
.
_delta
=
[]
self
.
condition
=
lambda
_
:
True
self
.
condition_failed_text
=
""
def
get_flags
(
self
):
return
(
"f"
,
[
"force"
])
def
process_flag
(
self
,
p_opt
,
p_value
):
if
p_opt
==
"-f"
or
p_opt
==
"--force"
:
def
process_flag
(
self
,
p_opt
ion
,
p_value
):
if
p_opt
ion
==
"-f"
or
p_option
==
"--force"
:
self
.
force
=
True
def
_uncompleted_children
(
self
,
p_todo
):
...
...
@@ -93,15 +94,6 @@ class DCommand(MultiCommand):
return
[
todo
for
todo
in
self
.
todolist
.
todos
()
if
not
self
.
_uncompleted_children
(
todo
)
and
todo
.
is_active
()]
def
condition
(
self
,
_
):
"""
An additional condition whether execute_specific should be executed.
"""
return
True
def
condition_failed_text
(
self
):
raise
NotImplementedError
def
execute_specific
(
self
,
_
):
raise
NotImplementedError
...
...
@@ -120,7 +112,7 @@ class DCommand(MultiCommand):
self
.
_process_subtasks
(
todo
)
self
.
execute_specific
(
todo
)
else
:
self
.
error
(
self
.
condition_failed_text
()
)
self
.
error
(
self
.
condition_failed_text
)
current_active
=
self
.
_active_todos
()
self
.
_delta
=
[
todo
for
todo
in
current_active
...
...
topydo/lib/ExpressionCommand.py
View file @
c6e098e3
...
...
@@ -14,8 +14,6 @@
# 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
re
from
topydo.lib
import
Filter
from
topydo.lib.Command
import
Command
from
topydo.lib.Config
import
config
...
...
topydo/lib/ListFormat.py
View file @
c6e098e3
...
...
@@ -16,12 +16,13 @@
""" Utilities for formatting output with "list_format" option."""
import
arrow
import
re
import
arrow
from
topydo.lib.Config
import
config
from
topydo.lib.ProgressColor
import
progress_color
from
topydo.lib.Utils
import
get_terminal_size
,
escape_ansi
,
humanize_date
from
topydo.lib.Utils
import
escape_ansi
,
get_terminal_size
,
humanize_date
MAIN_PATTERN
=
(
r'^({{(?P<before>.+?)}})?'
r'(?P<placeholder>{ph}|\
[{ph}
\])'
...
...
@@ -205,7 +206,7 @@ class ListFormatParser(object):
'T'
:
lambda
t
:
humanize_date
(
t
.
start_date
())
if
t
.
start_date
()
else
''
,
# unique text ID
'u'
:
lambda
t
:
self
.
todolist
.
uid
(
t
)
,
'u'
:
self
.
todolist
.
uid
if
self
.
todolist
else
lambda
_
:
''
,
# unique text ID, padded with spaces
'U'
:
lambda
t
:
_filler
(
self
.
todolist
.
uid
(
t
),
...
...
topydo/lib/MultiCommand.py
View file @
c6e098e3
...
...
@@ -35,6 +35,7 @@ class MultiCommand(ExpressionCommand):
self
.
is_expression
=
False
self
.
multi_mode
=
True
# pylint: disable=no-self-use
def
get_flags
(
self
):
""" Default implementation of getting specific flags. """
return
(
""
,
[])
...
...
topydo/lib/ProgressColor.py
View file @
c6e098e3
...
...
@@ -20,7 +20,6 @@ from topydo.lib.Color import Color
from
topydo.lib.Config
import
config
from
topydo.lib.Recurrence
import
relative_date_to_date
# when a todo item has not enough information to determine the length, assume
# this length
ASSUMED_TODO_LENGTH
=
14
# days
...
...
topydo/lib/Sorter.py
View file @
c6e098e3
...
...
@@ -16,16 +16,15 @@
""" This module provides functionality to sort lists with todo items. """
from
collections
import
OrderedDict
,
namedtuple
from
itertools
import
groupby
import
re
from
collections
import
OrderedDict
,
namedtuple
from
datetime
import
date
from
itertools
import
groupby
from
topydo.lib.Config
import
config
from
topydo.lib.Importance
import
average_importance
,
importance
from
topydo.lib.Utils
import
date_string_to_date
,
humanize_date
Field
=
namedtuple
(
'Field'
,
[
'sort'
,
'group'
,
'label'
])
FIELDS
=
{
...
...
@@ -148,57 +147,7 @@ class Sorter(object):
"""
def
__init__
(
self
,
p_sortstring
=
"desc:priority"
,
p_groupstring
=
""
):
self
.
groupfunctions
=
self
.
_parse
(
p_groupstring
,
p_group
=
True
)
if
p_groupstring
else
[]
self
.
pregroupfunctions
=
self
.
_parse
(
p_groupstring
,
p_group
=
False
)
if
p_groupstring
else
[]
self
.
sortfunctions
=
self
.
_parse
(
p_sortstring
,
p_group
=
False
)
def
sort
(
self
,
p_todos
):
"""
Sorts the list of todos given as a parameter, returns a new sorted
list.
The list is traversed in reverse order, such that the most specific
sort operation is done first, relying on the stability of the sorted()
function.
"""
return
_apply_sort_functions
(
p_todos
,
self
.
sortfunctions
)
def
group
(
self
,
p_todos
):
"""
Groups the todos according to the given group string.
"""
# preorder todos for the group sort
p_todos
=
_apply_sort_functions
(
p_todos
,
self
.
pregroupfunctions
)
# initialize result with a single group
result
=
OrderedDict
([((),
p_todos
)])
for
(
function
,
label
),
_
in
self
.
groupfunctions
:
oldresult
=
result
result
=
OrderedDict
()
for
oldkey
,
oldgroup
in
oldresult
.
items
():
for
key
,
_group
in
groupby
(
oldgroup
,
function
):
newgroup
=
list
(
_group
)
if
not
isinstance
(
key
,
list
):
key
=
[
key
]
for
subkey
in
key
:
subkey
=
"{}: {}"
.
format
(
label
,
subkey
)
newkey
=
oldkey
+
(
subkey
,)
if
newkey
in
result
:
result
[
newkey
]
=
result
[
newkey
]
+
newgroup
else
:
result
[
newkey
]
=
newgroup
# sort all groups
for
key
,
_group
in
result
.
items
():
result
[
key
]
=
self
.
sort
(
_group
)
return
result
def
_parse
(
self
,
p_string
,
p_group
):
def
parse
(
p_string
,
p_group
):
"""
Parses a sort/group string and returns a list of functions and the
desired order.
...
...
@@ -270,3 +219,52 @@ class Sorter(object):
return result
self.groupfunctions = parse(p_groupstring, p_group=True) if p_groupstring else []
self.pregroupfunctions = parse(p_groupstring, p_group=False) if p_groupstring else []
self.sortfunctions = parse(p_sortstring, p_group=False)
def sort(self, p_todos):
"""
Sorts the list of todos given as a parameter, returns a new sorted
list.
The list is traversed in reverse order, such that the most specific
sort operation is done first, relying on the stability of the sorted()
function.
"""
return _apply_sort_functions(p_todos, self.sortfunctions)
def group(self, p_todos):
"""
Groups the todos according to the given group string.
"""
# preorder todos for the group sort
p_todos = _apply_sort_functions(p_todos, self.pregroupfunctions)
# initialize result with a single group
result = OrderedDict([((), p_todos)])
for (function, label), _ in self.groupfunctions:
oldresult = result
result = OrderedDict()
for oldkey, oldgroup in oldresult.items():
for key, _group in groupby(oldgroup, function):
newgroup = list(_group)
if not isinstance(key, list):
key = [key]
for subkey in key:
subkey = "{}: {}".format(label, subkey)
newkey = oldkey + (subkey,)
if newkey in result:
result[newkey] = result[newkey] + newgroup
else:
result[newkey] = newgroup
# sort all groups
for key, _group in result.items():
result[key] = self.sort(_group)
return result
topydo/lib/TodoFileWatched.py
View file @
c6e098e3
...
...
@@ -20,8 +20,10 @@ changes.
"""
import
os.path
from
watchdog.events
import
(
FileCreatedEvent
,
FileModifiedEvent
,
FileSystemEventHandler
)
from
watchdog.observers
import
Observer
from
watchdog.events
import
FileSystemEventHandler
,
FileModifiedEvent
,
FileCreatedEvent
from
topydo.lib.TodoFile
import
TodoFile
...
...
topydo/lib/TodoList.py
View file @
c6e098e3
...
...
@@ -116,7 +116,7 @@ class TodoList(TodoListBase):
super
().
add_todos
(
p_todos
)
for
todo
in
self
.
_todos
:
todo
.
parents
=
types
.
MethodType
(
lambda
i
:
self
.
parents
(
i
)
,
todo
)
todo
.
parents
=
types
.
MethodType
(
self
.
parents
,
todo
)
# only do administration when the dependency info is initialized,
# otherwise we postpone it until it's really needed (through the
...
...
topydo/lib/TopydoString.py
View file @
c6e098e3
...
...
@@ -18,6 +18,7 @@
import
collections
class
TopydoString
(
collections
.
UserString
):
"""
Represents a string that also contains color information. A combination of
...
...
@@ -50,4 +51,3 @@ class TopydoString(collections.UserString):
def
set_color
(
self
,
p_pos
,
p_color
):
""" Start using a color at the given position. """
self
.
colors
[
p_pos
]
=
p_color
topydo/lib/Utils.py
View file @
c6e098e3
...
...
@@ -18,12 +18,12 @@
Various utility functions.
"""
import
arrow
import
re
from
collections
import
namedtuple
from
datetime
import
date
import
arrow
def
date_string_to_date
(
p_date
):
"""
...
...
@@ -81,16 +81,14 @@ def get_terminal_size(p_getter=None):
except
ImportError
:
from
backports.shutil_get_terminal_size
import
get_terminal_size
as
_get_terminal_size
# pylint: disable=import-error
s
z
=
_get_terminal_size
()
s
ize
=
_get_terminal_size
()
except
ValueError
:
"""
This can result from the 'underlying buffer being detached', which
occurs during running the unittest on Windows (but not on Linux?)
"""
# This can result from the 'underlying buffer being detached', which
# occurs during running the unittest on Windows (but not on Linux?)
terminal_size
=
namedtuple
(
'Terminal_Size'
,
'columns lines'
)
s
z
=
terminal_size
(
80
,
24
)
s
ize
=
terminal_size
(
80
,
24
)
return
s
z
return
s
ize
get_terminal_size
.
getter
=
inner
...
...
@@ -114,6 +112,5 @@ def translate_key_to_config(p_key):
def
humanize_date
(
p_datetime
):
""" Returns a relative date string from a datetime object. """
now
=
arrow
.
now
()
date
=
now
.
replace
(
day
=
p_datetime
.
day
,
month
=
p_datetime
.
month
,
year
=
p_datetime
.
year
)
return
date
.
humanize
(
now
).
replace
(
'just now'
,
'today'
)
_date
=
now
.
replace
(
day
=
p_datetime
.
day
,
month
=
p_datetime
.
month
,
year
=
p_datetime
.
year
)
return
_date
.
humanize
(
now
).
replace
(
'just now'
,
'today'
)
topydo/lib/prettyprinters/Colors.py
View file @
c6e098e3
...
...
@@ -56,4 +56,3 @@ class PrettyPrinterColorFilter(PrettyPrinterFilter):
p_todo_str.append('', AbstractColor.NEUTRAL)
return p_todo_str
topydo/lib/prettyprinters/Format.py
View file @
c6e098e3
...
...
@@ -19,8 +19,8 @@ Provides a pretty printer filter that generates a todo string based on a format
string.
"""
from
topydo.lib.PrettyPrinterFilter
import
PrettyPrinterFilter
from
topydo.lib.ListFormat
import
ListFormatParser
from
topydo.lib.PrettyPrinterFilter
import
PrettyPrinterFilter
class
PrettyPrinterFormatFilter
(
PrettyPrinterFilter
):
...
...
topydo/lib/prettyprinters/Numbers.py
View file @
c6e098e3
...
...
@@ -29,4 +29,3 @@ class PrettyPrinterNumbers(PrettyPrinterFilter):
def
filter
(
self
,
p_todo_str
,
p_todo
):
""" Prepends the number to the todo string. """
return
"|{:>3}| {}"
.
format
(
self
.
todolist
.
number
(
p_todo
),
p_todo_str
)
topydo/ui/CLIApplicationBase.py
View file @
c6e098e3
...
...
@@ -177,7 +177,8 @@ class CLIApplicationBase(object):
self
.
_post_archive_action
=
None
self
.
backup
=
None
def
_usage
(
self
):
@
staticmethod
def
_usage
():
usage
()
sys
.
exit
(
0
)
...
...
@@ -208,7 +209,7 @@ class CLIApplicationBase(object):
elif
opt
in
(
"-v"
,
"--version"
):
version
()
else
:
self
.
_usage
()
CLIApplicationBase
.
_usage
()
if
alt_config_path
:
config
(
alt_config_path
,
overrides
)
...
...
@@ -237,21 +238,17 @@ class CLIApplicationBase(object):
if
archive
.
dirty
:
archive_file
.
write
(
archive
.
print_todos
())
def
_help
(
self
,
args
):
if
args
is
None
:
pass
# TODO
else
:
pass
# TODO
def
is_read_only
(
self
,
p_command
):
@
staticmethod
def
is_read_only
(
p_command
):
""" Returns True when the given command class is read-only. """
read_only_commands
=
tuple
(
cmd
for
cmd
in
(
'revert'
,
)
+
READ_ONLY_COMMANDS
)
return
p_command
.
name
()
in
read_only_commands
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
):
call
=
[
p_command
.
name
()]
+
p_args
def
_backup
(
self
,
p_command
,
p_args
=
None
,
p_label
=
None
):
if
config
().
backup_count
()
>
0
and
p_command
and
not
CLIApplicationBase
.
is_read_only
(
p_command
):
p_args
=
p_args
if
p_args
else
[]
call
=
[
p_command
.
name
()]
+
p_args
from
topydo.lib.ChangeSet
import
ChangeSet
label
=
p_label
if
p_label
else
call
...
...
topydo/ui/CompleterBase.py
View file @
c6e098e3
...
...
@@ -15,7 +15,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import
datetime
from
functools
import
lru_cache
from
topydo.Commands
import
SUBCOMMAND_MAP
...
...
topydo/ui/UILoader.py
View file @
c6e098e3
...
...
@@ -20,7 +20,7 @@ import getopt
import
sys
from
topydo.ui.cli.CLI
import
CLIApplication
from
topydo.ui.CLIApplicationBase
import
MAIN_
OPTS
,
MAIN_LONG
_OPTS
,
error
from
topydo.ui.CLIApplicationBase
import
MAIN_
LONG_OPTS
,
MAIN
_OPTS
,
error
_WINDOWS
=
"win32"
in
sys
.
platform
...
...
topydo/ui/cli/CLI.py
View file @
c6e098e3
...
...
@@ -18,9 +18,10 @@
import
sys
from
topydo.Commands
import
get_subcommand
from
topydo.lib
import
TodoFile
,
TodoList
from
topydo.lib.Config
import
ConfigError
,
config
from
topydo.ui.CLIApplicationBase
import
CLIApplicationBase
,
error
from
topydo.lib
import
TodoFile
from
topydo.lib.Config
import
config
,
ConfigError
# First thing is to poke the configuration and check whether it's sane
# The modules below may already read in configuration upon import, so
...
...
@@ -31,8 +32,6 @@ except ConfigError as config_error:
error
(
str
(
config_error
))
sys
.
exit
(
1
)
from
topydo.Commands
import
get_subcommand
from
topydo.lib
import
TodoList
class
CLIApplication
(
CLIApplicationBase
):
...
...
@@ -57,7 +56,7 @@ class CLIApplication(CLIApplicationBase):
sys
.
exit
(
1
)
if
subcommand
is
None
:
self
.
_usage
()
CLIApplicationBase
.
_usage
()
if
self
.
_execute
(
subcommand
,
args
)
==
False
:
sys
.
exit
(
1
)
...
...
topydo/ui/columns/ColumnLayout.py
View file @
c6e098e3
...
...
@@ -14,10 +14,10 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from
configparser
import
RawConfigParser
,
NoOptionErro
r
from
configparser
import
NoOptionError
,
RawConfigParse
r
from
os.path
import
expanduser
from
topydo.lib.Config
import
home_config_path
,
config
from
topydo.lib.Config
import
config
,
home_config_path
def
columns
(
p_alt_layout_path
=
None
):
...
...
topydo/ui/columns/CommandLineWidget.py
View file @
c6e098e3
...
...
@@ -14,10 +14,10 @@
# 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
urwid
from
os.path
import
commonprefix
import
urwid
from
topydo.ui.columns.CompletionBoxWidget
import
CompletionBoxWidget
...
...
topydo/ui/columns/Main.py
View file @
c6e098e3
...
...
@@ -19,30 +19,32 @@ import getopt
import
shlex
import
sys
import
time
import
urwid
from
collections
import
namedtuple
from
string
import
ascii_uppercase
import
urwid
from
topydo.Commands
import
get_subcommand
from
topydo.lib.Config
import
config
,
ConfigError
from
topydo.ui.columns.ColumnCompleter
import
ColumnCompleter
from
topydo.lib
import
TodoList
from
topydo.lib.Config
import
ConfigError
,
config
from
topydo.lib.Filter
import
(
DependencyFilter
,
HiddenTagFilter
,
RelevanceFilter
,
get_filter_list
)
from
topydo.lib.Sorter
import
Sorter
from
topydo.lib.
Filter
import
get_filter_list
,
RelevanceFilter
,
DependencyFilter
,
HiddenTagFilter
from
topydo.lib.
TodoFileWatched
import
TodoFileWatched
from
topydo.lib.Utils
import
get_terminal_size
from
topydo.lib.View
import
View
from
topydo.lib.TodoFileWatched
import
TodoFileWatched
from
topydo.lib
import
TodoList
from
topydo.ui.CLIApplicationBase
import
CLIApplicationBase
,
error
,
GENERIC_HELP
from
topydo.ui.CLIApplicationBase
import
(
GENERIC_HELP
,
CLIApplicationBase
,
error
)
from
topydo.ui.columns.ColumnCompleter
import
ColumnCompleter
from
topydo.ui.columns.ColumnLayout
import
columns
from
topydo.ui.columns.CommandLineWidget
import
CommandLineWidget
from
topydo.ui.columns.ConsoleWidget
import
ConsoleWidget
from
topydo.ui.columns.KeystateWidget
import
KeystateWidget
from
topydo.ui.columns.TodoWidget
import
TodoWidget
from
topydo.ui.columns.TodoListWidget
import
TodoListWidget
from
topydo.ui.columns.TodoWidget
import
TodoWidget
from
topydo.ui.columns.Transaction
import
Transaction
from
topydo.ui.columns.Utils
import
PaletteItem
,
to_urwid_color
from
topydo.ui.columns.ViewWidget
import
ViewWidget
from
topydo.ui.columns.ColumnLayout
import
columns
class
UIView
(
View
):
...
...
@@ -196,24 +198,7 @@ class UIApplication(CLIApplicationBase):
self
.
_screen
=
urwid
.
raw_display
.
Screen
()
if
config
().
colors
():
self
.
_screen
.
register_palette
(
self
.
_create_color_palette
())
else
:
self
.
_screen
.
register_palette
(
self
.
_create_mono_palette
())
self
.
_screen
.
set_terminal_properties
(
256
)
self
.
mainloop
=
urwid
.
MainLoop
(
self
.
mainwindow
,
screen
=
self
.
_screen
,
unhandled_input
=
self
.
_handle_input
,
pop_ups
=
True
)
self
.
column_mode
=
_APPEND_COLUMN
self
.
_set_alarm_for_next_midnight_update
()
def
_create_color_palette
(
self
):
def
create_color_palette
():
project_color
=
to_urwid_color
(
config
().
project_color
())
context_color
=
to_urwid_color
(
config
().
context_color
())
metadata_color
=
to_urwid_color
(
config
().
metadata_color
())
...
...
@@ -249,7 +234,7 @@ class UIApplication(CLIApplicationBase):
return
palette
def
_create_mono_palette
(
self
):
def
create_mono_palette
(
):
palette
=
[
(
PaletteItem
.
DEFAULT_FOCUS
,
'black'
,
'light gray'
),
(
PaletteItem
.
PROJECT_FOCUS
,
PaletteItem
.
DEFAULT_FOCUS
),
...
...
@@ -266,6 +251,23 @@ class UIApplication(CLIApplicationBase):
return
palette
if
config
().
colors
():
self
.
_screen
.
register_palette
(
create_color_palette
())
else
:
self
.
_screen
.
register_palette
(
create_mono_palette
())
self
.
_screen
.
set_terminal_properties
(
256
)
self
.
mainloop
=
urwid
.
MainLoop
(
self
.
mainwindow
,
screen
=
self
.
_screen
,
unhandled_input
=
self
.
_handle_input
,
pop_ups
=
True
)
self
.
column_mode
=
_APPEND_COLUMN
self
.
_set_alarm_for_next_midnight_update
()
def
_set_alarm_for_next_midnight_update
(
self
):
def
callback
(
p_loop
,
p_data
):
TodoWidget
.
wipe_cache
()
...
...
topydo/ui/columns/TodoListWidget.py
View file @
c6e098e3
...
...
@@ -207,6 +207,7 @@ class TodoListWidget(urwid.LineBox):
p_row
,
p_focus
)
# pylint: disable=no-self-use
def
selectable
(
self
):
return
True
...
...
topydo/ui/columns/TodoWidget.py
View file @
c6e098e3
...
...
@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import
re
import
urwid
from
topydo.lib.Config
import
config
...
...
@@ -91,7 +92,6 @@ class TodoWidget(urwid.WidgetWrap):
priority_widget = urwid.Text(priority_text)
self.text_widget = urwid.Text(txt_markup)
progress = to_urwid_color(progress_color(p_todo)) if config().colors() else PaletteItem.DEFAULT
self.progress_bar = urwid.AttrMap(
urwid.SolidFill('
'),
{},
...
...
@@ -117,13 +117,15 @@ class TodoWidget(urwid.WidgetWrap):
super().__init__(self.widget)
def keypress(self, p_size, p_key):
# pylint: disable=no-self-use
def keypress(self, _, p_key):
"""
Override keypress to prevent the wrapped Columns widget to
receive any key.
"""
return p_key
# pylint: disable=no-self-use
def selectable(self):
# make sure that ListBox will highlight this widget
return True
...
...
@@ -196,4 +198,3 @@ class TodoWidget(urwid.WidgetWrap):
def wipe_cache(p_class):
""" Wipes the cache """
p_class.cache = {}
topydo/ui/columns/ViewWidget.py
View file @
c6e098e3
...
...
@@ -18,6 +18,7 @@ import urwid
from
topydo.lib.Config
import
config
class
ViewWidget
(
urwid
.
LineBox
):
def
__init__
(
self
,
p_todolist
):
self
.
_todolist
=
p_todolist
...
...
topydo/ui/prompt/Prompt.py
View file @
c6e098e3
...
...
@@ -16,16 +16,18 @@
""" Entry file for the topydo Prompt interface (CLI). """
import
os.path
import
shlex
import
sys
from
topydo.ui.CLIApplicationBase
import
CLIApplicationBase
,
error
,
GENERIC_HELP
from
topydo.ui.prompt.PromptCompleter
import
PromptCompleter
from
prompt_toolkit.shortcuts
import
prompt
from
prompt_toolkit.history
import
InMemoryHistory
from
prompt_toolkit.shortcuts
import
prompt
from
topydo.lib.Config
import
config
,
ConfigError
from
topydo.Commands
import
get_subcommand
from
topydo.lib.Config
import
ConfigError
,
config
from
topydo.lib.TodoFileWatched
import
TodoFileWatched
from
topydo.ui.CLIApplicationBase
import
(
GENERIC_HELP
,
CLIApplicationBase
,
error
)
from
topydo.ui.prompt.PromptCompleter
import
PromptCompleter
# First thing is to poke the configuration and check whether it's sane
# The modules below may already read in configuration upon import, so
...
...
@@ -36,9 +38,6 @@ except ConfigError as config_error:
error
(
str
(
config_error
))
sys
.
exit
(
1
)
from
topydo.Commands
import
get_subcommand
from
topydo.lib.TodoFileWatched
import
TodoFileWatched
from
topydo.lib
import
TodoList
class
PromptApplication
(
CLIApplicationBase
):
...
...
topydo/ui/prompt/PromptCompleter.py
View file @
c6e098e3
...
...
@@ -22,9 +22,10 @@ by the prompt toolkit.
import
re
from
prompt_toolkit.completion
import
Completer
,
Completion
from
topydo.ui.CompleterBase
import
CompleterBase
,
date_suggestions
from
topydo.lib.Config
import
config
from
topydo.lib.RelativeDate
import
relative_date_to_date
from
topydo.ui.CompleterBase
import
CompleterBase
,
date_suggestions
def
_dates
(
p_word_before_cursor
):
...
...
@@ -52,15 +53,14 @@ class PromptCompleter(CompleterBase, Completer):
for
candidate
in
candidates
:
yield
Completion
(
candidate
,
-
len
(
p_word
))
def
get_completions
(
self
,
p_
document
,
_
):
def
get_completions
(
self
,
p_
word
,
p_is_first_word
=
False
):
# include all characters except whitespaces (for + and @)
word_before_cursor
=
p_
document
.
get_word_before_cursor
(
True
)
word_before_cursor
=
p_
word
.
get_word_before_cursor
(
True
)
is_first_word
=
not
re
.
match
(
r'\
s*
\S+\
s
',
p_document.current_line_before_cursor)
p_word.current_line_before_cursor)
if word_before_cursor.startswith(config().tag_due() + '
:
'):
return _dates(word_before_cursor)
elif word_before_cursor.startswith(config().tag_start() + '
:
'):
return _dates(word_before_cursor)
else:
return self._completion_generator(word_before_cursor, is_first_word)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment