Esempio n. 1
0
    def _setup(self):
        self.apobj = apprise.Apprise()
        self.tags = {}
        # first load configfile if specified
        tags = self.settings.get("tags", "")
        configfile = self.settings.get("configfile", "")
        self.log.debug("%s - %s" % (tags, configfile))
        if tags and configfile:
            if configfile[:1] != "/":
                configfile = "/opt/mycroft/skills/apprise-skill/" + configfile
            self.log.debug("configfile - %s" % configfile)
            if os.path.isfile(configfile):
                config = apprise.AppriseConfig()
                config.add(configfile)
                self.apobj.add(config)
                taglist = tags.split(",")
                self.log.debug("taglist: %s" % taglist)
                for t in taglist:
                    self.tags[t.strip().lower()] = t.strip()
            else:
                self.log.warn("config file does not exist: %s" % configfile)
        # second load tags and service-urls from settings
        for i in range(1, 4):
            tag = self.settings.get("tag{}".format(i), "")
            service = self.settings.get("service{}".format(i), "")
            if tag and service:
                self.tags[tag.lower()] = tag
                self.apobj.add(service, tag=tag)

        self.log.debug("tags - %s" % self.tags)
Esempio n. 2
0
def get_service(hass, config, discovery_info=None):
    """Get the Apprise notification service."""

    # Create our Apprise Asset Object
    asset = apprise.AppriseAsset(async_mode=False)

    # Create our Apprise Instance (reference our asset)
    a_obj = apprise.Apprise(asset=asset)

    if config.get(CONF_FILE):
        # Sourced from a Configuration File
        a_config = apprise.AppriseConfig()
        if not a_config.add(config[CONF_FILE]):
            _LOGGER.error("Invalid Apprise config url provided")
            return None

        if not a_obj.add(a_config):
            _LOGGER.error("Invalid Apprise config url provided")
            return None

    if config.get(CONF_URL):
        # Ordered list of URLs
        if not a_obj.add(config[CONF_URL]):
            _LOGGER.error("Invalid Apprise URL(s) supplied")
            return None

    return AppriseNotificationService(a_obj)
    def __init__(self):
        if not os.path.exists(APPRISE_CONFIG_PATH):
            raise RuntimeError("No Apprise config found.")

        config = apprise.AppriseConfig()
        config.add(APPRISE_CONFIG_PATH)
        self.apobj = apprise.Apprise()
        self.apobj.add(config)

        self.queue = queue.Queue()
Esempio n. 4
0
 def __init__(self, enabled=True):
     if enabled and path.exists(APPRISE_CONFIG_PATH):
         self.apobj = apprise.Apprise()
         config = apprise.AppriseConfig()
         config.add(APPRISE_CONFIG_PATH)
         self.apobj.add(config)
         self.queue = queue.Queue()
         self.start_worker()
         self.enabled = True
     else:
         self.enabled = False
Esempio n. 5
0
 def __init__(self):
     if path.exists(APPRISE_CONFIG_PATH):
         log.info(f"Initializing Apprise handler using: {APPRISE_CONFIG_PATH}")
         self.apb = apprise.Apprise()
         config = apprise.AppriseConfig()
         config.add(APPRISE_CONFIG_PATH)
         # Get the service names from the config, not the Apprise instance when reading from config file
         for server in config.servers():
             log.info(f"Found {server.service_name} configuration")
             self.enabled_handlers.append(server.service_name)
         self.apb.add(config)
         self.queue = queue.Queue()
         self.start_worker()
         self.enabled = True
     else:
         self.enabled = False
         log.info(f"No Apprise config found at {APPRISE_CONFIG_PATH}.")
         log.info(f"For notifications, see {APPRISE_CONFIG_PATH}_template")
Esempio n. 6
0
    def send(self, event, msg, key):
        if not check_module("apprise"):
            self.log_error(
                self._("Cannot send notification: apprise is not installed."),
                self.
                _("Install apprise by issuing 'pip install apprise' command."),
            )
            return

        import apprise

        apprise_obj = apprise.Apprise()
        apprise_config = apprise.AppriseConfig()

        for c in key:
            apprise_config.add(c)

        apprise_obj.add(apprise_config)

        apprise_obj.notify(
            title=self.config.get("title"),
            body="%s: %s" % (event, msg) if msg else event,
        )
Esempio n. 7
0
    def post(self, request, key):
        """
        Handle a POST request
        """
        # our content
        content = {}
        if MIME_IS_FORM.match(request.content_type):
            content = {}
            form = NotifyForm(request.POST)
            if form.is_valid():
                content.update(form.cleaned_data)

        elif MIME_IS_JSON.match(request.content_type):
            # Prepare our default response
            try:
                # load our JSON content
                content = json.loads(request.body.decode('utf-8'))

            except (AttributeError, ValueError):
                # could not parse JSON response...
                return HttpResponse(_('Invalid JSON specified.'),
                                    status=ResponseCode.bad_request)

        if not content:
            # We could not handle the Content-Type
            return HttpResponse(_('The message format is not supported.'),
                                status=ResponseCode.bad_request)

        # Some basic error checking
        if not content.get('body') or \
                content.get('type', apprise.NotifyType.INFO) \
                not in apprise.NOTIFY_TYPES:

            return HttpResponse(_('An invalid payload was specified.'),
                                status=ResponseCode.bad_request)

        # If we get here, we have enough information to generate a notification
        # with.
        config, format = ConfigCache.get(key)
        if config is None:
            # The returned value of config and format tell a rather cryptic
            # story; this portion could probably be updated in the future.
            # but for now it reads like this:
            #   config == None and format == None: We had an internal error
            #   config == None and format != None: we simply have no data
            #   config != None: we simply have no data
            if format is not None:
                # no content to return
                return HttpResponse(
                    _('There was no configuration found.'),
                    status=ResponseCode.no_content,
                )

            # Something went very wrong; return 500
            return HttpResponse(
                _('An error occured accessing configuration.'),
                status=ResponseCode.internal_server_error,
            )

        # Prepare our apprise object
        a_obj = apprise.Apprise()

        # Create an apprise config object
        ac_obj = apprise.AppriseConfig()

        # Load our configuration
        ac_obj.add_config(config, format=format)

        # Add our configuration
        a_obj.add(ac_obj)

        # Perform our notification at this point
        result = a_obj.notify(
            content.get('body'),
            title=content.get('title', ''),
            notify_type=content.get('type', apprise.NotifyType.INFO),
            tag=content.get('tag'),
        )

        if not result:
            # If at least one notification couldn't be sent; change up
            # the response to a 424 error code
            return HttpResponse(
                _('One or more notification could not be sent.'),
                status=ResponseCode.failed_dependency)

        # Return our retrieved content
        return HttpResponse(_('Notification(s) sent.'),
                            status=ResponseCode.okay)
Esempio n. 8
0
    def post(self, request, key):
        """
        Handle a POST request
        """
        # our content
        content = {}
        if MIME_IS_FORM.match(request.content_type):
            content = {}
            form = AddByConfigForm(request.POST)
            if form.is_valid():
                content.update(form.cleaned_data)

            form = AddByUrlForm(request.POST)
            if form.is_valid():
                content.update(form.cleaned_data)

        elif MIME_IS_JSON.match(request.content_type):
            # Prepare our default response
            try:
                # load our JSON content
                content = json.loads(request.body.decode('utf-8'))

            except (AttributeError, ValueError):
                # could not parse JSON response...
                return HttpResponse(_('Invalid JSON specified.'),
                                    status=ResponseCode.bad_request)

        if not content:
            return HttpResponse(_('The message format is not supported.'),
                                status=ResponseCode.bad_request)

        # Create ourselves an apprise object to work with
        a_obj = apprise.Apprise()
        if 'urls' in content:
            # Load our content
            a_obj.add(content['urls'])
            if not len(a_obj):
                # No URLs were loaded
                return HttpResponse(
                    _('No valid URLs were found.'),
                    status=ResponseCode.bad_request,
                )

            if not ConfigCache.put(key, '\r\n'.join([s.url() for s in a_obj]),
                                   apprise.ConfigFormat.TEXT):

                return HttpResponse(
                    _('The configuration could not be saved.'),
                    status=ResponseCode.internal_server_error,
                )

        elif 'config' in content:
            fmt = content.get('format', '').lower()
            if fmt not in [i[0] for i in CONFIG_FORMATS]:
                # Format must be one supported by apprise
                return HttpResponse(
                    _('The format specified is invalid.'),
                    status=ResponseCode.bad_request,
                )

            # prepare our apprise config object
            ac_obj = apprise.AppriseConfig()

            if fmt == AUTO_DETECT_CONFIG_KEYWORD:
                # By setting format to None, it is automatically detected from
                # within the add_config() call
                fmt = None

            # Load our configuration
            if not ac_obj.add_config(content['config'], format=fmt):
                # The format could not be detected
                return HttpResponse(
                    _('The configuration format could not be detected.'),
                    status=ResponseCode.bad_request,
                )

            # Add our configuration
            a_obj.add(ac_obj)

            if not len(a_obj):
                # No specified URL(s) were loaded due to
                # mis-configuration on the caller's part
                return HttpResponse(
                    _('No valid URL(s) were specified.'),
                    status=ResponseCode.bad_request,
                )

            if not ConfigCache.put(
                    key, content['config'], fmt=ac_obj[0].config_format):
                # Something went very wrong; return 500
                return HttpResponse(
                    _('An error occured saving configuration.'),
                    status=ResponseCode.internal_server_error,
                )
        else:
            # No configuration specified; we're done
            return HttpResponse(
                _('No configuration specified.'),
                status=ResponseCode.bad_request,
            )

        # If we reach here; we successfully loaded the configuration so we can
        # go ahead and write it to disk and alert our caller of the success.
        return HttpResponse(
            _('Successfully saved configuration.'),
            status=ResponseCode.okay,
        )
Esempio n. 9
0
import time
import os.path
import automationhat
import apprise

alarm_sounding = False

script_dir = os.path.dirname(os.path.abspath(__file__))

# Configure notifications. You can use many different services.
apobj = apprise.Apprise()
config = apprise.AppriseConfig()
config.add(script_dir + '/.apprise')
apobj.add(config)

print("Arming in 10 seconds")
time.sleep(10)
print("Armed!")

while True:

    # Check the current state of the PIR sensor
    motion_detected = automationhat.input.three.read()

    # If new motion detected sound the alarm
    if motion_detected and alarm_sounding != True:
        print("Motion detected, loud noise time")
        #automationhat.relay.one.on()
        alarm_sounding = True

        apobj.notify(
Esempio n. 10
0
def test_plugin_join_config_files(mock_post):
    """
    NotifyJoin() Config File Cases
    """
    content = """
    urls:
      - join://%s@%s:
          - priority: -2
            tag: join_int low
          - priority: "-2"
            tag: join_str_int low
          - priority: low
            tag: join_str low

          # This will take on normal (default) priority
          - priority: invalid
            tag: join_invalid

      - join://%s@%s:
          - priority: 2
            tag: join_int emerg
          - priority: "2"
            tag: join_str_int emerg
          - priority: emergency
            tag: join_str emerg
    """ % ('a' * 32, 'b' * 32, 'c' * 32, 'd' * 32)

    # Disable Throttling to speed testing
    plugins.NotifyJoin.request_rate_per_sec = 0

    # Prepare Mock
    mock_post.return_value = requests.Request()
    mock_post.return_value.status_code = requests.codes.ok

    # Create ourselves a config object
    ac = apprise.AppriseConfig()
    assert ac.add_config(content=content) is True

    aobj = apprise.Apprise()

    # Add our configuration
    aobj.add(ac)

    # We should be able to read our 7 servers from that
    # 3x low
    # 3x emerg
    # 1x invalid (so takes on normal priority)
    assert len(ac.servers()) == 7
    assert len(aobj) == 7
    assert len([x for x in aobj.find(tag='low')]) == 3
    for s in aobj.find(tag='low'):
        assert s.priority == JoinPriority.LOW

    assert len([x for x in aobj.find(tag='emerg')]) == 3
    for s in aobj.find(tag='emerg'):
        assert s.priority == JoinPriority.EMERGENCY

    assert len([x for x in aobj.find(tag='join_str')]) == 2
    assert len([x for x in aobj.find(tag='join_str_int')]) == 2
    assert len([x for x in aobj.find(tag='join_int')]) == 2

    assert len([x for x in aobj.find(tag='join_invalid')]) == 1
    assert next(aobj.find(tag='join_invalid')).priority == \
        JoinPriority.NORMAL

    # Notifications work
    assert aobj.notify(title="title", body="body") is True
Esempio n. 11
0
    def post(self, request, key):
        """
        Handle a POST request
        """
        # our content
        content = {}
        if MIME_IS_FORM.match(request.content_type):
            content = {}
            form = NotifyForm(request.POST)
            if form.is_valid():
                content.update(form.cleaned_data)

        elif MIME_IS_JSON.match(request.content_type):
            # Prepare our default response
            try:
                # load our JSON content
                content = json.loads(request.body.decode('utf-8'))

            except (AttributeError, ValueError):
                # could not parse JSON response...
                return HttpResponse(_('Invalid JSON specified.'),
                                    status=ResponseCode.bad_request)

        if not content:
            # We could not handle the Content-Type
            return HttpResponse(_('The message format is not supported.'),
                                status=ResponseCode.bad_request)

        # Some basic error checking
        if not content.get('body') or \
                content.get('type', apprise.NotifyType.INFO) \
                not in apprise.NOTIFY_TYPES:

            return HttpResponse(_('An invalid payload was specified.'),
                                status=ResponseCode.bad_request)

        # If we get here, we have enough information to generate a notification
        # with.
        config, format = ConfigCache.get(key)
        if config is None:
            # The returned value of config and format tell a rather cryptic
            # story; this portion could probably be updated in the future.
            # but for now it reads like this:
            #   config == None and format == None: We had an internal error
            #   config == None and format != None: we simply have no data
            #   config != None: we simply have no data
            if format is not None:
                # no content to return
                return HttpResponse(
                    _('There was no configuration found.'),
                    status=ResponseCode.no_content,
                )

            # Something went very wrong; return 500
            return HttpResponse(
                _('An error occured accessing configuration.'),
                status=ResponseCode.internal_server_error,
            )

        # Prepare our apprise object
        a_obj = apprise.Apprise()

        # Create an apprise config object
        ac_obj = apprise.AppriseConfig()

        try:
            # Write our file to a temporary file containing our configuration
            # so that we can read it back.  In the future a change will be to
            # Apprise so that we can just directly write the configuration as
            # is to the AppriseConfig() object... but for now...
            with tempfile.NamedTemporaryFile() as f:
                # Write our content to disk
                f.write(config.encode())
                f.flush()

                # Read our configuration back in to our configuration
                ac_obj.add('file://{}?format={}'.format(f.name, format))

                # Add our configuration
                a_obj.add(ac_obj)

                # Perform our notification at this point
                a_obj.notify(
                    content.get('body'),
                    title=content.get('title', ''),
                    notify_type=content.get('type', apprise.NotifyType.INFO),
                    tag=content.get('tag'),
                )

        except OSError:
            # We could not write the temporary file to disk
            return HttpResponse(_('The configuration could not be loaded.'),
                                status=ResponseCode.internal_server_error)

        # Return our retrieved content
        return HttpResponse(_('Notification(s) sent.'),
                            status=ResponseCode.okay)
Esempio n. 12
0
    def post(self, request, key):
        """
        Handle a POST request
        """
        # our content
        content = {}
        if MIME_IS_FORM.match(request.content_type):
            content = {}
            form = AddByConfigForm(request.POST)
            if form.is_valid():
                content.update(form.cleaned_data)

            form = AddByUrlForm(request.POST)
            if form.is_valid():
                content.update(form.cleaned_data)

        elif MIME_IS_JSON.match(request.content_type):
            # Prepare our default response
            try:
                # load our JSON content
                content = json.loads(request.body.decode('utf-8'))

            except (AttributeError, ValueError):
                # could not parse JSON response...
                return HttpResponse(_('Invalid JSON specified.'),
                                    status=ResponseCode.bad_request)

        if not content:
            return HttpResponse(_('The message format is not supported.'),
                                status=ResponseCode.bad_request)

        # Create ourselves an apprise object to work with
        a_obj = apprise.Apprise()
        if 'urls' in content:
            # Load our content
            a_obj.add(content['urls'])
            if not len(a_obj):
                # No URLs were loaded
                return HttpResponse(
                    _('No valid URLs were found.'),
                    status=ResponseCode.bad_request,
                )

            if not ConfigCache.put(key, '\r\n'.join([s.url() for s in a_obj]),
                                   apprise.ConfigFormat.TEXT):

                return HttpResponse(
                    _('The configuration could not be saved.'),
                    status=ResponseCode.internal_server_error,
                )

        elif 'config' in content:
            fmt = content.get('format', '').lower()
            if fmt not in apprise.CONFIG_FORMATS:
                # Format must be one supported by apprise
                return HttpResponse(
                    _('The format specified is invalid.'),
                    status=ResponseCode.bad_request,
                )

            # prepare our apprise config object
            ac_obj = apprise.AppriseConfig()

            try:
                # Write our file to a temporary file
                with tempfile.NamedTemporaryFile() as f:
                    # Write our content to disk
                    f.write(content['config'].encode())
                    f.flush()

                    if not ac_obj.add('file://{}?format={}'.format(
                            f.name, fmt)):

                        # Bad Configuration
                        return HttpResponse(
                            _('The configuration specified is invalid.'),
                            status=ResponseCode.bad_request,
                        )

                    # Add our configuration
                    a_obj.add(ac_obj)

                    if not len(a_obj):
                        # No specified URL(s) were loaded due to
                        # mis-configuration on the caller's part
                        return HttpResponse(
                            _('No valid URL(s) were specified.'),
                            status=ResponseCode.bad_request,
                        )

            except OSError:
                # We could not write the temporary file to disk
                return HttpResponse(
                    _('The configuration could not be loaded.'),
                    status=ResponseCode.internal_server_error,
                )

            if not ConfigCache.put(key, content['config'], fmt=fmt):
                # Something went very wrong; return 500
                return HttpResponse(
                    _('An error occured saving configuration.'),
                    status=ResponseCode.internal_server_error,
                )
        else:
            # No configuration specified; we're done
            return HttpResponse(
                _('No configuration specified.'),
                status=ResponseCode.bad_request,
            )

        # If we reach here; we successfully loaded the configuration so we can
        # go ahead and write it to disk and alert our caller of the success.
        return HttpResponse(
            _('Successfully saved configuration.'),
            status=ResponseCode.okay,
        )
Esempio n. 13
0
def test_plugin_ntfy_config_files(mock_post, mock_get):
    """
    NotifyNtfy() Config File Cases
    """
    content = """
    urls:
      - ntfy://localhost/topic1:
          - priority: 1
            tag: ntfy_int min
          - priority: "1"
            tag: ntfy_str_int min
          - priority: min
            tag: ntfy_str min

          # This will take on normal (default) priority
          - priority: invalid
            tag: ntfy_invalid

      - ntfy://localhost/topic2:
          - priority: 5
            tag: ntfy_int max
          - priority: "5"
            tag: ntfy_str_int max
          - priority: emergency
            tag: ntfy_str max
          - priority: max
            tag: ntfy_str max
    """

    # Disable Throttling to speed testing
    plugins.NotifyNtfy.request_rate_per_sec = 0

    # Prepare Mock
    mock_post.return_value = requests.Request()
    mock_post.return_value.status_code = requests.codes.ok
    mock_get.return_value = requests.Request()
    mock_get.return_value.status_code = requests.codes.ok

    # Create ourselves a config object
    ac = apprise.AppriseConfig()
    assert ac.add_config(content=content) is True

    aobj = apprise.Apprise()

    # Add our configuration
    aobj.add(ac)

    # We should be able to read our 8 servers from that
    # 3x min
    # 4x max
    # 1x invalid (so takes on normal priority)
    assert len(ac.servers()) == 8
    assert len(aobj) == 8
    assert len([x for x in aobj.find(tag='min')]) == 3
    for s in aobj.find(tag='min'):
        assert s.priority == NtfyPriority.MIN

    assert len([x for x in aobj.find(tag='max')]) == 4
    for s in aobj.find(tag='max'):
        assert s.priority == NtfyPriority.MAX

    assert len([x for x in aobj.find(tag='ntfy_str')]) == 3
    assert len([x for x in aobj.find(tag='ntfy_str_int')]) == 2
    assert len([x for x in aobj.find(tag='ntfy_int')]) == 2

    assert len([x for x in aobj.find(tag='ntfy_invalid')]) == 1
    assert next(aobj.find(tag='ntfy_invalid')).priority == \
        NtfyPriority.NORMAL
Esempio n. 14
0
def test_plugin_opsgenie_config_files(mock_post):
    """
    NotifyOpsgenie() Config File Cases
    """
    content = """
    urls:
      - opsgenie://apikey/user:
          - priority: 1
            tag: opsgenie_int low
          - priority: "1"
            tag: opsgenie_str_int low
          - priority: "p1"
            tag: opsgenie_pstr_int low
          - priority: low
            tag: opsgenie_str low

          # This will take on moderate (default) priority
          - priority: invalid
            tag: opsgenie_invalid

      - opsgenie://apikey2/user2:
          - priority: 5
            tag: opsgenie_int emerg
          - priority: "5"
            tag: opsgenie_str_int emerg
          - priority: "p5"
            tag: opsgenie_pstr_int emerg
          - priority: emergency
            tag: opsgenie_str emerg
    """

    # Disable Throttling to speed testing
    apprise.plugins.NotifyOpsgenie.request_rate_per_sec = 0

    # Prepare Mock
    mock_post.return_value = requests.Request()
    mock_post.return_value.status_code = requests.codes.ok

    # Create ourselves a config object
    ac = apprise.AppriseConfig()
    assert ac.add_config(content=content) is True

    aobj = apprise.Apprise()

    # Add our configuration
    aobj.add(ac)

    # We should be able to read our 9 servers from that
    # 4x low
    # 4x emerg
    # 1x invalid (so takes on normal priority)
    assert len(ac.servers()) == 9
    assert len(aobj) == 9
    assert len([x for x in aobj.find(tag='low')]) == 4
    for s in aobj.find(tag='low'):
        assert s.priority == OpsgeniePriority.LOW

    assert len([x for x in aobj.find(tag='emerg')]) == 4
    for s in aobj.find(tag='emerg'):
        assert s.priority == OpsgeniePriority.EMERGENCY

    assert len([x for x in aobj.find(tag='opsgenie_str')]) == 2
    assert len([x for x in aobj.find(tag='opsgenie_str_int')]) == 2
    assert len([x for x in aobj.find(tag='opsgenie_pstr_int')]) == 2
    assert len([x for x in aobj.find(tag='opsgenie_int')]) == 2

    assert len([x for x in aobj.find(tag='opsgenie_invalid')]) == 1
    assert next(aobj.find(tag='opsgenie_invalid')).priority == \
        OpsgeniePriority.NORMAL
Esempio n. 15
0
def test_plugin_dapnet_config_files(mock_post):
    """
    NotifyDapnet() Config File Cases
    """
    content = """
    urls:
      - dapnet://user:pass@DF1ABC:
          - priority: 0
            tag: dapnet_int normal
          - priority: "0"
            tag: dapnet_str_int normal
          - priority: normal
            tag: dapnet_str normal

          # This will take on normal (default) priority
          - priority: invalid
            tag: dapnet_invalid

      - dapnet://user1:pass2@DF1ABC:
          - priority: 1
            tag: dapnet_int emerg
          - priority: "1"
            tag: dapnet_str_int emerg
          - priority: emergency
            tag: dapnet_str emerg
    """

    # Disable Throttling to speed testing
    plugins.NotifyDapnet.request_rate_per_sec = 0

    # Prepare Mock
    mock_post.return_value = requests.Request()
    mock_post.return_value.status_code = requests.codes.created

    # Create ourselves a config object
    ac = apprise.AppriseConfig()
    assert ac.add_config(content=content) is True

    aobj = apprise.Apprise()

    # Add our configuration
    aobj.add(ac)

    # We should be able to read our 7 servers from that
    # 4x normal (invalid + 3 exclusivly specified to be so)
    # 3x emerg
    assert len(ac.servers()) == 7
    assert len(aobj) == 7
    assert len([x for x in aobj.find(tag='normal')]) == 3
    for s in aobj.find(tag='normal'):
        assert s.priority == DapnetPriority.NORMAL

    assert len([x for x in aobj.find(tag='emerg')]) == 3
    for s in aobj.find(tag='emerg'):
        assert s.priority == DapnetPriority.EMERGENCY

    assert len([x for x in aobj.find(tag='dapnet_str')]) == 2
    assert len([x for x in aobj.find(tag='dapnet_str_int')]) == 2
    assert len([x for x in aobj.find(tag='dapnet_int')]) == 2

    assert len([x for x in aobj.find(tag='dapnet_invalid')]) == 1
    assert next(aobj.find(tag='dapnet_invalid')).priority == \
        DapnetPriority.NORMAL

    # Notifications work
    assert aobj.notify(title="title", body="body") is True
Esempio n. 16
0
    def get(self, request, key):
        """
        Handle a POST request
        """

        # Now build our tag response that identifies all of the tags
        # and the URL's they're associated with
        #  {
        #    "tags": ["tag1', "tag2", "tag3"],
        #    "urls": [
        #       {
        #          "url": "windows://",
        #          "tags": [],
        #       },
        #       {
        #          "url": "mailto://*****:*****@gmail.com"
        #          "tags": ["tag1", "tag2", "tag3"]
        #       }
        #    ]
        #  }
        response = {
            'tags': set(),
            'urls': [],
        }

        # Privacy flag
        privacy = bool(request.GET.get('privacy', False))

        config, format = ConfigCache.get(key)
        if config is None:
            # The returned value of config and format tell a rather cryptic
            # story; this portion could probably be updated in the future.
            # but for now it reads like this:
            #   config == None and format == None: We had an internal error
            #   config == None and format != None: we simply have no data
            #   config != None: we simply have no data
            if format is not None:
                # no content to return
                return JsonResponse(
                    response,
                    encoder=JSONEncoder,
                    safe=False,
                    status=ResponseCode.no_content,
                )

            # Something went very wrong; return 500
            response['error'] = _('There was no configuration found.')
            return JsonResponse(
                response,
                encoder=JSONEncoder,
                safe=False,
                status=ResponseCode.internal_server_error,
            )

        # Prepare our apprise object
        a_obj = apprise.Apprise()

        # Create an apprise config object
        ac_obj = apprise.AppriseConfig()

        # Load our configuration
        ac_obj.add_config(config, format=format)

        # Add our configuration
        a_obj.add(ac_obj)

        for notification in a_obj:
            # Set Notification
            response['urls'].append({
                'url': notification.url(privacy=privacy),
                'tags': notification.tags,
            })

            # Store Tags
            response['tags'] |= notification.tags

        # Return our retrieved content
        return JsonResponse(response,
                            encoder=JSONEncoder,
                            safe=False,
                            status=ResponseCode.okay)
Esempio n. 17
0
    def get(self, request, key):
        """
        Handle a POST request
        """

        # Now build our tag response that identifies all of the tags
        # and the URL's they're associated with
        #  {
        #    "tags": ["tag1', "tag2", "tag3"],
        #    "urls": [
        #       {
        #          "url": "windows://",
        #          "tags": [],
        #       },
        #       {
        #          "url": "mailto://*****:*****@gmail.com"
        #          "tags": ["tag1", "tag2", "tag3"]
        #       }
        #    ]
        #  }
        response = {
            'tags': set(),
            'urls': [],
        }

        # Privacy flag
        privacy = bool(request.GET.get('privacy', False))

        config, format = ConfigCache.get(key)
        if config is None:
            # The returned value of config and format tell a rather cryptic
            # story; this portion could probably be updated in the future.
            # but for now it reads like this:
            #   config == None and format == None: We had an internal error
            #   config == None and format != None: we simply have no data
            #   config != None: we simply have no data
            if format is not None:
                # no content to return
                return JsonResponse(
                    response,
                    encoder=JSONEncoder,
                    safe=False,
                    status=ResponseCode.no_content,
                )

            # Something went very wrong; return 500
            response['error'] = _('There was no configuration found.')
            return JsonResponse(
                response,
                encoder=JSONEncoder,
                safe=False,
                status=ResponseCode.internal_server_error,
            )

        # Prepare our apprise object
        a_obj = apprise.Apprise()

        # Create an apprise config object
        ac_obj = apprise.AppriseConfig()

        try:
            # Write our file to a temporary file containing our configuration
            # so that we can read it back.  In the future a change will be to
            # Apprise so that we can just directly write the configuration as
            # is to the AppriseConfig() object... but for now...
            with tempfile.NamedTemporaryFile() as f:
                # Write our content to disk
                f.write(config.encode())
                f.flush()

                # Read our configuration back in to our configuration
                ac_obj.add('file://{}?format={}'.format(f.name, format))

                # Add our configuration
                a_obj.add(ac_obj)

                for notification in a_obj:
                    # Set Notification
                    response['urls'].append({
                        'url':
                        notification.url(privacy=privacy),
                        'tags':
                        notification.tags,
                    })

                    # Store Tags
                    response['tags'] |= notification.tags

        except OSError:
            # We could not write the temporary file to disk
            response['error'] = _('The configuration could not be loaded.'),
            return JsonResponse(
                response,
                encoder=JSONEncoder,
                safe=False,
                status=ResponseCode.internal_server_error,
            )

        # Return our retrieved content
        return JsonResponse(response,
                            encoder=JSONEncoder,
                            safe=False,
                            status=ResponseCode.okay)
Esempio n. 18
0
def test_plugin_gnome_general():
    """
    NotifyGnome() General Checks

    """

    # Our module base
    gi_name = 'gi'

    # First we do an import without the gi library available to ensure
    # we can handle cases when the library simply isn't available

    if gi_name in sys.modules:
        # Test cases where the gi library exists; we want to remove it
        # for the purpose of testing and capture the handling of the
        # library when it is missing
        del sys.modules[gi_name]
        reload(sys.modules['apprise.plugins.NotifyGnome'])

    # We need to fake our gnome environment for testing purposes since
    # the gi library isn't available in Travis CI
    gi = types.ModuleType(gi_name)
    gi.repository = types.ModuleType(gi_name + '.repository')
    gi.module = types.ModuleType(gi_name + '.module')

    mock_pixbuf = mock.Mock()
    mock_notify = mock.Mock()

    gi.repository.GdkPixbuf = \
        types.ModuleType(gi_name + '.repository.GdkPixbuf')
    gi.repository.GdkPixbuf.Pixbuf = mock_pixbuf
    gi.repository.Notify = mock.Mock()
    gi.repository.Notify.init.return_value = True
    gi.repository.Notify.Notification = mock_notify

    # Emulate require_version function:
    gi.require_version = mock.Mock(name=gi_name + '.require_version')

    # Force the fake module to exist
    sys.modules[gi_name] = gi
    sys.modules[gi_name + '.repository'] = gi.repository
    sys.modules[gi_name + '.repository.Notify'] = gi.repository.Notify

    # Notify Object
    notify_obj = mock.Mock()
    notify_obj.set_urgency.return_value = True
    notify_obj.set_icon_from_pixbuf.return_value = True
    notify_obj.set_image_from_pixbuf.return_value = True
    notify_obj.show.return_value = True
    mock_notify.new.return_value = notify_obj
    mock_pixbuf.new_from_file.return_value = True

    # The following libraries need to be reloaded to prevent
    #  TypeError: super(type, obj): obj must be an instance or subtype of type
    #  This is better explained in this StackOverflow post:
    #     https://stackoverflow.com/questions/31363311/\
    #       any-way-to-manually-fix-operation-of-\
    #          super-after-ipython-reload-avoiding-ty
    #
    reload(sys.modules['apprise.plugins.NotifyGnome'])
    reload(sys.modules['apprise.plugins'])
    reload(sys.modules['apprise.Apprise'])
    reload(sys.modules['apprise'])

    # Create our instance
    obj = apprise.Apprise.instantiate('gnome://', suppress_exceptions=False)
    assert obj is not None

    # Set our duration to 0 to speed up timeouts (for testing)
    obj.duration = 0

    # Check that it found our mocked environments
    assert obj.enabled is True

    # Test url() call
    assert isinstance(obj.url(), six.string_types) is True

    # test notifications
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    # test notification without a title
    assert obj.notify(
        title='', body='body', notify_type=apprise.NotifyType.INFO) is True

    obj = apprise.Apprise.instantiate('gnome://_/?image=True',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyGnome) is True
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    obj = apprise.Apprise.instantiate('gnome://_/?image=False',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyGnome) is True
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    # Test Priority (alias of urgency)
    obj = apprise.Apprise.instantiate('gnome://_/?priority=invalid',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyGnome) is True
    assert obj.urgency == 1
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    obj = apprise.Apprise.instantiate('gnome://_/?priority=high',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyGnome) is True
    assert obj.urgency == 2
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    obj = apprise.Apprise.instantiate('gnome://_/?priority=2',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyGnome) is True
    assert obj.urgency == 2
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    # Test Urgeny
    obj = apprise.Apprise.instantiate('gnome://_/?urgency=invalid',
                                      suppress_exceptions=False)
    assert obj.urgency == 1
    assert isinstance(obj, apprise.plugins.NotifyGnome) is True
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    obj = apprise.Apprise.instantiate('gnome://_/?urgency=high',
                                      suppress_exceptions=False)
    assert obj.urgency == 2
    assert isinstance(obj, apprise.plugins.NotifyGnome) is True
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    obj = apprise.Apprise.instantiate('gnome://_/?urgency=2',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyGnome) is True
    assert obj.urgency == 2
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    # Test configuration parsing
    content = """
    urls:
      - gnome://:
          - priority: 0
            tag: gnome_int low
          - priority: "0"
            tag: gnome_str_int low
          - priority: low
            tag: gnome_str low
          - urgency: 0
            tag: gnome_int low
          - urgency: "0"
            tag: gnome_str_int low
          - urgency: low
            tag: gnome_str low

          # These will take on normal (default) urgency
          - priority: invalid
            tag: gnome_invalid
          - urgency: invalid
            tag: gnome_invalid

      - gnome://:
          - priority: 2
            tag: gnome_int high
          - priority: "2"
            tag: gnome_str_int high
          - priority: high
            tag: gnome_str high
          - urgency: 2
            tag: gnome_int high
          - urgency: "2"
            tag: gnome_str_int high
          - urgency: high
            tag: gnome_str high
    """

    # Create ourselves a config object
    ac = apprise.AppriseConfig()
    assert ac.add_config(content=content) is True

    aobj = apprise.Apprise()

    # Add our configuration
    aobj.add(ac)

    # We should be able to read our 14 servers from that
    # 6x low
    # 6x high
    # 2x invalid (so takes on normal urgency)
    assert len(ac.servers()) == 14
    assert len(aobj) == 14
    assert len([x for x in aobj.find(tag='low')]) == 6
    for s in aobj.find(tag='low'):
        assert s.urgency == GnomeUrgency.LOW

    assert len([x for x in aobj.find(tag='high')]) == 6
    for s in aobj.find(tag='high'):
        assert s.urgency == GnomeUrgency.HIGH

    assert len([x for x in aobj.find(tag='gnome_str')]) == 4
    assert len([x for x in aobj.find(tag='gnome_str_int')]) == 4
    assert len([x for x in aobj.find(tag='gnome_int')]) == 4

    assert len([x for x in aobj.find(tag='gnome_invalid')]) == 2
    for s in aobj.find(tag='gnome_invalid'):
        assert s.urgency == GnomeUrgency.NORMAL

    # Test our loading of our icon exception; it will still allow the
    # notification to be sent
    mock_pixbuf.new_from_file.side_effect = AttributeError()
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True
    # Undo our change
    mock_pixbuf.new_from_file.side_effect = None

    # Test our exception handling during initialization
    sys.modules['gi.repository.Notify']\
        .Notification.new.return_value = None
    sys.modules['gi.repository.Notify']\
        .Notification.new.side_effect = AttributeError()
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is False

    # Undo our change
    sys.modules['gi.repository.Notify']\
        .Notification.new.side_effect = None

    # Toggle our testing for when we can't send notifications because the
    # package has been made unavailable to us
    obj.enabled = False
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is False

    # Test the setting of a the urgency (through priority keyword)
    apprise.plugins.NotifyGnome(priority=0)

    # Verify this all works in the event a ValueError is also thronw
    # out of the call to gi.require_version()

    # Emulate require_version function:
    gi.require_version.side_effect = ValueError()

    # The following libraries need to be reloaded to prevent
    #  TypeError: super(type, obj): obj must be an instance or subtype of type
    #  This is better explained in this StackOverflow post:
    #     https://stackoverflow.com/questions/31363311/\
    #       any-way-to-manually-fix-operation-of-\
    #          super-after-ipython-reload-avoiding-ty
    #
    reload(sys.modules['apprise.plugins.NotifyGnome'])
    reload(sys.modules['apprise.plugins'])
    reload(sys.modules['apprise.Apprise'])
    reload(sys.modules['apprise'])

    # We can now no longer load our instance
    # The object internally is marked disabled
    obj = apprise.Apprise.instantiate('gnome://', suppress_exceptions=False)
    assert obj is None
Esempio n. 19
0
def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
                             mock_interface, mock_sessionbus):
    """
    NotifyDBus() General Tests
    """

    # Our module base
    gi_name = 'gi'

    # First we do an import without the gi library available to ensure
    # we can handle cases when the library simply isn't available

    if gi_name in sys.modules:
        # Test cases where the gi library exists; we want to remove it
        # for the purpose of testing and capture the handling of the
        # library when it is missing
        del sys.modules[gi_name]
        reload(sys.modules['apprise.plugins.NotifyDBus'])

    # We need to fake our dbus environment for testing purposes since
    # the gi library isn't available in Travis CI
    gi = types.ModuleType(gi_name)
    gi.repository = types.ModuleType(gi_name + '.repository')

    mock_pixbuf = mock.Mock()
    mock_image = mock.Mock()
    mock_pixbuf.new_from_file.return_value = mock_image

    mock_image.get_width.return_value = 100
    mock_image.get_height.return_value = 100
    mock_image.get_rowstride.return_value = 1
    mock_image.get_has_alpha.return_value = 0
    mock_image.get_bits_per_sample.return_value = 8
    mock_image.get_n_channels.return_value = 1
    mock_image.get_pixels.return_value = ''

    gi.repository.GdkPixbuf = \
        types.ModuleType(gi_name + '.repository.GdkPixbuf')
    gi.repository.GdkPixbuf.Pixbuf = mock_pixbuf

    # Emulate require_version function:
    gi.require_version = mock.Mock(name=gi_name + '.require_version')

    # Force the fake module to exist
    sys.modules[gi_name] = gi
    sys.modules[gi_name + '.repository'] = gi.repository

    # Exception Handling
    mock_mainloop.qt.DBusQtMainLoop.return_value = True
    mock_mainloop.qt.DBusQtMainLoop.side_effect = ImportError
    sys.modules['dbus.mainloop.qt'] = mock_mainloop.qt
    reload(sys.modules['apprise.plugins.NotifyDBus'])
    mock_mainloop.qt.DBusQtMainLoop.side_effect = None

    # Python v2.x
    mock_mainloop.glib.DBusGMainLoop.return_value = True
    mock_mainloop.glib.DBusGMainLoop.side_effect = ImportError()
    # Python 3.x
    mock_mainloop.glib.NativeMainLoop.return_value = True
    mock_mainloop.glib.NativeMainLoop.side_effect = ImportError()
    sys.modules['dbus.mainloop.glib'] = mock_mainloop.glib
    reload(sys.modules['apprise.plugins.NotifyDBus'])
    mock_mainloop.glib.DBusGMainLoop.side_effect = None
    mock_mainloop.glib.NativeMainLoop.side_effect = None

    # The following libraries need to be reloaded to prevent
    #  TypeError: super(type, obj): obj must be an instance or subtype of type
    #  This is better explained in this StackOverflow post:
    #     https://stackoverflow.com/questions/31363311/\
    #       any-way-to-manually-fix-operation-of-\
    #          super-after-ipython-reload-avoiding-ty
    #
    reload(sys.modules['apprise.plugins.NotifyDBus'])
    reload(sys.modules['apprise.plugins'])
    reload(sys.modules['apprise.Apprise'])
    reload(sys.modules['apprise'])

    # Create our instance (identify all supported types)
    obj = apprise.Apprise.instantiate('dbus://', suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.url().startswith('dbus://_/')
    obj = apprise.Apprise.instantiate('kde://', suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.url().startswith('kde://_/')
    obj = apprise.Apprise.instantiate('qt://', suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.url().startswith('qt://_/')
    obj = apprise.Apprise.instantiate('glib://', suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.url().startswith('glib://_/')
    obj.duration = 0

    # Test our class loading using a series of arguments
    with pytest.raises(TypeError):
        apprise.plugins.NotifyDBus(**{'schema': 'invalid'})

    # Set our X and Y coordinate and try the notification
    assert apprise.plugins.NotifyDBus(
        x_axis=0, y_axis=0, **{'schema': 'dbus'})\
        .notify(title='', body='body',
                notify_type=apprise.NotifyType.INFO) is True

    # test notifications
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    # test notification without a title
    assert obj.notify(
        title='', body='body', notify_type=apprise.NotifyType.INFO) is True

    # Test our arguments through the instantiate call
    obj = apprise.Apprise.instantiate('dbus://_/?image=True',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.url().startswith('dbus://_/')
    assert re.search('image=yes', obj.url())

    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    obj = apprise.Apprise.instantiate('dbus://_/?image=False',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.url().startswith('dbus://_/')
    assert re.search('image=no', obj.url())

    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    # Test priority (alias to urgency) handling
    obj = apprise.Apprise.instantiate('dbus://_/?priority=invalid',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    obj = apprise.Apprise.instantiate('dbus://_/?priority=high',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    obj = apprise.Apprise.instantiate('dbus://_/?priority=2',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    # Test urgency handling
    obj = apprise.Apprise.instantiate('dbus://_/?urgency=invalid',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    obj = apprise.Apprise.instantiate('dbus://_/?urgency=high',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    obj = apprise.Apprise.instantiate('dbus://_/?urgency=2',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    obj = apprise.Apprise.instantiate('dbus://_/?urgency=',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    # Test x/y
    obj = apprise.Apprise.instantiate('dbus://_/?x=5&y=5',
                                      suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    assert isinstance(obj.url(), six.string_types) is True
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    with pytest.raises(TypeError):
        obj = apprise.Apprise.instantiate('dbus://_/?x=invalid&y=invalid',
                                          suppress_exceptions=False)

    # Test configuration parsing
    content = """
    urls:
      - dbus://:
          - priority: 0
            tag: dbus_int low
          - priority: "0"
            tag: dbus_str_int low
          - priority: low
            tag: dbus_str low
          - urgency: 0
            tag: dbus_int low
          - urgency: "0"
            tag: dbus_str_int low
          - urgency: low
            tag: dbus_str low

          # These will take on normal (default) urgency
          - priority: invalid
            tag: dbus_invalid
          - urgency: invalid
            tag: dbus_invalid

      - dbus://:
          - priority: 2
            tag: dbus_int high
          - priority: "2"
            tag: dbus_str_int high
          - priority: high
            tag: dbus_str high
          - urgency: 2
            tag: dbus_int high
          - urgency: "2"
            tag: dbus_str_int high
          - urgency: high
            tag: dbus_str high
    """

    # Create ourselves a config object
    ac = apprise.AppriseConfig()
    assert ac.add_config(content=content) is True

    aobj = apprise.Apprise()

    # Add our configuration
    aobj.add(ac)

    # We should be able to read our 14 servers from that
    # 6x low
    # 6x high
    # 2x invalid (so takes on normal urgency)
    assert len(ac.servers()) == 14
    assert len(aobj) == 14
    assert len([x for x in aobj.find(tag='low')]) == 6
    for s in aobj.find(tag='low'):
        assert s.urgency == DBusUrgency.LOW

    assert len([x for x in aobj.find(tag='high')]) == 6
    for s in aobj.find(tag='high'):
        assert s.urgency == DBusUrgency.HIGH

    assert len([x for x in aobj.find(tag='dbus_str')]) == 4
    assert len([x for x in aobj.find(tag='dbus_str_int')]) == 4
    assert len([x for x in aobj.find(tag='dbus_int')]) == 4

    assert len([x for x in aobj.find(tag='dbus_invalid')]) == 2
    for s in aobj.find(tag='dbus_invalid'):
        assert s.urgency == DBusUrgency.NORMAL

    # If our underlining object throws for whatever rea on, we will
    # gracefully fail
    mock_notify = mock.Mock()
    mock_interface.return_value = mock_notify
    mock_notify.Notify.side_effect = AttributeError()
    assert obj.notify(
        title='', body='body', notify_type=apprise.NotifyType.INFO) is False
    mock_notify.Notify.side_effect = None

    # Test our loading of our icon exception; it will still allow the
    # notification to be sent
    mock_pixbuf.new_from_file.side_effect = AttributeError()
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True
    # Undo our change
    mock_pixbuf.new_from_file.side_effect = None

    # Test our exception handling during initialization
    # Toggle our testing for when we can't send notifications because the
    # package has been made unavailable to us
    obj.enabled = False
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is False

    # Test the setting of a the urgency
    apprise.plugins.NotifyDBus(urgency=0)

    #
    # We can still notify if the gi library is the only inaccessible
    # compontent
    #

    # Emulate require_version function:
    gi.require_version.side_effect = ImportError()

    # The following libraries need to be reloaded to prevent
    #  TypeError: super(type, obj): obj must be an instance or subtype of type
    #  This is better explained in this StackOverflow post:
    #     https://stackoverflow.com/questions/31363311/\
    #       any-way-to-manually-fix-operation-of-\
    #          super-after-ipython-reload-avoiding-ty
    #
    reload(sys.modules['apprise.plugins.NotifyDBus'])
    reload(sys.modules['apprise.plugins'])
    reload(sys.modules['apprise.Apprise'])
    reload(sys.modules['apprise'])

    # Create our instance
    obj = apprise.Apprise.instantiate('glib://', suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    obj.duration = 0

    # Test url() call
    assert isinstance(obj.url(), six.string_types) is True

    # Our notification succeeds even though the gi library was not loaded
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    # Verify this all works in the event a ValueError is also thronw
    # out of the call to gi.require_version()

    mock_sessionbus.side_effect = DBusException('test')
    # Handle Dbus Session Initialization error
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is False

    # Return side effect to normal
    mock_sessionbus.side_effect = None

    # Emulate require_version function:
    gi.require_version.side_effect = ValueError()

    # The following libraries need to be reloaded to prevent
    #  TypeError: super(type, obj): obj must be an instance or subtype of type
    #  This is better explained in this StackOverflow post:
    #     https://stackoverflow.com/questions/31363311/\
    #       any-way-to-manually-fix-operation-of-\
    #          super-after-ipython-reload-avoiding-ty
    #
    reload(sys.modules['apprise.plugins.NotifyDBus'])
    reload(sys.modules['apprise.plugins'])
    reload(sys.modules['apprise.Apprise'])
    reload(sys.modules['apprise'])

    # Create our instance
    obj = apprise.Apprise.instantiate('glib://', suppress_exceptions=False)
    assert isinstance(obj, apprise.plugins.NotifyDBus) is True
    obj.duration = 0

    # Test url() call
    assert isinstance(obj.url(), six.string_types) is True

    # Our notification succeeds even though the gi library was not loaded
    assert obj.notify(title='title',
                      body='body',
                      notify_type=apprise.NotifyType.INFO) is True

    # Force a global import error
    _session_bus = sys.modules['dbus']
    sys.modules['dbus'] = compile('raise ImportError()', 'dbus', 'exec')

    # Reload our modules
    reload(sys.modules['apprise.plugins.NotifyDBus'])
    reload(sys.modules['apprise.plugins'])
    reload(sys.modules['apprise.Apprise'])
    reload(sys.modules['apprise'])

    # We can no longer instantiate an instance because dbus has been
    # officialy marked unavailable and thus the module is marked
    # as such
    obj = apprise.Apprise.instantiate('glib://', suppress_exceptions=False)
    assert obj is None

    # Since playing with the sys.modules is not such a good idea,
    # let's just put our old configuration back:
    sys.modules['dbus'] = _session_bus
    # Reload our modules
    reload(sys.modules['apprise.plugins.NotifyDBus'])
    reload(sys.modules['apprise.plugins'])
    reload(sys.modules['apprise.Apprise'])
    reload(sys.modules['apprise'])
Esempio n. 20
0
def test_plugin_growl_config_files(mock_gntp):
    """
    NotifyGrowl() Config File Cases
    """
    content = """
    urls:
      - growl://[email protected]:
          - priority: -2
            tag: growl_int low
          - priority: "-2"
            tag: growl_str_int low
          - priority: low
            tag: growl_str low

          # This will take on moderate (default) priority
          - priority: invalid
            tag: growl_invalid

      - growl://[email protected]:
          - priority: 2
            tag: growl_int emerg
          - priority: "2"
            tag: growl_str_int emerg
          - priority: emergency
            tag: growl_str emerg
    """

    # Disable Throttling to speed testing
    apprise.plugins.NotifyGrowl.request_rate_per_sec = 0

    mock_notifier = mock.Mock()
    mock_gntp.return_value = mock_notifier
    mock_notifier.notify.return_value = True

    # Create ourselves a config object
    ac = apprise.AppriseConfig()
    assert ac.add_config(content=content) is True

    aobj = apprise.Apprise()

    # Add our configuration
    aobj.add(ac)

    # We should be able to read our 7 servers from that
    # 3x low
    # 3x emerg
    # 1x invalid (so takes on normal priority)
    assert len(ac.servers()) == 7
    assert len(aobj) == 7
    assert len([x for x in aobj.find(tag='low')]) == 3
    for s in aobj.find(tag='low'):
        assert s.priority == GrowlPriority.LOW

    assert len([x for x in aobj.find(tag='emerg')]) == 3
    for s in aobj.find(tag='emerg'):
        assert s.priority == GrowlPriority.EMERGENCY

    assert len([x for x in aobj.find(tag='growl_str')]) == 2
    assert len([x for x in aobj.find(tag='growl_str_int')]) == 2
    assert len([x for x in aobj.find(tag='growl_int')]) == 2

    assert len([x for x in aobj.find(tag='growl_invalid')]) == 1
    assert next(aobj.find(tag='growl_invalid')).priority == \
        GrowlPriority.NORMAL