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 listitem.getPath() or 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': if self.is_strm or not ADDON.getSettingBool('only_resolve_strm'): resolve_to_dummy(handle, self.dummy_duration, self.dummy_delay) xbmc.executebuiltin(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: if self.is_strm or not ADDON.getSettingBool('only_resolve_strm'): 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'), 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', 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( listitem.getPath(), listitem) if self.force_xbmcplayer else xbmc.executebuiltin( u'PlayMedia({})'.format(listitem.getPath())) kodi_log([ 'Finished executing {}\n'.format( 'xbmc.Player()' if self.force_xbmcplayer else 'PlayMedia'), listitem.getPath() ], 1)
def set_property(self, key, value): key = u'{}.{}'.format(self.property_prefix, key) if value is None: get_property(key, clear_property=True) else: get_property(key, set_property=u'{0}'.format(value))
def _win_prop(name, prefix=None, **kwargs): if not name: return prefix = u'UserDiscover.{}'.format(prefix) if prefix else 'UserDiscover' return get_property(u'{}.{}'.format(prefix, name), **kwargs)
def clear_property(self, key): key = '{}.{}'.format(self.property_prefix, key) try: get_property(key, clear_property=True) except Exception as exc: kodi_log(['Func: clear_property\n', key, exc], 1)
def clear_property(self, key): key = u'{}.{}'.format(self.property_prefix, key) get_property(key, clear_property=True)
def set_properties(self, position=1, path=None): self.position = position self.added_path = path or '' window.get_property(PREFIX_CURRENT, set_property=path) window.get_property('{}{}'.format(PREFIX_PATH, position), set_property=path) window.get_property(PREFIX_POSITION, set_property=position)
def _on_add(self): self.position += 1 self.set_properties(self.position, window.get_property(PREFIX_ADDPATH)) window.wait_for_property(PREFIX_ADDPATH, None, True) # Clear property before continuing
def run(self): get_property('ServiceStarted', 'True') self.cron_job.start() self.player_monitor = PlayerMonitor() self.poller()
def restart_service_monitor(): if get_property('ServiceStarted') == 'True': wait_for_property('ServiceStop', value='True', set_property=True) # Stop service wait_for_property('ServiceStop', value=None) # Wait until Service clears property Thread(target=ServiceMonitor().run).start()
def timeout_error(self, err): """ Log timeout error - if two in one minute set connection error """ if get_timestamp(self.req_timeout_err): self.connection_error(err) self.req_timeout_err = set_timestamp() get_property(self.req_timeout_err_prop, self.req_timeout_err)
def get_season_list(self, tmdb_id, special_folders=0): """ special_folders: int binary to hide: 001 (1) = Hide Specials, 010 (2) = Hide Up Next, 100 (4) = Hide Groups """ request = self.get_request_sc(u'tv/{}'.format(tmdb_id)) if not request: return [] base_item = self.mapper.get_info(request, 'tv') items, items_end = [], [] for i in request.get('seasons', []): item = self.mapper.get_info(i, 'season', base_item, definition=TMDB_PARAMS_SEASONS, tmdb_id=tmdb_id) # TODO: Fix play all # Might be issue with resolving to dummy file that resets playlist to 1 # item['context_menu'] += [( # xbmc.getLocalizedString(22083), # 'RunScript(plugin.video.themoviedb.helper,play_season={},tmdb_id={})'.format( # item['infolabels']['season'], tmdb_id))] if i.get('season_number') != 0: items.append(item) elif ((special_folders >> 0) & 1) == 0: # on bit in 0 pos hides specials items_end.append(item) # Episode Groups if ((special_folders >> 2) & 1) == 0: # on bit in 2 pos hides episode groups egroups = self.get_request_sc( u'tv/{}/episode_groups'.format(tmdb_id)) if egroups and egroups.get('results'): egroup_item = self.mapper.get_info( {'title': ADDON.getLocalizedString(32345)}, 'season', base_item, tmdb_id=tmdb_id, definition={ 'info': 'episode_groups', 'tmdb_type': 'tv', 'tmdb_id': tmdb_id }) egroup_item['art']['thumb'] = egroup_item['art'][ 'poster'] = u'{}/resources/icons/trakt/groupings.png'.format( ADDONPATH) items_end.append(egroup_item) # Up Next if ((special_folders >> 1) & 1) == 0: # on bit in 1 pos hides up next if get_property('TraktIsAuth') == 'True': upnext_item = self.mapper.get_info( {'title': ADDON.getLocalizedString(32043)}, 'season', base_item, tmdb_id=tmdb_id, definition={ 'info': 'trakt_upnext', 'tmdb_type': 'tv', 'tmdb_id': tmdb_id }) upnext_item['art']['thumb'] = upnext_item['art'][ 'poster'] = u'{}/resources/icons/trakt/up-next.png'.format( ADDONPATH) items_end.append(upnext_item) return items + items_end
def get_listitem(self): self.get_container() # Don't bother getting new details if we've got the same item if self.is_same_item(update=True): return # Parent folder item so clear properties and stop if self.get_infolabel('Label') == '..': return self.clear_properties() # Set our is_updating flag get_property('IsUpdating', 'True') # If the folder changed let's clear all the properties before doing a look-up # Possible that our new look-up will fail so good to have a clean slate if not self.is_same_folder(): self.clear_properties() # Get look-up details self.set_cur_item() # Blur Image if xbmc.getCondVisibility("Skin.HasSetting(TMDbHelper.EnableBlur)"): self.blur_img = ImageFunctions( method='blur', artwork=self.get_artwork( source=get_property('Blur.SourceImage'), fallback=get_property('Blur.Fallback'))) self.blur_img.setName('blur_img') self.blur_img.start() self._last_blur_fallback = False # Desaturate Image if xbmc.getCondVisibility( "Skin.HasSetting(TMDbHelper.EnableDesaturate)"): self.desaturate_img = ImageFunctions( method='desaturate', artwork=self.get_artwork( source=get_property('Desaturate.SourceImage'), fallback=get_property('Desaturate.Fallback'))) self.desaturate_img.setName('desaturate_img') self.desaturate_img.start() # CompColors if xbmc.getCondVisibility("Skin.HasSetting(TMDbHelper.EnableColors)"): self.colors_img = ImageFunctions( method='colors', artwork=self.get_artwork( source=get_property('Colors.SourceImage'), fallback=get_property('Colors.Fallback'))) self.colors_img.setName('colors_img') self.colors_img.start() # Allow early exit to only do image manipulations if xbmc.getCondVisibility("!Skin.HasSetting(TMDbHelper.Service)"): return get_property('IsUpdating', clear_property=True) # Need a TMDb type to do a details look-up so exit if we don't have one tmdb_type = self.get_tmdb_type() if not tmdb_type: self.clear_properties() return get_property('IsUpdating', clear_property=True) # Immediately clear some properties like ratings and artwork # Don't want these to linger on-screen if the look-up takes a moment if self.dbtype not in ['episodes', 'seasons']: self.clear_property_list(SETMAIN_ARTWORK) self.clear_property_list(SETPROP_RATINGS) # Get TMDb Details tmdb_id = self.get_tmdb_id( tmdb_type, self.imdb_id, self.query, year=self.year if tmdb_type == 'movie' else None, episode_year=self.year if tmdb_type == 'tv' else None) details = self.tmdb_api.get_details(tmdb_type, tmdb_id, self.season, self.episode) if not details: self.clear_properties() return get_property('IsUpdating', clear_property=True) # Need to update Next Aired with a shorter cache time than details if tmdb_type == 'tv' and details.get('infoproperties'): details['infoproperties'].update( self.tmdb_api.get_tvshow_nextaired(tmdb_id)) # Get our artwork properties if xbmc.getCondVisibility( "!Skin.HasSetting(TMDbHelper.DisableArtwork)"): thread_artwork = Thread(target=self.process_artwork, args=[details, tmdb_type]) thread_artwork.start() # Item changed whilst retrieving details so lets clear and get next item if not self.is_same_item(): ignore_keys = None if self.dbtype in ['episodes', 'seasons']: ignore_keys = SETMAIN_ARTWORK self.clear_properties(ignore_keys=ignore_keys) return get_property('IsUpdating', clear_property=True) # Get person library statistics if tmdb_type == 'person' and details.get('infolabels', {}).get('title'): if xbmc.getCondVisibility( "!Skin.HasSetting(TMDbHelper.DisablePersonStats)"): details.setdefault('infoproperties', {}).update( get_person_stats(details['infolabels']['title']) or {}) # Get our item ratings if xbmc.getCondVisibility( "!Skin.HasSetting(TMDbHelper.DisableRatings)"): thread_ratings = Thread(target=self.process_ratings, args=[details, tmdb_type, tmdb_id]) thread_ratings.start() self.set_properties(details) get_property('IsUpdating', clear_property=True)
def get_container(): widget_id = get_property('WidgetContainer', is_type=int) if widget_id: return u'Container({0}).'.format(widget_id) return 'Container.'
def split_value(split_value, separator=None, **kwargs): split_value = split_value or '' for x, i in enumerate(split_value.split(separator or ' / ')): name = u'{}.{}'.format(kwargs.get('property') or 'TMDbHelper.Split', x) get_property(name, set_property=i, prefix=-1)