示例#1
0
    def __init__(self):
        self.id = 'plugin.video.unified.search'
        self.addon = xbmcaddon.Addon(self.id)
        # self.icon = self.addon.getAddonInfo('icon')
        self.path = self.addon.getAddonInfo('path')
        self.language = self.addon.getLocalizedString

        self.debug = self.addon.getSetting("debug") == 'true'

        database_nc = xbmc.translatePath('special://database')
        try:
            database = os.path.normpath(database_nc.decode('utf-8'))
        except:
            database = os.path.normpath(database_nc)

        self.addons_dir = os.path.dirname(self.path)
        db_index = 27
        while db_index > 0:
            db_name = 'Addons%d.db' % db_index
            db_path = os.path.join(database, db_name)
            self.log("db_path - %s" % (db_path))
            db_index -= 1
            if xbmcvfs.exists(db_path):
                self.addon_db = db_path
                break

        self.supported_addons = self.get_supported_addons()

        self.result_db = ResultDB()
        self.search_db = SearchDB()
示例#2
0
    def __init__(self):
        self.id = 'plugin.video.unified.search'
        self.addon = xbmcaddon.Addon(self.id)
        # self.icon = self.addon.getAddonInfo('icon')
        self.path = self.addon.getAddonInfo('path')
        self.language = self.addon.getLocalizedString

        self.addons_dir = os.path.dirname(self.path)
        self.addon_db = os.path.join(
            os.path.dirname(os.path.dirname(self.path)),
            'userdata/Database/Addons16.db')

        self.supported_addons = self.get_supported_addons()

        self.result_db = ResultDB()
        self.search_db = SearchDB()

        self.debug = self.addon.getSetting("debug") == 'true'
示例#3
0
    def __init__(self):
        self.id = 'plugin.video.unified.search'
        self.addon = xbmcaddon.Addon(self.id)
        self.icon = self.addon.getAddonInfo('icon')
        self.path = self.addon.getAddonInfo('path')
        self.profile = self.addon.getAddonInfo('profile')
        self.language = self.addon.getLocalizedString

        self.xpath = sys.argv[0]
        self.handle = int(sys.argv[1])
        self.params = sys.argv[2]

        self.supported_addons = UnifiedSearch().get_supported_addons()
        self.result_db = ResultDB()
        self.search_db = SearchDB()

        self.latest_search_id = self.search_db.get_latest_search_id()
        self.search_id = self.latest_search_id if self.latest_search_id else 0
        self.debug = self.addon.getSetting("debug") == 'true'

        # Custom icons
        self.search_icon = os.path.join(self.path, 'resources/icons/search.png')
        self.folder_icon = os.path.join(self.path, 'resources/icons/folder.png')
        self.warning_icon = os.path.join(self.path, 'resources/icons/warning.png')
示例#4
0
    def __init__(self):
        self.id = "plugin.video.unified.search"
        self.addon = xbmcaddon.Addon(self.id)
        # self.icon = self.addon.getAddonInfo('icon')
        self.path = self.addon.getAddonInfo("path")
        self.language = self.addon.getLocalizedString

        self.addons_dir = os.path.dirname(self.path)
        self.addon_db = os.path.join(os.path.dirname(os.path.dirname(self.path)), "userdata/Database/Addons15.db")

        self.supported_addons = self.get_supported_addons()

        self.result_db = ResultDB()
        self.search_db = SearchDB()

        self.debug = self.addon.getSetting("debug") == "true"
示例#5
0
    def __init__(self):
        self.id = "plugin.video.unified.search"
        self.addon = xbmcaddon.Addon(self.id)
        self.icon = self.addon.getAddonInfo("icon")
        self.path = self.addon.getAddonInfo("path")
        self.profile = self.addon.getAddonInfo("profile")
        self.language = self.addon.getLocalizedString

        self.xpath = sys.argv[0]
        self.handle = int(sys.argv[1])
        self.params = sys.argv[2]

        self.supported_addons = UnifiedSearch().get_supported_addons()
        self.result_db = ResultDB()
        self.search_db = SearchDB()

        self.latest_search_id = self.search_db.get_latest_search_id()
        self.search_id = self.latest_search_id if self.latest_search_id else 0
        self.debug = self.addon.getSetting("debug") == "true"

        # Custom icons
        self.search_icon = os.path.join(self.path, "resources/icons/search.png")
        self.folder_icon = os.path.join(self.path, "resources/icons/folder.png")
        self.warning_icon = os.path.join(self.path, "resources/icons/warning.png")
示例#6
0
class UnifiedSearch:
    def __init__(self):
        self.id = "plugin.video.unified.search"
        self.addon = xbmcaddon.Addon(self.id)
        # self.icon = self.addon.getAddonInfo('icon')
        self.path = self.addon.getAddonInfo("path")
        self.language = self.addon.getLocalizedString

        self.addons_dir = os.path.dirname(self.path)
        self.addon_db = os.path.join(os.path.dirname(os.path.dirname(self.path)), "userdata/Database/Addons15.db")

        self.supported_addons = self.get_supported_addons()

        self.result_db = ResultDB()
        self.search_db = SearchDB()

        self.debug = self.addon.getSetting("debug") == "true"

    def collect(self, results):
        # INFO: Update counter and compare with a number of supported_addons
        search_id = self.search_db.get_latest_search_id()
        counter = self.search_db.update_counter(search_id)

        self.log("Search counter => %d" % (counter))
        # xbmc.sleep(100)

        if results:
            for result in results:
                if "is_playable" in result:
                    self.result_db.create(
                        search_id,
                        result["title"].lstrip(),
                        result["url"],
                        result["image"],
                        result["plugin"],
                        result["is_playable"],
                    )
                else:
                    self.result_db.create(
                        search_id, result["title"].lstrip(), result["url"], result["image"], result["plugin"]
                    )

            if len(self.supported_addons) == counter:
                self.log("ALL DONE => %s of %d done" % (counter, len(self.supported_addons)))
                self.notify("Search", "Done")

                # xbmc.executebuiltin('XBMC.ReplaceWindow(10025, %s, return)' % "plugin://%s/?mode=show&search_id=%d" % (self.id, search_id))
                xbmc.executebuiltin(
                    "Container.Update(%s)" % "plugin://%s/?mode=show&search_id=%d" % (self.id, search_id)
                )

            else:
                # self.log("Wait and do nothing => %s of %d done" % (counter, len(self.supported_addons)))
                return True

        else:
            if len(self.supported_addons) == counter:
                self.notify("Search", "Done")
                # INFO:  Fix for ERROR: Control 50 in window 10025 has been asked to focus, but it can't.
                xbmc.executebuiltin(
                    "Container.Update(%s)" % "plugin://%s/?mode=show&search_id=%d" % (self.id, search_id)
                )
            else:
                self.log("!!! Nothing found !!!")
                return True

    def get_supported_addons(self):
        disabled_addons = self.get_disabled_addons()
        supported_addons = []

        for addon in os.listdir(self.addons_dir):
            if (
                os.path.isdir(os.path.join(self.addons_dir, addon))
                and "plugin.video" in addon
                and addon not in disabled_addons
            ):
                try:
                    if xbmcaddon.Addon(addon).getSetting("unified_search") == "true":
                        supported_addons.append(addon)
                except Exception, e:
                    self.error("Exception in get_supported_addons")
                    continue

        return supported_addons
示例#7
0
class UnifiedSearch():
    def __init__(self):
        self.id = 'plugin.video.unified.search'
        self.addon = xbmcaddon.Addon(self.id)
        # self.icon = self.addon.getAddonInfo('icon')
        self.path = self.addon.getAddonInfo('path')
        self.language = self.addon.getLocalizedString

        self.debug = self.addon.getSetting("debug") == 'true'

        database_nc = xbmc.translatePath('special://database')
        try:
            database = os.path.normpath(database_nc.decode('utf-8'))
        except:
            database = os.path.normpath(database_nc)

        self.addons_dir = os.path.dirname(self.path)
        db_index = 27
        while db_index > 0:
            db_name = 'Addons%d.db' % db_index
            db_path = os.path.join(database, db_name)
            self.log("db_path - %s" % (db_path))
            db_index -= 1
            if xbmcvfs.exists(db_path):
                self.addon_db = db_path
                break

        self.supported_addons = self.get_supported_addons()

        self.result_db = ResultDB()
        self.search_db = SearchDB()

    def collect(self, results):
        # INFO: Update counter and compare with a number of supported_addons
        search_id = self.search_db.get_latest_search_id()

        if results:
            for result in results:
                if 'is_playable' in result:
                    self.result_db.create(search_id, result['title'].lstrip(),
                                          result['url'], result['image'],
                                          result['plugin'],
                                          result['is_playable'])
                else:
                    self.result_db.create(search_id, result['title'].lstrip(),
                                          result['url'], result['image'],
                                          result['plugin'])

#            if len(self.supported_addons) == counter:
#                self.log("ALL DONE => %s of %d done" % (counter, len(self.supported_addons)))
#                self.notify("Search", "Done")

# xbmc.executebuiltin('XBMC.ReplaceWindow(10025, %s, return)' % "plugin://%s/?mode=show&search_id=%d" % (self.id, search_id))
#                xbmc.executebuiltin('Container.Update(%s)' % "plugin://%s/?mode=show&search_id=%d" % (self.id, search_id))

#            else:
# self.log("Wait and do nothing => %s of %d done" % (counter, len(self.supported_addons)))
#                return True

#        else:
#            if len(self.supported_addons) == counter:
#                self.notify("Search", "Done")
# INFO:  Fix for ERROR: Control 50 in window 10025 has been asked to focus, but it can't.
#                xbmc.executebuiltin('Container.Update(%s)' % "plugin://%s/?mode=show&search_id=%d" % (self.id, search_id))
#            else:
#              self.log("!!! Nothing found !!!")
#              return True

        counter = self.search_db.update_counter(search_id)
        self.log("Search counter => %d" % (counter))

    def get_supported_addons(self):
        disabled_addons = self.get_disabled_addons()
        self.log("disabled_addons - %s" % (str(disabled_addons)))
        supported_addons = []

        for addon in os.listdir(self.addons_dir):
            if os.path.isdir(
                    os.path.join(self.addons_dir, addon)
            ) and 'plugin.video' in addon and addon not in disabled_addons:
                try:
                    if xbmcaddon.Addon(addon).getSetting(
                            'unified_search') == 'true':
                        supported_addons.append(addon)
                except Exception, e:
                    self.error("Exception in get_supported_addons")
                    continue

        return supported_addons
示例#8
0
class UnifiedSearchPlugin:
    def __init__(self):
        self.id = "plugin.video.unified.search"
        self.addon = xbmcaddon.Addon(self.id)
        self.icon = self.addon.getAddonInfo("icon")
        self.path = self.addon.getAddonInfo("path")
        self.profile = self.addon.getAddonInfo("profile")
        self.language = self.addon.getLocalizedString

        self.xpath = sys.argv[0]
        self.handle = int(sys.argv[1])
        self.params = sys.argv[2]

        self.supported_addons = UnifiedSearch().get_supported_addons()
        self.result_db = ResultDB()
        self.search_db = SearchDB()

        self.latest_search_id = self.search_db.get_latest_search_id()
        self.search_id = self.latest_search_id if self.latest_search_id else 0
        self.debug = self.addon.getSetting("debug") == "true"

        # Custom icons
        self.search_icon = os.path.join(self.path, "resources/icons/search.png")
        self.folder_icon = os.path.join(self.path, "resources/icons/folder.png")
        self.warning_icon = os.path.join(self.path, "resources/icons/warning.png")

    def main(self):
        self.log("Xpath: %s" % self.xpath)
        self.log("Addon: %s" % self.id)
        self.log("Handle: %d" % self.handle)
        self.log("Params: %s" % self.params)

        params = common.getParameters(self.params)
        mode = params["mode"] if "mode" in params else None
        keyword = params["keyword"] if "keyword" in params else None
        search_id = int(params["search_id"]) if ("search_id" in params and params["search_id"] != "None") else None

        url = params["url"] if "url" in params else None
        plugin = params["plugin"] if "plugin" in params else None
        playable = bool(params["playable"]) if "playable" in params else False

        if mode == "search":
            self.search(keyword)
        if mode == "show":
            self.show(search_id)
        if mode == "previous":
            self.previous_results()
        if mode == "activate":
            self.activate(plugin, url, playable)
        if mode == "reset":
            self.reset()
        elif mode is None:
            self.menu()

    # === XBMC VIEWS
    def menu(self):
        self.log("Supported add-ons: %s" % self.supported_addons)

        uri = self.xpath + "?mode=%s" % "search"
        item = xbmcgui.ListItem("[COLOR=FF00FF00]%s[/COLOR]" % self.language(1000), iconImage=self.search_icon)
        xbmcplugin.addDirectoryItem(self.handle, uri, item, True)

        item = xbmcgui.ListItem("%s" % self.language(1001), iconImage=self.folder_icon)
        xbmcplugin.addDirectoryItem(self.handle, "%s?mode=show&search_id=%s" % (self.xpath, self.search_id), item, True)

        item = xbmcgui.ListItem("%s" % self.language(1002), iconImage=self.folder_icon)
        xbmcplugin.addDirectoryItem(self.handle, "%s?mode=previous" % self.xpath, item, True)

        item = xbmcgui.ListItem("[COLOR=FFFF4000]%s[/COLOR]" % self.language(1003), iconImage=self.warning_icon)
        xbmcplugin.addDirectoryItem(self.handle, self.xpath + "?mode=reset", item, False)

        xbmc.executebuiltin("Container.SetViewMode(50)")
        xbmcplugin.endOfDirectory(self.handle, True)

    def search(self, keyword):
        keyword = self.get_user_input()

        if keyword:
            self.log("Call other add-ons and pass keyword: %s" % keyword)

            # INFO: Generate new search id and save it
            self.search_id = self.search_db.new(keyword)
            keyword = translit.eng(keyword) if self.isCyrillic(keyword) else keyword

            for i, plugin in enumerate(self.supported_addons):
                script = "special://home/addons/%s/default.py" % plugin
                xbmc.executebuiltin(
                    "XBMC.RunScript(%s, %d, mode=search&keyword=%s&unified=True)" % (script, self.handle, keyword),
                    False,
                )

            # INFO: None means show please wait ...
            # self.show(None)

            # print len(self.supported_addons)
            self.notify(self.language(1000).encode("utf-8"), self.language(2000).encode("utf-8"))
            # xbmcplugin.endOfDirectory(self.handle, False)

    def show(self, search_id):
        self.log("Show results on separate page for search_id")
        results = self.result_db.find_by_search_id(search_id) if search_id else []

        if results:
            for i, item in enumerate(results):
                image = item["image"] if item["image"] else self.icon

                if item["is_playable"]:
                    uri = "%s?mode=activate&plugin=%s&url=%s&playable=True" % (self.xpath, item["plugin"], item["url"])
                    item = xbmcgui.ListItem(
                        "%s (%s)" % (item["title"], item["plugin"].replace("plugin.video.", "")), thumbnailImage=image
                    )
                    xbmcplugin.addDirectoryItem(self.handle, uri, item, False)
                else:
                    uri = "%s?mode=activate&plugin=%s&url=%s" % (self.xpath, item["plugin"], item["url"])
                    item = xbmcgui.ListItem(
                        "%s (%s)" % (item["title"], item["plugin"].replace("plugin.video.", "")), thumbnailImage=image
                    )
                    xbmcplugin.addDirectoryItem(self.handle, uri, item, False)
        else:
            if search_id or search_id == 0:
                item = xbmcgui.ListItem("[COLOR=FFFF4000]%s[/COLOR]" % self.language(2001))
                item.setProperty("IsPlayable", "false")
                xbmcplugin.addDirectoryItem(self.handle, "", item, False)
            else:
                item = xbmcgui.ListItem(self.language(2000))
                item.setProperty("IsPlayable", "false")
                xbmcplugin.addDirectoryItem(self.handle, "", item, False)

        xbmc.executebuiltin("Container.SetViewMode(50)")
        xbmcplugin.endOfDirectory(self.handle, True)

    def previous_results(self):
        self.log("Show search result")
        search_results = self.search_db.all()

        if search_results:
            for i, result in enumerate(search_results):
                uri = "%s?mode=show&search_id=%d" % (self.xpath, result["id"])
                item = xbmcgui.ListItem(
                    "%02d. %s [%d]" % (result["id"], translit.rus(result["keyword"]), result["counter"]),
                    thumbnailImage=self.icon,
                )
                xbmcplugin.addDirectoryItem(self.handle, uri, item, True)

        else:
            item = xbmcgui.ListItem("[COLOR=FFFF4000]%s[/COLOR]" % self.language(2001))
            item.setProperty("IsPlayable", "false")
            xbmcplugin.addDirectoryItem(self.handle, "", item, False)

        xbmc.executebuiltin("Container.SetViewMode(50)")
        xbmcplugin.endOfDirectory(self.handle, True)

    def activate(self, plugin, url, playable):
        self.log("Playable %r %s => %s" % (plugin, url, playable))
        window = "plugin://%s/?mode=show&url=%s" % (plugin, url)

        if playable:
            xbmc.Player().play(window)
            xbmcplugin.endOfDirectory(self.handle, True)
        else:
            xbmc.executebuiltin("Container.Update(%s)" % window)

    def reset(self):
        self.result_db.drop()
        self.search_db.drop()
        xbmc.executebuiltin("Container.refresh()")

    # === HELPERS
    def get_user_input(self):
        kbd = xbmc.Keyboard()
        kbd.setDefault("")
        kbd.setHeading(self.language(1000))
        kbd.doModal()
        keyword = None

        if kbd.isConfirmed():
            keyword = kbd.getText()

        return keyword

    def log(self, message):
        if self.debug:
            print "=== %s: %s" % ("UnifiedSearch::Plugin", message)

    def error(self, message):
        print "%s ERROR: %s" % (self.id, message)

    def notify(self, header, msg):
        xbmc.executebuiltin("Notification(%s,%s,%s,%s)" % ("UnifiedSearch", msg, "30000", self.icon))

    def isCyrillic(self, keyword):
        if not re.findall(u"[\u0400-\u0500]+", keyword):
            return False
        else:
            return True
示例#9
0
class UnifiedSearch():
    def __init__(self):
        self.id = 'plugin.video.unified.search'
        self.addon = xbmcaddon.Addon(self.id)
        # self.icon = self.addon.getAddonInfo('icon')
        self.path = self.addon.getAddonInfo('path')
        self.language = self.addon.getLocalizedString

        self.addons_dir = os.path.dirname(self.path)
        self.addon_db = os.path.join(
            os.path.dirname(os.path.dirname(self.path)),
            'userdata/Database/Addons16.db')

        self.supported_addons = self.get_supported_addons()

        self.result_db = ResultDB()
        self.search_db = SearchDB()

        self.debug = self.addon.getSetting("debug") == 'true'

    def collect(self, results):
        # INFO: Update counter and compare with a number of supported_addons
        search_id = self.search_db.get_latest_search_id()
        counter = self.search_db.update_counter(search_id)

        self.log("Search counter => %d" % (counter))
        # xbmc.sleep(100)

        if results:
            for result in results:
                if 'is_playable' in result:
                    self.result_db.create(search_id, result['title'].lstrip(),
                                          result['url'], result['image'],
                                          result['plugin'],
                                          result['is_playable'])
                else:
                    self.result_db.create(search_id, result['title'].lstrip(),
                                          result['url'], result['image'],
                                          result['plugin'])

            if len(self.supported_addons) == counter:
                self.log("ALL DONE => %s of %d done" %
                         (counter, len(self.supported_addons)))
                self.notify("Search", "Done")

                # xbmc.executebuiltin('XBMC.ReplaceWindow(10025, %s, return)' % "plugin://%s/?mode=show&search_id=%d" % (self.id, search_id))
                xbmc.executebuiltin('Container.Update(%s)' %
                                    "plugin://%s/?mode=show&search_id=%d" %
                                    (self.id, search_id))

            else:
                # self.log("Wait and do nothing => %s of %d done" % (counter, len(self.supported_addons)))
                return True

        else:
            if len(self.supported_addons) == counter:
                self.notify("Search", "Done")
                # INFO:  Fix for ERROR: Control 50 in window 10025 has been asked to focus, but it can't.
                xbmc.executebuiltin('Container.Update(%s)' %
                                    "plugin://%s/?mode=show&search_id=%d" %
                                    (self.id, search_id))
            else:
                self.log("!!! Nothing found !!!")
                return True

    def get_supported_addons(self):
        disabled_addons = self.get_disabled_addons()
        supported_addons = []

        for addon in os.listdir(self.addons_dir):
            if os.path.isdir(
                    os.path.join(self.addons_dir, addon)
            ) and 'plugin.video' in addon and addon not in disabled_addons:
                try:
                    if xbmcaddon.Addon(addon).getSetting(
                            'unified_search') == 'true':
                        supported_addons.append(addon)
                except Exception, e:
                    self.error("Exception in get_supported_addons")
                    continue

        return supported_addons
示例#10
0
def searching():
    form = Search()
    if form.validate_on_submit():
        return SearchDB(form.state.data)
    return render_template("search.html", form=form)
示例#11
0
class UnifiedSearchPlugin():
    def __init__(self):
        self.id = 'plugin.video.unified.search'
        self.addon = xbmcaddon.Addon(self.id)
        self.icon = self.addon.getAddonInfo('icon')
        self.path = self.addon.getAddonInfo('path')
        self.profile = self.addon.getAddonInfo('profile')
        self.language = self.addon.getLocalizedString

        self.xpath = sys.argv[0]
        self.handle = int(sys.argv[1])
        self.params = sys.argv[2]

        self.supported_addons = UnifiedSearch().get_supported_addons()
        self.result_db = ResultDB()
        self.search_db = SearchDB()

        self.latest_search_id = self.search_db.get_latest_search_id()
        self.search_id = self.latest_search_id if self.latest_search_id else 0
        self.debug = self.addon.getSetting("debug") == 'true'

        # Custom icons
        self.search_icon = os.path.join(self.path, 'resources/icons/search.png')
        self.folder_icon = os.path.join(self.path, 'resources/icons/folder.png')
        self.warning_icon = os.path.join(self.path, 'resources/icons/warning.png')

    def main(self):
        self.log("Xpath: %s" % self.xpath)
        self.log("Addon: %s"  % self.id)
        self.log("Handle: %d" % self.handle)
        self.log("Params: %s" % self.params)

        params = common.getParameters(self.params)
        mode = params['mode'] if 'mode' in params else None
        keyword = params['keyword'] if 'keyword' in params else None
        search_id = int(params['search_id']) if('search_id' in params and params['search_id'] != 'None') else None

        url = params['url'] if 'url' in params else None
        plugin = params['plugin'] if 'plugin' in params else None
        playable = bool(params['playable']) if 'playable' in params else False

        if mode == 'search':
            self.search(keyword)
        if mode == 'show':
            self.show(search_id)
        if mode == 'previous':
            self.previous_results()
        if mode == 'activate':
            self.activate(plugin, url, playable)
        if mode == 'reset':
            self.reset()
        elif mode is None:
            self.menu()

    # === XBMC VIEWS
    def menu(self):
        self.log("Supported add-ons: %s" % self.supported_addons)

        uri = self.xpath + '?mode=%s' % "search"
        item = xbmcgui.ListItem("[COLOR=FF00FF00]%s[/COLOR]" % self.language(1000), iconImage=self.search_icon)
        xbmcplugin.addDirectoryItem(self.handle, uri, item, True)

        item = xbmcgui.ListItem("%s" % self.language(1001), iconImage=self.folder_icon)
        xbmcplugin.addDirectoryItem(self.handle, "%s?mode=show&search_id=%s" % (self.xpath, self.search_id), item, True)

        item = xbmcgui.ListItem("%s" % self.language(1002), iconImage=self.folder_icon)
        xbmcplugin.addDirectoryItem(self.handle, "%s?mode=previous" % self.xpath, item, True)

        item = xbmcgui.ListItem("[COLOR=FFFF4000]%s[/COLOR]" % self.language(1003), iconImage=self.warning_icon)
        xbmcplugin.addDirectoryItem(self.handle, self.xpath + '?mode=reset', item, False)

        xbmc.executebuiltin('Container.SetViewMode(50)')
        xbmcplugin.endOfDirectory(self.handle, True)

    def search(self, keyword):
        keyword = self.get_user_input()

        if keyword:
            self.log("Call other add-ons and pass keyword: %s" % keyword)

            # INFO: Generate new search id and save it
            self.search_id = self.search_db.new(keyword)
            keyword = translit.eng(keyword) if self.isCyrillic(keyword) else keyword

            for i, plugin in enumerate(self.supported_addons):
                script = "special://home/addons/%s/default.py" % plugin
                xbmc.executebuiltin("XBMC.RunScript(%s, %d, mode=search&keyword=%s&unified=True)" % (script, self.handle, keyword), False)

            # INFO: None means show please wait ...
            # self.show(None)

            # print len(self.supported_addons)
            self.notify(self.language(1000).encode('utf-8'), self.language(2000).encode('utf-8'))            
            # xbmcplugin.endOfDirectory(self.handle, False)

    def show(self, search_id):
        self.log("Show results on separate page for search_id")
        results = self.result_db.find_by_search_id(search_id) if search_id else []

        if results:
            for i, item in enumerate(results):
                image = item['image'] if item['image']  else self.icon

                if item['is_playable']:
                    uri = '%s?mode=activate&plugin=%s&url=%s&playable=True' % (self.xpath, item['plugin'], item['url'])
                    item = xbmcgui.ListItem("%s (%s)" % (item['title'], item['plugin'].replace('plugin.video.', '')), thumbnailImage=image)
                    xbmcplugin.addDirectoryItem(self.handle, uri, item, False)
                else:
                    uri = '%s?mode=activate&plugin=%s&url=%s' % (self.xpath, item['plugin'], item['url'])
                    item = xbmcgui.ListItem("%s (%s)" % (item['title'], item['plugin'].replace('plugin.video.', '')), thumbnailImage=image)
                    xbmcplugin.addDirectoryItem(self.handle, uri, item, False)
        else:
            if search_id or search_id == 0:
                item = xbmcgui.ListItem("[COLOR=FFFF4000]%s[/COLOR]" % self.language(2001))
                item.setProperty('IsPlayable', 'false')
                xbmcplugin.addDirectoryItem(self.handle, '', item, False)                
            else:
                item = xbmcgui.ListItem(self.language(2000))
                item.setProperty('IsPlayable', 'false')
                xbmcplugin.addDirectoryItem(self.handle, '', item, False)

        xbmc.executebuiltin('Container.SetViewMode(50)')
        xbmcplugin.endOfDirectory(self.handle, True)

    def previous_results(self):
        self.log("Show search result")
        search_results = self.search_db.all()
        
        if search_results:
            for i, result in enumerate(search_results):
                uri = '%s?mode=show&search_id=%d' % (self.xpath, result['id'])
                item = xbmcgui.ListItem("%02d. %s [%d]" % (result['id'], translit.rus(result['keyword']), result['counter']), thumbnailImage=self.icon)
                xbmcplugin.addDirectoryItem(self.handle, uri, item, True)

        else:
            item = xbmcgui.ListItem("[COLOR=FFFF4000]%s[/COLOR]" % self.language(2001))
            item.setProperty('IsPlayable', 'false')
            xbmcplugin.addDirectoryItem(self.handle, '', item, False)

        xbmc.executebuiltin('Container.SetViewMode(50)')
        xbmcplugin.endOfDirectory(self.handle, True)

    def activate(self, plugin, url, playable):
        self.log("Playable %r %s => %s" % (plugin, url, playable))
        window = "plugin://%s/?mode=show&url=%s" % (plugin, url)

        if playable:
            xbmc.Player().play(window)
            xbmcplugin.endOfDirectory(self.handle, True)
        else:
            xbmc.executebuiltin('Container.Update(%s)' % window)

    def reset(self):
        self.result_db.drop()
        self.search_db.drop()
        xbmc.executebuiltin("Container.refresh()")

    # === HELPERS
    def get_user_input(self):
        kbd = xbmc.Keyboard()
        kbd.setDefault('')
        kbd.setHeading(self.language(1000))
        kbd.doModal()
        keyword = None

        if kbd.isConfirmed():
            keyword = kbd.getText()

        return keyword

    def log(self, message):
        if self.debug:
            print "=== %s: %s" % ("UnifiedSearch::Plugin", message)

    def error(self, message):
        print "%s ERROR: %s" % (self.id, message)

    def notify(self, header, msg):
        xbmc.executebuiltin("Notification(%s,%s,%s,%s)" % ('UnifiedSearch', msg, '30000', self.icon))

    def isCyrillic(self, keyword):
        if not re.findall(u"[\u0400-\u0500]+", keyword):
            return False
        else:
            return True