Passed
Push — main ( 57139e...393c8e )
by Douglas
04:05
created

pocketutils.misc.notifiers_utils   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 75
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 52
dl 0
loc 75
rs 10
c 0
b 0
f 0
wmc 15

8 Methods

Rating   Name   Duplication   Size   Complexity  
A Notifier.from_dict() 0 5 1
A Notifier.__repr__() 0 2 1
A Notifier.__post_init__() 0 5 3
A Notifier.__str__() 0 2 1
A Notifier.from_json_file() 0 5 1
B Notifier.notify() 0 11 6
A Notifier.services() 0 3 1
A Notifier.from_toml_file() 0 5 1
1
from __future__ import annotations
0 ignored issues
show
introduced by
Missing module docstring
Loading history...
2
3
import logging
4
from collections import Mapping
0 ignored issues
show
Bug introduced by
The name Mapping does not seem to exist in module collections.
Loading history...
5
from dataclasses import dataclass
6
from typing import AbstractSet, Any, Callable, Sequence, Union
7
8
from notifiers import notify
0 ignored issues
show
introduced by
Unable to import 'notifiers'
Loading history...
9
from notifiers.core import Response, get_notifier
0 ignored issues
show
introduced by
Unable to import 'notifiers.core'
Loading history...
10
11
from pocketutils.core import PathLike
0 ignored issues
show
Bug introduced by
The name core does not seem to exist in module pocketutils.
Loading history...
introduced by
Cannot import 'pocketutils.core' due to syntax error 'invalid syntax (<unknown>, line 134)'
Loading history...
12
from pocketutils.core.dot_dict import NestedDotDict
0 ignored issues
show
Bug introduced by
The name core does not seem to exist in module pocketutils.
Loading history...
13
from pocketutils.core.exceptions import XValueError
0 ignored issues
show
Bug introduced by
The name core does not seem to exist in module pocketutils.
Loading history...
14
15
logger = logging.getLogger("pocketutils")
16
17
18
@dataclass(frozen=True)
19
class Notifier:
20
    """
21
    A simple config for notifiers from a .json or .toml file.
22
    """
23
24
    __config: Mapping[str, Mapping[str, Union[int, str, bool]]]
25
    _warn: Union[bool, Callable[[Response], Any]] = True
26
27
    @property
28
    def services(self) -> AbstractSet[str]:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
29
        return self.__config.keys()
30
31
    @classmethod
32
    def from_json_file(
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
33
        cls, path: PathLike, *, warn: Union[bool, Callable[[Response], Any]] = True
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
34
    ) -> Notifier:
35
        return cls.from_dict(NestedDotDict.read_json(path), warn=warn)
36
37
    @classmethod
38
    def from_toml_file(
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
39
        cls, path: PathLike, *, warn: Union[bool, Callable[[Response], Any]] = True
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
40
    ) -> Notifier:
41
        return cls.from_dict(NestedDotDict.read_toml(path), warn=warn)
42
43
    @classmethod
44
    def from_dict(
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
45
        cls, dct: Sequence[Any], *, warn: Union[bool, Callable[[Response], Any]] = True
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
46
    ) -> Notifier:
47
        return Notifier({x["services"]: x["defaults"] for x in dct}, _warn=warn)
48
49
    def __post_init__(self):
50
        for k, v in self.__config.items():
0 ignored issues
show
Coding Style Naming introduced by
Variable name "v" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
51
            if "message" in v:
52
                raise XValueError(f"Do not include message in defaults")
0 ignored issues
show
introduced by
Using an f-string that does not have any interpolated variables
Loading history...
53
            get_notifier(provider_name=k, strict=True)  # test
54
55
    def notify(self, message: str) -> Mapping[str, Response]:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
56
        returns = {}
57
        for service, defaults in self.__config.items():
58
            r = notify(service, message=message, **defaults)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "r" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
59
            returns[service] = r
60
            if self._warn and not r.ok and not defaults.get("raise_on_errors", False):
61
                if callable(self._warn):
62
                    self._warn(r)
63
                else:
64
                    logger.error(f"Error ({r.status}) notifying via {service}: {r.errors}")
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
65
        return returns
66
67
    def __repr__(self):
68
        return f"{self.__class__.__name__}({', '.join(self.services)})"
69
70
    def __str__(self):
71
        return repr(self)
72
73
74
__all__ = ["Notifier"]
75