mirror of https://github.com/caronc/apprise
Merge pull request #97 from caronc/logging-customization
Added deprecate and trace logging directivespull/98/head
commit
5997f6d6c5
|
@ -24,8 +24,8 @@
|
||||||
# THE SOFTWARE.
|
# THE SOFTWARE.
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import os
|
||||||
import six
|
import six
|
||||||
import logging
|
|
||||||
from markdown import markdown
|
from markdown import markdown
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ from .common import NotifyFormat
|
||||||
from .utils import is_exclusive_match
|
from .utils import is_exclusive_match
|
||||||
from .utils import parse_list
|
from .utils import parse_list
|
||||||
from .utils import GET_SCHEMA_RE
|
from .utils import GET_SCHEMA_RE
|
||||||
|
from .logger import logger
|
||||||
|
|
||||||
from .AppriseAsset import AppriseAsset
|
from .AppriseAsset import AppriseAsset
|
||||||
from .AppriseConfig import AppriseConfig
|
from .AppriseConfig import AppriseConfig
|
||||||
|
@ -43,8 +44,6 @@ from .plugins.NotifyBase import NotifyBase
|
||||||
from . import plugins
|
from . import plugins
|
||||||
from . import __version__
|
from . import __version__
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class Apprise(object):
|
class Apprise(object):
|
||||||
"""
|
"""
|
||||||
|
@ -112,6 +111,10 @@ class Apprise(object):
|
||||||
# Build a list of tags to associate with the newly added notifications
|
# Build a list of tags to associate with the newly added notifications
|
||||||
results['tag'] = set(parse_list(tag))
|
results['tag'] = set(parse_list(tag))
|
||||||
|
|
||||||
|
logger.trace('URL {} unpacked as:{}{}'.format(
|
||||||
|
url, os.linesep, os.linesep.join(
|
||||||
|
['{}="{}"'.format(k, v) for k, v in results.items()])))
|
||||||
|
|
||||||
# Prepare our Asset Object
|
# Prepare our Asset Object
|
||||||
results['asset'] = \
|
results['asset'] = \
|
||||||
asset if isinstance(asset, AppriseAsset) else AppriseAsset()
|
asset if isinstance(asset, AppriseAsset) else AppriseAsset()
|
||||||
|
@ -122,6 +125,9 @@ class Apprise(object):
|
||||||
# URL information
|
# URL information
|
||||||
plugin = plugins.SCHEMA_MAP[results['schema']](**results)
|
plugin = plugins.SCHEMA_MAP[results['schema']](**results)
|
||||||
|
|
||||||
|
# Create log entry of loaded URL
|
||||||
|
logger.debug('Loaded URL: {}'.format(plugin.url()))
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
# the arguments are invalid or can not be used.
|
# the arguments are invalid or can not be used.
|
||||||
logger.error('Could not load URL: %s' % url)
|
logger.error('Could not load URL: %s' % url)
|
||||||
|
@ -163,7 +169,7 @@ class Apprise(object):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
elif not isinstance(servers, (tuple, set, list)):
|
elif not isinstance(servers, (tuple, set, list)):
|
||||||
logging.error(
|
logger.error(
|
||||||
"An invalid notification (type={}) was specified.".format(
|
"An invalid notification (type={}) was specified.".format(
|
||||||
type(servers)))
|
type(servers)))
|
||||||
return False
|
return False
|
||||||
|
@ -176,7 +182,7 @@ class Apprise(object):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
elif not isinstance(_server, six.string_types):
|
elif not isinstance(_server, six.string_types):
|
||||||
logging.error(
|
logger.error(
|
||||||
"An invalid notification (type={}) was specified.".format(
|
"An invalid notification (type={}) was specified.".format(
|
||||||
type(_server)))
|
type(_server)))
|
||||||
return_status = False
|
return_status = False
|
||||||
|
@ -187,7 +193,7 @@ class Apprise(object):
|
||||||
instance = Apprise.instantiate(_server, asset=asset, tag=tag)
|
instance = Apprise.instantiate(_server, asset=asset, tag=tag)
|
||||||
if not isinstance(instance, NotifyBase):
|
if not isinstance(instance, NotifyBase):
|
||||||
return_status = False
|
return_status = False
|
||||||
logging.error(
|
logger.error(
|
||||||
"Failed to load notification url: {}".format(_server),
|
"Failed to load notification url: {}".format(_server),
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
@ -321,7 +327,7 @@ class Apprise(object):
|
||||||
except Exception:
|
except Exception:
|
||||||
# A catch all so we don't have to abort early
|
# A catch all so we don't have to abort early
|
||||||
# just because one of our plugins has a bug in it.
|
# just because one of our plugins has a bug in it.
|
||||||
logging.exception("Notification Exception")
|
logger.exception("Notification Exception")
|
||||||
status = False
|
status = False
|
||||||
|
|
||||||
return status
|
return status
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
# THE SOFTWARE.
|
# THE SOFTWARE.
|
||||||
|
|
||||||
import six
|
import six
|
||||||
import logging
|
|
||||||
|
|
||||||
from . import config
|
from . import config
|
||||||
from . import ConfigBase
|
from . import ConfigBase
|
||||||
|
@ -34,8 +33,7 @@ from .AppriseAsset import AppriseAsset
|
||||||
from .utils import GET_SCHEMA_RE
|
from .utils import GET_SCHEMA_RE
|
||||||
from .utils import parse_list
|
from .utils import parse_list
|
||||||
from .utils import is_exclusive_match
|
from .utils import is_exclusive_match
|
||||||
|
from .logger import logger
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class AppriseConfig(object):
|
class AppriseConfig(object):
|
||||||
|
@ -100,7 +98,7 @@ class AppriseConfig(object):
|
||||||
configs = (configs, )
|
configs = (configs, )
|
||||||
|
|
||||||
elif not isinstance(configs, (tuple, set, list)):
|
elif not isinstance(configs, (tuple, set, list)):
|
||||||
logging.error(
|
logger.error(
|
||||||
'An invalid configuration path (type={}) was '
|
'An invalid configuration path (type={}) was '
|
||||||
'specified.'.format(type(configs)))
|
'specified.'.format(type(configs)))
|
||||||
return False
|
return False
|
||||||
|
@ -114,7 +112,7 @@ class AppriseConfig(object):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
elif not isinstance(_config, six.string_types):
|
elif not isinstance(_config, six.string_types):
|
||||||
logging.warning(
|
logger.warning(
|
||||||
"An invalid configuration (type={}) was specified.".format(
|
"An invalid configuration (type={}) was specified.".format(
|
||||||
type(_config)))
|
type(_config)))
|
||||||
return_status = False
|
return_status = False
|
||||||
|
|
|
@ -35,15 +35,13 @@ from . import AppriseAsset
|
||||||
from . import AppriseConfig
|
from . import AppriseConfig
|
||||||
from .utils import parse_list
|
from .utils import parse_list
|
||||||
from .common import NOTIFY_TYPES
|
from .common import NOTIFY_TYPES
|
||||||
|
from .logger import logger
|
||||||
|
|
||||||
from . import __title__
|
from . import __title__
|
||||||
from . import __version__
|
from . import __version__
|
||||||
from . import __license__
|
from . import __license__
|
||||||
from . import __copywrite__
|
from . import __copywrite__
|
||||||
|
|
||||||
# Logging
|
|
||||||
logger = logging.getLogger('apprise')
|
|
||||||
|
|
||||||
# Defines our click context settings adding -h to the additional options that
|
# Defines our click context settings adding -h to the additional options that
|
||||||
# can be specified to get the help menu to come up
|
# can be specified to get the help menu to come up
|
||||||
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
|
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
|
||||||
|
@ -121,18 +119,28 @@ def main(body, title, config, urls, notification_type, theme, tag, verbose,
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
ch = logging.StreamHandler(sys.stdout)
|
ch = logging.StreamHandler(sys.stdout)
|
||||||
if verbose > 2:
|
if verbose > 3:
|
||||||
|
# -vvvv: Most Verbose Debug Logging
|
||||||
|
logger.setLevel(logging.TRACE)
|
||||||
|
|
||||||
|
elif verbose > 2:
|
||||||
|
# -vvv: Debug Logging
|
||||||
logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
elif verbose > 1:
|
elif verbose > 1:
|
||||||
|
# -vv: INFO Messages
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
elif verbose > 0:
|
elif verbose > 0:
|
||||||
|
# -v: WARNING Messages
|
||||||
logger.setLevel(logging.WARNING)
|
logger.setLevel(logging.WARNING)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
# No verbosity means we display ERRORS only AND any deprecation
|
||||||
|
# warnings
|
||||||
logger.setLevel(logging.ERROR)
|
logger.setLevel(logging.ERROR)
|
||||||
|
|
||||||
|
# Format our logger
|
||||||
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
|
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
|
||||||
ch.setFormatter(formatter)
|
ch.setFormatter(formatter)
|
||||||
logger.addHandler(ch)
|
logger.addHandler(ch)
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import six
|
import six
|
||||||
import logging
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from .. import plugins
|
from .. import plugins
|
||||||
|
@ -37,8 +36,6 @@ from ..common import CONFIG_FORMATS
|
||||||
from ..utils import GET_SCHEMA_RE
|
from ..utils import GET_SCHEMA_RE
|
||||||
from ..utils import parse_list
|
from ..utils import parse_list
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigBase(URLBase):
|
class ConfigBase(URLBase):
|
||||||
"""
|
"""
|
||||||
|
@ -61,9 +58,6 @@ class ConfigBase(URLBase):
|
||||||
# anything else. 128KB (131072B)
|
# anything else. 128KB (131072B)
|
||||||
max_buffer_size = 131072
|
max_buffer_size = 131072
|
||||||
|
|
||||||
# Logging
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
Initialize some general logging and common server arguments that will
|
Initialize some general logging and common server arguments that will
|
||||||
|
@ -128,6 +122,13 @@ class ConfigBase(URLBase):
|
||||||
# Execute our config parse function which always returns a list
|
# Execute our config parse function which always returns a list
|
||||||
self._cached_servers.extend(fn(content=content, asset=asset))
|
self._cached_servers.extend(fn(content=content, asset=asset))
|
||||||
|
|
||||||
|
if len(self._cached_servers):
|
||||||
|
self.logger.info('Loaded {} entries from {}'.format(
|
||||||
|
len(self._cached_servers), self.url()))
|
||||||
|
else:
|
||||||
|
self.logger.warning('Failed to load configuration from {}'.format(
|
||||||
|
self.url()))
|
||||||
|
|
||||||
return self._cached_servers
|
return self._cached_servers
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
|
@ -216,7 +217,7 @@ class ConfigBase(URLBase):
|
||||||
|
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# content was not expected string type
|
# content was not expected string type
|
||||||
logger.error('Invalid apprise text data specified')
|
ConfigBase.logger.error('Invalid apprise text data specified')
|
||||||
return list()
|
return list()
|
||||||
|
|
||||||
for entry in content:
|
for entry in content:
|
||||||
|
@ -226,7 +227,7 @@ class ConfigBase(URLBase):
|
||||||
result = valid_line_re.match(entry)
|
result = valid_line_re.match(entry)
|
||||||
if not result:
|
if not result:
|
||||||
# Invalid syntax
|
# Invalid syntax
|
||||||
logger.error(
|
ConfigBase.logger.error(
|
||||||
'Invalid apprise text format found '
|
'Invalid apprise text format found '
|
||||||
'{} on line {}.'.format(entry, line))
|
'{} on line {}.'.format(entry, line))
|
||||||
|
|
||||||
|
@ -255,7 +256,7 @@ class ConfigBase(URLBase):
|
||||||
|
|
||||||
# Some basic validation
|
# Some basic validation
|
||||||
if schema not in plugins.SCHEMA_MAP:
|
if schema not in plugins.SCHEMA_MAP:
|
||||||
logger.warning(
|
ConfigBase.logger.warning(
|
||||||
'Unsupported schema {} on line {}.'.format(
|
'Unsupported schema {} on line {}.'.format(
|
||||||
schema, line))
|
schema, line))
|
||||||
continue
|
continue
|
||||||
|
@ -266,7 +267,7 @@ class ConfigBase(URLBase):
|
||||||
|
|
||||||
if results is None:
|
if results is None:
|
||||||
# Failed to parse the server URL
|
# Failed to parse the server URL
|
||||||
logger.warning(
|
ConfigBase.logger.warning(
|
||||||
'Unparseable URL {} on line {}.'.format(url, line))
|
'Unparseable URL {} on line {}.'.format(url, line))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -274,6 +275,11 @@ class ConfigBase(URLBase):
|
||||||
# notifications if any were set
|
# notifications if any were set
|
||||||
results['tag'] = set(parse_list(result.group('tags')))
|
results['tag'] = set(parse_list(result.group('tags')))
|
||||||
|
|
||||||
|
ConfigBase.logger.trace(
|
||||||
|
'URL {} unpacked as:{}{}'.format(
|
||||||
|
url, os.linesep, os.linesep.join(
|
||||||
|
['{}="{}"'.format(k, v) for k, v in results.items()])))
|
||||||
|
|
||||||
# Prepare our Asset Object
|
# Prepare our Asset Object
|
||||||
results['asset'] = \
|
results['asset'] = \
|
||||||
asset if isinstance(asset, AppriseAsset) else AppriseAsset()
|
asset if isinstance(asset, AppriseAsset) else AppriseAsset()
|
||||||
|
@ -283,9 +289,12 @@ class ConfigBase(URLBase):
|
||||||
# parsed URL information
|
# parsed URL information
|
||||||
plugin = plugins.SCHEMA_MAP[results['schema']](**results)
|
plugin = plugins.SCHEMA_MAP[results['schema']](**results)
|
||||||
|
|
||||||
|
# Create log entry of loaded URL
|
||||||
|
ConfigBase.logger.debug('Loaded URL: {}'.format(plugin.url()))
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
# the arguments are invalid or can not be used.
|
# the arguments are invalid or can not be used.
|
||||||
logger.warning(
|
ConfigBase.logger.warning(
|
||||||
'Could not load URL {} on line {}.'.format(
|
'Could not load URL {} on line {}.'.format(
|
||||||
url, line))
|
url, line))
|
||||||
continue
|
continue
|
||||||
|
@ -314,20 +323,22 @@ class ConfigBase(URLBase):
|
||||||
|
|
||||||
except (AttributeError, yaml.error.MarkedYAMLError) as e:
|
except (AttributeError, yaml.error.MarkedYAMLError) as e:
|
||||||
# Invalid content
|
# Invalid content
|
||||||
logger.error('Invalid apprise yaml data specified.')
|
ConfigBase.logger.error(
|
||||||
logger.debug('YAML Exception:{}{}'.format(os.linesep, e))
|
'Invalid apprise yaml data specified.')
|
||||||
|
ConfigBase.logger.debug(
|
||||||
|
'YAML Exception:{}{}'.format(os.linesep, e))
|
||||||
return list()
|
return list()
|
||||||
|
|
||||||
if not isinstance(result, dict):
|
if not isinstance(result, dict):
|
||||||
# Invalid content
|
# Invalid content
|
||||||
logger.error('Invalid apprise yaml structure specified')
|
ConfigBase.logger.error('Invalid apprise yaml structure specified')
|
||||||
return list()
|
return list()
|
||||||
|
|
||||||
# YAML Version
|
# YAML Version
|
||||||
version = result.get('version', 1)
|
version = result.get('version', 1)
|
||||||
if version != 1:
|
if version != 1:
|
||||||
# Invalid syntax
|
# Invalid syntax
|
||||||
logger.error(
|
ConfigBase.logger.error(
|
||||||
'Invalid apprise yaml version specified {}.'.format(version))
|
'Invalid apprise yaml version specified {}.'.format(version))
|
||||||
return list()
|
return list()
|
||||||
|
|
||||||
|
@ -342,13 +353,15 @@ class ConfigBase(URLBase):
|
||||||
if k.startswith('_') or k.endswith('_'):
|
if k.startswith('_') or k.endswith('_'):
|
||||||
# Entries are considered reserved if they start or end
|
# Entries are considered reserved if they start or end
|
||||||
# with an underscore
|
# with an underscore
|
||||||
logger.warning('Ignored asset key "{}".'.format(k))
|
ConfigBase.logger.warning(
|
||||||
|
'Ignored asset key "{}".'.format(k))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not (hasattr(asset, k) and
|
if not (hasattr(asset, k) and
|
||||||
isinstance(getattr(asset, k), six.string_types)):
|
isinstance(getattr(asset, k), six.string_types)):
|
||||||
# We can't set a function or non-string set value
|
# We can't set a function or non-string set value
|
||||||
logger.warning('Invalid asset key "{}".'.format(k))
|
ConfigBase.logger.warning(
|
||||||
|
'Invalid asset key "{}".'.format(k))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if v is None:
|
if v is None:
|
||||||
|
@ -357,7 +370,8 @@ class ConfigBase(URLBase):
|
||||||
|
|
||||||
if not isinstance(v, six.string_types):
|
if not isinstance(v, six.string_types):
|
||||||
# we must set strings with a string
|
# we must set strings with a string
|
||||||
logger.warning('Invalid asset value to "{}".'.format(k))
|
ConfigBase.logger.warning(
|
||||||
|
'Invalid asset value to "{}".'.format(k))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Set our asset object with the new value
|
# Set our asset object with the new value
|
||||||
|
@ -379,7 +393,8 @@ class ConfigBase(URLBase):
|
||||||
urls = result.get('urls', None)
|
urls = result.get('urls', None)
|
||||||
if not isinstance(urls, (list, tuple)):
|
if not isinstance(urls, (list, tuple)):
|
||||||
# Unsupported
|
# Unsupported
|
||||||
logger.error('Missing "urls" directive in apprise yaml.')
|
ConfigBase.logger.error(
|
||||||
|
'Missing "urls" directive in apprise yaml.')
|
||||||
return list()
|
return list()
|
||||||
|
|
||||||
# Iterate over each URL
|
# Iterate over each URL
|
||||||
|
@ -400,7 +415,7 @@ class ConfigBase(URLBase):
|
||||||
# interpretation of a URL geared for them
|
# interpretation of a URL geared for them
|
||||||
schema = GET_SCHEMA_RE.match(_url)
|
schema = GET_SCHEMA_RE.match(_url)
|
||||||
if schema is None:
|
if schema is None:
|
||||||
logger.warning(
|
ConfigBase.logger.warning(
|
||||||
'Unsupported schema in urls entry #{}'.format(no))
|
'Unsupported schema in urls entry #{}'.format(no))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -409,7 +424,7 @@ class ConfigBase(URLBase):
|
||||||
|
|
||||||
# Some basic validation
|
# Some basic validation
|
||||||
if schema not in plugins.SCHEMA_MAP:
|
if schema not in plugins.SCHEMA_MAP:
|
||||||
logger.warning(
|
ConfigBase.logger.warning(
|
||||||
'Unsupported schema {} in urls entry #{}'.format(
|
'Unsupported schema {} in urls entry #{}'.format(
|
||||||
schema, no))
|
schema, no))
|
||||||
continue
|
continue
|
||||||
|
@ -418,7 +433,7 @@ class ConfigBase(URLBase):
|
||||||
# containing all of the information parsed from our URL
|
# containing all of the information parsed from our URL
|
||||||
_results = plugins.SCHEMA_MAP[schema].parse_url(_url)
|
_results = plugins.SCHEMA_MAP[schema].parse_url(_url)
|
||||||
if _results is None:
|
if _results is None:
|
||||||
logger.warning(
|
ConfigBase.logger.warning(
|
||||||
'Unparseable {} based url; entry #{}'.format(
|
'Unparseable {} based url; entry #{}'.format(
|
||||||
schema, no))
|
schema, no))
|
||||||
continue
|
continue
|
||||||
|
@ -439,7 +454,7 @@ class ConfigBase(URLBase):
|
||||||
# Get our schema
|
# Get our schema
|
||||||
schema = GET_SCHEMA_RE.match(_url)
|
schema = GET_SCHEMA_RE.match(_url)
|
||||||
if schema is None:
|
if schema is None:
|
||||||
logger.warning(
|
ConfigBase.logger.warning(
|
||||||
'Unsupported schema in urls entry #{}'.format(no))
|
'Unsupported schema in urls entry #{}'.format(no))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -448,7 +463,7 @@ class ConfigBase(URLBase):
|
||||||
|
|
||||||
# Some basic validation
|
# Some basic validation
|
||||||
if schema not in plugins.SCHEMA_MAP:
|
if schema not in plugins.SCHEMA_MAP:
|
||||||
logger.warning(
|
ConfigBase.logger.warning(
|
||||||
'Unsupported schema {} in urls entry #{}'.format(
|
'Unsupported schema {} in urls entry #{}'.format(
|
||||||
schema, no))
|
schema, no))
|
||||||
continue
|
continue
|
||||||
|
@ -494,7 +509,7 @@ class ConfigBase(URLBase):
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Unsupported
|
# Unsupported
|
||||||
logger.warning(
|
ConfigBase.logger.warning(
|
||||||
'Unsupported apprise yaml entry #{}'.format(no))
|
'Unsupported apprise yaml entry #{}'.format(no))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -519,6 +534,12 @@ class ConfigBase(URLBase):
|
||||||
# Just use the global settings
|
# Just use the global settings
|
||||||
_results['tag'] = global_tags
|
_results['tag'] = global_tags
|
||||||
|
|
||||||
|
ConfigBase.logger.trace(
|
||||||
|
'URL no.{} {} unpacked as:{}{}'
|
||||||
|
.format(os.linesep, no, url, os.linesep.join(
|
||||||
|
['{}="{}"'.format(k, a)
|
||||||
|
for k, a in _results.items()])))
|
||||||
|
|
||||||
# Prepare our Asset Object
|
# Prepare our Asset Object
|
||||||
_results['asset'] = asset
|
_results['asset'] = asset
|
||||||
|
|
||||||
|
@ -527,9 +548,13 @@ class ConfigBase(URLBase):
|
||||||
# parsed URL information
|
# parsed URL information
|
||||||
plugin = plugins.SCHEMA_MAP[_results['schema']](**_results)
|
plugin = plugins.SCHEMA_MAP[_results['schema']](**_results)
|
||||||
|
|
||||||
|
# Create log entry of loaded URL
|
||||||
|
ConfigBase.logger.debug(
|
||||||
|
'Loaded URL: {}'.format(plugin.url()))
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
# the arguments are invalid or can not be used.
|
# the arguments are invalid or can not be used.
|
||||||
logger.warning(
|
ConfigBase.logger.warning(
|
||||||
'Could not load apprise yaml entry #{}, item #{}'
|
'Could not load apprise yaml entry #{}, item #{}'
|
||||||
.format(no, entry))
|
.format(no, entry))
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -138,8 +138,6 @@ class ConfigFile(ConfigBase):
|
||||||
# YAML Filename Detected
|
# YAML Filename Detected
|
||||||
self.default_config_format = ConfigFormat.YAML
|
self.default_config_format = ConfigFormat.YAML
|
||||||
|
|
||||||
self.logger.debug('Succesfully read config file: %s' % (path))
|
|
||||||
|
|
||||||
# Return our response object
|
# Return our response object
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
|
@ -76,11 +76,7 @@ class ConfigHTTP(ConfigBase):
|
||||||
"""
|
"""
|
||||||
super(ConfigHTTP, self).__init__(**kwargs)
|
super(ConfigHTTP, self).__init__(**kwargs)
|
||||||
|
|
||||||
if self.secure:
|
self.schema = 'https' if self.secure else 'http'
|
||||||
self.schema = 'https'
|
|
||||||
|
|
||||||
else:
|
|
||||||
self.schema = 'http'
|
|
||||||
|
|
||||||
self.fullpath = kwargs.get('fullpath')
|
self.fullpath = kwargs.get('fullpath')
|
||||||
if not isinstance(self.fullpath, six.string_types):
|
if not isinstance(self.fullpath, six.string_types):
|
||||||
|
@ -242,9 +238,6 @@ class ConfigHTTP(ConfigBase):
|
||||||
# TEXT data detected based on header content
|
# TEXT data detected based on header content
|
||||||
self.default_config_format = ConfigFormat.TEXT
|
self.default_config_format = ConfigFormat.TEXT
|
||||||
|
|
||||||
# else do nothing; fall back to whatever default is
|
|
||||||
# already set.
|
|
||||||
|
|
||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
self.logger.error(
|
self.logger.error(
|
||||||
'A Connection error occured retrieving HTTP '
|
'A Connection error occured retrieving HTTP '
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This code is licensed under the MIT License.
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files(the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions :
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# Define a verbosity level that is a noisier then debug mode
|
||||||
|
logging.TRACE = logging.DEBUG - 1
|
||||||
|
|
||||||
|
# Define a verbosity level that is always used even when no verbosity is set
|
||||||
|
# from the command line. The idea here is to allow for deprecation notices
|
||||||
|
logging.DEPRECATE = logging.ERROR + 1
|
||||||
|
|
||||||
|
# Assign our Levels into our logging object
|
||||||
|
logging.addLevelName(logging.DEPRECATE, "DEPRECATION WARNING")
|
||||||
|
logging.addLevelName(logging.TRACE, "TRACE")
|
||||||
|
|
||||||
|
|
||||||
|
def trace(self, message, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Verbose Debug Logging - Trace
|
||||||
|
"""
|
||||||
|
if self.isEnabledFor(logging.TRACE):
|
||||||
|
self._log(logging.TRACE, message, args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def deprecate(self, message, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Deprication Warning Logging
|
||||||
|
"""
|
||||||
|
if self.isEnabledFor(logging.DEPRECATE):
|
||||||
|
self._log(logging.DEPRECATE, message, args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
# Assign our Loggers for use in Apprise
|
||||||
|
logging.Logger.trace = trace
|
||||||
|
logging.Logger.deprecate = deprecate
|
||||||
|
|
||||||
|
# Create ourselve a generic logging reference
|
||||||
|
logger = logging.getLogger('apprise')
|
|
@ -321,9 +321,9 @@ class NotifyDiscord(NotifyBase):
|
||||||
# Use Thumbnail
|
# Use Thumbnail
|
||||||
if 'thumbnail' in results['qsd']:
|
if 'thumbnail' in results['qsd']:
|
||||||
# Deprication Notice issued for v0.7.5
|
# Deprication Notice issued for v0.7.5
|
||||||
NotifyDiscord.logger.warning(
|
NotifyDiscord.logger.deprecate(
|
||||||
'DEPRICATION NOTICE - The Discord URL contains the parameter '
|
'The Discord URL contains the parameter '
|
||||||
'"thumbnail=" which will be depricated in an upcoming '
|
'"thumbnail=" which will be deprecated in an upcoming '
|
||||||
'release. Please use "image=" instead.'
|
'release. Please use "image=" instead.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ __all__ = [
|
||||||
'GrowlNotifier'
|
'GrowlNotifier'
|
||||||
]
|
]
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger('gntp')
|
||||||
|
|
||||||
|
|
||||||
class GrowlNotifier(notifier.GrowlNotifier):
|
class GrowlNotifier(notifier.GrowlNotifier):
|
||||||
|
|
|
@ -27,7 +27,7 @@ __all__ = [
|
||||||
'GrowlNotifier',
|
'GrowlNotifier',
|
||||||
]
|
]
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger('gntp')
|
||||||
|
|
||||||
|
|
||||||
class GrowlNotifier(object):
|
class GrowlNotifier(object):
|
||||||
|
|
|
@ -928,9 +928,9 @@ class NotifyMatrix(NotifyBase):
|
||||||
# Thumbnail (old way)
|
# Thumbnail (old way)
|
||||||
if 'thumbnail' in results['qsd']:
|
if 'thumbnail' in results['qsd']:
|
||||||
# Deprication Notice issued for v0.7.5
|
# Deprication Notice issued for v0.7.5
|
||||||
NotifyMatrix.logger.warning(
|
NotifyMatrix.logger.deprecate(
|
||||||
'DEPRICATION NOTICE - The Matrix URL contains the parameter '
|
'The Matrix URL contains the parameter '
|
||||||
'"thumbnail=" which will be depricated in an upcoming '
|
'"thumbnail=" which will be deprecated in an upcoming '
|
||||||
'release. Please use "image=" instead.'
|
'release. Please use "image=" instead.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -943,9 +943,9 @@ class NotifyMatrix(NotifyBase):
|
||||||
# Webhook (old way)
|
# Webhook (old way)
|
||||||
if 'webhook' in results['qsd']:
|
if 'webhook' in results['qsd']:
|
||||||
# Deprication Notice issued for v0.7.5
|
# Deprication Notice issued for v0.7.5
|
||||||
NotifyMatrix.logger.warning(
|
NotifyMatrix.logger.deprecate(
|
||||||
'DEPRICATION NOTICE - The Matrix URL contains the parameter '
|
'The Matrix URL contains the parameter '
|
||||||
'"webhook=" which will be depricated in an upcoming '
|
'"webhook=" which will be deprecated in an upcoming '
|
||||||
'release. Please use "mode=" instead.'
|
'release. Please use "mode=" instead.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -293,9 +293,9 @@ class NotifyRyver(NotifyBase):
|
||||||
|
|
||||||
if 'webhook' in results['qsd']:
|
if 'webhook' in results['qsd']:
|
||||||
# Deprication Notice issued for v0.7.5
|
# Deprication Notice issued for v0.7.5
|
||||||
NotifyRyver.logger.warning(
|
NotifyRyver.logger.deprecate(
|
||||||
'DEPRICATION NOTICE - The Ryver URL contains the parameter '
|
'The Ryver URL contains the parameter '
|
||||||
'"webhook=" which will be depricated in an upcoming '
|
'"webhook=" which will be deprecated in an upcoming '
|
||||||
'release. Please use "mode=" instead.'
|
'release. Please use "mode=" instead.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,6 @@ except ImportError:
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
import logging
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
# URL Indexing Table for returns via parse_url()
|
# URL Indexing Table for returns via parse_url()
|
||||||
VALID_URL_RE = re.compile(
|
VALID_URL_RE = re.compile(
|
||||||
r'^[\s]*(?P<schema>[^:\s]+):[/\\]*(?P<path>[^?]+)'
|
r'^[\s]*(?P<schema>[^:\s]+):[/\\]*(?P<path>[^?]+)'
|
||||||
|
|
|
@ -143,11 +143,19 @@ def test_apprise():
|
||||||
# We fail whenever we're initialized
|
# We fail whenever we're initialized
|
||||||
raise TypeError()
|
raise TypeError()
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# Support URL
|
||||||
|
return ''
|
||||||
|
|
||||||
class GoodNotification(NotifyBase):
|
class GoodNotification(NotifyBase):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(GoodNotification, self).__init__(
|
super(GoodNotification, self).__init__(
|
||||||
notify_format=NotifyFormat.HTML, **kwargs)
|
notify_format=NotifyFormat.HTML, **kwargs)
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# Support URL
|
||||||
|
return ''
|
||||||
|
|
||||||
def notify(self, **kwargs):
|
def notify(self, **kwargs):
|
||||||
# Pretend everything is okay
|
# Pretend everything is okay
|
||||||
return True
|
return True
|
||||||
|
@ -190,17 +198,29 @@ def test_apprise():
|
||||||
# Pretend everything is okay
|
# Pretend everything is okay
|
||||||
raise TypeError()
|
raise TypeError()
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# Support URL
|
||||||
|
return ''
|
||||||
|
|
||||||
class RuntimeNotification(NotifyBase):
|
class RuntimeNotification(NotifyBase):
|
||||||
def notify(self, **kwargs):
|
def notify(self, **kwargs):
|
||||||
# Pretend everything is okay
|
# Pretend everything is okay
|
||||||
raise RuntimeError()
|
raise RuntimeError()
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# Support URL
|
||||||
|
return ''
|
||||||
|
|
||||||
class FailNotification(NotifyBase):
|
class FailNotification(NotifyBase):
|
||||||
|
|
||||||
def notify(self, **kwargs):
|
def notify(self, **kwargs):
|
||||||
# Pretend everything is okay
|
# Pretend everything is okay
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# Support URL
|
||||||
|
return ''
|
||||||
|
|
||||||
# Store our bad notification in our schema map
|
# Store our bad notification in our schema map
|
||||||
SCHEMA_MAP['throw'] = ThrowNotification
|
SCHEMA_MAP['throw'] = ThrowNotification
|
||||||
|
|
||||||
|
@ -224,6 +244,11 @@ def test_apprise():
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
# Pretend everything is okay
|
# Pretend everything is okay
|
||||||
raise TypeError()
|
raise TypeError()
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# Support URL
|
||||||
|
return ''
|
||||||
|
|
||||||
SCHEMA_MAP['throw'] = ThrowInstantiateNotification
|
SCHEMA_MAP['throw'] = ThrowInstantiateNotification
|
||||||
|
|
||||||
# Reset our object
|
# Reset our object
|
||||||
|
@ -394,6 +419,10 @@ def test_apprise_notify_formats(tmpdir):
|
||||||
# Pretend everything is okay
|
# Pretend everything is okay
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# Support URL
|
||||||
|
return ''
|
||||||
|
|
||||||
class HtmlNotification(NotifyBase):
|
class HtmlNotification(NotifyBase):
|
||||||
|
|
||||||
# set our default notification format
|
# set our default notification format
|
||||||
|
@ -406,6 +435,10 @@ def test_apprise_notify_formats(tmpdir):
|
||||||
# Pretend everything is okay
|
# Pretend everything is okay
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# Support URL
|
||||||
|
return ''
|
||||||
|
|
||||||
class MarkDownNotification(NotifyBase):
|
class MarkDownNotification(NotifyBase):
|
||||||
|
|
||||||
# set our default notification format
|
# set our default notification format
|
||||||
|
@ -418,6 +451,10 @@ def test_apprise_notify_formats(tmpdir):
|
||||||
# Pretend everything is okay
|
# Pretend everything is okay
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# Support URL
|
||||||
|
return ''
|
||||||
|
|
||||||
# Store our notifications into our schema map
|
# Store our notifications into our schema map
|
||||||
SCHEMA_MAP['text'] = TextNotification
|
SCHEMA_MAP['text'] = TextNotification
|
||||||
SCHEMA_MAP['html'] = HtmlNotification
|
SCHEMA_MAP['html'] = HtmlNotification
|
||||||
|
|
|
@ -234,6 +234,10 @@ def test_apprise_multi_config_entries(tmpdir):
|
||||||
# Pretend everything is okay
|
# Pretend everything is okay
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# support url()
|
||||||
|
return ''
|
||||||
|
|
||||||
# Store our good notification in our schema map
|
# Store our good notification in our schema map
|
||||||
NOTIFY_SCHEMA_MAP['good'] = GoodNotification
|
NOTIFY_SCHEMA_MAP['good'] = GoodNotification
|
||||||
|
|
||||||
|
@ -357,6 +361,10 @@ def test_apprise_config_with_apprise_obj(tmpdir):
|
||||||
# Pretend everything is okay
|
# Pretend everything is okay
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# support url()
|
||||||
|
return ''
|
||||||
|
|
||||||
# Store our good notification in our schema map
|
# Store our good notification in our schema map
|
||||||
NOTIFY_SCHEMA_MAP['good'] = GoodNotification
|
NOTIFY_SCHEMA_MAP['good'] = GoodNotification
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,10 @@ def test_apprise_cli(tmpdir):
|
||||||
# Pretend everything is okay
|
# Pretend everything is okay
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# Support url()
|
||||||
|
return ''
|
||||||
|
|
||||||
class BadNotification(NotifyBase):
|
class BadNotification(NotifyBase):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(BadNotification, self).__init__(*args, **kwargs)
|
super(BadNotification, self).__init__(*args, **kwargs)
|
||||||
|
@ -56,6 +60,10 @@ def test_apprise_cli(tmpdir):
|
||||||
# Pretend everything is okay
|
# Pretend everything is okay
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# Support url()
|
||||||
|
return ''
|
||||||
|
|
||||||
# Set up our notification types
|
# Set up our notification types
|
||||||
SCHEMA_MAP['good'] = GoodNotification
|
SCHEMA_MAP['good'] = GoodNotification
|
||||||
SCHEMA_MAP['bad'] = BadNotification
|
SCHEMA_MAP['bad'] = BadNotification
|
||||||
|
|
|
@ -68,6 +68,10 @@ def test_config_http(mock_post, mock_get):
|
||||||
# Pretend everything is okay
|
# Pretend everything is okay
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def url(self):
|
||||||
|
# Support url() function
|
||||||
|
return ''
|
||||||
|
|
||||||
# Store our good notification in our schema map
|
# Store our good notification in our schema map
|
||||||
SCHEMA_MAP['good'] = GoodNotification
|
SCHEMA_MAP['good'] = GoodNotification
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This code is licensed under the MIT License.
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files(the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions :
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
|
||||||
|
from apprise import URLBase
|
||||||
|
|
||||||
|
# Disable logging for a cleaner testing output
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
def test_apprise_logger():
|
||||||
|
"""
|
||||||
|
API: Apprise() Logger
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Ensure we're not running in a disabled state
|
||||||
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
|
# Set our log level
|
||||||
|
URLBase.logger.setLevel(logging.DEPRECATE + 1)
|
||||||
|
|
||||||
|
# Deprication will definitely not trigger
|
||||||
|
URLBase.logger.deprecate('test')
|
||||||
|
|
||||||
|
# Verbose Debugging is not on at this point
|
||||||
|
URLBase.logger.trace('test')
|
||||||
|
|
||||||
|
# Set both logging entries on
|
||||||
|
URLBase.logger.setLevel(logging.TRACE)
|
||||||
|
|
||||||
|
# Deprication will definitely trigger
|
||||||
|
URLBase.logger.deprecate('test')
|
||||||
|
|
||||||
|
# Verbose Debugging will activate
|
||||||
|
URLBase.logger.trace('test')
|
Loading…
Reference in New Issue