diff --git a/organize/config.py b/organize/config.py index a03f55f2..c952f794 100644 --- a/organize/config.py +++ b/organize/config.py @@ -109,7 +109,7 @@ def instantiate_filters(self, rule_item: Mapping) -> Generator[Filter, None, Non if not isinstance(filter_list, list): raise self.FiltersNoListError() - for filter_item in filter_list: + for filter_item in flatten(filter_list): if filter_item is None: # TODO: don't know what this should be continue @@ -132,7 +132,7 @@ def instantiate_actions(self, rule_item: Mapping) -> Generator[Action, None, Non if not isinstance(action_list, list): raise self.ActionsNoListError() - for action_item in action_list: + for action_item in flatten(action_list): if isinstance(action_item, dict): name = first_key(action_item) args = action_item[name] diff --git a/tests/core/test_config.py b/tests/core/test_config.py index 66b5b21a..b5f156f5 100644 --- a/tests/core/test_config.py +++ b/tests/core/test_config.py @@ -1,8 +1,8 @@ import pytest -from organize.actions import Echo, Move, Shell, Trash +from organize.actions import Echo, Move, Shell, Trash, Rename from organize.config import Config, Rule -from organize.filters import Extension, LastModified +from organize.filters import Extension, LastModified, FileContent def test_basic(): @@ -196,3 +196,146 @@ def test_empty_filters(): system_files=False, ), ] + + +def test_flatten_filters_and_actions(): + config = """ + folder_aliases: + Downloads: &downloads ~/Downloads/ + Payables_due: &payables_due ~/PayablesDue/ + Payables_paid: &payables_paid ~/Accounting/Expenses/ + Receivables_due: &receivables_due ~/Receivables/ + Receivables_paid: &receivables_paid ~/Accounting/Income/ + + defaults: + filters: &default_filters + - extension: pdf + - filecontent: '(?P...)' + actions: &default_actions + - echo: 'Dated: {filecontent.date}' + - echo: 'Stem of filename: {filecontent.stem}' + post_actions: &default_sorting + - rename: '{python.timestamp}-{filecontent.stem}.{extension.lower}' + - move: '{path.parent}/{python.quarter}/' + + rules: + - folders: *downloads + filters: + - *default_filters + - filecontent: 'Due Date' # regex to id as payable + - filecontent: '(?P...)' # regex to extract supplier + actions: + - *default_actions + - move: *payables_due + - *default_sorting + + - folders: *downloads + filters: + - *default_filters + - filecontent: 'Account: 000000000' # regex to id as receivables due + - filecontent: '(?P...)' # regex to extract customer + actions: + - *default_actions + - move: *receivables_due + - *default_sorting + + - folders: *downloads + filters: + - *default_filters + - filecontent: 'PAID' # regex to id as receivables paid + - filecontent: '(?P...)' # regex to extract customer + - filecontent: '(?P...)' # regex to extract date paid + actions: + - *default_actions + - move: *receivables_paid + - *default_sorting + - rename: '{filecontent.paid}_{filecontent.stem}.{extension}' + """ + conf = Config.from_string(config) + assert conf.rules == [ + Rule( + folders=["~/Downloads/"], + filters=[ + # default_filters + Extension("pdf"), + FileContent(expr="(?P...)"), + # added filters + FileContent(expr="Due Date"), + FileContent(expr="(?P...)"), + ], + actions=[ + # default_actions + Echo(msg="Dated: {filecontent.date}"), + Echo(msg="Stem of filename: {filecontent.stem}"), + # added actions + Move(dest="~/PayablesDue/", overwrite=False), + # default_sorting + Rename( + name="{python.timestamp}-{filecontent.stem}.{extension.lower}", + overwrite=False, + ), + Move(dest="{path.parent}/{python.quarter}/", overwrite=False), + ], + subfolders=False, + system_files=False, + ), + Rule( + folders=["~/Downloads/"], + filters=[ + # default_filters + Extension("pdf"), + FileContent(expr="(?P...)"), + # added filters + FileContent(expr="Account: 000000000"), + FileContent(expr="(?P...)"), + ], + actions=[ + # default_actions + Echo(msg="Dated: {filecontent.date}"), + Echo(msg="Stem of filename: {filecontent.stem}"), + # added actions + Move(dest="~/Receivables/", overwrite=False), + # default_sorting + Rename( + name="{python.timestamp}-{filecontent.stem}.{extension.lower}", + overwrite=False, + ), + Move(dest="{path.parent}/{python.quarter}/", overwrite=False), + ], + subfolders=False, + system_files=False, + ), + Rule( + folders=["~/Downloads/"], + filters=[ + # default_filters + Extension("pdf"), + FileContent(expr="(?P...)"), + # added filters + FileContent(expr="PAID"), + FileContent(expr="(?P...)"), + FileContent(expr="(?P...)"), + ], + actions=[ + # default_actions + Echo(msg="Dated: {filecontent.date}"), + Echo(msg="Stem of filename: {filecontent.stem}"), + # added actions + Move(dest="~/Accounting/Income/", overwrite=False), + # default_sorting + Rename( + name="{python.timestamp}-{filecontent.stem}.{extension.lower}", + overwrite=False, + ), + Move(dest="{path.parent}/{python.quarter}/", overwrite=False), + # added actions + Rename( + name="{filecontent.paid}_{filecontent.stem}.{extension}", + overwrite=False, + ), + ], + subfolders=False, + system_files=False, + ), + ] +