mirror of
https://github.com/morpheus65535/bazarr.git
synced 2025-04-24 06:37:16 -04:00
Updated apprise module to improve notification system. #2163
This commit is contained in:
parent
0956d401bc
commit
07f601f407
122 changed files with 7156 additions and 2988 deletions
|
@ -1,28 +1,37 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import asyncio
|
||||
import concurrent.futures as cf
|
||||
import os
|
||||
from itertools import chain
|
||||
from . import common
|
||||
|
@ -43,11 +52,6 @@ from .plugins.NotifyBase import NotifyBase
|
|||
from . import plugins
|
||||
from . import __version__
|
||||
|
||||
# Python v3+ support code made importable, so it can remain backwards
|
||||
# compatible with Python v2
|
||||
# TODO: Review after dropping support for Python 2.
|
||||
from . import py3compat
|
||||
|
||||
|
||||
class Apprise:
|
||||
"""
|
||||
|
@ -369,91 +373,83 @@ class Apprise:
|
|||
such as turning a \n into an actual new line, etc.
|
||||
"""
|
||||
|
||||
return py3compat.asyncio.tosync(
|
||||
self.async_notify(
|
||||
try:
|
||||
# Process arguments and build synchronous and asynchronous calls
|
||||
# (this step can throw internal errors).
|
||||
sequential_calls, parallel_calls = self._create_notify_calls(
|
||||
body, title,
|
||||
notify_type=notify_type, body_format=body_format,
|
||||
tag=tag, match_always=match_always, attach=attach,
|
||||
interpret_escapes=interpret_escapes,
|
||||
),
|
||||
debug=self.debug
|
||||
)
|
||||
interpret_escapes=interpret_escapes
|
||||
)
|
||||
|
||||
def async_notify(self, *args, **kwargs):
|
||||
except TypeError:
|
||||
# No notifications sent, and there was an internal error.
|
||||
return False
|
||||
|
||||
if not sequential_calls and not parallel_calls:
|
||||
# Nothing to send
|
||||
return None
|
||||
|
||||
sequential_result = Apprise._notify_sequential(*sequential_calls)
|
||||
parallel_result = Apprise._notify_parallel_threadpool(*parallel_calls)
|
||||
return sequential_result and parallel_result
|
||||
|
||||
async def async_notify(self, *args, **kwargs):
|
||||
"""
|
||||
Send a notification to all the plugins previously loaded, for
|
||||
asynchronous callers. This method is an async method that should be
|
||||
awaited on, even if it is missing the async keyword in its signature.
|
||||
(This is omitted to preserve syntax compatibility with Python 2.)
|
||||
asynchronous callers.
|
||||
|
||||
The arguments are identical to those of Apprise.notify().
|
||||
|
||||
"""
|
||||
try:
|
||||
coroutines = list(
|
||||
self._notifyall(
|
||||
Apprise._notifyhandlerasync, *args, **kwargs))
|
||||
# Process arguments and build synchronous and asynchronous calls
|
||||
# (this step can throw internal errors).
|
||||
sequential_calls, parallel_calls = self._create_notify_calls(
|
||||
*args, **kwargs)
|
||||
|
||||
except TypeError:
|
||||
# No notifications sent, and there was an internal error.
|
||||
return py3compat.asyncio.toasyncwrapvalue(False)
|
||||
|
||||
else:
|
||||
if len(coroutines) > 0:
|
||||
# All notifications sent, return False if any failed.
|
||||
return py3compat.asyncio.notify(coroutines)
|
||||
|
||||
else:
|
||||
# No notifications sent.
|
||||
return py3compat.asyncio.toasyncwrapvalue(None)
|
||||
|
||||
@staticmethod
|
||||
def _notifyhandler(server, **kwargs):
|
||||
"""
|
||||
The synchronous notification sender. Returns True if the notification
|
||||
sent successfully.
|
||||
"""
|
||||
|
||||
try:
|
||||
# Send notification
|
||||
return server.notify(**kwargs)
|
||||
|
||||
except TypeError:
|
||||
# These our our internally thrown notifications
|
||||
return False
|
||||
|
||||
except Exception:
|
||||
# A catch all so we don't have to abort early
|
||||
# just because one of our plugins has a bug in it.
|
||||
logger.exception("Unhandled Notification Exception")
|
||||
return False
|
||||
if not sequential_calls and not parallel_calls:
|
||||
# Nothing to send
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _notifyhandlerasync(server, **kwargs):
|
||||
"""
|
||||
The asynchronous notification sender. Returns a coroutine that yields
|
||||
True if the notification sent successfully.
|
||||
"""
|
||||
sequential_result = Apprise._notify_sequential(*sequential_calls)
|
||||
parallel_result = \
|
||||
await Apprise._notify_parallel_asyncio(*parallel_calls)
|
||||
return sequential_result and parallel_result
|
||||
|
||||
if server.asset.async_mode:
|
||||
return server.async_notify(**kwargs)
|
||||
|
||||
else:
|
||||
# Send the notification immediately, and wrap the result in a
|
||||
# coroutine.
|
||||
status = Apprise._notifyhandler(server, **kwargs)
|
||||
return py3compat.asyncio.toasyncwrapvalue(status)
|
||||
|
||||
def _notifyall(self, handler, body, title='',
|
||||
notify_type=common.NotifyType.INFO, body_format=None,
|
||||
tag=common.MATCH_ALL_TAG, match_always=True, attach=None,
|
||||
interpret_escapes=None):
|
||||
def _create_notify_calls(self, *args, **kwargs):
|
||||
"""
|
||||
Creates notifications for all the plugins loaded.
|
||||
|
||||
Returns a generator that calls handler for each notification. The first
|
||||
and only argument supplied to handler is the server, and the keyword
|
||||
arguments are exactly as they would be passed to server.notify().
|
||||
Returns a list of (server, notify() kwargs) tuples for plugins with
|
||||
parallelism disabled and another list for plugins with parallelism
|
||||
enabled.
|
||||
"""
|
||||
|
||||
all_calls = list(self._create_notify_gen(*args, **kwargs))
|
||||
|
||||
# Split into sequential and parallel notify() calls.
|
||||
sequential, parallel = [], []
|
||||
for (server, notify_kwargs) in all_calls:
|
||||
if server.asset.async_mode:
|
||||
parallel.append((server, notify_kwargs))
|
||||
else:
|
||||
sequential.append((server, notify_kwargs))
|
||||
|
||||
return sequential, parallel
|
||||
|
||||
def _create_notify_gen(self, body, title='',
|
||||
notify_type=common.NotifyType.INFO,
|
||||
body_format=None, tag=common.MATCH_ALL_TAG,
|
||||
match_always=True, attach=None,
|
||||
interpret_escapes=None):
|
||||
"""
|
||||
Internal generator function for _create_notify_calls().
|
||||
"""
|
||||
|
||||
if len(self) == 0:
|
||||
|
@ -546,14 +542,121 @@ class Apprise:
|
|||
logger.error(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
yield handler(
|
||||
server,
|
||||
kwargs = dict(
|
||||
body=conversion_body_map[server.notify_format],
|
||||
title=conversion_title_map[server.notify_format],
|
||||
notify_type=notify_type,
|
||||
attach=attach,
|
||||
body_format=body_format,
|
||||
body_format=body_format
|
||||
)
|
||||
yield (server, kwargs)
|
||||
|
||||
@staticmethod
|
||||
def _notify_sequential(*servers_kwargs):
|
||||
"""
|
||||
Process a list of notify() calls sequentially and synchronously.
|
||||
"""
|
||||
|
||||
success = True
|
||||
|
||||
for (server, kwargs) in servers_kwargs:
|
||||
try:
|
||||
# Send notification
|
||||
result = server.notify(**kwargs)
|
||||
success = success and result
|
||||
|
||||
except TypeError:
|
||||
# These are our internally thrown notifications.
|
||||
success = False
|
||||
|
||||
except Exception:
|
||||
# A catch all so we don't have to abort early
|
||||
# just because one of our plugins has a bug in it.
|
||||
logger.exception("Unhandled Notification Exception")
|
||||
success = False
|
||||
|
||||
return success
|
||||
|
||||
@staticmethod
|
||||
def _notify_parallel_threadpool(*servers_kwargs):
|
||||
"""
|
||||
Process a list of notify() calls in parallel and synchronously.
|
||||
"""
|
||||
|
||||
n_calls = len(servers_kwargs)
|
||||
|
||||
# 0-length case
|
||||
if n_calls == 0:
|
||||
return True
|
||||
|
||||
# There's no need to use a thread pool for just a single notification
|
||||
if n_calls == 1:
|
||||
return Apprise._notify_sequential(servers_kwargs[0])
|
||||
|
||||
# Create log entry
|
||||
logger.info(
|
||||
'Notifying %d service(s) with threads.', len(servers_kwargs))
|
||||
|
||||
with cf.ThreadPoolExecutor() as executor:
|
||||
success = True
|
||||
futures = [executor.submit(server.notify, **kwargs)
|
||||
for (server, kwargs) in servers_kwargs]
|
||||
|
||||
for future in cf.as_completed(futures):
|
||||
try:
|
||||
result = future.result()
|
||||
success = success and result
|
||||
|
||||
except TypeError:
|
||||
# These are our internally thrown notifications.
|
||||
success = False
|
||||
|
||||
except Exception:
|
||||
# A catch all so we don't have to abort early
|
||||
# just because one of our plugins has a bug in it.
|
||||
logger.exception("Unhandled Notification Exception")
|
||||
success = False
|
||||
|
||||
return success
|
||||
|
||||
@staticmethod
|
||||
async def _notify_parallel_asyncio(*servers_kwargs):
|
||||
"""
|
||||
Process a list of async_notify() calls in parallel and asynchronously.
|
||||
"""
|
||||
|
||||
n_calls = len(servers_kwargs)
|
||||
|
||||
# 0-length case
|
||||
if n_calls == 0:
|
||||
return True
|
||||
|
||||
# (Unlike with the thread pool, we don't optimize for the single-
|
||||
# notification case because asyncio can do useful work while waiting
|
||||
# for that thread to complete)
|
||||
|
||||
# Create log entry
|
||||
logger.info(
|
||||
'Notifying %d service(s) asynchronously.', len(servers_kwargs))
|
||||
|
||||
async def do_call(server, kwargs):
|
||||
return await server.async_notify(**kwargs)
|
||||
|
||||
cors = (do_call(server, kwargs) for (server, kwargs) in servers_kwargs)
|
||||
results = await asyncio.gather(*cors, return_exceptions=True)
|
||||
|
||||
if any(isinstance(status, Exception)
|
||||
and not isinstance(status, TypeError) for status in results):
|
||||
# A catch all so we don't have to abort early just because
|
||||
# one of our plugins has a bug in it.
|
||||
logger.exception("Unhandled Notification Exception")
|
||||
return False
|
||||
|
||||
if any(isinstance(status, TypeError) for status in results):
|
||||
# These are our internally thrown notifications.
|
||||
return False
|
||||
|
||||
return all(results)
|
||||
|
||||
def details(self, lang=None, show_requirements=False, show_disabled=False):
|
||||
"""
|
||||
|
@ -581,6 +684,7 @@ class Apprise:
|
|||
'setup_url': getattr(plugin, 'setup_url', None),
|
||||
# Placeholder - populated below
|
||||
'details': None,
|
||||
|
||||
# Differentiat between what is a custom loaded plugin and
|
||||
# which is native.
|
||||
'category': getattr(plugin, 'category', None)
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
from uuid import uuid4
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from . import attachment
|
||||
from . import URLBase
|
||||
|
@ -170,6 +177,11 @@ class AppriseAttachment:
|
|||
return_status = False
|
||||
continue
|
||||
|
||||
elif isinstance(_attachment, AppriseAttachment):
|
||||
# We were provided a list of Apprise Attachments
|
||||
# append our content together
|
||||
instance = _attachment.attachments
|
||||
|
||||
elif not isinstance(_attachment, attachment.AttachBase):
|
||||
logger.warning(
|
||||
"An invalid attachment (type={}) was specified.".format(
|
||||
|
@ -196,7 +208,11 @@ class AppriseAttachment:
|
|||
continue
|
||||
|
||||
# Add our initialized plugin to our server listings
|
||||
self.attachments.append(instance)
|
||||
if isinstance(instance, list):
|
||||
self.attachments.extend(instance)
|
||||
|
||||
else:
|
||||
self.attachments.append(instance)
|
||||
|
||||
# Return our status
|
||||
return return_status
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from . import config
|
||||
from . import ConfigBase
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import ctypes
|
||||
import locale
|
||||
|
@ -67,7 +74,7 @@ class LazyTranslation:
|
|||
"""
|
||||
self.text = text
|
||||
|
||||
super(LazyTranslation, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
return gettext.gettext(self.text)
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
from .logger import logger
|
||||
|
@ -194,7 +201,7 @@ class URLBase:
|
|||
asset if isinstance(asset, AppriseAsset) else AppriseAsset()
|
||||
|
||||
# Certificate Verification (for SSL calls); default to being enabled
|
||||
self.verify_certificate = kwargs.get('verify', True)
|
||||
self.verify_certificate = parse_bool(kwargs.get('verify', True))
|
||||
|
||||
# Secure Mode
|
||||
self.secure = kwargs.get('secure', False)
|
||||
|
@ -222,24 +229,22 @@ class URLBase:
|
|||
self.password = URLBase.unquote(self.password)
|
||||
|
||||
# Store our Timeout Variables
|
||||
if 'socket_read_timeout' in kwargs:
|
||||
if 'rto' in kwargs:
|
||||
try:
|
||||
self.socket_read_timeout = \
|
||||
float(kwargs.get('socket_read_timeout'))
|
||||
self.socket_read_timeout = float(kwargs.get('rto'))
|
||||
except (TypeError, ValueError):
|
||||
self.logger.warning(
|
||||
'Invalid socket read timeout (rto) was specified {}'
|
||||
.format(kwargs.get('socket_read_timeout')))
|
||||
.format(kwargs.get('rto')))
|
||||
|
||||
if 'socket_connect_timeout' in kwargs:
|
||||
if 'cto' in kwargs:
|
||||
try:
|
||||
self.socket_connect_timeout = \
|
||||
float(kwargs.get('socket_connect_timeout'))
|
||||
self.socket_connect_timeout = float(kwargs.get('cto'))
|
||||
|
||||
except (TypeError, ValueError):
|
||||
self.logger.warning(
|
||||
'Invalid socket connect timeout (cto) was specified {}'
|
||||
.format(kwargs.get('socket_connect_timeout')))
|
||||
.format(kwargs.get('cto')))
|
||||
|
||||
if 'tag' in kwargs:
|
||||
# We want to associate some tags with our notification service.
|
||||
|
@ -598,7 +603,7 @@ class URLBase:
|
|||
}
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url, verify_host=True):
|
||||
def parse_url(url, verify_host=True, plus_to_space=False):
|
||||
"""Parses the URL and returns it broken apart into a dictionary.
|
||||
|
||||
This is very specific and customized for Apprise.
|
||||
|
@ -618,7 +623,8 @@ class URLBase:
|
|||
"""
|
||||
|
||||
results = parse_url(
|
||||
url, default_schema='unknown', verify_host=verify_host)
|
||||
url, default_schema='unknown', verify_host=verify_host,
|
||||
plus_to_space=plus_to_space)
|
||||
|
||||
if not results:
|
||||
# We're done; we failed to parse our url
|
||||
|
@ -646,11 +652,11 @@ class URLBase:
|
|||
|
||||
# Store our socket read timeout if specified
|
||||
if 'rto' in results['qsd']:
|
||||
results['socket_read_timeout'] = results['qsd']['rto']
|
||||
results['rto'] = results['qsd']['rto']
|
||||
|
||||
# Store our socket connect timeout if specified
|
||||
if 'cto' in results['qsd']:
|
||||
results['socket_connect_timeout'] = results['qsd']['cto']
|
||||
results['cto'] = results['qsd']['cto']
|
||||
|
||||
if 'port' in results['qsd']:
|
||||
results['port'] = results['qsd']['port']
|
||||
|
@ -679,6 +685,15 @@ class URLBase:
|
|||
|
||||
return response
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Should be over-ridden and allows the tracking of how many targets
|
||||
are associated with each URLBase object.
|
||||
|
||||
Default is always 1
|
||||
"""
|
||||
return 1
|
||||
|
||||
def schemas(self):
|
||||
"""A simple function that returns a set of all schemas associated
|
||||
with this object based on the object.protocol and
|
||||
|
|
|
@ -1,33 +1,40 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
__title__ = 'Apprise'
|
||||
__version__ = '1.1.0'
|
||||
__version__ = '1.4.0'
|
||||
__author__ = 'Chris Caron'
|
||||
__license__ = 'MIT'
|
||||
__copywrite__ = 'Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>'
|
||||
__license__ = 'BSD'
|
||||
__copywrite__ = 'Copyright (C) 2023 Chris Caron <lead2gold@gmail.com>'
|
||||
__email__ = 'lead2gold@gmail.com'
|
||||
__status__ = 'Production'
|
||||
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import time
|
||||
|
@ -120,7 +127,7 @@ class AttachBase(URLBase):
|
|||
should be considered expired.
|
||||
"""
|
||||
|
||||
super(AttachBase, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
if not mimetypes.inited:
|
||||
# Ensure mimetypes has been initialized
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import os
|
||||
|
@ -50,7 +57,7 @@ class AttachFile(AttachBase):
|
|||
Initialize Local File Attachment Object
|
||||
|
||||
"""
|
||||
super(AttachFile, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Store path but mark it dirty since we have not performed any
|
||||
# verification at this point.
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import os
|
||||
|
@ -61,7 +68,7 @@ class AttachHTTP(AttachBase):
|
|||
additionally include as part of the server headers to post with
|
||||
|
||||
"""
|
||||
super(AttachHTTP, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.schema = 'https' if self.secure else 'http'
|
||||
|
||||
|
@ -254,7 +261,7 @@ class AttachHTTP(AttachBase):
|
|||
self._temp_file.close()
|
||||
self._temp_file = None
|
||||
|
||||
super(AttachHTTP, self).invalidate()
|
||||
super().invalidate()
|
||||
|
||||
def url(self, privacy=False, *args, **kwargs):
|
||||
"""
|
||||
|
|
|
@ -1,30 +1,36 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
|
||||
from os import listdir
|
||||
from os.path import dirname
|
||||
from os.path import abspath
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# 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 :
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 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.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import click
|
||||
import logging
|
||||
|
@ -73,28 +80,64 @@ DEFAULT_CONFIG_PATHS = (
|
|||
'~/.apprise/apprise.yml',
|
||||
'~/.config/apprise/apprise',
|
||||
'~/.config/apprise/apprise.yml',
|
||||
|
||||
# Global Configuration Support
|
||||
'/etc/apprise',
|
||||
'/etc/apprise.yml',
|
||||
'/etc/apprise/apprise',
|
||||
'/etc/apprise/apprise.yml',
|
||||
)
|
||||
|
||||
# Define our paths to search for plugins
|
||||
DEFAULT_PLUGIN_PATHS = (
|
||||
'~/.apprise/plugins',
|
||||
'~/.config/apprise/plugins',
|
||||
|
||||
# Global Plugin Support
|
||||
'/var/lib/apprise/plugins',
|
||||
)
|
||||
|
||||
# Detect Windows
|
||||
if platform.system() == 'Windows':
|
||||
# Default Config Search Path for Windows Users
|
||||
DEFAULT_CONFIG_PATHS = (
|
||||
expandvars('%APPDATA%/Apprise/apprise'),
|
||||
expandvars('%APPDATA%/Apprise/apprise.yml'),
|
||||
expandvars('%LOCALAPPDATA%/Apprise/apprise'),
|
||||
expandvars('%LOCALAPPDATA%/Apprise/apprise.yml'),
|
||||
expandvars('%APPDATA%\\Apprise\\apprise'),
|
||||
expandvars('%APPDATA%\\Apprise\\apprise.yml'),
|
||||
expandvars('%LOCALAPPDATA%\\Apprise\\apprise'),
|
||||
expandvars('%LOCALAPPDATA%\\Apprise\\apprise.yml'),
|
||||
|
||||
#
|
||||
# Global Support
|
||||
#
|
||||
|
||||
# C:\ProgramData\Apprise\
|
||||
expandvars('%ALLUSERSPROFILE%\\Apprise\\apprise'),
|
||||
expandvars('%ALLUSERSPROFILE%\\Apprise\\apprise.yml'),
|
||||
|
||||
# C:\Program Files\Apprise
|
||||
expandvars('%PROGRAMFILES%\\Apprise\\apprise'),
|
||||
expandvars('%PROGRAMFILES%\\Apprise\\apprise.yml'),
|
||||
|
||||
# C:\Program Files\Common Files
|
||||
expandvars('%COMMONPROGRAMFILES%\\Apprise\\apprise'),
|
||||
expandvars('%COMMONPROGRAMFILES%\\Apprise\\apprise.yml'),
|
||||
)
|
||||
|
||||
# Default Plugin Search Path for Windows Users
|
||||
DEFAULT_PLUGIN_PATHS = (
|
||||
expandvars('%APPDATA%/Apprise/plugins'),
|
||||
expandvars('%LOCALAPPDATA%/Apprise/plugins'),
|
||||
expandvars('%APPDATA%\\Apprise\\plugins'),
|
||||
expandvars('%LOCALAPPDATA%\\Apprise\\plugins'),
|
||||
|
||||
#
|
||||
# Global Support
|
||||
#
|
||||
|
||||
# C:\ProgramData\Apprise\plugins
|
||||
expandvars('%ALLUSERSPROFILE%\\Apprise\\plugins'),
|
||||
# C:\Program Files\Apprise\plugins
|
||||
expandvars('%PROGRAMFILES%\\Apprise\\plugins'),
|
||||
# C:\Program Files\Common Files
|
||||
expandvars('%COMMONPROGRAMFILES%\\Apprise\\plugins'),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1,28 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# we mirror our base purely for the ability to reset everything; this
|
||||
# is generally only used in testing and should not be used by developers
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
import types
|
||||
import typing as t
|
||||
|
||||
|
||||
class NotifyType:
|
||||
INFO: NotifyType
|
||||
SUCCESS: NotifyType
|
||||
|
@ -12,4 +16,7 @@ class NotifyFormat:
|
|||
class ContentLocation:
|
||||
LOCAL: ContentLocation
|
||||
HOSTED: ContentLocation
|
||||
INACCESSIBLE: ContentLocation
|
||||
INACCESSIBLE: ContentLocation
|
||||
|
||||
|
||||
NOTIFY_MODULE_MAP: t.Dict[str, t.Dict[str, t.Union[t.Type["NotifyBase"], types.ModuleType]]]
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import re
|
||||
|
@ -113,7 +120,7 @@ class ConfigBase(URLBase):
|
|||
these 'include' entries to be honored, this value must be set to True.
|
||||
"""
|
||||
|
||||
super(ConfigBase, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Tracks the time the content was last retrieved on. This place a role
|
||||
# for cases where we are not caching our response and are required to
|
||||
|
@ -548,7 +555,7 @@ class ConfigBase(URLBase):
|
|||
# Define what a valid line should look like
|
||||
valid_line_re = re.compile(
|
||||
r'^\s*(?P<line>([;#]+(?P<comment>.*))|'
|
||||
r'(\s*(?P<tags>[^=]+)=|=)?\s*'
|
||||
r'(\s*(?P<tags>[a-z0-9, \t_-]+)\s*=|=)?\s*'
|
||||
r'(?P<url>[a-z0-9]{2,9}://.*)|'
|
||||
r'include\s+(?P<config>.+))?\s*$', re.I)
|
||||
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import os
|
||||
|
@ -53,7 +60,7 @@ class ConfigFile(ConfigBase):
|
|||
additionally include as part of the server headers to post with
|
||||
|
||||
"""
|
||||
super(ConfigFile, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Store our file path as it was set
|
||||
self.path = os.path.abspath(os.path.expanduser(path))
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import requests
|
||||
|
@ -75,7 +82,7 @@ class ConfigHTTP(ConfigBase):
|
|||
additionally include as part of the server headers to post with
|
||||
|
||||
"""
|
||||
super(ConfigHTTP, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.schema = 'https' if self.secure else 'http'
|
||||
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from .ConfigBase import ConfigBase
|
||||
from ..AppriseLocale import gettext_lazy as _
|
||||
|
@ -46,7 +53,7 @@ class ConfigMemory(ConfigBase):
|
|||
Memory objects just store the raw configuration in memory. There is
|
||||
no external reference point. It's always considered cached.
|
||||
"""
|
||||
super(ConfigMemory, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Store our raw config into memory
|
||||
self.content = content
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
from os import listdir
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
from markdown import markdown
|
||||
|
@ -99,7 +106,7 @@ class HTMLConverter(HTMLParser, object):
|
|||
BLOCK_END = {}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(HTMLConverter, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Shoudl we store the text content or not?
|
||||
self._do_store = True
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from ..plugins.NotifyBase import NotifyBase
|
||||
from ..utils import URL_DETAILS_RE
|
||||
from ..utils import parse_url
|
||||
|
@ -134,7 +142,7 @@ class CustomNotifyPlugin(NotifyBase):
|
|||
|
||||
"""
|
||||
# init parent
|
||||
super(CustomNotifyPluginWrapper, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self._default_args = {}
|
||||
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from .notify import notify
|
||||
|
||||
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from .CustomNotifyPlugin import CustomNotifyPlugin
|
||||
|
||||
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import logging
|
||||
|
@ -181,6 +188,7 @@ class LogCapture:
|
|||
if self.__path:
|
||||
# Close our file pointer
|
||||
self.__buffer_ptr.close()
|
||||
self.__handler.close()
|
||||
if self.__delete:
|
||||
try:
|
||||
# Always remove file afterwards
|
||||
|
|
|
@ -1,31 +1,39 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2021 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import requests
|
||||
from json import dumps
|
||||
import base64
|
||||
|
||||
from .NotifyBase import NotifyBase
|
||||
from ..URLBase import PrivacyMode
|
||||
|
@ -35,6 +43,20 @@ from ..utils import validate_regex
|
|||
from ..AppriseLocale import gettext_lazy as _
|
||||
|
||||
|
||||
class AppriseAPIMethod:
|
||||
"""
|
||||
Defines the method to post data tot he remote server
|
||||
"""
|
||||
JSON = 'json'
|
||||
FORM = 'form'
|
||||
|
||||
|
||||
APPRISE_API_METHODS = (
|
||||
AppriseAPIMethod.FORM,
|
||||
AppriseAPIMethod.JSON,
|
||||
)
|
||||
|
||||
|
||||
class NotifyAppriseAPI(NotifyBase):
|
||||
"""
|
||||
A wrapper for Apprise (Persistent) API Notifications
|
||||
|
@ -57,7 +79,7 @@ class NotifyAppriseAPI(NotifyBase):
|
|||
|
||||
# Depending on the number of transactions/notifications taking place, this
|
||||
# could take a while. 30 seconds should be enough to perform the task
|
||||
socket_connect_timeout = 30.0
|
||||
socket_read_timeout = 30.0
|
||||
|
||||
# Disable throttle rate for Apprise API requests since they are normally
|
||||
# local anyway
|
||||
|
@ -112,6 +134,12 @@ class NotifyAppriseAPI(NotifyBase):
|
|||
'name': _('Tags'),
|
||||
'type': 'string',
|
||||
},
|
||||
'method': {
|
||||
'name': _('Query Method'),
|
||||
'type': 'choice:string',
|
||||
'values': APPRISE_API_METHODS,
|
||||
'default': APPRISE_API_METHODS[0],
|
||||
},
|
||||
'to': {
|
||||
'alias_of': 'token',
|
||||
},
|
||||
|
@ -125,7 +153,8 @@ class NotifyAppriseAPI(NotifyBase):
|
|||
},
|
||||
}
|
||||
|
||||
def __init__(self, token=None, tags=None, headers=None, **kwargs):
|
||||
def __init__(self, token=None, tags=None, method=None, headers=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Initialize Apprise API Object
|
||||
|
||||
|
@ -133,7 +162,7 @@ class NotifyAppriseAPI(NotifyBase):
|
|||
additionally include as part of the server headers to post with
|
||||
|
||||
"""
|
||||
super(NotifyAppriseAPI, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.fullpath = kwargs.get('fullpath')
|
||||
if not isinstance(self.fullpath, str):
|
||||
|
@ -147,6 +176,14 @@ class NotifyAppriseAPI(NotifyBase):
|
|||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
self.method = self.template_args['method']['default'] \
|
||||
if not isinstance(method, str) else method.lower()
|
||||
|
||||
if self.method not in APPRISE_API_METHODS:
|
||||
msg = 'The method specified ({}) is invalid.'.format(method)
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
# Build list of tags
|
||||
self.__tags = parse_list(tags)
|
||||
|
||||
|
@ -162,8 +199,13 @@ class NotifyAppriseAPI(NotifyBase):
|
|||
Returns the URL built dynamically based on specified arguments.
|
||||
"""
|
||||
|
||||
# Our URL parameters
|
||||
params = self.url_parameters(privacy=privacy, *args, **kwargs)
|
||||
# Define any URL parameters
|
||||
params = {
|
||||
'method': self.method,
|
||||
}
|
||||
|
||||
# Extend our parameters
|
||||
params.update(self.url_parameters(privacy=privacy, *args, **kwargs))
|
||||
|
||||
# Append our headers into our parameters
|
||||
params.update({'+{}'.format(k): v for k, v in self.headers.items()})
|
||||
|
@ -202,15 +244,61 @@ class NotifyAppriseAPI(NotifyBase):
|
|||
token=self.pprint(self.token, privacy, safe=''),
|
||||
params=NotifyAppriseAPI.urlencode(params))
|
||||
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, attach=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Perform Apprise API Notification
|
||||
"""
|
||||
|
||||
headers = {}
|
||||
# Prepare HTTP Headers
|
||||
headers = {
|
||||
'User-Agent': self.app_id,
|
||||
}
|
||||
|
||||
# Apply any/all header over-rides defined
|
||||
headers.update(self.headers)
|
||||
|
||||
attachments = []
|
||||
files = []
|
||||
if attach:
|
||||
for no, attachment in enumerate(attach, start=1):
|
||||
# Perform some simple error checking
|
||||
if not attachment:
|
||||
# We could not access the attachment
|
||||
self.logger.error(
|
||||
'Could not access attachment {}.'.format(
|
||||
attachment.url(privacy=True)))
|
||||
return False
|
||||
|
||||
try:
|
||||
if self.method == AppriseAPIMethod.JSON:
|
||||
with open(attachment.path, 'rb') as f:
|
||||
# Output must be in a DataURL format (that's what
|
||||
# PushSafer calls it):
|
||||
attachments.append({
|
||||
'filename': attachment.name,
|
||||
'base64': base64.b64encode(f.read())
|
||||
.decode('utf-8'),
|
||||
'mimetype': attachment.mimetype,
|
||||
})
|
||||
|
||||
else: # AppriseAPIMethod.FORM
|
||||
files.append((
|
||||
'file{:02d}'.format(no),
|
||||
(
|
||||
attachment.name,
|
||||
open(attachment.path, 'rb'),
|
||||
attachment.mimetype,
|
||||
)
|
||||
))
|
||||
|
||||
except (OSError, IOError) as e:
|
||||
self.logger.warning(
|
||||
'An I/O error occurred while reading {}.'.format(
|
||||
attachment.name if attachment else 'attachment'))
|
||||
self.logger.debug('I/O Exception: %s' % str(e))
|
||||
return False
|
||||
|
||||
# prepare Apprise API Object
|
||||
payload = {
|
||||
# Apprise API Payload
|
||||
|
@ -220,6 +308,11 @@ class NotifyAppriseAPI(NotifyBase):
|
|||
'format': self.notify_format,
|
||||
}
|
||||
|
||||
if self.method == AppriseAPIMethod.JSON:
|
||||
headers['Content-Type'] = 'application/json'
|
||||
payload['attachments'] = attachments
|
||||
payload = dumps(payload)
|
||||
|
||||
if self.__tags:
|
||||
payload['tag'] = self.__tags
|
||||
|
||||
|
@ -240,8 +333,8 @@ class NotifyAppriseAPI(NotifyBase):
|
|||
|
||||
# Some entries can not be over-ridden
|
||||
headers.update({
|
||||
'User-Agent': self.app_id,
|
||||
'Content-Type': 'application/json',
|
||||
# Our response to be in JSON format always
|
||||
'Accept': 'application/json',
|
||||
# Pass our Source UUID4 Identifier
|
||||
'X-Apprise-ID': self.asset._uid,
|
||||
# Pass our current recursion count to our upstream server
|
||||
|
@ -259,9 +352,10 @@ class NotifyAppriseAPI(NotifyBase):
|
|||
try:
|
||||
r = requests.post(
|
||||
url,
|
||||
data=dumps(payload),
|
||||
data=payload,
|
||||
headers=headers,
|
||||
auth=auth,
|
||||
files=files if files else None,
|
||||
verify=self.verify_certificate,
|
||||
timeout=self.request_timeout,
|
||||
)
|
||||
|
@ -283,7 +377,8 @@ class NotifyAppriseAPI(NotifyBase):
|
|||
return False
|
||||
|
||||
else:
|
||||
self.logger.info('Sent Apprise API notification.')
|
||||
self.logger.info(
|
||||
'Sent Apprise API notification; method=%s.', self.method)
|
||||
|
||||
except requests.RequestException as e:
|
||||
self.logger.warning(
|
||||
|
@ -294,6 +389,18 @@ class NotifyAppriseAPI(NotifyBase):
|
|||
# Return; we're done
|
||||
return False
|
||||
|
||||
except (OSError, IOError) as e:
|
||||
self.logger.warning(
|
||||
'An I/O error occurred while reading one of the '
|
||||
'attached files.')
|
||||
self.logger.debug('I/O Exception: %s' % str(e))
|
||||
return False
|
||||
|
||||
finally:
|
||||
for file in files:
|
||||
# Ensure all files are closed
|
||||
file[1][1].close()
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
|
@ -370,4 +477,9 @@ class NotifyAppriseAPI(NotifyBase):
|
|||
# re-assemble our full path
|
||||
results['fullpath'] = '/'.join(entries)
|
||||
|
||||
# Set method if specified
|
||||
if 'method' in results['qsd'] and len(results['qsd']['method']):
|
||||
results['method'] = \
|
||||
NotifyAppriseAPI.unquote(results['qsd']['method'])
|
||||
|
||||
return results
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#
|
||||
# API: https://github.com/Finb/bark-server/blob/master/docs/API_V2.md#python
|
||||
#
|
||||
|
@ -204,7 +212,7 @@ class NotifyBark(NotifyBase):
|
|||
"""
|
||||
Initialize Notify Bark Object
|
||||
"""
|
||||
super(NotifyBark, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Prepare our URL
|
||||
self.notify_url = '%s://%s%s/push' % (
|
||||
|
@ -272,7 +280,7 @@ class NotifyBark(NotifyBase):
|
|||
# error tracking (used for function return)
|
||||
has_error = False
|
||||
|
||||
if not len(self.targets):
|
||||
if not self.targets:
|
||||
# We have nothing to notify; we're done
|
||||
self.logger.warning('There are no Bark devices to notify')
|
||||
return False
|
||||
|
@ -448,6 +456,12 @@ class NotifyBark(NotifyBase):
|
|||
params=NotifyBark.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,29 +1,38 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import asyncio
|
||||
import re
|
||||
from functools import partial
|
||||
|
||||
from ..URLBase import URLBase
|
||||
from ..common import NotifyType
|
||||
|
@ -36,12 +45,7 @@ from ..AppriseLocale import gettext_lazy as _
|
|||
from ..AppriseAttachment import AppriseAttachment
|
||||
|
||||
|
||||
# Wrap our base with the asyncio wrapper
|
||||
from ..py3compat.asyncio import AsyncNotifyBase
|
||||
BASE_OBJECT = AsyncNotifyBase
|
||||
|
||||
|
||||
class NotifyBase(BASE_OBJECT):
|
||||
class NotifyBase(URLBase):
|
||||
"""
|
||||
This is the base class for all notification services
|
||||
"""
|
||||
|
@ -180,7 +184,7 @@ class NotifyBase(BASE_OBJECT):
|
|||
|
||||
"""
|
||||
|
||||
super(NotifyBase, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
if 'format' in kwargs:
|
||||
# Store the specified format if specified
|
||||
|
@ -267,19 +271,64 @@ class NotifyBase(BASE_OBJECT):
|
|||
color_type=color_type,
|
||||
)
|
||||
|
||||
def notify(self, body, title=None, notify_type=NotifyType.INFO,
|
||||
overflow=None, attach=None, body_format=None, **kwargs):
|
||||
def notify(self, *args, **kwargs):
|
||||
"""
|
||||
Performs notification
|
||||
"""
|
||||
try:
|
||||
# Build a list of dictionaries that can be used to call send().
|
||||
send_calls = list(self._build_send_calls(*args, **kwargs))
|
||||
|
||||
except TypeError:
|
||||
# Internal error
|
||||
return False
|
||||
|
||||
else:
|
||||
# Loop through each call, one at a time. (Use a list rather than a
|
||||
# generator to call all the partials, even in case of a failure.)
|
||||
the_calls = [self.send(**kwargs2) for kwargs2 in send_calls]
|
||||
return all(the_calls)
|
||||
|
||||
async def async_notify(self, *args, **kwargs):
|
||||
"""
|
||||
Performs notification for asynchronous callers
|
||||
"""
|
||||
try:
|
||||
# Build a list of dictionaries that can be used to call send().
|
||||
send_calls = list(self._build_send_calls(*args, **kwargs))
|
||||
|
||||
except TypeError:
|
||||
# Internal error
|
||||
return False
|
||||
|
||||
else:
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
# Wrap each call in a coroutine that uses the default executor.
|
||||
# TODO: In the future, allow plugins to supply a native
|
||||
# async_send() method.
|
||||
async def do_send(**kwargs2):
|
||||
send = partial(self.send, **kwargs2)
|
||||
result = await loop.run_in_executor(None, send)
|
||||
return result
|
||||
|
||||
# gather() all calls in parallel.
|
||||
the_cors = (do_send(**kwargs2) for kwargs2 in send_calls)
|
||||
return all(await asyncio.gather(*the_cors))
|
||||
|
||||
def _build_send_calls(self, body, title=None,
|
||||
notify_type=NotifyType.INFO, overflow=None,
|
||||
attach=None, body_format=None, **kwargs):
|
||||
"""
|
||||
Get a list of dictionaries that can be used to call send() or
|
||||
(in the future) async_send().
|
||||
"""
|
||||
|
||||
if not self.enabled:
|
||||
# Deny notifications issued to services that are disabled
|
||||
self.logger.warning(
|
||||
"{} is currently disabled on this system.".format(
|
||||
self.service_name))
|
||||
return False
|
||||
msg = f"{self.service_name} is currently disabled on this system."
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
# Prepare attachments if required
|
||||
if attach is not None and not isinstance(attach, AppriseAttachment):
|
||||
|
@ -288,7 +337,7 @@ class NotifyBase(BASE_OBJECT):
|
|||
|
||||
except TypeError:
|
||||
# bad attachments
|
||||
return False
|
||||
raise
|
||||
|
||||
# Handle situations where the title is None
|
||||
title = '' if not title else title
|
||||
|
@ -299,14 +348,11 @@ class NotifyBase(BASE_OBJECT):
|
|||
body_format=body_format):
|
||||
|
||||
# Send notification
|
||||
if not self.send(body=chunk['body'], title=chunk['title'],
|
||||
notify_type=notify_type, attach=attach,
|
||||
body_format=body_format):
|
||||
|
||||
# Toggle our return status flag
|
||||
return False
|
||||
|
||||
return True
|
||||
yield dict(
|
||||
body=chunk['body'], title=chunk['title'],
|
||||
notify_type=notify_type, attach=attach,
|
||||
body_format=body_format
|
||||
)
|
||||
|
||||
def _apply_overflow(self, body, title=None, overflow=None,
|
||||
body_format=None):
|
||||
|
@ -423,13 +469,13 @@ class NotifyBase(BASE_OBJECT):
|
|||
'overflow': self.overflow_mode,
|
||||
}
|
||||
|
||||
params.update(super(NotifyBase, self).url_parameters(*args, **kwargs))
|
||||
params.update(super().url_parameters(*args, **kwargs))
|
||||
|
||||
# return default parameters
|
||||
return params
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url, verify_host=True):
|
||||
def parse_url(url, verify_host=True, plus_to_space=False):
|
||||
"""Parses the URL and returns it broken apart into a dictionary.
|
||||
|
||||
This is very specific and customized for Apprise.
|
||||
|
@ -447,7 +493,8 @@ class NotifyBase(BASE_OBJECT):
|
|||
A dictionary is returned containing the URL fully parsed if
|
||||
successful, otherwise None is returned.
|
||||
"""
|
||||
results = URLBase.parse_url(url, verify_host=verify_host)
|
||||
results = URLBase.parse_url(
|
||||
url, verify_host=verify_host, plus_to_space=plus_to_space)
|
||||
|
||||
if not results:
|
||||
# We're done; we failed to parse our url
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import requests
|
||||
|
@ -39,6 +46,7 @@ except ImportError:
|
|||
from .NotifyBase import NotifyBase
|
||||
from ..URLBase import PrivacyMode
|
||||
from ..utils import parse_bool
|
||||
from ..utils import parse_list
|
||||
from ..utils import validate_regex
|
||||
from ..common import NotifyType
|
||||
from ..common import NotifyImageSize
|
||||
|
@ -51,7 +59,7 @@ DEFAULT_TAG = '@all'
|
|||
# list of tagged devices that the notification need to be send to, and a
|
||||
# boolean operator (‘and’ / ‘or’) that defines the criteria to match devices
|
||||
# against those tags.
|
||||
IS_TAG = re.compile(r'^[@](?P<name>[A-Z0-9]{1,63})$', re.I)
|
||||
IS_TAG = re.compile(r'^[@]?(?P<name>[A-Z0-9]{1,63})$', re.I)
|
||||
|
||||
# Device tokens are only referenced when developing.
|
||||
# It's not likely you'll send a message directly to a device, but if you do;
|
||||
|
@ -150,10 +158,10 @@ class NotifyBoxcar(NotifyBase):
|
|||
"""
|
||||
Initialize Boxcar Object
|
||||
"""
|
||||
super(NotifyBoxcar, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Initialize tag list
|
||||
self.tags = list()
|
||||
self._tags = list()
|
||||
|
||||
# Initialize device_token list
|
||||
self.device_tokens = list()
|
||||
|
@ -177,29 +185,27 @@ class NotifyBoxcar(NotifyBase):
|
|||
raise TypeError(msg)
|
||||
|
||||
if not targets:
|
||||
self.tags.append(DEFAULT_TAG)
|
||||
self._tags.append(DEFAULT_TAG)
|
||||
targets = []
|
||||
|
||||
elif isinstance(targets, str):
|
||||
targets = [x for x in filter(bool, TAGS_LIST_DELIM.split(
|
||||
targets,
|
||||
))]
|
||||
|
||||
# Validate targets and drop bad ones:
|
||||
for target in targets:
|
||||
if IS_TAG.match(target):
|
||||
for target in parse_list(targets):
|
||||
result = IS_TAG.match(target)
|
||||
if result:
|
||||
# store valid tag/alias
|
||||
self.tags.append(IS_TAG.match(target).group('name'))
|
||||
self._tags.append(result.group('name'))
|
||||
continue
|
||||
|
||||
elif IS_DEVICETOKEN.match(target):
|
||||
result = IS_DEVICETOKEN.match(target)
|
||||
if result:
|
||||
# store valid device
|
||||
self.device_tokens.append(target)
|
||||
continue
|
||||
|
||||
else:
|
||||
self.logger.warning(
|
||||
'Dropped invalid tag/alias/device_token '
|
||||
'({}) specified.'.format(target),
|
||||
)
|
||||
self.logger.warning(
|
||||
'Dropped invalid tag/alias/device_token '
|
||||
'({}) specified.'.format(target),
|
||||
)
|
||||
|
||||
# Track whether or not we want to send an image with our notification
|
||||
# or not.
|
||||
|
@ -231,8 +237,8 @@ class NotifyBoxcar(NotifyBase):
|
|||
if body:
|
||||
payload['aps']['alert'] = body
|
||||
|
||||
if self.tags:
|
||||
payload['tags'] = {'or': self.tags}
|
||||
if self._tags:
|
||||
payload['tags'] = {'or': self._tags}
|
||||
|
||||
if self.device_tokens:
|
||||
payload['device_tokens'] = self.device_tokens
|
||||
|
@ -334,10 +340,18 @@ class NotifyBoxcar(NotifyBase):
|
|||
self.secret, privacy, mode=PrivacyMode.Secret, safe=''),
|
||||
targets='/'.join([
|
||||
NotifyBoxcar.quote(x, safe='') for x in chain(
|
||||
self.tags, self.device_tokens) if x != DEFAULT_TAG]),
|
||||
self._tags, self.device_tokens) if x != DEFAULT_TAG]),
|
||||
params=NotifyBoxcar.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self._tags) + len(self.device_tokens)
|
||||
# DEFAULT_TAG is set if no tokens/tags are otherwise set
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# To use this service you will need a BulkSMS account
|
||||
# You will need credits (new accounts start with a few)
|
||||
|
@ -30,7 +37,6 @@
|
|||
# API is documented here:
|
||||
# - https://www.bulksms.com/developer/json/v1/#tag/Message
|
||||
import re
|
||||
import six
|
||||
import requests
|
||||
import json
|
||||
from itertools import chain
|
||||
|
@ -192,7 +198,7 @@ class NotifyBulkSMS(NotifyBase):
|
|||
|
||||
# Setup our route
|
||||
self.route = self.template_args['route']['default'] \
|
||||
if not isinstance(route, six.string_types) else route.upper()
|
||||
if not isinstance(route, str) else route.upper()
|
||||
if self.route not in BULKSMS_ROUTING_GROUPS:
|
||||
msg = 'The route specified ({}) is invalid.'.format(route)
|
||||
self.logger.warning(msg)
|
||||
|
@ -408,6 +414,24 @@ class NotifyBulkSMS(NotifyBase):
|
|||
for x in self.groups])),
|
||||
params=NotifyBulkSMS.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
# Note: Groups always require a separate request (and can not be
|
||||
# included in batch calculations)
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
|
||||
return targets + len(self.groups)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# To use this plugin, simply signup with clicksend:
|
||||
# https://www.clicksend.com/
|
||||
|
@ -132,7 +139,7 @@ class NotifyClickSend(NotifyBase):
|
|||
"""
|
||||
Initialize ClickSend Object
|
||||
"""
|
||||
super(NotifyClickSend, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Prepare Batch Mode Flag
|
||||
self.batch = batch
|
||||
|
@ -281,6 +288,21 @@ class NotifyClickSend(NotifyBase):
|
|||
params=NotifyClickSend.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
|
||||
return targets
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# To use this service you will need a D7 Networks account from their website
|
||||
# at https://d7networks.com/
|
||||
|
@ -29,17 +36,18 @@
|
|||
# After you've established your account you can get your api login credentials
|
||||
# (both user and password) from the API Details section from within your
|
||||
# account profile area: https://d7networks.com/accounts/profile/
|
||||
#
|
||||
# API Reference: https://d7networks.com/docs/Messages/Send_Message/
|
||||
|
||||
import requests
|
||||
import base64
|
||||
from json import dumps
|
||||
from json import loads
|
||||
|
||||
from .NotifyBase import NotifyBase
|
||||
from ..URLBase import PrivacyMode
|
||||
from ..common import NotifyType
|
||||
from ..utils import is_phone_no
|
||||
from ..utils import parse_phone_no
|
||||
from ..utils import validate_regex
|
||||
from ..utils import parse_bool
|
||||
from ..AppriseLocale import gettext_lazy as _
|
||||
|
||||
|
@ -52,25 +60,6 @@ D7NETWORKS_HTTP_ERROR_MAP = {
|
|||
}
|
||||
|
||||
|
||||
# Priorities
|
||||
class D7SMSPriority:
|
||||
"""
|
||||
D7 Networks SMS Message Priority
|
||||
"""
|
||||
LOW = 0
|
||||
MODERATE = 1
|
||||
NORMAL = 2
|
||||
HIGH = 3
|
||||
|
||||
|
||||
D7NETWORK_SMS_PRIORITIES = (
|
||||
D7SMSPriority.LOW,
|
||||
D7SMSPriority.MODERATE,
|
||||
D7SMSPriority.NORMAL,
|
||||
D7SMSPriority.HIGH,
|
||||
)
|
||||
|
||||
|
||||
class NotifyD7Networks(NotifyBase):
|
||||
"""
|
||||
A wrapper for D7 Networks Notifications
|
||||
|
@ -92,11 +81,8 @@ class NotifyD7Networks(NotifyBase):
|
|||
# A URL that takes you to the setup/help of the specific protocol
|
||||
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_d7networks'
|
||||
|
||||
# D7 Networks batch notification URL
|
||||
notify_batch_url = 'http://rest-api.d7networks.com/secure/sendbatch'
|
||||
|
||||
# D7 Networks single notification URL
|
||||
notify_url = 'http://rest-api.d7networks.com/secure/send'
|
||||
notify_url = 'https://api.d7networks.com/messages/v1/send'
|
||||
|
||||
# The maximum length of the body
|
||||
body_maxlen = 160
|
||||
|
@ -107,21 +93,16 @@ class NotifyD7Networks(NotifyBase):
|
|||
|
||||
# Define object templates
|
||||
templates = (
|
||||
'{schema}://{user}:{password}@{targets}',
|
||||
'{schema}://{token}@{targets}',
|
||||
)
|
||||
|
||||
# Define our template tokens
|
||||
template_tokens = dict(NotifyBase.template_tokens, **{
|
||||
'user': {
|
||||
'name': _('Username'),
|
||||
'token': {
|
||||
'name': _('API Access Token'),
|
||||
'type': 'string',
|
||||
'required': True,
|
||||
},
|
||||
'password': {
|
||||
'name': _('Password'),
|
||||
'type': 'string',
|
||||
'private': True,
|
||||
'required': True,
|
||||
},
|
||||
'target_phone': {
|
||||
'name': _('Target Phone No'),
|
||||
|
@ -138,16 +119,11 @@ class NotifyD7Networks(NotifyBase):
|
|||
|
||||
# Define our template arguments
|
||||
template_args = dict(NotifyBase.template_args, **{
|
||||
'priority': {
|
||||
'name': _('Priority'),
|
||||
'type': 'choice:int',
|
||||
'min': D7SMSPriority.LOW,
|
||||
'max': D7SMSPriority.HIGH,
|
||||
'values': D7NETWORK_SMS_PRIORITIES,
|
||||
|
||||
# The website identifies that the default priority is low; so
|
||||
# this plugin will honor that same default
|
||||
'default': D7SMSPriority.LOW,
|
||||
'unicode': {
|
||||
# Unicode characters (default is 'auto')
|
||||
'name': _('Unicode Characters'),
|
||||
'type': 'bool',
|
||||
'default': False,
|
||||
},
|
||||
'batch': {
|
||||
'name': _('Batch Mode'),
|
||||
|
@ -172,19 +148,12 @@ class NotifyD7Networks(NotifyBase):
|
|||
},
|
||||
})
|
||||
|
||||
def __init__(self, targets=None, priority=None, source=None, batch=False,
|
||||
**kwargs):
|
||||
def __init__(self, token=None, targets=None, source=None,
|
||||
batch=False, unicode=None, **kwargs):
|
||||
"""
|
||||
Initialize D7 Networks Object
|
||||
"""
|
||||
super(NotifyD7Networks, self).__init__(**kwargs)
|
||||
|
||||
# The Priority of the message
|
||||
if priority not in D7NETWORK_SMS_PRIORITIES:
|
||||
self.priority = self.template_args['priority']['default']
|
||||
|
||||
else:
|
||||
self.priority = priority
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Prepare Batch Mode Flag
|
||||
self.batch = batch
|
||||
|
@ -193,8 +162,15 @@ class NotifyD7Networks(NotifyBase):
|
|||
self.source = None \
|
||||
if not isinstance(source, str) else source.strip()
|
||||
|
||||
if not (self.user and self.password):
|
||||
msg = 'A D7 Networks user/pass was not provided.'
|
||||
# Define whether or not we should set the unicode flag
|
||||
self.unicode = self.template_args['unicode']['default'] \
|
||||
if unicode is None else bool(unicode)
|
||||
|
||||
# The token associated with the account
|
||||
self.token = validate_regex(token)
|
||||
if not self.token:
|
||||
msg = 'The D7 Networks token specified ({}) is invalid.'\
|
||||
.format(token)
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
|
@ -229,40 +205,41 @@ class NotifyD7Networks(NotifyBase):
|
|||
# error tracking (used for function return)
|
||||
has_error = False
|
||||
|
||||
auth = '{user}:{password}'.format(
|
||||
user=self.user, password=self.password)
|
||||
|
||||
# Python 3's versio of b64encode() expects a byte array and not
|
||||
# a string. To accommodate this, we encode the content here
|
||||
auth = auth.encode('utf-8')
|
||||
|
||||
# Prepare our headers
|
||||
headers = {
|
||||
'User-Agent': self.app_id,
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Authorization': 'Basic {}'.format(base64.b64encode(auth))
|
||||
'Authorization': f'Bearer {self.token}',
|
||||
}
|
||||
|
||||
# Our URL varies depending if we're doing a batch mode or not
|
||||
url = self.notify_batch_url if self.batch else self.notify_url
|
||||
payload = {
|
||||
'message_globals': {
|
||||
'channel': 'sms',
|
||||
},
|
||||
'messages': [{
|
||||
# Populated later on
|
||||
'recipients': None,
|
||||
'content': body,
|
||||
'data_coding':
|
||||
# auto is a better substitute over 'text' as text is easier to
|
||||
# detect from a post than `unicode` is.
|
||||
'auto' if not self.unicode else 'unicode',
|
||||
}],
|
||||
}
|
||||
|
||||
# use the list directly
|
||||
targets = list(self.targets)
|
||||
|
||||
if self.source:
|
||||
payload['message_globals']['originator'] = self.source
|
||||
|
||||
target = None
|
||||
while len(targets):
|
||||
|
||||
if self.batch:
|
||||
# Prepare our payload
|
||||
payload = {
|
||||
'globals': {
|
||||
'priority': self.priority,
|
||||
'from': self.source if self.source else self.app_id,
|
||||
},
|
||||
'messages': [{
|
||||
'to': self.targets,
|
||||
'content': body,
|
||||
}],
|
||||
}
|
||||
payload['messages'][0]['recipients'] = self.targets
|
||||
|
||||
# Reset our targets so we don't keep going. This is required
|
||||
# because we're in batch mode; we only need to loop once.
|
||||
|
@ -274,24 +251,19 @@ class NotifyD7Networks(NotifyBase):
|
|||
target = targets.pop(0)
|
||||
|
||||
# Prepare our payload
|
||||
payload = {
|
||||
'priority': self.priority,
|
||||
'content': body,
|
||||
'to': target,
|
||||
'from': self.source if self.source else self.app_id,
|
||||
}
|
||||
payload['messages'][0]['recipients'] = [target]
|
||||
|
||||
# Some Debug Logging
|
||||
self.logger.debug(
|
||||
'D7 Networks POST URL: {} (cert_verify={})'.format(
|
||||
url, self.verify_certificate))
|
||||
self.notify_url, self.verify_certificate))
|
||||
self.logger.debug('D7 Networks Payload: {}' .format(payload))
|
||||
|
||||
# Always call throttle before any remote server i/o is made
|
||||
self.throttle()
|
||||
try:
|
||||
r = requests.post(
|
||||
url,
|
||||
self.notify_url,
|
||||
data=dumps(payload),
|
||||
headers=headers,
|
||||
verify=self.verify_certificate,
|
||||
|
@ -337,29 +309,9 @@ class NotifyD7Networks(NotifyBase):
|
|||
else:
|
||||
|
||||
if self.batch:
|
||||
count = len(self.targets)
|
||||
try:
|
||||
# Get our message delivery count if we can
|
||||
json_response = loads(r.content)
|
||||
count = int(json_response.get(
|
||||
'data', {}).get('messageCount', -1))
|
||||
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
# ValueError = r.content is Unparsable
|
||||
# TypeError = r.content is None
|
||||
# AttributeError = r is None
|
||||
|
||||
# We could not parse JSON response. Assume that
|
||||
# our delivery is okay for now.
|
||||
pass
|
||||
|
||||
if count != len(self.targets):
|
||||
has_error = True
|
||||
|
||||
self.logger.info(
|
||||
'Sent D7 Networks batch SMS notification to '
|
||||
'{} of {} target(s).'.format(
|
||||
count, len(self.targets)))
|
||||
'{} target(s).'.format(len(self.targets)))
|
||||
|
||||
else:
|
||||
self.logger.info(
|
||||
|
@ -389,26 +341,31 @@ class NotifyD7Networks(NotifyBase):
|
|||
# Define any URL parameters
|
||||
params = {
|
||||
'batch': 'yes' if self.batch else 'no',
|
||||
'unicode': 'yes' if self.unicode else 'no',
|
||||
}
|
||||
|
||||
# Extend our parameters
|
||||
params.update(self.url_parameters(privacy=privacy, *args, **kwargs))
|
||||
|
||||
if self.priority != self.template_args['priority']['default']:
|
||||
params['priority'] = str(self.priority)
|
||||
|
||||
if self.source:
|
||||
params['from'] = self.source
|
||||
|
||||
return '{schema}://{user}:{password}@{targets}/?{params}'.format(
|
||||
# Extend our parameters
|
||||
params.update(self.url_parameters(privacy=privacy, *args, **kwargs))
|
||||
|
||||
return '{schema}://{token}@{targets}/?{params}'.format(
|
||||
schema=self.secure_protocol,
|
||||
user=NotifyD7Networks.quote(self.user, safe=''),
|
||||
password=self.pprint(
|
||||
self.password, privacy, mode=PrivacyMode.Secret, safe=''),
|
||||
token=self.pprint(self.token, privacy, safe=''),
|
||||
targets='/'.join(
|
||||
[NotifyD7Networks.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyD7Networks.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
return len(self.targets) if not self.batch else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -421,6 +378,23 @@ class NotifyD7Networks(NotifyBase):
|
|||
# We're done early as we couldn't load the results
|
||||
return results
|
||||
|
||||
if 'token' in results['qsd'] and len(results['qsd']['token']):
|
||||
results['token'] = \
|
||||
NotifyD7Networks.unquote(results['qsd']['token'])
|
||||
|
||||
elif results['user']:
|
||||
results['token'] = NotifyD7Networks.unquote(results['user'])
|
||||
|
||||
if results['password']:
|
||||
# Support token containing a colon (:)
|
||||
results['token'] += \
|
||||
':' + NotifyD7Networks.unquote(results['password'])
|
||||
|
||||
elif results['password']:
|
||||
# Support token starting with a colon (:)
|
||||
results['token'] = \
|
||||
':' + NotifyD7Networks.unquote(results['password'])
|
||||
|
||||
# Initialize our targets
|
||||
results['targets'] = list()
|
||||
|
||||
|
@ -432,44 +406,27 @@ class NotifyD7Networks(NotifyBase):
|
|||
results['targets'].extend(
|
||||
NotifyD7Networks.split_path(results['fullpath']))
|
||||
|
||||
# Set our priority
|
||||
if 'priority' in results['qsd'] and len(results['qsd']['priority']):
|
||||
_map = {
|
||||
'l': D7SMSPriority.LOW,
|
||||
'0': D7SMSPriority.LOW,
|
||||
'm': D7SMSPriority.MODERATE,
|
||||
'1': D7SMSPriority.MODERATE,
|
||||
'n': D7SMSPriority.NORMAL,
|
||||
'2': D7SMSPriority.NORMAL,
|
||||
'h': D7SMSPriority.HIGH,
|
||||
'3': D7SMSPriority.HIGH,
|
||||
}
|
||||
try:
|
||||
results['priority'] = \
|
||||
_map[results['qsd']['priority'][0].lower()]
|
||||
|
||||
except KeyError:
|
||||
# No priority was set
|
||||
pass
|
||||
|
||||
# Support the 'from' and 'source' variable so that we can support
|
||||
# targets this way too.
|
||||
# The 'from' makes it easier to use yaml configuration
|
||||
if 'from' in results['qsd'] and len(results['qsd']['from']):
|
||||
results['source'] = \
|
||||
NotifyD7Networks.unquote(results['qsd']['from'])
|
||||
if 'source' in results['qsd'] and len(results['qsd']['source']):
|
||||
results['source'] = \
|
||||
NotifyD7Networks.unquote(results['qsd']['source'])
|
||||
|
||||
# Get Batch Mode Flag
|
||||
results['batch'] = \
|
||||
parse_bool(results['qsd'].get('batch', False))
|
||||
|
||||
# Get Unicode Flag
|
||||
results['unicode'] = \
|
||||
parse_bool(results['qsd'].get('unicode', False))
|
||||
|
||||
# Support the 'to' variable so that we can support targets this way too
|
||||
# The 'to' makes it easier to use yaml configuration
|
||||
if 'to' in results['qsd'] and len(results['qsd']['to']):
|
||||
results['targets'] += \
|
||||
NotifyD7Networks.parse_phone_no(results['qsd']['to'])
|
||||
|
||||
# Support the 'from' and source variable
|
||||
if 'from' in results['qsd'] and len(results['qsd']['from']):
|
||||
results['source'] = \
|
||||
NotifyD7Networks.unquote(results['qsd']['from'])
|
||||
|
||||
elif 'source' in results['qsd'] and len(results['qsd']['source']):
|
||||
results['source'] = \
|
||||
NotifyD7Networks.unquote(results['qsd']['source'])
|
||||
|
||||
return results
|
||||
|
|
|
@ -1,31 +1,39 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
from .NotifyBase import NotifyBase
|
||||
from ..common import NotifyImageSize
|
||||
from ..common import NotifyType
|
||||
|
@ -77,6 +85,13 @@ try:
|
|||
NOTIFY_DBUS_SUPPORT_ENABLED = (
|
||||
LOOP_GLIB is not None or LOOP_QT is not None)
|
||||
|
||||
# ImportError: When using gi.repository you must not import static modules
|
||||
# like "gobject". Please change all occurrences of "import gobject" to
|
||||
# "from gi.repository import GObject".
|
||||
# See: https://bugzilla.gnome.org/show_bug.cgi?id=709183
|
||||
if "gobject" in sys.modules: # pragma: no cover
|
||||
del sys.modules["gobject"]
|
||||
|
||||
try:
|
||||
# The following is required for Image/Icon loading only
|
||||
import gi
|
||||
|
@ -233,7 +248,7 @@ class NotifyDBus(NotifyBase):
|
|||
Initialize DBus Object
|
||||
"""
|
||||
|
||||
super(NotifyDBus, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Track our notifications
|
||||
self.registry = {}
|
||||
|
@ -272,12 +287,9 @@ class NotifyDBus(NotifyBase):
|
|||
self.x_axis = None
|
||||
self.y_axis = None
|
||||
|
||||
# Track whether or not we want to send an image with our notification
|
||||
# or not.
|
||||
# Track whether we want to add an image to the notification.
|
||||
self.include_image = include_image
|
||||
|
||||
return
|
||||
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
|
||||
"""
|
||||
Perform DBus Notification
|
||||
|
@ -286,10 +298,10 @@ class NotifyDBus(NotifyBase):
|
|||
try:
|
||||
session = SessionBus(mainloop=MAINLOOP_MAP[self.schema])
|
||||
|
||||
except DBusException:
|
||||
except DBusException as e:
|
||||
# Handle exception
|
||||
self.logger.warning('Failed to send DBus notification.')
|
||||
self.logger.exception('DBus Exception')
|
||||
self.logger.debug(f'DBus Exception: {e}')
|
||||
return False
|
||||
|
||||
# If there is no title, but there is a body, swap the two to get rid
|
||||
|
@ -342,8 +354,8 @@ class NotifyDBus(NotifyBase):
|
|||
|
||||
except Exception as e:
|
||||
self.logger.warning(
|
||||
"Could not load Gnome notification icon ({}): {}"
|
||||
.format(icon_path, e))
|
||||
"Could not load notification icon (%s).", icon_path)
|
||||
self.logger.debug(f'DBus Exception: {e}')
|
||||
|
||||
try:
|
||||
# Always call throttle() before any remote execution is made
|
||||
|
@ -370,9 +382,9 @@ class NotifyDBus(NotifyBase):
|
|||
|
||||
self.logger.info('Sent DBus notification.')
|
||||
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
self.logger.warning('Failed to send DBus notification.')
|
||||
self.logger.exception('DBus Exception')
|
||||
self.logger.debug(f'DBus Exception: {e}')
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# To use this plugin, sign up with Hampager (you need to be a licensed
|
||||
# ham radio operator
|
||||
|
@ -179,7 +186,7 @@ class NotifyDapnet(NotifyBase):
|
|||
"""
|
||||
Initialize Dapnet Object
|
||||
"""
|
||||
super(NotifyDapnet, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Parse our targets
|
||||
self.targets = list()
|
||||
|
@ -343,6 +350,21 @@ class NotifyDapnet(NotifyBase):
|
|||
params=NotifyDapnet.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
|
||||
return targets
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import time
|
||||
|
@ -124,7 +131,7 @@ class NotifyDingTalk(NotifyBase):
|
|||
"""
|
||||
Initialize DingTalk Object
|
||||
"""
|
||||
super(NotifyDingTalk, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Secret Key (associated with project)
|
||||
self.token = validate_regex(
|
||||
|
@ -302,6 +309,13 @@ class NotifyDingTalk(NotifyBase):
|
|||
[NotifyDingTalk.quote(x, safe='') for x in self.targets]),
|
||||
args=NotifyDingTalk.urlencode(args))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# For this to work correctly you need to create a webhook. To do this just
|
||||
# click on the little gear icon next to the channel you're part of. From
|
||||
|
@ -164,7 +171,7 @@ class NotifyDiscord(NotifyBase):
|
|||
Initialize Discord Object
|
||||
|
||||
"""
|
||||
super(NotifyDiscord, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Webhook ID (associated with project)
|
||||
self.webhook_id = validate_regex(webhook_id)
|
||||
|
@ -283,9 +290,6 @@ class NotifyDiscord(NotifyBase):
|
|||
payload['content'] = \
|
||||
body if not title else "{}\r\n{}".format(title, body)
|
||||
|
||||
if self.thread_id:
|
||||
payload['thread_id'] = self.thread_id
|
||||
|
||||
if self.avatar and (image_url or self.avatar_url):
|
||||
payload['avatar_url'] = \
|
||||
self.avatar_url if self.avatar_url else image_url
|
||||
|
@ -294,7 +298,8 @@ class NotifyDiscord(NotifyBase):
|
|||
# Optionally override the default username of the webhook
|
||||
payload['username'] = self.user
|
||||
|
||||
if not self._send(payload):
|
||||
params = {'thread_id': self.thread_id} if self.thread_id else None
|
||||
if not self._send(payload, params=params):
|
||||
# We failed to post our message
|
||||
return False
|
||||
|
||||
|
@ -338,7 +343,7 @@ class NotifyDiscord(NotifyBase):
|
|||
# Otherwise return
|
||||
return True
|
||||
|
||||
def _send(self, payload, attach=None, **kwargs):
|
||||
def _send(self, payload, attach=None, params=None, **kwargs):
|
||||
"""
|
||||
Wrapper to the requests (post) object
|
||||
"""
|
||||
|
@ -389,6 +394,7 @@ class NotifyDiscord(NotifyBase):
|
|||
|
||||
r = requests.post(
|
||||
notify_url,
|
||||
params=params,
|
||||
data=payload if files else dumps(payload),
|
||||
headers=headers,
|
||||
files=files,
|
||||
|
@ -580,7 +586,7 @@ class NotifyDiscord(NotifyBase):
|
|||
if description:
|
||||
# Strip description from our string since it has been handled
|
||||
# now.
|
||||
markdown = re.sub(description, '', markdown, count=1)
|
||||
markdown = re.sub(re.escape(description), '', markdown, count=1)
|
||||
|
||||
regex = re.compile(
|
||||
r'\s*#[# \t\v]*(?P<name>[^\n]+)(\n|\s*$)'
|
||||
|
|
|
@ -1,30 +1,39 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import dataclasses
|
||||
import re
|
||||
import smtplib
|
||||
import typing as t
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.application import MIMEApplication
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
|
@ -41,6 +50,7 @@ from ..common import NotifyFormat, NotifyType
|
|||
from ..conversion import convert_between
|
||||
from ..utils import is_email, parse_emails
|
||||
from ..AppriseLocale import gettext_lazy as _
|
||||
from ..logger import logger
|
||||
|
||||
# Globally Default encoding mode set to Quoted Printable.
|
||||
charset.add_charset('utf-8', charset.QP, charset.QP, 'utf-8')
|
||||
|
@ -60,15 +70,23 @@ class WebBaseLogin:
|
|||
|
||||
# Secure Email Modes
|
||||
class SecureMailMode:
|
||||
INSECURE = "insecure"
|
||||
SSL = "ssl"
|
||||
STARTTLS = "starttls"
|
||||
|
||||
|
||||
# Define all of the secure modes (used during validation)
|
||||
SECURE_MODES = (
|
||||
SecureMailMode.SSL,
|
||||
SecureMailMode.STARTTLS,
|
||||
)
|
||||
SECURE_MODES = {
|
||||
SecureMailMode.STARTTLS: {
|
||||
'default_port': 587,
|
||||
},
|
||||
SecureMailMode.SSL: {
|
||||
'default_port': 465,
|
||||
},
|
||||
SecureMailMode.INSECURE: {
|
||||
'default_port': 25,
|
||||
},
|
||||
}
|
||||
|
||||
# To attempt to make this script stupid proof, if we detect an email address
|
||||
# that is part of the this table, we can pre-use a lot more defaults if they
|
||||
|
@ -109,7 +127,7 @@ EMAIL_TEMPLATES = (
|
|||
'Microsoft Hotmail',
|
||||
re.compile(
|
||||
r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@'
|
||||
r'(?P<domain>(outlook|hotmail|live)\.com(\.au)?)$', re.I),
|
||||
r'(?P<domain>(hotmail|live)\.com(\.au)?)$', re.I),
|
||||
{
|
||||
'port': 587,
|
||||
'smtp_host': 'smtp-mail.outlook.com',
|
||||
|
@ -119,6 +137,21 @@ EMAIL_TEMPLATES = (
|
|||
},
|
||||
),
|
||||
|
||||
# Microsoft Outlook
|
||||
(
|
||||
'Microsoft Outlook',
|
||||
re.compile(
|
||||
r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@'
|
||||
r'(?P<domain>(smtp\.)?outlook\.com(\.au)?)$', re.I),
|
||||
{
|
||||
'port': 587,
|
||||
'smtp_host': 'smtp.outlook.com',
|
||||
'secure': True,
|
||||
'secure_mode': SecureMailMode.STARTTLS,
|
||||
'login_type': (WebBaseLogin.EMAIL, )
|
||||
},
|
||||
),
|
||||
|
||||
# Microsoft Office 365 (Email Server)
|
||||
# You must specify an authenticated sender address in the from= settings
|
||||
# and a valid email in the to= to deliver your emails to
|
||||
|
@ -282,6 +315,13 @@ EMAIL_TEMPLATES = (
|
|||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class EmailMessage:
|
||||
recipient: str
|
||||
to_addrs: t.List[str]
|
||||
body: str
|
||||
|
||||
|
||||
class NotifyEmail(NotifyBase):
|
||||
"""
|
||||
A wrapper to Email Notifications
|
||||
|
@ -303,15 +343,6 @@ class NotifyEmail(NotifyBase):
|
|||
# Default Notify Format
|
||||
notify_format = NotifyFormat.HTML
|
||||
|
||||
# Default Non-Encryption Port
|
||||
default_port = 25
|
||||
|
||||
# Default Secure Port
|
||||
default_secure_port = 587
|
||||
|
||||
# Default Secure Mode
|
||||
default_secure_mode = SecureMailMode.STARTTLS
|
||||
|
||||
# Default SMTP Timeout (in seconds)
|
||||
socket_connect_timeout = 15
|
||||
|
||||
|
@ -373,7 +404,7 @@ class NotifyEmail(NotifyBase):
|
|||
'name': {
|
||||
'name': _('From Name'),
|
||||
'type': 'string',
|
||||
'map_to': 'from_name',
|
||||
'map_to': 'from_addr',
|
||||
},
|
||||
'cc': {
|
||||
'name': _('Carbon Copy'),
|
||||
|
@ -410,24 +441,16 @@ class NotifyEmail(NotifyBase):
|
|||
},
|
||||
}
|
||||
|
||||
def __init__(self, smtp_host=None, from_name=None,
|
||||
from_addr=None, secure_mode=None, targets=None, cc=None,
|
||||
bcc=None, reply_to=None, headers=None, **kwargs):
|
||||
def __init__(self, smtp_host=None, from_addr=None, secure_mode=None,
|
||||
targets=None, cc=None, bcc=None, reply_to=None, headers=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Initialize Email Object
|
||||
|
||||
The smtp_host and secure_mode can be automatically detected depending
|
||||
on how the URL was built
|
||||
"""
|
||||
super(NotifyEmail, self).__init__(**kwargs)
|
||||
|
||||
# Handle SMTP vs SMTPS (Secure vs UnSecure)
|
||||
if not self.port:
|
||||
if self.secure:
|
||||
self.port = self.default_secure_port
|
||||
|
||||
else:
|
||||
self.port = self.default_port
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Acquire Email 'To'
|
||||
self.targets = list()
|
||||
|
@ -451,40 +474,49 @@ class NotifyEmail(NotifyBase):
|
|||
|
||||
# Now we want to construct the To and From email
|
||||
# addresses from the URL provided
|
||||
self.from_addr = from_addr
|
||||
self.from_addr = [False, '']
|
||||
|
||||
if self.user and not self.from_addr:
|
||||
# detect our email address
|
||||
self.from_addr = '{}@{}'.format(
|
||||
if self.user and self.host:
|
||||
# Prepare the bases of our email
|
||||
self.from_addr = [self.app_id, '{}@{}'.format(
|
||||
re.split(r'[\s@]+', self.user)[0],
|
||||
self.host,
|
||||
)
|
||||
)]
|
||||
|
||||
result = is_email(self.from_addr)
|
||||
if from_addr:
|
||||
result = is_email(from_addr)
|
||||
if result:
|
||||
self.from_addr = (
|
||||
result['name'] if result['name'] else False,
|
||||
result['full_email'])
|
||||
else:
|
||||
self.from_addr[0] = from_addr
|
||||
|
||||
result = is_email(self.from_addr[1])
|
||||
if not result:
|
||||
# Parse Source domain based on from_addr
|
||||
msg = 'Invalid ~From~ email specified: {}'.format(self.from_addr)
|
||||
msg = 'Invalid ~From~ email specified: {}'.format(
|
||||
'{} <{}>'.format(self.from_addr[0], self.from_addr[1])
|
||||
if self.from_addr[0] else '{}'.format(self.from_addr[1]))
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
# Store our email address
|
||||
self.from_addr = result['full_email']
|
||||
|
||||
# Set our from name
|
||||
self.from_name = from_name if from_name else result['name']
|
||||
|
||||
# Store our lookup
|
||||
self.names[self.from_addr] = \
|
||||
self.from_name if self.from_name else False
|
||||
self.names[self.from_addr[1]] = self.from_addr[0]
|
||||
|
||||
# Now detect the SMTP Server
|
||||
self.smtp_host = \
|
||||
smtp_host if isinstance(smtp_host, str) else ''
|
||||
|
||||
# Now detect secure mode
|
||||
self.secure_mode = self.default_secure_mode \
|
||||
if not isinstance(secure_mode, str) \
|
||||
else secure_mode.lower()
|
||||
if secure_mode:
|
||||
self.secure_mode = None \
|
||||
if not isinstance(secure_mode, str) \
|
||||
else secure_mode.lower()
|
||||
else:
|
||||
self.secure_mode = SecureMailMode.INSECURE \
|
||||
if not self.secure else self.template_args['mode']['default']
|
||||
|
||||
if self.secure_mode not in SECURE_MODES:
|
||||
msg = 'The secure mode specified ({}) is invalid.'\
|
||||
.format(secure_mode)
|
||||
|
@ -508,8 +540,7 @@ class NotifyEmail(NotifyBase):
|
|||
|
||||
else:
|
||||
# If our target email list is empty we want to add ourselves to it
|
||||
self.targets.append(
|
||||
(self.from_name if self.from_name else False, self.from_addr))
|
||||
self.targets.append((False, self.from_addr[1]))
|
||||
|
||||
# Validate recipients (cc:) and drop bad ones:
|
||||
for recipient in parse_emails(cc):
|
||||
|
@ -562,6 +593,15 @@ class NotifyEmail(NotifyBase):
|
|||
# Apply any defaults based on certain known configurations
|
||||
self.NotifyEmailDefaults(secure_mode=secure_mode, **kwargs)
|
||||
|
||||
if not self.secure and self.secure_mode != SecureMailMode.INSECURE:
|
||||
# Enable Secure mode if not otherwise set
|
||||
self.secure = True
|
||||
|
||||
if not self.port:
|
||||
# Assign our port based on our secure_mode if not otherwise
|
||||
# detected
|
||||
self.port = SECURE_MODES[self.secure_mode]['default_port']
|
||||
|
||||
# if there is still no smtp_host then we fall back to the hostname
|
||||
if not self.smtp_host:
|
||||
self.smtp_host = self.host
|
||||
|
@ -625,11 +665,11 @@ class NotifyEmail(NotifyBase):
|
|||
if login_type:
|
||||
# only apply additional logic to our user if a login_type
|
||||
# was specified.
|
||||
if is_email(self.user) and \
|
||||
WebBaseLogin.EMAIL not in login_type:
|
||||
# Email specified but login type
|
||||
# not supported; switch it to user id
|
||||
self.user = match.group('id')
|
||||
if is_email(self.user):
|
||||
if WebBaseLogin.EMAIL not in login_type:
|
||||
# Email specified but login type
|
||||
# not supported; switch it to user id
|
||||
self.user = match.group('id')
|
||||
|
||||
elif WebBaseLogin.USERID not in login_type:
|
||||
# user specified but login type
|
||||
|
@ -656,18 +696,14 @@ class NotifyEmail(NotifyBase):
|
|||
Perform Email Notification
|
||||
"""
|
||||
|
||||
# Initialize our default from name
|
||||
from_name = self.from_name if self.from_name else self.app_desc
|
||||
|
||||
# error tracking (used for function return)
|
||||
has_error = False
|
||||
|
||||
if not self.targets:
|
||||
# There is no one to email; we're done
|
||||
self.logger.warning(
|
||||
'There are no Email recipients to notify')
|
||||
return False
|
||||
|
||||
messages: t.List[EmailMessage] = []
|
||||
|
||||
# Create a copy of the targets list
|
||||
emails = list(self.targets)
|
||||
while len(emails):
|
||||
|
@ -700,7 +736,9 @@ class NotifyEmail(NotifyBase):
|
|||
for addr in reply_to]
|
||||
|
||||
self.logger.debug(
|
||||
'Email From: {} <{}>'.format(from_name, self.from_addr))
|
||||
'Email From: {}'.format(
|
||||
formataddr(self.from_addr, charset='utf-8')))
|
||||
|
||||
self.logger.debug('Email To: {}'.format(to_addr))
|
||||
if cc:
|
||||
self.logger.debug('Email Cc: {}'.format(', '.join(cc)))
|
||||
|
@ -763,9 +801,7 @@ class NotifyEmail(NotifyBase):
|
|||
base[k] = Header(v, self._get_charset(v))
|
||||
|
||||
base['Subject'] = Header(title, self._get_charset(title))
|
||||
base['From'] = formataddr(
|
||||
(from_name if from_name else False, self.from_addr),
|
||||
charset='utf-8')
|
||||
base['From'] = formataddr(self.from_addr, charset='utf-8')
|
||||
base['To'] = formataddr((to_name, to_addr), charset='utf-8')
|
||||
base['Message-ID'] = make_msgid(domain=self.smtp_host)
|
||||
base['Date'] = \
|
||||
|
@ -778,58 +814,79 @@ class NotifyEmail(NotifyBase):
|
|||
if reply_to:
|
||||
base['Reply-To'] = ','.join(reply_to)
|
||||
|
||||
# bind the socket variable to the current namespace
|
||||
socket = None
|
||||
message = EmailMessage(
|
||||
recipient=to_addr,
|
||||
to_addrs=[to_addr] + list(cc) + list(bcc),
|
||||
body=base.as_string())
|
||||
messages.append(message)
|
||||
|
||||
# Always call throttle before any remote server i/o is made
|
||||
self.throttle()
|
||||
return self.submit(messages)
|
||||
|
||||
try:
|
||||
self.logger.debug('Connecting to remote SMTP server...')
|
||||
socket_func = smtplib.SMTP
|
||||
if self.secure and self.secure_mode == SecureMailMode.SSL:
|
||||
self.logger.debug('Securing connection with SSL...')
|
||||
socket_func = smtplib.SMTP_SSL
|
||||
def submit(self, messages: t.List[EmailMessage]):
|
||||
|
||||
socket = socket_func(
|
||||
self.smtp_host,
|
||||
self.port,
|
||||
None,
|
||||
timeout=self.socket_connect_timeout,
|
||||
)
|
||||
# error tracking (used for function return)
|
||||
has_error = False
|
||||
|
||||
if self.secure and self.secure_mode == SecureMailMode.STARTTLS:
|
||||
# Handle Secure Connections
|
||||
self.logger.debug('Securing connection with STARTTLS...')
|
||||
socket.starttls()
|
||||
# bind the socket variable to the current namespace
|
||||
socket = None
|
||||
|
||||
if self.user and self.password:
|
||||
# Apply Login credetials
|
||||
self.logger.debug('Applying user credentials...')
|
||||
socket.login(self.user, self.password)
|
||||
# Always call throttle before any remote server i/o is made
|
||||
self.throttle()
|
||||
|
||||
# Send the email
|
||||
socket.sendmail(
|
||||
self.from_addr,
|
||||
[to_addr] + list(cc) + list(bcc),
|
||||
base.as_string())
|
||||
try:
|
||||
self.logger.debug('Connecting to remote SMTP server...')
|
||||
socket_func = smtplib.SMTP
|
||||
if self.secure_mode == SecureMailMode.SSL:
|
||||
self.logger.debug('Securing connection with SSL...')
|
||||
socket_func = smtplib.SMTP_SSL
|
||||
|
||||
self.logger.info(
|
||||
'Sent Email notification to "{}".'.format(to_addr))
|
||||
socket = socket_func(
|
||||
self.smtp_host,
|
||||
self.port,
|
||||
None,
|
||||
timeout=self.socket_connect_timeout,
|
||||
)
|
||||
|
||||
except (SocketError, smtplib.SMTPException, RuntimeError) as e:
|
||||
self.logger.warning(
|
||||
'A Connection error occurred sending Email '
|
||||
'notification to {}.'.format(self.smtp_host))
|
||||
self.logger.debug('Socket Exception: %s' % str(e))
|
||||
if self.secure_mode == SecureMailMode.STARTTLS:
|
||||
# Handle Secure Connections
|
||||
self.logger.debug('Securing connection with STARTTLS...')
|
||||
socket.starttls()
|
||||
|
||||
# Mark our failure
|
||||
has_error = True
|
||||
if self.user and self.password:
|
||||
# Apply Login credetials
|
||||
self.logger.debug('Applying user credentials...')
|
||||
socket.login(self.user, self.password)
|
||||
|
||||
finally:
|
||||
# Gracefully terminate the connection with the server
|
||||
if socket is not None: # pragma: no branch
|
||||
socket.quit()
|
||||
# Send the emails
|
||||
for message in messages:
|
||||
try:
|
||||
socket.sendmail(
|
||||
self.from_addr[1],
|
||||
message.to_addrs,
|
||||
message.body)
|
||||
|
||||
self.logger.info(
|
||||
f'Sent Email notification to "{message.recipient}".')
|
||||
except (SocketError, smtplib.SMTPException, RuntimeError) as e:
|
||||
self.logger.warning(
|
||||
f'Sending email to "{message.recipient}" failed. '
|
||||
f'Reason: {e}')
|
||||
|
||||
# Mark as failure
|
||||
has_error = True
|
||||
|
||||
except (SocketError, smtplib.SMTPException, RuntimeError) as e:
|
||||
self.logger.warning(
|
||||
f'Connection error while submitting email to {self.smtp_host}.'
|
||||
f' Reason: {e}')
|
||||
|
||||
# Mark as failure
|
||||
has_error = True
|
||||
|
||||
finally:
|
||||
# Gracefully terminate the connection with the server
|
||||
if socket is not None: # pragma: no branch
|
||||
socket.quit()
|
||||
|
||||
return not has_error
|
||||
|
||||
|
@ -839,12 +896,7 @@ class NotifyEmail(NotifyBase):
|
|||
"""
|
||||
|
||||
# Define an URL parameters
|
||||
params = {
|
||||
'from': self.from_addr,
|
||||
'mode': self.secure_mode,
|
||||
'smtp': self.smtp_host,
|
||||
'user': self.user,
|
||||
}
|
||||
params = {}
|
||||
|
||||
# Append our headers into our parameters
|
||||
params.update({'+{}'.format(k): v for k, v in self.headers.items()})
|
||||
|
@ -852,30 +904,60 @@ class NotifyEmail(NotifyBase):
|
|||
# Extend our parameters
|
||||
params.update(self.url_parameters(privacy=privacy, *args, **kwargs))
|
||||
|
||||
if self.from_name:
|
||||
params['name'] = self.from_name
|
||||
from_addr = None
|
||||
if len(self.targets) == 1 and self.targets[0][1] != self.from_addr[1]:
|
||||
# A custom email was provided
|
||||
from_addr = self.from_addr[1]
|
||||
|
||||
if self.smtp_host != self.host:
|
||||
# Apply our SMTP Host only if it differs from the provided hostname
|
||||
params['smtp'] = self.smtp_host
|
||||
|
||||
if self.secure:
|
||||
# Mode is only requried if we're dealing with a secure connection
|
||||
params['mode'] = self.secure_mode
|
||||
|
||||
if self.from_addr[0] and self.from_addr[0] != self.app_id:
|
||||
# A custom name was provided
|
||||
params['from'] = self.from_addr[0] if not from_addr else \
|
||||
formataddr((self.from_addr[0], from_addr), charset='utf-8')
|
||||
|
||||
elif from_addr:
|
||||
params['from'] = formataddr((False, from_addr), charset='utf-8')
|
||||
|
||||
elif not self.user:
|
||||
params['from'] = \
|
||||
formataddr((False, self.from_addr[1]), charset='utf-8')
|
||||
|
||||
if len(self.cc) > 0:
|
||||
# Handle our Carbon Copy Addresses
|
||||
params['cc'] = ','.join(
|
||||
['{}{}'.format(
|
||||
'' if not e not in self.names
|
||||
else '{}:'.format(self.names[e]), e) for e in self.cc])
|
||||
params['cc'] = ','.join([
|
||||
formataddr(
|
||||
(self.names[e] if e in self.names else False, e),
|
||||
# Swap comma for it's escaped url code (if detected) since
|
||||
# we're using that as a delimiter
|
||||
charset='utf-8').replace(',', '%2C')
|
||||
for e in self.cc])
|
||||
|
||||
if len(self.bcc) > 0:
|
||||
# Handle our Blind Carbon Copy Addresses
|
||||
params['bcc'] = ','.join(
|
||||
['{}{}'.format(
|
||||
'' if not e not in self.names
|
||||
else '{}:'.format(self.names[e]), e) for e in self.bcc])
|
||||
params['bcc'] = ','.join([
|
||||
formataddr(
|
||||
(self.names[e] if e in self.names else False, e),
|
||||
# Swap comma for it's escaped url code (if detected) since
|
||||
# we're using that as a delimiter
|
||||
charset='utf-8').replace(',', '%2C')
|
||||
for e in self.bcc])
|
||||
|
||||
if self.reply_to:
|
||||
# Handle our Reply-To Addresses
|
||||
params['reply'] = ','.join(
|
||||
['{}{}'.format(
|
||||
'' if not e not in self.names
|
||||
else '{}:'.format(self.names[e]), e)
|
||||
for e in self.reply_to])
|
||||
params['reply'] = ','.join([
|
||||
formataddr(
|
||||
(self.names[e] if e in self.names else False, e),
|
||||
# Swap comma for it's escaped url code (if detected) since
|
||||
# we're using that as a delimiter
|
||||
charset='utf-8').replace(',', '%2C')
|
||||
for e in self.reply_to])
|
||||
|
||||
# pull email suffix from username (if present)
|
||||
user = None if not self.user else self.user.split('@')[0]
|
||||
|
@ -895,14 +977,13 @@ class NotifyEmail(NotifyBase):
|
|||
)
|
||||
|
||||
# Default Port setup
|
||||
default_port = \
|
||||
self.default_secure_port if self.secure else self.default_port
|
||||
default_port = SECURE_MODES[self.secure_mode]['default_port']
|
||||
|
||||
# a simple boolean check as to whether we display our target emails
|
||||
# or not
|
||||
has_targets = \
|
||||
not (len(self.targets) == 1
|
||||
and self.targets[0][1] == self.from_addr)
|
||||
and self.targets[0][1] == self.from_addr[1])
|
||||
|
||||
return '{schema}://{auth}{hostname}{port}/{targets}?{params}'.format(
|
||||
schema=self.secure_protocol if self.secure else self.protocol,
|
||||
|
@ -918,6 +999,13 @@ class NotifyEmail(NotifyBase):
|
|||
params=NotifyEmail.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -946,14 +1034,24 @@ class NotifyEmail(NotifyBase):
|
|||
if 'from' in results['qsd'] and len(results['qsd']['from']):
|
||||
from_addr = NotifyEmail.unquote(results['qsd']['from'])
|
||||
|
||||
if 'name' in results['qsd'] and len(results['qsd']['name']):
|
||||
# Depricate use of both `from=` and `name=` in the same url as
|
||||
# they will be synomomus of one another in the future.
|
||||
from_addr = formataddr(
|
||||
(NotifyEmail.unquote(results['qsd']['name']), from_addr),
|
||||
charset='utf-8')
|
||||
logger.warning(
|
||||
'Email name= and from= are synonymous; '
|
||||
'use one or the other.')
|
||||
|
||||
elif 'name' in results['qsd'] and len(results['qsd']['name']):
|
||||
# Extract from name to associate with from address
|
||||
from_addr = NotifyEmail.unquote(results['qsd']['name'])
|
||||
|
||||
# Attempt to detect 'to' email address
|
||||
if 'to' in results['qsd'] and len(results['qsd']['to']):
|
||||
results['targets'].append(results['qsd']['to'])
|
||||
|
||||
if 'name' in results['qsd'] and len(results['qsd']['name']):
|
||||
# Extract from name to associate with from address
|
||||
results['from_name'] = NotifyEmail.unquote(results['qsd']['name'])
|
||||
|
||||
# Store SMTP Host if specified
|
||||
if 'smtp' in results['qsd'] and len(results['qsd']['smtp']):
|
||||
# Extract the smtp server
|
||||
|
|
|
@ -1,30 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# For this plugin to work correct, the Emby server must be set up to allow
|
||||
# for remote connections.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Emby Docker configuration: https://hub.docker.com/r/emby/embyserver/
|
||||
# Authentication: https://github.com/MediaBrowser/Emby/wiki/Authentication
|
||||
|
@ -117,7 +121,7 @@ class NotifyEmby(NotifyBase):
|
|||
Initialize Emby Object
|
||||
|
||||
"""
|
||||
super(NotifyEmby, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
if self.secure:
|
||||
self.schema = 'https'
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Sources
|
||||
# - https://dreambox.de/en/
|
||||
|
@ -155,7 +162,7 @@ class NotifyEnigma2(NotifyBase):
|
|||
headers can be a dictionary of key/value pairs that you want to
|
||||
additionally include as part of the server headers to post with
|
||||
"""
|
||||
super(NotifyEnigma2, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
try:
|
||||
self.timeout = int(timeout)
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2021 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# For this plugin to work correct, the FCM server must be set up to allow
|
||||
# for remote connections.
|
||||
|
@ -218,7 +225,7 @@ class NotifyFCM(NotifyBase):
|
|||
Initialize Firebase Cloud Messaging
|
||||
|
||||
"""
|
||||
super(NotifyFCM, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
if mode is None:
|
||||
# Detect our mode
|
||||
|
@ -548,6 +555,12 @@ class NotifyFCM(NotifyBase):
|
|||
params=NotifyFCM.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2021 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# New priorities are defined here:
|
||||
# - https://firebase.google.com/docs/reference/fcm/rest/v1/\
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2021 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
class FCMMode:
|
||||
"""
|
||||
Define the Firebase Cloud Messaging Modes
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2021 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# To generate a private key file for your service account:
|
||||
#
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2021 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# New priorities are defined here:
|
||||
# - https://firebase.google.com/docs/reference/fcm/rest/v1/\
|
||||
|
|
|
@ -1,26 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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 CON
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import requests
|
||||
|
||||
|
@ -84,7 +92,7 @@ class NotifyFaast(NotifyBase):
|
|||
"""
|
||||
Initialize Faast Object
|
||||
"""
|
||||
super(NotifyFaast, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Store the Authentication Token
|
||||
self.authtoken = validate_regex(authtoken)
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# To use this plugin, you need to first access https://dev.flock.com/webhooks
|
||||
# Specifically https://dev.flock.com/webhooks/incoming
|
||||
|
@ -145,7 +152,7 @@ class NotifyFlock(NotifyBase):
|
|||
"""
|
||||
Initialize Flock Object
|
||||
"""
|
||||
super(NotifyFlock, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Build ourselves a target list
|
||||
self.targets = list()
|
||||
|
@ -327,6 +334,13 @@ class NotifyFlock(NotifyBase):
|
|||
params=NotifyFlock.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,28 +1,36 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import requests
|
||||
|
||||
from .NotifyBase import NotifyBase
|
||||
|
@ -32,13 +40,24 @@ from ..common import NotifyType
|
|||
from ..AppriseLocale import gettext_lazy as _
|
||||
|
||||
|
||||
class FORMPayloadField:
|
||||
"""
|
||||
Identifies the fields available in the FORM Payload
|
||||
"""
|
||||
VERSION = 'version'
|
||||
TITLE = 'title'
|
||||
MESSAGE = 'message'
|
||||
MESSAGETYPE = 'type'
|
||||
|
||||
|
||||
# Defines the method to send the notification
|
||||
METHODS = (
|
||||
'POST',
|
||||
'GET',
|
||||
'DELETE',
|
||||
'PUT',
|
||||
'HEAD'
|
||||
'HEAD',
|
||||
'PATCH'
|
||||
)
|
||||
|
||||
|
||||
|
@ -47,6 +66,27 @@ class NotifyForm(NotifyBase):
|
|||
A wrapper for Form Notifications
|
||||
"""
|
||||
|
||||
# Support
|
||||
# - file*
|
||||
# - file?
|
||||
# - file*name
|
||||
# - file?name
|
||||
# - ?file
|
||||
# - *file
|
||||
# - file
|
||||
# The code will convert the ? or * to the digit increments
|
||||
__attach_as_re = re.compile(
|
||||
r'((?P<match1>(?P<id1a>[a-z0-9_-]+)?'
|
||||
r'(?P<wc1>[*?+$:.%]+)(?P<id1b>[a-z0-9_-]+))'
|
||||
r'|(?P<match2>(?P<id2>[a-z0-9_-]+)(?P<wc2>[*?+$:.%]?)))',
|
||||
re.IGNORECASE)
|
||||
|
||||
# Our count
|
||||
attach_as_count = '{:02d}'
|
||||
|
||||
# the default attach_as value
|
||||
attach_as_default = f'file{attach_as_count}'
|
||||
|
||||
# The default descriptive name associated with the Notification
|
||||
service_name = 'Form'
|
||||
|
||||
|
@ -66,6 +106,12 @@ class NotifyForm(NotifyBase):
|
|||
# local anyway
|
||||
request_rate_per_sec = 0
|
||||
|
||||
# Define the FORM version to place in all payloads
|
||||
# Version: Major.Minor, Major is only updated if the entire schema is
|
||||
# changed. If just adding new items (or removing old ones, only increment
|
||||
# the Minor!
|
||||
form_version = '1.0'
|
||||
|
||||
# Define object templates
|
||||
templates = (
|
||||
'{schema}://{host}',
|
||||
|
@ -111,6 +157,12 @@ class NotifyForm(NotifyBase):
|
|||
'values': METHODS,
|
||||
'default': METHODS[0],
|
||||
},
|
||||
'attach-as': {
|
||||
'name': _('Attach File As'),
|
||||
'type': 'string',
|
||||
'default': 'file*',
|
||||
'map_to': 'attach_as',
|
||||
},
|
||||
})
|
||||
|
||||
# Define any kwargs we're using
|
||||
|
@ -123,9 +175,14 @@ class NotifyForm(NotifyBase):
|
|||
'name': _('Payload Extras'),
|
||||
'prefix': ':',
|
||||
},
|
||||
'params': {
|
||||
'name': _('GET Params'),
|
||||
'prefix': '-',
|
||||
},
|
||||
}
|
||||
|
||||
def __init__(self, headers=None, method=None, payload=None, **kwargs):
|
||||
def __init__(self, headers=None, method=None, payload=None, params=None,
|
||||
attach_as=None, **kwargs):
|
||||
"""
|
||||
Initialize Form Object
|
||||
|
||||
|
@ -133,7 +190,7 @@ class NotifyForm(NotifyBase):
|
|||
additionally include as part of the server headers to post with
|
||||
|
||||
"""
|
||||
super(NotifyForm, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.fullpath = kwargs.get('fullpath')
|
||||
if not isinstance(self.fullpath, str):
|
||||
|
@ -147,15 +204,72 @@ class NotifyForm(NotifyBase):
|
|||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
# Custom File Attachment Over-Ride Support
|
||||
if not isinstance(attach_as, str):
|
||||
# Default value
|
||||
self.attach_as = self.attach_as_default
|
||||
self.attach_multi_support = True
|
||||
|
||||
else:
|
||||
result = self.__attach_as_re.match(attach_as.strip())
|
||||
if not result:
|
||||
msg = 'The attach-as specified ({}) is invalid.'.format(
|
||||
attach_as)
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
self.attach_as = ''
|
||||
self.attach_multi_support = False
|
||||
if result.group('match1'):
|
||||
if result.group('id1a'):
|
||||
self.attach_as += result.group('id1a')
|
||||
|
||||
self.attach_as += self.attach_as_count
|
||||
self.attach_multi_support = True
|
||||
self.attach_as += result.group('id1b')
|
||||
|
||||
else: # result.group('match2'):
|
||||
self.attach_as += result.group('id2')
|
||||
if result.group('wc2'):
|
||||
self.attach_as += self.attach_as_count
|
||||
self.attach_multi_support = True
|
||||
|
||||
# A payload map allows users to over-ride the default mapping if
|
||||
# they're detected with the :overide=value. Normally this would
|
||||
# create a new key and assign it the value specified. However
|
||||
# if the key you specify is actually an internally mapped one,
|
||||
# then a re-mapping takes place using the value
|
||||
self.payload_map = {
|
||||
FORMPayloadField.VERSION: FORMPayloadField.VERSION,
|
||||
FORMPayloadField.TITLE: FORMPayloadField.TITLE,
|
||||
FORMPayloadField.MESSAGE: FORMPayloadField.MESSAGE,
|
||||
FORMPayloadField.MESSAGETYPE: FORMPayloadField.MESSAGETYPE,
|
||||
}
|
||||
|
||||
self.params = {}
|
||||
if params:
|
||||
# Store our extra headers
|
||||
self.params.update(params)
|
||||
|
||||
self.headers = {}
|
||||
if headers:
|
||||
# Store our extra headers
|
||||
self.headers.update(headers)
|
||||
|
||||
self.payload_overrides = {}
|
||||
self.payload_extras = {}
|
||||
if payload:
|
||||
# Store our extra payload entries
|
||||
self.payload_extras.update(payload)
|
||||
for key in list(self.payload_extras.keys()):
|
||||
# Any values set in the payload to alter a system related one
|
||||
# alters the system key. Hence :message=msg maps the 'message'
|
||||
# variable that otherwise already contains the payload to be
|
||||
# 'msg' instead (containing the payload)
|
||||
if key in self.payload_map:
|
||||
self.payload_map[key] = self.payload_extras[key]
|
||||
self.payload_overrides[key] = self.payload_extras[key]
|
||||
del self.payload_extras[key]
|
||||
|
||||
return
|
||||
|
||||
|
@ -175,9 +289,18 @@ class NotifyForm(NotifyBase):
|
|||
# Append our headers into our parameters
|
||||
params.update({'+{}'.format(k): v for k, v in self.headers.items()})
|
||||
|
||||
# Append our GET params into our parameters
|
||||
params.update({'-{}'.format(k): v for k, v in self.params.items()})
|
||||
|
||||
# Append our payload extra's into our parameters
|
||||
params.update(
|
||||
{':{}'.format(k): v for k, v in self.payload_extras.items()})
|
||||
params.update(
|
||||
{':{}'.format(k): v for k, v in self.payload_overrides.items()})
|
||||
|
||||
if self.attach_as != self.attach_as_default:
|
||||
# Provide Attach-As extension details
|
||||
params['attach-as'] = self.attach_as
|
||||
|
||||
# Determine Authentication
|
||||
auth = ''
|
||||
|
@ -212,6 +335,7 @@ class NotifyForm(NotifyBase):
|
|||
Perform Form Notification
|
||||
"""
|
||||
|
||||
# Prepare HTTP Headers
|
||||
headers = {
|
||||
'User-Agent': self.app_id,
|
||||
}
|
||||
|
@ -233,7 +357,8 @@ class NotifyForm(NotifyBase):
|
|||
|
||||
try:
|
||||
files.append((
|
||||
'file{:02d}'.format(no), (
|
||||
self.attach_as.format(no)
|
||||
if self.attach_multi_support else self.attach_as, (
|
||||
attachment.name,
|
||||
open(attachment.path, 'rb'),
|
||||
attachment.mimetype)
|
||||
|
@ -246,22 +371,24 @@ class NotifyForm(NotifyBase):
|
|||
self.logger.debug('I/O Exception: %s' % str(e))
|
||||
return False
|
||||
|
||||
finally:
|
||||
for file in files:
|
||||
# Ensure all files are closed
|
||||
if file[1][1]:
|
||||
file[1][1].close()
|
||||
if not self.attach_multi_support and no > 1:
|
||||
self.logger.warning(
|
||||
'Multiple attachments provided while '
|
||||
'form:// Multi-Attachment Support not enabled')
|
||||
|
||||
# prepare Form Object
|
||||
payload = {
|
||||
# Version: Major.Minor, Major is only updated if the entire
|
||||
# schema is changed. If just adding new items (or removing
|
||||
# old ones, only increment the Minor!
|
||||
'version': '1.0',
|
||||
'title': title,
|
||||
'message': body,
|
||||
'type': notify_type,
|
||||
}
|
||||
payload = {}
|
||||
|
||||
for key, value in (
|
||||
(FORMPayloadField.VERSION, self.form_version),
|
||||
(FORMPayloadField.TITLE, title),
|
||||
(FORMPayloadField.MESSAGE, body),
|
||||
(FORMPayloadField.MESSAGETYPE, notify_type)):
|
||||
|
||||
if not self.payload_map[key]:
|
||||
# Do not store element in payload response
|
||||
continue
|
||||
payload[self.payload_map[key]] = value
|
||||
|
||||
# Apply any/all payload over-rides defined
|
||||
payload.update(self.payload_extras)
|
||||
|
@ -289,10 +416,14 @@ class NotifyForm(NotifyBase):
|
|||
|
||||
if self.method == 'GET':
|
||||
method = requests.get
|
||||
payload.update(self.params)
|
||||
|
||||
elif self.method == 'PUT':
|
||||
method = requests.put
|
||||
|
||||
elif self.method == 'PATCH':
|
||||
method = requests.patch
|
||||
|
||||
elif self.method == 'DELETE':
|
||||
method = requests.delete
|
||||
|
||||
|
@ -307,7 +438,7 @@ class NotifyForm(NotifyBase):
|
|||
url,
|
||||
files=None if not files else files,
|
||||
data=payload if self.method != 'GET' else None,
|
||||
params=payload if self.method == 'GET' else None,
|
||||
params=payload if self.method == 'GET' else self.params,
|
||||
headers=headers,
|
||||
auth=auth,
|
||||
verify=self.verify_certificate,
|
||||
|
@ -377,6 +508,16 @@ class NotifyForm(NotifyBase):
|
|||
results['headers'] = {NotifyForm.unquote(x): NotifyForm.unquote(y)
|
||||
for x, y in results['qsd+'].items()}
|
||||
|
||||
# Add our GET paramters in the event the user wants to pass these along
|
||||
results['params'] = {NotifyForm.unquote(x): NotifyForm.unquote(y)
|
||||
for x, y in results['qsd-'].items()}
|
||||
|
||||
# Allow Attach-As Support which over-rides the name of the filename
|
||||
# posted with the form://
|
||||
# the default is file01, file02, file03, etc
|
||||
if 'attach-as' in results['qsd'] and len(results['qsd']['attach-as']):
|
||||
results['attach_as'] = results['qsd']['attach-as']
|
||||
|
||||
# Set method if not otherwise set
|
||||
if 'method' in results['qsd'] and len(results['qsd']['method']):
|
||||
results['method'] = NotifyForm.unquote(results['qsd']['method'])
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Once you visit: https://developer.gitter.im/apps you'll get a personal
|
||||
# access token that will look something like this:
|
||||
|
@ -137,7 +144,7 @@ class NotifyGitter(NotifyBase):
|
|||
"""
|
||||
Initialize Gitter Object
|
||||
"""
|
||||
super(NotifyGitter, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Secret Key (associated with project)
|
||||
self.token = validate_regex(
|
||||
|
@ -382,6 +389,12 @@ class NotifyGitter(NotifyBase):
|
|||
[NotifyGitter.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyGitter.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
@ -54,8 +61,8 @@ except (ImportError, ValueError, AttributeError):
|
|||
# be in microsoft windows, or we just don't have the python-gobject
|
||||
# library available to us (or maybe one we don't support)?
|
||||
|
||||
# Alternativey A ValueError will get thrown upon calling
|
||||
# gi.require_version() if the requested Notify namespace isn't available
|
||||
# Alternatively, a `ValueError` will get raised upon calling
|
||||
# gi.require_version() if the requested Notify namespace isn't available.
|
||||
pass
|
||||
|
||||
|
||||
|
@ -164,7 +171,7 @@ class NotifyGnome(NotifyBase):
|
|||
Initialize Gnome Object
|
||||
"""
|
||||
|
||||
super(NotifyGnome, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# The urgency of the message
|
||||
self.urgency = int(
|
||||
|
@ -175,12 +182,9 @@ class NotifyGnome(NotifyBase):
|
|||
if str(urgency).lower().startswith(k)),
|
||||
NotifyGnome.template_args['urgency']['default']))
|
||||
|
||||
# Track whether or not we want to send an image with our notification
|
||||
# or not.
|
||||
# Track whether we want to add an image to the notification.
|
||||
self.include_image = include_image
|
||||
|
||||
return
|
||||
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
|
||||
"""
|
||||
Perform Gnome Notification
|
||||
|
@ -214,15 +218,15 @@ class NotifyGnome(NotifyBase):
|
|||
|
||||
except Exception as e:
|
||||
self.logger.warning(
|
||||
"Could not load Gnome notification icon ({}): {}"
|
||||
.format(icon_path, e))
|
||||
"Could not load notification icon (%s).", icon_path)
|
||||
self.logger.debug(f'Gnome Exception: {e}')
|
||||
|
||||
notification.show()
|
||||
self.logger.info('Sent Gnome notification.')
|
||||
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
self.logger.warning('Failed to send Gnome notification.')
|
||||
self.logger.exception('Gnome Exception')
|
||||
self.logger.debug(f'Gnome Exception: {e}')
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2021 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# For this to work correctly you need to create a webhook. You'll also
|
||||
# need a GSuite account (there are free trials if you don't have one)
|
||||
|
@ -80,8 +87,7 @@ class NotifyGoogleChat(NotifyBase):
|
|||
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_googlechat'
|
||||
|
||||
# Google Chat Webhook
|
||||
notify_url = 'https://chat.googleapis.com/v1/spaces/{workspace}/messages' \
|
||||
'?key={key}&token={token}'
|
||||
notify_url = 'https://chat.googleapis.com/v1/spaces/{workspace}/messages'
|
||||
|
||||
# Default Notify Format
|
||||
notify_format = NotifyFormat.MARKDOWN
|
||||
|
@ -96,6 +102,7 @@ class NotifyGoogleChat(NotifyBase):
|
|||
# Define object templates
|
||||
templates = (
|
||||
'{schema}://{workspace}/{webhook_key}/{webhook_token}',
|
||||
'{schema}://{workspace}/{webhook_key}/{webhook_token}/{thread_key}',
|
||||
)
|
||||
|
||||
# Define our template tokens
|
||||
|
@ -118,6 +125,11 @@ class NotifyGoogleChat(NotifyBase):
|
|||
'private': True,
|
||||
'required': True,
|
||||
},
|
||||
'thread_key': {
|
||||
'name': _('Thread Key'),
|
||||
'type': 'string',
|
||||
'private': True,
|
||||
},
|
||||
})
|
||||
|
||||
# Define our template arguments
|
||||
|
@ -131,14 +143,18 @@ class NotifyGoogleChat(NotifyBase):
|
|||
'token': {
|
||||
'alias_of': 'webhook_token',
|
||||
},
|
||||
'thread': {
|
||||
'alias_of': 'thread_key',
|
||||
},
|
||||
})
|
||||
|
||||
def __init__(self, workspace, webhook_key, webhook_token, **kwargs):
|
||||
def __init__(self, workspace, webhook_key, webhook_token,
|
||||
thread_key=None, **kwargs):
|
||||
"""
|
||||
Initialize Google Chat Object
|
||||
|
||||
"""
|
||||
super(NotifyGoogleChat, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Workspace (associated with project)
|
||||
self.workspace = validate_regex(workspace)
|
||||
|
@ -164,6 +180,16 @@ class NotifyGoogleChat(NotifyBase):
|
|||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
if thread_key:
|
||||
self.thread_key = validate_regex(thread_key)
|
||||
if not self.thread_key:
|
||||
msg = 'An invalid Google Chat Thread Key ' \
|
||||
'({}) was specified.'.format(thread_key)
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
else:
|
||||
self.thread_key = None
|
||||
|
||||
return
|
||||
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
|
||||
|
@ -185,13 +211,21 @@ class NotifyGoogleChat(NotifyBase):
|
|||
# Construct Notify URL
|
||||
notify_url = self.notify_url.format(
|
||||
workspace=self.workspace,
|
||||
key=self.webhook_key,
|
||||
token=self.webhook_token,
|
||||
)
|
||||
|
||||
params = {
|
||||
# Prepare our URL Parameters
|
||||
'token': self.webhook_token,
|
||||
'key': self.webhook_key,
|
||||
}
|
||||
|
||||
if self.thread_key:
|
||||
params['threadKey'] = self.thread_key
|
||||
|
||||
self.logger.debug('Google Chat POST URL: %s (cert_verify=%r)' % (
|
||||
notify_url, self.verify_certificate,
|
||||
))
|
||||
self.logger.debug('Google Chat Parameters: %s' % str(params))
|
||||
self.logger.debug('Google Chat Payload: %s' % str(payload))
|
||||
|
||||
# Always call throttle before any remote server i/o is made
|
||||
|
@ -199,6 +233,7 @@ class NotifyGoogleChat(NotifyBase):
|
|||
try:
|
||||
r = requests.post(
|
||||
notify_url,
|
||||
params=params,
|
||||
data=dumps(payload),
|
||||
headers=headers,
|
||||
verify=self.verify_certificate,
|
||||
|
@ -242,11 +277,13 @@ class NotifyGoogleChat(NotifyBase):
|
|||
# Set our parameters
|
||||
params = self.url_parameters(privacy=privacy, *args, **kwargs)
|
||||
|
||||
return '{schema}://{workspace}/{key}/{token}/?{params}'.format(
|
||||
return '{schema}://{workspace}/{key}/{token}/{thread}?{params}'.format(
|
||||
schema=self.secure_protocol,
|
||||
workspace=self.pprint(self.workspace, privacy, safe=''),
|
||||
key=self.pprint(self.webhook_key, privacy, safe=''),
|
||||
token=self.pprint(self.webhook_token, privacy, safe=''),
|
||||
thread='' if not self.thread_key
|
||||
else self.pprint(self.thread_key, privacy, safe=''),
|
||||
params=NotifyGoogleChat.urlencode(params),
|
||||
)
|
||||
|
||||
|
@ -258,6 +295,7 @@ class NotifyGoogleChat(NotifyBase):
|
|||
|
||||
Syntax:
|
||||
gchat://workspace/webhook_key/webhook_token
|
||||
gchat://workspace/webhook_key/webhook_token/thread_key
|
||||
|
||||
"""
|
||||
results = NotifyBase.parse_url(url, verify_host=False)
|
||||
|
@ -277,6 +315,9 @@ class NotifyGoogleChat(NotifyBase):
|
|||
# Store our Webhook Token
|
||||
results['webhook_token'] = tokens.pop(0) if tokens else None
|
||||
|
||||
# Store our Thread Key
|
||||
results['thread_key'] = tokens.pop(0) if tokens else None
|
||||
|
||||
# Support arguments as overrides (if specified)
|
||||
if 'workspace' in results['qsd']:
|
||||
results['workspace'] = \
|
||||
|
@ -290,6 +331,17 @@ class NotifyGoogleChat(NotifyBase):
|
|||
results['webhook_token'] = \
|
||||
NotifyGoogleChat.unquote(results['qsd']['token'])
|
||||
|
||||
if 'thread' in results['qsd']:
|
||||
results['thread_key'] = \
|
||||
NotifyGoogleChat.unquote(results['qsd']['thread'])
|
||||
|
||||
elif 'threadkey' in results['qsd']:
|
||||
# Support Google Chat's Thread Key (if set)
|
||||
# keys are always made lowercase; so check above is attually
|
||||
# testing threadKey successfully as well
|
||||
results['thread_key'] = \
|
||||
NotifyGoogleChat.unquote(results['qsd']['threadkey'])
|
||||
|
||||
return results
|
||||
|
||||
@staticmethod
|
||||
|
@ -298,6 +350,8 @@ class NotifyGoogleChat(NotifyBase):
|
|||
Support
|
||||
https://chat.googleapis.com/v1/spaces/{workspace}/messages
|
||||
'?key={key}&token={token}
|
||||
https://chat.googleapis.com/v1/spaces/{workspace}/messages
|
||||
'?key={key}&token={token}&threadKey={thread}
|
||||
"""
|
||||
|
||||
result = re.match(
|
||||
|
|
|
@ -1,30 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# For this plugin to work correct, the Gotify server must be set up to allow
|
||||
# for remote connections.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Gotify Docker configuration: https://hub.docker.com/r/gotify/server
|
||||
# Example: https://github.com/gotify/server/blob/\
|
||||
|
@ -155,7 +159,7 @@ class NotifyGotify(NotifyBase):
|
|||
Initialize Gotify Object
|
||||
|
||||
"""
|
||||
super(NotifyGotify, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Token (associated with project)
|
||||
self.token = validate_regex(token)
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from .NotifyBase import NotifyBase
|
||||
from ..URLBase import PrivacyMode
|
||||
|
@ -187,7 +194,7 @@ class NotifyGrowl(NotifyBase):
|
|||
"""
|
||||
Initialize Growl Object
|
||||
"""
|
||||
super(NotifyGrowl, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
if not self.port:
|
||||
self.port = self.default_port
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# For this to work correctly you need to create a webhook. To do this just
|
||||
# click on the little gear icon next to the channel you're part of. From
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2021 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# You must generate a "Long-Lived Access Token". This can be done from your
|
||||
# Home Assistant Profile page.
|
||||
|
@ -115,7 +122,7 @@ class NotifyHomeAssistant(NotifyBase):
|
|||
"""
|
||||
Initialize Home Assistant Object
|
||||
"""
|
||||
super(NotifyHomeAssistant, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.fullpath = kwargs.get('fullpath', '')
|
||||
|
||||
|
|
|
@ -1,29 +1,35 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# IFTTT (If-This-Then-That)
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 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 :
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# 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.
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#
|
||||
# For this plugin to work, you need to add the Maker applet to your profile
|
||||
# Simply visit https://ifttt.com/search and search for 'Webhooks'
|
||||
|
@ -147,7 +153,7 @@ class NotifyIFTTT(NotifyBase):
|
|||
reference to Value1, Value2, and/or Value3
|
||||
|
||||
"""
|
||||
super(NotifyIFTTT, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Webhook ID (associated with project)
|
||||
self.webhook_id = validate_regex(webhook_id)
|
||||
|
@ -306,6 +312,12 @@ class NotifyIFTTT(NotifyBase):
|
|||
params=NotifyIFTTT.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.events)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import requests
|
||||
import base64
|
||||
|
@ -34,13 +41,25 @@ from ..common import NotifyType
|
|||
from ..AppriseLocale import gettext_lazy as _
|
||||
|
||||
|
||||
class JSONPayloadField:
|
||||
"""
|
||||
Identifies the fields available in the JSON Payload
|
||||
"""
|
||||
VERSION = 'version'
|
||||
TITLE = 'title'
|
||||
MESSAGE = 'message'
|
||||
ATTACHMENTS = 'attachments'
|
||||
MESSAGETYPE = 'type'
|
||||
|
||||
|
||||
# Defines the method to send the notification
|
||||
METHODS = (
|
||||
'POST',
|
||||
'GET',
|
||||
'DELETE',
|
||||
'PUT',
|
||||
'HEAD'
|
||||
'HEAD',
|
||||
'PATCH'
|
||||
)
|
||||
|
||||
|
||||
|
@ -68,6 +87,12 @@ class NotifyJSON(NotifyBase):
|
|||
# local anyway
|
||||
request_rate_per_sec = 0
|
||||
|
||||
# Define the JSON version to place in all payloads
|
||||
# Version: Major.Minor, Major is only updated if the entire schema is
|
||||
# changed. If just adding new items (or removing old ones, only increment
|
||||
# the Minor!
|
||||
json_version = '1.0'
|
||||
|
||||
# Define object templates
|
||||
templates = (
|
||||
'{schema}://{host}',
|
||||
|
@ -125,9 +150,14 @@ class NotifyJSON(NotifyBase):
|
|||
'name': _('Payload Extras'),
|
||||
'prefix': ':',
|
||||
},
|
||||
'params': {
|
||||
'name': _('GET Params'),
|
||||
'prefix': '-',
|
||||
},
|
||||
}
|
||||
|
||||
def __init__(self, headers=None, method=None, payload=None, **kwargs):
|
||||
def __init__(self, headers=None, method=None, payload=None, params=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Initialize JSON Object
|
||||
|
||||
|
@ -135,7 +165,7 @@ class NotifyJSON(NotifyBase):
|
|||
additionally include as part of the server headers to post with
|
||||
|
||||
"""
|
||||
super(NotifyJSON, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.fullpath = kwargs.get('fullpath')
|
||||
if not isinstance(self.fullpath, str):
|
||||
|
@ -149,15 +179,44 @@ class NotifyJSON(NotifyBase):
|
|||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
# A payload map allows users to over-ride the default mapping if
|
||||
# they're detected with the :overide=value. Normally this would
|
||||
# create a new key and assign it the value specified. However
|
||||
# if the key you specify is actually an internally mapped one,
|
||||
# then a re-mapping takes place using the value
|
||||
self.payload_map = {
|
||||
JSONPayloadField.VERSION: JSONPayloadField.VERSION,
|
||||
JSONPayloadField.TITLE: JSONPayloadField.TITLE,
|
||||
JSONPayloadField.MESSAGE: JSONPayloadField.MESSAGE,
|
||||
JSONPayloadField.ATTACHMENTS: JSONPayloadField.ATTACHMENTS,
|
||||
JSONPayloadField.MESSAGETYPE: JSONPayloadField.MESSAGETYPE,
|
||||
}
|
||||
|
||||
self.params = {}
|
||||
if params:
|
||||
# Store our extra headers
|
||||
self.params.update(params)
|
||||
|
||||
self.headers = {}
|
||||
if headers:
|
||||
# Store our extra headers
|
||||
self.headers.update(headers)
|
||||
|
||||
self.payload_overrides = {}
|
||||
self.payload_extras = {}
|
||||
if payload:
|
||||
# Store our extra payload entries
|
||||
self.payload_extras.update(payload)
|
||||
for key in list(self.payload_extras.keys()):
|
||||
# Any values set in the payload to alter a system related one
|
||||
# alters the system key. Hence :message=msg maps the 'message'
|
||||
# variable that otherwise already contains the payload to be
|
||||
# 'msg' instead (containing the payload)
|
||||
if key in self.payload_map:
|
||||
self.payload_map[key] = self.payload_extras[key].strip()
|
||||
self.payload_overrides[key] = \
|
||||
self.payload_extras[key].strip()
|
||||
del self.payload_extras[key]
|
||||
|
||||
return
|
||||
|
||||
|
@ -177,9 +236,14 @@ class NotifyJSON(NotifyBase):
|
|||
# Append our headers into our parameters
|
||||
params.update({'+{}'.format(k): v for k, v in self.headers.items()})
|
||||
|
||||
# Append our GET params into our parameters
|
||||
params.update({'-{}'.format(k): v for k, v in self.params.items()})
|
||||
|
||||
# Append our payload extra's into our parameters
|
||||
params.update(
|
||||
{':{}'.format(k): v for k, v in self.payload_extras.items()})
|
||||
params.update(
|
||||
{':{}'.format(k): v for k, v in self.payload_overrides.items()})
|
||||
|
||||
# Determine Authentication
|
||||
auth = ''
|
||||
|
@ -214,6 +278,7 @@ class NotifyJSON(NotifyBase):
|
|||
Perform JSON Notification
|
||||
"""
|
||||
|
||||
# Prepare HTTP Headers
|
||||
headers = {
|
||||
'User-Agent': self.app_id,
|
||||
'Content-Type': 'application/json'
|
||||
|
@ -253,16 +318,18 @@ class NotifyJSON(NotifyBase):
|
|||
return False
|
||||
|
||||
# prepare JSON Object
|
||||
payload = {
|
||||
# Version: Major.Minor, Major is only updated if the entire
|
||||
# schema is changed. If just adding new items (or removing
|
||||
# old ones, only increment the Minor!
|
||||
'version': '1.0',
|
||||
'title': title,
|
||||
'message': body,
|
||||
'attachments': attachments,
|
||||
'type': notify_type,
|
||||
}
|
||||
payload = {}
|
||||
for key, value in (
|
||||
(JSONPayloadField.VERSION, self.json_version),
|
||||
(JSONPayloadField.TITLE, title),
|
||||
(JSONPayloadField.MESSAGE, body),
|
||||
(JSONPayloadField.ATTACHMENTS, attachments),
|
||||
(JSONPayloadField.MESSAGETYPE, notify_type)):
|
||||
|
||||
if not self.payload_map[key]:
|
||||
# Do not store element in payload response
|
||||
continue
|
||||
payload[self.payload_map[key]] = value
|
||||
|
||||
# Apply any/all payload over-rides defined
|
||||
payload.update(self.payload_extras)
|
||||
|
@ -294,6 +361,9 @@ class NotifyJSON(NotifyBase):
|
|||
elif self.method == 'PUT':
|
||||
method = requests.put
|
||||
|
||||
elif self.method == 'PATCH':
|
||||
method = requests.patch
|
||||
|
||||
elif self.method == 'DELETE':
|
||||
method = requests.delete
|
||||
|
||||
|
@ -307,6 +377,7 @@ class NotifyJSON(NotifyBase):
|
|||
r = method(
|
||||
url,
|
||||
data=dumps(payload),
|
||||
params=self.params,
|
||||
headers=headers,
|
||||
auth=auth,
|
||||
verify=self.verify_certificate,
|
||||
|
@ -364,6 +435,10 @@ class NotifyJSON(NotifyBase):
|
|||
results['headers'] = {NotifyJSON.unquote(x): NotifyJSON.unquote(y)
|
||||
for x, y in results['qsd+'].items()}
|
||||
|
||||
# Add our GET paramters in the event the user wants to pass these along
|
||||
results['params'] = {NotifyJSON.unquote(x): NotifyJSON.unquote(y)
|
||||
for x, y in results['qsd-'].items()}
|
||||
|
||||
# Set method if not otherwise set
|
||||
if 'method' in results['qsd'] and len(results['qsd']['method']):
|
||||
results['method'] = NotifyJSON.unquote(results['qsd']['method'])
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Join URL: http://joaoapps.com/join/
|
||||
# To use this plugin, you need to first access (make sure your browser allows
|
||||
|
@ -194,7 +201,7 @@ class NotifyJoin(NotifyBase):
|
|||
"""
|
||||
Initialize Join Object
|
||||
"""
|
||||
super(NotifyJoin, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Track whether or not we want to send an image with our notification
|
||||
# or not.
|
||||
|
@ -366,6 +373,12 @@ class NotifyJoin(NotifyBase):
|
|||
for x in self.targets]),
|
||||
params=NotifyJoin.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# To use this service you will need a Kavenegar account from their website
|
||||
# at https://kavenegar.com/
|
||||
|
@ -149,7 +156,7 @@ class NotifyKavenegar(NotifyBase):
|
|||
"""
|
||||
Initialize Kavenegar Object
|
||||
"""
|
||||
super(NotifyKavenegar, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# API Key (associated with project)
|
||||
self.apikey = validate_regex(
|
||||
|
@ -317,6 +324,12 @@ class NotifyKavenegar(NotifyBase):
|
|||
[NotifyKavenegar.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyKavenegar.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# To use this plugin, you must have a Kumulos account set up. Add a client
|
||||
# and link it with your phone using the phone app (using your Companion App
|
||||
|
@ -104,7 +111,7 @@ class NotifyKumulos(NotifyBase):
|
|||
"""
|
||||
Initialize Kumulos Object
|
||||
"""
|
||||
super(NotifyKumulos, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# API Key (associated with project)
|
||||
self.apikey = validate_regex(
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# For LaMetric to work, you need to first setup a custom application on their
|
||||
# website. it can be done as follows:
|
||||
|
@ -467,7 +474,7 @@ class NotifyLametric(NotifyBase):
|
|||
"""
|
||||
Initialize LaMetric Object
|
||||
"""
|
||||
super(NotifyLametric, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.mode = mode.strip().lower() \
|
||||
if isinstance(mode, str) \
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#
|
||||
# API Docs: https://developers.line.biz/en/reference/messaging-api/
|
||||
|
||||
|
@ -114,7 +122,7 @@ class NotifyLine(NotifyBase):
|
|||
"""
|
||||
Initialize Line Object
|
||||
"""
|
||||
super(NotifyLine, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Long-Lived Access token (generated from User Profile)
|
||||
self.token = validate_regex(token)
|
||||
|
@ -259,6 +267,12 @@ class NotifyLine(NotifyBase):
|
|||
params=NotifyLine.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2021 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# PAHO MQTT Documentation:
|
||||
# https://www.eclipse.org/paho/index.php?page=clients/python/docs/index.php
|
||||
|
@ -132,20 +139,6 @@ class NotifyMQTT(NotifyBase):
|
|||
# through their network flow at once.
|
||||
mqtt_inflight_messages = 200
|
||||
|
||||
# Taken from https://golang.org/src/crypto/x509/root_linux.go
|
||||
CA_CERTIFICATE_FILE_LOCATIONS = [
|
||||
# Debian/Ubuntu/Gentoo etc.
|
||||
"/etc/ssl/certs/ca-certificates.crt",
|
||||
# Fedora/RHEL 6
|
||||
"/etc/pki/tls/certs/ca-bundle.crt",
|
||||
# OpenSUSE
|
||||
"/etc/ssl/ca-bundle.pem",
|
||||
# OpenELEC
|
||||
"/etc/pki/tls/cacert.pem",
|
||||
# CentOS/RHEL 7
|
||||
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
|
||||
]
|
||||
|
||||
# Define object templates
|
||||
templates = (
|
||||
'{schema}://{user}@{host}/{topic}',
|
||||
|
@ -223,7 +216,7 @@ class NotifyMQTT(NotifyBase):
|
|||
Initialize MQTT Object
|
||||
"""
|
||||
|
||||
super(NotifyMQTT, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Initialize topics
|
||||
self.topics = parse_list(targets)
|
||||
|
@ -264,6 +257,9 @@ class NotifyMQTT(NotifyBase):
|
|||
self.ca_certs = None
|
||||
if self.secure:
|
||||
# verify SSL key or abort
|
||||
# TODO: There is no error reporting or aborting here?
|
||||
# It could be useful to inform the user _where_ Apprise
|
||||
# tried to find the root CA certificates file.
|
||||
self.ca_certs = next(
|
||||
(cert for cert in self.CA_CERTIFICATE_FILE_LOCATIONS
|
||||
if isfile(cert)), None)
|
||||
|
@ -316,9 +312,9 @@ class NotifyMQTT(NotifyBase):
|
|||
|
||||
if self.secure:
|
||||
if self.ca_certs is None:
|
||||
self.logger.warning(
|
||||
'MQTT Secure comunication can not be verified; '
|
||||
'no local CA certificate file')
|
||||
self.logger.error(
|
||||
'MQTT secure communication can not be verified, '
|
||||
'CA certificates file missing')
|
||||
return False
|
||||
|
||||
self.client.tls_set(
|
||||
|
@ -328,7 +324,7 @@ class NotifyMQTT(NotifyBase):
|
|||
ciphers=None)
|
||||
|
||||
# Set our TLS Verify Flag
|
||||
self.client.tls_insecure_set(self.verify_certificate)
|
||||
self.client.tls_insecure_set(not self.verify_certificate)
|
||||
|
||||
# Establish our connection
|
||||
if self.client.connect(
|
||||
|
@ -480,6 +476,12 @@ class NotifyMQTT(NotifyBase):
|
|||
params=NotifyMQTT.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.topics)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -528,3 +530,38 @@ class NotifyMQTT(NotifyBase):
|
|||
|
||||
# return results
|
||||
return results
|
||||
|
||||
@property
|
||||
def CA_CERTIFICATE_FILE_LOCATIONS(self):
|
||||
"""
|
||||
Return possible locations to root certificate authority (CA) bundles.
|
||||
|
||||
Taken from https://golang.org/src/crypto/x509/root_linux.go
|
||||
TODO: Maybe refactor to a general utility function?
|
||||
"""
|
||||
candidates = [
|
||||
# Debian/Ubuntu/Gentoo etc.
|
||||
"/etc/ssl/certs/ca-certificates.crt",
|
||||
# Fedora/RHEL 6
|
||||
"/etc/pki/tls/certs/ca-bundle.crt",
|
||||
# OpenSUSE
|
||||
"/etc/ssl/ca-bundle.pem",
|
||||
# OpenELEC
|
||||
"/etc/pki/tls/cacert.pem",
|
||||
# CentOS/RHEL 7
|
||||
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
|
||||
# macOS Homebrew; brew install ca-certificates
|
||||
"/usr/local/etc/ca-certificates/cert.pem",
|
||||
]
|
||||
|
||||
# Certifi provides Mozilla’s carefully curated collection of Root
|
||||
# Certificates for validating the trustworthiness of SSL certificates
|
||||
# while verifying the identity of TLS hosts. It has been extracted from
|
||||
# the Requests project.
|
||||
try:
|
||||
import certifi
|
||||
candidates.append(certifi.where())
|
||||
except ImportError: # pragma: no cover
|
||||
pass
|
||||
|
||||
return candidates
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Create an account https://msg91.com/ if you don't already have one
|
||||
#
|
||||
|
@ -156,7 +163,7 @@ class NotifyMSG91(NotifyBase):
|
|||
"""
|
||||
Initialize MSG91 Object
|
||||
"""
|
||||
super(NotifyMSG91, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Authentication Key (associated with project)
|
||||
self.authkey = validate_regex(
|
||||
|
@ -322,6 +329,12 @@ class NotifyMSG91(NotifyBase):
|
|||
[NotifyMSG91.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyMSG91.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# To use this plugin, you need to create a webhook; you can read more about
|
||||
# this here:
|
||||
|
@ -214,7 +221,7 @@ class NotifyMSTeams(NotifyBase):
|
|||
template arguments that can not be over-ridden are:
|
||||
`body`, `title`, and `type`.
|
||||
"""
|
||||
super(NotifyMSTeams, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
try:
|
||||
self.version = int(version)
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
@ -39,13 +46,15 @@ from ..AppriseLocale import gettext_lazy as _
|
|||
# Default our global support flag
|
||||
NOTIFY_MACOSX_SUPPORT_ENABLED = False
|
||||
|
||||
|
||||
# TODO: The module will be easier to test without module-level code.
|
||||
if platform.system() == 'Darwin':
|
||||
# Check this is Mac OS X 10.8, or higher
|
||||
major, minor = platform.mac_ver()[0].split('.')[:2]
|
||||
|
||||
# Toggle our enabled flag if verion is correct and executable
|
||||
# Toggle our enabled flag, if version is correct and executable
|
||||
# found. This is done in such a way to provide verbosity to the
|
||||
# end user so they know why it may or may not work for them.
|
||||
# end user, so they know why it may or may not work for them.
|
||||
NOTIFY_MACOSX_SUPPORT_ENABLED = \
|
||||
(int(major) > 10 or (int(major) == 10 and int(minor) >= 8))
|
||||
|
||||
|
@ -95,6 +104,8 @@ class NotifyMacOSX(NotifyBase):
|
|||
notify_paths = (
|
||||
'/opt/homebrew/bin/terminal-notifier',
|
||||
'/usr/local/bin/terminal-notifier',
|
||||
'/usr/bin/terminal-notifier',
|
||||
'/bin/terminal-notifier',
|
||||
)
|
||||
|
||||
# Define object templates
|
||||
|
@ -117,26 +128,32 @@ class NotifyMacOSX(NotifyBase):
|
|||
'name': _('Sound'),
|
||||
'type': 'string',
|
||||
},
|
||||
'click': {
|
||||
'name': _('Open/Click URL'),
|
||||
'type': 'string',
|
||||
},
|
||||
})
|
||||
|
||||
def __init__(self, sound=None, include_image=True, **kwargs):
|
||||
def __init__(self, sound=None, include_image=True, click=None, **kwargs):
|
||||
"""
|
||||
Initialize MacOSX Object
|
||||
"""
|
||||
|
||||
super(NotifyMacOSX, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Track whether or not we want to send an image with our notification
|
||||
# or not.
|
||||
# Track whether we want to add an image to the notification.
|
||||
self.include_image = include_image
|
||||
|
||||
# Acquire the notify path
|
||||
# Acquire the path to the `terminal-notifier` program.
|
||||
self.notify_path = next( # pragma: no branch
|
||||
(p for p in self.notify_paths if os.access(p, os.X_OK)), None)
|
||||
|
||||
# Click URL
|
||||
# Allow user to provide the `--open` argument on the notify wrapper
|
||||
self.click = click
|
||||
|
||||
# Set sound object (no q/a for now)
|
||||
self.sound = sound
|
||||
return
|
||||
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
|
||||
"""
|
||||
|
@ -160,6 +177,9 @@ class NotifyMacOSX(NotifyBase):
|
|||
if title:
|
||||
cmd.extend(['-title', title])
|
||||
|
||||
if self.click:
|
||||
cmd.extend(['-open', self.click])
|
||||
|
||||
# The sound to play
|
||||
if self.sound:
|
||||
cmd.extend(['-sound', self.sound])
|
||||
|
@ -201,6 +221,9 @@ class NotifyMacOSX(NotifyBase):
|
|||
'image': 'yes' if self.include_image else 'no',
|
||||
}
|
||||
|
||||
if self.click:
|
||||
params['click'] = self.click
|
||||
|
||||
# Extend our parameters
|
||||
params.update(self.url_parameters(privacy=privacy, *args, **kwargs))
|
||||
|
||||
|
@ -228,6 +251,10 @@ class NotifyMacOSX(NotifyBase):
|
|||
results['include_image'] = \
|
||||
parse_bool(results['qsd'].get('image', True))
|
||||
|
||||
# Support 'click'
|
||||
if 'click' in results['qsd'] and len(results['qsd']['click']):
|
||||
results['click'] = NotifyMacOSX.unquote(results['qsd']['click'])
|
||||
|
||||
# Support 'sound'
|
||||
if 'sound' in results['qsd'] and len(results['qsd']['sound']):
|
||||
results['sound'] = NotifyMacOSX.unquote(results['qsd']['sound'])
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Signup @ https://www.mailgun.com/
|
||||
#
|
||||
|
@ -60,6 +67,7 @@ from ..utils import parse_emails
|
|||
from ..utils import parse_bool
|
||||
from ..utils import is_email
|
||||
from ..utils import validate_regex
|
||||
from ..logger import logger
|
||||
from ..AppriseLocale import gettext_lazy as _
|
||||
|
||||
# Provide some known codes Mailgun uses and what they translate to:
|
||||
|
@ -116,9 +124,6 @@ class NotifyMailgun(NotifyBase):
|
|||
# Default Notify Format
|
||||
notify_format = NotifyFormat.HTML
|
||||
|
||||
# The default region to use if one isn't otherwise specified
|
||||
mailgun_default_region = MailgunRegion.US
|
||||
|
||||
# The maximum amount of emails that can reside within a single
|
||||
# batch transfer
|
||||
default_batch_size = 2000
|
||||
|
@ -158,7 +163,10 @@ class NotifyMailgun(NotifyBase):
|
|||
'name': {
|
||||
'name': _('From Name'),
|
||||
'type': 'string',
|
||||
'map_to': 'from_name',
|
||||
'map_to': 'from_addr',
|
||||
},
|
||||
'from': {
|
||||
'alias_of': 'name',
|
||||
},
|
||||
'region': {
|
||||
'name': _('Region Name'),
|
||||
|
@ -197,13 +205,13 @@ class NotifyMailgun(NotifyBase):
|
|||
},
|
||||
}
|
||||
|
||||
def __init__(self, apikey, targets, cc=None, bcc=None, from_name=None,
|
||||
def __init__(self, apikey, targets, cc=None, bcc=None, from_addr=None,
|
||||
region_name=None, headers=None, tokens=None, batch=False,
|
||||
**kwargs):
|
||||
"""
|
||||
Initialize Mailgun Object
|
||||
"""
|
||||
super(NotifyMailgun, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# API Key (associated with project)
|
||||
self.apikey = validate_regex(apikey)
|
||||
|
@ -246,7 +254,8 @@ class NotifyMailgun(NotifyBase):
|
|||
|
||||
# Store our region
|
||||
try:
|
||||
self.region_name = self.mailgun_default_region \
|
||||
self.region_name = \
|
||||
NotifyMailgun.template_args['region']['default'] \
|
||||
if region_name is None else region_name.lower()
|
||||
|
||||
if self.region_name not in MAILGUN_REGIONS:
|
||||
|
@ -260,12 +269,20 @@ class NotifyMailgun(NotifyBase):
|
|||
raise TypeError(msg)
|
||||
|
||||
# Get our From username (if specified)
|
||||
self.from_name = from_name
|
||||
self.from_addr = [
|
||||
self.app_id, '{user}@{host}'.format(
|
||||
user=self.user, host=self.host)]
|
||||
|
||||
# Get our from email address
|
||||
self.from_addr = '{user}@{host}'.format(user=self.user, host=self.host)
|
||||
if from_addr:
|
||||
result = is_email(from_addr)
|
||||
if result:
|
||||
self.from_addr = (
|
||||
result['name'] if result['name'] else False,
|
||||
result['full_email'])
|
||||
else:
|
||||
self.from_addr[0] = from_addr
|
||||
|
||||
if not is_email(self.from_addr):
|
||||
if not is_email(self.from_addr[1]):
|
||||
# Parse Source domain based on from_addr
|
||||
msg = 'Invalid ~From~ email format: {}'.format(self.from_addr)
|
||||
self.logger.warning(msg)
|
||||
|
@ -288,8 +305,7 @@ class NotifyMailgun(NotifyBase):
|
|||
|
||||
else:
|
||||
# If our target email list is empty we want to add ourselves to it
|
||||
self.targets.append(
|
||||
(self.from_name if self.from_name else False, self.from_addr))
|
||||
self.targets.append((False, self.from_addr[1]))
|
||||
|
||||
# Validate recipients (cc:) and drop bad ones:
|
||||
for recipient in parse_emails(cc):
|
||||
|
@ -383,9 +399,7 @@ class NotifyMailgun(NotifyBase):
|
|||
|
||||
return False
|
||||
|
||||
reply_to = formataddr(
|
||||
(self.from_name if self.from_name else False,
|
||||
self.from_addr), charset='utf-8')
|
||||
reply_to = formataddr(self.from_addr, charset='utf-8')
|
||||
|
||||
# Prepare our payload
|
||||
payload = {
|
||||
|
@ -581,9 +595,9 @@ class NotifyMailgun(NotifyBase):
|
|||
# Extend our parameters
|
||||
params.update(self.url_parameters(privacy=privacy, *args, **kwargs))
|
||||
|
||||
if self.from_name is not None:
|
||||
# from_name specified; pass it back on the url
|
||||
params['name'] = self.from_name
|
||||
if self.from_addr[0]:
|
||||
# from_addr specified; pass it back on the url
|
||||
params['name'] = self.from_addr[0]
|
||||
|
||||
if self.cc:
|
||||
# Handle our Carbon Copy Addresses
|
||||
|
@ -613,6 +627,20 @@ class NotifyMailgun(NotifyBase):
|
|||
safe='') for e in self.targets]),
|
||||
params=NotifyMailgun.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -637,13 +665,28 @@ class NotifyMailgun(NotifyBase):
|
|||
# We're done - no API Key found
|
||||
results['apikey'] = None
|
||||
|
||||
if 'name' in results['qsd'] and len(results['qsd']['name']):
|
||||
# Attempt to detect 'from' email address
|
||||
if 'from' in results['qsd'] and len(results['qsd']['from']):
|
||||
results['from_addr'] = \
|
||||
NotifyMailgun.unquote(results['qsd']['from'])
|
||||
|
||||
if 'name' in results['qsd'] and len(results['qsd']['name']):
|
||||
# Depricate use of both `from=` and `name=` in the same url as
|
||||
# they will be synomomus of one another in the future.
|
||||
results['from_addr'] = formataddr(
|
||||
(NotifyMailgun.unquote(results['qsd']['name']),
|
||||
results['from_addr']), charset='utf-8')
|
||||
logger.warning(
|
||||
'Mailgun name= and from= are synonymous; '
|
||||
'use one or the other.')
|
||||
|
||||
elif 'name' in results['qsd'] and len(results['qsd']['name']):
|
||||
# Extract from name to associate with from address
|
||||
results['from_name'] = \
|
||||
results['from_addr'] = \
|
||||
NotifyMailgun.unquote(results['qsd']['name'])
|
||||
|
||||
if 'region' in results['qsd'] and len(results['qsd']['region']):
|
||||
# Extract from name to associate with from address
|
||||
# Acquire region if defined
|
||||
results['region_name'] = \
|
||||
NotifyMailgun.unquote(results['qsd']['region'])
|
||||
|
||||
|
|
990
libs/apprise/plugins/NotifyMastodon.py
Normal file
990
libs/apprise/plugins/NotifyMastodon.py
Normal file
|
@ -0,0 +1,990 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import requests
|
||||
from copy import deepcopy
|
||||
from json import dumps, loads
|
||||
from datetime import datetime
|
||||
|
||||
from .NotifyBase import NotifyBase
|
||||
from ..URLBase import PrivacyMode
|
||||
from ..common import NotifyImageSize
|
||||
from ..common import NotifyFormat
|
||||
from ..common import NotifyType
|
||||
from ..utils import parse_list
|
||||
from ..utils import parse_bool
|
||||
from ..utils import validate_regex
|
||||
from ..AppriseLocale import gettext_lazy as _
|
||||
from ..attachment.AttachBase import AttachBase
|
||||
|
||||
# Accept:
|
||||
# - @username
|
||||
# - username
|
||||
# - username@host.com
|
||||
# - @username@host.com
|
||||
IS_USER = re.compile(
|
||||
r'^\s*@?(?P<user>[A-Z0-9_]+(?:@(?P<host>[A-Z0-9_.-]+))?)$', re.I)
|
||||
|
||||
USER_DETECTION_RE = re.compile(
|
||||
r'(@[A-Z0-9_]+(?:@[A-Z0-9_.-]+)?)(?=$|[\s,.&()\[\]]+)', re.I)
|
||||
|
||||
|
||||
class MastodonMessageVisibility:
|
||||
"""
|
||||
The visibility of any status message made
|
||||
"""
|
||||
# post visibility defaults to the accounts default-visibilty setting
|
||||
DEFAULT = 'default'
|
||||
|
||||
# post will be visible only to mentioned users
|
||||
# similar to a Twitter DM
|
||||
DIRECT = 'direct'
|
||||
|
||||
# post will be visible only to followers
|
||||
PRIVATE = 'private'
|
||||
|
||||
# post will be public but not appear on the public timeline
|
||||
UNLISTED = 'unlisted'
|
||||
|
||||
# post will be public
|
||||
PUBLIC = 'public'
|
||||
|
||||
|
||||
# Define the types in a list for validation purposes
|
||||
MASTODON_MESSAGE_VISIBILITIES = (
|
||||
MastodonMessageVisibility.DEFAULT,
|
||||
MastodonMessageVisibility.DIRECT,
|
||||
MastodonMessageVisibility.PRIVATE,
|
||||
MastodonMessageVisibility.UNLISTED,
|
||||
MastodonMessageVisibility.PUBLIC,
|
||||
)
|
||||
|
||||
|
||||
class NotifyMastodon(NotifyBase):
|
||||
"""
|
||||
A wrapper for Notify Mastodon Notifications
|
||||
"""
|
||||
|
||||
# The default descriptive name associated with the Notification
|
||||
service_name = 'Mastodon'
|
||||
|
||||
# The services URL
|
||||
service_url = 'https://joinmastodon.org'
|
||||
|
||||
# The default protocol
|
||||
protocol = ('mastodon', 'toot')
|
||||
|
||||
# The default secure protocol
|
||||
secure_protocol = ('mastodons', 'toots')
|
||||
|
||||
# A URL that takes you to the setup/help of the specific protocol
|
||||
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_mastodon'
|
||||
|
||||
# Allows the user to specify the NotifyImageSize object; this is supported
|
||||
# through the webhook
|
||||
image_size = NotifyImageSize.XY_128
|
||||
|
||||
# it is documented on the site that the maximum images per toot
|
||||
# is 4 (unless it's a GIF, then it's only 1)
|
||||
__toot_non_gif_images_batch = 4
|
||||
|
||||
# Mastodon API Reference To Acquire Current Users Information
|
||||
# See: https://docs.joinmastodon.org/methods/accounts/
|
||||
# Requires Scope Element: read:accounts
|
||||
mastodon_whoami = '/api/v1/accounts/verify_credentials'
|
||||
|
||||
# URL for posting media files
|
||||
mastodon_media = '/api/v1/media'
|
||||
|
||||
# URL for posting status messages
|
||||
mastodon_toot = '/api/v1/statuses'
|
||||
|
||||
# URL for posting direct messages
|
||||
mastodon_dm = '/api/v1/dm'
|
||||
|
||||
# The title is not used
|
||||
title_maxlen = 0
|
||||
|
||||
# The maximum size of the message
|
||||
body_maxlen = 500
|
||||
|
||||
# Default to text
|
||||
notify_format = NotifyFormat.TEXT
|
||||
|
||||
# Mastodon is kind enough to return how many more requests we're allowed to
|
||||
# continue to make within it's header response as:
|
||||
# X-Rate-Limit-Reset: The epoc time (in seconds) we can expect our
|
||||
# rate-limit to be reset.
|
||||
# X-Rate-Limit-Remaining: an integer identifying how many requests we're
|
||||
# still allow to make.
|
||||
request_rate_per_sec = 0
|
||||
|
||||
# For Tracking Purposes
|
||||
ratelimit_reset = datetime.utcnow()
|
||||
|
||||
# Default to 1000; users can send up to 1000 DM's and 2400 toot a day
|
||||
# This value only get's adjusted if the server sets it that way
|
||||
ratelimit_remaining = 1
|
||||
|
||||
# Define object templates
|
||||
templates = (
|
||||
'{schema}://{token}@{host}',
|
||||
'{schema}://{token}@{host}:{port}',
|
||||
'{schema}://{token}@{host}/{targets}',
|
||||
'{schema}://{token}@{host}:{port}/{targets}',
|
||||
)
|
||||
|
||||
# Define our template arguments
|
||||
template_tokens = dict(NotifyBase.template_tokens, **{
|
||||
'host': {
|
||||
'name': _('Hostname'),
|
||||
'type': 'string',
|
||||
'required': True,
|
||||
},
|
||||
'token': {
|
||||
'name': _('Access Token'),
|
||||
'type': 'string',
|
||||
'required': True,
|
||||
},
|
||||
'port': {
|
||||
'name': _('Port'),
|
||||
'type': 'int',
|
||||
'min': 1,
|
||||
'max': 65535,
|
||||
},
|
||||
'target_user': {
|
||||
'name': _('Target User'),
|
||||
'type': 'string',
|
||||
'prefix': '@',
|
||||
'map_to': 'targets',
|
||||
},
|
||||
'targets': {
|
||||
'name': _('Targets'),
|
||||
'type': 'list:string',
|
||||
},
|
||||
})
|
||||
|
||||
# Define our template arguments
|
||||
template_args = dict(NotifyBase.template_args, **{
|
||||
'token': {
|
||||
'alias_of': 'token',
|
||||
},
|
||||
'visibility': {
|
||||
'name': _('Visibility'),
|
||||
'type': 'choice:string',
|
||||
'values': MASTODON_MESSAGE_VISIBILITIES,
|
||||
'default': MastodonMessageVisibility.DEFAULT,
|
||||
},
|
||||
'cache': {
|
||||
'name': _('Cache Results'),
|
||||
'type': 'bool',
|
||||
'default': True,
|
||||
},
|
||||
'batch': {
|
||||
'name': _('Batch Mode'),
|
||||
'type': 'bool',
|
||||
'default': True,
|
||||
},
|
||||
'sensitive': {
|
||||
'name': _('Sensitive Attachments'),
|
||||
'type': 'bool',
|
||||
'default': False,
|
||||
},
|
||||
'spoiler': {
|
||||
'name': _('Spoiler Text'),
|
||||
'type': 'string',
|
||||
},
|
||||
'key': {
|
||||
'name': _('Idempotency-Key'),
|
||||
'type': 'string',
|
||||
},
|
||||
'language': {
|
||||
'name': _('Language Code'),
|
||||
'type': 'string',
|
||||
},
|
||||
'to': {
|
||||
'alias_of': 'targets',
|
||||
},
|
||||
})
|
||||
|
||||
def __init__(self, token=None, targets=None, batch=True,
|
||||
sensitive=None, spoiler=None, visibility=None, cache=True,
|
||||
key=None, language=None, **kwargs):
|
||||
"""
|
||||
Initialize Notify Mastodon Object
|
||||
"""
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Set our schema
|
||||
self.schema = 'https' if self.secure else 'http'
|
||||
|
||||
# Initialize our cache value
|
||||
self._whoami_cache = None
|
||||
|
||||
self.token = validate_regex(token)
|
||||
if not self.token:
|
||||
msg = 'An invalid Mastodon Access Token was specified.'
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
if visibility:
|
||||
# Input is a string; attempt to get the lookup from our
|
||||
# sound mapping
|
||||
vis = 'invalid' if not isinstance(visibility, str) \
|
||||
else visibility.lower().strip()
|
||||
|
||||
# This little bit of black magic allows us to match against
|
||||
# against multiple versions of the same string
|
||||
# ... etc
|
||||
self.visibility = \
|
||||
next((v for v in MASTODON_MESSAGE_VISIBILITIES
|
||||
if v.startswith(vis)), None)
|
||||
|
||||
if self.visibility not in MASTODON_MESSAGE_VISIBILITIES:
|
||||
msg = 'The Mastodon visibility specified ({}) is invalid.' \
|
||||
.format(visibility)
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
else:
|
||||
self.visibility = \
|
||||
self.template_args['visibility']['default']
|
||||
|
||||
# Prepare our URL
|
||||
self.api_url = '%s://%s' % (self.schema, self.host)
|
||||
|
||||
if isinstance(self.port, int):
|
||||
self.api_url += ':%d' % self.port
|
||||
|
||||
# Set Cache Flag
|
||||
self.cache = cache
|
||||
|
||||
# Prepare Image Batch Mode Flag
|
||||
self.batch = self.template_args['batch']['default'] \
|
||||
if batch is None else batch
|
||||
|
||||
# Images to be marked sensitive
|
||||
self.sensitive = self.template_args['sensitive']['default'] \
|
||||
if sensitive is None else sensitive
|
||||
|
||||
# Text marked as being a spoiler
|
||||
self.spoiler = spoiler if isinstance(spoiler, str) else None
|
||||
|
||||
# Idempotency Key
|
||||
self.idempotency_key = key if isinstance(key, str) else None
|
||||
|
||||
# Over-ride default language (ISO 639) (e.g: en, fr, es, etc)
|
||||
self.language = language if isinstance(language, str) else None
|
||||
|
||||
# Our target users
|
||||
self.targets = []
|
||||
|
||||
# Track any errors
|
||||
has_error = False
|
||||
|
||||
# Identify our targets
|
||||
for target in parse_list(targets):
|
||||
match = IS_USER.match(target)
|
||||
if match and match.group('user'):
|
||||
self.targets.append('@' + match.group('user'))
|
||||
continue
|
||||
|
||||
has_error = True
|
||||
self.logger.warning(
|
||||
'Dropped invalid Mastodon user ({}) specified.'.format(target),
|
||||
)
|
||||
|
||||
if has_error and not self.targets:
|
||||
# We have specified that we want to notify one or more individual
|
||||
# and we failed to load any of them. Since it's also valid to
|
||||
# notify no one at all (which means we notify ourselves), it's
|
||||
# important we don't switch from the users original intentions
|
||||
msg = 'No Mastodon targets to notify.'
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
return
|
||||
|
||||
def url(self, privacy=False, *args, **kwargs):
|
||||
"""
|
||||
Returns the URL built dynamically based on specified arguments.
|
||||
"""
|
||||
|
||||
# Define any URL parameters
|
||||
params = {
|
||||
'visibility': self.visibility,
|
||||
'batch': 'yes' if self.batch else 'no',
|
||||
'sensitive': 'yes' if self.sensitive else 'no',
|
||||
}
|
||||
|
||||
# Extend our parameters
|
||||
params.update(self.url_parameters(privacy=privacy, *args, **kwargs))
|
||||
|
||||
if self.spoiler:
|
||||
# Our Spoiler if one was specified
|
||||
params['spoiler'] = self.spoiler
|
||||
|
||||
if self.idempotency_key:
|
||||
# Our Idempotency Key
|
||||
params['key'] = self.idempotency_key
|
||||
|
||||
if self.language:
|
||||
# Override Language
|
||||
params['language'] = self.language
|
||||
|
||||
default_port = 443 if self.secure else 80
|
||||
|
||||
return '{schema}://{token}@{host}{port}/{targets}?{params}'.format(
|
||||
schema=self.secure_protocol[0]
|
||||
if self.secure else self.protocol[0],
|
||||
token=self.pprint(
|
||||
self.token, privacy, mode=PrivacyMode.Secret, safe=''),
|
||||
# never encode hostname since we're expecting it to be a valid one
|
||||
host=self.host,
|
||||
port='' if self.port is None or self.port == default_port
|
||||
else ':{}'.format(self.port),
|
||||
targets='/'.join(
|
||||
[NotifyMastodon.quote(x, safe='@') for x in self.targets]),
|
||||
params=NotifyMastodon.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, attach=None,
|
||||
**kwargs):
|
||||
"""
|
||||
wrapper to _send since we can alert more then one channel
|
||||
"""
|
||||
|
||||
# Build a list of our attachments
|
||||
attachments = []
|
||||
|
||||
# Smart Target Detection for Direct Messages; this prevents us from
|
||||
# adding @user entries that were already placed in the message body
|
||||
users = set(USER_DETECTION_RE.findall(body))
|
||||
targets = users - set(self.targets.copy())
|
||||
if not self.targets and self.visibility == \
|
||||
MastodonMessageVisibility.DIRECT:
|
||||
|
||||
result = self._whoami()
|
||||
if not result:
|
||||
# Could not access our status
|
||||
return False
|
||||
|
||||
myself = '@' + next(iter(result.keys()))
|
||||
if myself in users:
|
||||
targets.remove(myself)
|
||||
|
||||
else:
|
||||
targets.add(myself)
|
||||
|
||||
if attach:
|
||||
# We need to upload our payload first so that we can source it
|
||||
# in remaining messages
|
||||
for attachment in attach:
|
||||
|
||||
# Perform some simple error checking
|
||||
if not attachment:
|
||||
# We could not access the attachment
|
||||
self.logger.error(
|
||||
'Could not access attachment {}.'.format(
|
||||
attachment.url(privacy=True)))
|
||||
return False
|
||||
|
||||
#
|
||||
# Images (PNG, JPG, GIF) up to 8MB.
|
||||
# - Images will be downscaled to 1.6 megapixels (enough for a
|
||||
# 1280x1280 image).
|
||||
# - Up to 4 images can be attached.
|
||||
# - Animated GIFs are converted to soundless MP4s like on
|
||||
# Imgur/Gfycat (GIFV).
|
||||
# - You can also upload soundless MP4 and WebM, which will
|
||||
# be handled the same way.
|
||||
# Videos (MP4, M4V, MOV, WebM) up to 40MB.
|
||||
# - Video will be transcoded to H.264 MP4 with a maximum
|
||||
# bitrate of 1300kbps and framerate of 60fps.
|
||||
# Audio (MP3, OGG, WAV, FLAC, OPUS, AAC, M4A, 3GP) up to 40MB.
|
||||
# - Audio will be transcoded to MP3 using V2 VBR (roughly
|
||||
# 192kbps).
|
||||
if not re.match(r'^(image|video|audio)/.*',
|
||||
attachment.mimetype, re.I):
|
||||
# Only support images at this time
|
||||
self.logger.warning(
|
||||
'Ignoring unsupported Mastodon attachment {}.'.format(
|
||||
attachment.url(privacy=True)))
|
||||
continue
|
||||
|
||||
self.logger.debug(
|
||||
'Preparing Mastodon attachment {}'.format(
|
||||
attachment.url(privacy=True)))
|
||||
|
||||
# Upload our image and get our id associated with it
|
||||
postokay, response = self._request(
|
||||
self.mastodon_media,
|
||||
payload=attachment,
|
||||
)
|
||||
|
||||
if not postokay:
|
||||
# We can't post our attachment
|
||||
if response and 'authorized scopes' \
|
||||
in response.get('error', ''):
|
||||
self.logger.warning(
|
||||
'Failed to Send Attachment to Mastodon: '
|
||||
'missing scope: write:media')
|
||||
|
||||
# All other failures should cause us to abort
|
||||
return False
|
||||
|
||||
if not (isinstance(response, dict)
|
||||
and response.get('id')):
|
||||
self.logger.debug(
|
||||
'Could not attach the file to Mastodon: %s (mime=%s)',
|
||||
attachment.name, attachment.mimetype)
|
||||
continue
|
||||
|
||||
# If we get here, our output will look something like this:
|
||||
# {
|
||||
# 'id': '12345',
|
||||
# 'type': 'image',
|
||||
# 'url': 'https://.../6dad4663a.jpeg',
|
||||
# 'preview_url': 'https://.../adde6dad4663a.jpeg',
|
||||
# 'remote_url': None,
|
||||
# 'preview_remote_url': None,
|
||||
# 'text_url': None,
|
||||
# 'meta': {
|
||||
# 'original': {
|
||||
# 'width': 640,
|
||||
# 'height': 640,
|
||||
# 'size': '640x640',
|
||||
# 'aspect': 1.0
|
||||
# },
|
||||
# 'small': {
|
||||
# 'width': 400,
|
||||
# 'height': 400,
|
||||
# 'size': '400x400',
|
||||
# 'aspect': 1.0
|
||||
# }
|
||||
# },
|
||||
# 'description': None,
|
||||
# 'blurhash': 'UmIsdJnT^mX4V@XQofnQ~Ebq%4o3ofnQjZbt'
|
||||
# }
|
||||
response.update({
|
||||
# Update our response to additionally include the
|
||||
# attachment details
|
||||
'file_name': attachment.name,
|
||||
'file_mime': attachment.mimetype,
|
||||
'file_path': attachment.path,
|
||||
})
|
||||
|
||||
# Save our pre-prepared payload for attachment posting
|
||||
attachments.append(response)
|
||||
|
||||
payload = {
|
||||
'status': '{} {}'.format(' '.join(targets), body)
|
||||
if targets else body,
|
||||
'sensitive': self.sensitive,
|
||||
}
|
||||
|
||||
# Handle Visibility Flag
|
||||
if self.visibility != MastodonMessageVisibility.DEFAULT:
|
||||
payload['visibility'] = self.visibility
|
||||
|
||||
# Set Spoiler text (if set)
|
||||
if self.spoiler:
|
||||
payload['spoiler_text'] = self.spoiler
|
||||
|
||||
# Set Idempotency-Key (if set)
|
||||
if self.idempotency_key:
|
||||
payload['Idempotency-Key'] = self.idempotency_key
|
||||
|
||||
# Set Language
|
||||
if self.language:
|
||||
payload['language'] = self.language
|
||||
|
||||
payloads = []
|
||||
if not attachments:
|
||||
payloads.append(payload)
|
||||
|
||||
else:
|
||||
# Group our images if batch is set to do so
|
||||
batch_size = 1 if not self.batch \
|
||||
else self.__toot_non_gif_images_batch
|
||||
|
||||
# Track our batch control in our message generation
|
||||
batches = []
|
||||
batch = []
|
||||
for attachment in attachments:
|
||||
batch.append(attachment['id'])
|
||||
# Mastodon supports batching images together. This allows
|
||||
# the batching of multiple images together. Mastodon also
|
||||
# makes it clear that you can't batch `gif` files; they need
|
||||
# to be separate. So the below preserves the ordering that
|
||||
# a user passed their attachments in. if 4-non-gif images
|
||||
# are passed, they are all part of a single message.
|
||||
#
|
||||
# however, if they pass in image, gif, image, gif. The
|
||||
# gif's inbetween break apart the batches so this would
|
||||
# produce 4 separate toots.
|
||||
#
|
||||
# If you passed in, image, image, gif, image. <- This would
|
||||
# produce 3 images (as the first 2 images could be lumped
|
||||
# together as a batch)
|
||||
if not re.match(
|
||||
r'^image/(png|jpe?g)', attachment['file_mime'], re.I) \
|
||||
or len(batch) >= batch_size:
|
||||
batches.append(batch)
|
||||
batch = []
|
||||
|
||||
if batch:
|
||||
batches.append(batch)
|
||||
|
||||
for no, media_ids in enumerate(batches):
|
||||
_payload = deepcopy(payload)
|
||||
_payload['media_ids'] = media_ids
|
||||
|
||||
if no:
|
||||
# strip text and replace it with the image representation
|
||||
_payload['status'] = \
|
||||
'{:02d}/{:02d}'.format(no + 1, len(batches))
|
||||
# No longer sensitive information
|
||||
_payload['sensitive'] = False
|
||||
if self.idempotency_key:
|
||||
# Support multiposts while a Idempotency Key has been
|
||||
# defined
|
||||
_payload['Idempotency-Key'] = '{}-part{:02d}'.format(
|
||||
self.idempotency_key, no)
|
||||
payloads.append(_payload)
|
||||
|
||||
# Error Tracking
|
||||
has_error = False
|
||||
|
||||
for no, payload in enumerate(payloads, start=1):
|
||||
postokay, response = self._request(self.mastodon_toot, payload)
|
||||
if not postokay:
|
||||
# Track our error
|
||||
has_error = True
|
||||
|
||||
# We can't post our attachment
|
||||
if response and 'authorized scopes' \
|
||||
in response.get('error', ''):
|
||||
self.logger.warning(
|
||||
'Failed to Send Status to Mastodon: '
|
||||
'missing scope: write:statuses')
|
||||
|
||||
continue
|
||||
|
||||
# Example Attachment Output:
|
||||
# {
|
||||
# "id":"109315796435904505",
|
||||
# "created_at":"2022-11-09T20:44:39.017Z",
|
||||
# "in_reply_to_id":null,
|
||||
# "in_reply_to_account_id":null,
|
||||
# "sensitive":false,
|
||||
# "spoiler_text":"",
|
||||
# "visibility":"public",
|
||||
# "language":"en",
|
||||
# "uri":"https://host/users/caronc/statuses/109315796435904505",
|
||||
# "url":"https://host/@caronc/109315796435904505",
|
||||
# "replies_count":0,
|
||||
# "reblogs_count":0,
|
||||
# "favourites_count":0,
|
||||
# "edited_at":null,
|
||||
# "favourited":false,
|
||||
# "reblogged":false,
|
||||
# "muted":false,
|
||||
# "bookmarked":false,
|
||||
# "pinned":false,
|
||||
# "content":"<p>test</p>",
|
||||
# "reblog":null,
|
||||
# "application":{
|
||||
# "name":"Apprise Notifications",
|
||||
# "website":"https://github.com/caronc/apprise"
|
||||
# },
|
||||
# "account":{
|
||||
# "id":"109310334138718878",
|
||||
# "username":"caronc",
|
||||
# "acct":"caronc",
|
||||
# "display_name":"Chris",
|
||||
# "locked":false,
|
||||
# "bot":false,
|
||||
# "discoverable":false,
|
||||
# "group":false,
|
||||
# "created_at":"2022-11-08T00:00:00.000Z",
|
||||
# "note":"content",
|
||||
# "url":"https://host/@caronc",
|
||||
# "avatar":"https://host/path/file.png",
|
||||
# "avatar_static":"https://host/path/file.png",
|
||||
# "header":"https://host/headers/original/missing.png",
|
||||
# "header_static":"https://host/path/missing.png",
|
||||
# "followers_count":0,
|
||||
# "following_count":0,
|
||||
# "statuses_count":15,
|
||||
# "last_status_at":"2022-11-09",
|
||||
# "emojis":[
|
||||
#
|
||||
# ],
|
||||
# "fields":[
|
||||
#
|
||||
# ]
|
||||
# },
|
||||
# "media_attachments":[
|
||||
# {
|
||||
# "id":"109315796405707501",
|
||||
# "type":"image",
|
||||
# "url":"https://host/path/file.jpeg",
|
||||
# "preview_url":"https://host/path/file.jpeg",
|
||||
# "remote_url":null,
|
||||
# "preview_remote_url":null,
|
||||
# "text_url":null,
|
||||
# "meta":{
|
||||
# "original":{
|
||||
# "width":640,
|
||||
# "height":640,
|
||||
# "size":"640x640",
|
||||
# "aspect":1.0
|
||||
# },
|
||||
# "small":{
|
||||
# "width":400,
|
||||
# "height":400,
|
||||
# "size":"400x400",
|
||||
# "aspect":1.0
|
||||
# }
|
||||
# },
|
||||
# "description":null,
|
||||
# "blurhash":"UmIsdJnT^mX4V@XQofnQ~Ebq%4o3ofnQjZbt"
|
||||
# }
|
||||
# ],
|
||||
# "mentions":[
|
||||
#
|
||||
# ],
|
||||
# "tags":[
|
||||
#
|
||||
# ],
|
||||
# "emojis":[
|
||||
#
|
||||
# ],
|
||||
# "card":null,
|
||||
# "poll":null
|
||||
# }
|
||||
|
||||
try:
|
||||
url = '{}/web/@{}'.format(
|
||||
self.api_url,
|
||||
response['account']['username'])
|
||||
|
||||
except (KeyError, TypeError):
|
||||
url = 'unknown'
|
||||
|
||||
self.logger.debug(
|
||||
'Mastodon [%.2d/%.2d] (%d attached) delivered to %s',
|
||||
no, len(payloads), len(payload.get('media_ids', [])), url)
|
||||
|
||||
self.logger.info(
|
||||
'Sent [%.2d/%.2d] Mastodon notification as public toot.',
|
||||
no, len(payloads))
|
||||
|
||||
return not has_error
|
||||
|
||||
def _whoami(self, lazy=True):
|
||||
"""
|
||||
Looks details of current authenticated user
|
||||
|
||||
"""
|
||||
|
||||
if lazy and self._whoami_cache is not None:
|
||||
# Use cached response
|
||||
return self._whoami_cache
|
||||
|
||||
# Send Mastodon Whoami request
|
||||
postokay, response = self._request(
|
||||
self.mastodon_whoami,
|
||||
method='GET',
|
||||
)
|
||||
|
||||
if postokay:
|
||||
# Sample Response:
|
||||
# {
|
||||
# 'id': '12345',
|
||||
# 'username': 'caronc',
|
||||
# 'acct': 'caronc',
|
||||
# 'display_name': 'Chris',
|
||||
# 'locked': False,
|
||||
# 'bot': False,
|
||||
# 'discoverable': False,
|
||||
# 'group': False,
|
||||
# 'created_at': '2022-11-08T00:00:00.000Z',
|
||||
# 'note': 'details',
|
||||
# 'url': 'https://noc.social/@caronc',
|
||||
# 'avatar': 'https://host/path/image.png',
|
||||
# 'avatar_static': 'https://host/path/image.png',
|
||||
# 'header': 'https://host/path/missing.png',
|
||||
# 'header_static': 'https://host/path/missing.png',
|
||||
# 'followers_count': 0,
|
||||
# 'following_count': 0,
|
||||
# 'statuses_count': 2,
|
||||
# 'last_status_at': '2022-11-09',
|
||||
# 'source': {
|
||||
# 'privacy': 'public',
|
||||
# 'sensitive': False,
|
||||
# 'language': None,
|
||||
# 'note': 'details',
|
||||
# 'fields': [],
|
||||
# 'follow_requests_count': 0
|
||||
# },
|
||||
# 'emojis': [],
|
||||
# 'fields': []
|
||||
# }
|
||||
try:
|
||||
# Cache our response for future references
|
||||
self._whoami_cache = {
|
||||
response['username']: response['id']}
|
||||
|
||||
except (TypeError, KeyError):
|
||||
pass
|
||||
|
||||
elif response and 'authorized scopes' in response.get('error', ''):
|
||||
self.logger.warning(
|
||||
'Failed to lookup Mastodon Auth details; '
|
||||
'missing scope: read:accounts')
|
||||
|
||||
return self._whoami_cache if postokay else {}
|
||||
|
||||
def _request(self, path, payload=None, method='POST'):
|
||||
"""
|
||||
Wrapper to Mastodon API requests object
|
||||
"""
|
||||
|
||||
headers = {
|
||||
'User-Agent': self.app_id,
|
||||
'Authorization': f'Bearer {self.token}',
|
||||
}
|
||||
|
||||
data = None
|
||||
files = None
|
||||
|
||||
# Prepare our message
|
||||
url = '{}{}'.format(self.api_url, path)
|
||||
|
||||
# Some Debug Logging
|
||||
self.logger.debug('Mastodon {} URL: {} (cert_verify={})'.format(
|
||||
method, url, self.verify_certificate))
|
||||
|
||||
# Open our attachment path if required:
|
||||
if isinstance(payload, AttachBase):
|
||||
# prepare payload
|
||||
files = {
|
||||
'file': (payload.name, open(payload.path, 'rb'),
|
||||
'application/octet-stream')}
|
||||
|
||||
# Provide a description
|
||||
data = {
|
||||
'description': payload.name,
|
||||
}
|
||||
|
||||
else:
|
||||
headers['Content-Type'] = 'application/json'
|
||||
data = dumps(payload)
|
||||
self.logger.debug('Mastodon Payload: %s' % str(payload))
|
||||
|
||||
# Default content response object
|
||||
content = {}
|
||||
|
||||
# By default set wait to None
|
||||
wait = None
|
||||
|
||||
if self.ratelimit_remaining == 0:
|
||||
# Determine how long we should wait for or if we should wait at
|
||||
# all. This isn't fool-proof because we can't be sure the client
|
||||
# time (calling this script) is completely synced up with the
|
||||
# Mastodon server. One would hope we're on NTP and our clocks are
|
||||
# the same allowing this to role smoothly:
|
||||
|
||||
now = datetime.utcnow()
|
||||
if now < self.ratelimit_reset:
|
||||
# We need to throttle for the difference in seconds
|
||||
# We add 0.5 seconds to the end just to allow a grace
|
||||
# period.
|
||||
wait = (self.ratelimit_reset - now).total_seconds() + 0.5
|
||||
|
||||
# Always call throttle before any remote server i/o is made;
|
||||
self.throttle(wait=wait)
|
||||
|
||||
# acquire our request mode
|
||||
fn = requests.post if method == 'POST' else requests.get
|
||||
|
||||
try:
|
||||
r = fn(
|
||||
url,
|
||||
data=data,
|
||||
files=files,
|
||||
headers=headers,
|
||||
verify=self.verify_certificate,
|
||||
timeout=self.request_timeout,
|
||||
)
|
||||
|
||||
try:
|
||||
content = loads(r.content)
|
||||
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
# ValueError = r.content is Unparsable
|
||||
# TypeError = r.content is None
|
||||
# AttributeError = r is None
|
||||
content = {}
|
||||
|
||||
if r.status_code not in (
|
||||
requests.codes.ok, requests.codes.created,
|
||||
requests.codes.accepted):
|
||||
|
||||
# We had a problem
|
||||
status_str = \
|
||||
NotifyMastodon.http_response_code_lookup(r.status_code)
|
||||
|
||||
self.logger.warning(
|
||||
'Failed to send Mastodon {} to {}: '
|
||||
'{}error={}.'.format(
|
||||
method,
|
||||
url,
|
||||
', ' if status_str else '',
|
||||
r.status_code))
|
||||
|
||||
self.logger.debug(
|
||||
'Response Details:\r\n{}'.format(r.content))
|
||||
|
||||
# Mark our failure
|
||||
return (False, content)
|
||||
|
||||
try:
|
||||
# Capture rate limiting if possible
|
||||
self.ratelimit_remaining = \
|
||||
int(r.headers.get('X-RateLimit-Remaining'))
|
||||
self.ratelimit_reset = datetime.utcfromtimestamp(
|
||||
int(r.headers.get('X-RateLimit-Limit')))
|
||||
|
||||
except (TypeError, ValueError):
|
||||
# This is returned if we could not retrieve this information
|
||||
# gracefully accept this state and move on
|
||||
pass
|
||||
|
||||
except requests.RequestException as e:
|
||||
self.logger.warning(
|
||||
'Exception received when sending Mastodon {} to {}: '.
|
||||
format(method, url))
|
||||
self.logger.debug('Socket Exception: %s' % str(e))
|
||||
|
||||
# Mark our failure
|
||||
return (False, content)
|
||||
|
||||
except (OSError, IOError) as e:
|
||||
self.logger.warning(
|
||||
'An I/O error occurred while handling {}.'.format(
|
||||
payload.name if isinstance(payload, AttachBase)
|
||||
else payload))
|
||||
self.logger.debug('I/O Exception: %s' % str(e))
|
||||
return (False, content)
|
||||
|
||||
finally:
|
||||
# Close our file (if it's open) stored in the second element
|
||||
# of our files tuple (index 1)
|
||||
if files:
|
||||
files['file'][1].close()
|
||||
|
||||
return (True, content)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
Parses the URL and returns enough arguments that can allow
|
||||
us to re-instantiate this object.
|
||||
|
||||
"""
|
||||
results = NotifyBase.parse_url(url)
|
||||
if not results:
|
||||
# We're done early as we couldn't load the results
|
||||
return results
|
||||
|
||||
if 'token' in results['qsd'] and len(results['qsd']['token']):
|
||||
results['token'] = NotifyMastodon.unquote(results['qsd']['token'])
|
||||
|
||||
elif not results['password'] and results['user']:
|
||||
results['token'] = NotifyMastodon.unquote(results['user'])
|
||||
|
||||
# Apply our targets
|
||||
results['targets'] = NotifyMastodon.split_path(results['fullpath'])
|
||||
|
||||
# The defined Mastodon visibility
|
||||
if 'visibility' in results['qsd'] and \
|
||||
len(results['qsd']['visibility']):
|
||||
# Simplified version
|
||||
results['visibility'] = \
|
||||
NotifyMastodon.unquote(results['qsd']['visibility'])
|
||||
|
||||
elif results['schema'].startswith('toot'):
|
||||
results['visibility'] = MastodonMessageVisibility.PUBLIC
|
||||
|
||||
# Get Idempotency Key (if specified)
|
||||
if 'key' in results['qsd'] and len(results['qsd']['key']):
|
||||
results['key'] = \
|
||||
NotifyMastodon.unquote(results['qsd']['key'])
|
||||
|
||||
# Get Spoiler Text
|
||||
if 'spoiler' in results['qsd'] and len(results['qsd']['spoiler']):
|
||||
results['spoiler'] = \
|
||||
NotifyMastodon.unquote(results['qsd']['spoiler'])
|
||||
|
||||
# Get Language (if specified)
|
||||
if 'language' in results['qsd'] and len(results['qsd']['language']):
|
||||
results['language'] = \
|
||||
NotifyMastodon.unquote(results['qsd']['language'])
|
||||
|
||||
# Get Sensitive Flag (for Attachments)
|
||||
results['sensitive'] = \
|
||||
parse_bool(results['qsd'].get(
|
||||
'sensitive',
|
||||
NotifyMastodon.template_args['sensitive']['default']))
|
||||
|
||||
# Get Batch Mode Flag
|
||||
results['batch'] = \
|
||||
parse_bool(results['qsd'].get(
|
||||
'batch', NotifyMastodon.template_args['batch']['default']))
|
||||
|
||||
# The 'to' makes it easier to use yaml configuration
|
||||
if 'to' in results['qsd'] and len(results['qsd']['to']):
|
||||
results['targets'] += \
|
||||
NotifyMastodon.parse_list(results['qsd']['to'])
|
||||
|
||||
return results
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Great sources
|
||||
# - https://github.com/matrix-org/matrix-python-sdk
|
||||
|
@ -128,7 +135,14 @@ class NotifyMatrix(NotifyBase):
|
|||
image_size = NotifyImageSize.XY_32
|
||||
|
||||
# The maximum allowable characters allowed in the body per message
|
||||
body_maxlen = 1000
|
||||
# https://spec.matrix.org/v1.6/client-server-api/#size-limits
|
||||
# The complete event MUST NOT be larger than 65536 bytes, when formatted
|
||||
# with the federation event format, including any signatures, and encoded
|
||||
# as Canonical JSON.
|
||||
#
|
||||
# To gracefully allow for some overhead' we'll define a max body length
|
||||
# of just slighty lower then the limit of the full message itself.
|
||||
body_maxlen = 65000
|
||||
|
||||
# Throttle a wee-bit to avoid thrashing
|
||||
request_rate_per_sec = 0.5
|
||||
|
@ -239,7 +253,7 @@ class NotifyMatrix(NotifyBase):
|
|||
"""
|
||||
Initialize Matrix Object
|
||||
"""
|
||||
super(NotifyMatrix, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Prepare a list of rooms to connect and notify
|
||||
self.rooms = parse_list(targets)
|
||||
|
@ -1182,6 +1196,13 @@ class NotifyMatrix(NotifyBase):
|
|||
params=NotifyMatrix.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.rooms)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Create an incoming webhook; the website will provide you with something like:
|
||||
# http://localhost:8065/hooks/yobjmukpaw3r3urc5h6i369yima
|
||||
|
@ -145,7 +152,7 @@ class NotifyMattermost(NotifyBase):
|
|||
"""
|
||||
Initialize Mattermost Object
|
||||
"""
|
||||
super(NotifyMattermost, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
if self.secure:
|
||||
self.schema = 'https'
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Create an account https://messagebird.com if you don't already have one
|
||||
#
|
||||
|
@ -115,7 +122,7 @@ class NotifyMessageBird(NotifyBase):
|
|||
"""
|
||||
Initialize MessageBird Object
|
||||
"""
|
||||
super(NotifyMessageBird, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# API Key (associated with project)
|
||||
self.apikey = validate_regex(
|
||||
|
@ -304,6 +311,13 @@ class NotifyMessageBird(NotifyBase):
|
|||
[NotifyMessageBird.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyMessageBird.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
310
libs/apprise/plugins/NotifyMisskey.py
Normal file
310
libs/apprise/plugins/NotifyMisskey.py
Normal file
|
@ -0,0 +1,310 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# 1. visit https://misskey-hub.net/ and see what it's all about if you want.
|
||||
# Choose a service you want to create an account on from here:
|
||||
# https://misskey-hub.net/en/instances.html
|
||||
#
|
||||
# - For this plugin, I tested using https://misskey.sda1.net and created an
|
||||
# account.
|
||||
#
|
||||
# 2. Generate an API Key:
|
||||
# - Settings > API > Generate Key
|
||||
# - Name it whatever you want
|
||||
# - Assign it 'AT LEAST':
|
||||
# a. Compose or delete chat messages
|
||||
# b. Compose or delete notes
|
||||
#
|
||||
#
|
||||
# This plugin also supports taking the URL (as identified above) directly
|
||||
# as well.
|
||||
|
||||
import requests
|
||||
from json import dumps
|
||||
|
||||
from .NotifyBase import NotifyBase
|
||||
from ..common import NotifyType
|
||||
from ..utils import validate_regex
|
||||
from ..AppriseLocale import gettext_lazy as _
|
||||
|
||||
|
||||
class MisskeyVisibility:
|
||||
"""
|
||||
The visibility of any note created
|
||||
"""
|
||||
# post will be public
|
||||
PUBLIC = 'public'
|
||||
|
||||
HOME = 'home'
|
||||
|
||||
FOLLOWERS = 'followers'
|
||||
|
||||
PRIVATE = 'private'
|
||||
|
||||
SPECIFIED = 'specified'
|
||||
|
||||
|
||||
# Define the types in a list for validation purposes
|
||||
MISSKEY_VISIBILITIES = (
|
||||
MisskeyVisibility.PUBLIC,
|
||||
MisskeyVisibility.HOME,
|
||||
MisskeyVisibility.FOLLOWERS,
|
||||
MisskeyVisibility.PRIVATE,
|
||||
MisskeyVisibility.SPECIFIED,
|
||||
)
|
||||
|
||||
|
||||
class NotifyMisskey(NotifyBase):
|
||||
"""
|
||||
A wrapper for Misskey Notifications
|
||||
"""
|
||||
|
||||
# The default descriptive name associated with the Notification
|
||||
service_name = 'Misskey'
|
||||
|
||||
# The services URL
|
||||
service_url = 'https://misskey-hub.net/'
|
||||
|
||||
# The default protocol
|
||||
protocol = 'misskey'
|
||||
|
||||
# The default secure protocol
|
||||
secure_protocol = 'misskeys'
|
||||
|
||||
# A URL that takes you to the setup/help of the specific protocol
|
||||
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_misskey'
|
||||
|
||||
# The title is not used
|
||||
title_maxlen = 0
|
||||
|
||||
# The maximum allowable characters allowed in the body per message
|
||||
body_maxlen = 512
|
||||
|
||||
# Define object templates
|
||||
templates = (
|
||||
'{schema}://{project_id}/{msghook}',
|
||||
)
|
||||
|
||||
# Define object templates
|
||||
templates = (
|
||||
'{schema}://{token}@{host}',
|
||||
'{schema}://{token}@{host}:{port}',
|
||||
)
|
||||
|
||||
# Define our template arguments
|
||||
# Define our template arguments
|
||||
template_tokens = dict(NotifyBase.template_tokens, **{
|
||||
'host': {
|
||||
'name': _('Hostname'),
|
||||
'type': 'string',
|
||||
'required': True,
|
||||
},
|
||||
'token': {
|
||||
'name': _('Access Token'),
|
||||
'type': 'string',
|
||||
'required': True,
|
||||
},
|
||||
'port': {
|
||||
'name': _('Port'),
|
||||
'type': 'int',
|
||||
'min': 1,
|
||||
'max': 65535,
|
||||
},
|
||||
})
|
||||
|
||||
# Define our template arguments
|
||||
template_args = dict(NotifyBase.template_args, **{
|
||||
'token': {
|
||||
'alias_of': 'token',
|
||||
},
|
||||
'visibility': {
|
||||
'name': _('Visibility'),
|
||||
'type': 'choice:string',
|
||||
'values': MISSKEY_VISIBILITIES,
|
||||
'default': MisskeyVisibility.PUBLIC,
|
||||
},
|
||||
})
|
||||
|
||||
def __init__(self, token=None, visibility=None, **kwargs):
|
||||
"""
|
||||
Initialize Misskey Object
|
||||
"""
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.token = validate_regex(token)
|
||||
if not self.token:
|
||||
msg = 'An invalid Misskey Access Token was specified.'
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
if visibility:
|
||||
# Input is a string; attempt to get the lookup from our
|
||||
# sound mapping
|
||||
vis = 'invalid' if not isinstance(visibility, str) \
|
||||
else visibility.lower().strip()
|
||||
|
||||
# This little bit of black magic allows us to match against
|
||||
# against multiple versions of the same string ... etc
|
||||
self.visibility = \
|
||||
next((v for v in MISSKEY_VISIBILITIES
|
||||
if v.startswith(vis)), None)
|
||||
|
||||
if self.visibility not in MISSKEY_VISIBILITIES:
|
||||
msg = 'The Misskey visibility specified ({}) is invalid.' \
|
||||
.format(visibility)
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
else:
|
||||
self.visibility = self.template_args['visibility']['default']
|
||||
|
||||
# Prepare our URL
|
||||
self.schema = 'https' if self.secure else 'http'
|
||||
self.api_url = '%s://%s' % (self.schema, self.host)
|
||||
|
||||
if isinstance(self.port, int):
|
||||
self.api_url += ':%d' % self.port
|
||||
|
||||
return
|
||||
|
||||
def url(self, privacy=False, *args, **kwargs):
|
||||
"""
|
||||
Returns the URL built dynamically based on specified arguments.
|
||||
"""
|
||||
|
||||
params = {
|
||||
'visibility': self.visibility,
|
||||
}
|
||||
|
||||
# Extend our parameters
|
||||
params.update(self.url_parameters(privacy=privacy, *args, **kwargs))
|
||||
|
||||
host = self.host
|
||||
if isinstance(self.port, int):
|
||||
host += ':%d' % self.port
|
||||
|
||||
return '{schema}://{token}@{host}/?{params}'.format(
|
||||
schema=self.secure_protocol if self.secure else self.protocol,
|
||||
host=host,
|
||||
token=self.pprint(self.token, privacy, safe=''),
|
||||
params=NotifyMisskey.urlencode(params),
|
||||
)
|
||||
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
|
||||
"""
|
||||
wrapper to _send since we can alert more then one channel
|
||||
"""
|
||||
|
||||
# prepare our headers
|
||||
headers = {
|
||||
'User-Agent': self.app_id,
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
|
||||
# Prepare our payload
|
||||
payload = {
|
||||
'i': self.token,
|
||||
'text': body,
|
||||
'visibility': self.visibility,
|
||||
}
|
||||
|
||||
api_url = f'{self.api_url}/api/notes/create'
|
||||
self.logger.debug('Misskey GET URL: %s (cert_verify=%r)' % (
|
||||
api_url, self.verify_certificate))
|
||||
self.logger.debug('Misskey Payload: %s' % str(payload))
|
||||
|
||||
# Always call throttle before any remote server i/o is made
|
||||
self.throttle()
|
||||
|
||||
try:
|
||||
r = requests.post(
|
||||
api_url,
|
||||
headers=headers,
|
||||
data=dumps(payload),
|
||||
verify=self.verify_certificate,
|
||||
timeout=self.request_timeout,
|
||||
)
|
||||
if r.status_code != requests.codes.ok:
|
||||
# We had a problem
|
||||
status_str = \
|
||||
NotifyMisskey.http_response_code_lookup(r.status_code)
|
||||
|
||||
self.logger.warning(
|
||||
'Failed to send Misskey notification: '
|
||||
'{}{}error={}.'.format(
|
||||
status_str,
|
||||
', ' if status_str else '',
|
||||
r.status_code))
|
||||
|
||||
self.logger.debug('Response Details:\r\n{}'.format(r.content))
|
||||
|
||||
# Return; we're done
|
||||
return False
|
||||
|
||||
else:
|
||||
self.logger.info('Sent Misskey notification.')
|
||||
|
||||
except requests.RequestException as e:
|
||||
self.logger.warning(
|
||||
'A Connection error occurred sending Misskey '
|
||||
'notification.')
|
||||
self.logger.debug('Socket Exception: %s' % str(e))
|
||||
|
||||
# Return; we're done
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
Parses the URL and returns enough arguments that can allow
|
||||
us to re-instantiate this object.
|
||||
|
||||
"""
|
||||
|
||||
results = NotifyBase.parse_url(url)
|
||||
if not results:
|
||||
# We're done early as we couldn't load the results
|
||||
return results
|
||||
|
||||
if 'token' in results['qsd'] and len(results['qsd']['token']):
|
||||
results['token'] = NotifyMisskey.unquote(results['qsd']['token'])
|
||||
|
||||
elif not results['password'] and results['user']:
|
||||
results['token'] = NotifyMisskey.unquote(results['user'])
|
||||
|
||||
# Capture visibility if specified
|
||||
if 'visibility' in results['qsd'] and \
|
||||
len(results['qsd']['visibility']):
|
||||
results['visibility'] = \
|
||||
NotifyMisskey.unquote(results['qsd']['visibility'])
|
||||
|
||||
return results
|
|
@ -1,26 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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 CON
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import requests
|
||||
|
||||
|
@ -125,7 +133,7 @@ class NotifyNextcloud(NotifyBase):
|
|||
"""
|
||||
Initialize Nextcloud Object
|
||||
"""
|
||||
super(NotifyNextcloud, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.targets = parse_list(targets)
|
||||
if len(self.targets) == 0:
|
||||
|
@ -304,6 +312,12 @@ class NotifyNextcloud(NotifyBase):
|
|||
params=NotifyNextcloud.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,29 +1,38 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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 CON
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import requests
|
||||
|
||||
from json import dumps
|
||||
from .NotifyBase import NotifyBase
|
||||
from ..URLBase import PrivacyMode
|
||||
from ..common import NotifyType
|
||||
|
@ -106,7 +115,7 @@ class NotifyNextcloudTalk(NotifyBase):
|
|||
"""
|
||||
Initialize Nextcloud Talk Object
|
||||
"""
|
||||
super(NotifyNextcloudTalk, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
if self.user is None or self.password is None:
|
||||
msg = 'User and password have to be specified.'
|
||||
|
@ -134,7 +143,9 @@ class NotifyNextcloudTalk(NotifyBase):
|
|||
# Prepare our Header
|
||||
headers = {
|
||||
'User-Agent': self.app_id,
|
||||
'OCS-APIREQUEST': 'true',
|
||||
'OCS-APIRequest': 'true',
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
|
||||
# Apply any/all header over-rides defined
|
||||
|
@ -183,7 +194,7 @@ class NotifyNextcloudTalk(NotifyBase):
|
|||
try:
|
||||
r = requests.post(
|
||||
notify_url,
|
||||
data=payload,
|
||||
data=dumps(payload),
|
||||
headers=headers,
|
||||
auth=(self.user, self.password),
|
||||
verify=self.verify_certificate,
|
||||
|
@ -252,6 +263,12 @@ class NotifyNextcloudTalk(NotifyBase):
|
|||
for x in self.targets]),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,26 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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 CON
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# 1. Simply visit https://notica.us
|
||||
# 2. You'll be provided a new variation of the website which will look
|
||||
|
@ -160,7 +168,7 @@ class NotifyNotica(NotifyBase):
|
|||
"""
|
||||
Initialize Notica Object
|
||||
"""
|
||||
super(NotifyNotica, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Token (associated with project)
|
||||
self.token = validate_regex(token)
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Notifico allows you to relay notifications into IRC channels.
|
||||
#
|
||||
|
@ -160,7 +167,7 @@ class NotifyNotifico(NotifyBase):
|
|||
"""
|
||||
Initialize Notifico Object
|
||||
"""
|
||||
super(NotifyNotifico, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Assign our message hook
|
||||
self.project_id = validate_regex(
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Great sources
|
||||
# - https://github.com/matrix-org/matrix-python-sdk
|
||||
|
@ -40,8 +47,10 @@ from os.path import basename
|
|||
|
||||
from .NotifyBase import NotifyBase
|
||||
from ..common import NotifyType
|
||||
from ..common import NotifyImageSize
|
||||
from ..AppriseLocale import gettext_lazy as _
|
||||
from ..utils import parse_list
|
||||
from ..utils import parse_bool
|
||||
from ..utils import is_hostname
|
||||
from ..utils import is_ipaddr
|
||||
from ..utils import validate_regex
|
||||
|
@ -65,6 +74,27 @@ NTFY_MODES = (
|
|||
NtfyMode.PRIVATE,
|
||||
)
|
||||
|
||||
# A Simple regular expression used to auto detect Auth mode if it isn't
|
||||
# otherwise specified:
|
||||
NTFY_AUTH_DETECT_RE = re.compile('tk_[^ \t]+', re.IGNORECASE)
|
||||
|
||||
|
||||
class NtfyAuth:
|
||||
"""
|
||||
Define ntfy Authentication Modes
|
||||
"""
|
||||
# Basic auth (user and password provided)
|
||||
BASIC = "basic"
|
||||
|
||||
# Auth Token based
|
||||
TOKEN = "token"
|
||||
|
||||
|
||||
NTFY_AUTH = (
|
||||
NtfyAuth.BASIC,
|
||||
NtfyAuth.TOKEN,
|
||||
)
|
||||
|
||||
|
||||
class NtfyPriority:
|
||||
"""
|
||||
|
@ -142,6 +172,9 @@ class NotifyNtfy(NotifyBase):
|
|||
# Default upstream/cloud host if none is defined
|
||||
cloud_notify_url = 'https://ntfy.sh'
|
||||
|
||||
# Allows the user to specify the NotifyImageSize object
|
||||
image_size = NotifyImageSize.XY_256
|
||||
|
||||
# Message time to live (if remote client isn't around to receive it)
|
||||
time_to_live = 2419200
|
||||
|
||||
|
@ -158,6 +191,8 @@ class NotifyNtfy(NotifyBase):
|
|||
'{schema}://{user}@{host}:{port}/{targets}',
|
||||
'{schema}://{user}:{password}@{host}/{targets}',
|
||||
'{schema}://{user}:{password}@{host}:{port}/{targets}',
|
||||
'{schema}://{token}@{host}/{targets}',
|
||||
'{schema}://{token}@{host}:{port}/{targets}',
|
||||
)
|
||||
|
||||
# Define our template tokens
|
||||
|
@ -181,6 +216,11 @@ class NotifyNtfy(NotifyBase):
|
|||
'type': 'string',
|
||||
'private': True,
|
||||
},
|
||||
'token': {
|
||||
'name': _('Token'),
|
||||
'type': 'string',
|
||||
'private': True,
|
||||
},
|
||||
'topic': {
|
||||
'name': _('Topic'),
|
||||
'type': 'string',
|
||||
|
@ -199,6 +239,16 @@ class NotifyNtfy(NotifyBase):
|
|||
'name': _('Attach'),
|
||||
'type': 'string',
|
||||
},
|
||||
'image': {
|
||||
'name': _('Include Image'),
|
||||
'type': 'bool',
|
||||
'default': True,
|
||||
'map_to': 'include_image',
|
||||
},
|
||||
'avatar_url': {
|
||||
'name': _('Avatar URL'),
|
||||
'type': 'string',
|
||||
},
|
||||
'filename': {
|
||||
'name': _('Attach Filename'),
|
||||
'type': 'string',
|
||||
|
@ -231,6 +281,15 @@ class NotifyNtfy(NotifyBase):
|
|||
'values': NTFY_MODES,
|
||||
'default': NtfyMode.PRIVATE,
|
||||
},
|
||||
'token': {
|
||||
'alias_of': 'token',
|
||||
},
|
||||
'auth': {
|
||||
'name': _('Authentication Type'),
|
||||
'type': 'choice:string',
|
||||
'values': NTFY_AUTH,
|
||||
'default': NtfyAuth.BASIC,
|
||||
},
|
||||
'to': {
|
||||
'alias_of': 'targets',
|
||||
},
|
||||
|
@ -238,11 +297,12 @@ class NotifyNtfy(NotifyBase):
|
|||
|
||||
def __init__(self, targets=None, attach=None, filename=None, click=None,
|
||||
delay=None, email=None, priority=None, tags=None, mode=None,
|
||||
include_image=True, avatar_url=None, auth=None, token=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Initialize ntfy Object
|
||||
"""
|
||||
super(NotifyNtfy, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Prepare our mode
|
||||
self.mode = mode.strip().lower() \
|
||||
|
@ -254,6 +314,20 @@ class NotifyNtfy(NotifyBase):
|
|||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
# Show image associated with notification
|
||||
self.include_image = include_image
|
||||
|
||||
# Prepare our authentication type
|
||||
self.auth = auth.strip().lower() \
|
||||
if isinstance(auth, str) \
|
||||
else self.template_args['auth']['default']
|
||||
|
||||
if self.auth not in NTFY_AUTH:
|
||||
msg = 'An invalid ntfy Authentication type ({}) was specified.' \
|
||||
.format(auth)
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
# Attach a file (URL supported)
|
||||
self.attach = attach
|
||||
|
||||
|
@ -269,6 +343,9 @@ class NotifyNtfy(NotifyBase):
|
|||
# An email to forward notifications to
|
||||
self.email = email
|
||||
|
||||
# Save our token
|
||||
self.token = token
|
||||
|
||||
# The Priority of the message
|
||||
self.priority = NotifyNtfy.template_args['priority']['default'] \
|
||||
if not priority else \
|
||||
|
@ -280,6 +357,11 @@ class NotifyNtfy(NotifyBase):
|
|||
# Any optional tags to attach to the notification
|
||||
self.__tags = parse_list(tags)
|
||||
|
||||
# Avatar URL
|
||||
# This allows a user to provide an over-ride to the otherwise
|
||||
# dynamically generated avatar url images
|
||||
self.avatar_url = avatar_url
|
||||
|
||||
# Build list of topics
|
||||
topics = parse_list(targets)
|
||||
self.topics = []
|
||||
|
@ -308,6 +390,15 @@ class NotifyNtfy(NotifyBase):
|
|||
self.logger.warning('There are no ntfy topics to notify')
|
||||
return False
|
||||
|
||||
# Acquire image_url
|
||||
image_url = self.image_url(notify_type)
|
||||
|
||||
if self.include_image and (image_url or self.avatar_url):
|
||||
image_url = \
|
||||
self.avatar_url if self.avatar_url else image_url
|
||||
else:
|
||||
image_url = None
|
||||
|
||||
# Create a copy of the topics
|
||||
topics = list(self.topics)
|
||||
while len(topics) > 0:
|
||||
|
@ -336,20 +427,23 @@ class NotifyNtfy(NotifyBase):
|
|||
attachment.url(privacy=True)))
|
||||
|
||||
okay, response = self._send(
|
||||
topic, body=_body, title=_title, attach=attachment)
|
||||
topic, body=_body, title=_title, image_url=image_url,
|
||||
attach=attachment)
|
||||
if not okay:
|
||||
# We can't post our attachment; abort immediately
|
||||
return False
|
||||
else:
|
||||
# Send our Notification Message
|
||||
okay, response = self._send(topic, body=body, title=title)
|
||||
okay, response = self._send(
|
||||
topic, body=body, title=title, image_url=image_url)
|
||||
if not okay:
|
||||
# Mark our failure, but contiue to move on
|
||||
has_error = True
|
||||
|
||||
return not has_error
|
||||
|
||||
def _send(self, topic, body=None, title=None, attach=None, **kwargs):
|
||||
def _send(self, topic, body=None, title=None, attach=None, image_url=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Wrapper to the requests (post) object
|
||||
"""
|
||||
|
@ -376,9 +470,17 @@ class NotifyNtfy(NotifyBase):
|
|||
|
||||
else: # NotifyNtfy.PRVATE
|
||||
# Allow more settings to be applied now
|
||||
if self.user:
|
||||
if self.auth == NtfyAuth.BASIC and self.user:
|
||||
auth = (self.user, self.password)
|
||||
|
||||
elif self.auth == NtfyAuth.TOKEN:
|
||||
if not self.token:
|
||||
self.logger.warning('No Ntfy Token was specified')
|
||||
return False, None
|
||||
|
||||
# Set Token
|
||||
headers['Authorization'] = f'Bearer {self.token}'
|
||||
|
||||
# Prepare our ntfy Template URL
|
||||
schema = 'https' if self.secure else 'http'
|
||||
|
||||
|
@ -397,6 +499,9 @@ class NotifyNtfy(NotifyBase):
|
|||
virt_payload = params
|
||||
notify_url += '/{topic}'.format(topic=topic)
|
||||
|
||||
if image_url:
|
||||
headers['X-Icon'] = image_url
|
||||
|
||||
if title:
|
||||
virt_payload['title'] = title
|
||||
|
||||
|
@ -529,8 +634,13 @@ class NotifyNtfy(NotifyBase):
|
|||
params = {
|
||||
'priority': self.priority,
|
||||
'mode': self.mode,
|
||||
'image': 'yes' if self.include_image else 'no',
|
||||
'auth': self.auth,
|
||||
}
|
||||
|
||||
if self.avatar_url:
|
||||
params['avatar_url'] = self.avatar_url
|
||||
|
||||
if self.attach is not None:
|
||||
params['attach'] = self.attach
|
||||
|
||||
|
@ -550,15 +660,22 @@ class NotifyNtfy(NotifyBase):
|
|||
|
||||
# Determine Authentication
|
||||
auth = ''
|
||||
if self.user and self.password:
|
||||
auth = '{user}:{password}@'.format(
|
||||
user=NotifyNtfy.quote(self.user, safe=''),
|
||||
password=self.pprint(
|
||||
self.password, privacy, mode=PrivacyMode.Secret, safe=''),
|
||||
)
|
||||
elif self.user:
|
||||
auth = '{user}@'.format(
|
||||
user=NotifyNtfy.quote(self.user, safe=''),
|
||||
if self.auth == NtfyAuth.BASIC:
|
||||
if self.user and self.password:
|
||||
auth = '{user}:{password}@'.format(
|
||||
user=NotifyNtfy.quote(self.user, safe=''),
|
||||
password=self.pprint(
|
||||
self.password, privacy, mode=PrivacyMode.Secret,
|
||||
safe=''),
|
||||
)
|
||||
elif self.user:
|
||||
auth = '{user}@'.format(
|
||||
user=NotifyNtfy.quote(self.user, safe=''),
|
||||
)
|
||||
|
||||
elif self.token: # NtfyAuth.TOKEN also
|
||||
auth = '{token}@'.format(
|
||||
token=self.pprint(self.token, privacy, safe=''),
|
||||
)
|
||||
|
||||
if self.mode == NtfyMode.PRIVATE:
|
||||
|
@ -581,6 +698,12 @@ class NotifyNtfy(NotifyBase):
|
|||
params=NotifyNtfy.urlencode(params)
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.topics)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -623,6 +746,15 @@ class NotifyNtfy(NotifyBase):
|
|||
results['tags'] = \
|
||||
parse_list(NotifyNtfy.unquote(results['qsd']['tags']))
|
||||
|
||||
# Boolean to include an image or not
|
||||
results['include_image'] = parse_bool(results['qsd'].get(
|
||||
'image', NotifyNtfy.template_args['image']['default']))
|
||||
|
||||
# Extract avatar url if it was specified
|
||||
if 'avatar_url' in results['qsd']:
|
||||
results['avatar_url'] = \
|
||||
NotifyNtfy.unquote(results['qsd']['avatar_url'])
|
||||
|
||||
# Acquire our targets/topics
|
||||
results['targets'] = NotifyNtfy.split_path(results['fullpath'])
|
||||
|
||||
|
@ -631,6 +763,37 @@ class NotifyNtfy(NotifyBase):
|
|||
results['targets'] += \
|
||||
NotifyNtfy.parse_list(results['qsd']['to'])
|
||||
|
||||
# Token Specified
|
||||
if 'token' in results['qsd'] and len(results['qsd']['token']):
|
||||
# Token presumed to be the one in use
|
||||
results['auth'] = NtfyAuth.TOKEN
|
||||
results['token'] = NotifyNtfy.unquote(results['qsd']['token'])
|
||||
|
||||
# Auth override
|
||||
if 'auth' in results['qsd'] and results['qsd']['auth']:
|
||||
results['auth'] = NotifyNtfy.unquote(
|
||||
results['qsd']['auth'].strip().lower())
|
||||
|
||||
if not results.get('auth') and results['user'] \
|
||||
and not results['password']:
|
||||
# We can try to detect the authentication type on the formatting of
|
||||
# the username. Look for tk_.*
|
||||
#
|
||||
# This isn't a surfire way to do things though; it's best to
|
||||
# specify the auth= flag
|
||||
results['auth'] = NtfyAuth.TOKEN \
|
||||
if NTFY_AUTH_DETECT_RE.match(results['user']) \
|
||||
else NtfyAuth.BASIC
|
||||
|
||||
if results.get('auth') == NtfyAuth.TOKEN and not results.get('token'):
|
||||
if results['user'] and not results['password']:
|
||||
# Make sure we properly set our token
|
||||
results['token'] = NotifyNtfy.unquote(results['user'])
|
||||
|
||||
elif results['password']:
|
||||
# Make sure we properly set our token
|
||||
results['token'] = NotifyNtfy.unquote(results['password'])
|
||||
|
||||
# Mode override
|
||||
if 'mode' in results['qsd'] and results['qsd']['mode']:
|
||||
results['mode'] = NotifyNtfy.unquote(
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# API Details:
|
||||
# https://docs.microsoft.com/en-us/previous-versions/office/\
|
||||
|
@ -173,7 +180,7 @@ class NotifyOffice365(NotifyBase):
|
|||
"""
|
||||
Initialize Office 365 Object
|
||||
"""
|
||||
super(NotifyOffice365, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Tenant identifier
|
||||
self.tenant = validate_regex(
|
||||
|
@ -589,6 +596,12 @@ class NotifyOffice365(NotifyBase):
|
|||
safe='') for e in self.targets]),
|
||||
params=NotifyOffice365.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# One Signal requires that you've signed up with the service and
|
||||
# generated yourself an API Key and APP ID.
|
||||
|
@ -44,7 +51,7 @@ from ..utils import is_email
|
|||
from ..AppriseLocale import gettext_lazy as _
|
||||
|
||||
|
||||
class OneSignalCategory(NotifyBase):
|
||||
class OneSignalCategory:
|
||||
"""
|
||||
We define the different category types that we can notify via OneSignal
|
||||
"""
|
||||
|
@ -85,7 +92,7 @@ class NotifyOneSignal(NotifyBase):
|
|||
image_size = NotifyImageSize.XY_72
|
||||
|
||||
# The maximum allowable batch sizes per message
|
||||
maximum_batch_size = 2000
|
||||
default_batch_size = 2000
|
||||
|
||||
# Define object templates
|
||||
templates = (
|
||||
|
@ -114,7 +121,7 @@ class NotifyOneSignal(NotifyBase):
|
|||
'private': True,
|
||||
'required': True,
|
||||
},
|
||||
'target_device': {
|
||||
'target_player': {
|
||||
'name': _('Target Player ID'),
|
||||
'type': 'string',
|
||||
'map_to': 'targets',
|
||||
|
@ -178,7 +185,7 @@ class NotifyOneSignal(NotifyBase):
|
|||
Initialize OneSignal
|
||||
|
||||
"""
|
||||
super(NotifyOneSignal, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# The apikey associated with the account
|
||||
self.apikey = validate_regex(apikey)
|
||||
|
@ -197,7 +204,7 @@ class NotifyOneSignal(NotifyBase):
|
|||
raise TypeError(msg)
|
||||
|
||||
# Prepare Batch Mode Flag
|
||||
self.batch_size = self.maximum_batch_size if batch else 1
|
||||
self.batch_size = self.default_batch_size if batch else 1
|
||||
|
||||
# Place a thumbnail image inline with the message body
|
||||
self.include_image = include_image
|
||||
|
@ -425,6 +432,26 @@ class NotifyOneSignal(NotifyBase):
|
|||
params=NotifyOneSignal.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
if self.batch_size > 1:
|
||||
# Batches can only be sent by group (you can't combine groups into
|
||||
# a single batch)
|
||||
total_targets = 0
|
||||
for k, m in self.targets.items():
|
||||
targets = len(m)
|
||||
total_targets += int(targets / self.batch_size) + \
|
||||
(1 if targets % self.batch_size else 0)
|
||||
return total_targets
|
||||
|
||||
# Normal batch count; just count the targets
|
||||
return sum([len(m) for _, m in self.targets.items()])
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Signup @ https://www.opsgenie.com
|
||||
#
|
||||
|
@ -165,7 +172,7 @@ class NotifyOpsgenie(NotifyBase):
|
|||
opsgenie_default_region = OpsgenieRegion.US
|
||||
|
||||
# The maximum allowable targets within a notification
|
||||
maximum_batch_size = 50
|
||||
default_batch_size = 50
|
||||
|
||||
# Define object templates
|
||||
templates = (
|
||||
|
@ -262,7 +269,7 @@ class NotifyOpsgenie(NotifyBase):
|
|||
"""
|
||||
Initialize Opsgenie Object
|
||||
"""
|
||||
super(NotifyOpsgenie, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# API Key (associated with project)
|
||||
self.apikey = validate_regex(apikey)
|
||||
|
@ -301,7 +308,7 @@ class NotifyOpsgenie(NotifyBase):
|
|||
self.details.update(details)
|
||||
|
||||
# Prepare Batch Mode Flag
|
||||
self.batch_size = self.maximum_batch_size if batch else 1
|
||||
self.batch_size = self.default_batch_size if batch else 1
|
||||
|
||||
# Assign our tags (if defined)
|
||||
self.__tags = parse_list(tags)
|
||||
|
@ -382,7 +389,7 @@ class NotifyOpsgenie(NotifyBase):
|
|||
has_error = False
|
||||
|
||||
# Use body if title not set
|
||||
title_body = body if not title else body
|
||||
title_body = body if not title else title
|
||||
|
||||
# Create a copy ouf our details object
|
||||
details = self.details.copy()
|
||||
|
@ -529,6 +536,20 @@ class NotifyOpsgenie(NotifyBase):
|
|||
for x in self.targets]),
|
||||
params=NotifyOpsgenie.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
targets = len(self.targets)
|
||||
if self.batch_size > 1:
|
||||
targets = int(targets / self.batch_size) + \
|
||||
(1 if targets % self.batch_size else 0)
|
||||
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# API Refererence:
|
||||
# - https://developer.pagerduty.com/api-reference/\
|
||||
|
@ -61,6 +68,13 @@ PAGERDUTY_SEVERITY_MAP = {
|
|||
NotifyType.FAILURE: PagerDutySeverity.CRITICAL,
|
||||
}
|
||||
|
||||
PAGERDUTY_SEVERITIES = (
|
||||
PagerDutySeverity.INFO,
|
||||
PagerDutySeverity.WARNING,
|
||||
PagerDutySeverity.CRITICAL,
|
||||
PagerDutySeverity.ERROR,
|
||||
)
|
||||
|
||||
|
||||
# Priorities
|
||||
class PagerDutyRegion:
|
||||
|
@ -169,6 +183,14 @@ class NotifyPagerDuty(NotifyBase):
|
|||
'default': PagerDutyRegion.US,
|
||||
'map_to': 'region_name',
|
||||
},
|
||||
# The severity is automatically determined, however you can optionally
|
||||
# over-ride its value and force it to be what you want
|
||||
'severity': {
|
||||
'name': _('Severity'),
|
||||
'type': 'choice:string',
|
||||
'values': PAGERDUTY_SEVERITIES,
|
||||
'map_to': 'severity',
|
||||
},
|
||||
'image': {
|
||||
'name': _('Include Image'),
|
||||
'type': 'bool',
|
||||
|
@ -188,11 +210,11 @@ class NotifyPagerDuty(NotifyBase):
|
|||
def __init__(self, apikey, integrationkey=None, source=None,
|
||||
component=None, group=None, class_id=None,
|
||||
include_image=True, click=None, details=None,
|
||||
region_name=None, **kwargs):
|
||||
region_name=None, severity=None, **kwargs):
|
||||
"""
|
||||
Initialize Pager Duty Object
|
||||
"""
|
||||
super(NotifyPagerDuty, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Long-Lived Access token (generated from User Profile)
|
||||
self.apikey = validate_regex(apikey)
|
||||
|
@ -248,6 +270,19 @@ class NotifyPagerDuty(NotifyBase):
|
|||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
# The severity (if specified)
|
||||
self.severity = \
|
||||
None if severity is None else next((
|
||||
s for s in PAGERDUTY_SEVERITIES
|
||||
if str(s).lower().startswith(severity)), False)
|
||||
|
||||
if self.severity is False:
|
||||
# Invalid severity specified
|
||||
msg = 'The PagerDuty severity specified ({}) is invalid.' \
|
||||
.format(severity)
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
# A clickthrough option for notifications
|
||||
self.click = click
|
||||
|
||||
|
@ -289,8 +324,8 @@ class NotifyPagerDuty(NotifyBase):
|
|||
'summary': body,
|
||||
|
||||
# Set our severity
|
||||
'severity': PAGERDUTY_SEVERITY_MAP[notify_type],
|
||||
|
||||
'severity': PAGERDUTY_SEVERITY_MAP[notify_type]
|
||||
if not self.severity else self.severity,
|
||||
|
||||
# Our Alerting Source/Component
|
||||
'source': self.source,
|
||||
|
@ -400,6 +435,9 @@ class NotifyPagerDuty(NotifyBase):
|
|||
if self.click is not None:
|
||||
params['click'] = self.click
|
||||
|
||||
if self.severity:
|
||||
params['severity'] = self.severity
|
||||
|
||||
# Append our custom entries our parameters
|
||||
params.update({'+{}'.format(k): v for k, v in self.details.items()})
|
||||
|
||||
|
@ -464,6 +502,10 @@ class NotifyPagerDuty(NotifyBase):
|
|||
results['class_id'] = \
|
||||
NotifyPagerDuty.unquote(results['qsd']['class'])
|
||||
|
||||
if 'severity' in results['qsd'] and len(results['qsd']['severity']):
|
||||
results['severity'] = \
|
||||
NotifyPagerDuty.unquote(results['qsd']['severity'])
|
||||
|
||||
# Acquire our full path
|
||||
fullpath = NotifyPagerDuty.split_path(results['fullpath'])
|
||||
|
||||
|
|
424
libs/apprise/plugins/NotifyPagerTree.py
Normal file
424
libs/apprise/plugins/NotifyPagerTree.py
Normal file
|
@ -0,0 +1,424 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import requests
|
||||
from json import dumps
|
||||
|
||||
from uuid import uuid4
|
||||
|
||||
from .NotifyBase import NotifyBase
|
||||
from ..common import NotifyType
|
||||
from ..utils import parse_list
|
||||
from ..utils import validate_regex
|
||||
from ..AppriseLocale import gettext_lazy as _
|
||||
|
||||
|
||||
# Actions
|
||||
class PagerTreeAction:
|
||||
CREATE = 'create'
|
||||
ACKNOWLEDGE = 'acknowledge'
|
||||
RESOLVE = 'resolve'
|
||||
|
||||
|
||||
# Urgencies
|
||||
class PagerTreeUrgency:
|
||||
SILENT = "silent"
|
||||
LOW = "low"
|
||||
MEDIUM = "medium"
|
||||
HIGH = "high"
|
||||
CRITICAL = "critical"
|
||||
|
||||
|
||||
PAGERTREE_ACTIONS = {
|
||||
PagerTreeAction.CREATE: 'create',
|
||||
PagerTreeAction.ACKNOWLEDGE: 'acknowledge',
|
||||
PagerTreeAction.RESOLVE: 'resolve',
|
||||
}
|
||||
|
||||
PAGERTREE_URGENCIES = {
|
||||
# Note: This also acts as a reverse lookup mapping
|
||||
PagerTreeUrgency.SILENT: 'silent',
|
||||
PagerTreeUrgency.LOW: 'low',
|
||||
PagerTreeUrgency.MEDIUM: 'medium',
|
||||
PagerTreeUrgency.HIGH: 'high',
|
||||
PagerTreeUrgency.CRITICAL: 'critical',
|
||||
}
|
||||
# Extend HTTP Error Messages
|
||||
PAGERTREE_HTTP_ERROR_MAP = {
|
||||
402: 'Payment Required - Please subscribe or upgrade',
|
||||
403: 'Forbidden - Blocked',
|
||||
404: 'Not Found - Invalid Integration ID',
|
||||
405: 'Method Not Allowed - Integration Disabled',
|
||||
429: 'Too Many Requests - Rate Limit Exceeded',
|
||||
}
|
||||
|
||||
|
||||
class NotifyPagerTree(NotifyBase):
|
||||
"""
|
||||
A wrapper for PagerTree Notifications
|
||||
"""
|
||||
|
||||
# The default descriptive name associated with the Notification
|
||||
service_name = 'PagerTree'
|
||||
|
||||
# The services URL
|
||||
service_url = 'https://pagertree.com/'
|
||||
|
||||
# All PagerTree requests are secure
|
||||
secure_protocol = 'pagertree'
|
||||
|
||||
# A URL that takes you to the setup/help of the specific protocol
|
||||
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_pagertree'
|
||||
|
||||
# PagerTree uses the http protocol with JSON requests
|
||||
notify_url = 'https://api.pagertree.com/integration/{}'
|
||||
|
||||
# Define object templates
|
||||
templates = (
|
||||
'{schema}://{integration}',
|
||||
)
|
||||
|
||||
# Define our template tokens
|
||||
template_tokens = dict(NotifyBase.template_tokens, **{
|
||||
'integration': {
|
||||
'name': _('Integration ID'),
|
||||
'type': 'string',
|
||||
'private': True,
|
||||
'required': True,
|
||||
}
|
||||
})
|
||||
|
||||
# Define our template arguments
|
||||
template_args = dict(NotifyBase.template_args, **{
|
||||
'action': {
|
||||
'name': _('Action'),
|
||||
'type': 'choice:string',
|
||||
'values': PAGERTREE_ACTIONS,
|
||||
'default': PagerTreeAction.CREATE,
|
||||
},
|
||||
'thirdparty': {
|
||||
'name': _('Third Party ID'),
|
||||
'type': 'string',
|
||||
},
|
||||
'urgency': {
|
||||
'name': _('Urgency'),
|
||||
'type': 'choice:string',
|
||||
'values': PAGERTREE_URGENCIES,
|
||||
},
|
||||
'tags': {
|
||||
'name': _('Tags'),
|
||||
'type': 'string',
|
||||
},
|
||||
})
|
||||
|
||||
# Define any kwargs we're using
|
||||
template_kwargs = {
|
||||
'headers': {
|
||||
'name': _('HTTP Header'),
|
||||
'prefix': '+',
|
||||
},
|
||||
'payload_extras': {
|
||||
'name': _('Payload Extras'),
|
||||
'prefix': ':',
|
||||
},
|
||||
'meta_extras': {
|
||||
'name': _('Meta Extras'),
|
||||
'prefix': '-',
|
||||
},
|
||||
}
|
||||
|
||||
def __init__(self, integration, action=None, thirdparty=None,
|
||||
urgency=None, tags=None, headers=None,
|
||||
payload_extras=None, meta_extras=None, **kwargs):
|
||||
"""
|
||||
Initialize PagerTree Object
|
||||
"""
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Integration ID (associated with account)
|
||||
self.integration = \
|
||||
validate_regex(integration, r'^int_[a-zA-Z0-9\-_]{7,14}$')
|
||||
if not self.integration:
|
||||
msg = 'An invalid PagerTree Integration ID ' \
|
||||
'({}) was specified.'.format(integration)
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
# thirdparty (optional, in case they want to pass the
|
||||
# acknowledge or resolve action)
|
||||
self.thirdparty = None
|
||||
if thirdparty:
|
||||
# An id was specified, we want to validate it
|
||||
self.thirdparty = validate_regex(thirdparty)
|
||||
if not self.thirdparty:
|
||||
msg = 'An invalid PagerTree third party ID ' \
|
||||
'({}) was specified.'.format(thirdparty)
|
||||
self.logger.warning(msg)
|
||||
raise TypeError(msg)
|
||||
|
||||
self.headers = {}
|
||||
if headers:
|
||||
# Store our extra headers
|
||||
self.headers.update(headers)
|
||||
|
||||
self.payload_extras = {}
|
||||
if payload_extras:
|
||||
# Store our extra payload entries
|
||||
self.payload_extras.update(payload_extras)
|
||||
|
||||
self.meta_extras = {}
|
||||
if meta_extras:
|
||||
# Store our extra payload entries
|
||||
self.meta_extras.update(meta_extras)
|
||||
|
||||
# Setup our action
|
||||
self.action = NotifyPagerTree.template_args['action']['default'] \
|
||||
if action not in PAGERTREE_ACTIONS else \
|
||||
PAGERTREE_ACTIONS[action]
|
||||
|
||||
# Setup our urgency
|
||||
self.urgency = \
|
||||
None if urgency not in PAGERTREE_URGENCIES else \
|
||||
PAGERTREE_URGENCIES[urgency]
|
||||
|
||||
# Any optional tags to attach to the notification
|
||||
self.__tags = parse_list(tags)
|
||||
|
||||
return
|
||||
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
|
||||
"""
|
||||
Perform PagerTree Notification
|
||||
"""
|
||||
|
||||
# Prepare our headers
|
||||
headers = {
|
||||
'User-Agent': self.app_id,
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
|
||||
# Apply any/all header over-rides defined
|
||||
# For things like PagerTree Token
|
||||
headers.update(self.headers)
|
||||
|
||||
# prepare JSON Object
|
||||
payload = {
|
||||
# Generate an ID (unless one was explicitly forced to be used)
|
||||
'id': self.thirdparty if self.thirdparty else str(uuid4()),
|
||||
'event_type': self.action,
|
||||
}
|
||||
|
||||
if self.action == PagerTreeAction.CREATE:
|
||||
payload['title'] = title if title else self.app_desc
|
||||
payload['description'] = body
|
||||
|
||||
payload['meta'] = self.meta_extras
|
||||
payload['tags'] = self.__tags
|
||||
|
||||
if self.urgency is not None:
|
||||
payload['urgency'] = self.urgency
|
||||
|
||||
# Apply any/all payload over-rides defined
|
||||
payload.update(self.payload_extras)
|
||||
|
||||
# Prepare our URL based on integration
|
||||
notify_url = self.notify_url.format(self.integration)
|
||||
|
||||
self.logger.debug('PagerTree POST URL: %s (cert_verify=%r)' % (
|
||||
notify_url, self.verify_certificate,
|
||||
))
|
||||
self.logger.debug('PagerTree Payload: %s' % str(payload))
|
||||
|
||||
# Always call throttle before any remote server i/o is made
|
||||
self.throttle()
|
||||
|
||||
try:
|
||||
r = requests.post(
|
||||
notify_url,
|
||||
data=dumps(payload),
|
||||
headers=headers,
|
||||
verify=self.verify_certificate,
|
||||
timeout=self.request_timeout,
|
||||
)
|
||||
if r.status_code not in (
|
||||
requests.codes.ok, requests.codes.created,
|
||||
requests.codes.accepted):
|
||||
# We had a problem
|
||||
status_str = \
|
||||
NotifyPagerTree.http_response_code_lookup(
|
||||
r.status_code)
|
||||
|
||||
self.logger.warning(
|
||||
'Failed to send PagerTree notification: '
|
||||
'{}{}error={}.'.format(
|
||||
status_str,
|
||||
', ' if status_str else '',
|
||||
r.status_code))
|
||||
|
||||
self.logger.debug('Response Details:\r\n{}'.format(r.content))
|
||||
|
||||
# Return; we're done
|
||||
return False
|
||||
|
||||
else:
|
||||
self.logger.info('Sent PagerTree notification.')
|
||||
|
||||
except requests.RequestException as e:
|
||||
self.logger.warning(
|
||||
'A Connection error occurred sending PagerTree '
|
||||
'notification to %s.' % self.host)
|
||||
self.logger.debug('Socket Exception: %s' % str(e))
|
||||
|
||||
# Return; we're done
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def url(self, privacy=False, *args, **kwargs):
|
||||
"""
|
||||
Returns the URL built dynamically based on specified arguments.
|
||||
"""
|
||||
|
||||
# Define any URL parameters
|
||||
params = {
|
||||
'action': self.action,
|
||||
}
|
||||
|
||||
if self.thirdparty:
|
||||
params['tid'] = self.thirdparty
|
||||
|
||||
if self.urgency:
|
||||
params['urgency'] = self.urgency
|
||||
|
||||
if self.__tags:
|
||||
params['tags'] = ','.join([x for x in self.__tags])
|
||||
|
||||
# Extend our parameters
|
||||
params.update(self.url_parameters(privacy=privacy, *args, **kwargs))
|
||||
|
||||
# Headers prefixed with a '+' sign
|
||||
# Append our headers into our parameters
|
||||
params.update({'+{}'.format(k): v for k, v in self.headers.items()})
|
||||
|
||||
# Meta: {} prefixed with a '-' sign
|
||||
# Append our meta extras into our parameters
|
||||
params.update(
|
||||
{'-{}'.format(k): v for k, v in self.meta_extras.items()})
|
||||
|
||||
# Payload body extras prefixed with a ':' sign
|
||||
# Append our payload extras into our parameters
|
||||
params.update(
|
||||
{':{}'.format(k): v for k, v in self.payload_extras.items()})
|
||||
|
||||
return '{schema}://{integration}?{params}'.format(
|
||||
schema=self.secure_protocol,
|
||||
# never encode hostname since we're expecting it to be a valid one
|
||||
integration=self.pprint(self.integration, privacy, safe=''),
|
||||
params=NotifyPagerTree.urlencode(params),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
Parses the URL and returns enough arguments that can allow
|
||||
us to re-instantiate this object.
|
||||
|
||||
"""
|
||||
results = NotifyBase.parse_url(url, verify_host=False)
|
||||
|
||||
if not results:
|
||||
# We're done early as we couldn't load the results
|
||||
return results
|
||||
|
||||
# Add our headers that the user can potentially over-ride if they wish
|
||||
# to to our returned result set and tidy entries by unquoting them
|
||||
results['headers'] = {
|
||||
NotifyPagerTree.unquote(x): NotifyPagerTree.unquote(y)
|
||||
for x, y in results['qsd+'].items()
|
||||
}
|
||||
|
||||
# store any additional payload extra's defined
|
||||
results['payload_extras'] = {
|
||||
NotifyPagerTree.unquote(x): NotifyPagerTree.unquote(y)
|
||||
for x, y in results['qsd:'].items()
|
||||
}
|
||||
|
||||
# store any additional meta extra's defined
|
||||
results['meta_extras'] = {
|
||||
NotifyPagerTree.unquote(x): NotifyPagerTree.unquote(y)
|
||||
for x, y in results['qsd-'].items()
|
||||
}
|
||||
|
||||
# Integration ID
|
||||
if 'id' in results['qsd'] and len(results['qsd']['id']):
|
||||
# Shortened version of integration id
|
||||
results['integration'] = \
|
||||
NotifyPagerTree.unquote(results['qsd']['id'])
|
||||
|
||||
elif 'integration' in results['qsd'] and \
|
||||
len(results['qsd']['integration']):
|
||||
results['integration'] = \
|
||||
NotifyPagerTree.unquote(results['qsd']['integration'])
|
||||
|
||||
else:
|
||||
results['integration'] = \
|
||||
NotifyPagerTree.unquote(results['host'])
|
||||
|
||||
# Set our thirdparty
|
||||
|
||||
if 'tid' in results['qsd'] and len(results['qsd']['tid']):
|
||||
# Shortened version of thirdparty
|
||||
results['thirdparty'] = \
|
||||
NotifyPagerTree.unquote(results['qsd']['tid'])
|
||||
|
||||
elif 'thirdparty' in results['qsd'] and \
|
||||
len(results['qsd']['thirdparty']):
|
||||
results['thirdparty'] = \
|
||||
NotifyPagerTree.unquote(results['qsd']['thirdparty'])
|
||||
|
||||
# Set our urgency
|
||||
if 'action' in results['qsd'] and \
|
||||
len(results['qsd']['action']):
|
||||
results['action'] = \
|
||||
NotifyPagerTree.unquote(results['qsd']['action'])
|
||||
|
||||
# Set our urgency
|
||||
if 'urgency' in results['qsd'] and len(results['qsd']['urgency']):
|
||||
results['urgency'] = \
|
||||
NotifyPagerTree.unquote(results['qsd']['urgency'])
|
||||
|
||||
# Set our tags
|
||||
if 'tags' in results['qsd'] and len(results['qsd']['tags']):
|
||||
results['tags'] = \
|
||||
parse_list(NotifyPagerTree.unquote(results['qsd']['tags']))
|
||||
|
||||
return results
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Official API reference: https://developer.gitter.im/docs/user-resource
|
||||
|
||||
|
@ -130,7 +137,7 @@ class NotifyParsePlatform(NotifyBase):
|
|||
"""
|
||||
Initialize Parse Platform Object
|
||||
"""
|
||||
super(NotifyParsePlatform, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.fullpath = kwargs.get('fullpath')
|
||||
if not isinstance(self.fullpath, str):
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import requests
|
||||
|
||||
|
@ -105,7 +112,7 @@ class NotifyPopcornNotify(NotifyBase):
|
|||
"""
|
||||
Initialize PopcornNotify Object
|
||||
"""
|
||||
super(NotifyPopcornNotify, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Access Token (associated with project)
|
||||
self.apikey = validate_regex(
|
||||
|
@ -258,6 +265,21 @@ class NotifyPopcornNotify(NotifyBase):
|
|||
[NotifyPopcornNotify.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyPopcornNotify.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
|
||||
return targets
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import requests
|
||||
|
||||
|
@ -143,7 +150,7 @@ class NotifyProwl(NotifyBase):
|
|||
"""
|
||||
Initialize Prowl Object
|
||||
"""
|
||||
super(NotifyProwl, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# The Priority of the message
|
||||
self.priority = NotifyProwl.template_args['priority']['default'] \
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import requests
|
||||
from json import dumps
|
||||
|
@ -115,7 +122,7 @@ class NotifyPushBullet(NotifyBase):
|
|||
"""
|
||||
Initialize PushBullet Object
|
||||
"""
|
||||
super(NotifyPushBullet, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Access Token (associated with project)
|
||||
self.accesstoken = validate_regex(accesstoken)
|
||||
|
@ -399,6 +406,12 @@ class NotifyPushBullet(NotifyBase):
|
|||
targets=targets,
|
||||
params=NotifyPushBullet.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import base64
|
||||
import requests
|
||||
|
@ -400,7 +407,7 @@ class NotifyPushSafer(NotifyBase):
|
|||
"""
|
||||
Initialize PushSafer Object
|
||||
"""
|
||||
super(NotifyPushSafer, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
#
|
||||
# Priority
|
||||
|
@ -787,6 +794,12 @@ class NotifyPushSafer(NotifyBase):
|
|||
targets=targets,
|
||||
params=NotifyPushSafer.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import requests
|
||||
|
@ -120,7 +127,7 @@ class NotifyPushed(NotifyBase):
|
|||
Initialize Pushed Object
|
||||
|
||||
"""
|
||||
super(NotifyPushed, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Application Key (associated with project)
|
||||
self.app_key = validate_regex(app_key)
|
||||
|
@ -322,6 +329,13 @@ class NotifyPushed(NotifyBase):
|
|||
)]),
|
||||
params=NotifyPushed.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.channels) + len(self.users)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import requests
|
||||
from json import dumps
|
||||
|
@ -102,7 +109,7 @@ class NotifyPushjet(NotifyBase):
|
|||
"""
|
||||
Initialize Pushjet Object
|
||||
"""
|
||||
super(NotifyPushjet, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Secret Key (associated with project)
|
||||
self.secret_key = validate_regex(secret_key)
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import requests
|
||||
|
@ -158,7 +165,7 @@ class NotifyPushover(NotifyBase):
|
|||
notify_url = 'https://api.pushover.net/1/messages.json'
|
||||
|
||||
# The maximum allowable characters allowed in the body per message
|
||||
body_maxlen = 512
|
||||
body_maxlen = 1024
|
||||
|
||||
# Default Pushover sound
|
||||
default_pushover_sound = PushoverSound.PUSHOVER
|
||||
|
@ -251,7 +258,7 @@ class NotifyPushover(NotifyBase):
|
|||
"""
|
||||
Initialize Pushover Object
|
||||
"""
|
||||
super(NotifyPushover, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Access Token (associated with project)
|
||||
self.token = validate_regex(token)
|
||||
|
@ -570,6 +577,12 @@ class NotifyPushover(NotifyBase):
|
|||
devices=devices,
|
||||
params=NotifyPushover.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2021 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#
|
||||
# 1. Visit https://www.reddit.com/prefs/apps and scroll to the bottom
|
||||
# 2. Click on the button that reads 'are you a developer? create an app...'
|
||||
|
@ -240,7 +248,7 @@ class NotifyReddit(NotifyBase):
|
|||
"""
|
||||
Initialize Notify Reddit Object
|
||||
"""
|
||||
super(NotifyReddit, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Initialize subreddit list
|
||||
self.subreddits = set()
|
||||
|
@ -359,6 +367,12 @@ class NotifyReddit(NotifyBase):
|
|||
params=NotifyReddit.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.subreddits)
|
||||
|
||||
def login(self):
|
||||
"""
|
||||
A simple wrapper to authenticate with the Reddit Server
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import requests
|
||||
|
@ -48,10 +55,6 @@ RC_HTTP_ERROR_MAP = {
|
|||
401: 'Authentication tokens provided is invalid or missing.',
|
||||
}
|
||||
|
||||
# Used to break apart list of potential tags by their delimiter
|
||||
# into a usable list.
|
||||
LIST_DELIM = re.compile(r'[ \t\r\n,\\/]+')
|
||||
|
||||
|
||||
class RocketChatAuthMode:
|
||||
"""
|
||||
|
@ -188,7 +191,7 @@ class NotifyRocketChat(NotifyBase):
|
|||
"""
|
||||
Initialize Notify Rocket.Chat Object
|
||||
"""
|
||||
super(NotifyRocketChat, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Set our schema
|
||||
self.schema = 'https' if self.secure else 'http'
|
||||
|
@ -320,7 +323,8 @@ class NotifyRocketChat(NotifyBase):
|
|||
auth = '{user}{webhook}@'.format(
|
||||
user='{}:'.format(NotifyRocketChat.quote(self.user, safe=''))
|
||||
if self.user else '',
|
||||
webhook=self.pprint(self.webhook, privacy, safe=''),
|
||||
webhook=self.pprint(self.webhook, privacy,
|
||||
mode=PrivacyMode.Secret, safe=''),
|
||||
)
|
||||
|
||||
default_port = 443 if self.secure else 80
|
||||
|
@ -333,7 +337,7 @@ class NotifyRocketChat(NotifyBase):
|
|||
port='' if self.port is None or self.port == default_port
|
||||
else ':{}'.format(self.port),
|
||||
targets='/'.join(
|
||||
[NotifyRocketChat.quote(x, safe='') for x in chain(
|
||||
[NotifyRocketChat.quote(x, safe='@#') for x in chain(
|
||||
# Channels are prefixed with a pound/hashtag symbol
|
||||
['#{}'.format(x) for x in self.channels],
|
||||
# Rooms are as is
|
||||
|
@ -344,6 +348,13 @@ class NotifyRocketChat(NotifyBase):
|
|||
params=NotifyRocketChat.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.channels) + len(self.rooms) + len(self.users)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
|
||||
"""
|
||||
wrapper to _send since we can alert more then one channel
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# To use this plugin, you need to first generate a webhook.
|
||||
|
||||
|
@ -129,7 +136,7 @@ class NotifyRyver(NotifyBase):
|
|||
"""
|
||||
Initialize Ryver Object
|
||||
"""
|
||||
super(NotifyRyver, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# API Token (associated with project)
|
||||
self.token = validate_regex(
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2021 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# API Information:
|
||||
# - https://docs.aws.amazon.com/ses/latest/APIReference/API_SendRawEmail.html
|
||||
|
@ -217,7 +224,7 @@ class NotifySES(NotifyBase):
|
|||
"""
|
||||
Initialize Notify AWS SES Object
|
||||
"""
|
||||
super(NotifySES, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Store our AWS API Access Key
|
||||
self.aws_access_key_id = validate_regex(access_key_id)
|
||||
|
@ -809,6 +816,13 @@ class NotifySES(NotifyBase):
|
|||
params=NotifySES.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import requests
|
||||
|
@ -66,6 +73,22 @@ SMSEAGLE_PRIORITY_MAP = {
|
|||
}
|
||||
|
||||
|
||||
class SMSEagleCategory:
|
||||
"""
|
||||
We define the different category types that we can notify via SMS Eagle
|
||||
"""
|
||||
PHONE = 'phone'
|
||||
GROUP = 'group'
|
||||
CONTACT = 'contact'
|
||||
|
||||
|
||||
SMSEAGLE_CATEGORIES = (
|
||||
SMSEagleCategory.PHONE,
|
||||
SMSEagleCategory.GROUP,
|
||||
SMSEagleCategory.CONTACT,
|
||||
)
|
||||
|
||||
|
||||
class NotifySMSEagle(NotifyBase):
|
||||
"""
|
||||
A wrapper for SMSEagle Notifications
|
||||
|
@ -191,7 +214,7 @@ class NotifySMSEagle(NotifyBase):
|
|||
"""
|
||||
Initialize SMSEagle Object
|
||||
"""
|
||||
super(NotifySMSEagle, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Prepare Flash Mode Flag
|
||||
self.flash = flash
|
||||
|
@ -396,15 +419,15 @@ class NotifySMSEagle(NotifyBase):
|
|||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
|
||||
notify_by = {
|
||||
'phone': {
|
||||
SMSEagleCategory.PHONE: {
|
||||
"method": "sms.send_sms",
|
||||
'target': 'to',
|
||||
},
|
||||
'group': {
|
||||
SMSEagleCategory.GROUP: {
|
||||
"method": "sms.send_togroup",
|
||||
'target': 'groupname',
|
||||
},
|
||||
'contact': {
|
||||
SMSEagleCategory.CONTACT: {
|
||||
"method": "sms.send_tocontact",
|
||||
'target': 'contactname',
|
||||
},
|
||||
|
@ -413,7 +436,7 @@ class NotifySMSEagle(NotifyBase):
|
|||
# categories separated into a tuple since notify_by.keys()
|
||||
# returns an unpredicable list in Python 2.7 which causes
|
||||
# tests to fail every so often
|
||||
for category in ('phone', 'group', 'contact'):
|
||||
for category in SMSEAGLE_CATEGORIES:
|
||||
# Create a copy of our template
|
||||
payload = {
|
||||
'method': notify_by[category]['method'],
|
||||
|
@ -583,10 +606,34 @@ class NotifySMSEagle(NotifyBase):
|
|||
['@{}'.format(x) for x in self.target_contacts],
|
||||
# Groups
|
||||
['#{}'.format(x) for x in self.target_groups],
|
||||
# Pass along the same invalid entries as were provided
|
||||
self.invalid_targets,
|
||||
)]),
|
||||
params=NotifySMSEagle.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
if batch_size > 1:
|
||||
# Batches can only be sent by group (you can't combine groups into
|
||||
# a single batch)
|
||||
total_targets = 0
|
||||
for c in SMSEAGLE_CATEGORIES:
|
||||
targets = len(getattr(self, f'target_{c}s'))
|
||||
total_targets += int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
return total_targets
|
||||
|
||||
# Normal batch count; just count the targets
|
||||
return len(self.target_phones) + len(self.target_contacts) + \
|
||||
len(self.target_groups)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -633,6 +680,7 @@ class NotifySMSEagle(NotifyBase):
|
|||
results['status'] = \
|
||||
parse_bool(results['qsd'].get('status', False))
|
||||
|
||||
# Get priority
|
||||
if 'priority' in results['qsd'] and len(results['qsd']['priority']):
|
||||
results['priority'] = \
|
||||
NotifySMSEagle.unquote(results['qsd']['priority'])
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2021 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Signup @ https://smtp2go.com (free accounts available)
|
||||
#
|
||||
|
@ -159,7 +166,7 @@ class NotifySMTP2Go(NotifyBase):
|
|||
"""
|
||||
Initialize SMTP2Go Object
|
||||
"""
|
||||
super(NotifySMTP2Go, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# API Key (associated with project)
|
||||
self.apikey = validate_regex(apikey)
|
||||
|
@ -506,6 +513,21 @@ class NotifySMTP2Go(NotifyBase):
|
|||
safe='') for e in self.targets]),
|
||||
params=NotifySMTP2Go.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import hmac
|
||||
|
@ -159,7 +166,7 @@ class NotifySNS(NotifyBase):
|
|||
"""
|
||||
Initialize Notify AWS SNS Object
|
||||
"""
|
||||
super(NotifySNS, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Store our AWS API Access Key
|
||||
self.aws_access_key_id = validate_regex(access_key_id)
|
||||
|
@ -593,6 +600,12 @@ class NotifySNS(NotifyBase):
|
|||
params=NotifySNS.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.phone) + len(self.topics)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#
|
||||
# You will need an API Key for this plugin to work.
|
||||
# From the Settings -> API Keys you can click "Create API Key" if you don't
|
||||
|
@ -159,7 +167,7 @@ class NotifySendGrid(NotifyBase):
|
|||
"""
|
||||
Initialize Notify SendGrid Object
|
||||
"""
|
||||
super(NotifySendGrid, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# API Key (associated with project)
|
||||
self.apikey = validate_regex(
|
||||
|
@ -279,6 +287,12 @@ class NotifySendGrid(NotifyBase):
|
|||
params=NotifySendGrid.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
|
||||
"""
|
||||
Perform SendGrid Notification
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2020 Chris Caron <xuzheliang135@qq.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import requests
|
||||
|
@ -79,7 +86,7 @@ class NotifyServerChan(NotifyBase):
|
|||
"""
|
||||
Initialize ServerChan Object
|
||||
"""
|
||||
super(NotifyServerChan, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Token (associated with project)
|
||||
self.token = validate_regex(
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2022 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import re
|
||||
import requests
|
||||
|
@ -157,7 +164,7 @@ class NotifySignalAPI(NotifyBase):
|
|||
"""
|
||||
Initialize SignalAPI Object
|
||||
"""
|
||||
super(NotifySignalAPI, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Prepare Batch Mode Flag
|
||||
self.batch = batch
|
||||
|
@ -424,6 +431,21 @@ class NotifySignalAPI(NotifyBase):
|
|||
params=NotifySignalAPI.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
|
||||
return targets
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from os import urandom
|
||||
from json import loads
|
||||
import requests
|
||||
|
@ -125,7 +133,7 @@ class NotifySimplePush(NotifyBase):
|
|||
"""
|
||||
Initialize SimplePush Object
|
||||
"""
|
||||
super(NotifySimplePush, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# API Key (associated with project)
|
||||
self.apikey = validate_regex(apikey)
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# BSD 3-Clause License
|
||||
#
|
||||
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
|
||||
# All rights reserved.
|
||||
# Apprise - Push Notification Library.
|
||||
# Copyright (c) 2023, Chris Caron <lead2gold@gmail.com>
|
||||
#
|
||||
# This code is licensed under the MIT License.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 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 :
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 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.
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# To use this service you will need a Sinch account to which you can get your
|
||||
# API_TOKEN and SERVICE_PLAN_ID right from your console/dashboard at:
|
||||
|
@ -169,7 +176,7 @@ class NotifySinch(NotifyBase):
|
|||
"""
|
||||
Initialize Sinch Object
|
||||
"""
|
||||
super(NotifySinch, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# The Account SID associated with the account
|
||||
self.service_plan_id = validate_regex(
|
||||
|
@ -401,6 +408,13 @@ class NotifySinch(NotifyBase):
|
|||
[NotifySinch.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifySinch.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue