mirror of
https://github.com/caronc/apprise.git
synced 2024-11-22 08:04:02 +01:00
Improved YAML group support (#998)
This commit is contained in:
parent
7e87807f90
commit
0c5bd8afe1
@ -393,7 +393,11 @@ class ConfigBase(URLBase):
|
|||||||
# Track our groups
|
# Track our groups
|
||||||
groups.add(tag)
|
groups.add(tag)
|
||||||
|
|
||||||
# Store what we know is worth keping
|
# Store what we know is worth keeping
|
||||||
|
if tag not in group_tags: # pragma: no cover
|
||||||
|
# handle cases where the tag doesn't exist
|
||||||
|
group_tags[tag] = set()
|
||||||
|
|
||||||
results |= group_tags[tag] - tag_groups
|
results |= group_tags[tag] - tag_groups
|
||||||
|
|
||||||
# Get simple tag assignments
|
# Get simple tag assignments
|
||||||
@ -898,19 +902,11 @@ class ConfigBase(URLBase):
|
|||||||
# groups root directive
|
# groups root directive
|
||||||
#
|
#
|
||||||
groups = result.get('groups', None)
|
groups = result.get('groups', None)
|
||||||
if not isinstance(groups, (list, tuple)):
|
if isinstance(groups, dict):
|
||||||
# Not a problem; we simply have no group entry
|
#
|
||||||
groups = list()
|
# Dictionary
|
||||||
|
#
|
||||||
# Iterate over each group defined and store it
|
for _groups, tags in groups.items():
|
||||||
for no, entry in enumerate(groups):
|
|
||||||
if not isinstance(entry, dict):
|
|
||||||
ConfigBase.logger.warning(
|
|
||||||
'No assignment for group {}, entry #{}'.format(
|
|
||||||
entry, no + 1))
|
|
||||||
continue
|
|
||||||
|
|
||||||
for _groups, tags in entry.items():
|
|
||||||
for group in parse_list(_groups, cast=str):
|
for group in parse_list(_groups, cast=str):
|
||||||
if isinstance(tags, (list, tuple)):
|
if isinstance(tags, (list, tuple)):
|
||||||
_tags = set()
|
_tags = set()
|
||||||
@ -932,7 +928,41 @@ class ConfigBase(URLBase):
|
|||||||
else:
|
else:
|
||||||
group_tags[group] |= tags
|
group_tags[group] |= tags
|
||||||
|
|
||||||
#
|
elif isinstance(groups, (list, tuple)):
|
||||||
|
#
|
||||||
|
# List of Dictionaries
|
||||||
|
#
|
||||||
|
|
||||||
|
# Iterate over each group defined and store it
|
||||||
|
for no, entry in enumerate(groups):
|
||||||
|
if not isinstance(entry, dict):
|
||||||
|
ConfigBase.logger.warning(
|
||||||
|
'No assignment for group {}, entry #{}'.format(
|
||||||
|
entry, no + 1))
|
||||||
|
continue
|
||||||
|
|
||||||
|
for _groups, tags in entry.items():
|
||||||
|
for group in parse_list(_groups, cast=str):
|
||||||
|
if isinstance(tags, (list, tuple)):
|
||||||
|
_tags = set()
|
||||||
|
for e in tags:
|
||||||
|
if isinstance(e, dict):
|
||||||
|
_tags |= set(e.keys())
|
||||||
|
else:
|
||||||
|
_tags |= set(parse_list(e, cast=str))
|
||||||
|
|
||||||
|
# Final assignment
|
||||||
|
tags = _tags
|
||||||
|
|
||||||
|
else:
|
||||||
|
tags = set(parse_list(tags, cast=str))
|
||||||
|
|
||||||
|
if group not in group_tags:
|
||||||
|
group_tags[group] = tags
|
||||||
|
|
||||||
|
else:
|
||||||
|
group_tags[group] |= tags
|
||||||
|
|
||||||
# include root directive
|
# include root directive
|
||||||
#
|
#
|
||||||
includes = result.get('include', None)
|
includes = result.get('include', None)
|
||||||
|
@ -191,7 +191,7 @@ urls:
|
|||||||
- tag: devops, admin
|
- tag: devops, admin
|
||||||
""", asset=AppriseAsset())
|
""", asset=AppriseAsset())
|
||||||
|
|
||||||
# We expect to parse 3 entries from the above
|
# We expect to parse 2 entries from the above
|
||||||
assert isinstance(result, tuple)
|
assert isinstance(result, tuple)
|
||||||
assert len(result) == 2
|
assert len(result) == 2
|
||||||
assert isinstance(result[0], list)
|
assert isinstance(result[0], list)
|
||||||
@ -263,7 +263,7 @@ def test_config_base_config_parse_text():
|
|||||||
# A relative include statement (with trailing spaces)
|
# A relative include statement (with trailing spaces)
|
||||||
include apprise.cfg """, asset=AppriseAsset())
|
include apprise.cfg """, asset=AppriseAsset())
|
||||||
|
|
||||||
# We expect to parse 3 entries from the above
|
# We expect to parse 4 entries from the above
|
||||||
assert isinstance(result, list)
|
assert isinstance(result, list)
|
||||||
assert isinstance(config, list)
|
assert isinstance(config, list)
|
||||||
assert len(result) == 4
|
assert len(result) == 4
|
||||||
@ -409,7 +409,7 @@ def test_config_base_config_tag_groups_text():
|
|||||||
|
|
||||||
""", asset=AppriseAsset())
|
""", asset=AppriseAsset())
|
||||||
|
|
||||||
# We expect to parse 3 entries from the above
|
# We expect to parse 4 entries from the above
|
||||||
assert isinstance(result, list)
|
assert isinstance(result, list)
|
||||||
assert isinstance(config, list)
|
assert isinstance(config, list)
|
||||||
assert len(result) == 4
|
assert len(result) == 4
|
||||||
@ -442,7 +442,7 @@ def test_config_base_config_tag_groups_text():
|
|||||||
groupD=form://localhost
|
groupD=form://localhost
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# We expect to parse 3 entries from the above
|
# We expect to parse 0 entries from the above
|
||||||
assert isinstance(result, list)
|
assert isinstance(result, list)
|
||||||
assert isinstance(config, list)
|
assert isinstance(config, list)
|
||||||
assert len(result) == 0
|
assert len(result) == 0
|
||||||
@ -827,7 +827,7 @@ urls:
|
|||||||
- dbus://
|
- dbus://
|
||||||
""", asset=asset)
|
""", asset=asset)
|
||||||
|
|
||||||
# We expect to parse 3 entries from the above
|
# We expect to parse 2 entries from the above
|
||||||
assert isinstance(result, list)
|
assert isinstance(result, list)
|
||||||
assert len(result) == 2
|
assert len(result) == 2
|
||||||
|
|
||||||
@ -861,7 +861,7 @@ urls:
|
|||||||
assert 'admin' in entry.tags
|
assert 'admin' in entry.tags
|
||||||
assert 'devops' in entry.tags
|
assert 'devops' in entry.tags
|
||||||
|
|
||||||
# We expect to parse 3 entries from the above
|
# We expect to parse 2 entries from the above
|
||||||
assert isinstance(result, list)
|
assert isinstance(result, list)
|
||||||
assert len(result) == 2
|
assert len(result) == 2
|
||||||
|
|
||||||
@ -886,7 +886,7 @@ urls:
|
|||||||
- entry
|
- entry
|
||||||
""", asset=asset)
|
""", asset=asset)
|
||||||
|
|
||||||
# We expect to parse 3 entries from the above
|
# We expect to parse 0 entries from the above
|
||||||
assert isinstance(result, list)
|
assert isinstance(result, list)
|
||||||
assert len(result) == 0
|
assert len(result) == 0
|
||||||
|
|
||||||
@ -932,7 +932,7 @@ urls:
|
|||||||
- json://localhost:
|
- json://localhost:
|
||||||
""", asset=asset)
|
""", asset=asset)
|
||||||
|
|
||||||
# We expect to parse 3 entries from the above
|
# We expect to parse 1 entries from the above
|
||||||
assert isinstance(result, list)
|
assert isinstance(result, list)
|
||||||
assert len(result) == 1
|
assert len(result) == 1
|
||||||
|
|
||||||
@ -1155,9 +1155,9 @@ def test_yaml_vs_text_tagging():
|
|||||||
assert 'mytag' in yaml_result[0]
|
assert 'mytag' in yaml_result[0]
|
||||||
|
|
||||||
|
|
||||||
def test_config_base_config_tag_groups_yaml():
|
def test_config_base_config_tag_groups_yaml_01():
|
||||||
"""
|
"""
|
||||||
API: ConfigBase.config_tag_groups_yaml object
|
API: ConfigBase.config_tag_groups_yaml #1 object
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -1233,7 +1233,7 @@ urls:
|
|||||||
|
|
||||||
""", asset=asset)
|
""", asset=asset)
|
||||||
|
|
||||||
# We expect to parse 3 entries from the above
|
# We expect to parse 4 entries from the above
|
||||||
assert isinstance(result, list)
|
assert isinstance(result, list)
|
||||||
assert isinstance(config, list)
|
assert isinstance(config, list)
|
||||||
assert len(result) == 4
|
assert len(result) == 4
|
||||||
@ -1261,11 +1261,132 @@ urls:
|
|||||||
assert len([x for x in apobj.find('group3')]) == 2
|
assert len([x for x in apobj.find('group3')]) == 2
|
||||||
assert len([x for x in apobj.find('group4')]) == 0
|
assert len([x for x in apobj.find('group4')]) == 0
|
||||||
assert len([x for x in apobj.find('group5')]) == 0
|
assert len([x for x in apobj.find('group5')]) == 0
|
||||||
|
# json:// -- group6 -> 4 -> TagA
|
||||||
|
# xml:// -- group6 -> TagC
|
||||||
assert len([x for x in apobj.find('group6')]) == 2
|
assert len([x for x in apobj.find('group6')]) == 2
|
||||||
assert len([x for x in apobj.find('4')]) == 1
|
assert len([x for x in apobj.find('4')]) == 1
|
||||||
assert len([x for x in apobj.find('groupN')]) == 1
|
assert len([x for x in apobj.find('groupN')]) == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_config_base_config_tag_groups_yaml_02():
|
||||||
|
"""
|
||||||
|
API: ConfigBase.config_tag_groups_yaml #2 object
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# general reference used below
|
||||||
|
asset = AppriseAsset()
|
||||||
|
|
||||||
|
# Valid Configuration
|
||||||
|
result, config = ConfigBase.config_parse_yaml("""
|
||||||
|
# if no version is specified then version 1 is presumed
|
||||||
|
version: 1
|
||||||
|
|
||||||
|
groups:
|
||||||
|
group1: tagB, tagC, tagNotAssigned
|
||||||
|
group2:
|
||||||
|
- tagA
|
||||||
|
- tagC
|
||||||
|
group3:
|
||||||
|
- tagD: optional comment
|
||||||
|
- tagA: optional comment #2
|
||||||
|
|
||||||
|
# No assignment type 2
|
||||||
|
group5:
|
||||||
|
|
||||||
|
# Integer assignment (since it's not a list, the last element prevails
|
||||||
|
# and replaces the above); '4' does not get appended as it would in
|
||||||
|
# the event this was a list instead
|
||||||
|
group6: 3
|
||||||
|
group6: 3, 4, 5, test
|
||||||
|
group6: 3.5, tagC
|
||||||
|
|
||||||
|
# Recursion
|
||||||
|
groupA: groupB
|
||||||
|
groupB: groupA
|
||||||
|
# And Again... (just because)
|
||||||
|
groupA: groupB
|
||||||
|
groupB: groupA
|
||||||
|
|
||||||
|
# Self assignment
|
||||||
|
groupX: groupX
|
||||||
|
|
||||||
|
# Set up a larger recursive loop
|
||||||
|
groupG: groupH
|
||||||
|
groupH: groupI, groupJ
|
||||||
|
groupI: groupJ, groupG
|
||||||
|
groupJ: groupK, groupH, groupI
|
||||||
|
groupK: groupG
|
||||||
|
|
||||||
|
# No tags assigned
|
||||||
|
groupK: ",, , ,"
|
||||||
|
" , ": ",, , ,"
|
||||||
|
|
||||||
|
# Multi Assignments
|
||||||
|
groupL, groupM: tagD, tagA
|
||||||
|
4, groupN:
|
||||||
|
- tagD
|
||||||
|
- tagE, TagA
|
||||||
|
|
||||||
|
# Add one more tag to groupL making it different then GroupM by 1
|
||||||
|
groupL: tagB
|
||||||
|
#
|
||||||
|
# Define your notification urls:
|
||||||
|
#
|
||||||
|
urls:
|
||||||
|
- form://localhost:
|
||||||
|
- tag: tagA
|
||||||
|
- mailto://test:password@gmail.com:
|
||||||
|
- tag: tagB
|
||||||
|
- xml://localhost:
|
||||||
|
- tag: tagC
|
||||||
|
- json://localhost:
|
||||||
|
- tag: tagD, tagA
|
||||||
|
|
||||||
|
""", asset=asset)
|
||||||
|
|
||||||
|
# We expect to parse 4 entries from the above
|
||||||
|
assert isinstance(result, list)
|
||||||
|
assert isinstance(config, list)
|
||||||
|
assert len(result) == 4
|
||||||
|
|
||||||
|
# Our first element is our group tags
|
||||||
|
assert len(result[0].tags) == 5
|
||||||
|
assert 'group2' in result[0].tags
|
||||||
|
assert 'group3' in result[0].tags
|
||||||
|
assert 'groupL' in result[0].tags
|
||||||
|
assert 'groupM' in result[0].tags
|
||||||
|
assert 'tagA' in result[0].tags
|
||||||
|
|
||||||
|
# No additional configuration is loaded
|
||||||
|
assert len(config) == 0
|
||||||
|
|
||||||
|
apobj = Apprise()
|
||||||
|
assert apobj.add(result)
|
||||||
|
# We match against 1 entry
|
||||||
|
assert len([x for x in apobj.find('tagA')]) == 2
|
||||||
|
assert len([x for x in apobj.find('tagB')]) == 1
|
||||||
|
assert len([x for x in apobj.find('tagC')]) == 1
|
||||||
|
assert len([x for x in apobj.find('tagD')]) == 1
|
||||||
|
assert len([x for x in apobj.find('group1')]) == 2
|
||||||
|
assert len([x for x in apobj.find('group2')]) == 3
|
||||||
|
assert len([x for x in apobj.find('group3')]) == 2
|
||||||
|
assert len([x for x in apobj.find('group4')]) == 0
|
||||||
|
assert len([x for x in apobj.find('group5')]) == 0
|
||||||
|
# NOT json:// -- group6 -> 4 -> TagA (not appended because dict storage)
|
||||||
|
# ^
|
||||||
|
# |
|
||||||
|
# See: test_config_base_config_tag_groups_yaml_01 (above)
|
||||||
|
# dict storage (as this tests for) causes last entry to
|
||||||
|
# prevail; previous assignments are lost
|
||||||
|
#
|
||||||
|
# xml:// -- group6 -> TagC
|
||||||
|
assert len([x for x in apobj.find('group6')]) == 1
|
||||||
|
assert len([x for x in apobj.find('4')]) == 1
|
||||||
|
assert len([x for x in apobj.find('groupN')]) == 1
|
||||||
|
assert len([x for x in apobj.find('groupK')]) == 0
|
||||||
|
|
||||||
|
|
||||||
def test_config_base_config_parse_yaml_globals():
|
def test_config_base_config_parse_yaml_globals():
|
||||||
"""
|
"""
|
||||||
API: ConfigBase.config_parse_yaml globals
|
API: ConfigBase.config_parse_yaml globals
|
||||||
|
Loading…
Reference in New Issue
Block a user