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]
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
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
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
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
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()
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)
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()
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))
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
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
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
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)
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
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
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
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.")
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()
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()
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
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")
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 {}
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)
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