mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-05-10 16:48:31 +02:00
Prevent filtered delete from deleting journal (#935)
* Prevent filtered deletion from deleting entire journal #932 and add lots of deletion tests * Undo removal of deletion feature * Use more performant deletion
This commit is contained in:
parent
cfbebe0d38
commit
d9ebfe852b
6 changed files with 191 additions and 17 deletions
12
features/data/configs/deletion_filters.yaml
Normal file
12
features/data/configs/deletion_filters.yaml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
default_hour: 9
|
||||||
|
default_minute: 0
|
||||||
|
editor: ""
|
||||||
|
encrypt: false
|
||||||
|
highlight: true
|
||||||
|
journals:
|
||||||
|
default: features/journals/deletion_filters.journal
|
||||||
|
linewrap: 80
|
||||||
|
tagsymbols: "@"
|
||||||
|
template: false
|
||||||
|
timeformat: "%Y-%m-%d %H:%M"
|
||||||
|
indent_character: "|"
|
14
features/data/journals/deletion_filters.journal
Normal file
14
features/data/journals/deletion_filters.journal
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[2019-10-01 08:00] It's just another day in October.
|
||||||
|
Not much to write about.
|
||||||
|
|
||||||
|
[2020-01-01 08:00] Happy New Year!
|
||||||
|
So this is the New Year. @holidays
|
||||||
|
|
||||||
|
[2020-03-01 08:00] It's just another day in March.
|
||||||
|
A stick, a stone, it's the end of the road.
|
||||||
|
|
||||||
|
[2020-05-01 09:00] Happy May Day!
|
||||||
|
@holidays @springtime Several holidays fall on this date.
|
||||||
|
|
||||||
|
[2020-05-02 12:10] Writing tests. *
|
||||||
|
@springtime They will help prevent bugs.
|
|
@ -1,5 +1,4 @@
|
||||||
Feature: Delete entries from journal
|
Feature: Delete entries from journal
|
||||||
@skip
|
|
||||||
Scenario: --delete flag allows deletion of single entry
|
Scenario: --delete flag allows deletion of single entry
|
||||||
Given we use the config "deletion.yaml"
|
Given we use the config "deletion.yaml"
|
||||||
When we run "jrnl -n 1"
|
When we run "jrnl -n 1"
|
||||||
|
@ -18,3 +17,133 @@ Feature: Delete entries from journal
|
||||||
"""
|
"""
|
||||||
2019-10-29 11:11 Second entry.
|
2019-10-29 11:11 Second entry.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
Scenario: Backing out of interactive delete does not change journal
|
||||||
|
Given we use the config "deletion.yaml"
|
||||||
|
When we run "jrnl --delete -n 1" and enter
|
||||||
|
"""
|
||||||
|
N
|
||||||
|
"""
|
||||||
|
Then the journal should have 3 entries
|
||||||
|
And the journal should contain "[2019-10-29 11:11] First entry."
|
||||||
|
And the journal should contain "[2019-10-29 11:11] Second entry."
|
||||||
|
And the journal should contain "[2019-10-29 11:13] Third entry."
|
||||||
|
|
||||||
|
Scenario: --delete flag with nonsense input deletes nothing (issue #932)
|
||||||
|
Given we use the config "deletion.yaml"
|
||||||
|
When we run "jrnl --delete asdfasdf"
|
||||||
|
When we run "jrnl -n 1"
|
||||||
|
Then the output should contain
|
||||||
|
"""
|
||||||
|
2019-10-29 11:13 Third entry.
|
||||||
|
"""
|
||||||
|
And the journal should have 3 entries
|
||||||
|
|
||||||
|
Scenario: --delete flag with tag only deletes tagged entries
|
||||||
|
Given we use the config "deletion_filters.yaml"
|
||||||
|
When we run "jrnl --delete @holidays" and enter
|
||||||
|
"""
|
||||||
|
Y
|
||||||
|
Y
|
||||||
|
"""
|
||||||
|
Then the journal should have 3 entries
|
||||||
|
Then the journal should contain "[2019-10-01 08:00] It's just another day in October."
|
||||||
|
and the journal should contain "[2020-03-01 08:00] It's just another day in March."
|
||||||
|
and the journal should contain "[2020-05-02 12:10] Writing tests."
|
||||||
|
|
||||||
|
Scenario: --delete flag with multiple tags deletes all entries matching any of the tags
|
||||||
|
Given we use the config "deletion_filters.yaml"
|
||||||
|
When we run "jrnl --delete @holidays @springtime" and enter
|
||||||
|
"""
|
||||||
|
Y
|
||||||
|
Y
|
||||||
|
Y
|
||||||
|
"""
|
||||||
|
Then the journal should contain "[2019-10-01 08:00] It's just another day in October."
|
||||||
|
and the journal should not contain "[2020-01-01 08:00] Happy New Year!"
|
||||||
|
and the journal should contain "[2020-03-01 08:00] It's just another day in March."
|
||||||
|
and the journal should not contain "[2020-05-01 09:00] Happy May Day!"
|
||||||
|
and the journal should not contain "[2020-05-02 12:10] Writing tests. *"
|
||||||
|
and the journal should have 2 entries
|
||||||
|
|
||||||
|
Scenario: --delete flag with -and and tags only deletes boolean AND of tagged entries
|
||||||
|
Given we use the config "deletion_filters.yaml"
|
||||||
|
When we run "jrnl --delete -and @holidays @springtime" and enter
|
||||||
|
"""
|
||||||
|
Y
|
||||||
|
"""
|
||||||
|
Then the journal should contain "[2019-10-01 08:00] It's just another day in October."
|
||||||
|
and the journal should contain "[2020-01-01 08:00] Happy New Year!"
|
||||||
|
and the journal should contain "[2020-03-01 08:00] It's just another day in March."
|
||||||
|
and the journal should not contain "[2020-05-01 09:00] Happy May Day!"
|
||||||
|
and the journal should contain "[2020-05-02 12:10] Writing tests. *"
|
||||||
|
and the journal should have 4 entries
|
||||||
|
|
||||||
|
Scenario: --delete flag with -not does not delete entries with -not tag
|
||||||
|
Given we use the config "deletion_filters.yaml"
|
||||||
|
When we run "jrnl --delete @holidays -not @springtime" and enter
|
||||||
|
"""
|
||||||
|
Y
|
||||||
|
"""
|
||||||
|
Then the journal should contain "[2019-10-01 08:00] It's just another day in October."
|
||||||
|
and the journal should not contain "[2020-01-01 08:00] Happy New Year!"
|
||||||
|
and the journal should contain "[2020-03-01 08:00] It's just another day in March."
|
||||||
|
and the journal should contain "[2020-05-01 09:00] Happy May Day!"
|
||||||
|
and the journal should contain "[2020-05-02 12:10] Writing tests. *"
|
||||||
|
and the journal should have 4 entries
|
||||||
|
|
||||||
|
Scenario: --delete flag with -from only deletes entries since a specified date
|
||||||
|
Given we use the config "deletion_filters.yaml"
|
||||||
|
When we run "jrnl --delete -from 2020-01-02" and enter
|
||||||
|
"""
|
||||||
|
Y
|
||||||
|
Y
|
||||||
|
Y
|
||||||
|
"""
|
||||||
|
Then the journal should contain "[2019-10-01 08:00] It's just another day in October."
|
||||||
|
and the journal should contain "[2020-01-01 08:00] Happy New Year!"
|
||||||
|
and the journal should not contain "[2020-03-01 08:00] It's just another day in March."
|
||||||
|
and the journal should not contain "[2020-05-01 09:00] Happy May Day!"
|
||||||
|
and the journal should not contain "[2020-05-02 12:10] Writing tests."
|
||||||
|
and the journal should have 2 entries
|
||||||
|
|
||||||
|
Scenario: --delete flag with -to only deletes entries up to specified date
|
||||||
|
Given we use the config "deletion_filters.yaml"
|
||||||
|
When we run "jrnl --delete -to 2020-01-02" and enter
|
||||||
|
"""
|
||||||
|
Y
|
||||||
|
Y
|
||||||
|
"""
|
||||||
|
Then the journal should not contain "[2019-10-01 08:00] It's just another day in October."
|
||||||
|
and the journal should not contain "[2020-01-01 08:00] Happy New Year!"
|
||||||
|
and the journal should contain "[2020-03-01 08:00] It's just another day in March."
|
||||||
|
and the journal should contain "[2020-05-01 09:00] Happy May Day!"
|
||||||
|
and the journal should contain "[2020-05-02 12:10] Writing tests."
|
||||||
|
and the journal should have 3 entries
|
||||||
|
|
||||||
|
Scenario: --delete flag with -starred only deletes starred entries
|
||||||
|
Given we use the config "deletion_filters.yaml"
|
||||||
|
When we run "jrnl --delete -starred" and enter
|
||||||
|
"""
|
||||||
|
Y
|
||||||
|
"""
|
||||||
|
Then the journal should contain "[2019-10-01 08:00] It's just another day in October."
|
||||||
|
and the journal should contain "[2020-01-01 08:00] Happy New Year!"
|
||||||
|
and the journal should contain "[2020-03-01 08:00] It's just another day in March."
|
||||||
|
and the journal should contain "[2020-05-01 09:00] Happy May Day!"
|
||||||
|
and the journal should not contain "[2020-05-02 12:10] Writing tests. *"
|
||||||
|
and the journal should have 4 entries
|
||||||
|
|
||||||
|
Scenario: --delete flag with -contains only entries containing expression
|
||||||
|
Given we use the config "deletion_filters.yaml"
|
||||||
|
When we run "jrnl --delete -contains happy" and enter
|
||||||
|
"""
|
||||||
|
Y
|
||||||
|
Y
|
||||||
|
"""
|
||||||
|
Then the journal should contain "[2019-10-01 08:00] It's just another day in October."
|
||||||
|
and the journal should not contain "[2020-01-01 08:00] Happy New Year!"
|
||||||
|
and the journal should contain "[2020-03-01 08:00] It's just another day in March."
|
||||||
|
and the journal should not contain "[2020-05-01 09:00] Happy May Day!"
|
||||||
|
and the journal should contain "[2020-05-02 12:10] Writing tests. *"
|
||||||
|
and the journal should have 3 entries
|
||||||
|
|
|
@ -257,6 +257,13 @@ def check_journal_content(context, text, journal_name="default"):
|
||||||
assert text in journal, journal
|
assert text in journal, journal
|
||||||
|
|
||||||
|
|
||||||
|
@then('the journal should not contain "{text}"')
|
||||||
|
@then('journal "{journal_name}" should not contain "{text}"')
|
||||||
|
def check_not_journal_content(context, text, journal_name="default"):
|
||||||
|
journal = read_journal(journal_name)
|
||||||
|
assert text not in journal, journal
|
||||||
|
|
||||||
|
|
||||||
@then('journal "{journal_name}" should not exist')
|
@then('journal "{journal_name}" should not exist')
|
||||||
def journal_doesnt_exist(context, journal_name="default"):
|
def journal_doesnt_exist(context, journal_name="default"):
|
||||||
with open(install.CONFIG_FILE_PATH) as config_file:
|
with open(install.CONFIG_FILE_PATH) as config_file:
|
||||||
|
|
|
@ -234,8 +234,14 @@ class Journal:
|
||||||
|
|
||||||
self.entries = result
|
self.entries = result
|
||||||
|
|
||||||
|
def delete_entries(self, entries_to_delete):
|
||||||
|
"""Deletes specific entries from a journal."""
|
||||||
|
for entry in entries_to_delete:
|
||||||
|
self.entries.remove(entry)
|
||||||
|
|
||||||
def prompt_delete_entries(self):
|
def prompt_delete_entries(self):
|
||||||
"""Prompts for deletion of entries in a journal."""
|
"""Prompts for deletion of each of the entries in a journal.
|
||||||
|
Returns the entries the user wishes to delete."""
|
||||||
|
|
||||||
to_delete = []
|
to_delete = []
|
||||||
|
|
||||||
|
@ -248,8 +254,7 @@ class Journal:
|
||||||
if ask_delete(entry):
|
if ask_delete(entry):
|
||||||
to_delete.append(entry)
|
to_delete.append(entry)
|
||||||
|
|
||||||
self.entries = [entry for entry in self.entries if entry not in to_delete]
|
return to_delete
|
||||||
self.write()
|
|
||||||
|
|
||||||
def new_entry(self, raw, date=None, sort=True):
|
def new_entry(self, raw, date=None, sort=True):
|
||||||
"""Constructs a new entry from some raw text input.
|
"""Constructs a new entry from some raw text input.
|
||||||
|
|
31
jrnl/cli.py
31
jrnl/cli.py
|
@ -187,14 +187,12 @@ def parse_args(args=None):
|
||||||
action="store_true",
|
action="store_true",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Disabling this momentarily due to critical bug
|
exporting.add_argument(
|
||||||
# @see https://github.com/jrnl-org/jrnl/issues/932
|
"--delete",
|
||||||
# exporting.add_argument(
|
dest="delete",
|
||||||
# "--delete",
|
action="store_true",
|
||||||
# dest="delete",
|
help="Opens an interactive interface for deleting entries.",
|
||||||
# action="store_true",
|
)
|
||||||
# help="Opens an interactive interface for deleting entries.",
|
|
||||||
# )
|
|
||||||
|
|
||||||
# Handle '-123' as a shortcut for '-n 123'
|
# Handle '-123' as a shortcut for '-n 123'
|
||||||
num = re.compile(r"^-(\d+)$")
|
num = re.compile(r"^-(\d+)$")
|
||||||
|
@ -304,9 +302,6 @@ def configure_logger(debug=False):
|
||||||
def run(manual_args=None):
|
def run(manual_args=None):
|
||||||
args = parse_args(manual_args)
|
args = parse_args(manual_args)
|
||||||
|
|
||||||
# temporary until bring back --delete
|
|
||||||
args.delete = False # TODO: remove me
|
|
||||||
|
|
||||||
configure_logger(args.debug)
|
configure_logger(args.debug)
|
||||||
if args.version:
|
if args.version:
|
||||||
version_str = f"{jrnl.__title__} version {jrnl.__version__}"
|
version_str = f"{jrnl.__title__} version {jrnl.__version__}"
|
||||||
|
@ -341,6 +336,7 @@ def run(manual_args=None):
|
||||||
config = util.scope_config(config, journal_name)
|
config = util.scope_config(config, journal_name)
|
||||||
|
|
||||||
log.debug('Using journal "%s"', journal_name)
|
log.debug('Using journal "%s"', journal_name)
|
||||||
|
|
||||||
mode_compose, mode_export, mode_import = guess_mode(args, config)
|
mode_compose, mode_export, mode_import = guess_mode(args, config)
|
||||||
|
|
||||||
# How to quit writing?
|
# How to quit writing?
|
||||||
|
@ -484,5 +480,16 @@ def run(manual_args=None):
|
||||||
journal.write()
|
journal.write()
|
||||||
|
|
||||||
elif args.delete:
|
elif args.delete:
|
||||||
journal.prompt_delete_entries()
|
if journal.entries:
|
||||||
|
entries_to_delete = journal.prompt_delete_entries()
|
||||||
|
|
||||||
|
if entries_to_delete:
|
||||||
|
journal.entries = old_entries
|
||||||
|
journal.delete_entries(entries_to_delete)
|
||||||
|
|
||||||
journal.write()
|
journal.write()
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
"No entries deleted, because the search returned no results.",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue