script.module.gorrent2http/lib/gorrent2http/util.py

177 lines
5.2 KiB
Python

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']
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 not mime_type:
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