def get_quasar_binary(): binary = "quasar" + (PLATFORM["os"] == "windows" and ".exe" or "") platform = PLATFORM.copy() if platform["os"] == "darwin": # 64 bits anyway on Darwin platform["arch"] = "x64" # elif platform["os"] == "windows": # 32 bits anyway on Windows # platform["arch"] = "x86" binary_dir = os.path.join(ADDON.getAddonInfo("path"), "resources", "bin", "%(os)s_%(arch)s" % platform) if platform["os"] == "android": binary_dir = binary_dir.replace("/storage/emulated/0", "/storage/emulated/legacy") app_id = android_get_current_appid() xbmc_data_path = os.path.join("/data", "data", app_id) dest_binary_dir = os.path.join(xbmc_data_path, "files", ADDON_ID, "bin", "%(os)s_%(arch)s" % platform) else: dest_binary_dir = os.path.join(xbmc.translatePath(ADDON.getAddonInfo("profile")), "bin", "%(os)s_%(arch)s" % platform) try: binary_dir = binary_dir.decode("latin1") dest_binary_dir = dest_binary_dir.decode("latin1") except UnicodeEncodeError: log.info("Unable to decode: binary_dir=%s dest_binary_dir=%s" % (repr(binary_dir), repr(dest_binary_dir))) binary_path = os.path.join(binary_dir, binary) dest_binary_path = os.path.join(dest_binary_dir, binary) if not os.path.exists(dest_binary_path) or get_quasard_checksum(dest_binary_path) != get_quasard_checksum(binary_path): log.info("Updating quasar daemon...") try: os.makedirs(dest_binary_dir) except OSError: pass try: shutil.rmtree(dest_binary_dir) except: pass shutil.copytree(binary_dir, dest_binary_dir) # Clean stale files in the directory, as this can cause headaches on # Android when they are unreachable dest_files = set(os.listdir(dest_binary_dir)) orig_files = set(os.listdir(binary_dir)) log.info("Deleting stale files %s" % (dest_files - orig_files)) for file_ in (dest_files - orig_files): path = os.path.join(dest_binary_dir, file_) if os.path.isdir(path): shutil.rmtree(path) else: os.remove(path) return dest_binary_dir, ensure_exec_perms(dest_binary_path)
def GetAddonInfo(self): info = {} for key in ("author", "changelog", "description", "disclaimer", "fanart", "icon", "id", "name", "path", "profile", "stars", "summary", "type", "version"): info[key] = ADDON.getAddonInfo(key) return info
def GetAddonInfo(self): info = {} for key in ("author", "changelog", "description", "disclaimer", "fanart", "icon", "id", "name", "path", "profile", "stars", "summary", "type", "version"): info[key] = ADDON.getAddonInfo(key) return info
def run(url_suffix=""): if not os.path.exists(os.path.join(xbmc.translatePath(ADDON.getAddonInfo("path")), ".firstrun")): notify(ADDON.getLocalizedString(30101).encode('utf-8')) system_information() return socket.setdefaulttimeout(300) urllib2.install_opener(urllib2.build_opener(NoRedirectHandler())) url = sys.argv[0].replace("plugin://%s" % ADDON_ID, QUASARD_HOST + url_suffix) + sys.argv[2] log.info("Requesting %s" % url) try: data = _json(url) except Exception as e: map(log.error, traceback.format_exc().split("\n")) notify("%s: %s" % (ADDON.getLocalizedString(30225).encode('utf-8'), e)) return if not data: return if data["content_type"]: xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_UNSORTED) xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE) xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_DATE) xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_GENRE) xbmcplugin.setContent(HANDLE, data["content_type"]) listitems = range(len(data["items"])) for i, item in enumerate(data["items"]): # Translate labels if item["label"][0:8] == "LOCALIZE": item["label"] = GetLocalizedString(item["label"]) if item["label2"][0:8] == "LOCALIZE": item["label2"] = GetLocalizedString(item["label2"]) listItem = xbmcgui.ListItem(label=item["label"], label2=item["label2"], iconImage=item["icon"], thumbnailImage=item["thumbnail"]) if item.get("info"): listItem.setInfo("video", item["info"]) if item.get("stream_info"): for type_, values in item["stream_info"].items(): listItem.addStreamInfo(type_, values) if item.get("art"): listItem.setArt(item["art"]) if item.get("context_menu"): # Translate context menus for m, menu in enumerate(item["context_menu"]): if menu[0][0:8] == "LOCALIZE": menu[0] = GetLocalizedString(menu[0]) listItem.addContextMenuItems(item["context_menu"]) listItem.setProperty("isPlayable", item["is_playable"] and "true" or "false") if item.get("properties"): for k, v in item["properties"].items(): listItem.setProperty(k, v) listitems[i] = (item["path"], listItem, not item["is_playable"]) xbmcplugin.addDirectoryItems(HANDLE, listitems, totalItems=len(listitems)) xbmcplugin.endOfDirectory(HANDLE, succeeded=True, updateListing=False, cacheToDisc=True)
def GetAddonInfo(self): info = {} for key in ("author", "changelog", "description", "disclaimer", "fanart", "icon", "id", "name", "profile", "stars", "summary", "type", "version"): info[key] = ADDON.getAddonInfo(key) info['path'] = ADDON_PATH info['home'] = "special://home" info['xbmc'] = "special://xbmc" return info
def GetAllSettings(self): settings = [] settingsFile = os.path.join(ADDON.getAddonInfo("path"), "resources", "settings.xml") with open(settingsFile, 'r') as settingsStr: fileContent = settingsStr.read() keyType = re.findall(r".*id=\"(\w+)\".*type=\"(\w+)\"", fileContent) for key, _type in keyType: settings.append({ "key": key, "type": _type, "value": ADDON.getSetting(key) }) return settings
def GetAllSettings(self): settings = [] settingsFile = os.path.join(ADDON.getAddonInfo("path"), "resources", "settings.xml") with open(settingsFile, 'r') as settingsStr: fileContent = settingsStr.read() keyType = re.findall(r".*id=\"(\w+)\".*type=\"(\w+)\"", fileContent) for key, _type in keyType: settings.append({ "key": key, "type": _type, "value": ADDON.getSetting(key) }) return settings
def get_quasar_binary(): binary = "quasar" + (PLATFORM["os"] == "windows" and ".exe" or "") binary_dir = os.path.join(ADDON.getAddonInfo("path"), "resources", "bin", "%(os)s_%(arch)s" % PLATFORM) if PLATFORM["os"] == "android": log.info("Detected binary folder: %s" % binary_dir) binary_dir_legacy = binary_dir.replace("/storage/emulated/0", "/storage/emulated/legacy") if os.path.exists(binary_dir_legacy): binary_dir = binary_dir_legacy log.info("Using binary folder: %s" % binary_dir) app_id = android_get_current_appid() xbmc_data_path = os.path.join("/data", "data", app_id) dest_binary_dir = os.path.join(xbmc_data_path, "files", ADDON_ID, "bin", "%(os)s_%(arch)s" % PLATFORM) else: dest_binary_dir = os.path.join( xbmc.translatePath(ADDON.getAddonInfo("profile")), "bin", "%(os)s_%(arch)s" % PLATFORM) try: binary_dir = binary_dir.decode("latin1") dest_binary_dir = dest_binary_dir.decode("latin1") except UnicodeEncodeError: log.info("Unable to decode: binary_dir=%s dest_binary_dir=%s" % (repr(binary_dir), repr(dest_binary_dir))) binary_path = os.path.join(binary_dir, binary) dest_binary_path = os.path.join(dest_binary_dir, binary) if not os.path.exists(binary_path): notify(ADDON.getLocalizedString(30103).encode('utf-8')) system_information() return False, False if not os.path.exists(dest_binary_path) or get_quasard_checksum( dest_binary_path) != get_quasard_checksum(binary_path): log.info("Updating quasar daemon...") try: os.makedirs(dest_binary_dir) except OSError: pass try: shutil.rmtree(dest_binary_dir) except OSError as e: log.error("Unable to remove destination path for update: %s" % e) system_information() pass try: shutil.copytree(binary_dir, dest_binary_dir) except OSError as e: log.error("Unable to copy to destination path for update: %s" % e) notify(ADDON.getLocalizedString(30227).encode('utf-8')) system_information() pass # Clean stale files in the directory, as this can cause headaches on # Android when they are unreachable dest_files = set(os.listdir(dest_binary_dir)) orig_files = set(os.listdir(binary_dir)) log.info("Deleting stale files %s" % (dest_files - orig_files)) for file_ in (dest_files - orig_files): path = os.path.join(dest_binary_dir, file_) if os.path.isdir(path): shutil.rmtree(path) else: os.remove(path) return dest_binary_dir, ensure_exec_perms(dest_binary_path)
def get_quasar_binary(): binary = "quasar" + (PLATFORM["os"] == "windows" and ".exe" or "") log.info("PLATFORM: %s" % str(PLATFORM)) binary_dir = os.path.join(ADDON_PATH, "resources", "bin", "%(os)s_%(arch)s" % PLATFORM) if PLATFORM["os"] == "android": log.info("Detected binary folder: %s" % binary_dir) binary_dir_legacy = binary_dir.replace("/storage/emulated/0", "/storage/emulated/legacy") if os.path.exists(binary_dir_legacy): binary_dir = binary_dir_legacy log.info("Using binary folder: %s" % binary_dir) app_id = android_get_current_appid() xbmc_data_path = os.path.join("/data", "data", app_id) try: #Test if there is any permisions problem f = open(os.path.join(xbmc_data_path, "test.txt"), "wb") f.write("test") f.close() os.remove(os.path.join(xbmc_data_path, "test.txt")) except: xbmc_data_path = '' if not os.path.exists(xbmc_data_path): log.info("%s path does not exist, so using %s as xbmc_data_path" % (xbmc_data_path, xbmc.translatePath("special://xbmcbin/"))) xbmc_data_path = xbmc.translatePath("special://xbmcbin/") try: #Test if there is any permisions problem f = open(os.path.join(xbmc_data_path, "test.txt"), "wb") f.write("test") f.close() os.remove(os.path.join(xbmc_data_path, "test.txt")) except: xbmc_data_path = '' if not os.path.exists(xbmc_data_path): log.info("%s path does not exist, so using %s as xbmc_data_path" % (xbmc_data_path, xbmc.translatePath("special://masterprofile/"))) xbmc_data_path = xbmc.translatePath("special://masterprofile/") dest_binary_dir = os.path.join(xbmc_data_path, "files", ADDON_ID, "bin", "%(os)s_%(arch)s" % PLATFORM) else: dest_binary_dir = os.path.join(xbmc.translatePath(ADDON.getAddonInfo("profile")).decode('utf-8'), "bin", "%(os)s_%(arch)s" % PLATFORM) log.info("Using destination binary folder: %s" % dest_binary_dir) binary_path = os.path.join(binary_dir, binary) dest_binary_path = os.path.join(dest_binary_dir, binary) if not os.path.exists(binary_path): notify((getLocalizedString(30103) + " %(os)s_%(arch)s" % PLATFORM), time=7000) system_information() try: log.info("Source directory (%s):\n%s" % (binary_dir, os.listdir(os.path.join(binary_dir, "..")))) log.info("Destination directory (%s):\n%s" % (dest_binary_dir, os.listdir(os.path.join(dest_binary_dir, "..")))) except Exception: pass return False, False if os.path.isdir(dest_binary_path): log.warning("Destination path is a directory, expected previous binary file, removing...") try: shutil.rmtree(dest_binary_path) except Exception as e: log.error("Unable to remove destination path for update: %s" % e) system_information() return False, False if not os.path.exists(dest_binary_path) or get_quasard_checksum(dest_binary_path) != get_quasard_checksum(binary_path): log.info("Updating quasar daemon...") try: os.makedirs(dest_binary_dir) except OSError: pass try: shutil.rmtree(dest_binary_dir) except Exception as e: log.error("Unable to remove destination path for update: %s" % e) system_information() pass try: shutil.copytree(binary_dir, dest_binary_dir) except Exception as e: log.error("Unable to copy to destination path for update: %s" % e) system_information() return False, False # Clean stale files in the directory, as this can cause headaches on # Android when they are unreachable dest_files = set(os.listdir(dest_binary_dir)) orig_files = set(os.listdir(binary_dir)) log.info("Deleting stale files %s" % (dest_files - orig_files)) for file_ in (dest_files - orig_files): path = os.path.join(dest_binary_dir, file_) if os.path.isdir(path): shutil.rmtree(path) else: os.remove(path) return dest_binary_dir, ensure_exec_perms(dest_binary_path)
def start_quasard(**kwargs): jsonrpc_failures = 0 while jsonrpc_enabled() is False: jsonrpc_failures += 1 log.warning("Unable to connect to Kodi's JSON-RPC service, retrying...") if jsonrpc_failures > 1: time.sleep(5) if not jsonrpc_enabled(notify=True): log.error("Unable to reach Kodi's JSON-RPC service, aborting...") return False else: break time.sleep(3) quasar_dir, quasar_binary = get_quasar_binary() if quasar_dir is False or quasar_binary is False: return False lockfile = os.path.join(ADDON_PATH, ".lockfile") if os.path.exists(lockfile): log.warning("Existing process found from lockfile, killing...") try: with open(lockfile) as lf: pid = int(lf.read().rstrip(" \t\r\n\0")) os.kill(pid, 9) except Exception as e: log.error(repr(e)) if PLATFORM["os"] == "windows": log.warning("Removing library.db.lock file...") try: library_lockfile = os.path.join(xbmc.translatePath(ADDON.getAddonInfo("profile")).decode('utf-8'), "library.db.lock") os.remove(library_lockfile) except Exception as e: log.error(repr(e)) SW_HIDE = 0 STARTF_USESHOWWINDOW = 1 args = [quasar_binary] kwargs["cwd"] = quasar_dir if PLATFORM["os"] == "windows": args[0] = getWindowsShortPath(quasar_binary) kwargs["cwd"] = getWindowsShortPath(quasar_dir) si = subprocess.STARTUPINFO() si.dwFlags = STARTF_USESHOWWINDOW si.wShowWindow = SW_HIDE clear_fd_inherit_flags() kwargs["startupinfo"] = si else: env = os.environ.copy() env["LD_LIBRARY_PATH"] = "%s:%s" % (quasar_dir, env.get("LD_LIBRARY_PATH", "")) kwargs["env"] = env kwargs["close_fds"] = True wait_counter = 1 while xbmc.getCondVisibility('Window.IsVisible(10140)') or xbmc.getCondVisibility('Window.IsActive(10140)'): if wait_counter == 1: log.info('Add-on settings currently opened, waiting before starting...') if wait_counter > 300: break time.sleep(1) wait_counter += 1 return subprocess.Popen(args, **kwargs)
def get_quasar_binary(): binary = "quasar" + (PLATFORM["os"] == "windows" and ".exe" or "") binary_dir = os.path.join(ADDON.getAddonInfo("path"), "resources", "bin", "%(os)s_%(arch)s" % PLATFORM) if PLATFORM["os"] == "android": log.info("Detected binary folder: %s" % binary_dir) binary_dir_legacy = binary_dir.replace("/storage/emulated/0", "/storage/emulated/legacy") if os.path.exists(binary_dir_legacy): binary_dir = binary_dir_legacy log.info("Using binary folder: %s" % binary_dir) app_id = android_get_current_appid() xbmc_data_path = os.path.join("/data", "data", app_id) dest_binary_dir = os.path.join(xbmc_data_path, "files", ADDON_ID, "bin", "%(os)s_%(arch)s" % PLATFORM) else: dest_binary_dir = os.path.join(xbmc.translatePath(ADDON.getAddonInfo("profile")), "bin", "%(os)s_%(arch)s" % PLATFORM) try: binary_dir = binary_dir.decode("latin1") dest_binary_dir = dest_binary_dir.decode("latin1") except UnicodeEncodeError: log.info("Unable to decode: binary_dir=%s dest_binary_dir=%s" % (repr(binary_dir), repr(dest_binary_dir))) binary_path = os.path.join(binary_dir, binary) dest_binary_path = os.path.join(dest_binary_dir, binary) if not os.path.exists(binary_path): notify(ADDON.getLocalizedString(30103).encode('utf-8')) system_information() return False, False if not os.path.exists(dest_binary_path) or get_quasard_checksum(dest_binary_path) != get_quasard_checksum(binary_path): log.info("Updating quasar daemon...") try: os.makedirs(dest_binary_dir) except OSError: pass try: shutil.rmtree(dest_binary_dir) except OSError as e: log.error("Unable to remove destination path for update: %s" % e) system_information() pass try: shutil.copytree(binary_dir, dest_binary_dir) except OSError as e: log.error("Unable to copy to destination path for update: %s" % e) notify(ADDON.getLocalizedString(30227).encode('utf-8')) system_information() pass # Clean stale files in the directory, as this can cause headaches on # Android when they are unreachable dest_files = set(os.listdir(dest_binary_dir)) orig_files = set(os.listdir(binary_dir)) log.info("Deleting stale files %s" % (dest_files - orig_files)) for file_ in (dest_files - orig_files): path = os.path.join(dest_binary_dir, file_) if os.path.isdir(path): shutil.rmtree(path) else: os.remove(path) return dest_binary_dir, ensure_exec_perms(dest_binary_path)
def start_quasard(**kwargs): jsonrpc_failures = 0 while jsonrpc_enabled() is False: jsonrpc_failures += 1 log.warning("Unable to connect to Kodi's JSON-RPC service, retrying...") if jsonrpc_failures > 1: time.sleep(5) if not jsonrpc_enabled(notify=True): log.error("Unable to reach Kodi's JSON-RPC service, aborting...") return False else: break time.sleep(3) quasar_dir, quasar_binary = get_quasar_binary() if quasar_dir is False or quasar_binary is False: return False lockfile = os.path.join(ADDON_PATH, ".lockfile") if os.path.exists(lockfile): log.warning("Existing process found from lockfile, killing...") try: with open(lockfile) as lf: pid = int(lf.read().rstrip(" \t\r\n\0")) os.kill(pid, 9) except Exception as e: log.error(repr(e)) if PLATFORM["os"] == "windows": log.warning("Removing library.db.lock file...") try: library_lockfile = os.path.join(xbmc.translatePath(ADDON.getAddonInfo("profile")).decode('utf-8'), "library.db.lock") os.remove(library_lockfile) except Exception as e: log.error(repr(e)) SW_HIDE = 0 STARTF_USESHOWWINDOW = 1 args = [quasar_binary] kwargs["cwd"] = quasar_dir if PLATFORM["os"] == "windows": args[0] = getWindowsShortPath(quasar_binary) kwargs["cwd"] = getWindowsShortPath(quasar_dir) si = subprocess.STARTUPINFO() si.dwFlags = STARTF_USESHOWWINDOW si.wShowWindow = SW_HIDE clear_fd_inherit_flags() kwargs["startupinfo"] = si else: env = os.environ.copy() env["LD_LIBRARY_PATH"] = "%s:%s" % (quasar_dir, env.get("LD_LIBRARY_PATH", "")) kwargs["env"] = env kwargs["close_fds"] = True wait_counter = 1 while xbmc.getCondVisibility('Window.IsVisible(10140)'): if wait_counter == 1: log.info('Add-on settings currently opened, waiting before starting...') if wait_counter > 300: break time.sleep(1) return subprocess.Popen(args, **kwargs)
def get_quasar_binary(): binary = "quasar" + (PLATFORM["os"] == "windows" and ".exe" or "") log.info("PLATFORM: %s" % str(PLATFORM)) binary_dir = os.path.join(ADDON_PATH, "resources", "bin", "%(os)s_%(arch)s" % PLATFORM) if PLATFORM["os"] == "android": log.info("Detected binary folder: %s" % binary_dir) binary_dir_legacy = binary_dir.replace("/storage/emulated/0", "/storage/emulated/legacy") if os.path.exists(binary_dir_legacy): binary_dir = binary_dir_legacy app_id = android_get_current_appid() xbmc_data_path = translatePath("special://xbmcbin/").replace('user/0', 'data').replace('cache/apk/assets', 'files/quasar') log.info("Trying binary Kodi folder: %s" % xbmc_data_path) try: #Test if there is any permisions problem if not os.path.exists(xbmc_data_path): os.makedirs(xbmc_data_path) except Exception as e: log.info("ERROR %s in binary Kodi folder: %s" % (str(e), xbmc_data_path)) if not os.path.exists(xbmc_data_path): xbmc_data_path = translatePath("special://xbmcbin/").replace('cache/apk/assets', 'files/quasar') log.info("Trying alternative binary Kodi folder: %s" % xbmc_data_path) try: #Test if there is any permisions problem if not os.path.exists(xbmc_data_path): os.makedirs(xbmc_data_path) except Exception as e: log.info("ERROR %s in alternative binary Kodi folder: %s" % (str(e), xbmc_data_path)) dest_binary_dir = xbmc_data_path else: if not PY3: dest_binary_dir = os.path.join(translatePath(ADDON.getAddonInfo("profile")).decode('utf-8'), "bin", "%(os)s_%(arch)s" % PLATFORM) else: dest_binary_dir = os.path.join(translatePath(ADDON.getAddonInfo("profile")), "bin", "%(os)s_%(arch)s" % PLATFORM) if PY3 and isinstance(dest_binary_dir, bytes): dest_binary_dir = dest_binary_dir.decode("utf8") log.info("Using destination binary folder: %s" % dest_binary_dir) binary_path = os.path.join(binary_dir, binary) dest_binary_path = os.path.join(dest_binary_dir, binary) if not os.path.exists(binary_path): notify((getLocalizedString(30103) + " %(os)s_%(arch)s" % PLATFORM), time=7000) system_information() try: log.info("Source directory (%s):\n%s" % (binary_dir, os.listdir(os.path.join(binary_dir, "..")))) log.info("Destination directory (%s):\n%s" % (dest_binary_dir, os.listdir(os.path.join(dest_binary_dir, "..")))) except Exception: pass #return False, False if os.path.isdir(dest_binary_path): log.warning("Destination path is a directory, expected previous binary file, removing...") try: shutil.rmtree(dest_binary_path) except Exception as e: log.error("Unable to remove destination path for update: %s" % e) system_information() #return False, False if not os.path.exists(dest_binary_path) or get_quasard_checksum(dest_binary_path) != get_quasard_checksum(binary_path): log.info("Updating quasar daemon...") try: os.makedirs(dest_binary_dir) except OSError: pass try: shutil.rmtree(dest_binary_dir) except Exception as e: log.error("Unable to remove destination path for update: %s" % e) system_information() #return False, False try: shutil.copytree(binary_dir, dest_binary_dir) except Exception as e: log.error("Unable to copy to destination path for update: %s" % e) system_information() #return False, False # Clean stale files in the directory, as this can cause headaches on # Android when they are unreachable if os.path.exists(dest_binary_dir): try: dest_files = set(os.listdir(dest_binary_dir)) orig_files = set(os.listdir(binary_dir)) log.info("Deleting stale files %s" % (dest_files - orig_files)) for file_ in (dest_files - orig_files): path = os.path.join(dest_binary_dir, file_) if os.path.isdir(path): shutil.rmtree(path) else: os.remove(path) except: pass return dest_binary_dir, ensure_exec_perms(dest_binary_path)
def run(url_suffix=""): if not os.path.exists(os.path.join(xbmc.translatePath(ADDON.getAddonInfo("path")), ".firstrun")): notify(getLocalizedString(30101)) system_information() return donatePath = os.path.join(xbmc.translatePath(ADDON.getAddonInfo("path")), ".donate") if not os.path.exists(donatePath): with open(donatePath, "w"): os.utime(donatePath, None) dialog = xbmcgui.Dialog() dialog.ok("Quasar", "Please support Quasar development by visiting https://quasar.surge.sh to donate with Bitcoin, or buying a VPN subscription using the affiliate link at the bottom.") socket.setdefaulttimeout(300) urllib2.install_opener(urllib2.build_opener(NoRedirectHandler())) url = sys.argv[0].replace("plugin://%s" % ADDON_ID, QUASARD_HOST + url_suffix) + sys.argv[2] log.debug("Requesting %s from %s" % (url, repr(sys.argv))) try: data = _json(url) except Exception as e: map(log.error, traceback.format_exc().split("\n")) notify("%s: %s" % (getLocalizedString(30225), repr(e).encode('utf-8'))) return if not data: return if data["content_type"]: xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_UNSORTED) if data["content_type"] != "tvshows": xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE) xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_DATE) xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_GENRE) xbmcplugin.setContent(HANDLE, data["content_type"]) listitems = range(len(data["items"])) for i, item in enumerate(data["items"]): # Translate labels if item["label"][0:8] == "LOCALIZE": item["label"] = getLocalizedLabel(item["label"]) if item["label2"][0:8] == "LOCALIZE": item["label2"] = getLocalizedLabel(item["label2"]) listItem = xbmcgui.ListItem(label=item["label"], label2=item["label2"], iconImage=item["icon"], thumbnailImage=item["thumbnail"]) if item.get("info"): listItem.setInfo("video", item["info"]) if item.get("stream_info"): for type_, values in item["stream_info"].items(): listItem.addStreamInfo(type_, values) if item.get("art"): listItem.setArt(item["art"]) if item.get("context_menu"): # Translate context menus for m, menu in enumerate(item["context_menu"]): if menu[0][0:8] == "LOCALIZE": menu[0] = getLocalizedLabel(menu[0]) listItem.addContextMenuItems(item["context_menu"]) listItem.setProperty("isPlayable", item["is_playable"] and "true" or "false") if item.get("properties"): for k, v in item["properties"].items(): listItem.setProperty(k, v) listitems[i] = (item["path"], listItem, not item["is_playable"]) xbmcplugin.addDirectoryItems(HANDLE, listitems, totalItems=len(listitems)) # Set ViewMode if data["content_type"]: viewMode = ADDON.getSetting("viewmode_%s" % data["content_type"]) try: xbmc.executebuiltin('Container.SetViewMode(%s)' % (viewMode)) except Exception as e: log.warning("Unable to SetViewMode(%s): %s" % (viewMode, repr(e))) xbmcplugin.endOfDirectory(HANDLE, succeeded=True, updateListing=False, cacheToDisc=True)
def run(url_suffix=""): if not os.path.exists( os.path.join(xbmc.translatePath(ADDON.getAddonInfo("path")), ".firstrun")): notify(getLocalizedString(30101)) system_information() return donatePath = os.path.join(xbmc.translatePath(ADDON.getAddonInfo("path")), ".donate") if not os.path.exists(donatePath): with open(donatePath, "w"): os.utime(donatePath, None) dialog = xbmcgui.Dialog() dialog.ok( "Quasar", "Please support Quasar development by visiting https://quasar.surge.sh to donate with Bitcoin, or buying a VPN subscription using the affiliate link at the bottom." ) socket.setdefaulttimeout(300) urllib2.install_opener(urllib2.build_opener(NoRedirectHandler())) url = sys.argv[0].replace("plugin://%s" % ADDON_ID, QUASARD_HOST + url_suffix) + sys.argv[2] log.debug("Requesting %s from %s" % (url, repr(sys.argv))) try: data = _json(url) except Exception as e: map(log.error, traceback.format_exc().split("\n")) notify("%s: %s" % (getLocalizedString(30225), repr(e).encode('utf-8'))) return if not data: return if data["content_type"]: xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_UNSORTED) if data["content_type"] != "tvshows": xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE) xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_DATE) xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_GENRE) xbmcplugin.setContent(HANDLE, data["content_type"]) listitems = range(len(data["items"])) for i, item in enumerate(data["items"]): # Translate labels if item["label"][0:8] == "LOCALIZE": item["label"] = getLocalizedLabel(item["label"]) if item["label2"][0:8] == "LOCALIZE": item["label2"] = getLocalizedLabel(item["label2"]) listItem = xbmcgui.ListItem(label=item["label"], label2=item["label2"], iconImage=item["icon"], thumbnailImage=item["thumbnail"]) if item.get("info"): listItem.setInfo("video", item["info"]) if item.get("stream_info"): for type_, values in item["stream_info"].items(): listItem.addStreamInfo(type_, values) if item.get("art"): listItem.setArt(item["art"]) if item.get("context_menu"): # Translate context menus for m, menu in enumerate(item["context_menu"]): if menu[0][0:8] == "LOCALIZE": menu[0] = getLocalizedLabel(menu[0]) listItem.addContextMenuItems(item["context_menu"]) listItem.setProperty("isPlayable", item["is_playable"] and "true" or "false") if item.get("properties"): for k, v in item["properties"].items(): listItem.setProperty(k, v) listitems[i] = (item["path"], listItem, not item["is_playable"]) xbmcplugin.addDirectoryItems(HANDLE, listitems, totalItems=len(listitems)) # Set ViewMode if data["content_type"]: viewMode = ADDON.getSetting("viewmode_%s" % data["content_type"]) try: xbmc.executebuiltin('Container.SetViewMode(%s)' % (viewMode)) except Exception as e: log.warning("Unable to SetViewMode(%s): %s" % (viewMode, repr(e))) xbmcplugin.endOfDirectory(HANDLE, succeeded=True, updateListing=False, cacheToDisc=True)