def _get_root_videoid(filename, pattern): match = re.search( pattern, xbmcvfs.File(filename, 'r').read().decode('utf-8').split('\n')[-1]) metadata = api.get_metadata(common.VideoId(videoid=match.groups()[0]))[0] if metadata['type'] == 'show': return common.VideoId(tvshowid=metadata['id']) return common.VideoId(movieid=metadata['id'])
def compile_tasks(videoid, task_handler, nfo_settings=None): """Compile a list of tasks for items based on the videoid""" common.debug('Compiling library tasks for {}', videoid) task = None try: if task_handler == export_item: metadata = api.get_metadata(videoid) if videoid.mediatype == common.VideoId.MOVIE: task = _create_export_movie_task(videoid, metadata[0], nfo_settings) elif videoid.mediatype in common.VideoId.TV_TYPES: task = _create_export_tv_tasks(videoid, metadata, nfo_settings) else: raise ValueError('Cannot handle {}'.format(videoid)) if task_handler == export_new_item: metadata = api.get_metadata(videoid, True) task = _create_new_episodes_tasks(videoid, metadata, nfo_settings) if task_handler == remove_item: if videoid.mediatype == common.VideoId.MOVIE: task = _create_remove_movie_task(videoid) if videoid.mediatype == common.VideoId.SHOW: task = _compile_remove_tvshow_tasks(videoid) if videoid.mediatype == common.VideoId.SEASON: task = _compile_remove_season_tasks(videoid) if videoid.mediatype == common.VideoId.EPISODE: task = _create_remove_episode_task(videoid) except MetadataNotAvailable: common.warn( 'compile_tasks: task_handler {} unavailable metadata for {} task skipped', task_handler, videoid) return [{}] if task is None: common.warn( 'compile_tasks: task_handler {} did not match any task for {}', task_handler, videoid) return task
def play(videoid): """Play an episode or movie as specified by the path""" common.info('Playing {}', videoid) is_up_next_enabled = g.ADDON.getSettingBool('UpNextNotifier_enabled') metadata = [{}, {}] try: metadata = api.get_metadata(videoid) common.debug('Metadata is {}', metadata) except MetadataNotAvailable: common.warn('Metadata not available for {}', videoid) # Parental control PIN pin_result = _verify_pin(metadata[0].get('requiresPin', False)) if not pin_result: if pin_result is not None: ui.show_notification(common.get_local_string(30106), time=10000) xbmcplugin.endOfDirectory(g.PLUGIN_HANDLE, succeeded=False) return list_item = get_inputstream_listitem(videoid) resume_position = None event_data = {} if g.IS_ADDON_EXTERNAL_CALL: # Workaround for resuming strm files from library resume_position = (infolabels.get_resume_info_from_library(videoid).get('position') if g.ADDON.getSettingBool('ResumeManager_enabled') else None) if resume_position: index_selected = (ui.ask_for_resume(resume_position) if g.ADDON.getSettingBool('ResumeManager_dialog') else None) if index_selected == -1: xbmcplugin.setResolvedUrl(handle=g.PLUGIN_HANDLE, succeeded=False, listitem=list_item) return if index_selected == 1: resume_position = None elif (g.ADDON.getSettingBool('ProgressManager_enabled') and videoid.mediatype in [common.VideoId.MOVIE, common.VideoId.EPISODE]): # To now we have this limits: # - enabled only with items played inside the addon then not Kodi library, need impl. JSON-RPC lib update code event_data = _get_event_data(videoid) event_data['videoid'] = videoid.to_dict() event_data['is_played_by_library'] = g.IS_ADDON_EXTERNAL_CALL # Todo: UpNext addon is incompatible with netflix watched status sync feature # Problems: # - Need to modify the cache (to update the watched status) on every played item # - Modifying the cache after the stop, is wrong due to below problems # - The new fast play, 'play_url' method, cause problems with the Player callbacks, after press play next is missing the Stop event in the controller! # - To verify possibility problems of data mixing of controller._get_player_state() # - The call of next video from UpNext is recognized as Skin call, because it's an external addon call, so it causes several operating problems is_up_next_enabled = False if 'raspberrypi' in common.get_system_platform() and g.KODI_VERSION.is_major_ver('18'): # OMX Player is not compatible with netflix video streams # Only Kodi 18 has this property, on Kodi 19 Omx Player has been removed value = common.json_rpc('Settings.GetSettingValue', {'setting': 'videoplayer.useomxplayer'}) if value.get('value'): common.json_rpc('Settings.SetSettingValue', {'setting': 'videoplayer.useomxplayer', 'value': False}) xbmcplugin.setResolvedUrl(handle=g.PLUGIN_HANDLE, succeeded=True, listitem=list_item) upnext_info = get_upnext_info(videoid, metadata) if is_up_next_enabled else None g.LOCAL_DB.set_value('last_videoid_played', videoid.to_dict(), table=TABLE_SESSION) common.debug('Sending initialization signal') common.send_signal(common.Signals.PLAYBACK_INITIATED, { 'videoid': videoid.to_dict(), 'timeline_markers': get_timeline_markers(metadata[0]), 'upnext_info': upnext_info, 'resume_position': resume_position, 'event_data': event_data}, non_blocking=True)
def play(videoid): """Play an episode or movie as specified by the path""" is_upnext_enabled = g.ADDON.getSettingBool('UpNextNotifier_enabled') # For db settings 'upnext_play_callback_received' and 'upnext_play_callback_file_type' see action_controller.py is_upnext_callback_received = g.LOCAL_DB.get_value( 'upnext_play_callback_received', False) is_upnext_callback_file_type_strm = g.LOCAL_DB.get_value( 'upnext_play_callback_file_type', '') == 'strm' # This is the only way found to know if the played item come from the add-on itself or from Kodi library # also when Up Next Add-on is used is_played_from_addon = not g.IS_ADDON_EXTERNAL_CALL or ( g.IS_ADDON_EXTERNAL_CALL and is_upnext_callback_received and not is_upnext_callback_file_type_strm) common.info('Playing {} from {} (Is Up Next Add-on call: {})', videoid, 'add-on' if is_played_from_addon else 'external call', is_upnext_callback_received) metadata = [{}, {}] try: metadata = api.get_metadata(videoid) common.debug('Metadata is {}', metadata) except MetadataNotAvailable: common.warn('Metadata not available for {}', videoid) # Parental control PIN pin_result = _verify_pin(metadata[0].get('requiresPin', False)) if not pin_result: if pin_result is not None: ui.show_notification(common.get_local_string(30106), time=8000) xbmcplugin.endOfDirectory(g.PLUGIN_HANDLE, succeeded=False) return list_item = get_inputstream_listitem(videoid) resume_position = None info_data = None event_data = {} videoid_next_episode = None if not is_played_from_addon or is_upnext_enabled: if is_upnext_enabled and videoid.mediatype == common.VideoId.EPISODE: # When UpNext is enabled, get the next episode to play videoid_next_episode = _upnext_get_next_episode_videoid( videoid, metadata) info_data = infolabels.get_info_from_netflix( [videoid, videoid_next_episode] if videoid_next_episode else [videoid]) info, arts = info_data[videoid.value] # When a item is played from Kodi library or Up Next add-on is needed set info and art to list_item list_item.setInfo('video', info) list_item.setArt(arts) if not is_played_from_addon: # Workaround for resuming strm files from library resume_position = ( infolabels.get_resume_info_from_library(videoid).get('position') if g.ADDON.getSettingBool('ResumeManager_enabled') else None) if resume_position: index_selected = (ui.ask_for_resume(resume_position) if g.ADDON.getSettingBool('ResumeManager_dialog') else None) if index_selected == -1: xbmcplugin.setResolvedUrl(handle=g.PLUGIN_HANDLE, succeeded=False, listitem=list_item) return if index_selected == 1: resume_position = None if (g.ADDON.getSettingBool('ProgressManager_enabled') and videoid.mediatype in [common.VideoId.MOVIE, common.VideoId.EPISODE] and is_played_from_addon): # Enable the progress manager only when: # - It is not an add-on external call # - It is an external call, but the played item is not a STRM file # Todo: # in theory to enable in Kodi library need implement the update watched status code for items of Kodi library # by using JSON RPC Files.SetFileDetails https://github.com/xbmc/xbmc/pull/17202 # that can be used only on Kodi 19.x event_data = _get_event_data(videoid) event_data['videoid'] = videoid.to_dict() event_data['is_played_by_library'] = not is_played_from_addon if 'raspberrypi' in common.get_system_platform( ) and g.KODI_VERSION.is_major_ver('18'): # OMX Player is not compatible with netflix video streams # Only Kodi 18 has this property, on Kodi 19 Omx Player has been removed value = common.json_rpc('Settings.GetSettingValue', {'setting': 'videoplayer.useomxplayer'}) if value.get('value'): common.json_rpc('Settings.SetSettingValue', { 'setting': 'videoplayer.useomxplayer', 'value': False }) xbmcplugin.setResolvedUrl(handle=g.PLUGIN_HANDLE, succeeded=True, listitem=list_item) g.LOCAL_DB.set_value('last_videoid_played', videoid.to_dict(), table=TABLE_SESSION) common.debug('Sending initialization signal') common.send_signal(common.Signals.PLAYBACK_INITIATED, { 'videoid': videoid.to_dict(), 'videoid_next_episode': videoid_next_episode.to_dict() if videoid_next_episode else None, 'metadata': metadata, 'info_data': info_data, 'is_played_from_addon': is_played_from_addon, 'resume_position': resume_position, 'event_data': event_data, 'is_upnext_callback_received': is_upnext_callback_received }, non_blocking=True)
def play(videoid): """Play an episode or movie as specified by the path""" is_upnext_enabled = g.ADDON.getSettingBool('UpNextNotifier_enabled') # For db settings 'upnext_play_callback_received' and 'upnext_play_callback_file_type' see action_controller.py is_upnext_callback_received = g.LOCAL_DB.get_value( 'upnext_play_callback_received', False) is_upnext_callback_file_type_strm = g.LOCAL_DB.get_value( 'upnext_play_callback_file_type', '') == 'strm' # This is the only way found to know if the played item come from the add-on itself or from Kodi library # also when Up Next Add-on is used is_played_from_addon = not g.IS_ADDON_EXTERNAL_CALL or ( g.IS_ADDON_EXTERNAL_CALL and is_upnext_callback_received and not is_upnext_callback_file_type_strm) common.info('Playing {} from {} (Is Up Next Add-on call: {})', videoid, 'add-on' if is_played_from_addon else 'external call', is_upnext_callback_received) # Profile switch when playing from Kodi library if not is_played_from_addon: if not _profile_switch(): xbmcplugin.endOfDirectory(g.PLUGIN_HANDLE, succeeded=False) return # Get metadata of videoid try: metadata = api.get_metadata(videoid) common.debug('Metadata is {}', metadata) except MetadataNotAvailable: common.warn('Metadata not available for {}', videoid) metadata = [{}, {}] # Check parental control PIN pin_result = _verify_pin(metadata[0].get('requiresPin', False)) if not pin_result: if pin_result is not None: ui.show_notification(common.get_local_string(30106), time=8000) xbmcplugin.endOfDirectory(g.PLUGIN_HANDLE, succeeded=False) return # Generate the xbmcgui.ListItem to be played list_item = get_inputstream_listitem(videoid) # STRM file resume workaround (Kodi library) resume_position = _strm_resume_workaroud(is_played_from_addon, videoid) if resume_position == '': xbmcplugin.setResolvedUrl(handle=g.PLUGIN_HANDLE, succeeded=False, listitem=list_item) return info_data = None event_data = {} videoid_next_episode = None # Get Infolabels and Arts for the videoid to be played, and for the next video if it is an episode (for UpNext) if not is_played_from_addon or is_upnext_enabled: if is_upnext_enabled and videoid.mediatype == common.VideoId.EPISODE: # When UpNext is enabled, get the next episode to play videoid_next_episode = _upnext_get_next_episode_videoid( videoid, metadata) info_data = infolabels.get_info_from_netflix( [videoid, videoid_next_episode] if videoid_next_episode else [videoid]) info, arts = info_data[videoid.value] # When a item is played from Kodi library or Up Next add-on is needed set info and art to list_item list_item.setInfo('video', info) list_item.setArt(arts) # Get event data for videoid to be played (needed for sync of watched status with Netflix) if (g.ADDON.getSettingBool('ProgressManager_enabled') and videoid.mediatype in [common.VideoId.MOVIE, common.VideoId.EPISODE] and is_played_from_addon): # Enable the progress manager only when: # - It is not an add-on external call # - It is an external call, but the played item is not a STRM file # Todo: # in theory to enable in Kodi library need implement the update watched status code for items of Kodi library # by using JSON RPC Files.SetFileDetails https://github.com/xbmc/xbmc/pull/17202 # that can be used only on Kodi 19.x event_data = _get_event_data(videoid) event_data['videoid'] = videoid.to_dict() event_data['is_played_by_library'] = not is_played_from_addon if 'raspberrypi' in common.get_system_platform(): _raspberry_disable_omxplayer() xbmcplugin.setResolvedUrl(handle=g.PLUGIN_HANDLE, succeeded=True, listitem=list_item) g.LOCAL_DB.set_value('last_videoid_played', videoid.to_dict(), table=TABLE_SESSION) # Start and initialize the action controller (see action_controller.py) common.debug('Sending initialization signal') common.send_signal(common.Signals.PLAYBACK_INITIATED, { 'videoid': videoid.to_dict(), 'videoid_next_episode': videoid_next_episode.to_dict() if videoid_next_episode else None, 'metadata': metadata, 'info_data': info_data, 'is_played_from_addon': is_played_from_addon, 'resume_position': resume_position, 'event_data': event_data, 'is_upnext_callback_received': is_upnext_callback_received }, non_blocking=True)
def _play(videoid, is_played_from_strm=False): """Play an episode or movie as specified by the path""" is_upnext_enabled = G.ADDON.getSettingBool('UpNextNotifier_enabled') common.info('Playing {}{}{}', videoid, ' [STRM file]' if is_played_from_strm else '', ' [external call]' if G.IS_ADDON_EXTERNAL_CALL else '') # Profile switch when playing from a STRM file (library) if is_played_from_strm: if not _profile_switch(): xbmcplugin.endOfDirectory(G.PLUGIN_HANDLE, succeeded=False) return # Get metadata of videoid try: metadata = api.get_metadata(videoid) common.debug('Metadata is {}', metadata) except MetadataNotAvailable: common.warn('Metadata not available for {}', videoid) metadata = [{}, {}] # Check parental control PIN pin_result = _verify_pin(metadata[0].get('requiresPin', False)) if not pin_result: if pin_result is not None: ui.show_notification(common.get_local_string(30106), time=8000) xbmcplugin.endOfDirectory(G.PLUGIN_HANDLE, succeeded=False) return # Generate the xbmcgui.ListItem to be played list_item = get_inputstream_listitem(videoid) # STRM file resume workaround (Kodi library) resume_position = _strm_resume_workaroud(is_played_from_strm, videoid) if resume_position == '': xbmcplugin.setResolvedUrl(handle=G.PLUGIN_HANDLE, succeeded=False, listitem=list_item) return info_data = None event_data = {} videoid_next_episode = None # Get Infolabels and Arts for the videoid to be played, and for the next video if it is an episode (for UpNext) if is_played_from_strm or is_upnext_enabled or G.IS_ADDON_EXTERNAL_CALL: if is_upnext_enabled and videoid.mediatype == common.VideoId.EPISODE: # When UpNext is enabled, get the next episode to play videoid_next_episode = _upnext_get_next_episode_videoid( videoid, metadata) info_data = infolabels.get_info_from_netflix( [videoid, videoid_next_episode] if videoid_next_episode else [videoid]) info, arts = info_data[videoid.value] # When a item is played from Kodi library or Up Next add-on is needed set info and art to list_item list_item.setInfo('video', info) list_item.setArt(arts) # Get event data for videoid to be played (needed for sync of watched status with Netflix) if (G.ADDON.getSettingBool('ProgressManager_enabled') and videoid.mediatype in [common.VideoId.MOVIE, common.VideoId.EPISODE]): if not is_played_from_strm or is_played_from_strm and G.ADDON.getSettingBool( 'sync_watched_status_library'): event_data = _get_event_data(videoid) event_data['videoid'] = videoid.to_dict() event_data['is_played_by_library'] = is_played_from_strm if 'raspberrypi' in common.get_system_platform(): _raspberry_disable_omxplayer() # Start and initialize the action controller (see action_controller.py) common.debug('Sending initialization signal') common.send_signal(common.Signals.PLAYBACK_INITIATED, { 'videoid': videoid.to_dict(), 'videoid_next_episode': videoid_next_episode.to_dict() if videoid_next_episode else None, 'metadata': metadata, 'info_data': info_data, 'is_played_from_strm': is_played_from_strm, 'resume_position': resume_position, 'event_data': event_data }, non_blocking=True) # Send callback after send the initialization signal # to give a bit of more time to the action controller (see note in initialize_playback of action_controller.py) xbmcplugin.setResolvedUrl(handle=G.PLUGIN_HANDLE, succeeded=True, listitem=list_item)