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 __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 __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 __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 __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")
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
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
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
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
def searching(): form = Search() if form.validate_on_submit(): return SearchDB(form.state.data) return render_template("search.html", form=form)
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