Example #1
0
    def onInit(self):
        '''triggered when the dialog is drawn'''
        if self.listitem:
            self.clearList()
            kodidb = KodiDb()
            if isinstance(self.listitem, dict):
                self.listitem = kodidb.prepare_listitem(self.listitem)
                self.listitem = kodidb.create_listitem(self.listitem, False)
            del kodidb
            self.addItem(self.listitem)

        # disable some controls if existing
        disable_controls = [9, 7, 101, 6]
        for item in disable_controls:
            try:
                self.getControl(item).setVisible(False)
            except Exception:
                pass

        # enable some controls if existing
        disable_controls = [351, 352]
        for item in disable_controls:
            try:
                self.getControl(item).setVisible(True)
                self.getControl(item).setEnabled(True)
            except Exception:
                pass
Example #2
0
 def open_item(self):
     '''open selected item'''
     control_id = self.getFocusId()
     listitem = self.getControl(control_id).getSelectedItem()
     if "videodb:" in listitem.getfilename():
         # tvshow: open path
         xbmc.executebuiltin('ReplaceWindow(Videos,"%s")' %
                             self.listitem.getfilename())
         self.close_dialog()
     elif "actor" in listitem.getProperty("DBTYPE"):
         # cast dialog
         xbmc.executebuiltin("ActivateWindow(busydialog)")
         from dialogselect import DialogSelect
         results = []
         kodidb = KodiDb()
         name = listitem.getLabel().decode("utf-8")
         items = kodidb.castmedia(name)
         items = process_method_on_list(kodidb.prepare_listitem, items)
         for item in items:
             if item["file"].startswith("videodb://"):
                 item["file"] = "ActivateWindow(Videos,%s,return)" % item[
                     "file"]
             else:
                 item["file"] = 'PlayMedia("%s")' % item["file"]
             results.append(kodidb.create_listitem(item, False))
         # finished lookup - display listing with results
         xbmc.executebuiltin("dialog.Close(busydialog)")
         dialog = DialogSelect("DialogSelect.xml",
                               "",
                               listing=results,
                               windowtitle=name,
                               richlayout=True)
         dialog.doModal()
         result = dialog.result
         del dialog
         if result:
             xbmc.executebuiltin(result.getfilename())
             self.close_dialog()
     else:
         # video file: start playback
         xbmc.executebuiltin('PlayMedia("%s")' % listitem.getfilename())
         self.close_dialog()
 def open_item(self):
     '''open selected item'''
     control_id = self.getFocusId()
     listitem = self.getControl(control_id).getSelectedItem()
     if "videodb:" in listitem.getfilename():
         #tvshow: open path
         xbmc.executebuiltin('ReplaceWindow(Videos,"%s")' % self.listitem.getfilename())
         self.close_dialog()
     elif "actor" in listitem.getProperty("DBTYPE"):
         #cast dialog
         xbmc.executebuiltin("ActivateWindow(busydialog)")
         from dialogselect import DialogSelect
         results = []
         kodidb = KodiDb()
         name = listitem.getLabel().decode("utf-8")
         items = kodidb.castmedia(name)
         items = process_method_on_list(kodidb.prepare_listitem, items)
         for item in items:
             if item["file"].startswith("videodb://"):
                 item["file"] = "ActivateWindow(Videos,%s,return)" % item["file"]
             else:
                 item["file"] = 'PlayMedia("%s")' % item["file"]
             results.append(kodidb.create_listitem(item, False))
         # finished lookup - display listing with results
         xbmc.executebuiltin("dialog.Close(busydialog)")
         dialog = DialogSelect("DialogSelect.xml", "", listing=results, windowtitle=name, richlayout=True)
         dialog.doModal()
         result = dialog.result
         del dialog
         if result:
             xbmc.executebuiltin(result.getfilename())
             self.close_dialog()
     else:
         # video file: start playback
         xbmc.executebuiltin('PlayMedia("%s")' % listitem.getfilename())
         self.close_dialog()
Example #4
0
class SearchBackgroundThread(threading.Thread):
    '''Background thread to complement our search dialog,
    fills the listing while UI keeps responsive'''
    active = True
    dialog = None
    search_string = ""

    def __init__(self, *args):
        xbmc.log("SearchBackgroundThread Init")
        threading.Thread.__init__(self, *args)
        self.kodidb = KodiDb()
        self.actors = []
        thread.start_new_thread(self.set_actors, ())

    def set_search(self, searchstr):
        '''set search query'''
        self.search_string = searchstr

    def stop_running(self):
        '''stop thread end exit'''
        self.active = False

    def set_dialog(self, dialog):
        '''set the active dialog to perform actions'''
        self.dialog = dialog

    def set_actors(self):
        '''fill list with all actors'''
        self.actors = self.kodidb.actors()

    def run(self):
        '''Main run loop for the background thread'''
        last_searchstring = ""
        monitor = xbmc.Monitor()
        while not monitor.abortRequested() and self.active:
            if self.search_string != last_searchstring:
                last_searchstring = self.search_string
                self.do_search(self.search_string)
            monitor.waitForAbort(1)
        del monitor

    def do_search(self, search_term):
        '''scrape results for search query'''

        movies_list = self.dialog.getControl(3110)
        series_list = self.dialog.getControl(3111)
        cast_list = self.dialog.getControl(3112)

        # clear current values
        movies_list.reset()
        series_list.reset()
        cast_list.reset()

        if len(search_term) == 0:
            return

        filters = [{
            "operator": "contains",
            "field": "title",
            "value": search_term
        }]

        # Process movies
        items = self.kodidb.movies(filters=filters)
        items = process_method_on_list(self.kodidb.prepare_listitem, items)
        result = []
        for item in items:
            result.append(self.kodidb.create_listitem(item, False))
        movies_list.addItems(result)

        # Process tvshows
        items = self.kodidb.tvshows(filters=filters)
        items = process_method_on_list(self.kodidb.prepare_listitem, items)
        result = []
        for item in items:
            item["file"] = 'videodb://tvshows/titles/%s' % item['tvshowid']
            item["isFolder"] = True
            result.append(self.kodidb.create_listitem(item, False))
        series_list.addItems(result)

        # Process cast
        result = []
        for item in self.actors:
            if search_term.lower() in item["label"].lower():
                item = self.kodidb.prepare_listitem(item)
                item[
                    "file"] = "RunScript(script.skin.helper.service,action=getcastmedia,name=%s)" % item[
                        "label"]
                result.append(self.kodidb.create_listitem(item, False))
        cast_list.addItems(result)
class SearchBackgroundThread(threading.Thread):
    '''Background thread to complement our search dialog,
    fills the listing while UI keeps responsive'''
    active = True
    dialog = None
    search_string = ""

    def __init__(self, *args):
        xbmc.log("SearchBackgroundThread Init")
        threading.Thread.__init__(self, *args)
        self.kodidb = KodiDb()
        self.actors = []
        thread.start_new_thread(self.set_actors, ())

    def set_search(self, searchstr):
        '''set search query'''
        self.search_string = searchstr

    def stop_running(self):
        '''stop thread end exit'''
        self.active = False

    def set_dialog(self, dialog):
        '''set the active dialog to perform actions'''
        self.dialog = dialog
        
    def set_actors(self):
        '''fill list with all actors'''
        self.actors = self.kodidb.actors()

    def run(self):
        '''Main run loop for the background thread'''
        last_searchstring = ""
        monitor = xbmc.Monitor()
        while not monitor.abortRequested() and self.active:
            if self.search_string != last_searchstring:
                last_searchstring = self.search_string
                self.do_search(self.search_string)
            monitor.waitForAbort(1)
        del monitor

    def do_search(self, search_term):
        '''scrape results for search query'''

        movies_list = self.dialog.getControl(3110)
        series_list = self.dialog.getControl(3111)
        cast_list = self.dialog.getControl(3112)

        # clear current values
        movies_list.reset()
        series_list.reset()
        cast_list.reset()

        if len(search_term) == 0:
            return

        filters = [{"operator": "contains", "field": "title", "value": search_term}]

        # Process movies
        items = self.kodidb.movies(filters=filters)
        items = process_method_on_list(self.kodidb.prepare_listitem, items)
        result = []
        for item in items:
            result.append(self.kodidb.create_listitem(item, False))
        movies_list.addItems(result)

        # Process tvshows
        items = self.kodidb.tvshows(filters=filters)
        items = process_method_on_list(self.kodidb.prepare_listitem, items)
        result = []
        for item in items:
            item["file"] = 'videodb://tvshows/titles/%s' % item['tvshowid']
            item["isFolder"] = True
            result.append(self.kodidb.create_listitem(item, False))
        series_list.addItems(result)

        # Process cast
        result = []
        for item in self.actors:
            if search_term.lower() in item["label"].lower():
                item = self.kodidb.prepare_listitem(item)
                item["file"] = "RunScript(script.skin.helper.service,action=getcastmedia,name=%s)" % item["label"]
                result.append(self.kodidb.create_listitem(item, False))
        cast_list.addItems(result)
class MainModule:
    '''mainmodule provides the script methods for the skinhelper addon'''

    def __init__(self):
        '''Initialization and main code run'''
        self.win = xbmcgui.Window(10000)
        self.addon = xbmcaddon.Addon(ADDON_ID)
        self.kodidb = KodiDb()
        self.cache = SimpleCache()

        self.params = self.get_params()
        log_msg("MainModule called with parameters: %s" % self.params)
        action = self.params.get("action", "")
        # launch module for action provided by this script
        try:
            getattr(self, action)()
        except AttributeError:
            log_exception(__name__, "No such action: %s" % action)
        except Exception as exc:
            log_exception(__name__, exc)
        finally:
            xbmc.executebuiltin("dialog.Close(busydialog)")

        # do cleanup
        self.close()

    def close(self):
        '''Cleanup Kodi Cpython instances on exit'''
        self.cache.close()
        del self.win
        del self.addon
        del self.kodidb
        log_msg("MainModule exited")

    @classmethod
    def get_params(self):
        '''extract the params from the called script path'''
        params = {}
        for arg in sys.argv[1:]:
            paramname = arg.split('=')[0]
            paramvalue = arg.replace(paramname + "=", "")
            paramname = paramname.lower()
            if paramname == "action":
                paramvalue = paramvalue.lower()
            params[paramname] = paramvalue
        return params

    def deprecated_method(self, newaddon):
        '''
            used when one of the deprecated methods is called
            print warning in log and call the external script with the same parameters
        '''
        action = self.params.get("action")
        log_msg("Deprecated method: %s. Please call %s directly" % (action, newaddon), xbmc.LOGWARNING)
        paramstring = ""
        for key, value in self.params.iteritems():
            paramstring += ",%s=%s" % (key, value)
        if xbmc.getCondVisibility("System.HasAddon(%s)" % newaddon):
            xbmc.executebuiltin("RunAddon(%s%s)" % (newaddon, paramstring))
        else:
            # trigger install of the addon
            if KODI_VERSION >= 17:
                xbmc.executebuiltin("InstallAddon(%s)" % newaddon)
            else:
                xbmc.executebuiltin("RunPlugin(plugin://%s)" % newaddon)

    @staticmethod
    def musicsearch():
        '''helper to go directly to music search dialog'''
        xbmc.executebuiltin("ActivateWindow(Music)")
        xbmc.executebuiltin("SendClick(8)")

    def setview(self):
        '''sets the selected viewmode for the container'''
        xbmc.executebuiltin("ActivateWindow(busydialog)")
        content_type = get_current_content_type()
        if not content_type:
            content_type = "files"
        current_view = xbmc.getInfoLabel("Container.Viewmode").decode("utf-8")
        view_id, view_label = self.selectview(content_type, current_view)
        current_forced_view = xbmc.getInfoLabel("Skin.String(SkinHelper.ForcedViews.%s)" % content_type)

        if view_id is not None:
            # also store forced view
            if (content_type and current_forced_view and current_forced_view != "None" and
                    xbmc.getCondVisibility("Skin.HasSetting(SkinHelper.ForcedViews.Enabled)")):
                xbmc.executebuiltin("Skin.SetString(SkinHelper.ForcedViews.%s,%s)" % (content_type, view_id))
                xbmc.executebuiltin("Skin.SetString(SkinHelper.ForcedViews.%s.label,%s)" % (content_type, view_label))
                self.win.setProperty("SkinHelper.ForcedView", view_id)
                if not xbmc.getCondVisibility("Control.HasFocus(%s)" % current_forced_view):
                    xbmc.sleep(100)
                    xbmc.executebuiltin("Container.SetViewMode(%s)" % view_id)
                    xbmc.executebuiltin("SetFocus(%s)" % view_id)
            else:
                self.win.clearProperty("SkinHelper.ForcedView")
            # set view
            xbmc.executebuiltin("Container.SetViewMode(%s)" % view_id)

    def selectview(self, content_type="other", current_view=None, display_none=False):
        '''reads skinfile with all views to present a dialog to choose from'''
        cur_view_select_id = None
        label = ""
        all_views = []
        if display_none:
            listitem = xbmcgui.ListItem(label="None")
            listitem.setProperty("id", "None")
            all_views.append(listitem)
        # read the special skin views file
        views_file = xbmc.translatePath('special://skin/extras/views.xml').decode("utf-8")
        if xbmcvfs.exists(views_file):
            doc = parse(views_file)
            listing = doc.documentElement.getElementsByTagName('view')
            itemcount = 0
            for view in listing:
                label = xbmc.getLocalizedString(int(view.attributes['languageid'].nodeValue))
                viewid = view.attributes['value'].nodeValue
                mediatypes = view.attributes['type'].nodeValue.lower().split(",")
                if label.lower() == current_view.lower() or viewid == current_view:
                    cur_view_select_id = itemcount
                    if display_none:
                        cur_view_select_id += 1
                if (("all" in mediatypes or content_type.lower() in mediatypes) and
                    (not "!" + content_type.lower() in mediatypes) and not
                        xbmc.getCondVisibility("Skin.HasSetting(SkinHelper.view.Disabled.%s)" % viewid)):
                    image = "special://skin/extras/viewthumbs/%s.jpg" % viewid
                    listitem = xbmcgui.ListItem(label=label, iconImage=image)
                    listitem.setProperty("viewid", viewid)
                    listitem.setProperty("icon", image)
                    all_views.append(listitem)
                    itemcount += 1
        dialog = DialogSelect("DialogSelect.xml", "", listing=all_views,
                              windowtitle=self.addon.getLocalizedString(32012), richlayout=True)
        dialog.autofocus_id = cur_view_select_id
        dialog.doModal()
        result = dialog.result
        del dialog
        if result:
            viewid = result.getProperty("viewid")
            label = result.getLabel().decode("utf-8")
            return (viewid, label)
        else:
            return (None, None)

    def enableviews(self):
        '''show select dialog to enable/disable views'''
        all_views = []
        views_file = xbmc.translatePath('special://skin/extras/views.xml').decode("utf-8")
        if xbmcvfs.exists(views_file):
            doc = parse(views_file)
            listing = doc.documentElement.getElementsByTagName('view')
            for view in listing:
                view_id = view.attributes['value'].nodeValue
                label = xbmc.getLocalizedString(int(view.attributes['languageid'].nodeValue))
                desc = label + " (" + str(view_id) + ")"
                listitem = xbmcgui.ListItem(label=label, label2=desc)
                listitem.setProperty("viewid", view_id)
                if not xbmc.getCondVisibility("Skin.HasSetting(SkinHelper.view.Disabled.%s)" % view_id):
                    listitem.select(selected=True)
                all_views.append(listitem)

        dialog = DialogSelect(
            "DialogSelect.xml",
            "",
            listing=all_views,
            windowtitle=self.addon.getLocalizedString(32013),
            multiselect=True)
        dialog.doModal()
        result = dialog.result
        del dialog
        if result:
            for item in result:
                view_id = item.getProperty("viewid")
                if item.isSelected():
                    # view is enabled
                    xbmc.executebuiltin("Skin.Reset(SkinHelper.view.Disabled.%s)" % view_id)
                else:
                    # view is disabled
                    xbmc.executebuiltin("Skin.SetBool(SkinHelper.view.Disabled.%s)" % view_id)

    def setforcedview(self):
        '''helper that sets a forced view for a specific content type'''
        content_type = self.params.get("contenttype")
        if content_type:
            current_view = xbmc.getInfoLabel("Skin.String(SkinHelper.ForcedViews.%s)" % content_type)
            if not current_view:
                current_view = "0"
            view_id, view_label = self.selectview(content_type, current_view, True)
            if view_id:
                xbmc.executebuiltin("Skin.SetString(SkinHelper.ForcedViews.%s,%s)" % (content_type, view_id))
                xbmc.executebuiltin("Skin.SetString(SkinHelper.ForcedViews.%s.label,%s)" % (content_type, view_label))

    @staticmethod
    def get_youtube_listing(searchquery):
        '''get items from youtube plugin by query'''
        lib_path = u"plugin://plugin.video.youtube/kodion/search/query/?q=%s" % searchquery
        return KodiDb().files(lib_path)

    def searchyoutube(self):
        '''helper to search youtube for the given title'''
        xbmc.executebuiltin("ActivateWindow(busydialog)")
        title = self.params.get("title", "")
        window_header = self.params.get("header", "")
        results = []
        for media in self.get_youtube_listing(title):
            if not media["filetype"] == "directory":
                label = media["label"]
                label2 = media["plot"]
                image = ""
                if media.get('art'):
                    if media['art'].get('thumb'):
                        image = (media['art']['thumb'])
                listitem = xbmcgui.ListItem(label=label, label2=label2, iconImage=image)
                listitem.setProperty("path", media["file"])
                results.append(listitem)

        # finished lookup - display listing with results
        xbmc.executebuiltin("dialog.Close(busydialog)")
        dialog = DialogSelect("DialogSelect.xml", "", listing=results, windowtitle=window_header, multiselect=False)
        dialog.doModal()
        result = dialog.result
        del dialog
        if result:
            if xbmc.getCondVisibility(
                    "Window.IsActive(script-skin_helper_service-CustomInfo.xml) | "
                    "Window.IsActive(movieinformation)"):
                xbmc.executebuiltin("Dialog.Close(movieinformation)")
                xbmc.executebuiltin("Dialog.Close(script-skin_helper_service-CustomInfo.xml)")
                xbmc.sleep(1000)
            xbmc.executebuiltin('PlayMedia("%s")' % result.getProperty("path"))
            del result

    def getcastmedia(self):
        '''helper to show a dialog with all media for a specific actor'''
        xbmc.executebuiltin("ActivateWindow(busydialog)")
        name = self.params.get("name", "")
        window_header = self.params.get("name", "")
        results = []
        items = self.kodidb.castmedia(name)
        items = process_method_on_list(self.kodidb.prepare_listitem, items)
        for item in items:
            if item["file"].startswith("videodb://"):
                item["file"] = "ActivateWindow(Videos,%s,return)" % item["file"]
            else:
                item["file"] = 'PlayMedia("%s")' % item["file"]
            results.append(self.kodidb.create_listitem(item, False))
        # finished lookup - display listing with results
        xbmc.executebuiltin("dialog.Close(busydialog)")
        dialog = DialogSelect("DialogSelect.xml", "", listing=results, windowtitle=window_header, richlayout=True)
        dialog.doModal()
        result = dialog.result
        del dialog
        if result:
            while xbmc.getCondVisibility("System.HasModalDialog"):
                xbmc.executebuiltin("Action(Back)")
                xbmc.sleep(300)
            xbmc.executebuiltin(result.getfilename())
            del result

    def setfocus(self):
        '''helper to set focus on a list or control'''
        control = self.params.get("control")
        fallback = self.params.get("fallback")
        count = 0
        if control:
            while not xbmc.getCondVisibility("Control.HasFocus(%s)" % control):
                if xbmc.getCondVisibility("Window.IsActive(busydialog)"):
                    continue
                elif count == 20 or (xbmc.getCondVisibility(
                        "!Control.IsVisible(%s) | "
                        "!IntegerGreaterThan(Container(%s).NumItems,0)" % (control, control))):
                    if fallback:
                        xbmc.executebuiltin("Control.SetFocus(%s)" % fallback)
                    break
                else:
                    xbmc.executebuiltin("Control.SetFocus(%s)" % control)
                    xbmc.sleep(50)
                    count += 1
                    break

    def setwidgetcontainer(self):
        '''helper that reports the current selected widget container/control'''
        controls = self.params.get("controls", "").split("-")
        if controls:
            xbmc.sleep(50)
            for i in range(10):
                for control in controls:
                    if xbmc.getCondVisibility("Control.IsVisible(%s) + IntegerGreaterThan(Container(%s).NumItems,0)"
                                              % (control, control)):
                        self.win.setProperty("SkinHelper.WidgetContainer", control)
                        return
                xbmc.sleep(50)
        self.win.clearProperty("SkinHelper.WidgetContainer")

    def saveskinimage(self):
        '''let the user select an image and save it to addon_data for easy backup'''
        skinstring = self.params.get("skinstring", "")
        allow_multi = self.params.get("multi", "") == "true"
        header = self.params.get("header", "")
        value = SkinSettings().save_skin_image(skinstring, allow_multi, header)
        if value:
            xbmc.executebuiltin("Skin.SetString(%s,%s)" %(skinstring.encode("utf-8"), value.encode("utf-8")))

    @staticmethod
    def checkskinsettings():
        '''performs check of all default skin settings and labels'''
        SkinSettings().correct_skin_settings()

    def setskinsetting(self):
        '''allows the user to set a skin setting with a select dialog'''
        setting = self.params.get("setting", "")
        org_id = self.params.get("id", "")
        if "$" in org_id:
            org_id = xbmc.getInfoLabel(org_id).decode("utf-8")
        header = self.params.get("header", "")
        SkinSettings().set_skin_setting(setting=setting, window_header=header, original_id=org_id)

    def setskinconstant(self):
        '''allows the user to set a skin constant with a select dialog'''
        setting = self.params.get("setting", "").split("|")
        value = self.params.get("value", "").split("|")
        header = self.params.get("header", "")
        SkinSettings().set_skin_constant(setting, header, value)

    def setskinconstants(self):
        '''allows the skinner to set multiple skin constants'''
        settings = self.params.get("settings", "")
        values = self.params.get("values", "")
        SkinSettings().set_skin_constants(settings, values)

    def setskinshortcutsproperty(self):
        '''allows the user to make a setting for skinshortcuts using the special skinsettings dialogs'''
        setting = self.params.get("setting", "")
        prop = self.params.get("property", "")
        header = self.params.get("header", "")
        SkinSettings().set_skinshortcuts_property(setting, header, prop)

    def togglekodisetting(self):
        '''toggle kodi setting'''
        settingname = self.params.get("setting", "")
        cur_value = xbmc.getCondVisibility("system.getbool(%s)" % settingname)
        if cur_value:
            new_value = "false"
        else:
            new_value = "true"
        xbmc.executeJSONRPC(
            '{"jsonrpc":"2.0", "id":1, "method":"Settings.SetSettingValue","params":{"setting":"%s","value":%s}}' %
            (settingname, new_value))

    def setkodisetting(self):
        '''set kodi setting'''
        settingname = self.params.get("setting", "")
        value = self.params.get("value", "")
        is_int = False
        try:
            valueint = int(value)
            is_int = True
            del valueint
        except Exception:
            pass
        if value.lower() == "true":
            value = 'true'
        elif value.lower() == "false":
            value = 'false'
        elif is_int:
            value = '"%s"' % value
        xbmc.executeJSONRPC('{"jsonrpc":"2.0", "id":1, "method":"Settings.SetSettingValue",\
            "params":{"setting":"%s","value":%s}}' % (settingname, value))

    def playtrailer(self):
        '''auto play windowed trailer inside video listing'''
        if not xbmc.getCondVisibility("Player.HasMedia | Container.Scrolling | Container.OnNext | "
                                      "Container.OnPrevious | !IsEmpty(Window(Home).Property(traileractionbusy))"):
            self.win.setProperty("traileractionbusy", "traileractionbusy")
            widget_container = self.params.get("widgetcontainer", "")
            trailer_mode = self.params.get("mode", "").replace("auto_", "")
            allow_youtube = self.params.get("youtube", "") == "true"
            if not trailer_mode:
                trailer_mode = "windowed"
            if widget_container:
                widget_container_prefix = "Container(%s)." % widget_container
            else:
                widget_container_prefix = ""

            li_title = xbmc.getInfoLabel("%sListItem.Title" % widget_container_prefix).decode('utf-8')
            li_trailer = xbmc.getInfoLabel("%sListItem.Trailer" % widget_container_prefix).decode('utf-8')
            if not li_trailer and allow_youtube:
                youtube_result = self.get_youtube_listing("%s Trailer" % li_title)
                if youtube_result:
                    li_trailer = youtube_result[0].get("file")
            # always wait a bit to prevent trailer start playing when we're scrolling the list
            xbmc.Monitor().waitForAbort(3)
            if li_trailer and (li_title == xbmc.getInfoLabel("%sListItem.Title"
                                                             % widget_container_prefix).decode('utf-8')):
                if trailer_mode == "fullscreen" and li_trailer:
                    xbmc.executebuiltin('PlayMedia("%s")' % li_trailer)
                else:
                    xbmc.executebuiltin('PlayMedia("%s",1)' % li_trailer)
                self.win.setProperty("TrailerPlaying", trailer_mode)
            self.win.clearProperty("traileractionbusy")

    def colorpicker(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.colorpicker")

    def backup(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.skinbackup")

    def restore(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.skinbackup")

    def reset(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.skinbackup")

    def colorthemes(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.skinbackup")

    def createcolortheme(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.skinbackup")

    def restorecolortheme(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.skinbackup")

    def conditionalbackgrounds(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.backgrounds")

    def splashscreen(self):
        '''helper to show a user defined splashscreen in the skin'''
        import time
        splashfile = self.params.get("file", "")
        duration = int(self.params.get("duration", 5))
        if (splashfile.lower().endswith("jpg") or splashfile.lower().endswith("gif") or
                splashfile.lower().endswith("png") or splashfile.lower().endswith("tiff")):
            # this is an image file
            self.win.setProperty("SkinHelper.SplashScreen", splashfile)
            # for images we just wait for X seconds to close the splash again
            start_time = time.time()
            while (time.time() - start_time) <= duration:
                xbmc.sleep(500)
        else:
            # for video or audio we have to wait for the player to finish...
            xbmc.Player().play(splashfile, windowed=True)
            xbmc.sleep(500)
            while xbmc.getCondVisibility("Player.HasMedia"):
                xbmc.sleep(150)
        # replace startup window with home
        startupwindow = xbmc.getInfoLabel("System.StartupWindow")
        xbmc.executebuiltin("ReplaceWindow(%s)" % startupwindow)
        autostart_playlist = xbmc.getInfoLabel("$ESCINFO[Skin.String(autostart_playlist)]")
        if autostart_playlist:
            xbmc.executebuiltin("PlayMedia(%s)" % autostart_playlist)

    def videosearch(self):
        '''show the special search dialog'''
        xbmc.executebuiltin("ActivateWindow(busydialog)")
        from resources.lib.searchdialog import SearchDialog
        search_dialog = SearchDialog("script-skin_helper_service-CustomSearch.xml",
                                     self.addon.getAddonInfo('path').decode("utf-8"), "Default", "1080i")
        search_dialog.doModal()
        del search_dialog

    def showinfo(self):
        '''shows our special videoinfo dialog'''
        dbid = self.params.get("dbid", "")
        dbtype = self.params.get("dbtype", "")
        from infodialog import show_infodialog
        show_infodialog(dbid, dbtype)

    def deletedir(self):
        '''helper to delete a directory, input can be normal filesystem path or vfs'''
        del_path = self.params.get("path")
        if del_path:
            ret = xbmcgui.Dialog().yesno(heading=xbmc.getLocalizedString(122),
                                         line1=u"%s[CR]%s" % (xbmc.getLocalizedString(125), del_path))
            if ret:
                success = recursive_delete_dir(del_path)
                if success:
                    xbmcgui.Dialog().ok(heading=xbmc.getLocalizedString(19179),
                                        line1=self.addon.getLocalizedString(32014))
                else:
                    xbmcgui.Dialog().ok(heading=xbmc.getLocalizedString(16205),
                                        line1=xbmc.getLocalizedString(32015))

    def overlaytexture(self):
        '''legacy: helper to let the user choose a background overlay from a skin defined folder'''
        skinstring = self.params.get("skinstring", "BackgroundOverlayTexture")
        self.params["skinstring"] = skinstring
        self.params["resourceaddon"] = "resource.images.backgroundoverlays"
        self.params["customfolder"] = "special://skin/extras/bgoverlays/"
        self.params["allowmulti"] = "false"
        self.params["header"] = self.addon.getLocalizedString(32002)
        self.selectimage()

    def busytexture(self):
        '''legacy: helper which lets the user select a busy spinner from predefined spinners in the skin'''
        skinstring = self.params.get("skinstring", "SkinHelper.SpinnerTexture")
        self.params["skinstring"] = skinstring
        self.params["resourceaddon"] = "resource.images.busyspinners"
        self.params["customfolder"] = "special://skin/extras/busy_spinners/"
        self.params["allowmulti"] = "true"
        self.params["header"] = self.addon.getLocalizedString(32006)
        self.selectimage()

    def selectimage(self):
        '''helper which lets the user select an image or imagepath from resourceaddons or custom path'''
        skinsettings = SkinSettings()
        skinstring = self.params.get("skinstring", "")
        skinshortcutsprop = self.params.get("skinshortcutsproperty", "")
        current_value = self.params.get("currentvalue", "")
        resource_addon = self.params.get("resourceaddon", "")
        allow_multi = self.params.get("allowmulti", "false") == "true"
        windowheader = self.params.get("header", "")
        skinhelper_backgrounds = self.params.get("skinhelperbackgrounds", "false") == "true"
        label, value = skinsettings.select_image(
            skinstring, allow_multi=allow_multi, windowheader=windowheader, resource_addon=resource_addon,
            skinhelper_backgrounds=skinhelper_backgrounds, current_value=current_value)
        if label:
            if skinshortcutsprop:
                # write value to skinshortcuts prop
                from skinshortcuts import set_skinshortcuts_property
                set_skinshortcuts_property(skinshortcutsprop, value, label)
            else:
                # write the values to skin strings
                if value.startswith("$INFO"):
                    # we got an dynamic image from window property
                    skinsettings.set_skin_variable(skinstring, value)
                    value = "$VAR[%s]" % skinstring
                skinstring = skinstring.encode("utf-8")
                label = label.encode("utf-8")
                xbmc.executebuiltin("Skin.SetString(%s.label,%s)" % (skinstring, label))
                xbmc.executebuiltin("Skin.SetString(%s.name,%s)" % (skinstring, label))
                xbmc.executebuiltin("Skin.SetString(%s,%s)" % (skinstring, value))
                xbmc.executebuiltin("Skin.SetString(%s.path,%s)" % (skinstring, value))
        del skinsettings

    def dialogok(self):
        '''helper to show an OK dialog with a message'''
        headertxt = self.params.get("header")
        bodytxt = self.params.get("message")
        if bodytxt.startswith(" "):
            bodytxt = bodytxt[1:]
        if headertxt.startswith(" "):
            headertxt = headertxt[1:]
        dialog = xbmcgui.Dialog()
        dialog.ok(heading=headertxt, line1=bodytxt)
        del dialog

    def dialogyesno(self):
        '''helper to show a YES/NO dialog with a message'''
        headertxt = self.params.get("header")
        bodytxt = self.params.get("message")
        yesactions = self.params.get("yesaction", "").split("|")
        noactions = self.params.get("noaction", "").split("|")
        if bodytxt.startswith(" "):
            bodytxt = bodytxt[1:]
        if headertxt.startswith(" "):
            headertxt = headertxt[1:]
        if xbmcgui.Dialog().yesno(heading=headertxt, line1=bodytxt):
            for action in yesactions:
                xbmc.executebuiltin(action.encode("utf-8"))
        else:
            for action in noactions:
                xbmc.executebuiltin(action.encode("utf-8"))

    def textviewer(self):
        '''helper to show a textviewer dialog with a message'''
        headertxt = self.params.get("header", "")
        bodytxt = self.params.get("message", "")
        if bodytxt.startswith(" "):
            bodytxt = bodytxt[1:]
        if headertxt.startswith(" "):
            headertxt = headertxt[1:]
        xbmcgui.Dialog().textviewer(headertxt, bodytxt)

    def fileexists(self):
        '''helper to let the skinner check if a file exists
        and write the outcome to a window prop or skinstring'''
        filename = self.params.get("file")
        skinstring = self.params.get("skinstring")
        windowprop = self.params.get("winprop")
        if xbmcvfs.exists(filename):
            if windowprop:
                self.win.setProperty(windowprop, "exists")
            if skinstring:
                xbmc.executebuiltin("Skin.SetString(%s,exists)" % skinstring)
        else:
            if windowprop:
                self.win.clearProperty(windowprop)
            if skinstring:
                xbmc.executebuiltin("Skin.Reset(%s)" % skinstring)

    def stripstring(self):
        '''helper to allow the skinner to strip a string and write results to a skin string'''
        splitchar = self.params.get("splitchar")
        if splitchar.upper() == "[SPACE]":
            splitchar = " "
        skinstring = self.params.get("string")
        if not skinstring:
            skinstring = self.params.get("skinstring")
        output = self.params.get("output")
        index = self.params.get("index", 0)
        skinstring = skinstring.split(splitchar)[int(index)]
        self.win.setProperty(output, skinstring)

    def getfilename(self, filename=""):
        '''helper to display a sanitized filename in the vidoeinfo dialog'''
        output = self.params.get("output")
        if not filename:
            filename = xbmc.getInfoLabel("ListItem.FileNameAndPath")
        if not filename:
            filename = xbmc.getInfoLabel("ListItem.FileName")
        if "filename=" in filename:
            url_params = dict(urlparse.parse_qsl(filename))
            filename = url_params.get("filename")
        self.win.setProperty(output, filename)

    def getplayerfilename(self):
        '''helper to parse the filename from a plugin (e.g. emby) filename'''
        filename = xbmc.getInfoLabel("Player.FileNameAndPath")
        if not filename:
            filename = xbmc.getInfoLabel("Player.FileName")
        self.getfilename(filename)

    def getpercentage(self):
        '''helper to calculate the percentage of 2 numbers and write results to a skinstring'''
        total = int(params.get("total"))
        count = int(params.get("count"))
        roundsteps = self.params.get("roundsteps")
        skinstring = self.params.get("skinstring")
        percentage = int(round((1.0 * count / total) * 100))
        if roundsteps:
            roundsteps = int(roundsteps)
            percentage = percentage + (roundsteps - percentage) % roundsteps
        xbmc.executebuiltin("Skin.SetString(%s,%s)" % (skinstring, percentage))

    def setresourceaddon(self):
        '''helper to let the user choose a resource addon and set that as skin string'''
        from resourceaddons import setresourceaddon
        addontype = self.params.get("addontype", "")
        skinstring = self.params.get("skinstring", "")
        setresourceaddon(addontype, skinstring)

    def checkresourceaddons(self):
        '''allow the skinner to perform a basic check if some required resource addons are available'''
        from resourceaddons import checkresourceaddons
        addonslist = self.params.get("addonslist", [])
        if addonslist:
            addonslist = addonslist.split("|")
        checkresourceaddons(addonslist)
class MainModule:
    '''mainmodule provides the script methods for the skinhelper addon'''
    def __init__(self):
        '''Initialization and main code run'''
        self.win = xbmcgui.Window(10000)
        self.addon = xbmcaddon.Addon(ADDON_ID)
        self.kodidb = KodiDb()
        self.cache = SimpleCache()

        self.params = self.get_params()
        log_msg("MainModule called with parameters: %s" % self.params)
        action = self.params.get("action", "")
        # launch module for action provided by this script
        try:
            getattr(self, action)()
        except AttributeError:
            log_exception(__name__, "No such action: %s" % action)
        except Exception as exc:
            log_exception(__name__, exc)
        finally:
            xbmc.executebuiltin("dialog.Close(busydialog)")

        # do cleanup
        self.close()

    def close(self):
        '''Cleanup Kodi Cpython instances on exit'''
        self.cache.close()
        del self.win
        del self.addon
        del self.kodidb
        log_msg("MainModule exited")

    @classmethod
    def get_params(self):
        '''extract the params from the called script path'''
        params = {}
        for arg in sys.argv[1:]:
            paramname = arg.split('=')[0]
            paramvalue = arg.replace(paramname + "=", "")
            paramname = paramname.lower()
            if paramname == "action":
                paramvalue = paramvalue.lower()
            params[paramname] = paramvalue
        return params

    def deprecated_method(self, newaddon):
        '''
            used when one of the deprecated methods is called
            print warning in log and call the external script with the same parameters
        '''
        action = self.params.get("action")
        log_msg(
            "Deprecated method: %s. Please call %s directly" %
            (action, newaddon), xbmc.LOGWARNING)
        paramstring = ""
        for key, value in self.params.iteritems():
            paramstring += ",%s=%s" % (key, value)
        if xbmc.getCondVisibility("System.HasAddon(%s)" % newaddon):
            xbmc.executebuiltin("RunAddon(%s%s)" % (newaddon, paramstring))
        else:
            # trigger install of the addon
            if KODI_VERSION > 16:
                xbmc.executebuiltin("InstallAddon(%s)" % newaddon)
            else:
                xbmc.executebuiltin("RunPlugin(plugin://%s)" % newaddon)

    @staticmethod
    def musicsearch():
        '''helper to go directly to music search dialog'''
        xbmc.executebuiltin("ActivateWindow(Music)")
        xbmc.executebuiltin("SendClick(8)")

    def setview(self):
        '''sets the selected viewmode for the container'''
        xbmc.executebuiltin("ActivateWindow(busydialog)")
        content_type = get_current_content_type()
        if not content_type:
            content_type = "files"
        current_view = xbmc.getInfoLabel("Container.Viewmode").decode("utf-8")
        view_id, view_label = self.selectview(content_type, current_view)
        current_forced_view = xbmc.getInfoLabel(
            "Skin.String(SkinHelper.ForcedViews.%s)" % content_type)

        if view_id is not None:
            # also store forced view
            if (content_type and current_forced_view
                    and current_forced_view != "None"
                    and xbmc.getCondVisibility(
                        "Skin.HasSetting(SkinHelper.ForcedViews.Enabled)")):
                xbmc.executebuiltin(
                    "Skin.SetString(SkinHelper.ForcedViews.%s,%s)" %
                    (content_type, view_id))
                xbmc.executebuiltin(
                    "Skin.SetString(SkinHelper.ForcedViews.%s.label,%s)" %
                    (content_type, view_label))
                self.win.setProperty("SkinHelper.ForcedView", view_id)
                if not xbmc.getCondVisibility(
                        "Control.HasFocus(%s)" % current_forced_view):
                    xbmc.sleep(100)
                    xbmc.executebuiltin("Container.SetViewMode(%s)" % view_id)
                    xbmc.executebuiltin("SetFocus(%s)" % view_id)
            else:
                self.win.clearProperty("SkinHelper.ForcedView")
            # set view
            xbmc.executebuiltin("Container.SetViewMode(%s)" % view_id)

    def selectview(self,
                   content_type="other",
                   current_view=None,
                   display_none=False):
        '''reads skinfile with all views to present a dialog to choose from'''
        cur_view_select_id = None
        label = ""
        all_views = []
        if display_none:
            listitem = xbmcgui.ListItem(label="None")
            listitem.setProperty("id", "None")
            all_views.append(listitem)
        # read the special skin views file
        views_file = xbmc.translatePath(
            'special://skin/extras/views.xml').decode("utf-8")
        if xbmcvfs.exists(views_file):
            doc = parse(views_file)
            listing = doc.documentElement.getElementsByTagName('view')
            itemcount = 0
            for view in listing:
                label = xbmc.getLocalizedString(
                    int(view.attributes['languageid'].nodeValue))
                viewid = view.attributes['value'].nodeValue
                mediatypes = view.attributes['type'].nodeValue.lower().split(
                    ",")
                if label.lower() == current_view.lower(
                ) or viewid == current_view:
                    cur_view_select_id = itemcount
                    if display_none:
                        cur_view_select_id += 1
                if (("all" in mediatypes or content_type.lower() in mediatypes)
                        and (not "!" + content_type.lower() in mediatypes)
                        and not xbmc.getCondVisibility(
                            "Skin.HasSetting(SkinHelper.view.Disabled.%s)" %
                            viewid)):
                    image = "special://skin/extras/viewthumbs/%s.jpg" % viewid
                    listitem = xbmcgui.ListItem(label=label, iconImage=image)
                    listitem.setProperty("viewid", viewid)
                    listitem.setProperty("icon", image)
                    all_views.append(listitem)
                    itemcount += 1
        dialog = DialogSelect("DialogSelect.xml",
                              "",
                              listing=all_views,
                              windowtitle=self.addon.getLocalizedString(32012),
                              richlayout=True)
        dialog.autofocus_id = cur_view_select_id
        dialog.doModal()
        result = dialog.result
        del dialog
        if result:
            viewid = result.getProperty("viewid")
            label = result.getLabel().decode("utf-8")
            return (viewid, label)
        else:
            return (None, None)

    def enableviews(self):
        '''show select dialog to enable/disable views'''
        all_views = []
        views_file = xbmc.translatePath(
            'special://skin/extras/views.xml').decode("utf-8")
        if xbmcvfs.exists(views_file):
            doc = parse(views_file)
            listing = doc.documentElement.getElementsByTagName('view')
            for view in listing:
                view_id = view.attributes['value'].nodeValue
                label = xbmc.getLocalizedString(
                    int(view.attributes['languageid'].nodeValue))
                desc = label + " (" + str(view_id) + ")"
                listitem = xbmcgui.ListItem(label=label, label2=desc)
                listitem.setProperty("viewid", view_id)
                if not xbmc.getCondVisibility(
                        "Skin.HasSetting(SkinHelper.view.Disabled.%s)" %
                        view_id):
                    listitem.select(selected=True)
                all_views.append(listitem)

        dialog = DialogSelect("DialogSelect.xml",
                              "",
                              listing=all_views,
                              windowtitle=self.addon.getLocalizedString(32013),
                              multiselect=True)
        dialog.doModal()
        result = dialog.result
        del dialog
        if result:
            for item in result:
                view_id = item.getProperty("viewid")
                if item.isSelected():
                    # view is enabled
                    xbmc.executebuiltin(
                        "Skin.Reset(SkinHelper.view.Disabled.%s)" % view_id)
                else:
                    # view is disabled
                    xbmc.executebuiltin(
                        "Skin.SetBool(SkinHelper.view.Disabled.%s)" % view_id)

    def setforcedview(self):
        '''helper that sets a forced view for a specific content type'''
        content_type = self.params.get("contenttype")
        if content_type:
            current_view = xbmc.getInfoLabel(
                "Skin.String(SkinHelper.ForcedViews.%s)" % content_type)
            if not current_view:
                current_view = "0"
            view_id, view_label = self.selectview(content_type, current_view,
                                                  True)
            if view_id:
                xbmc.executebuiltin(
                    "Skin.SetString(SkinHelper.ForcedViews.%s,%s)" %
                    (content_type, view_id))
                xbmc.executebuiltin(
                    "Skin.SetString(SkinHelper.ForcedViews.%s.label,%s)" %
                    (content_type, view_label))

    @staticmethod
    def get_youtube_listing(searchquery):
        '''get items from youtube plugin by query'''
        lib_path = u"plugin://plugin.video.youtube/kodion/search/query/?q=%s" % searchquery
        return KodiDb().files(lib_path)

    def searchyoutube(self):
        '''helper to search youtube for the given title'''
        xbmc.executebuiltin("ActivateWindow(busydialog)")
        title = self.params.get("title", "")
        window_header = self.params.get("header", "")
        results = []
        for media in self.get_youtube_listing(title):
            if not media["filetype"] == "directory":
                label = media["label"]
                label2 = media["plot"]
                image = ""
                if media.get('art'):
                    if media['art'].get('thumb'):
                        image = (media['art']['thumb'])
                listitem = xbmcgui.ListItem(label=label,
                                            label2=label2,
                                            iconImage=image)
                listitem.setProperty("path", media["file"])
                results.append(listitem)

        # finished lookup - display listing with results
        xbmc.executebuiltin("dialog.Close(busydialog)")
        dialog = DialogSelect("DialogSelect.xml",
                              "",
                              listing=results,
                              windowtitle=window_header,
                              multiselect=False,
                              richlayout=True)
        dialog.doModal()
        result = dialog.result
        del dialog
        if result:
            if xbmc.getCondVisibility(
                    "Window.IsActive(script-skin_helper_service-CustomInfo.xml) | "
                    "Window.IsActive(movieinformation)"):
                xbmc.executebuiltin("Dialog.Close(movieinformation)")
                xbmc.executebuiltin(
                    "Dialog.Close(script-skin_helper_service-CustomInfo.xml)")
                xbmc.sleep(1000)
            xbmc.executebuiltin('PlayMedia("%s")' % result.getProperty("path"))
            del result

    def getcastmedia(self):
        '''helper to show a dialog with all media for a specific actor'''
        xbmc.executebuiltin("ActivateWindow(busydialog)")
        name = self.params.get("name", "")
        window_header = self.params.get("name", "")
        results = []
        items = self.kodidb.castmedia(name)
        items = process_method_on_list(self.kodidb.prepare_listitem, items)
        for item in items:
            if item["file"].startswith("videodb://"):
                item[
                    "file"] = "ActivateWindow(Videos,%s,return)" % item["file"]
            else:
                item["file"] = 'PlayMedia("%s")' % item["file"]
            results.append(self.kodidb.create_listitem(item, False))
        # finished lookup - display listing with results
        xbmc.executebuiltin("dialog.Close(busydialog)")
        dialog = DialogSelect("DialogSelect.xml",
                              "",
                              listing=results,
                              windowtitle=window_header,
                              richlayout=True)
        dialog.doModal()
        result = dialog.result
        del dialog
        if result:
            while xbmc.getCondVisibility("System.HasModalDialog"):
                xbmc.executebuiltin("Action(Back)")
                xbmc.sleep(300)
            xbmc.executebuiltin(result.getfilename())
            del result

    def setfocus(self):
        '''helper to set focus on a list or control'''
        control = self.params.get("control")
        fallback = self.params.get("fallback")
        position = self.params.get("position", "0")
        relativeposition = self.params.get("relativeposition")
        if relativeposition:
            position = int(relativeposition) - 1
        count = 0
        if control:
            while not xbmc.getCondVisibility("Control.HasFocus(%s)" % control):
                if xbmc.getCondVisibility("Window.IsActive(busydialog)"):
                    continue
                elif count == 20 or (xbmc.getCondVisibility(
                        "!Control.IsVisible(%s) | "
                        "!IntegerGreaterThan(Container(%s).NumItems,0)" %
                    (control, control))):
                    if fallback:
                        xbmc.executebuiltin("Control.SetFocus(%s)" % fallback)
                    break
                else:
                    xbmc.executebuiltin("Control.SetFocus(%s,%s)" %
                                        (control, position))
                    xbmc.sleep(50)
                    count += 1
                    break

    def setwidgetcontainer(self):
        '''helper that reports the current selected widget container/control'''
        controls = self.params.get("controls", "").split("-")
        if controls:
            xbmc.sleep(50)
            for i in range(10):
                for control in controls:
                    if xbmc.getCondVisibility(
                            "Control.IsVisible(%s) + IntegerGreaterThan(Container(%s).NumItems,0)"
                            % (control, control)):
                        self.win.setProperty("SkinHelper.WidgetContainer",
                                             control)
                        return
                xbmc.sleep(50)
        self.win.clearProperty("SkinHelper.WidgetContainer")

    def saveskinimage(self):
        '''let the user select an image and save it to addon_data for easy backup'''
        skinstring = self.params.get("skinstring", "")
        allow_multi = self.params.get("multi", "") == "true"
        header = self.params.get("header", "")
        value = SkinSettings().save_skin_image(skinstring, allow_multi, header)
        if value:
            xbmc.executebuiltin(
                "Skin.SetString(%s,%s)" %
                (skinstring.encode("utf-8"), value.encode("utf-8")))

    @staticmethod
    def checkskinsettings():
        '''performs check of all default skin settings and labels'''
        SkinSettings().correct_skin_settings()

    def setskinsetting(self):
        '''allows the user to set a skin setting with a select dialog'''
        setting = self.params.get("setting", "")
        org_id = self.params.get("id", "")
        if "$" in org_id:
            org_id = xbmc.getInfoLabel(org_id).decode("utf-8")
        header = self.params.get("header", "")
        SkinSettings().set_skin_setting(setting=setting,
                                        window_header=header,
                                        original_id=org_id)

    def setskinconstant(self):
        '''allows the user to set a skin constant with a select dialog'''
        setting = self.params.get("setting", "")
        value = self.params.get("value", "")
        header = self.params.get("header", "")
        SkinSettings().set_skin_constant(setting, header, value)

    def setskinconstants(self):
        '''allows the skinner to set multiple skin constants'''
        settings = self.params.get("settings", "").split("|")
        values = self.params.get("values", "").split("|")
        SkinSettings().set_skin_constants(settings, values)

    def setskinshortcutsproperty(self):
        '''allows the user to make a setting for skinshortcuts using the special skinsettings dialogs'''
        setting = self.params.get("setting", "")
        prop = self.params.get("property", "")
        header = self.params.get("header", "")
        SkinSettings().set_skinshortcuts_property(setting, header, prop)

    def togglekodisetting(self):
        '''toggle kodi setting'''
        settingname = self.params.get("setting", "")
        cur_value = xbmc.getCondVisibility("system.getbool(%s)" % settingname)
        if cur_value:
            new_value = "false"
        else:
            new_value = "true"
        xbmc.executeJSONRPC(
            '{"jsonrpc":"2.0", "id":1, "method":"Settings.SetSettingValue","params":{"setting":"%s","value":%s}}'
            % (settingname, new_value))

    def setkodisetting(self):
        '''set kodi setting'''
        settingname = self.params.get("setting", "")
        value = self.params.get("value", "")
        is_int = False
        try:
            valueint = int(value)
            is_int = True
            del valueint
        except Exception:
            pass
        if value.lower() == "true":
            value = 'true'
        elif value.lower() == "false":
            value = 'false'
        elif is_int:
            value = '"%s"' % value
        xbmc.executeJSONRPC(
            '{"jsonrpc":"2.0", "id":1, "method":"Settings.SetSettingValue",\
            "params":{"setting":"%s","value":%s}}' % (settingname, value))

    def playtrailer(self):
        '''auto play windowed trailer inside video listing'''
        if not xbmc.getCondVisibility(
                "Player.HasMedia | Container.Scrolling | Container.OnNext | "
                "Container.OnPrevious | !IsEmpty(Window(Home).Property(traileractionbusy))"
        ):
            self.win.setProperty("traileractionbusy", "traileractionbusy")
            widget_container = self.params.get("widgetcontainer", "")
            trailer_mode = self.params.get("mode", "").replace("auto_", "")
            allow_youtube = self.params.get("youtube", "") == "true"
            if not trailer_mode:
                trailer_mode = "windowed"
            if widget_container:
                widget_container_prefix = "Container(%s)." % widget_container
            else:
                widget_container_prefix = ""

            li_title = xbmc.getInfoLabel(
                "%sListItem.Title" % widget_container_prefix).decode('utf-8')
            li_trailer = xbmc.getInfoLabel(
                "%sListItem.Trailer" % widget_container_prefix).decode('utf-8')
            if not li_trailer and allow_youtube:
                youtube_result = self.get_youtube_listing("%s Trailer" %
                                                          li_title)
                if youtube_result:
                    li_trailer = youtube_result[0].get("file")
            # always wait a bit to prevent trailer start playing when we're scrolling the list
            xbmc.Monitor().waitForAbort(3)
            if li_trailer and (li_title == xbmc.getInfoLabel(
                    "%sListItem.Title" %
                    widget_container_prefix).decode('utf-8')):
                if trailer_mode == "fullscreen" and li_trailer:
                    xbmc.executebuiltin('PlayMedia("%s")' % li_trailer)
                else:
                    xbmc.executebuiltin('PlayMedia("%s",1)' % li_trailer)
                self.win.setProperty("TrailerPlaying", trailer_mode)
            self.win.clearProperty("traileractionbusy")

    def colorpicker(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.colorpicker")

    def backup(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.skinbackup")

    def restore(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.skinbackup")

    def reset(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.skinbackup")

    def colorthemes(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.skinbackup")

    def createcolortheme(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.skinbackup")

    def restorecolortheme(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.skinbackup")

    def conditionalbackgrounds(self):
        '''legacy'''
        self.deprecated_method("script.skin.helper.backgrounds")

    def splashscreen(self):
        '''helper to show a user defined splashscreen in the skin'''
        import time
        splashfile = self.params.get("file", "")
        duration = int(self.params.get("duration", 5))
        if (splashfile.lower().endswith("jpg")
                or splashfile.lower().endswith("gif")
                or splashfile.lower().endswith("png")
                or splashfile.lower().endswith("tiff")):
            # this is an image file
            self.win.setProperty("SkinHelper.SplashScreen", splashfile)
            # for images we just wait for X seconds to close the splash again
            start_time = time.time()
            while (time.time() - start_time) <= duration:
                xbmc.sleep(500)
        else:
            # for video or audio we have to wait for the player to finish...
            xbmc.Player().play(splashfile, windowed=True)
            xbmc.sleep(500)
            while xbmc.getCondVisibility("Player.HasMedia"):
                xbmc.sleep(150)
        # replace startup window with home
        startupwindow = xbmc.getInfoLabel("System.StartupWindow")
        xbmc.executebuiltin("ReplaceWindow(%s)" % startupwindow)
        autostart_playlist = xbmc.getInfoLabel(
            "$ESCINFO[Skin.String(autostart_playlist)]")
        if autostart_playlist:
            xbmc.executebuiltin("PlayMedia(%s)" % autostart_playlist)

    def videosearch(self):
        '''show the special search dialog'''
        xbmc.executebuiltin("ActivateWindow(busydialog)")
        from resources.lib.searchdialog import SearchDialog
        search_dialog = SearchDialog(
            "script-skin_helper_service-CustomSearch.xml",
            self.addon.getAddonInfo('path').decode("utf-8"), "Default",
            "1080i")
        search_dialog.doModal()
        del search_dialog

    def showinfo(self):
        '''shows our special videoinfo dialog'''
        dbid = self.params.get("dbid", "")
        dbtype = self.params.get("dbtype", "")
        from infodialog import show_infodialog
        show_infodialog(dbid, dbtype)

    def deletedir(self):
        '''helper to delete a directory, input can be normal filesystem path or vfs'''
        del_path = self.params.get("path")
        if del_path:
            ret = xbmcgui.Dialog().yesno(
                heading=xbmc.getLocalizedString(122),
                line1=u"%s[CR]%s" % (xbmc.getLocalizedString(125), del_path))
            if ret:
                success = recursive_delete_dir(del_path)
                if success:
                    xbmcgui.Dialog().ok(
                        heading=xbmc.getLocalizedString(19179),
                        line1=self.addon.getLocalizedString(32014))
                else:
                    xbmcgui.Dialog().ok(heading=xbmc.getLocalizedString(16205),
                                        line1=xbmc.getLocalizedString(32015))

    def overlaytexture(self):
        '''legacy: helper to let the user choose a background overlay from a skin defined folder'''
        skinstring = self.params.get("skinstring", "BackgroundOverlayTexture")
        self.params["skinstring"] = skinstring
        self.params["resourceaddon"] = "resource.images.backgroundoverlays"
        self.params["customfolder"] = "special://skin/extras/bgoverlays/"
        self.params["allowmulti"] = "false"
        self.params["header"] = self.addon.getLocalizedString(32002)
        self.selectimage()

    def busytexture(self):
        '''legacy: helper which lets the user select a busy spinner from predefined spinners in the skin'''
        skinstring = self.params.get("skinstring", "SkinHelper.SpinnerTexture")
        self.params["skinstring"] = skinstring
        self.params["resourceaddon"] = "resource.images.busyspinners"
        self.params["customfolder"] = "special://skin/extras/busy_spinners/"
        self.params["allowmulti"] = "true"
        self.params["header"] = self.addon.getLocalizedString(32006)
        self.selectimage()

    def selectimage(self):
        '''helper which lets the user select an image or imagepath from resourceaddons or custom path'''
        skinsettings = SkinSettings()
        skinstring = self.params.get("skinstring", "")
        skinshortcutsprop = self.params.get("skinshortcutsproperty", "")
        current_value = self.params.get("currentvalue", "")
        resource_addon = self.params.get("resourceaddon", "")
        allow_multi = self.params.get("allowmulti", "false") == "true"
        windowheader = self.params.get("header", "")
        skinhelper_backgrounds = self.params.get("skinhelperbackgrounds",
                                                 "false") == "true"
        label, value = skinsettings.select_image(
            skinstring,
            allow_multi=allow_multi,
            windowheader=windowheader,
            resource_addon=resource_addon,
            skinhelper_backgrounds=skinhelper_backgrounds,
            current_value=current_value)
        if label:
            if skinshortcutsprop:
                # write value to skinshortcuts prop
                from skinshortcuts import set_skinshortcuts_property
                set_skinshortcuts_property(skinshortcutsprop, value, label)
            else:
                # write the values to skin strings
                if value.startswith("$INFO"):
                    # we got an dynamic image from window property
                    skinsettings.set_skin_variable(skinstring, value)
                    value = "$VAR[%s]" % skinstring
                skinstring = skinstring.encode("utf-8")
                label = label.encode("utf-8")
                xbmc.executebuiltin("Skin.SetString(%s.label,%s)" %
                                    (skinstring, label))
                xbmc.executebuiltin("Skin.SetString(%s.name,%s)" %
                                    (skinstring, label))
                xbmc.executebuiltin("Skin.SetString(%s,%s)" %
                                    (skinstring, value))
                xbmc.executebuiltin("Skin.SetString(%s.path,%s)" %
                                    (skinstring, value))
        del skinsettings

    def dialogok(self):
        '''helper to show an OK dialog with a message'''
        headertxt = self.params.get("header")
        bodytxt = self.params.get("message")
        if bodytxt.startswith(" "):
            bodytxt = bodytxt[1:]
        if headertxt.startswith(" "):
            headertxt = headertxt[1:]
        dialog = xbmcgui.Dialog()
        dialog.ok(heading=headertxt, line1=bodytxt)
        del dialog

    def dialogyesno(self):
        '''helper to show a YES/NO dialog with a message'''
        headertxt = self.params.get("header")
        bodytxt = self.params.get("message")
        yesactions = self.params.get("yesaction", "").split("|")
        noactions = self.params.get("noaction", "").split("|")
        if bodytxt.startswith(" "):
            bodytxt = bodytxt[1:]
        if headertxt.startswith(" "):
            headertxt = headertxt[1:]
        if xbmcgui.Dialog().yesno(heading=headertxt, line1=bodytxt):
            for action in yesactions:
                xbmc.executebuiltin(action.encode("utf-8"))
        else:
            for action in noactions:
                xbmc.executebuiltin(action.encode("utf-8"))

    def textviewer(self):
        '''helper to show a textviewer dialog with a message'''
        headertxt = self.params.get("header", "")
        bodytxt = self.params.get("message", "")
        if bodytxt.startswith(" "):
            bodytxt = bodytxt[1:]
        if headertxt.startswith(" "):
            headertxt = headertxt[1:]
        xbmcgui.Dialog().textviewer(headertxt, bodytxt)

    def fileexists(self):
        '''helper to let the skinner check if a file exists
        and write the outcome to a window prop or skinstring'''
        filename = self.params.get("file")
        skinstring = self.params.get("skinstring")
        windowprop = self.params.get("winprop")
        if xbmcvfs.exists(filename):
            if windowprop:
                self.win.setProperty(windowprop, "exists")
            if skinstring:
                xbmc.executebuiltin("Skin.SetString(%s,exists)" % skinstring)
        else:
            if windowprop:
                self.win.clearProperty(windowprop)
            if skinstring:
                xbmc.executebuiltin("Skin.Reset(%s)" % skinstring)

    def stripstring(self):
        '''helper to allow the skinner to strip a string and write results to a skin string'''
        splitchar = self.params.get("splitchar")
        if splitchar.upper() == "[SPACE]":
            splitchar = " "
        skinstring = self.params.get("string")
        if not skinstring:
            skinstring = self.params.get("skinstring")
        output = self.params.get("output")
        index = self.params.get("index", 0)
        skinstring = skinstring.split(splitchar)[int(index)]
        self.win.setProperty(output, skinstring)

    def getfilename(self, filename=""):
        '''helper to display a sanitized filename in the vidoeinfo dialog'''
        output = self.params.get("output")
        if not filename:
            filename = xbmc.getInfoLabel("ListItem.FileNameAndPath")
        if not filename:
            filename = xbmc.getInfoLabel("ListItem.FileName")
        if "filename=" in filename:
            url_params = dict(urlparse.parse_qsl(filename))
            filename = url_params.get("filename")
        self.win.setProperty(output, filename)

    def getplayerfilename(self):
        '''helper to parse the filename from a plugin (e.g. emby) filename'''
        filename = xbmc.getInfoLabel("Player.FileNameAndPath")
        if not filename:
            filename = xbmc.getInfoLabel("Player.FileName")
        self.getfilename(filename)

    def getpercentage(self):
        '''helper to calculate the percentage of 2 numbers and write results to a skinstring'''
        total = int(params.get("total"))
        count = int(params.get("count"))
        roundsteps = self.params.get("roundsteps")
        skinstring = self.params.get("skinstring")
        percentage = int(round((1.0 * count / total) * 100))
        if roundsteps:
            roundsteps = int(roundsteps)
            percentage = percentage + (roundsteps - percentage) % roundsteps
        xbmc.executebuiltin("Skin.SetString(%s,%s)" % (skinstring, percentage))

    def setresourceaddon(self):
        '''helper to let the user choose a resource addon and set that as skin string'''
        from resourceaddons import setresourceaddon
        addontype = self.params.get("addontype", "")
        skinstring = self.params.get("skinstring", "")
        setresourceaddon(addontype, skinstring)

    def checkresourceaddons(self):
        '''allow the skinner to perform a basic check if some required resource addons are available'''
        from resourceaddons import checkresourceaddons
        addonslist = self.params.get("addonslist", [])
        if addonslist:
            addonslist = addonslist.split("|")
        checkresourceaddons(addonslist)