Use hook system for config_changed hook
This commit is contained in:
parent
6001640a8a
commit
3b53270ee3
@ -24,8 +24,6 @@ import typing
|
||||
from PyQt5.QtCore import QUrl
|
||||
|
||||
from qutebrowser.config import config
|
||||
# pylint: disable=unused-import
|
||||
from qutebrowser.config.config import change_filter
|
||||
|
||||
val = typing.cast('config.ConfigContainer', None)
|
||||
|
||||
|
@ -26,14 +26,31 @@ import typing
|
||||
from qutebrowser.extensions import loader
|
||||
|
||||
|
||||
def _add_module_info(func: typing.Callable) -> loader.ModuleInfo:
|
||||
"""Add module info to the given function."""
|
||||
module = importlib.import_module(func.__module__)
|
||||
return loader.add_module_info(module)
|
||||
|
||||
|
||||
class init: # noqa: N801,N806 pylint: disable=invalid-name
|
||||
|
||||
"""Decorator to mark a function to run when initializing."""
|
||||
|
||||
def __call__(self, func: typing.Callable) -> typing.Callable:
|
||||
module = importlib.import_module(func.__module__)
|
||||
info = loader.add_module_info(module)
|
||||
info = _add_module_info(func)
|
||||
if info.init_hook is not None:
|
||||
raise ValueError("init hook is already registered!")
|
||||
info.init_hook = func
|
||||
return func
|
||||
|
||||
|
||||
class config_changed:
|
||||
|
||||
"""Decorator to get notified about changed configs."""
|
||||
|
||||
def __init__(self, option_filter=None):
|
||||
self._filter = option_filter
|
||||
|
||||
def __call__(self, func: typing.Callable) -> typing.Callable:
|
||||
info = _add_module_info(func)
|
||||
info.config_changed_hooks.append((self._filter, func))
|
||||
|
@ -294,7 +294,6 @@ class HostBlocker:
|
||||
message.info("adblock: Read {} hosts from {} sources.".format(
|
||||
len(self._blocked_hosts), self._done_count))
|
||||
|
||||
@config.change_filter('content.host_blocking.lists')
|
||||
def update_files(self):
|
||||
"""Update files when the config changed."""
|
||||
if not config.val.content.host_blocking.lists:
|
||||
@ -337,6 +336,11 @@ def adblock_update():
|
||||
_host_blocker.adblock_update()
|
||||
|
||||
|
||||
@hook.config_changed('content.host_blocking.lists')
|
||||
def on_config_changed():
|
||||
_host_blocker.update_files()
|
||||
|
||||
|
||||
@hook.init()
|
||||
def init(context):
|
||||
global _host_blocker
|
||||
@ -344,6 +348,4 @@ def init(context):
|
||||
config_dir=context.config_dir,
|
||||
args=context.args)
|
||||
_host_blocker.read_hosts()
|
||||
|
||||
context.signals.config_changed.connect(_host_blocker.update_files)
|
||||
requests.register_filter(_host_blocker.filter_request)
|
||||
|
@ -86,7 +86,7 @@ class change_filter: # noqa: N801,N806 pylint: disable=invalid-name
|
||||
not configdata.is_valid_prefix(self._option)):
|
||||
raise configexc.NoOptionError(self._option)
|
||||
|
||||
def _check_match(self, option: typing.Optional[str]) -> bool:
|
||||
def check_match(self, option: typing.Optional[str]) -> bool:
|
||||
"""Check if the given option matches the filter."""
|
||||
if option is None:
|
||||
# Called directly, not from a config change event.
|
||||
@ -119,7 +119,7 @@ class change_filter: # noqa: N801,N806 pylint: disable=invalid-name
|
||||
@functools.wraps(func)
|
||||
def func_wrapper(option: str = None) -> typing.Any:
|
||||
"""Call the underlying function."""
|
||||
if self._check_match(option):
|
||||
if self.check_match(option):
|
||||
return func()
|
||||
return None
|
||||
return func_wrapper
|
||||
@ -128,7 +128,7 @@ class change_filter: # noqa: N801,N806 pylint: disable=invalid-name
|
||||
def meth_wrapper(wrapper_self: typing.Any,
|
||||
option: str = None) -> typing.Any:
|
||||
"""Call the underlying function."""
|
||||
if self._check_match(option):
|
||||
if self.check_match(option):
|
||||
return func(wrapper_self)
|
||||
return None
|
||||
return meth_wrapper
|
||||
|
@ -28,13 +28,17 @@ import pathlib
|
||||
|
||||
import attr
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, QObject
|
||||
from PyQt5.QtCore import pyqtSlot, QObject
|
||||
|
||||
from qutebrowser import components
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import log, standarddir, objreg
|
||||
|
||||
|
||||
# ModuleInfo objects for all loaded plugins
|
||||
_module_infos = []
|
||||
|
||||
|
||||
@attr.s
|
||||
class InitContext:
|
||||
|
||||
@ -43,14 +47,6 @@ class InitContext:
|
||||
data_dir = attr.ib() # type: pathlib.Path
|
||||
config_dir = attr.ib() # type: pathlib.Path
|
||||
args = attr.ib() # type: argparse.Namespace
|
||||
signals = attr.ib() # type: ExtensionSignals
|
||||
|
||||
|
||||
class ExtensionSignals(QObject):
|
||||
|
||||
"""Signals exposed to an extension."""
|
||||
|
||||
config_changed = pyqtSignal(str)
|
||||
|
||||
|
||||
@attr.s
|
||||
@ -61,7 +57,11 @@ class ModuleInfo:
|
||||
This gets used by qutebrowser.api.hook.
|
||||
"""
|
||||
|
||||
_ConfigChangedHooksType = typing.List[typing.Tuple[str, typing.Callable]]
|
||||
|
||||
init_hook = attr.ib(None) # type: typing.Optional[typing.Callable]
|
||||
config_changed_hooks = attr.ib(
|
||||
attr.Factory(list)) # type: _ConfigChangedHooksType
|
||||
|
||||
|
||||
@attr.s
|
||||
@ -72,12 +72,6 @@ class ExtensionInfo:
|
||||
name = attr.ib() # type: str
|
||||
|
||||
|
||||
# Global extension signals, shared between all extensions.
|
||||
# At some point we might want to make this per-extension, but then we'll need
|
||||
# to find out what to set as its Qt parent so it's kept alive.
|
||||
_extension_signals = ExtensionSignals()
|
||||
|
||||
|
||||
def add_module_info(module: types.ModuleType) -> ModuleInfo:
|
||||
"""Add ModuleInfo to a module (if not added yet)."""
|
||||
# pylint: disable=protected-access
|
||||
@ -138,8 +132,7 @@ def _get_init_context() -> InitContext:
|
||||
"""Get an InitContext object."""
|
||||
return InitContext(data_dir=pathlib.Path(standarddir.data()),
|
||||
config_dir=pathlib.Path(standarddir.config()),
|
||||
args=objreg.get('args'),
|
||||
signals=_extension_signals)
|
||||
args=objreg.get('args'))
|
||||
|
||||
|
||||
def _load_component(info: ExtensionInfo) -> types.ModuleType:
|
||||
@ -153,8 +146,21 @@ def _load_component(info: ExtensionInfo) -> types.ModuleType:
|
||||
.format(mod_info.init_hook.__name__))
|
||||
mod_info.init_hook(_get_init_context())
|
||||
|
||||
_module_infos.append(mod_info)
|
||||
|
||||
return mod
|
||||
|
||||
|
||||
@pyqtSlot(str)
|
||||
def _on_config_changed(changed_name: str) -> None:
|
||||
"""Call config_changed hooks if the config changed."""
|
||||
for mod_info in _module_infos:
|
||||
for option, hook in mod_info.config_changed_hooks:
|
||||
cfilter = config.change_filter(option)
|
||||
cfilter.validate()
|
||||
if cfilter.check_match(changed_name):
|
||||
hook()
|
||||
|
||||
|
||||
def init() -> None:
|
||||
config.instance.changed.connect(_extension_signals.config_changed)
|
||||
config.instance.changed.connect(_on_config_changed)
|
||||
|
Loading…
Reference in New Issue
Block a user