def _import_videoid_old(self, file_content, folder_name):
     try:
         # The STRM file in add-on v13.x is different and can contains two lines, example:
         #   #EXTINF:-1,Tv show title - "meta data ..."
         #   plugin://plugin.video.netflix/?video_id=12345678&action=play_video
         # Get last line and extract the videoid value
         match = re.search(r'video_id=(\d+)', file_content.split('\n')[-1])
         # Create a videoid of UNSPECIFIED type (we do not know the real type of videoid)
         videoid = common.VideoId(videoid=match.groups()[0])
         # Try to get the videoid metadata:
         # - To know if the videoid still exists on netflix
         # - To get the videoid type
         # - To get the Tv show videoid, in the case of STRM of an episode
         metadata = self.ext_func_get_metadata(videoid)[0]  # pylint: disable=not-callable
         # Generate the a good videoid
         if metadata['type'] == 'show':
             return common.VideoId(tvshowid=metadata['id'])
         return common.VideoId(movieid=metadata['id'])
     except MetadataNotAvailable:
         LOG.warn('Import error: folder {} skipped, metadata not available',
                  folder_name)
         return None
     except (AttributeError, IndexError):
         LOG.warn(
             'Import error: folder {} skipped, STRM not conform to v0.13.x format',
             folder_name)
         return None
Пример #2
0
def _get_root_videoid(filename, pattern):
    match = re.search(
        pattern,
        xbmcvfs.File(filename, 'r').read().decode('utf-8').split('\n')[-1])
    metadata = api.metadata(common.VideoId(videoid=match.groups()[0]))[0]
    if metadata['type'] == 'show':
        return common.VideoId(tvshowid=metadata['id'])
    return common.VideoId(movieid=metadata['id'])
Пример #3
0
def _find_next_episode(videoid, metadata):
    try:
        # Find next episode in current season
        episode = common.find(metadata[0]['seq'] + 1, 'seq',
                              metadata[1]['episodes'])
        return common.VideoId(tvshowid=videoid.tvshowid,
                              seasonid=videoid.seasonid,
                              episodeid=episode['id'])
    except (IndexError, KeyError):
        # Find first episode of next season
        next_season = common.find(metadata[1]['seq'] + 1, 'seq',
                                  metadata[2]['seasons'])
        episode = common.find(1, 'seq', next_season['episodes'])
        return common.VideoId(tvshowid=videoid.tvshowid,
                              seasonid=next_season['id'],
                              episodeid=episode['id'])
Пример #4
0
    def _sync_my_list_ops(self, videoids_tasks, exp_tvshows_videoids_values, exp_movies_videoids_values):
        # Get videoids from the My list (of the chosen profile)
        # pylint: disable=not-callable
        mylist_video_id_list, mylist_video_id_list_type = self.ext_func_get_mylist_videoids_profile_switch()

        # Check if tv shows have been removed from the My List
        for videoid_value in exp_tvshows_videoids_values:
            if unicode(videoid_value) in mylist_video_id_list:
                continue
            # The tv show no more exist in My List so remove it from library
            videoid = common.VideoId.from_path([common.VideoId.SHOW, videoid_value])
            videoids_tasks.update({videoid: self.remove_item})

        # Check if movies have been removed from the My List
        for videoid_value in exp_movies_videoids_values:
            if unicode(videoid_value) in mylist_video_id_list:
                continue
            # The movie no more exist in My List so remove it from library
            videoid = common.VideoId.from_path([common.VideoId.MOVIE, videoid_value])
            videoids_tasks.update({videoid: self.remove_item})

        # Add to library the missing tv shows / movies of My List
        for index, videoid_value in enumerate(mylist_video_id_list):
            if (int(videoid_value) not in exp_tvshows_videoids_values and
                    int(videoid_value) not in exp_movies_videoids_values):
                is_movie = mylist_video_id_list_type[index] == 'movie'
                videoid = common.VideoId(**{('movieid' if is_movie else 'tvshowid'): videoid_value})
                videoids_tasks.update({videoid: self.export_item if is_movie else self.export_new_item})
Пример #5
0
 def __init__(self, path_response, list_id=None):
     # common.debug('VideoList data: {}', path_response)
     self.perpetual_range_selector = path_response.get(
         '_perpetual_range_selector')
     self.data = path_response
     has_data = bool(path_response.get('lists'))
     self.videos = OrderedDict()
     self.artitem = None
     self.contained_titles = None
     self.videoids = None
     if has_data:
         # Generate one videoid, or from the first id of the list or with specified one
         self.videoid = common.VideoId(videoid=(
             list_id if list_id else next(iter(self.data['lists']))))
         self.videos = OrderedDict(
             resolve_refs(self.data['lists'][self.videoid.value],
                          self.data))
         if self.videos:
             # self.artitem = next(itervalues(self.videos))
             self.artitem = listvalues(self.videos)[0]
             self.contained_titles = _get_titles(self.videos)
             try:
                 self.videoids = _get_videoids(self.videos)
             except KeyError:
                 self.videoids = None
Пример #6
0
 def __init__(self, path_response, list_id):
     # common.debug('VideoListLoCo data: {}', path_response)
     self.perpetual_range_selector = path_response.get(
         '_perpetual_range_selector')
     self.data = path_response
     self.list_id = list_id
     self.videoids = None
     # Set a 'UNSPECIFIED' type videoid (special handling for menus see parse_info in infolabels.py)
     self.videoid = common.VideoId(videoid=list_id)
     self.contained_titles = None
     self.artitem = None
     if 'lists' not in path_response:
         # No data in path response
         return
     # Set videos data for the specified list id
     self.videos = OrderedDict(
         resolve_refs(self.data['lists'][list_id], self.data))
     if not self.videos:
         return
     # Set first videos titles (special handling for menus see parse_info in infolabels.py)
     self.contained_titles = _get_titles(self.videos)
     # Set art data of first video (special handling for menus see parse_info in infolabels.py)
     self.artitem = listvalues(self.videos)[0]
     try:
         self.videoids = _get_videoids(self.videos)
     except KeyError:
         self.videoids = None
 def _create_remove_jobs_from_rows(self, row_results):
     """Create jobs data to remove episodes, from the rows results of the database"""
     return [
         self._build_remove_job_data(
             get_episode_title_from_path(row['FilePath']), row['FilePath'],
             common.VideoId(tvshowid=row['TvShowID'],
                            seasonid=row['SeasonID'],
                            episodeid=row['EpisodeID']))
         for row in row_results
     ]
Пример #8
0
def _create_supplemental_item(videoid_value, video, video_list, params):
    """Create a tuple that can be added to a Kodi directory that represents
    a video as listed in a videolist"""
    videoid = common.VideoId(**{'supplementalid': videoid_value})
    list_item = list_item_skeleton(video['title'])
    add_info(videoid, list_item, video, video_list.data)
    add_art(videoid, list_item, video)
    url = common.build_url(videoid=videoid, mode=g.MODE_PLAY, params=params)
    list_item.addContextMenuItems(generate_context_menu_items(videoid))
    return (url, list_item, False)
def _create_supplemental_item(videoid_value, video, video_list):
    """Create a tuple that can be added to a Kodi directory that represents
    a video as listed in a videolist"""
    videoid = common.VideoId(**{'supplementalid': videoid_value})
    list_item = list_item_skeleton(video['title'])
    add_info(videoid, list_item, video, video_list.data)
    add_art(videoid, list_item, video)
    url = common.build_url(videoid=videoid, mode=g.MODE_PLAY)
    # replaceItems still look broken because it does not remove the default ctx menu, i hope in the future Kodi fix this
    list_item.addContextMenuItems(generate_context_menu_items(videoid),
                                  replaceItems=True)
    return (url, list_item, False)
Пример #10
0
def _create_video_item(videoid_value, video, video_list):
    """Create a tuple that can be added to a Kodi directory that represents
    a video as listed in a videolist"""
    is_movie = video['summary']['type'] == 'movie'
    videoid = common.VideoId(
        **{('movieid' if is_movie else 'tvshowid'): videoid_value})
    list_item = list_item_skeleton(video['title'])
    add_info(videoid, list_item, video, video_list.data)
    add_art(videoid, list_item, video)
    url = common.build_url(
        videoid=videoid, mode=(g.MODE_PLAY if is_movie else g.MODE_DIRECTORY))
    list_item.addContextMenuItems(generate_context_menu_items(videoid))
    return (url, list_item, not is_movie)
Пример #11
0
 def __init__(self, path_response, list_id=None):
     self.data = path_response
     self.id = common.VideoId(
         videoid=(list_id
                  if list_id
                  else next(self.data['lists'].iterkeys())))
     self.title = self['displayName']
     self.videos = OrderedDict(
         resolve_refs(self.data['lists'][self.id.value], self.data))
     self.artitem = next(self.videos.itervalues())
     self.contained_titles = _get_titles(self.videos)
     try:
         self.videoids = _get_videoids(self.videos)
     except KeyError:
         self.videoids = None
Пример #12
0
def _create_video_item(videoid_value, video, video_list, menu_data, params):
    """Create a tuple that can be added to a Kodi directory that represents
    a video as listed in a videolist"""
    is_movie = video['summary']['type'] == 'movie'
    videoid = common.VideoId(
        **{('movieid' if is_movie else 'tvshowid'): videoid_value})
    list_item = list_item_skeleton(video['title'])
    infos = add_info(videoid, list_item, video, video_list.data)
    if menu_data['path'][1] != 'myList':
        add_highlighted_title(list_item, videoid, infos)
    list_item.setInfo('video', infos)
    add_art(videoid, list_item, video)
    url = common.build_url(
        videoid=videoid,
        mode=(g.MODE_PLAY if is_movie else g.MODE_DIRECTORY),
        params=params)
    list_item.addContextMenuItems(generate_context_menu_items(videoid))
    return (url, list_item, not is_movie)
Пример #13
0
 def __init__(self, path_response, list_id=None):
     self.perpetual_range_selector = path_response.get(
         '_perpetual_range_selector')
     self.data = path_response
     self.id = common.VideoId(videoid=(
         list_id if list_id else next(self.data['lists'].iterkeys())))
     #self.title = self['displayName']   Not more used
     self.videos = OrderedDict(
         resolve_refs(self.data['lists'][self.id.value], self.data))
     if self.videos:
         self.artitem = next(self.videos.itervalues())
         self.contained_titles = _get_titles(self.videos)
         try:
             self.videoids = _get_videoids(self.videos)
         except KeyError:
             self.videoids = None
     else:
         self.artitem = None
         self.contained_titles = None
         self.videoids = None
Пример #14
0
def sync_mylist_to_library():
    """
    Perform a full sync of Netflix "My List" with the Kodi library
    by deleting everything that was previously exported
    """
    common.info(
        'Performing full sync of Netflix "My List" with the Kodi library')
    purge()
    nfo_settings = nfo.NFOSettings()
    nfo_settings.show_export_dialog()

    mylist_video_id_list, mylist_video_id_list_type = common.make_call(
        'get_mylist_videoids_profile_switch')
    for index, video_id in enumerate(mylist_video_id_list):
        videoid = common.VideoId(
            **{
                ('movieid' if (mylist_video_id_list_type[index] == 'movie') else 'tvshowid'):
                video_id
            })
        execute_library_tasks(videoid, [export_item],
                              common.get_local_string(30018),
                              nfo_settings=nfo_settings)
def auto_update_library(sync_with_mylist, silent):
    """
    Perform an auto update of the exported items to Kodi library,
    so check if there is new seasons/episodes.
    If sync_with_mylist is enabled the Kodi library will be also synchronized
    with the Netflix "My List".
    :param sync_with_mylist: True to enable sync with My List
    :param silent: don't display user interface while performing an operation
    :return: None
    """
    if _is_auto_update_library_running():
        return
    execute_lib_tasks_method = execute_library_tasks_silently if silent else execute_library_tasks
    common.info(
        'Starting auto update library - check updates for tv shows (sync with My List is {})',
        'ENABLED' if sync_with_mylist else 'DISABLED')
    g.SHARED_DB.set_value('library_auto_update_is_running', True)
    g.SHARED_DB.set_value('library_auto_update_start_time', datetime.now())
    try:
        videoids_to_update = []

        # Get the list of the exported items to Kodi library
        exported_tvshows_videoids_values = g.SHARED_DB.get_tvshows_id_list()
        exported_movies_videoids_values = g.SHARED_DB.get_movies_id_list()

        if sync_with_mylist:
            # Get My List videoids of the chosen profile
            # Use make_http_call instead make_http because call AddonSignals on same instance makes problems
            mylist_video_id_list, mylist_video_id_list_type = common.make_http_call(
                'get_mylist_videoids_profile_switch', None)

            # Check if tv shows have been removed from the My List
            for videoid_value in exported_tvshows_videoids_values:
                if unicode(videoid_value) in mylist_video_id_list:
                    continue
                # The tv show no more exist in My List so remove it from library
                videoid = common.VideoId.from_path(
                    [common.VideoId.SHOW, videoid_value])
                execute_lib_tasks_method(videoid, [remove_item])

            # Check if movies have been removed from the My List
            for videoid_value in exported_movies_videoids_values:
                if unicode(videoid_value) in mylist_video_id_list:
                    continue
                # The movie no more exist in My List so remove it from library
                videoid = common.VideoId.from_path(
                    [common.VideoId.MOVIE, videoid_value])
                execute_lib_tasks_method(videoid, [remove_item])

            # Add missing tv shows / movies of My List to library
            for index, video_id in enumerate(mylist_video_id_list):
                if (int(video_id) not in exported_tvshows_videoids_values and
                        int(video_id) not in exported_movies_videoids_values):
                    videoids_to_update.append(
                        common.VideoId(
                            **{
                                ('movieid' if (mylist_video_id_list_type[index] == 'movie') else 'tvshowid'):
                                video_id
                            }))

        # Add the exported tv shows to be updated to the list..
        tvshows_videoids_to_upd = [
            common.VideoId.from_path([common.VideoId.SHOW, videoid_value])
            for videoid_value in g.SHARED_DB.get_tvshows_id_list(
                VidLibProp['exclude_update'], False)
        ]
        # ..and avoids any duplication caused by possible unexpected errors
        videoids_to_update.extend(
            list(set(tvshows_videoids_to_upd) - set(videoids_to_update)))

        # Add missing tv shows/movies or update existing tv shows
        _update_library(videoids_to_update, exported_tvshows_videoids_values,
                        silent)

        common.debug('Auto update of the library completed')
        g.SHARED_DB.set_value('library_auto_update_is_running', False)
        if not g.ADDON.getSettingBool('lib_auto_upd_disable_notification'):
            ui.show_notification(common.get_local_string(30220), time=5000)
        common.debug(
            'Notify service to communicate to Kodi of update the library')
        common.send_signal(common.Signals.LIBRARY_UPDATE_REQUESTED)
    except Exception:  # pylint: disable=broad-except
        import traceback
        common.error('An error has occurred in the library auto update')
        common.error(traceback.format_exc())
        g.SHARED_DB.set_value('library_auto_update_is_running', False)