def get_kodi_details(self, item): #return item if not self.dbid or self.dbid == '': return item details = {} if self.dbtype == 'movies': details = KodiLibrary().get_movie_details(self.dbid) if self.dbtype == 'tvshows': details = KodiLibrary().get_tvshow_details(self.dbid) if self.dbtype == 'episodes': details = KodiLibrary().get_episode_details(self.dbid) if self.dbtype == 'sets': details = KodiLibrary().get_movieset_details(self.dbid) #utils.kodi_log('SetCount{0}'.format(item['infoproperties']['set.numitems']), 2) if not details: return item #self.icon = details.get('icon') or self.icon #self.thumb = details.get('thumb') or self.thumb #self.poster = details.get('poster') or self.poster #self.fanart = details.get('fanart') or self.fanart #self.landscape = details.get('landscape') or self.landscape #self.clearart = details.get('clearart') or self.clearart #self.clearlogo = details.get('clearlogo') or self.clearlogo #self.discart = details.get('discart') or self.discart #self.cast = self.cast or details.get('cast', []) item['infolabels'] = utils.merge_dicts_overwrite_empty( item.get('infolabels', {}), details.get('infolabels', {})) item['infoproperties'] = utils.merge_dicts_overwrite_empty( item.get('infoproperties', {}), details.get('infoproperties', {})) #self.streamdetails = details.get('streamdetails', {}) return item
def localepisode(self): # fuzzy_match = self.addon.getSettingBool('fuzzymatch_tv') dbid = KodiLibrary(dbtype='tvshow').get_info( 'dbid', fuzzy_match=False, tmdb_id=self.item.get('tmdb_id'), tvdb_id=self.item.get('tvdb_id'), imdb_id=self.item.get('imdb_id')) return self.localfile(KodiLibrary(dbtype='episode', tvshowid=dbid).get_info( 'file', season=self.season, episode=self.episode))
def playepisode(self): fuzzy_match = self.addon.getSettingBool('fuzzymatch_tv') dbid = KodiLibrary(dbtype='tvshow').get_info('dbid', fuzzy_match=fuzzy_match, **self.item) return self.playfile( KodiLibrary(dbtype='episode', tvshowid=dbid).get_info('file', season=self.season, episode=self.episode))
def localepisode(self): fuzzy_match = self.addon.getSettingBool('fuzzymatch_tv') fuzzy_match = True # TODO: Get tvshow year to match against but for now force fuzzy match dbid = KodiLibrary(dbtype='tvshow').get_info('dbid', fuzzy_match=fuzzy_match, **self.item) return self.localfile( KodiLibrary(dbtype='episode', tvshowid=dbid).get_info('file', season=self.season, episode=self.episode))
def localmovie(self): # fuzzy_match = self.addon.getSettingBool('fuzzymatch_movie') return self.localfile( KodiLibrary(dbtype='movie').get_info( 'file', fuzzy_match=False, tmdb_id=self.item.get('tmdb_id'), imdb_id=self.item.get('imdb_id')))
def get_kodi_person_stats(self, item): if item.get('infolabels', {}).get('title'): statistics = KodiLibrary().get_person_stats( item.get('infolabels', {}).get('title')) if statistics: item['infoproperties'] = utils.merge_two_dicts( item.get('infoproperties', {}), statistics) return item
def player_resolveurl(self, player=None): if not player or not player[1] or not isinstance(player[1], list): return player # No player configured or not a list of actions so return keyboard_input = None player_actions = player[1] player = (False, player_actions[0] ) # player tuple is: isPlayable flag; path URI to call. for action in player_actions[1:]: # If playable item was found in last action then let's break and play it if player[0]: break # Start thread with keyboard inputter if needed if action.get('keyboard'): if action.get('keyboard') in [ 'Up', 'Down', 'Left', 'Right', 'Select' ]: keyboard_input = KeyboardInputter( action="Input.{}".format(action.get('keyboard'))) else: keyboard_input = KeyboardInputter(text=string_format_map( action.get('keyboard', ''), self.item)) keyboard_input.setName('keyboard_input') keyboard_input.start() continue # Go to next action # Get the next folder from the plugin with utils.busy_dialog(): folder = KodiLibrary().get_directory( string_format_map(player[1], self.item)) # Kill our keyboard inputter thread if keyboard_input: keyboard_input.exit = True keyboard_input = None # Special option to show dialog of items to select from if action.get('dialog'): auto = True if action.get('dialog', '').lower() == 'auto' else False return self.player_dialogselect(folder, auto=auto) utils.kodi_log( 'Player -- Retrieved Folder\n{}'.format( string_format_map(player[1], self.item)), 2) # Iterate through plugin folder looking for item that matches rules player = self.player_applyrules(folder, action) or player if player == -1: break return player
def library_addtvshow(basedir=None, folder=None, url=None, tmdb_id=None): if not basedir or not folder or not url: return seasons = library_cleancontent(url, details='info=seasons') seasons = KodiLibrary().get_directory(seasons) library_create_nfo('tv', tmdb_id, folder, basedir=basedir) for season in seasons: if not season.get('season'): continue # Skip special seasons S00 season_name = 'Season {}'.format(season.get('season')) episodes = KodiLibrary().get_directory(season.get('file')) for episode in episodes: if not episode.get('episode'): continue # Skip special episodes E00 episode_path = library_cleancontent(episode.get('file')) episode_name = 'S{:02d}E{:02d} - {}'.format( utils.try_parse_int(episode.get('season')), utils.try_parse_int(episode.get('episode')), utils.validify_filename(episode.get('title'))) library_createfile(episode_name, episode_path, folder, season_name, basedir=basedir)
def library(): with utils.busy_dialog(): title = utils.validify_filename(sys.listitem.getVideoInfoTag().getTitle()) dbtype = sys.listitem.getVideoInfoTag().getMediaType() basedir_movie = _addon.getSettingString('movies_library') or 'special://profile/addon_data/plugin.video.skin.info.provider/movies/' basedir_tv = _addon.getSettingString('tvshows_library') or 'special://profile/addon_data/plugin.video.skin.info.provider/tvshows/' auto_update = _addon.getSettingBool('auto_update') or False # Setup our folders and file names if dbtype == 'movie': folder = '{} ({})'.format(title, sys.listitem.getVideoInfoTag().getYear()) movie_name = '{} ({})'.format(title, sys.listitem.getVideoInfoTag().getYear()) library_createfile(movie_name, sys.listitem.getPath(), folder, basedir=basedir_movie) library_create_nfo('movie', sys.listitem.getProperty('tmdb_id'), folder, basedir=basedir_movie) xbmc.executebuiltin('UpdateLibrary(video, {})'.format(basedir_movie)) if auto_update else None elif dbtype == 'episode': folder = sys.listitem.getVideoInfoTag().getTVShowTitle() season_name = 'Season {}'.format(sys.listitem.getVideoInfoTag().getSeason()) episode_name = 'S{:02d}E{:02d} - {}'.format( utils.try_parse_int(sys.listitem.getVideoInfoTag().getSeason()), utils.try_parse_int(sys.listitem.getVideoInfoTag().getEpisode()), title) library_createfile(episode_name, sys.listitem.getPath(), folder, season_name, basedir=basedir_tv) library_create_nfo('tv', sys.listitem.getProperty('tvshow.tmdb_id'), folder, basedir=basedir_tv) xbmc.executebuiltin('UpdateLibrary(video, {})'.format(basedir_tv)) if auto_update else None elif dbtype == 'tvshow': folder = sys.listitem.getVideoInfoTag().getTVShowTitle() or title library_addtvshow( basedir=basedir_tv, folder=folder, url=sys.listitem.getPath(), tmdb_id=sys.listitem.getProperty('tmdb_id')) xbmc.executebuiltin('UpdateLibrary(video, {})'.format(basedir_tv)) if auto_update else None elif dbtype == 'season': folder = sys.listitem.getVideoInfoTag().getTVShowTitle() episodes = KodiLibrary().get_directory(sys.listitem.getPath()) season_name = 'Season {}'.format(sys.listitem.getVideoInfoTag().getSeason()) for episode in episodes: if not episode.get('episode'): continue # Skip special episodes E00 episode_path = library_cleancontent(episode.get('file')) episode_name = 'S{:02d}E{:02d} - {}'.format( utils.try_parse_int(episode.get('season')), utils.try_parse_int(episode.get('episode')), utils.validify_filename(episode.get('title'))) library_createfile(episode_name, episode_path, folder, season_name, basedir=basedir_tv) library_create_nfo('tv', sys.listitem.getProperty('tvshow.tmdb_id'), folder, basedir=basedir_tv) xbmc.executebuiltin('UpdateLibrary(video, {})'.format(basedir_tv)) if auto_update else None else: return
def library_addtvshow(basedir=None, folder=None, url=None, tmdb_id=None, tvdb_id=None, imdb_id=None, p_dialog=None): if not basedir or not folder or not url: return seasons = library_cleancontent_replacer(url, 'type=episode', 'type=tv') # Clean-up flatseasons seasons = library_cleancontent(seasons, details='info=seasons') seasons = KodiLibrary().get_directory(seasons) library_create_nfo('tv', tmdb_id, folder, basedir=basedir) s_count = 0 s_total = len(seasons) for season in seasons: s_count += 1 if not season.get('season'): continue # Skip special seasons S00 season_name = '{} {}'.format(xbmc.getLocalizedString(20373), season.get('season')) p_dialog.update((s_count * 100) // s_total, message=u'Adding {} - {} to library...'.format(season.get('showtitle'), season_name)) if p_dialog else None episodes = library_cleancontent_replacer(season.get('file'), 'type=episode', 'type=season') # Clean to prevent flatseasons episodes = library_cleancontent(episodes, details='info=episodes') episodes = KodiLibrary().get_directory(episodes) i_count = 0 i_total = len(episodes) for episode in episodes: i_count += 1 if not episode.get('episode'): continue # Skip special episodes E00 s_num = episode.get('season') e_num = episode.get('episode') episode_name = 'S{:02d}E{:02d} - {}'.format( utils.try_parse_int(s_num), utils.try_parse_int(e_num), utils.validify_filename(episode.get('title'))) if _plugin.get_db_info(info='dbid', tmdbtype='episode', imdb_id=imdb_id, tmdb_id=tmdb_id, season=s_num, episode=e_num): utils.kodi_log(u'Trakt List Add to Library\nFound {} - {} in library. Skipping...'.format(episode.get('showtitle'), episode_name)) p_dialog.update((i_count * 100) // i_total, message=u'Found {} in library. Skipping...'.format(episode_name)) if p_dialog else None continue # Skip added items p_dialog.update((i_count * 100) // i_total, message=u'Adding {} to library...'.format(episode_name)) if p_dialog else None episode_path = library_cleancontent(episode.get('file')) library_createfile(episode_name, episode_path, folder, season_name, basedir=basedir)
def get_db_info(self, info=None, tmdbtype=None, imdb_id=None, originaltitle=None, title=None, year=None, tvshowtitle=None, season=None, episode=None): dbid = None kodidatabase = None if tmdbtype == 'movie': kodidatabase = self.kodimoviedb = self.kodimoviedb or KodiLibrary(dbtype='movie') if tmdbtype == 'tv': kodidatabase = self.koditvshowdb = self.koditvshowdb or KodiLibrary(dbtype='tvshow') if kodidatabase and info: return kodidatabase.get_info(info=info, imdb_id=imdb_id, originaltitle=originaltitle, title=title, year=year) if tmdbtype == 'episode': kodidatabase = self.koditvshowdb = self.koditvshowdb or KodiLibrary(dbtype='tvshow') dbid = kodidatabase.get_info(info='dbid', imdb_id=imdb_id, title=tvshowtitle, year=year) kodidatabase = KodiLibrary(dbtype='episode', tvshowid=dbid) if dbid and kodidatabase and season and episode: return kodidatabase.get_info('dbid', season=season, episode=episode)
def get_kodi_artwork(self, item, dbtype=None, dbid=None): if not dbid: return item details = {} if dbtype == 'movies': details = KodiLibrary().get_movie_details(dbid) elif dbtype == 'tvshows': details = KodiLibrary().get_tvshow_details(dbid) elif dbtype == 'episodes': details = KodiLibrary().get_episode_details(dbid) if not details: return item item['icon'] = details.get('icon') or item.get('icon') or '' item['thumb'] = details.get('thumb') or item.get('thumb') or '' item['poster'] = details.get('poster') or item.get('poster') or '' item['fanart'] = details.get('fanart') or item.get('fanart') or '' item['landscape'] = details.get('landscape') or item.get( 'landscape') or '' item['clearart'] = details.get('clearart') or item.get( 'clearart') or '' item['clearlogo'] = details.get('clearlogo') or item.get( 'clearlogo') or '' item['discart'] = details.get('discart') or item.get('discart') or '' return item
def play_external(self, force_dialog=False, playerindex=-1): if playerindex > -1: # Previous iteration didn't find an item to play so remove it and retry xbmcgui.Dialog().notification( self.itemlist[playerindex].getLabel(), self.addon.getLocalizedString(32040)) del self.actions[ playerindex] # Item not found so remove the player's action list del self.itemlist[ playerindex] # Item not found so remove the player's select dialog entry del self.identifierlist[ playerindex] # Item not found so remove the player's index playerindex = self.get_playerindex(force_dialog=force_dialog) # User cancelled dialog if not playerindex > -1: return False player = self.actions[playerindex] if not player or not player[1]: return False # External player has list of actions so let's iterate through them to find our item resolve_url = False if isinstance(player[1], list): actionlist = player[1] player = (False, actionlist[0]) for d in actionlist[1:]: if player[0]: break # Playable item was found in last action so let's break and play it folder = KodiLibrary().get_directory( string_format_map( player[1], self.item)) # Get the next folder from the plugin if d.get( 'dialog' ): # Special option to show dialog of items to select from d_items = [] for f in folder: # Create our list of items if not f.get('label') or f.get('label') == 'None': continue lb_list = [] label_a = f.get('label') if f.get('year') and f.get('year') != 1601: label_a = u'{} ({})'.format(label_a, f.get('year')) if utils.try_parse_int(f.get( 'season', 0)) > 0 and utils.try_parse_int( f.get('episode', 0)) > 0: label_a = u'{}x{}. {}'.format( f.get('season'), f.get('episode'), label_a) if f.get('streamdetails'): sdv_list = f.get('streamdetails', {}).get( 'video', [{}]) or [{}] sda_list = f.get('streamdetails', {}).get( 'audio', [{}]) or [{}] sdv, sda = sdv_list[0], sda_list[0] if sdv.get('width') or sdv.get('height'): lb_list.append(u'{}x{}'.format( sdv.get('width'), sdv.get('height'))) if sdv.get('codec'): lb_list.append(u'{}'.format( sdv.get('codec', '').upper())) if sda.get('codec'): lb_list.append(u'{}'.format( sda.get('codec', '').upper())) if sda.get('channels'): lb_list.append(u'{} CH'.format( sda.get('channels', ''))) for i in sda_list: if i.get('language'): lb_list.append(u'{}'.format( i.get('language', '').upper())) if sdv.get('duration'): lb_list.append(u'{} mins'.format( utils.try_parse_int(sdv.get('duration', 0)) // 60)) if f.get('size'): lb_list.append(u'{}'.format( utils.normalise_filesize(f.get('size', 0)))) label_b = ' | '.join(lb_list) if lb_list else '' d_items.append( ListItem(label=label_a, label2=label_b, icon=f.get('thumbnail')).set_listitem()) if d_items: idx = 0 if d.get('dialog', '').lower() != 'auto' or len(d_items) != 1: idx = xbmcgui.Dialog().select('Select Item', d_items, useDetails=True) if idx == -1: # User exited the dialog so return and do nothing return resolve_url = True if folder[idx].get( 'filetype' ) == 'file' else False # Set true for files so we can play player = (resolve_url, folder[idx].get('file') ) # Set the folder path to open/play break # Move onto next action else: # Ask user to select a different player if no items in dialog return self.play_external(force_dialog=force_dialog, playerindex=playerindex) x = 0 for f in folder: # Iterate through plugin folder looking for a matching item x += 1 # Keep an index for position matching for k, v in d.items( ): # Iterate through our key (infolabel) / value (infolabel must match) pairs of our action if k == 'position': # We're looking for an item position not an infolabel if utils.try_parse_int( string_format_map(v, self.item) ) != x: # Format our position value break # Not the item position we want so let's go to next item in folder elif not f.get(k) or string_format_map( v, self.item ) not in u'{}'.format( f.get(k, '') ): # Format our value and check if it matches the infolabel key break # Item's key value doesn't match value we are looking for so let's got to next item in folder else: # Item matched our criteria so let's open it up resolve_url = True if f.get( 'filetype' ) == 'file' else False # Set true for files so we can play player = (resolve_url, f.get('file') ) # Get ListItem.FolderPath for item break # Move onto next action (either open next folder or play file) else: return self.play_external( force_dialog=force_dialog, playerindex=playerindex ) # Ask user to select a different player # Play/Search found item if player and player[1]: action = string_format_map(player[1], self.item) if player[0] and action.endswith( '.strm'): # Action is play and is a strm so PlayMedia xbmc.executebuiltin( utils.try_decode_string(u'PlayMedia({0})'.format(action))) elif player[ 0]: # Action is play and not a strm so play with player xbmc.Player().play( action, ListItem(library='video', **self.details).set_listitem()) else: action = u'Container.Update({0})'.format( action) if xbmc.getCondVisibility( "Window.IsMedia" ) else u'ActivateWindow(videos,{0},return)'.format(action) xbmc.executebuiltin(utils.try_decode_string(action)) return action
def localmovie(self): fuzzy_match = self.addon.getSettingBool('fuzzymatch_movie') return self.localfile( KodiLibrary(dbtype='movie').get_info('file', fuzzy_match=fuzzy_match, **self.item))
def get_kodi_details(self): if not self.dbid and not self.tvshow_dbid: return details = {} tvshow_details = {} if self.infolabels.get('mediatype') == 'movie' and self.dbid: details = KodiLibrary().get_movie_details(self.dbid) elif self.infolabels.get('mediatype') == 'tvshow' and self.dbid: details = KodiLibrary().get_tvshow_details(self.dbid) elif self.infolabels.get('mediatype') == 'episode': details = KodiLibrary().get_episode_details( self.dbid) if self.dbid else {} tvshow_details = KodiLibrary().get_tvshow_details( self.tvshow_dbid) if self.tvshow_dbid else {} if tvshow_details: self.tvshow_poster = tvshow_details.get( 'poster') or self.tvshow_poster self.tvshow_fanart = tvshow_details.get( 'fanart') or self.tvshow_fanart self.tvshow_landscape = tvshow_details.get( 'landscape') or self.tvshow_landscape self.tvshow_clearart = tvshow_details.get( 'clearart') or self.tvshow_clearart self.tvshow_clearlogo = tvshow_details.get( 'clearlogo') or self.tvshow_clearlogo if not details: return self.local_path = details.get('path') self.icon = details.get('icon') or self.icon self.poster = details.get('poster') or self.poster self.fanart = details.get('fanart') or self.fanart self.landscape = details.get('landscape') or self.landscape self.clearart = details.get('clearart') or self.clearart self.clearlogo = details.get('clearlogo') or self.clearlogo self.discart = details.get('discart') or self.discart self.cast = self.cast or details.get('cast', []) self.infolabels = utils.merge_two_dicts(details.get('infolabels', {}), self.infolabels) self.infoproperties = utils.merge_two_dicts( details.get('infoproperties', {}), self.infoproperties) self.streamdetails = details.get('streamdetails', {})
def play_external(self, force_dialog=False): itemindex = self.get_itemindex(force_dialog=force_dialog) # User cancelled dialog if not itemindex > -1: return False player = self.actions[itemindex] if not player or not player[1]: return False # External player has list of actions so let's iterate through them to find our item resolve_url = False if isinstance(player[1], list): actionlist = player[1] player = (False, actionlist[0]) with utils.busy_dialog(): for d in actionlist[1:]: if player[0]: break # Playable item was found in last action so let's break and play it folder = KodiLibrary().get_directory( string_format_map( player[1], self.item)) # Get the next folder from the plugin x = 0 for f in folder: # Iterate through plugin folder looking for a matching item x += 1 # Keep an index for position matching for k, v in d.items( ): # Iterate through our key (infolabel) / value (infolabel must match) pairs of our action if k == 'position': # We're looking for an item position not an infolabel if utils.try_parse_int( string_format_map(v, self.item) ) != x: # Format our position value break # Not the item position we want so let's go to next item in folder elif not f.get(k) or string_format_map( v, self.item ) not in u'{}'.format( f.get(k, '') ): # Format our value and check if it matches the infolabel key break # Item's key value doesn't match value we are looking for so let's got to next item in folder else: # Item matched our criteria so let's open it up resolve_url = True if f.get( 'filetype' ) == 'file' else False # Set true for files so we can play player = (resolve_url, f.get('file') ) # Get ListItem.FolderPath for item break # Move onto next action (either open next folder or play file) else: xbmcgui.Dialog().notification( self.itemlist[itemindex].getLabel(), self.addon.getLocalizedString(32040)) del self.actions[ itemindex] # Item not found so remove the player's action list del self.itemlist[ itemindex] # Item not found so remove the player's select dialog entry return self.play_external( force_dialog=True ) # Ask user to select a different player # Play/Search found item if player and player[1]: action = string_format_map(player[1], self.item) if player[0]: # Action is play so let's play the item and return xbmc.Player().play( action, ListItem(library='video', **self.details).set_listitem()) return action # Action is search so let's load the plugin path action = u'Container.Update({0})'.format( action) if xbmc.getCondVisibility( "Window.IsMedia" ) else u'ActivateWindow(videos,{0},return)'.format(action) xbmc.executebuiltin(utils.try_decode_string(action)) return action
def get_kodi_details(self): if not self.dbid: return details = {} if self.infolabels.get('mediatype') == 'movie': details = KodiLibrary().get_movie_details(self.dbid) if self.infolabels.get('mediatype') == 'tvshow': details = KodiLibrary().get_tvshow_details(self.dbid) if self.infolabels.get('mediatype') == 'episode': details = KodiLibrary().get_episode_details(self.dbid) if not details: return self.icon = self.icon or details.get('icon', '') self.thumb = self.thumb or details.get('thumb', '') self.poster = self.poster or details.get('poster', '') self.fanart = self.fanart or details.get('fanart', '') self.landscape = self.landscape or details.get('landscape', '') self.clearart = self.clearart or details.get('clearart', '') self.clearlogo = self.clearlogo or details.get('clearlogo', '') self.discart = self.discart or details.get('discart', '') self.cast = self.cast or details.get('cast', []) self.infolabels = utils.merge_two_dicts(details.get('infolabels', {}), self.infolabels) self.infoproperties = utils.merge_two_dicts( details.get('infoproperties', {}), self.infoproperties) self.streamdetails = details.get('streamdetails', {})