Skip to content

Commit

Permalink
Add support to kodi platform detection
Browse files Browse the repository at this point in the history
  • Loading branch information
i96751414 committed Feb 12, 2024
1 parent 2c12d26 commit 5f8ddae
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 44 deletions.
2 changes: 1 addition & 1 deletion lib/entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import xbmcgui

from lib.kodi import ADDON_DATA, ADDON_NAME, translate, notification, get_repository_port, str_to_unicode, translatePath
from lib.os_platform import get_platform_arch, dump_platform
from lib.platform_ import get_platform_arch, dump_platform
from lib.repository import validate_json_schema, get_request

if not os.path.exists(ADDON_DATA):
Expand Down
35 changes: 35 additions & 0 deletions lib/platform_/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import logging

from . import kodi_platform
from . import os_platform
from .definitions import PlatformError, Arch, System, Platform, SHARED_LIB_EXTENSIONS, EXECUTABLE_EXTENSIONS


def dump_platform():
return "Kodi platform: " + kodi_platform.dump_platform() + "\n" + os_platform.dump_platform()


def get_platform():
try:
return kodi_platform.get_platform()
except PlatformError:
return os_platform.get_platform()


try:
PLATFORM = get_platform()
SHARED_LIB_EXTENSION = SHARED_LIB_EXTENSIONS.get(PLATFORM.system, "")
EXECUTABLE_EXTENSION = EXECUTABLE_EXTENSIONS.get(PLATFORM.system, "")
except Exception as _e:
logging.fatal(_e, exc_info=True)
logging.fatal(dump_platform())
raise _e


def get_platform_arch(sep="-"):
return PLATFORM.system + sep + PLATFORM.arch


__all__ = ["PlatformError", "Arch", "System", "Platform",
"dump_platform", "get_platform", "get_platform_arch",
"PLATFORM", "SHARED_LIB_EXTENSION", "EXECUTABLE_EXTENSION"]
36 changes: 36 additions & 0 deletions lib/platform_/definitions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from collections import namedtuple


class PlatformError(Exception):
pass


class Enum:
@classmethod
def values(cls):
return [value for name, value in vars(cls).items() if not name.startswith("_")]


class System(Enum):
linux = "linux"
android = "android"
darwin = "darwin"
windows = "windows"


class Arch(Enum):
x64 = "x64"
x86 = "x86"
arm = "arm"
arm64 = "arm64"
armv7 = "armv7"


Platform = namedtuple("Platform", [
"system", # type:str
"version", # type:str
"arch", # type:str
])

SHARED_LIB_EXTENSIONS = {System.linux: ".so", System.android: ".so", System.darwin: ".dylib", System.windows: ".dll"}
EXECUTABLE_EXTENSIONS = {System.linux: "", System.android: "", System.darwin: "", System.windows: ".exe"}
97 changes: 97 additions & 0 deletions lib/platform_/kodi_platform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import json
import logging
import os
import re
from platform import release

import xbmc

try:
from xbmcvfs import translatePath
except ImportError:
from xbmc import translatePath

from .definitions import PlatformError, System, Arch, Platform

DARWIN_PLATFORMS = ("macOS", "iOS", "tvOS")
LINUX_PLATFORMS = ("Linux", "webOS")
ANDROID_PLATFORMS = ("Android",)
WINDOWS_PLATFORMS = ("Windows NT", "unknown Win32 platform")
SUPPORTED_PLATFORMS = DARWIN_PLATFORMS + ANDROID_PLATFORMS + LINUX_PLATFORMS + WINDOWS_PLATFORMS + (
"FreeBSD", "unknown platform")

SUPPORTED_CPUS = ["ARM (Thumb)", "ARM", "LoongArch", "MIPS", "x86", "s390", "PowerPC", "RISC-V", "unknown CPU family"]

_PLATFORM_RE = re.compile(r"^({}) ({}) (\d+)-bit$".format(
"|".join(map(re.escape, SUPPORTED_PLATFORMS)), "|".join(map(re.escape, SUPPORTED_PLATFORMS))))


def get_application_name():
cmd = '{"jsonrpc":"2.0", "method":"Application.GetProperties","params": {"properties": ["name"]}, "id":1}'
data = json.loads(xbmc.executeJSONRPC(cmd))
return data["result"]["name"]


def get_kodi_log_path():
log_name = os.path.join(translatePath("special://logpath"), get_application_name().lower())
return log_name + ".log", log_name + ".old.log"


def get_kodi_platform_from_log():
# GetBuildTargetPlatformName, GetBuildTargetCpuFamily and GetXbmcBitness from 2nd log line
# (tree/master -> blob/6d5b46ba127eacd706610a91a32167abfbf8ac8e)
# https://github.com/xbmc/xbmc/tree/master/xbmc/utils/SystemInfo.cpp
# https://github.com/xbmc/xbmc/tree/master/xbmc/application/Application.cpp#L3673
new_log_path, old_log_path = get_kodi_log_path()
with open(old_log_path if os.path.exists(old_log_path) else new_log_path) as f:
# Ignore first line
next(f)
# Second line ends with the platform
kodi_platform = next(f).split("Platform: ")[-1].rstrip()

return kodi_platform


def dump_platform():
try:
return get_kodi_platform_from_log()
except Exception as e:
logging.warning("Failed getting kodi platform: %s", e, exc_info=True)
return "unknown"


def get_platform():
raw_platform = dump_platform()
logging.debug("Resolving platform - %s", raw_platform)
match = _PLATFORM_RE.match(raw_platform)
if not match:
raise PlatformError("Unable to parse Kodi platform")

platform_name = match.group(1)
cpu_family = match.group(2)
bitness = int(match.group(3))

if platform_name in ANDROID_PLATFORMS:
system = System.android
elif platform_name in LINUX_PLATFORMS:
system = System.linux
elif platform_name in WINDOWS_PLATFORMS:
system = System.windows
elif platform_name in DARWIN_PLATFORMS:
system = System.darwin
else:
raise PlatformError("Unknown platform: {}".format(platform_name))

if cpu_family == "ARM":
if system == System.android:
arch = Arch.arm64 if bitness == 64 else Arch.arm
elif system == System.linux:
arch = Arch.arm64 if bitness == 64 else Arch.armv7
else:
raise PlatformError("Unknown arch {} for platform: {}".format(cpu_family, system))
elif cpu_family == "x86":
arch = Arch.x64 if bitness == 64 else Arch.x86
else:
raise PlatformError("Unknown platform: {}".format(cpu_family))

return Platform(system, release(), arch)
45 changes: 3 additions & 42 deletions lib/os_platform.py → lib/platform_/os_platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,8 @@
import os
import platform
import sys
from collections import namedtuple


class Enum:
@classmethod
def values(cls):
return [value for name, value in vars(cls).items() if not name.startswith("_")]


class System(Enum):
linux = "linux"
android = "android"
darwin = "darwin"
windows = "windows"


class Arch(Enum):
x64 = "x64"
x86 = "x86"
arm = "arm"
arm64 = "arm64"
armv7 = "armv7"


Platform = namedtuple("Platform", [
"system", # type:str
"version", # type:str
"arch", # type:str
])
from .definitions import Arch, System, Platform


def get_platform():
Expand Down Expand Up @@ -66,18 +39,6 @@ def get_platform():


def dump_platform():
return "system: {}\nrelease: {}\nmachine: {}\narchitecture: {}\nmax_size: {} ({:x} {})".format(
return "system: {}\nrelease: {}\nmachine: {}\narchitecture: {}\nmax_size: {} ({:x} {})\nplatform: {}".format(
platform.system(), platform.release(), platform.machine(), platform.architecture(), sys.maxsize,
sys.maxsize, ">32b" if sys.maxsize > 2 ** 32 else "<=32b")


try:
PLATFORM = get_platform()
except Exception as _e:
logging.fatal(_e, exc_info=True)
logging.fatal(dump_platform())
raise _e


def get_platform_arch(sep="-"):
return PLATFORM.system + sep + PLATFORM.arch
sys.maxsize, ">32b" if sys.maxsize > 2 ** 32 else "<=32b", platform.platform())
2 changes: 1 addition & 1 deletion lib/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from lib.cache import cached
from lib.kodi import string_types
from lib.os_platform import PLATFORM, get_platform_arch
from lib.platform_ import PLATFORM, get_platform_arch

ADDON = namedtuple("ADDON", "id username branch assets asset_prefix repository")

Expand Down

0 comments on commit 5f8ddae

Please sign in to comment.