示例#1
0
 def __init__(self, w=OVERLAY_WIDTH, h=OVERLAY_HEIGHT, *args, **kwargs):
     self.window = xbmcgui.Window(WINDOW_FULLSCREEN_VIDEO)
     viewport_w, viewport_h = self._get_skin_resolution()
     # Adjust size based on viewport, we are using 1080p coordinates
     w = int(w * viewport_w / VIEWPORT_WIDTH)
     h = int(h * viewport_h / VIEWPORT_HEIGHT)
     x = (viewport_w - w) / 2
     y = (viewport_h - h) / 2 + int(
         ADDON.getSetting(id="overlay_status_offset"))
     self._shown = False
     self._text = ""
     self._label = xbmcgui.ControlLabel(x,
                                        y,
                                        w,
                                        h,
                                        self._text,
                                        alignment=XBFONT_CENTER_X
                                        | XBFONT_CENTER_Y,
                                        *args,
                                        **kwargs)
     self._shadow = xbmcgui.ControlLabel(x + 1,
                                         y + 1,
                                         w,
                                         h,
                                         self._text,
                                         textColor='0xD0000000',
                                         alignment=XBFONT_CENTER_X
                                         | XBFONT_CENTER_Y,
                                         *args,
                                         **kwargs)
     self._background = xbmcgui.ControlImage(
         x, y, w, h,
         os.path.join(ADDON_PATH, "resources", "img",
                      "black.png").encode('utf-8'))
     self._background.setColorDiffuse("0xD0000000")
示例#2
0
    def AddonFailure(self, addonId):
        if ADDON.getSetting("provider_disable_failing") == u"false":
            return 0

        if addonId in self._failures:
            self._failures[addonId] += 1
        else:
            self._failures[addonId] = 1

        log.warning("Recorded failure %d for %s" % (self._failures[addonId], addonId))

        if self._failures[addonId] > int(ADDON.getSetting("provider_allowed_failures")):
            try:
                time.sleep(10)
                notify(getLocalizedString(30111))
                urllib_request.urlopen("%s/provider/%s/disable" % (ELEMENTUMD_HOST, addonId))
            except:
                notify(getLocalizedString(30112))
                return 0
        return self._failures[addonId]
示例#3
0
 def GetAllSettings(self):
     settings = []
     settingsFile = os.path.join(ADDON_PATH, "resources", "settings.xml")
     with open(settingsFile, 'r') as settingsStr:
         fileContent = settingsStr.read()
         keyType = re.findall(r".*id=\"(\w+)\".*type=\"(\w+)\"(.*option=\"(\w+)\")?", fileContent)
     for key, _type, optgroup, option in keyType:
         settings.append({
             "key": key,
             "type": _type,
             "option": option,
             "value": ADDON.getSetting(key)
         })
     return settings
示例#4
0
def get_setting(key, converter=str, choices=None):
    value = ADDON.getSetting(id=key)
    if converter is six.text_type or converter is str:
        return py2_decode(value)
    elif converter is bool:
        return value == 'true'
    elif converter is int:
        return int(value)
    elif isinstance(choices, (list, tuple)):
        return choices[int(value)]
    else:
        raise TypeError('Acceptable converters are str, unicode, bool and '
                        'int. Acceptable choices are instances of list '
                        ' or tuple.')
示例#5
0
def _get_logger(name):
    global loggers

    if loggers.get(name):
        return loggers.get(name)
    else:
        logger = logging.getLogger(ADDON_ID)
        if ADDON.getSetting("logger_silent") == 'true':
            logger.setLevel(logging.ERROR)
        else:
            logger.setLevel(logging.DEBUG)

        handler = XBMCHandler()
        handler.setFormatter(logging.Formatter('[%(name)s] %(message)s'))
        logger.addHandler(handler)
        return logger
def _get_logger(name):
    global loggers

    if loggers.get(name):
        return loggers.get(name)
    else:
        logger = logging.getLogger(ADDON_ID)
        log_level = ADDON.getSetting("log_level")
        if log_level == 0:
            logger.setLevel(logging.CRITICAL)
        elif log_level == 1:
            logger.setLevel(logging.ERROR)
        elif log_level == 2:
            logger.setLevel(logging.INFO)
        else:
            logger.setLevel(logging.DEBUG)

        handler = XBMCHandler()
        handler.setFormatter(logging.Formatter('[%(name)s] %(message)s'))
        logger.addHandler(handler)
        return logger
示例#7
0
 def GetSetting(self, *args, **kwargs):
     return ADDON.getSetting(*args, **kwargs)
def get_platform():
    try:
        binary_platform = ADDON.getSetting("binary_platform")
    except:
        binary_platform = "auto"
        pass

    build = xbmc.getInfoLabel("System.BuildVersion")
    kodi_version = int(build.split()[0][:2])

    if binary_platform and "auto" not in binary_platform.lower():
        custom = binary_platform.split('_')
        if len(custom) > 1:
            return {
                "os": custom[0],
                "arch": custom[1],
                "fork": True,
                "version": "",
                "kodi": kodi_version,
                "build": build
            }

    ret = {
        "auto_arch": sys.maxsize > 2 ** 32 and "64-bit" or "32-bit",
        "arch": sys.maxsize > 2 ** 32 and "x64" or "x86",
        "os": "",
        "version": "",
        "kodi": kodi_version,
        "build": build,
        "fork": True,
        "machine": "",
        "system": "",
        "platform": ""
    }

    try:
        ret["os"] = platform.release()
    except:
        pass

    try:
        ret["machine"] = platform.machine()
    except:
        # Default 'machine' for Android can be 'arm'
        if xbmc.getCondVisibility("system.platform.android"):
            ret["machine"] = "arm"
        pass

    try:
        ret["system"] = platform.system()
    except:
        pass

    try:
        ret["platform"] = platform.platform()
    except:
        pass

    if xbmc.getCondVisibility("system.platform.android"):
        ret["os"] = "android"
        if "arm" in ret["machine"].lower() or "aarch" in ret["machine"].lower():
            ret["arch"] = "arm"
            if "64" in ret["machine"] and ret["auto_arch"] == "64-bit":
                ret["arch"] = "arm64"
    elif xbmc.getCondVisibility("system.platform.linux"):
        ret["os"] = "linux"

        if "aarch" in ret["machine"].lower() or "arm64" in ret["machine"].lower():
            if xbmc.getCondVisibility("system.platform.linux.raspberrypi"):
                ret["arch"] = "armv7"
            elif ret["auto_arch"] == "32-bit":
                ret["arch"] = "armv7"
            elif ret["auto_arch"] == "64-bit":
                ret["arch"] = "arm64"
            # elif platform.architecture()[0].startswith("32"):
            #     ret["arch"] = "armv6"
            else:
                ret["arch"] = "armv7"
        elif "armv7" in ret["machine"]:
            ret["arch"] = "armv7"
        elif "arm" in ret["machine"]:
            cpuarch = ""
            if "aarch" in ret["machine"].lower() or "arm" in ret["machine"].lower():
                info = cpuinfo()
                for proc in info.keys():
                    log.info("CPU: %s=%s" % (proc, info[proc]))
                    model = ""
                    if "model name" in info[proc]:
                        model = info[proc]["model name"].lower()
                    elif "Processor" in info[proc]:
                        model = info[proc]["Processor"].lower()

                    if model:
                        log.info("Exploring model: %s" % model)
                        if "aarch" in model or "arm64" in model or "v8l" in model:
                            cpuarch = "arm64"
                        elif "armv7" in model or "v7l" in model:
                            cpuarch = "armv7"
                        break

            if cpuarch:
                log.info("Using CPU info arch: %s" % cpuarch)
                ret["arch"] = cpuarch
            else:
                ret["arch"] = "armv6"
    elif xbmc.getCondVisibility("system.platform.xbox"):
        ret["os"] = "windows"
        ret["arch"] = "x64"
        ret["fork"] = False
    elif xbmc.getCondVisibility("system.platform.windows"):
        ret["os"] = "windows"
        if ret["machine"].endswith('64'):
            ret["arch"] = "x64"
    elif ret["system"] == "Darwin":
        ret["os"] = "darwin"
        ret["arch"] = "x64"

        if "AppleTV" in ret["platform"]:
            ret["os"] = "ios"
            ret["arch"] = "armv7"
            ret["fork"] = False
            if "64bit" in ret["platform"]:
                ret["arch"] = "arm64"
        elif xbmc.getCondVisibility("system.platform.ios"):
            ret["os"] = "ios"
            ret["arch"] = "armv7"
            ret["fork"] = False
            if "64bit" in ret["platform"]:
                ret["arch"] = "arm64"

    # elif xbmc.getCondVisibility("system.platform.osx"):
    #     ret["os"] = "darwin"
    #     ret["arch"] = "x64"
    # elif xbmc.getCondVisibility("system.platform.ios"):
    #     ret["os"] = "ios"
    #     ret["arch"] = "armv7"
    return ret
示例#9
0
def run(url_suffix=""):
    socket.setdefaulttimeout(int(ADDON.getSetting("buffer_timeout")))
    urllib2.install_opener(urllib2.build_opener(NoRedirectHandler()))

    # Pause currently playing Elementum file to avoid doubling requests
    if xbmc.Player().isPlaying() and ADDON_ID in xbmc.Player().getPlayingFile(
    ):
        xbmc.Player().pause()

    url = sys.argv[0].replace("plugin://%s" % ADDON_ID,
                              ELEMENTUMD_HOST + url_suffix) + sys.argv[2]
    if len(sys.argv) > 3:
        app = sys.argv[3].replace(":", "=")

        # Replacing resume=false with resume=true if item is launched from main window
        title = xbmc.getInfoLabel('ListItem.Title')
        label = xbmc.getInfoLabel('ListItem.Label')
        if "resume" in app and not title and not label:
            app = app.replace("resume=false", "resume=true")

        if "?" in url:
            url += "&" + app
        else:
            url += "?" + app

    log.debug("Requesting %s from %s" % (url, repr(sys.argv)))

    try:
        data = _json(url)
    except urllib2.URLError as e:
        if 'Connection refused' in e.reason:
            notify(getLocalizedString(30116), time=7000)
        else:
            import traceback
            map(log.error, traceback.format_exc().split("\n"))
            notify(e.reason, time=7000)
        return
    except Exception as e:
        import traceback
        map(log.error, traceback.format_exc().split("\n"))
        try:
            msg = unicode(e)
        except:
            try:
                msg = str(e)
            except:
                msg = repr(e)
        notify(getLocalizedLabel(msg), time=7000)
        return

    if not data:
        return

    if data["content_type"]:
        content_type = data["content_type"]
        if data["content_type"].startswith("menus"):
            content_type = data["content_type"].split("_")[1]

        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_UNSORTED)
        if content_type != "tvshows":
            xbmcplugin.addSortMethod(HANDLE,
                                     xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE)
        else:
            xbmcplugin.addSortMethod(HANDLE,
                                     xbmcplugin.SORT_METHOD_TITLE_IGNORE_THE)
        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_DATE)
        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_GENRE)
        xbmcplugin.setContent(HANDLE, content_type)

    listitems = range(len(data["items"]))
    for i, item in enumerate(data["items"]):
        # Translate labels
        if item["label"][0:8] == "LOCALIZE":
            item["label"] = unicode(getLocalizedLabel(item["label"]), 'utf-8')
        if item["label2"][0:8] == "LOCALIZE":
            item["label2"] = getLocalizedLabel(item["label2"])

        listItem = xbmcgui.ListItem(label=item["label"],
                                    label2=item["label2"],
                                    iconImage=item["icon"],
                                    thumbnailImage=item["thumbnail"])
        if item.get("info"):
            listItem.setInfo("video", item["info"])
        if item.get("stream_info"):
            for type_, values in item["stream_info"].items():
                listItem.addStreamInfo(type_, values)
        if item.get("art"):
            listItem.setArt(item["art"])
        elif ADDON.getSetting(
                'default_fanart') == 'true' and item["label"] != unicode(
                    getLocalizedString(30218), 'utf-8'):
            fanart = os.path.join(ADDON_PATH, "fanart.png")
            listItem.setArt({'fanart': fanart})
        if item.get("context_menu"):
            # Translate context menus
            for m, menu in enumerate(item["context_menu"]):
                if menu[0][0:8] == "LOCALIZE":
                    menu[0] = getLocalizedLabel(menu[0])
            listItem.addContextMenuItems(item["context_menu"])
        listItem.setProperty("isPlayable", item["is_playable"] and "true"
                             or "false")
        if item.get("properties"):
            for k, v in item["properties"].items():
                listItem.setProperty(k, v)
        listitems[i] = (item["path"], listItem, not item["is_playable"])

    xbmcplugin.addDirectoryItems(HANDLE, listitems, totalItems=len(listitems))

    # Set ViewMode
    if data["content_type"]:
        viewMode = ADDON.getSetting("viewmode_%s" % data["content_type"])
        if viewMode:
            try:
                xbmc.executebuiltin('Container.SetViewMode(%s)' % viewMode)
            except Exception as e:
                log.warning("Unable to SetViewMode(%s): %s" %
                            (viewMode, repr(e)))

    xbmcplugin.endOfDirectory(HANDLE,
                              succeeded=True,
                              updateListing=False,
                              cacheToDisc=True)
示例#10
0
def start_elementumd(**kwargs):
    jsonrpc_failures = 0
    while jsonrpc_enabled() is False:
        jsonrpc_failures += 1
        log.warning("Unable to connect to Kodi's JSON-RPC service, retrying...")
        if jsonrpc_failures > 1:
            time.sleep(5)
            if not jsonrpc_enabled(notify=True):
                log.error("Unable to reach Kodi's JSON-RPC service, aborting...")
                return False
            else:
                break
        time.sleep(3)

    elementum_dir, elementum_binary = get_elementum_binary()

    log.info("Binary dir: %s, item: %s " % (elementum_dir, elementum_binary))
    if elementum_dir is False or elementum_binary is False:
        return False

    lockfile = os.path.join(ADDON_PATH, ".lockfile")
    if os.path.exists(lockfile):
        log.warning("Existing process found from lockfile, killing...")
        try:
            with open(lockfile) as lf:
                pid = int(lf.read().rstrip(" \t\r\n\0"))
            os.kill(pid, 9)
        except OSError as e:
            if e.errno != 3:
                # Ignore:   OSError: [Errno 3] No such process
                log.error(repr(e))
        except Exception as e:
            log.error(repr(e))

        if binary_platform["os"] == "windows":
            try:
                library_lockfile = os.path.join(py2_decode(translatePath(ADDON.getAddonInfo("profile"))), "library.db.lock")
                log.warning("Removing library.db.lock file at %s ..." % library_lockfile)
                os.remove(library_lockfile)
            except Exception as e:
                log.error(repr(e))

    SW_HIDE = 0
    STARTF_USESHOWWINDOW = 1

    args = [elementum_binary]
    if ADDON.getSetting("local_port") != "":
        args.append("-remotePort=" + ADDON.getSetting("local_port"))
    if ADDON.getSetting("remote_host") != "":
        args.append("-localHost=" + ADDON.getSetting("remote_host"))
    if ADDON.getSetting("remote_port") != "":
        args.append("-localPort=" + ADDON.getSetting("remote_port"))
    kwargs["cwd"] = elementum_dir

    if binary_platform["os"] == "windows":
        args[0] = getWindowsShortPath(elementum_binary)
        kwargs["cwd"] = getWindowsShortPath(elementum_dir)
        si = subprocess.STARTUPINFO()
        si.dwFlags = STARTF_USESHOWWINDOW
        si.wShowWindow = SW_HIDE
        clear_fd_inherit_flags()
        kwargs["startupinfo"] = si
    else:
        env = os.environ.copy()
        env["LD_LIBRARY_PATH"] = "%s:%s" % (elementum_dir, env.get("LD_LIBRARY_PATH", ""))
        env["GODEBUG"] = "madvdontneed=1"
        kwargs["env"] = env
        kwargs["close_fds"] = True

    wait_counter = 1
    log.debug("Checking for visible")
    while xbmc.getCondVisibility('Window.IsVisible(10140)') or xbmc.getCondVisibility('Window.IsActive(10140)'):
        if wait_counter == 1:
            log.info('Add-on settings currently opened, waiting before starting...')
        if wait_counter > 300:
            break
        time.sleep(1)
        wait_counter += 1

    log.info("elementumd: start args: %s, kw: %s" % (args, kwargs))

    if hasSubprocess:
        return subprocess.Popen(args, **kwargs)
    return False
示例#11
0
def run(url_suffix="", retry=0):
    if '/restart/' in sys.argv[0]:
        restart_signal()
        return

    try:
        buffer_timeout = int(ADDON.getSetting("buffer_timeout"))
        if buffer_timeout < 60:
            buffer_timeout = 60
    except:
        buffer_timeout = 60
    buffer_timeout = buffer_timeout * 2

    try:
        preload_timeout = int(ADDON.getSetting("preload_timeout"))
        if preload_timeout < 1:
            preload_timeout = 1
    except:
        preload_timeout = 1

    socket.setdefaulttimeout(buffer_timeout)
    opener = urllib_request.build_opener(NoRedirectHandler())
    opener.addheaders = [('User-Agent', ADDON_ID)]
    urllib_request.install_opener(opener)

    # Pause currently playing Elementum file to avoid doubling requests
    try:
        if xbmc.Player().isPlaying() and ADDON_ID in xbmc.Player(
        ).getPlayingFile():
            xbmc.Player().pause()
    except:
        pass

    url = sys.argv[0].replace("plugin://%s" % ADDON_ID,
                              ELEMENTUMD_HOST + url_suffix) + sys.argv[2]
    query_add = ""

    if len(sys.argv) > 3:
        query_add = sys.argv[3].replace(":", "=")

    if query_add and "resume=" not in url:
        query_add = query_add.replace("resume=", "doresume=")
        if "?" in url:
            url += "&" + query_add
        else:
            url += "?" + query_add

    log.debug("Requesting %s from %s" % (url, repr(sys.argv)))

    try:
        data = _json(url)
    except PlayerException as e:
        redirect_url = e.__str__()
        log.debug("Launching player with %s" % (redirect_url))
        xbmcplugin.endOfDirectory(HANDLE, succeeded=True)
        xbmc.sleep(500)
        xbmc.executeJSONRPC(
            '{"jsonrpc":"2.0","method":"Player.Open","params":{"item":{"file":"%s"}},"id":"1"}'
            % (redirect_url))
        return
    except RedirectException as e:
        redirect_url = e.__str__()
        log.debug("Redirecting Kodi with %s" % (redirect_url))
        xbmcplugin.endOfDirectory(HANDLE, succeeded=True)
        xbmc.sleep(500)
        if "keyboard=1" in sys.argv[0]:
            xbmc.executebuiltin('Container.Update(%s,replace)' %
                                (redirect_url))
        else:
            xbmc.executebuiltin('Container.Update(%s)' % (redirect_url))
        return
    except urllib_error.URLError as e:
        # We can retry the request if connection is refused.
        # For example when plugin has not yet started but is requested by someone.
        if retry <= 2:
            time.sleep(preload_timeout)
            return run(retry=retry + 1)

        if isinstance(e.reason, IOError) or isinstance(
                e.reason, OSError) or 'Connection refused' in e.reason:
            notify(getLocalizedString(30116), time=7000)
        else:
            import traceback
            map(log.error, traceback.format_exc().split("\n"))
            notify(e.reason, time=7000)
        return
    except Exception as e:
        import traceback
        log.debug(traceback.print_exc())
        map(log.error, traceback.format_exc().split("\n"))
        try:
            msg = six.ensure_text(e.__str__(), errors='ignore')
        except:
            try:
                msg = six.ensure_binary(e.__str__(), errors='ignore')
            except:
                msg = repr(e)
        notify(getLocalizedLabel(msg), time=7000)
        return

    if not data:
        return

    if data["content_type"]:
        content_type = data["content_type"]
        if data["content_type"].startswith("menus"):
            content_type = data["content_type"].split("_")[1]

        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_UNSORTED)
        if content_type != "tvshows":
            xbmcplugin.addSortMethod(HANDLE,
                                     xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE)
        else:
            xbmcplugin.addSortMethod(HANDLE,
                                     xbmcplugin.SORT_METHOD_TITLE_IGNORE_THE)
        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_DATE)
        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_GENRE)
        xbmcplugin.setContent(HANDLE, content_type)

    listitems = list(range(len(data["items"])))
    for i, item in enumerate(data["items"]):
        # Translate labels
        if "LOCALIZE" in item["label"]:
            if item["label"][0:8] == "LOCALIZE":
                item["label"] = getLocalizedLabel(item["label"])
            else:
                item["label"] = getLocalizedText(item["label"])
            if isinstance(item["label"], str):
                item["label"] = six.ensure_text(item["label"], 'utf-8')
        if "LOCALIZE" in item["label2"]:
            if item["label2"][0:8] == "LOCALIZE":
                item["label2"] = getLocalizedText(item["label2"])
            else:
                item["label2"] = getLocalizedText(item["label2"])
            if isinstance(item["label2"], str):
                item["label2"] = six.ensure_text(item["label2"], 'utf-8')

        if PLATFORM['kodi'] >= 19:
            listItem = xbmcgui.ListItem(label=item["label"],
                                        label2=item["label2"])
            listItem.setArt({'icon': item["icon"]})
            listItem.setArt({'thumb': item["thumbnail"]})
        else:
            listItem = xbmcgui.ListItem(label=item["label"],
                                        label2=item["label2"],
                                        iconImage=item["icon"],
                                        thumbnailImage=item["thumbnail"])

        try:
            if item.get("castmembers") and PLATFORM['kodi'] >= 17:
                listItem.setCast(item.get("castmembers"))
            if item.get("info"):
                item["info"] = normalizeLabels(item["info"])
                listItem.setInfo("video", item["info"])
            if item.get("stream_info"):
                for type_, values in item["stream_info"].items():
                    listItem.addStreamInfo(type_, values)
            if item.get("art"):
                if "fanarts" in item.get("art") and item.get("art")["fanarts"]:
                    try:
                        start = 0
                        fanart_list = []
                        for fa in item.get("art")["fanarts"]:
                            start += 1
                            item.get("art")["fanart{}".format(start)] = fa
                            fanart_list.append({'image': fa})

                        if PLATFORM['kodi'] >= 18:
                            listItem.setAvailableFanart(fanart_list)
                    except Exception as e:
                        log.warning(
                            "Could not initialize ListItem.Art (%s): %s" %
                            (repr(item.get("art")), repr(e)))
                        pass
                    del item.get("art")["fanarts"]

                listItem.setArt(item["art"])
            elif ADDON.getSetting('default_fanart') == 'true' and item[
                    "label"] != six.ensure_text(getLocalizedString(30218),
                                                'utf-8'):
                fanart = os.path.join(ADDON_PATH, "fanart.jpg")
                listItem.setArt({'fanart': fanart})
            if item.get("context_menu"):
                # Translate context menus
                for m, menu in enumerate(item["context_menu"]):
                    if menu[0][0:8] == "LOCALIZE":
                        menu[0] = getLocalizedLabel(menu[0])
                    if PLATFORM['kodi'] >= 19 and menu[1][0:5] == "XBMC.":
                        menu[1] = menu[1][5:]
                listItem.addContextMenuItems(item["context_menu"])
            listItem.setProperty("isPlayable", item["is_playable"] and "true"
                                 or "false")
            if item.get("properties"):
                for k, v in item["properties"].items():
                    listItem.setProperty(k, v)
        except Exception as e:
            log.warning("Could not initialize ListItem (%s): %s" %
                        (repr(item.get("info")), repr(e)))
        listitems[i] = (item["path"], listItem, not item["is_playable"])

    xbmcplugin.addDirectoryItems(HANDLE, listitems, totalItems=len(listitems))

    # Set ViewMode
    if data["content_type"]:
        viewMode = ADDON.getSetting("viewmode_%s" % data["content_type"])
        if viewMode:
            try:
                xbmc.executebuiltin('Container.SetViewMode(%s)' % viewMode)
            except Exception as e:
                log.warning("Unable to SetViewMode(%s): %s" %
                            (viewMode, repr(e)))

    xbmcplugin.endOfDirectory(HANDLE,
                              succeeded=True,
                              updateListing=False,
                              cacheToDisc=True)
def notify(message, header=ADDON_NAME, time=5000, image=ADDON_ICON):
    sound = ADDON.getSetting('do_not_disturb') == 'false'
    dialog = xbmcgui.Dialog()
    return dialog.notification(toUtf8(header), toUtf8(message), toUtf8(image),
                               time, sound)