def related_lists(tmdb_id=None, tmdb_type=None, season=None, episode=None, container_update=True, include_play=False, **kwargs): if not tmdb_id or not tmdb_type: return items = get_basedir_details(tmdb_type=tmdb_type, tmdb_id=tmdb_id, season=season, episode=episode, include_play=include_play) if not items or len(items) <= 1: return choice = xbmcgui.Dialog().contextmenu([i.get('label') for i in items]) if choice == -1: return item = items[choice] params = item.get('params') if not params: return item['params']['tmdb_id'] = tmdb_id item['params']['tmdb_type'] = tmdb_type if not container_update: return item path = format_folderpath( path=encode_url(path=item.get('path'), **item.get('params')), info=item['params']['info'], play= 'RunPlugin', # Use RunPlugin to avoid window manager info dialog crash with Browse method content='pictures' if item['params']['info'] in ['posters', 'fanart'] else 'videos') xbmc.executebuiltin(try_encode(path))
def _do_cleanup(self): '''perform cleanup task''' if self._exit or self._monitor.abortRequested(): return with self.busy_tasks(__name__): cur_time = datetime.datetime.now() cur_timestamp = self._get_timestamp(cur_time) kodi_log("CACHE: Running cleanup...") if self._win.getProperty("{}.cleanbusy".format(self._sc_name)): return self._win.setProperty("{}.cleanbusy".format(self._sc_name), "busy") query = "SELECT id, expires FROM simplecache" for cache_data in self._execute_sql(query).fetchall(): cache_id = cache_data[0] cache_expires = cache_data[1] if self._exit or self._monitor.abortRequested(): return # always cleanup all memory objects on each interval self._win.clearProperty(try_encode(cache_id)) # clean up db cache object only if expired if cache_expires < cur_timestamp: query = 'DELETE FROM simplecache WHERE id = ?' self._execute_sql(query, (cache_id, )) kodi_log("CACHE: delete from db {}".format(cache_id)) # compact db self._execute_sql("VACUUM") # Washup self._win.setProperty("{}.clean.lastexecuted".format(self._sc_name), repr(cur_time)) self._win.clearProperty("{}.cleanbusy".format(self._sc_name)) kodi_log("CACHE: Auto cleanup done")
def run_plugin(**kwargs): with busy_dialog(): kodi_log([ 'lib.script.router - attempting to play\n', kwargs.get('run_plugin') ], 1) xbmc.executebuiltin( try_encode(u'RunPlugin({})'.format(kwargs.get('run_plugin'))))
def play_media(**kwargs): with busy_dialog(): kodi_log([ 'lib.script.router - attempting to play\n', kwargs.get('play_media') ], 1) xbmc.executebuiltin( try_encode(u'PlayMedia({})'.format(kwargs.get('play_media'))))
def sort_list(**kwargs): sort_methods = get_sort_methods() x = xbmcgui.Dialog().contextmenu([i['name'] for i in sort_methods]) if x == -1: return for k, v in viewitems(sort_methods[x]['params']): kwargs[k] = v xbmc.executebuiltin(try_encode(format_folderpath(encode_url(**kwargs))))
def _get_mem_cache(self, endpoint, checksum, cur_time): ''' get cache data from memory cache we use window properties because we need to be stateless ''' endpoint = u'{}_{}'.format( self._sc_name, endpoint) # Append name of cache since we can change it now cachedata = self._win.getProperty(try_encode(endpoint)) if not cachedata: return cachedata = literal_eval(cachedata) if not cachedata or cachedata[0] <= cur_time: return if not checksum or checksum == cachedata[2]: return cachedata[1]
def get_directory(self): items = self.get_items(**self.params) if not items: return self.add_items( items, pagination=self.pagination, parent_params=self.parent_params, property_params=self.set_params_to_container(**self.params), kodi_db=self.kodi_db, tmdb_cache_only=self.tmdb_cache_only) self.finish_container( update_listing=self.update_listing, plugin_category=self.plugin_category, container_content=self.container_content) if self.container_update: xbmc.executebuiltin(try_encode(u'Container.Update({})'.format(self.container_update))) if self.container_refresh: xbmc.executebuiltin('Container.Refresh')
def _update_listing_hack(self, folder_path=None, reset_focus=None): """ Some plugins use container.update after search results to rewrite path history This is a quick hack to rewrite the path back to our original path before updating """ if not folder_path: return xbmc.Monitor().waitForAbort(2) container_folderpath = xbmc.getInfoLabel("Container.FolderPath") if container_folderpath == folder_path: return xbmc.executebuiltin( try_encode(u'Container.Update({},replace)'.format(folder_path))) if not reset_focus: return timeout = 20 while not xbmc.Monitor().abortRequested() and xbmc.getInfoLabel( "Container.FolderPath") != folder_path and timeout > 0: xbmc.Monitor().waitForAbort(0.25) timeout -= 1 xbmc.executebuiltin(reset_focus) xbmc.Monitor().waitForAbort(0.5)
def write_to_file(filepath, content): f = xbmcvfs.File(filepath, 'w') f.write(try_encode(content)) f.close()
def play(self, folder_path=None, reset_focus=None, handle=None): # Get some info about current container for container update hack if not folder_path: folder_path = xbmc.getInfoLabel("Container.FolderPath") if not reset_focus and folder_path: containerid = xbmc.getInfoLabel("System.CurrentControlID") current_pos = xbmc.getInfoLabel( "Container({}).CurrentItem".format(containerid)) reset_focus = 'SetFocus({},{},absolute)'.format( containerid, try_int(current_pos) - 1) # Get the resolved path listitem = self.get_resolved_path() # Reset folder hack self._update_listing_hack(folder_path=folder_path, reset_focus=reset_focus) # Check we have an actual path to open if not try_decode(listitem.getPath()) or try_decode( listitem.getPath()) == PLUGINPATH: return action = self.configure_action(listitem, handle) # Kodi launches busy dialog on home screen that needs to be told to close # Otherwise the busy dialog will prevent window activation for folder path xbmc.executebuiltin('Dialog.Close(busydialog)') # If a folder we need to resolve to dummy and then open folder if listitem.getProperty('is_folder') == 'true': resolve_to_dummy(handle, self.dummy_duration, self.dummy_delay) xbmc.executebuiltin(try_encode(action)) kodi_log(['lib.player - finished executing action\n', action], 1) return # Set our playerstring for player monitor to update kodi watched status if self.playerstring: get_property('PlayerInfoString', set_property=self.playerstring) # If PlayMedia method chosen re-route to Player() unless expert settings on if action: resolve_to_dummy( handle, self.dummy_duration, self.dummy_delay ) # If we're calling external we need to resolve to dummy xbmc.Player().play( action, listitem) if self.force_xbmcplayer else xbmc.executebuiltin( u'PlayMedia({})'.format(action)) kodi_log([ 'lib.player - playing path with {}\n'.format( 'xbmc.Player()' if self.force_xbmcplayer else 'PlayMedia'), try_decode(listitem.getPath()) ], 1) return # Otherwise we have a url we can resolve to xbmcplugin.setResolvedUrl(handle, True, listitem) kodi_log([ 'lib.player - finished resolving path to url\n', try_decode(listitem.getPath()) ], 1) # Re-send local files to player due to "bug" (or maybe "feature") of setResolvedUrl # Because setResolvedURL doesn't set id/type (sets None, "unknown" instead) to player for plugins # If id/type not set to Player.GetItem things like Trakt don't work correctly. # Looking for better solution than this hack. if ADDON.getSettingBool('trakt_localhack') and listitem.getProperty( 'is_local') == 'true': xbmc.Player().play( try_decode(listitem.getPath()), listitem) if self.force_xbmcplayer else xbmc.executebuiltin( u'PlayMedia({})'.format(try_decode(listitem.getPath()))) kodi_log([ 'Finished executing {}\n'.format( 'xbmc.Player()' if self.force_xbmcplayer else 'PlayMedia'), try_decode(listitem.getPath()) ], 1)
def get_detailed_item(tmdb_type, tmdb_id, season=None, episode=None, details=None): details = details or get_item_details(tmdb_type, tmdb_id, season, episode) if not details: return None item = defaultdict(lambda: '+') item['id'] = item['tmdb'] = tmdb_id item['imdb'] = details.unique_ids.get('imdb') item['tvdb'] = details.unique_ids.get('tvdb') item['trakt'] = details.unique_ids.get('trakt') item['slug'] = details.unique_ids.get('slug') item['season'] = season item['episode'] = episode item['originaltitle'] = details.infolabels.get('originaltitle') item['title'] = details.infolabels.get( 'tvshowtitle') or details.infolabels.get('title') item['showname'] = item['clearname'] = item['tvshowtitle'] = item.get( 'title') item['year'] = details.infolabels.get('year') item['name'] = u'{} ({})'.format(item.get('title'), item.get('year')) item['premiered'] = item['firstaired'] = item[ 'released'] = details.infolabels.get('premiered') item['plot'] = details.infolabels.get('plot') item['cast'] = item['actors'] = " / ".join( [i.get('name') for i in details.cast if i.get('name')]) item['thumbnail'] = details.art.get('thumb') item['poster'] = details.art.get('poster') item['fanart'] = details.art.get('fanart') item['now'] = datetime.datetime.now().strftime('%Y%m%d%H%M%S%f') if tmdb_type == 'tv' and season is not None and episode is not None: item['id'] = item['epid'] = item['eptvdb'] = item.get('tvdb') item['title'] = details.infolabels.get('title') # Set Episode Title item['name'] = u'{0} S{1:02d}E{2:02d}'.format(item.get('showname'), try_int(season), try_int(episode)) item['season'] = season item['episode'] = episode item['showpremiered'] = details.infoproperties.get('tvshow.premiered') item['showyear'] = details.infoproperties.get('tvshow.year') item['eptmdb'] = details.unique_ids.get('tmdb') item['epimdb'] = details.unique_ids.get('imdb') item['eptrakt'] = details.unique_ids.get('trakt') item['epslug'] = details.unique_ids.get('slug') item['tmdb'] = details.unique_ids.get('tvshow.tmdb') item['imdb'] = details.unique_ids.get('tvshow.imdb') item['tvdb'] = details.unique_ids.get('tvshow.tvdb') item['trakt'] = details.unique_ids.get('tvshow.trakt') item['slug'] = details.unique_ids.get('tvshow.slug') for k, v in viewitems(item.copy()): if k not in PLAYERS_URLENCODE: continue v = u'{0}'.format(v) for key, value in viewitems({k: v, '{}_meta'.format(k): dumps(v)}): item[key] = value.replace(',', '') item[key + '_+'] = value.replace(',', '').replace(' ', '+') item[key + '_-'] = value.replace(',', '').replace(' ', '-') item[key + '_escaped'] = quote(quote(try_encode(value))) item[key + '_escaped+'] = quote(quote_plus(try_encode(value))) item[key + '_url'] = quote(try_encode(value)) item[key + '_url+'] = quote_plus(try_encode(value)) return item