mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2025-12-15 04:26:14 +00:00
experiment with default plugins
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
from json_logic import jsonLogic
|
from json_logic import jsonLogic
|
||||||
from json_logic.builtins import BUILTINS
|
from json_logic.builtins import BUILTINS
|
||||||
|
from .pluggy_interface import plugin_manager # Import the pluggy plugin manager
|
||||||
|
from . import default_plugin
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
# List of all supported JSON Logic operators
|
# List of all supported JSON Logic operators
|
||||||
@@ -78,7 +81,19 @@ CUSTOM_OPERATIONS = {
|
|||||||
"!contains_regex": not_contains_regex
|
"!contains_regex": not_contains_regex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ✅ Load plugins dynamically
|
||||||
|
for plugin in plugin_manager.get_plugins():
|
||||||
|
new_ops = plugin.register_operators()
|
||||||
|
if isinstance(new_ops, dict):
|
||||||
|
CUSTOM_OPERATIONS.update(new_ops)
|
||||||
|
|
||||||
|
new_operator_choices = plugin.register_operator_choices()
|
||||||
|
if isinstance(new_operator_choices, list):
|
||||||
|
operator_choices.extend(new_operator_choices)
|
||||||
|
|
||||||
|
new_field_choices = plugin.register_field_choices()
|
||||||
|
if isinstance(new_field_choices, list):
|
||||||
|
field_choices.extend(new_field_choices)
|
||||||
|
|
||||||
def run(ruleset, data):
|
def run(ruleset, data):
|
||||||
"""
|
"""
|
||||||
30
changedetectionio/conditions/default_plugin.py
Normal file
30
changedetectionio/conditions/default_plugin.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import pluggy
|
||||||
|
|
||||||
|
hookimpl = pluggy.HookimplMarker("conditions")
|
||||||
|
|
||||||
|
@hookimpl
|
||||||
|
def register_operators():
|
||||||
|
def starts_with(_, text, prefix):
|
||||||
|
return text.lower().startswith(prefix.lower())
|
||||||
|
|
||||||
|
def ends_with(_, text, suffix):
|
||||||
|
return text.lower().endswith(suffix.lower())
|
||||||
|
|
||||||
|
return {
|
||||||
|
"starts_with": starts_with,
|
||||||
|
"ends_with": ends_with
|
||||||
|
}
|
||||||
|
|
||||||
|
@hookimpl
|
||||||
|
def register_operator_choices():
|
||||||
|
return [
|
||||||
|
("starts_with", "Text Starts With"),
|
||||||
|
("ends_with", "Text Ends With"),
|
||||||
|
]
|
||||||
|
|
||||||
|
@hookimpl
|
||||||
|
def register_field_choices():
|
||||||
|
return [
|
||||||
|
("meta_description", "Meta Description"),
|
||||||
|
("meta_keywords", "Meta Keywords"),
|
||||||
|
]
|
||||||
32
changedetectionio/conditions/pluggy_interface.py
Normal file
32
changedetectionio/conditions/pluggy_interface.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import pluggy
|
||||||
|
|
||||||
|
# Define `pluggy` hookspecs (Specifications for Plugins)
|
||||||
|
hookspec = pluggy.HookspecMarker("conditions")
|
||||||
|
hookimpl = pluggy.HookimplMarker("conditions")
|
||||||
|
|
||||||
|
|
||||||
|
class ConditionsSpec:
|
||||||
|
"""Hook specifications for extending JSON Logic conditions."""
|
||||||
|
|
||||||
|
@hookspec
|
||||||
|
def register_operators():
|
||||||
|
"""Return a dictionary of new JSON Logic operators."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@hookspec
|
||||||
|
def register_operator_choices():
|
||||||
|
"""Return a list of new operator choices."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@hookspec
|
||||||
|
def register_field_choices():
|
||||||
|
"""Return a list of new field choices."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# ✅ Set up `pluggy` Plugin Manager
|
||||||
|
plugin_manager = pluggy.PluginManager("conditions")
|
||||||
|
plugin_manager.add_hookspecs(ConditionsSpec)
|
||||||
|
|
||||||
|
# Discover installed plugins
|
||||||
|
plugin_manager.load_setuptools_entrypoints("conditions")
|
||||||
@@ -5,9 +5,6 @@ from wtforms.widgets.core import TimeInput
|
|||||||
|
|
||||||
from changedetectionio.strtobool import strtobool
|
from changedetectionio.strtobool import strtobool
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from wtforms import SelectField, StringField, SubmitField, FieldList, FormField
|
|
||||||
from wtforms.validators import DataRequired, URL
|
|
||||||
from flask_wtf.file import FileField
|
|
||||||
|
|
||||||
from wtforms import (
|
from wtforms import (
|
||||||
BooleanField,
|
BooleanField,
|
||||||
@@ -310,7 +307,6 @@ class ValidateAppRiseServers(object):
|
|||||||
import apprise
|
import apprise
|
||||||
apobj = apprise.Apprise()
|
apobj = apprise.Apprise()
|
||||||
# so that the custom endpoints are registered
|
# so that the custom endpoints are registered
|
||||||
from changedetectionio.apprise_plugin import apprise_custom_api_call_wrapper
|
|
||||||
for server_url in field.data:
|
for server_url in field.data:
|
||||||
url = server_url.strip()
|
url = server_url.strip()
|
||||||
if url.startswith("#"):
|
if url.startswith("#"):
|
||||||
@@ -516,7 +512,7 @@ class quickWatchForm(Form):
|
|||||||
|
|
||||||
# Condition Rule Form (for each rule row)
|
# Condition Rule Form (for each rule row)
|
||||||
class ConditionForm(FlaskForm):
|
class ConditionForm(FlaskForm):
|
||||||
from .conditions import operator_choices, field_choices
|
from changedetectionio.conditions import operator_choices, field_choices
|
||||||
|
|
||||||
operator = SelectField(
|
operator = SelectField(
|
||||||
"Operator",
|
"Operator",
|
||||||
|
|||||||
Reference in New Issue
Block a user