Beispiel #1
0
def dump_version():
    try:
        p = platform.platform()
    except:
        p = "Could not detect"

    log.info("""Python version: %s
    dist: %s
    linux_distribution: %s
    system: %s
    machine: %s
    platform: %s
    uname: %s
    version: %s
    mac_ver: %s
    """ % (
        sys.version.split('\n'),
        str(platform.dist()),
        linux_distribution(),
        platform.system(),
        platform.machine(),
        p,
        platform.uname(),
        platform.version(),
        platform.mac_ver(),
    ))
Beispiel #2
0
def run():
    # Make sure the XBMC jsonrpc server is started.
    xbmc.startServer(xbmc.SERVER_JSONRPCSERVER, True)

    # Make the monitor
    monitor = ElementumMonitor()

    threads = [
        threading.Thread(target=server_thread),  # JSONRPC thread
    ]
    if not ONLY_CLIENT and PLATFORM["fork"]:
        threads.append(
            threading.Thread(target=elementumd_thread,
                             args=[monitor]))  # Elementumd thread

    for t in threads:
        t.daemon = True
        t.start()

    # XBMC loop
    while not monitor.abortRequested():
        xbmc.sleep(1000)

    if PLATFORM['kodi'] >= 19:
        monitor.onAbortRequested()

    log.info("elementum: exiting elementumd")
Beispiel #3
0
def run():
    # Make sure the XBMC jsonrpc server is started.
    xbmc.startServer(xbmc.SERVER_JSONRPCSERVER, True)

    # Make the monitor
    monitor = ElementumMonitor()

    threads = [
        threading.Thread(target=server_thread),  # JSONRPC thread
    ]
    if not ONLY_CLIENT:
        sys.stderr.write("elementum: ONLY " + str(ONLY_CLIENT))
        threads.append(
            threading.Thread(target=elementumd_thread,
                             args=[monitor]))  # Elementumd thread

    for t in threads:
        t.daemon = True
        t.start()

    # XBMC loop
    while not xbmc.abortRequested:
        xbmc.sleep(1000)

    log.info("elementum: exiting elementumd")
def dump_version(ret):
    try:
        p = platform.platform()
    except:
        p = "Could not detect"

    try:
        log.info("""Python version: %s
        dist: %s
        linux_distribution: %s
        system: %s
        machine: %s
        platform: %s
        uname: %s
        version: %s
        mac_ver: %s
        """ % (
            sys.version.split('\n'),
            str(platform.dist()),
            linux_distribution(),
            platform.system(),
            platform.machine(),
            p,
            platform.uname(),
            platform.version(),
            platform.mac_ver()
        ))
    except:
        if ret is not None:
            log.info("Cannot write detection info. Ret: %s" % (repr(ret)))
        pass
Beispiel #5
0
def download_github_folder(repo, folder, destination):
    contents_url = "https://api.github.com/repos/%s/contents/%s" % (repo, folder)
    log.info("Downloading repo content for folder: %s, to folder: %s" % (contents_url, destination))
    try:
        with requests.get(contents_url) as r:
            lists = json.loads(r.content, parse_int=str)

            downloaded = 0
            for i in lists:
                if 'download_url' not in i:
                    continue

                dest = os.path.join(destination, urllib_parse.unquote(i['download_url'].rsplit('/', 1)[1]))
                log.info("Downloading file '%s' to '%s'" % (i['download_url'], dest))

                with requests.get(i['download_url'], stream=True) as rd:
                    rd.raise_for_status()
                    with open(dest, 'wb') as f:
                        for chunk in rd.iter_content(chunk_size=8192):
                            f.write(chunk)
                downloaded += 1
            return downloaded > 0
    except Exception as e:
        log.error("Could not get list of files from github: %s" % e)
        raise
Beispiel #6
0
 def Reset(self):
     for i in self._objects:
         try:
             self._objects[i].hide()
         except:
             pass
     log.info("Resetting RPC objects...")
     self._objects = {}
Beispiel #7
0
def wait_for_abortRequested(proc, monitor):
    monitor.closing.wait()
    log.info("elementumd: exiting elementumd daemon")
    try:
        proc.terminate()
    except OSError:
        pass  # Process already exited, nothing to terminate
    log.info("elementumd: elementumd daemon exited")
Beispiel #8
0
def server_thread():
    try:
        s = bjsonrpc.createserver(host="0.0.0.0", port=JSONRPC_EXT_PORT, handler_factory=ElementumRPCServer)
        log.info("elementum: starting jsonrpc service")
        s.serve()
        log.info("elementum: exiting jsonrpc service")
    except Exception:
        import traceback
        map(log.error, traceback.format_exc().split("\n"))
        raise
Beispiel #9
0
def doPlay():
    dbid = getDbId()
    mediatype = getMediaType()

    xbmcgui.Dialog().notification(ADDON.getLocalizedString(32009),
                                  sys.listitem.getLabel(),
                                  xbmcgui.NOTIFICATION_INFO, 3000)

    log.info("Playing for: DBID=%s, MediaType=%s" % (dbid, mediatype))

    url = "plugin://plugin.video.elementum/context/%s/%s/play" % (mediatype,
                                                                  dbid)
    log.info("Starting Elementum with: %s" % url)
    xbmc.Player().play(url)
def system_information():
    build = xbmc.getInfoLabel("System.BuildVersion")
    log.info("System information: %(os)s_%(arch)s %(version)s" % PLATFORM)
    log.info("Kodi build version: %s" % build)
    log.info("OS type: %s" % platform.system())
    log.info("uname: %s" % repr(platform.uname()))
    return PLATFORM
Beispiel #11
0
def jsonrpc_enabled(notify=False):
    try:
        s = socket.socket()
        s.connect(('127.0.0.1', 9090))
        s.close()
        log.info("Kodi's JSON-RPC service is available, starting up...")
        del s
        return True
    except Exception as e:
        log.error(repr(e))
        if notify:
            xbmc.executebuiltin("ActivateWindow(ServiceSettings)")
            dialog = xbmcgui.Dialog()
            dialog.ok("Elementum", getLocalizedString(30199))
    return False
Beispiel #12
0
def doLibraryAction(action):
    dbid = getDbId()
    mediatype = getMediaType()

    heading = ADDON.getLocalizedString(
        32017) if action == "add" else "Unsupported action"
    xbmcgui.Dialog().notification(heading, sys.listitem.getLabel(),
                                  xbmcgui.NOTIFICATION_INFO, 3000)

    log.info("%s library item: DBID=%s, MediaType=%s" %
             (action, dbid, mediatype))

    url = "plugin://plugin.video.elementum/context/library/%s/%s/%s" % (
        mediatype, dbid, action)
    log.info("Starting Elementum with: %s" % url)
    xbmc.Player().play(url)
Beispiel #13
0
def run():
    # Make sure the XBMC jsonrpc server is started.
    xbmc.startServer(xbmc.SERVER_JSONRPCSERVER, True)

    # Make the monitor
    monitor = ElementumMonitor()

    threads = [
        threading.Thread(target=server_thread),  # JSONRPC thread
        threading.Thread(target=elementumd_thread,
                         args=[monitor]),  # Elementumd thread
    ]
    for t in threads:
        t.daemon = True
        t.start()

    # XBMC loop
    while not xbmc.abortRequested:
        xbmc.sleep(1000)

    log.info("elementum: exiting elementumd")
Beispiel #14
0
 def GetCurrentView(self):
     skinPath = xbmc.translatePath('special://skin/')
     xml = os.path.join(skinPath, 'addon.xml')
     f = xbmcvfs.File(xml)
     read = f.read()
     f.close()
     try:
         src = re.search('defaultresolution="([^"]+)', read, re.DOTALL).group(1)
     except:
         src = re.search('<res.+?folder="([^"]+)', read, re.DOTALL).group(1)
     src = os.path.join(skinPath, src, 'MyVideoNav.xml')
     f = xbmcvfs.File(src)
     read = f.read()
     f.close()
     match = re.search('<views>([^<]+)', read, re.DOTALL)
     if match:
         views = match.group(1)
         log.info("Skin's ViewModes: %s" % views)
         for view in views.split(','):
             if xbmc.getInfoLabel('Control.GetLabel(%s)' % view):
                 return view
Beispiel #15
0
def doPlay():
    dbid = getDbId()
    mediatype = getMediaType()

    use_elementum_path = False
    if not dbid.isdigit():
        try:
            path = sys.listitem.getfilename()
        except AttributeError:
            path = sys.listitem.getPath()
        if path.startswith("plugin://plugin.video.elementum"):
            use_elementum_path = True

    xbmcgui.Dialog().notification(ADDON.getLocalizedString(32009),
                                  sys.listitem.getLabel(),
                                  xbmcgui.NOTIFICATION_INFO, 3000)

    if use_elementum_path:
        log.info("Playing elementum item: path=%s, MediaType=%s" %
                 (path, mediatype))
        if mediatype == 'season':
            url = re.sub(r'/(episodes)(/?[^/]*)$',
                         r'/links\g<2>',
                         path,
                         count=1)
        else:
            url = path
    else:
        log.info("Playing library item: DBID=%s, MediaType=%s" %
                 (dbid, mediatype))
        url = "plugin://plugin.video.elementum/context/media/%s/%s/play" % (
            mediatype, dbid)

    log.info("Starting Elementum with: %s" % url)
    xbmc.Player().play(url)
Beispiel #16
0
def elementumd_thread(monitor):
    crash_count = 0
    try:
        while not xbmc.abortRequested:
            log.info("elementumd: starting elementumd")
            proc = start_elementumd(stdout=subprocess.PIPE,
                                    stderr=subprocess.STDOUT)
            if not proc:
                break
            threading.Thread(target=wait_for_abortRequested,
                             args=[proc, monitor]).start()

            if PLATFORM["os"] == "windows":
                while proc.poll() is None:
                    log.info(proc.stdout.readline())
            else:
                # Kodi hangs on some Android (sigh...) systems when doing a blocking
                # read. We count on the fact that Elementum daemon flushes its log
                # output on \n, creating a pretty clean output
                import fcntl
                import select
                fd = proc.stdout.fileno()
                fl = fcntl.fcntl(fd, fcntl.F_GETFL)
                fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
                while proc.poll() is None:
                    try:
                        to_read, _, _ = select.select([proc.stdout], [], [])
                        for ro in to_read:
                            line = ro.readline()
                            if line == "":  # write end is closed
                                break
                            log.info(line)
                    except IOError:
                        time.sleep(1)  # nothing to read, sleep

            if proc.returncode == 0 or xbmc.abortRequested:
                break

            if proc.returncode == 5:
                notify(getLocalizedString(30332), time=3000)
            else:
                crash_count += 1
                notify(getLocalizedString(30100), time=3000)

            xbmc.executebuiltin("Dialog.Close(all, true)")
            system_information()
            time.sleep(5)
            if crash_count >= 3:
                notify(getLocalizedString(30110), time=3000)
                break

    except Exception as e:
        import traceback
        map(log.error, traceback.format_exc().split("\n"))
        notify("%s: %s" % (getLocalizedString(30226), repr(e).encode('utf-8')))
        raise
Beispiel #17
0
def doTraktAction(action):
    dbid = getDbId()
    mediatype = getMediaType()

    if action == "watched":
        heading = ADDON.getLocalizedString(32018)
    elif action == "unwatched":
        heading = ADDON.getLocalizedString(32019)
    else:
        heading = "Unsupported action"

    if not dbid.isdigit():
        showtmdbid = xbmc.getInfoLabel('ListItem.Property(ShowTMDBId)')
        try:
            tmdbID = sys.listitem.getUniqueID('tmdb')
        except AttributeError:
            tmdbID = ""
        if tmdbID == "" or ((mediatype == 'season' or mediatype == 'episode')
                            and showtmdbid == ""):
            log.error("Could not find TMDB id for %s" % dbid)
            xbmcgui.Dialog().notification(ADDON.getLocalizedString(32007),
                                          ADDON.getLocalizedString(32014),
                                          xbmcgui.NOTIFICATION_WARNING, 3000)
            return

    xbmcgui.Dialog().notification(heading, sys.listitem.getLabel(),
                                  xbmcgui.NOTIFICATION_INFO, 3000)
    if not dbid.isdigit():
        log.info("Make %s non-library item: tmdbID=%s, MediaType=%s" %
                 (action, tmdbID, mediatype))
    else:
        log.info("Make %s library item: DBID=%s, MediaType=%s" %
                 (action, dbid, mediatype))

    if not dbid.isdigit():
        if mediatype == 'movie':
            url = "plugin://plugin.video.elementum/movie/%s/%s" % (tmdbID,
                                                                   action)
        if mediatype == 'tvshow':
            url = "plugin://plugin.video.elementum/show/%s/%s" % (tmdbID,
                                                                  action)
        elif mediatype == 'season':
            season = xbmc.getInfoLabel('ListItem.Season')
            url = "plugin://plugin.video.elementum/show/%s/season/%s/%s" % (
                showtmdbid, season, action)
        elif mediatype == 'episode':
            season = xbmc.getInfoLabel('ListItem.Season')
            episode = xbmc.getInfoLabel('ListItem.Episode')
            url = "plugin://plugin.video.elementum/show/%s/season/%s/episode/%s/%s" % (
                showtmdbid, season, episode, action)
    else:
        url = "plugin://plugin.video.elementum/context/media/%s/%s/%s" % (
            mediatype, dbid, action)
    log.info("Starting Elementum with: %s" % url)
    xbmc.Player().play(url)
Beispiel #18
0
def elementumd_thread(monitor):
    restart_count = 0
    max_restart = 3
    last_code = 0

    try:
        monitor_abort = xbmc.Monitor()  # For Kodi >= 14
        while not monitor_abort.abortRequested():
            # If we ran out of attempts of last exit code was '-9': we do not try to start it again.
            # So if you kill the binary with '-9': it will not be restarted by this monitor.
            if restart_count > max_restart or last_code == -9:
                if monitor.reboot():
                    log.debug("elementumd: resetting attempts")
                    restart_count = 0
                    last_code = 0
                    monitor.reboot(False)
                else:
                    time.sleep(5)

                continue

            log.info("elementumd: starting elementumd")
            proc = None
            if hasSubprocess:
                proc = start_elementumd(stdout=subprocess.PIPE,
                                        stderr=subprocess.STDOUT)
                if not proc:
                    break
            else:
                log.info(
                    "elementumd: current system is unable to run the binary")
                break

            threading.Thread(target=wait_for_abortRequested,
                             args=[proc, monitor]).start()

            if not hasSubprocess:
                break

            if binary_platform["os"] == "windows":
                while proc.poll() is None:
                    log.info(toUtf8(proc.stdout.readline()))
            else:
                # Kodi hangs on some Android (sigh...) systems when doing a blocking
                # read. We count on the fact that Elementum daemon flushes its log
                # output on \n, creating a pretty clean output
                import fcntl
                import select
                fd = proc.stdout.fileno()
                fl = fcntl.fcntl(fd, fcntl.F_GETFL)
                fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
                while proc.poll() is None:
                    try:
                        to_read, _, _ = select.select([proc.stdout], [], [])
                        for ro in to_read:
                            line = ro.readline()
                            if line == "":  # write end is closed
                                break
                            try:
                                log.info(toUtf8(line))
                            except TypeError:
                                pass
                    except IOError:
                        time.sleep(1)  # nothing to read, sleep

            last_code = proc.returncode
            if monitor_abort.abortRequested():
                break
            if proc.returncode == 0 or proc.returncode == -9 or proc.returncode == -1:
                continue

            if proc.returncode == 5:
                restart_count = 0
                notify(getLocalizedString(30332), time=3000)
            else:
                restart_count += 1
                notify(getLocalizedString(30100), time=3000)

            xbmc.executebuiltin("Dialog.Close(all, true)")
            system_information()
            time.sleep(5)

            if restart_count >= max_restart:
                log.debug("elementumd: no attempts left")
                notify(getLocalizedString(30110), time=3000)
                continue

    except Exception as e:
        import traceback
        map(log.error, traceback.format_exc().split("\n"))
        notify("%s: %s" % (getLocalizedString(30226), repr(e).encode('utf-8')))
        raise

    log.debug("elementumd: closing")
Beispiel #19
0
 def DialogProgressBG_Cleanup(self):
     log.info("Cleaning up dialogs")
     for hwnd in self._objects:
         if isinstance(self._objects[hwnd], xbmcgui.DialogProgressBG):
             self._objects[hwnd].close()
def get_platform():
    try:
        binary_platform = ADDON.getSetting("binary_platform")
    except:
        binary_platform = "auto"
        pass

    build = xbmc.getInfoLabel("System.BuildVersion")
    kodi_version = int(build.split()[0][:2])

    if binary_platform and "auto" not in binary_platform.lower():
        custom = binary_platform.split('_')
        if len(custom) > 1:
            return {
                "os": custom[0],
                "arch": custom[1],
                "fork": True,
                "version": "",
                "kodi": kodi_version,
                "build": build
            }

    ret = {
        "auto_arch": sys.maxsize > 2 ** 32 and "64-bit" or "32-bit",
        "arch": sys.maxsize > 2 ** 32 and "x64" or "x86",
        "os": "",
        "version": "",
        "kodi": kodi_version,
        "build": build,
        "fork": True,
        "machine": "",
        "system": "",
        "platform": ""
    }

    try:
        ret["os"] = platform.release()
    except:
        pass

    try:
        ret["machine"] = platform.machine()
    except:
        # Default 'machine' for Android can be 'arm'
        if xbmc.getCondVisibility("system.platform.android"):
            ret["machine"] = "arm"
        pass

    try:
        ret["system"] = platform.system()
    except:
        pass

    try:
        ret["platform"] = platform.platform()
    except:
        pass

    if xbmc.getCondVisibility("system.platform.android"):
        ret["os"] = "android"
        if "arm" in ret["machine"].lower() or "aarch" in ret["machine"].lower():
            ret["arch"] = "arm"
            if "64" in ret["machine"] and ret["auto_arch"] == "64-bit":
                ret["arch"] = "arm64"
    elif xbmc.getCondVisibility("system.platform.linux"):
        ret["os"] = "linux"

        if "aarch" in ret["machine"].lower() or "arm64" in ret["machine"].lower():
            if xbmc.getCondVisibility("system.platform.linux.raspberrypi"):
                ret["arch"] = "armv7"
            elif ret["auto_arch"] == "32-bit":
                ret["arch"] = "armv7"
            elif ret["auto_arch"] == "64-bit":
                ret["arch"] = "arm64"
            # elif platform.architecture()[0].startswith("32"):
            #     ret["arch"] = "armv6"
            else:
                ret["arch"] = "armv7"
        elif "armv7" in ret["machine"]:
            ret["arch"] = "armv7"
        elif "arm" in ret["machine"]:
            cpuarch = ""
            if "aarch" in ret["machine"].lower() or "arm" in ret["machine"].lower():
                info = cpuinfo()
                for proc in info.keys():
                    log.info("CPU: %s=%s" % (proc, info[proc]))
                    model = ""
                    if "model name" in info[proc]:
                        model = info[proc]["model name"].lower()
                    elif "Processor" in info[proc]:
                        model = info[proc]["Processor"].lower()

                    if model:
                        log.info("Exploring model: %s" % model)
                        if "aarch" in model or "arm64" in model or "v8l" in model:
                            cpuarch = "arm64"
                        elif "armv7" in model or "v7l" in model:
                            cpuarch = "armv7"
                        break

            if cpuarch:
                log.info("Using CPU info arch: %s" % cpuarch)
                ret["arch"] = cpuarch
            else:
                ret["arch"] = "armv6"
    elif xbmc.getCondVisibility("system.platform.xbox"):
        ret["os"] = "windows"
        ret["arch"] = "x64"
        ret["fork"] = False
    elif xbmc.getCondVisibility("system.platform.windows"):
        ret["os"] = "windows"
        if ret["machine"].endswith('64'):
            ret["arch"] = "x64"
    elif ret["system"] == "Darwin":
        ret["os"] = "darwin"
        ret["arch"] = "x64"

        if "AppleTV" in ret["platform"]:
            ret["os"] = "ios"
            ret["arch"] = "armv7"
            ret["fork"] = False
            if "64bit" in ret["platform"]:
                ret["arch"] = "arm64"
        elif xbmc.getCondVisibility("system.platform.ios"):
            ret["os"] = "ios"
            ret["arch"] = "armv7"
            ret["fork"] = False
            if "64bit" in ret["platform"]:
                ret["arch"] = "arm64"

    # elif xbmc.getCondVisibility("system.platform.osx"):
    #     ret["os"] = "darwin"
    #     ret["arch"] = "x64"
    # elif xbmc.getCondVisibility("system.platform.ios"):
    #     ret["os"] = "ios"
    #     ret["arch"] = "armv7"
    return ret
Beispiel #21
0
def doAssign():
    mediatype = getMediaType()

    try:
        path = sys.listitem.getfilename()
    except AttributeError:
        path = sys.listitem.getPath()

    use_tmdb_id = False

    if path.startswith("plugin://plugin.video.elementum"):
        """plugin://plugin.video.elementum/show/1622/season/15/episode/1/links/Supernatural%20S15E01
        plugin://plugin.video.elementum/show/1622/season/15/episodes
        plugin://plugin.video.elementum/movie/628/links/Interview%20with%20the%20Vampire%20%281994%29"""
        use_tmdb_id = True
        result = re.search(r'plugin://plugin.video.elementum/[^/]+/(\d+)/.*',
                           path)
        if result:
            tmdbID = result.group(1)
        else:
            log.error("Could not find TMDB id for %s" % path)
            xbmcgui.Dialog().notification(ADDON.getLocalizedString(32007),
                                          ADDON.getLocalizedString(32014),
                                          xbmcgui.NOTIFICATION_WARNING, 3000)
            return

        if mediatype == 'season':
            result = re.search(
                r'plugin://plugin.video.elementum/[^/]+/\d+/season/(\d+)/.*',
                path)
            if result:
                season_number = result.group(1)
            else:
                log.error("Could not find season number for %s" % path)
                xbmcgui.Dialog().notification(ADDON.getLocalizedString(32007),
                                              ADDON.getLocalizedString(32014),
                                              xbmcgui.NOTIFICATION_WARNING,
                                              3000)
                return

        if mediatype == 'episode':
            result = re.search(
                r'plugin://plugin.video.elementum/[^/]+/\d+/season/(\d+)/episode/(\d+)/.*',
                path)
            if result:
                season_number = result.group(1)
                episode_number = result.group(2)
            else:
                log.error("Could not find season/episode number for %s" % path)
                xbmcgui.Dialog().notification(ADDON.getLocalizedString(32007),
                                              ADDON.getLocalizedString(32014),
                                              xbmcgui.NOTIFICATION_WARNING,
                                              3000)
                return
    else:
        dbid = getDbId()
        if not dbid.isdigit():
            log.error("Kodi library ID is wrong %s" % dbid)
            xbmcgui.Dialog().notification(ADDON.getLocalizedString(32007),
                                          ADDON.getLocalizedString(32016),
                                          xbmcgui.NOTIFICATION_WARNING, 3000)
            return

    # we also can use plugin://plugin.video.elementum/torrents/
    file = xbmcgui.Dialog().browseSingle(
        1, ADDON.getLocalizedString(32010), 'files', '', False, False,
        'plugin://plugin.video.elementum/history/')

    if file == '':
        return

    try:
        parsed_url = urlparse(file)
        params = parse_qs(parsed_url.query)
        if 'infohash' in params:
            torrentid = params['infohash'][0]
        else:
            torrentid = params['resume'][0]
    except Exception as e:
        log.error("Could not get torrent info for %s: %s" % (file, e))
        xbmcgui.Dialog().notification(ADDON.getLocalizedString(32007),
                                      ADDON.getLocalizedString(32015),
                                      xbmcgui.NOTIFICATION_WARNING, 3000)
        return

    if not use_tmdb_id:
        url = "plugin://plugin.video.elementum/context/torrents/assign/%s/kodi/%s/%s" % (
            torrentid, mediatype, dbid)
        log.info("Assigning torrent %s for: DBID=%s, MediaType=%s" %
                 (torrentid, dbid, mediatype))
    else:
        if mediatype == 'movie':
            url = "plugin://plugin.video.elementum/context/torrents/assign/%s/tmdb/%s/%s" % (
                torrentid, mediatype, tmdbID)
        elif mediatype == 'season':
            url = "plugin://plugin.video.elementum/context/torrents/assign/%s/tmdb/show/%s/%s/%s" % (
                torrentid, tmdbID, mediatype, season_number)
        elif mediatype == 'episode':
            url = "plugin://plugin.video.elementum/context/torrents/assign/%s/tmdb/show/%s/season/%s/%s/%s" % (
                torrentid, tmdbID, season_number, mediatype, episode_number)
        log.info("Assigning torrent %s for: TMDBID=%s, MediaType=%s" %
                 (torrentid, tmdbID, mediatype))

    xbmcgui.Dialog().notification(ADDON.getLocalizedString(32010),
                                  sys.listitem.getLabel(),
                                  xbmcgui.NOTIFICATION_INFO, 3000)

    log.info("Starting Elementum with: %s" % url)

    xbmc.Player().play(url)
Beispiel #22
0
    except AttributeError:
        path = item.getPath()
    truelabel = item.getLabel()
    infolabel = xbmc.getInfoLabel('ListItem.Label')
    dbid = xbmc.getInfoLabel('ListItem.DBID')
    mediatype = xbmc.getInfoLabel('ListItem.DBTYPE')
    try:
        tmdbID = item.getUniqueID('tmdb')
    except AttributeError:
        tmdbID = "not supported"

    properties = {
        'resume_time': item.getProperty('ResumeTime'),
        'start_offset': item.getProperty('StartOffset'),
        'start_percent': item.getProperty('StartPercent')
    }
    log.info("Properties: %s;" % properties)

    all_labels = getJSONResponse(
        '{"jsonrpc": "2.0", "method": "XBMC.GetInfoLabels", "params": { "labels": %s }, "id": "0"}'
        % json.dumps(info_labels))
    log.info("Labels: %s" % json.dumps(all_labels["result"], indent=4))

    log.info(
        "truelabel: %s; infolabel: %s; dbid: %s; tmdbID: %s; mediatype: %s; path: %s;"
        % (truelabel, infolabel, dbid, tmdbID, mediatype, path))
    xbmcgui.Dialog().notification(
        "truelabel: %s" % truelabel,
        "infolabel: %s; dbid: %s; tmdbID: %s; mediatype: %s; path: %s;" %
        (infolabel, dbid, tmdbID, mediatype, path))
Beispiel #23
0
def get_platform():
    build = xbmc.getInfoLabel("System.BuildVersion")
    kodi_version = int(build.split()[0][:2])
    ret = {
        "auto_arch": sys.maxsize > 2 ** 32 and "64-bit" or "32-bit",
        "arch": sys.maxsize > 2 ** 32 and "x64" or "x86",
        "os": "",
        "version": platform.release(),
        "kodi": kodi_version,
        "build": build,
        "fork": True,
    }

    if xbmc.getCondVisibility("system.platform.android"):
        dump_version()

        ret["os"] = "android"
        if "arm" in platform.machine().lower() or "aarch" in platform.machine().lower():
            ret["arch"] = "arm"
            if "64" in platform.machine() and ret["auto_arch"] == "64-bit":
                ret["arch"] = "arm64"
    elif xbmc.getCondVisibility("system.platform.linux"):
        ret["os"] = "linux"

        if "aarch" in platform.machine().lower() or "arm64" in platform.machine().lower():
            dump_version()

            if xbmc.getCondVisibility("system.platform.linux.raspberrypi"):
                ret["arch"] = "armv7"
            elif ret["auto_arch"] == "32-bit":
                ret["arch"] = "armv7"
            elif ret["auto_arch"] == "64-bit":
                ret["arch"] = "arm64"
            # elif platform.architecture()[0].startswith("32"):
            #     ret["arch"] = "armv6"
            else:
                ret["arch"] = "armv7"
        elif "armv7" in platform.machine():
            dump_version()
            ret["arch"] = "armv7"
        elif "arm" in platform.machine():
            dump_version()

            cpuarch = ""
            if "aarch" in platform.machine().lower() or "arm" in platform.machine().lower():
                info = cpuinfo()
                for proc in info.keys():
                    log.info("CPU: %s=%s" % (proc, info[proc]))
                    model = ""
                    if "model name" in info[proc]:
                        model = info[proc]["model name"].lower()
                    elif "Processor" in info[proc]:
                        model = info[proc]["Processor"].lower()

                    if model:
                        log.info("Exploring model: %s" % model)
                        if "aarch" in model or "arm64" in model or "v8l" in model:
                            cpuarch = "arm64"
                        elif "armv7" in model or "v7l" in model:
                            cpuarch = "armv7"
                        break

            if cpuarch:
                log.info("Using CPU info arch: %s" % cpuarch)
                ret["arch"] = cpuarch
            else:
                ret["arch"] = "armv6"
    elif xbmc.getCondVisibility("system.platform.xbox"):
        ret["os"] = "windows"
        ret["arch"] = "x64"
        ret["fork"] = False
    elif xbmc.getCondVisibility("system.platform.windows"):
        ret["os"] = "windows"
        if platform.machine().endswith('64'):
            ret["arch"] = "x64"
    elif platform.system() == "Darwin":
        dump_version()

        ret["os"] = "darwin"
        ret["arch"] = "x64"

        if "AppleTV" in platform.platform():
            ret["os"] = "ios"
            ret["arch"] = "armv7"
            ret["fork"] = False
            if "64bit" in platform.platform():
                ret["arch"] = "arm64"
        elif xbmc.getCondVisibility("system.platform.ios"):
            ret["os"] = "ios"
            ret["arch"] = "armv7"
            ret["fork"] = False
            if "64bit" in platform.platform():
                ret["arch"] = "arm64"

    # elif xbmc.getCondVisibility("system.platform.osx"):
    #     ret["os"] = "darwin"
    #     ret["arch"] = "x64"
    # elif xbmc.getCondVisibility("system.platform.ios"):
    #     ret["os"] = "ios"
    #     ret["arch"] = "armv7"
    return ret
Beispiel #24
0
def start_elementumd(**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)

    elementum_dir, elementum_binary = get_elementum_binary()

    log.info("Binary dir: %s, item: %s " % (elementum_dir, elementum_binary))
    if elementum_dir is False or elementum_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 OSError as e:
            if e.errno != 3:
                # Ignore:   OSError: [Errno 3] No such process
                log.error(repr(e))
        except Exception as e:
            log.error(repr(e))

        if binary_platform["os"] == "windows":
            try:
                library_lockfile = os.path.join(
                    xbmc.translatePath(
                        ADDON.getAddonInfo("profile")).decode('utf-8'),
                    "library.db.lock")
                log.warning("Removing library.db.lock file at %s ..." %
                            library_lockfile)
                os.remove(library_lockfile)
            except Exception as e:
                log.error(repr(e))

    SW_HIDE = 0
    STARTF_USESHOWWINDOW = 1

    args = [elementum_binary]
    kwargs["cwd"] = elementum_dir

    if binary_platform["os"] == "windows":
        args[0] = getWindowsShortPath(elementum_binary)
        kwargs["cwd"] = getWindowsShortPath(elementum_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" % (elementum_dir,
                                            env.get("LD_LIBRARY_PATH", ""))
        kwargs["env"] = env
        kwargs["close_fds"] = True

    wait_counter = 1
    log.debug("Checking for visible")
    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

    log.info("elementumd: start args: %s, kw: %s" % (args, kwargs))

    if hasSubprocess:
        return subprocess.Popen(args, **kwargs)
    return False
Beispiel #25
0
def get_elementum_binary():
    global binary_platform
    binary_platform = get_platform()

    binary = "elementum" + (binary_platform["os"] == "windows" and ".exe"
                            or "")
    binary_dir = os.path.join(ADDON_PATH, "resources", "bin",
                              "%(os)s_%(arch)s" % binary_platform)

    if binary_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 changed binary folder for Android: %s" %
                     binary_dir)

        app_id = android_get_current_appid()
        xbmc_data_path = os.path.join("/data", "data", app_id)
        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/")

        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" % binary_platform)
    else:
        dest_binary_dir = os.path.join(
            xbmc.translatePath(ADDON.getAddonInfo("profile")), "bin",
            "%(os)s_%(arch)s" % binary_platform)

    binary_path = os.path.join(binary_dir, binary)
    dest_binary_path = os.path.join(dest_binary_dir, binary)

    log.info("Binary detection. Source: %s, Destination: %s" %
             (binary_path, dest_binary_path))

    if not os.path.exists(binary_path):
        # notify((getLocalizedString(30103) + " %(os)s_%(arch)s" % PLATFORM), time=7000)
        dialog_ok("LOCALIZE[30347];;" + "%(os)s_%(arch)s" % binary_platform)
        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 not os.path.exists(
            binary_path) or get_elementumd_checksum(
                dest_binary_path) != get_elementumd_checksum(
                    binary_path) or not filecmp.cmp(
                        dest_binary_path, binary_path, shallow=True):
        log.info("Updating elementum 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)

    log.info("Binary detection: [ Source: %s, Destination: %s ]" %
             (binary_path, dest_binary_path))
    return dest_binary_dir, ensure_exec_perms(dest_binary_path)
Beispiel #26
0
def doAssign():
    mediatype = getMediaType()

    try:
        path = sys.listitem.getfilename()
    except AttributeError:
        path = sys.listitem.getPath()

    use_elementum_path = False

    try:
        tmdbID = sys.listitem.getUniqueID('tmdb')
    except AttributeError:
        tmdbID = ""

    if tmdbID == "":
        if path.startswith("plugin://plugin.video.elementum"):
            use_elementum_path = True
            tmdbID = getTMDBidFromElementumPath(path)
            if not tmdbID:
                return

            if mediatype == 'season':
                season_number = getSeasonNumberFromElementumPath(path)
                if not season_number:
                    return

            if mediatype == 'episode':
                season_number = getSeasonNumberFromElementumPath(path)
                episode_number = getEpisodeNumberFromElementumPath(path)
                if not season_number or not episode_number:
                    return
        else:
            dbid = getDbId()
            if not dbid.isdigit():
                log.error("Kodi library ID is wrong %s" % dbid)
                xbmcgui.Dialog().notification(ADDON.getLocalizedString(32007),
                                              ADDON.getLocalizedString(32016),
                                              xbmcgui.NOTIFICATION_WARNING,
                                              3000)
                return

    # we also can use plugin://plugin.video.elementum/torrents/
    file = xbmcgui.Dialog().browseSingle(
        1, ADDON.getLocalizedString(32010), 'files', '', False, False,
        'plugin://plugin.video.elementum/history/')

    if file == '':
        return

    try:
        parsed_url = urlparse(file)
        params = parse_qs(parsed_url.query)
        if 'infohash' in params:
            torrentid = params['infohash'][0]
        else:
            torrentid = params['resume'][0]
    except Exception as e:
        log.error("Could not get torrent info for %s: %s" % (file, e))
        xbmcgui.Dialog().notification(ADDON.getLocalizedString(32007),
                                      ADDON.getLocalizedString(32015),
                                      xbmcgui.NOTIFICATION_WARNING, 3000)
        return

    if use_elementum_path:
        if mediatype == 'movie':
            url = "plugin://plugin.video.elementum/context/torrents/assign/%s/tmdb/%s/%s" % (
                torrentid, mediatype, tmdbID)
        elif mediatype == 'season':
            url = "plugin://plugin.video.elementum/context/torrents/assign/%s/tmdb/show/%s/%s/%s" % (
                torrentid, tmdbID, mediatype, season_number)
        elif mediatype == 'episode':
            url = "plugin://plugin.video.elementum/context/torrents/assign/%s/tmdb/show/%s/season/%s/%s/%s" % (
                torrentid, tmdbID, season_number, mediatype, episode_number)
        log.info("Assigning torrent %s for: TMDBID=%s, MediaType=%s" %
                 (torrentid, tmdbID, mediatype))
    else:
        if tmdbID != "":
            url = "plugin://plugin.video.elementum/torrents/assign/%s/%s" % (
                torrentid, tmdbID)
            log.info("Assigning torrent %s for: TMDBID=%s, MediaType=%s" %
                     (torrentid, tmdbID, mediatype))
        else:
            url = "plugin://plugin.video.elementum/context/torrents/assign/%s/kodi/%s/%s" % (
                torrentid, mediatype, dbid)
            log.info("Assigning torrent %s for: DBID=%s, MediaType=%s" %
                     (torrentid, dbid, mediatype))

    xbmcgui.Dialog().notification(ADDON.getLocalizedString(32010),
                                  sys.listitem.getLabel(),
                                  xbmcgui.NOTIFICATION_INFO, 3000)

    log.info("Starting Elementum with: %s" % url)

    xbmc.Player().play(url)