summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin Proffitt <jprof.dev@gmail.com>2019-07-28 21:57:53 -0400
committerJustin Proffitt <jprof.dev@gmail.com>2020-04-10 11:51:55 -0700
commitc249c8ded9c5d13c57a6f158ea2bdb6d28ce8534 (patch)
tree41bd00be4b929ff06ca9c2382723bb572d5a8731
parentbd806efb9899ada2b90aae65843bf4de12cb51fc (diff)
Add '-not' flag for excluding tags from filter
Add tests for the excluding tags with -not
-rw-r--r--features/tagging.feature32
-rw-r--r--jrnl/Journal.py9
-rw-r--r--jrnl/cli.py4
3 files changed, 42 insertions, 3 deletions
diff --git a/features/tagging.feature b/features/tagging.feature
index cc686673..2cbf7ce1 100644
--- a/features/tagging.feature
+++ b/features/tagging.feature
@@ -50,3 +50,35 @@ Feature: Tagging
@foo : 1
@bar : 1
"""
+
+ Scenario: Excluding a tag should filter it
+ Given we use the config "basic.yaml"
+ When we run "jrnl today: @foo came over, we went to a bar"
+ When we run "jrnl I have decided I did not enjoy that @bar"
+ When we run "jrnl --tags -not @bar"
+ Then the output should be
+ """
+ @foo : 1
+ """
+
+ Scenario: Excluding a tag should filter an entry, even if an unfiltered tag is in that entry
+ Given we use the config "basic.yaml"
+ When we run "jrnl today: I do @not think this will show up @thought"
+ When we run "jrnl today: I think this will show up @thought"
+ When we run "jrnl --tags -not @not"
+ Then the output should be
+ """
+ @thought : 1
+ """
+
+ Scenario: Excluding multiple tags should filter them
+ Given we use the config "basic.yaml"
+ When we run "jrnl today: I do @not think this will show up @thought"
+ When we run "jrnl today: I think this will show up @thought"
+ When we run "jrnl today: This should @never show up @thought"
+ When we run "jrnl today: What a nice day for filtering @thought"
+ When we run "jrnl --tags -not @not @never"
+ Then the output should be
+ """
+ @thought : 2
+ """
diff --git a/jrnl/Journal.py b/jrnl/Journal.py
index 7feb49a6..72fe94b1 100644
--- a/jrnl/Journal.py
+++ b/jrnl/Journal.py
@@ -186,7 +186,7 @@ class Journal(object):
tag_counts = set([(tags.count(tag), tag) for tag in tags])
return [Tag(tag, count=count) for count, tag in sorted(tag_counts)]
- def filter(self, tags=[], start_date=None, end_date=None, starred=False, strict=False, short=False):
+ def filter(self, tags=[], start_date=None, end_date=None, starred=False, strict=False, short=False, exclude=[]):
"""Removes all entries from the journal that don't match the filter.
tags is a list of tags, each being a string that starts with one of the
@@ -197,19 +197,24 @@ class Journal(object):
starred limits journal to starred entries
If strict is True, all tags must be present in an entry. If false, the
- entry is kept if any tag is present."""
+
+ exclude is a list of the tags which should not appear in the results.
+ entry is kept if any tag is present, unless they appear in exclude."""
self.search_tags = set([tag.lower() for tag in tags])
+ excluded_tags = set([tag.lower() for tag in exclude])
end_date = time.parse(end_date, inclusive=True)
start_date = time.parse(start_date)
# If strict mode is on, all tags have to be present in entry
tagged = self.search_tags.issubset if strict else self.search_tags.intersection
+ excluded = lambda tags: len([tag for tag in tags if tag in excluded_tags]) > 0
result = [
entry for entry in self.entries
if (not tags or tagged(entry.tags))
and (not starred or entry.starred)
and (not start_date or entry.date >= start_date)
and (not end_date or entry.date <= end_date)
+ and (not exclude or not excluded(entry.tags))
]
self.entries = result
diff --git a/jrnl/cli.py b/jrnl/cli.py
index 6d88685a..65a53516 100644
--- a/jrnl/cli.py
+++ b/jrnl/cli.py
@@ -39,6 +39,7 @@ def parse_args(args=None):
reading.add_argument('-and', dest='strict', action="store_true", help='Filter by tags using AND (default: OR)')
reading.add_argument('-starred', dest='starred', action="store_true", help='Show only starred entries')
reading.add_argument('-n', dest='limit', default=None, metavar="N", help="Shows the last n entries matching the filter. '-n 3' and '-3' have the same effect.", nargs="?", type=int)
+ reading.add_argument('-not', dest='excluded', nargs='+', default=[], metavar="E", help="Exclude entries with these tags")
exporting = parser.add_argument_group('Export / Import', 'Options for transmogrifying your journal')
exporting.add_argument('-s', '--short', dest='short', action="store_true", help='Show only titles or line containing the search tags')
@@ -239,7 +240,8 @@ def run(manual_args=None):
start_date=args.start_date, end_date=args.end_date,
strict=args.strict,
short=args.short,
- starred=args.starred)
+ starred=args.starred,
+ exclude=args.excluded)
journal.limit(args.limit)
# Reading mode