Exemple #1
0
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
Exemple #3
0
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)
Exemple #4
0
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)
Exemple #5
0
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)