Ejemplo n.º 1
0
 def _dispatch_delete(self, objectname):
     try:
         self._objects[objectname]._shutdown()
     except Exception:
         _log.error("Error when shutting down the object %s:",
                    type(self._objects[objectname]))
         _log.debug(traceback.format_exc())
     del self._objects[objectname]
Ejemplo n.º 2
0
    def onSettingsChanged(self):
        log.debug('{0}.onSettingsChanged()'.format(self))

        try:
            init()
            urllib_request.urlopen("%s/reload" % ELEMENTUMD_HOST)
            urllib_request.urlopen("%s/cmd/clear_page_cache" % ELEMENTUMD_HOST)
        except:
            pass
Ejemplo n.º 3
0
 def http_error_302(self, req, fp, code, msg, headers):
     infourl = urllib_response.addinfourl(fp, headers, headers["Location"])
     try:
         infourl.status = code
     except AttributeError:
         pass
     infourl.code = code
     log.debug("Redirecting with code %d to: %s", code, headers["Location"])
     return infourl
Ejemplo n.º 4
0
    def Dialog_Browse_Single(self, type, heading, shares, mask, useThumbs,
                             treatAsFolder, defaultt):
        fn = six.ensure_text(xbmcgui.Dialog().browseSingle(
            type, getLocalizedLabel(heading), shares, mask, useThumbs,
            treatAsFolder, defaultt),
                             errors='ignore')
        log.debug("Dialog_Browse_Single got file %s", fn)

        return fn
Ejemplo n.º 5
0
def register(search, search_movie, search_episode, search_season=None):
    try:
        payload = json.loads(base64.b64decode(sys.argv[1]))
    except:
        notify(getElementumLocalizedString(30102), time=1000)
        return

    results = ()
    method = {
        "search": search,
        "search_movie": search_movie,
        "search_season": search_season,
        "search_episode": search_episode,
    }.get(payload["method"]) or (lambda *a, **kw: [])
    try:
        results = ()
        try:
            objects = method(payload["search_object"])
            if objects is not None:
                results = tuple(objects)
        except Exception as e:
            import traceback
            map(log.error, traceback.format_exc().split("\n"))
            notify(
                py2_encode(
                    "%s: %s" % (getElementumLocalizedString(30224), repr(e)),
                    'utf-8'))
            try:
                urllib_request.urlopen("%s/provider/%s/failure" %
                                       (ELEMENTUMD_HOST, ADDON_ID))
            except:
                pass
    finally:
        try:
            req_data = json.dumps(results)
            if not PY2 and isinstance(req_data, str):
                req_data = req_data.encode()
            req = urllib_request.Request(payload["callback_url"],
                                         data=req_data)
            with closing(urllib_request.urlopen(req)) as response:
                log.debug("callback returned: %d" % response.getcode())
        except Exception as e:
            import traceback
            map(log.error, traceback.format_exc().split("\n"))
            notify(
                py2_encode(
                    "%s: %s" % (getElementumLocalizedString(30224), repr(e)),
                    'utf-8'))
            try:
                urllib_request.urlopen("%s/provider/%s/failure" %
                                       (ELEMENTUMD_HOST, ADDON_ID))
            except:
                pass
Ejemplo n.º 6
0
    def read_and_dispatch(self, timeout=None, thread=True, condition=None):
        """
            Read one message from socket (with timeout specified by the optional
            argument *timeout*) and dispatches that message.

            Parameters:

            **timeout** = None
                Timeout in seconds of the read operation. If it is None
                (or ommitted) then the read will wait
                until new data is available.

            **(return value)**
                True, in case of the operation has suceeded and **one** message
                has been dispatched. False, if no data or malformed data has
                been received.

        """
        self.read_lock.acquire()
        self.reading_event.set()
        try:
            if condition:
                if condition() is False:
                    return False
            if thread:
                dispatch_item = self.dispatch_item_threaded
            else:
                dispatch_item = self.dispatch_item_single

            data = self.read(timeout=timeout)
            if not data:
                return False
            try:
                item = json.loads(data, self)
                if type(item) is list:  # batch call
                    for i in item:
                        dispatch_item(i)
                elif type(item) is dict:  # std call
                    if 'result' in item:
                        self.dispatch_item_single(item)
                    else:
                        dispatch_item(item)
                else:  # Unknown format :-(
                    _log.debug("Received message with unknown format type: %s",
                               type(item))
                    return False
            except Exception:
                _log.debug(traceback.format_exc())
                return False
            return True
        finally:
            self.reading_event.clear()
            self.read_lock.release()
Ejemplo n.º 7
0
    def Wait_Window_Loaded(self):
        tries = 9
        while self.Window_Is_Loading():
            if tries == 0:
                log.error("Failed to wait till window has finished loading")
                return int(False)

            tries = tries - 1
            time.sleep(0.3)

        log.debug("Finished waiting till window has finished loading")
        return int(True)
Ejemplo n.º 8
0
    def write_line(self, data):
        """
            Write a line *data* to socket. It appends a **newline** at
            the end of the *data* before sending it.

            The string MUST NOT contain **newline** otherwise an AssertionError will
            raise.

            Parameters:

            **data**
                String containing the data to be sent.
        """
        assert ('\n' not in data)
        self.write_lock.acquire()
        try:
            try:
                data = data.encode('utf-8')
            except AttributeError:
                pass
            if self._debug_socket:
                _log.debug("<:%d: %s", len(data), data.decode('utf-8')[:130])

            self._wbuffer += data + b'\n'
            sbytes = 0
            while self._wbuffer:
                try:
                    sbytes = self._sck.send(self._wbuffer)
                except IOError:
                    _log.debug("Read socket error: IOError (timeout: %r)",
                               self._sck.gettimeout())
                    _log.debug(traceback.format_exc(0))
                    return 0
                except socket.error:
                    _log.debug("Read socket error: socket.error (timeout: %r)",
                               self._sck.gettimeout())
                    _log.debug(traceback.format_exc(0))
                    return 0
                except:
                    raise
                if sbytes == 0:
                    break
                self._wbuffer = self._wbuffer[sbytes:]
            if self._wbuffer:
                _log.warning("%d bytes left in write buffer",
                             len(self._wbuffer))
            return len(self._wbuffer)
        finally:
            self.write_lock.release()
Ejemplo n.º 9
0
def doAssign():
    if not configureTMDB():
        return

    dbid = getDbId()
    imdbnumber = getIMDBNumber()
    mediatype = getMediaType()

    xbmcgui.Dialog().notification(
        ADDON.getLocalizedString(32011)
        if mediatype == 'season' else ADDON.getLocalizedString(32010),
        sys.listitem.getLabel(), xbmcgui.NOTIFICATION_INFO, 3000)

    log.debug("Assigning for: DBID=%s, IMDB=%s, MediaType=%s" %
              (dbid, imdbnumber, mediatype))
Ejemplo n.º 10
0
def download_current_version(repo):
    contents_url = "https://api.github.com/repos/%s/git/refs/tags" % (repo)
    log.debug("Downloading repo releases: %s" % (contents_url))
    try:
        with requests.get(contents_url) as r:
            lists = json.loads(r.content, parse_int=str)

            ref = lists[-1]["ref"]
            if ref.find('/'):
                return ref.rsplit('/', 1)[1]

            return ""
    except Exception as e:
        log.error("Could not get list of tags from github: %s" % e)
        raise
Ejemplo n.º 11
0
    def onNotification(self, sender, method, data):
        log.debug('{0}.onNotification({1}, {2}, {3})'.format(
            self, sender, method, py2_decode(data)))

        if PY2:
            data_base64 = base64.b64encode(data)
        else:
            data_base64 = base64.b64encode(data.encode("utf-8"))

        try:
            urllib_request.urlopen(
                "%s/notification?sender=%s&method=%s&data=%s" %
                (ELEMENTUMD_HOST, sender, method, data_base64))
        except:
            pass
Ejemplo n.º 12
0
    def onAbortRequested(self):
        log.debug('{0}.onAbortRequested()'.format(self))

        # Only when closing Kodi
        if self.abortRequested():
            xbmc.executebuiltin("Dialog.Close(all, true)")
            if not ONLY_CLIENT:
                shutdown()
            try:
                self._closing.set()
                self._closing.clear()
            except SystemExit as e:
                if e.code != 0:
                    os._exit(0)
                pass
Ejemplo n.º 13
0
    def _format_exception(self, obj, method, args, kw, exc):
        etype, evalue, etb = exc
        funargs = ", ".join([repr(x) for x in args] +
                            ["%s=%r" % (k, kw[k]) for k in kw])
        if len(funargs) > 40:
            funargs = funargs[:37] + "..."

        _log.error("(%s) In Handler method %s.%s(%s) ",
                   obj.__class__.__module__, obj.__class__.__name__, method,
                   funargs)
        _log.debug("\n".join([
            "%s::%s:%d %s" % (filename, fnname, lineno, srcline) for filename,
            lineno, fnname, srcline in traceback.extract_tb(etb)[1:]
        ]))
        _log.error("Unhandled error: %s: %s", etype.__name__, evalue)
        del etb
        return '%s: %s' % (etype.__name__, evalue)
Ejemplo n.º 14
0
    def _readn(self):
        """
            Internal function which reads from socket waiting for a newline
        """
        streambuffer = self._buffer
        pos = streambuffer.find(b'\n')
        # _log.debug("read...")
        # retry = 0
        while pos == -1:
            data = b''
            try:
                data = self._sck.recv(2048)
            except IOError as inst:
                _log.debug("Read socket error: IOError%r (timeout: %r)",
                           inst.args, self._sck.gettimeout())
                if inst.errno in (errno.EAGAIN, errno.EWOULDBLOCK):
                    if self._sck.gettimeout() == 0:  # if it was too fast
                        self._sck.settimeout(5)
                        continue
                        # time.sleep(0.5)
                        # retry += 1
                        # if retry < 10:
                        #     _log.debug("Retry %s", retry)
                        #     continue
                # _log.debug(traceback.format_exc(0))
                if inst.errno in self._SOCKET_COMM_ERRORS:
                    raise EofError(len(streambuffer))

                return b''
            except socket.error as inst:
                _log.error("Read socket error: socket.error%r (timeout: %r)",
                           inst.args, self._sck.gettimeout())
                # _log.debug(traceback.format_exc(0))
                return b''
            except:
                raise
            if not data:
                raise EofError(len(streambuffer))
            # _log.debug("readbuf+: %r", data)
            streambuffer += data
            pos = streambuffer.find(b'\n')

        self._buffer = streambuffer[pos + 1:]
        streambuffer = streambuffer[:pos]
        # _log.debug("read: %r", buffer)
        return streambuffer
Ejemplo n.º 15
0
    def Player_WatchTimes(self):
        error = ""
        watchedTime = "0"
        videoDuration = "0"
        try:
            watchedTime = str(XBMC_PLAYER.getTime())
            videoDuration = str(XBMC_PLAYER.getTotalTime())
            log.debug("Watched: %s, duration: %s" % (watchedTime, videoDuration))
        except Exception as e:
            error = "Stopped playing: %s" % repr(e)

        watchTimes = {
            "watchedTime": watchedTime,
            "videoDuration": videoDuration,
            "error": error
        }
        return watchTimes
Ejemplo n.º 16
0
 def _send(self, response):
     txtResponse = None
     try:
         txtResponse = json.dumps(response, self)
     except Exception as e:
         _log.error(
             "An unexpected error ocurred when trying to create the message: %r",
             e)
         response = {
             'result': None,
             'error': "InternalServerError: " + repr(e)
         }
         txtResponse = json.dumps(response, self)
     try:
         self.write(txtResponse)
     except TypeError:
         _log.debug("response was: %r", response)
         raise
Ejemplo n.º 17
0
 def write_thread(self):
     abort = False
     while not abort:
         self.write_thread_semaphore.acquire()
         try:
             item = self.write_thread_queue.pop(0)
         except IndexError:  # pop from empty list?
             _log.warning("write queue was empty??")
             continue
         abort = item.get("abort", False)
         event = item.get("event")
         write_data = item.get("write_data")
         if write_data:
             item["result"] = self.write_now(write_data)
         if event:
             event.set()
     if self._debug_socket:
         _log.debug("Writing thread finished.")
Ejemplo n.º 18
0
    def read_line(self):
        """
            Read a line of *data* from socket. It removes the `\\n` at
            the end before returning the value.

            If the original packet contained `\\n`, the message will be decoded
            as two or more messages.

            Returns the line of *data* received from the socket.
        """

        self.read_lock.acquire()
        try:
            data = self._readn()
            if len(data) and self._debug_socket:
                _log.debug(">:%d: %s", len(data), data.decode('utf-8')[:130])
            return data.decode('utf-8')
        finally:
            self.read_lock.release()
Ejemplo n.º 19
0
    def setresponse(self, value):
        """
            Method used by Connection instance to tell Request that a Response
            is available to this request.

            Parameters:

            **value**
                Value (JSON decoded) received from socket.
        """
        self.responses.put(value)
        for callback in self.callbacks:
            try:
                callback(self)
            except Exception as exc:
                _log.error("Error on callback: %r", exc)
                _log.debug(traceback.format_exc())

        self.event_response.set()  # helper for threads.
        if self.auto_close:
            self.close()
Ejemplo n.º 20
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
Ejemplo n.º 21
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")
Ejemplo n.º 22
0
def getInfoLabels():
    id_list = [int(s) for s in sys.argv[0].split("/") if s.isdigit()]
    tmdb_id = id_list[0] if id_list else None

    # if xbmc.getInfoLabel("ListItem.DBID"):
    #     url = "%s/infolabels" % (ELEMENTUMD_HOST)
    # elif not tmdb_id:
    if not tmdb_id:
        request_url = sys.argv[0] + sys.argv[2]
        parsed_url = urlparse.urlparse(request_url)
        query = urlparse.parse_qs(parsed_url.query)
        log.debug("Parsed URL: %s, Query: %s", repr(parsed_url), repr(query))
        if 'tmdb' in query and 'type' in query and query['type'][0] == 'search':
            tmdb_id = query['tmdb'][0]
            url = "%s/search/infolabels/%s" % (ELEMENTUMD_HOST, tmdb_id)
        elif '/search' in parsed_url and 'tmdb' in query:
            tmdb_id = query['tmdb'][0]
            url = "%s/search/infolabels/%s" % (ELEMENTUMD_HOST, tmdb_id)
        elif '/search' in parsed_url and 'q' in query:
            tmdb_id = query['q'][0]
            url = "%s/search/infolabels/%s" % (ELEMENTUMD_HOST, tmdb_id)
        elif 'tmdb' in query and 'type' in query and query['type'][
                0] == 'movie':
            tmdb_id = query['tmdb'][0]
            url = "%s/movie/%s/infolabels" % (ELEMENTUMD_HOST, tmdb_id)
        elif 'show' in query:
            tmdb_id = query['show'][0]
            if 'season' in query and 'episode' in query:
                url = "%s/show/%s/season/%s/episode/%s/infolabels" % (
                    ELEMENTUMD_HOST, tmdb_id, query['season'][0],
                    query['episode'][0])
            else:
                url = "%s/show/%s/infolabels" % (ELEMENTUMD_HOST, tmdb_id)
        else:
            url = "%s/infolabels" % (ELEMENTUMD_HOST)
    elif 'movie' in sys.argv[0]:
        url = "%s/movie/%s/infolabels" % (ELEMENTUMD_HOST, tmdb_id)
    elif ('episode' in sys.argv[0]
          or 'show' in sys.argv[0]) and len(id_list) > 2:
        url = "%s/show/%s/season/%s/episode/%s/infolabels" % (
            ELEMENTUMD_HOST, tmdb_id, id_list[1], id_list[2])
    elif 'show' in sys.argv[0] and len(id_list) == 2:
        url = "%s/show/%s/season/%s/episode/%s/infolabels" % (
            ELEMENTUMD_HOST, tmdb_id, id_list[1], 1)
    else:
        url = "%s/infolabels" % (ELEMENTUMD_HOST)

    log.debug("Resolving TMDB item by calling %s for %s" %
              (url, repr(sys.argv)))

    try:
        with closing(urllib2.urlopen(url)) as response:
            resolved = json.loads(response.read(), parse_int=str)
            if not resolved:
                return {}

            if 'info' in resolved and resolved['info']:
                resolved.update(resolved['info'])

            if 'art' in resolved and resolved['art']:
                resolved['artbanner'] = ''
                for k, v in resolved['art'].items():
                    resolved['art' + k] = v

            if 'info' in resolved:
                del resolved['info']
            if 'art' in resolved:
                del resolved['art']
            if 'stream_info' in resolved:
                del resolved['stream_info']

            if 'DBTYPE' not in resolved:
                resolved['DBTYPE'] = 'video'
            if 'mediatype' not in resolved or resolved['mediatype'] == '':
                resolved['mediatype'] = resolved['DBTYPE']

            return resolved
    except:
        log.debug("Could not resolve TMDB item: %s" % tmdb_id)
        return {}
Ejemplo n.º 23
0
def run(url_suffix=""):
    socket.setdefaulttimeout(int(ADDON.getSetting("buffer_timeout")))
    urllib2.install_opener(urllib2.build_opener(NoRedirectHandler()))

    # Pause currently playing Elementum file to avoid doubling requests
    if xbmc.Player().isPlaying() and ADDON_ID in xbmc.Player().getPlayingFile(
    ):
        xbmc.Player().pause()

    url = sys.argv[0].replace("plugin://%s" % ADDON_ID,
                              ELEMENTUMD_HOST + url_suffix) + sys.argv[2]
    if len(sys.argv) > 3:
        app = sys.argv[3].replace(":", "=")

        # Replacing resume=false with resume=true if item is launched from main window
        title = xbmc.getInfoLabel('ListItem.Title')
        label = xbmc.getInfoLabel('ListItem.Label')
        if "resume" in app and not title and not label:
            app = app.replace("resume=false", "resume=true")

        if "?" in url:
            url += "&" + app
        else:
            url += "?" + app

    log.debug("Requesting %s from %s" % (url, repr(sys.argv)))

    try:
        data = _json(url)
    except urllib2.URLError as e:
        if 'Connection refused' in e.reason:
            notify(getLocalizedString(30116), time=7000)
        else:
            import traceback
            map(log.error, traceback.format_exc().split("\n"))
            notify(e.reason, time=7000)
        return
    except Exception as e:
        import traceback
        map(log.error, traceback.format_exc().split("\n"))
        try:
            msg = unicode(e)
        except:
            try:
                msg = str(e)
            except:
                msg = repr(e)
        notify(getLocalizedLabel(msg), time=7000)
        return

    if not data:
        return

    if data["content_type"]:
        content_type = data["content_type"]
        if data["content_type"].startswith("menus"):
            content_type = data["content_type"].split("_")[1]

        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_UNSORTED)
        if content_type != "tvshows":
            xbmcplugin.addSortMethod(HANDLE,
                                     xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE)
        else:
            xbmcplugin.addSortMethod(HANDLE,
                                     xbmcplugin.SORT_METHOD_TITLE_IGNORE_THE)
        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_DATE)
        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_GENRE)
        xbmcplugin.setContent(HANDLE, content_type)

    listitems = range(len(data["items"]))
    for i, item in enumerate(data["items"]):
        # Translate labels
        if item["label"][0:8] == "LOCALIZE":
            item["label"] = unicode(getLocalizedLabel(item["label"]), 'utf-8')
        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"])
        elif ADDON.getSetting(
                'default_fanart') == 'true' and item["label"] != unicode(
                    getLocalizedString(30218), 'utf-8'):
            fanart = os.path.join(ADDON_PATH, "fanart.png")
            listItem.setArt({'fanart': fanart})
        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"])
        if viewMode:
            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)
Ejemplo n.º 24
0
def run(url_suffix="", retry=0):
    if '/restart/' in sys.argv[0]:
        restart_signal()
        return

    try:
        buffer_timeout = int(ADDON.getSetting("buffer_timeout"))
        if buffer_timeout < 60:
            buffer_timeout = 60
    except:
        buffer_timeout = 60
    buffer_timeout = buffer_timeout * 2

    try:
        preload_timeout = int(ADDON.getSetting("preload_timeout"))
        if preload_timeout < 1:
            preload_timeout = 1
    except:
        preload_timeout = 1

    socket.setdefaulttimeout(buffer_timeout)
    opener = urllib_request.build_opener(NoRedirectHandler())
    opener.addheaders = [('User-Agent', ADDON_ID)]
    urllib_request.install_opener(opener)

    # Pause currently playing Elementum file to avoid doubling requests
    try:
        if xbmc.Player().isPlaying() and ADDON_ID in xbmc.Player(
        ).getPlayingFile():
            xbmc.Player().pause()
    except:
        pass

    url = sys.argv[0].replace("plugin://%s" % ADDON_ID,
                              ELEMENTUMD_HOST + url_suffix) + sys.argv[2]
    query_add = ""

    if len(sys.argv) > 3:
        query_add = sys.argv[3].replace(":", "=")

    if query_add and "resume=" not in url:
        query_add = query_add.replace("resume=", "doresume=")
        if "?" in url:
            url += "&" + query_add
        else:
            url += "?" + query_add

    log.debug("Requesting %s from %s" % (url, repr(sys.argv)))

    try:
        data = _json(url)
    except PlayerException as e:
        redirect_url = e.__str__()
        log.debug("Launching player with %s" % (redirect_url))
        xbmcplugin.endOfDirectory(HANDLE, succeeded=True)
        xbmc.sleep(500)
        xbmc.executeJSONRPC(
            '{"jsonrpc":"2.0","method":"Player.Open","params":{"item":{"file":"%s"}},"id":"1"}'
            % (redirect_url))
        return
    except RedirectException as e:
        redirect_url = e.__str__()
        log.debug("Redirecting Kodi with %s" % (redirect_url))
        xbmcplugin.endOfDirectory(HANDLE, succeeded=True)
        xbmc.sleep(500)
        if "keyboard=1" in sys.argv[0]:
            xbmc.executebuiltin('Container.Update(%s,replace)' %
                                (redirect_url))
        else:
            xbmc.executebuiltin('Container.Update(%s)' % (redirect_url))
        return
    except urllib_error.URLError as e:
        # We can retry the request if connection is refused.
        # For example when plugin has not yet started but is requested by someone.
        if retry <= 2:
            time.sleep(preload_timeout)
            return run(retry=retry + 1)

        if isinstance(e.reason, IOError) or isinstance(
                e.reason, OSError) or 'Connection refused' in e.reason:
            notify(getLocalizedString(30116), time=7000)
        else:
            import traceback
            map(log.error, traceback.format_exc().split("\n"))
            notify(e.reason, time=7000)
        return
    except Exception as e:
        import traceback
        log.debug(traceback.print_exc())
        map(log.error, traceback.format_exc().split("\n"))
        try:
            msg = six.ensure_text(e.__str__(), errors='ignore')
        except:
            try:
                msg = six.ensure_binary(e.__str__(), errors='ignore')
            except:
                msg = repr(e)
        notify(getLocalizedLabel(msg), time=7000)
        return

    if not data:
        return

    if data["content_type"]:
        content_type = data["content_type"]
        if data["content_type"].startswith("menus"):
            content_type = data["content_type"].split("_")[1]

        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_UNSORTED)
        if content_type != "tvshows":
            xbmcplugin.addSortMethod(HANDLE,
                                     xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE)
        else:
            xbmcplugin.addSortMethod(HANDLE,
                                     xbmcplugin.SORT_METHOD_TITLE_IGNORE_THE)
        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_DATE)
        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_GENRE)
        xbmcplugin.setContent(HANDLE, content_type)

    listitems = list(range(len(data["items"])))
    for i, item in enumerate(data["items"]):
        # Translate labels
        if "LOCALIZE" in item["label"]:
            if item["label"][0:8] == "LOCALIZE":
                item["label"] = getLocalizedLabel(item["label"])
            else:
                item["label"] = getLocalizedText(item["label"])
            if isinstance(item["label"], str):
                item["label"] = six.ensure_text(item["label"], 'utf-8')
        if "LOCALIZE" in item["label2"]:
            if item["label2"][0:8] == "LOCALIZE":
                item["label2"] = getLocalizedText(item["label2"])
            else:
                item["label2"] = getLocalizedText(item["label2"])
            if isinstance(item["label2"], str):
                item["label2"] = six.ensure_text(item["label2"], 'utf-8')

        if PLATFORM['kodi'] >= 19:
            listItem = xbmcgui.ListItem(label=item["label"],
                                        label2=item["label2"])
            listItem.setArt({'icon': item["icon"]})
            listItem.setArt({'thumb': item["thumbnail"]})
        else:
            listItem = xbmcgui.ListItem(label=item["label"],
                                        label2=item["label2"],
                                        iconImage=item["icon"],
                                        thumbnailImage=item["thumbnail"])

        try:
            if item.get("castmembers") and PLATFORM['kodi'] >= 17:
                listItem.setCast(item.get("castmembers"))
            if item.get("info"):
                item["info"] = normalizeLabels(item["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"):
                if "fanarts" in item.get("art") and item.get("art")["fanarts"]:
                    try:
                        start = 0
                        fanart_list = []
                        for fa in item.get("art")["fanarts"]:
                            start += 1
                            item.get("art")["fanart{}".format(start)] = fa
                            fanart_list.append({'image': fa})

                        if PLATFORM['kodi'] >= 18:
                            listItem.setAvailableFanart(fanart_list)
                    except Exception as e:
                        log.warning(
                            "Could not initialize ListItem.Art (%s): %s" %
                            (repr(item.get("art")), repr(e)))
                        pass
                    del item.get("art")["fanarts"]

                listItem.setArt(item["art"])
            elif ADDON.getSetting('default_fanart') == 'true' and item[
                    "label"] != six.ensure_text(getLocalizedString(30218),
                                                'utf-8'):
                fanart = os.path.join(ADDON_PATH, "fanart.jpg")
                listItem.setArt({'fanart': fanart})
            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])
                    if PLATFORM['kodi'] >= 19 and menu[1][0:5] == "XBMC.":
                        menu[1] = menu[1][5:]
                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)
        except Exception as e:
            log.warning("Could not initialize ListItem (%s): %s" %
                        (repr(item.get("info")), repr(e)))
        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"])
        if viewMode:
            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 http_error_302(self, req, fp, code, msg, headers):
     infourl = urllib_response.addinfourl(fp, headers, headers["Location"])
     infourl.status = code
     infourl.code = code
     log.debug("Redirecting to: %s", headers["Location"])
     return infourl