import mimetypes import os import socket import urllib.error import urllib.parse import urllib.parse import urllib.request import chardet import sys import xbmc from .structs import MediaType SUBTITLES_FORMATS = ['.aqt', '.gsub', '.jss', '.sub', '.ttxt', '.pjs', '.psb', '.rt', '.smi', '.stl', '.ssf', '.srt', '.ssa', '.ass', '.usf', '.idx'] VIDEO_FORMATS = ['.mkv', '.mp4', '.avi', '.ogv', '.ts', '.flv', '.webm', '.vob', '.3gp', '.mpg', '.mpeg'] class Struct(dict): def __getattr__(self, attr): return self[attr] def __setattr__(self, attr, value): self[attr] = value def uri2path(uri: str) -> str: uri_path: str = '' if uri[1] == ':' and sys.platform.startswith('win'): uri = 'file:///' + uri file_uri = urllib.parse.urlparse(uri) if file_uri.scheme == 'file': uri_path = file_uri.path if uri_path != '' and sys.platform.startswith('win') and (os.path.sep == uri_path[0] or uri_path[0] == '/'): uri_path = uri_path[1:] abs_path = os.path.abspath(urllib.parse.unquote(uri_path)) return localize_path(abs_path) def detect_media_type(name): ext = os.path.splitext(name)[1] if ext in SUBTITLES_FORMATS: return MediaType.SUBTITLES else: mime_type = mimetypes.guess_type(name)[0] if mime_type is None: if ext.lower() in VIDEO_FORMATS: return MediaType.VIDEO return MediaType.UNKNOWN mime_type = mime_type.split("/")[0] if mime_type == 'audio': return MediaType.AUDIO elif mime_type == 'video': return MediaType.VIDEO else: return MediaType.UNKNOWN def unicode_msg(tmpl, args): msg = isinstance(tmpl, str) and tmpl or tmpl.decode(chardet.detect(tmpl)['encoding']) arg_ = [] for a in args: arg_.append(isinstance(a, str) and a or a.decode(chardet.detect(a)['encoding'])) return msg % tuple(arg_) def encode_msg(msg): msg = isinstance(msg, str) and msg.encode( sys.getfilesystemencoding() != 'ascii' and sys.getfilesystemencoding() or 'utf-8') or msg return msg def localize_path(path): if isinstance(path, bytes): path = path.decode(chardet.detect(path)['encoding']) # if not sys.platform.startswith('win'): # path = path.encode( # (sys.getfilesystemencoding() not in ('ascii', 'ANSI_X3.4-1968')) and sys.getfilesystemencoding() or 'utf-8') return path def can_bind(host, port): """ Checks we can bind to specified host and port :param host: Host :param port: Port :return: True if bind succeed """ try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((host, port)) s.close() except socket.error: return False return True def find_free_port(host): """ Finds free TCP port that can be used for binding :param host: Host :return: Free port """ try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((host, 0)) port = s.getsockname()[1] s.close() except socket.error: return False return port def ensure_fs_encoding(string): if isinstance(string, bytes): string = string.decode('utf-8') return string.encode(sys.getfilesystemencoding() or 'utf-8') def get_platform(): ret = { "arch": sys.maxsize > 2 ** 32 and "x64" or "x86", } if xbmc.getCondVisibility("system.platform.android"): ret["os"] = "android" if "arm" in os.uname()[4] or "aarch64" in os.uname()[4]: ret["arch"] = "arm" elif xbmc.getCondVisibility("system.platform.linux"): ret["os"] = "linux" uname = os.uname()[4] if "arm" in uname: if "armv7" in uname: ret["arch"] = "armv7" else: ret["arch"] = "armv6" elif "mips" in uname: ret["arch"] = 'mipsel' elif "aarch64" in uname: if sys.maxsize > 2147483647: # is_64bit_system ret["arch"] = 'aarch64' else: ret["arch"] = "armv7" # 32-bit userspace elif xbmc.getCondVisibility("system.platform.windows"): ret["os"] = "windows" elif xbmc.getCondVisibility("system.platform.osx"): ret["os"] = "darwin" elif xbmc.getCondVisibility("system.platform.ios"): ret["os"] = "ios" ret["arch"] = "arm" ret = get_system(ret) return ret def get_system(ret): ret["system"] = '' if ret["os"] == 'windows': ret["system"] = 'windows_' + ret['arch'] elif ret["os"] == "linux" and ret["arch"] == "x64": ret["system"] = 'linux_x86_64' elif ret["os"] == "linux" and ret["arch"] == "x86": ret["system"] = 'linux_x86' elif ret["os"] == "linux" and "aarch64" in ret["arch"]: ret["system"] = 'linux_' + ret["arch"] elif ret["os"] == "linux" and ("arm" in ret["arch"] or 'mips' in ret["arch"]): ret["system"] = 'linux_' + ret["arch"] elif ret["os"] == "android": if ret["arch"] == 'arm': ret["system"] = 'android_armv7' else: ret["system"] = 'android_x86' elif ret["os"] == "darwin": ret["system"] = 'darwin' elif ret["os"] == "ios" and ret["arch"] == "arm": ret["system"] = 'ios_arm' return ret