mirror of
https://gitlab.com/chicken-riders/RcGcDw.git
synced 2025-02-24 00:34:10 +00:00
Added #279, added priority number for hooks so they can be started in sequence, added condition for running a hook
This commit is contained in:
parent
afc503a285
commit
f870a53e82
|
@ -27,3 +27,21 @@ def example_pre_hook(context: Context, change: dict):
|
||||||
def example_post_hook(message: DiscordMessage, metadata: DiscordMessageMetadata, context: Context, change: dict):
|
def example_post_hook(message: DiscordMessage, metadata: DiscordMessageMetadata, context: Context, change: dict):
|
||||||
print("Our Discord message looks as follows: ")
|
print("Our Discord message looks as follows: ")
|
||||||
print(message)
|
print(message)
|
||||||
|
|
||||||
|
|
||||||
|
def verify_upload(context: Context, change: dict) -> bool:
|
||||||
|
return hasattr(context, "event") and context.event.startswith("upload")
|
||||||
|
|
||||||
|
|
||||||
|
@pre_hook(priority=105, condition=verify_upload)
|
||||||
|
def example_pre_hook_with_args(context: Context, change: dict):
|
||||||
|
print("I'm an upload! Also I'm using a fancy decorator!")
|
||||||
|
|
||||||
|
|
||||||
|
def never_register_this_one(settings):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@pre_hook(priority=2, register=never_register_this_one)
|
||||||
|
def example_pre_hook_that_will_never_register(context: Context, change: dict):
|
||||||
|
print("EVIL THINGS HAPPENING IN HERE MUHAHHAHAHHA")
|
|
@ -14,27 +14,53 @@
|
||||||
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import functools
|
||||||
|
from src.configloader import settings
|
||||||
|
from typing import Optional, Callable
|
||||||
import src.api.hooks
|
import src.api.hooks
|
||||||
|
|
||||||
logger = logging.getLogger("src.api.hook")
|
logger = logging.getLogger("src.api.hook")
|
||||||
|
|
||||||
def pre_hook(func):
|
|
||||||
|
def pre_hook(_func: Optional[Callable] = None, priority: int = 100, condition: Optional[Callable] = None, register: Optional[Callable] = None):
|
||||||
"""
|
"""
|
||||||
Decorator to register a pre hook and return a function
|
Decorator to register a pre hook and return a function
|
||||||
|
|
||||||
:return: func
|
:return: func
|
||||||
"""
|
"""
|
||||||
logger.info("{hook_name} has been registered as a pre hook.".format(hook_name=func.__name__))
|
def decorator_prehook(func):
|
||||||
src.api.hooks.pre_hooks.append(func)
|
if register is None or register(settings):
|
||||||
return func
|
logger.info("{hook_name} has been registered as a pre hook.".format(hook_name=func.__name__))
|
||||||
|
src.api.hooks.pre_hooks.append((func, priority, condition))
|
||||||
|
|
||||||
|
@functools.wraps(func)
|
||||||
|
def wrapper_prehook(*args, **kwargs):
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
return wrapper_prehook
|
||||||
|
|
||||||
|
if _func is None:
|
||||||
|
return decorator_prehook
|
||||||
|
else:
|
||||||
|
return decorator_prehook(_func)
|
||||||
|
|
||||||
|
|
||||||
def post_hook(func):
|
def post_hook(_func: Optional[Callable] = None, priority: int = 100, condition: Optional[Callable] = None, register: Optional[Callable] = None):
|
||||||
"""
|
"""
|
||||||
Decorator to register a post hook and return a function
|
Decorator to register a post hook and return a function
|
||||||
|
|
||||||
:return: func
|
:return: func
|
||||||
"""
|
"""
|
||||||
logger.info("{hook_name} has been registered as a post hook.".format(hook_name=func.__name__))
|
def decorator_posthook(func):
|
||||||
src.api.hooks.post_hooks.append(func)
|
if register is None or register(settings):
|
||||||
return func
|
logger.info("{hook_name} has been registered as a post hook.".format(hook_name=func.__name__))
|
||||||
|
src.api.hooks.post_hooks.append((func, priority, condition))
|
||||||
|
|
||||||
|
@functools.wraps(func)
|
||||||
|
def wrapper_posthook(*args, **kwargs):
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
return wrapper_posthook
|
||||||
|
|
||||||
|
if _func is None:
|
||||||
|
return decorator_posthook
|
||||||
|
else:
|
||||||
|
return decorator_posthook(_func)
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# Made just to avoid circular imports
|
# Made just to avoid circular imports
|
||||||
from typing import Callable, List, Dict
|
from typing import Callable, List, Dict, Tuple, Optional
|
||||||
from src.discord.message import DiscordMessage, DiscordMessageMetadata
|
from src.discord.message import DiscordMessage, DiscordMessageMetadata
|
||||||
from src.api.context import Context
|
from src.api.context import Context
|
||||||
|
|
||||||
formatter_hooks: Dict[str, Callable[[Context, dict], DiscordMessage]] = {}
|
formatter_hooks: Dict[str, Callable[[Context, dict], DiscordMessage]] = {}
|
||||||
pre_hooks: List[Callable[[Context, dict], None]] = []
|
pre_hooks: List[Tuple[Callable[[Context, dict], None], int, Optional[Callable[[Context, dict], bool]]]] = []
|
||||||
post_hooks: List[Callable[[DiscordMessage, DiscordMessageMetadata, Context, dict], None]] = []
|
post_hooks: List[Tuple[Callable[[DiscordMessage, DiscordMessageMetadata, Context, dict], None], int, Optional[Callable[[DiscordMessage, DiscordMessageMetadata, Context, dict], bool]]]] = []
|
19
src/misc.py
19
src/misc.py
|
@ -17,9 +17,11 @@
|
||||||
import base64
|
import base64
|
||||||
import json, logging, sys, re, platform
|
import json, logging, sys, re, platform
|
||||||
from html.parser import HTMLParser
|
from html.parser import HTMLParser
|
||||||
|
from typing import Callable, Tuple, List, Optional, Union
|
||||||
from urllib.parse import urlparse, urlunparse
|
from urllib.parse import urlparse, urlunparse
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
from api.context import Context
|
||||||
from src.argparser import command_args
|
from src.argparser import command_args
|
||||||
from src.configloader import settings
|
from src.configloader import settings
|
||||||
import src.api.util
|
import src.api.util
|
||||||
|
@ -314,13 +316,24 @@ def prepare_paths(path: str, dry=False):
|
||||||
prepare_paths(settings["wiki_url"])
|
prepare_paths(settings["wiki_url"])
|
||||||
|
|
||||||
|
|
||||||
def run_hooks(hooks, *arguments):
|
def run_hooks(hooks: Union[List[Tuple[Callable[[Context, dict], None], int, Optional[Callable]]], List[Tuple[Callable[[DiscordMessage, DiscordMessageMetadata, Context, dict], None], int, Optional[Callable]]]], *arguments):
|
||||||
for hook in hooks:
|
for hook in hooks:
|
||||||
|
if hook[2] is not None:
|
||||||
|
try:
|
||||||
|
if hook[2](*arguments) is False:
|
||||||
|
misc_logger.debug(f"Ignoring hook {hook[0].__name__} due to conditions not being met for execution")
|
||||||
|
continue
|
||||||
|
except:
|
||||||
|
if settings.get("error_tolerance", 1) > 0:
|
||||||
|
misc_logger.exception("On running a hook check function, ignoring hook")
|
||||||
|
else:
|
||||||
|
raise
|
||||||
try:
|
try:
|
||||||
hook(*arguments)
|
misc_logger.debug(f"Running {hook[0].__name__} hook")
|
||||||
|
hook[0](*arguments)
|
||||||
except:
|
except:
|
||||||
if settings.get("error_tolerance", 1) > 0:
|
if settings.get("error_tolerance", 1) > 0:
|
||||||
misc_logger.exception("On running a pre hook, ignoring pre-hook")
|
misc_logger.exception("On running a hook, ignoring hook")
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import operator
|
||||||
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
|
||||||
# RcGcDw is free software: you can redistribute it and/or modify
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
@ -25,7 +25,8 @@ import src.configloader
|
||||||
from src.migrations import *
|
from src.migrations import *
|
||||||
from collections import defaultdict, Counter, OrderedDict
|
from collections import defaultdict, Counter, OrderedDict
|
||||||
from src.argparser import command_args
|
from src.argparser import command_args
|
||||||
from typing import Optional
|
from typing import Optional, Callable, Tuple
|
||||||
|
from operator import itemgetter
|
||||||
import src.api.client
|
import src.api.client
|
||||||
from src.api.context import Context
|
from src.api.context import Context
|
||||||
from src.api.hooks import formatter_hooks, pre_hooks, post_hooks
|
from src.api.hooks import formatter_hooks, pre_hooks, post_hooks
|
||||||
|
@ -53,6 +54,12 @@ logger = logging.getLogger("rcgcdw")
|
||||||
logger.debug("Current settings: {settings}".format(settings=settings))
|
logger.debug("Current settings: {settings}".format(settings=settings))
|
||||||
|
|
||||||
|
|
||||||
|
def sort_hooks():
|
||||||
|
"""Sort hooks according to their priority, first are executed hooks that have higher priority then lower"""
|
||||||
|
pre_hooks.sort(key=operator.itemgetter(1), reverse=True)
|
||||||
|
post_hooks.sort(key=operator.itemgetter(1), reverse=True)
|
||||||
|
|
||||||
|
|
||||||
def load_extensions():
|
def load_extensions():
|
||||||
"""Loads all of the extensions, can be a local import because all we need is them to register"""
|
"""Loads all of the extensions, can be a local import because all we need is them to register"""
|
||||||
try:
|
try:
|
||||||
|
@ -309,6 +316,7 @@ def abuselog_processing(entry):
|
||||||
|
|
||||||
|
|
||||||
load_extensions()
|
load_extensions()
|
||||||
|
sort_hooks()
|
||||||
# Log in and download wiki information
|
# Log in and download wiki information
|
||||||
wiki = Wiki(rc_processor, abuselog_processing)
|
wiki = Wiki(rc_processor, abuselog_processing)
|
||||||
client = src.api.client.Client(formatter_hooks, wiki)
|
client = src.api.client.Client(formatter_hooks, wiki)
|
||||||
|
|
Loading…
Reference in a new issue