Esempio n. 1
0
    def initial_addon_configuration(self):
        """
        Initial addon configuration,
        helps users to automatically configure addon parameters for proper viewing of videos
        """
        run_initial_config = self.ADDON.getSettingBool('run_init_configuration')
        if run_initial_config:
            import resources.lib.common as common
            import resources.lib.kodi.ui as ui
            self.settings_monitor_suspended(True)

            system = common.get_system_platform()
            common.debug('Running initial addon configuration dialogs on system: {}'.format(system))
            if system in ['osx', 'ios', 'xbox']:
                self.ADDON.setSettingBool('enable_vp9_profiles', False)
                self.ADDON.setSettingBool('enable_hevc_profiles', True)
            elif system == 'windows':
                # Currently inputstream does not support hardware video acceleration on windows,
                # there is no guarantee that we will get 4K without video hardware acceleration,
                # so no 4K configuration
                self.ADDON.setSettingBool('enable_vp9_profiles', True)
                self.ADDON.setSettingBool('enable_hevc_profiles', False)
            elif system == 'android':
                ultrahd_capable_device = False
                premium_account = ui.ask_for_confirmation(common.get_local_string(30154),
                                                          common.get_local_string(30155))
                if premium_account:
                    ultrahd_capable_device = ui.ask_for_confirmation(common.get_local_string(30154),
                                                                     common.get_local_string(30156))
                if ultrahd_capable_device:
                    ui.show_ok_dialog(common.get_local_string(30154),
                                      common.get_local_string(30157))
                    ia_enabled = xbmc.getCondVisibility('System.HasAddon(inputstream.adaptive)')
                    if ia_enabled:
                        xbmc.executebuiltin('Addon.OpenSettings(inputstream.adaptive)')
                    else:
                        ui.show_ok_dialog(common.get_local_string(30154),
                                          common.get_local_string(30046))
                    self.ADDON.setSettingBool('enable_vp9_profiles', False)
                    self.ADDON.setSettingBool('enable_hevc_profiles', True)
                else:
                    # VP9 should have better performance since there is no need for 4k
                    self.ADDON.setSettingBool('enable_vp9_profiles', True)
                    self.ADDON.setSettingBool('enable_hevc_profiles', False)
                self.ADDON.setSettingBool('enable_force_hdcp', ultrahd_capable_device)
            elif system == 'linux':
                # Too many different linux systems, we can not predict all the behaviors
                # Some linux distributions have encountered problems with VP9,
                # OMSC users complain that hevc creates problems
                self.ADDON.setSettingBool('enable_vp9_profiles', False)
                self.ADDON.setSettingBool('enable_hevc_profiles', False)
            else:
                self.ADDON.setSettingBool('enable_vp9_profiles', False)
                self.ADDON.setSettingBool('enable_hevc_profiles', False)
            self.ADDON.setSettingBool('run_init_configuration', False)
            self.settings_monitor_suspended(False)
Esempio n. 2
0
 def _reset(self):
     if not ui.ask_for_confirmation(
             common.get_local_string(13007),  # 13007=Reset
             common.get_local_string(30609)):
         return
     with common.show_busy_dialog():
         # Set WV Sec. Lev. to Disabled
         self._ensure_wv_btn_check(
             self.WV_SECLEV_MAP_BTN[WidevineForceSecLev.DISABLED])
         self.wv_sec_lev_new = WidevineForceSecLev.DISABLED
         if self.is_android:
             # Generate the ESN
             self.esn_new = generate_android_esn(
                 wv_force_sec_lev=self.wv_sec_lev_new)
         else:
             # To retrieve the ESN from the website,
             # to avoid possible problems we refresh the nf session data to get a new ESN
             set_website_esn('')
             common.make_call('refresh_session_data',
                              {'update_profiles': False})
             self.esn_new = get_website_esn()
             if not self.esn_new:
                 raise Exception(
                     'It was not possible to obtain the ESN, try restarting the add-on'
                 )
     self._update_esn_label()
 def remove(self, videoid):
     """Remove an item from the Kodi library"""
     if ui.ask_for_confirmation(common.get_local_string(30030),
                                common.get_local_string(30124)):
         library.execute_library_tasks(videoid, [library.remove_item],
                                       common.get_local_string(30030))
         common.container_refresh(use_delay=True)
 def initial_mylist_sync(self, pathitems):
     """Perform an initial sync of My List and the Kodi library"""
     # pylint: disable=unused-argument
     from resources.lib.cache import CACHE_COMMON
     # This is a temporary workaround to prevent sync from mylist of non owner account profiles
     # TODO: in the future you can also add the possibility to synchronize from a chosen profile
     is_account_owner = g.LOCAL_DB.get_profile_config(
         'isAccountOwner', False)
     if not is_account_owner:
         ui.show_ok_dialog('Netflix', common.get_local_string(30223))
         return
     do_it = ui.ask_for_confirmation(common.get_local_string(30122),
                                     common.get_local_string(30123))
     if not do_it:
         return
     common.debug('Performing full sync from My List to Kodi library')
     library.purge()
     nfo_settings = nfo.NFOSettings()
     nfo_settings.show_export_dialog()
     # Invalidate my-list cached data to force to obtain new data
     g.CACHE.invalidate_entry(CACHE_COMMON, 'my_list_items')
     for videoid in api.mylist_items():
         library.execute_library_tasks(videoid, [library.export_item],
                                       common.get_local_string(30018),
                                       sync_mylist=False,
                                       nfo_settings=nfo_settings)
Esempio n. 5
0
 def remove(self, videoid):
     """Remove an item from the Kodi library"""
     if not ui.ask_for_confirmation(common.get_local_string(30030),
                                    common.get_local_string(30124)):
         return
     get_library_cls().remove_from_library(videoid)
     common.container_refresh(use_delay=True)
Esempio n. 6
0
def search_clear():
    """Clear all search items"""
    if not ui.ask_for_confirmation(common.get_local_string(30404), common.get_local_string(30406)):
        return False
    G.LOCAL_DB.clear_search_items()
    search_list(dir_update_listing=True)
    return True
Esempio n. 7
0
 def show_export_dialog(self,
                        mediatype=None,
                        dialog_message=common.get_local_string(30183)):
     """Ask the user if he wants to export NFO for movies and/or tvshows, this override the default settings"""
     if not self.export_enabled or (not self.movie_prompt_dialog
                                    and not self.tvshow_prompt_dialog):
         return
     ask_message_typelist = []
     if mediatype == common.VideoId.MOVIE and self.movie_prompt_dialog:
         ask_message_typelist.append(common.get_local_string(30189))
     if mediatype in common.VideoId.TV_TYPES and self.tvshow_prompt_dialog:
         ask_message_typelist.append(common.get_local_string(30190))
     if not mediatype:
         # If 'None' a massive export has been requested (i.e. first library sync, manual sync, my list auto-sync...)
         if self.movie_prompt_dialog:
             ask_message_typelist.append(common.get_local_string(30189))
         if self.tvshow_prompt_dialog:
             ask_message_typelist.append(common.get_local_string(30190))
     if ask_message_typelist:
         message = ' {} '.format(
             common.get_local_string(1397)).join(ask_message_typelist)
         message = dialog_message.format(message) + common.get_local_string(
             30192)
         user_choice = ui.ask_for_confirmation(
             common.get_local_string(30182), message)
         if len(ask_message_typelist) == 2 and not user_choice:
             self._export_movie_id = 0
             self._export_tvshow_id = 0
         elif common.get_local_string(
                 30189) in ask_message_typelist and not user_choice:
             self._export_movie_id = 0
         elif common.get_local_string(
                 30190) in ask_message_typelist and not user_choice:
             self._export_tvshow_id = 0
Esempio n. 8
0
 def remove_watched_status(self, videoid):
     """Remove the watched status from the Netflix service"""
     if not ui.ask_for_confirmation(
             common.get_local_string(30168),
             common.get_local_string(30300).format(
                 xbmc.getInfoLabel('ListItem.Label'))):
         return
     if not api.remove_watched_status(videoid):
         ui.show_notification(
             'The operation was cancelled due to an unexpected error')
         return
     # Check if item is in the cache
     videoid_exists, list_id = common.make_http_call(
         'get_continuewatching_videoid_exists',
         {'video_id': str(videoid.value)})
     if videoid_exists:
         # Try to remove the videoid from the list in the cache
         try:
             video_list_sorted_data = G.CACHE.get(cache_utils.CACHE_COMMON,
                                                  list_id)
             del video_list_sorted_data.videos[videoid.value]
             G.CACHE.add(cache_utils.CACHE_COMMON, list_id,
                         video_list_sorted_data)
             common.json_rpc(
                 'Input.Down')  # Avoids selection back to the top
         except CacheMiss:
             pass
     common.container_refresh()
Esempio n. 9
0
 def sync_mylist(self, pathitems):  # pylint: disable=unused-argument
     """
     Perform a full sync of Netflix "My List" with the Kodi library
     """
     if not ui.ask_for_confirmation(common.get_local_string(30122),
                                    common.get_local_string(30123)):
         return
     library.sync_mylist_to_library()
Esempio n. 10
0
def search_clear():
    """Clear all search items"""
    if not ui.ask_for_confirmation(common.get_local_string(30404),
                                   common.get_local_string(30406)):
        return False
    G.LOCAL_DB.clear_search_items()
    common.container_refresh()
    return True
Esempio n. 11
0
 def import_library(self, pathitems):  # pylint: disable=unused-argument
     """Import previous exported STRM files to add-on and/or convert them to the current STRM format type"""
     if _check_auto_update_running():
         return
     if not ui.ask_for_confirmation(common.get_local_string(30140),
                                    common.get_local_string(20135)):
         return
     get_library_cls().import_library()
Esempio n. 12
0
 def purge(self, pathitems):  # pylint: disable=unused-argument
     """Delete all previously exported items from the Kodi library"""
     if _check_auto_update_running():
         return
     if not ui.ask_for_confirmation(common.get_local_string(30125),
                                    common.get_local_string(30126)):
         return
     get_library_cls().clear_library()
Esempio n. 13
0
 def auto_upd_run_now(self, pathitems):  # pylint: disable=unused-argument
     """
     Perform an auto update of Kodi library to add new seasons/episodes of tv shows
     """
     if not ui.ask_for_confirmation(common.get_local_string(30065),
                                    common.get_local_string(30231)):
         return
     library.auto_update_library(False, False)
Esempio n. 14
0
 def lib_remove(self, pathitems, videoid=None):  # pylint: disable=unused-argument
     """Remove an item to the Kodi library"""
     if videoid.mediatype in [common.VideoId.SUPPLEMENTAL, common.VideoId.EPISODE]:
         return
     if not ui.ask_for_confirmation(common.get_local_string(30030),
                                    common.get_local_string(30124)):
         return
     get_library_cls().remove_from_library(videoid)
     common.container_refresh(use_delay=True)
Esempio n. 15
0
 def import_library(self, pathitems):  # pylint: disable=unused-argument
     """Import previous exported STRM files to add-on and/or convert them to the current STRM format type"""
     if _check_auto_update_running():
         return
     path = ui.show_browse_dialog(common.get_local_string(651),
                                  default_path=G.DATA_PATH)
     if path:
         if not ui.ask_for_confirmation(common.get_local_string(30140),
                                        common.get_local_string(20135)):
             return
         get_library_cls().import_library(path)
Esempio n. 16
0
    def initial_mylist_sync(self, pathitems):
        """Perform an initial sync of My List and the Kodi library"""
        # pylint: disable=unused-argument
        do_it = ui.ask_for_confirmation(common.get_local_string(30122),
                                        common.get_local_string(30123))
        if not do_it or not g.ADDON.getSettingBool('mylist_library_sync'):
            return

        common.debug('Performing full sync from My List to Kodi library')
        library.purge()
        for videoid in api.video_list(
                api.list_id_for_type('queue')).videoids:
            library.execute_library_tasks(videoid, library.export_item,
                                          common.get_local_string(30018),
                                          sync_mylist=False)
 def reset_esn(self, pathitems=None):  # pylint: disable=unused-argument
     """Reset the ESN stored (retrieved from website and manual)"""
     from resources.lib.database.db_utils import (TABLE_SESSION, TABLE_SETTINGS_MONITOR)
     if not ui.ask_for_confirmation(common.get_local_string(30217),
                                    common.get_local_string(30218)):
         return
     # Reset the ESN obtained from website/generated
     g.LOCAL_DB.set_value('esn', '', TABLE_SESSION)
     # Reset the custom ESN (manual ESN from settings)
     g.settings_monitor_suspend(at_first_change=True)
     g.ADDON.setSetting('esn', '')
     # Reset the custom ESN (backup of manual ESN from settings, used in settings_monitor.py)
     g.LOCAL_DB.set_value('custom_esn', '', TABLE_SETTINGS_MONITOR)
     # Perform a new login to get/generate a new ESN
     api.login(ask_credentials=False)
     # Warning after login netflix switch to the main profile! so return to the main screen
     # Open root page
     common.container_update(g.BASE_URL, True)
Esempio n. 18
0
 def initial_mylist_sync(self, pathitems):
     """Perform an initial sync of My List and the Kodi library"""
     # pylint: disable=unused-argument
     from resources.lib.cache import CACHE_COMMON
     do_it = ui.ask_for_confirmation(common.get_local_string(30122),
                                     common.get_local_string(30123))
     if not do_it:
         return
     common.debug('Performing full sync from My List to Kodi library')
     library.purge()
     nfo_settings = nfo.NFOSettings()
     nfo_settings.show_export_dialog()
     # Invalidate my-list cached data to force to obtain new data
     g.CACHE.invalidate_entry(CACHE_COMMON, 'my_list_items')
     for videoid in api.mylist_items():
         library.execute_library_tasks(videoid, [library.export_item],
                                       common.get_local_string(30018),
                                       sync_mylist=False,
                                       nfo_settings=nfo_settings)
Esempio n. 19
0
 def _import_library_remove(self, remove_titles, remove_folders):
     if not remove_folders:
         return False
     # If there are STRM files that it was not possible to import them,
     # we will ask to user if you want to delete them
     tot_folders = len(remove_folders)
     if tot_folders > 50:
         remove_titles = remove_titles[:50] + ['...']
     message = common.get_local_string(30246).format(tot_folders) + '[CR][CR]' + ', '.join(remove_titles)
     if not ui.ask_for_confirmation(common.get_local_string(30140), message):
         return False
     # Delete all folders
     LOG.info('Start deleting folders')
     with ui.ProgressDialog(True, max_value=tot_folders) as progress_bar:
         for file_path in remove_folders:
             progress_bar.set_message('{}/{}'.format(progress_bar.value, tot_folders))
             LOG.debug('Deleting folder: {}', file_path)
             common.delete_folder(file_path)
             progress_bar.perform_step()
     return True
Esempio n. 20
0
 def reset_esn(self, pathitems=None):  # pylint: disable=unused-argument
     """Reset the ESN stored (retrieved from website and manual)"""
     if not ui.ask_for_confirmation(common.get_local_string(30217),
                                    common.get_local_string(30218)):
         return
     # Generate a new ESN
     generated_esn = self._get_new_esn()
     # Reset the ESN obtained from website/generated
     G.LOCAL_DB.set_value('esn', '', TABLE_SESSION)
     # Reset the custom ESN (manual ESN from settings)
     G.settings_monitor_suspend(at_first_change=True)
     G.ADDON.setSetting('esn', '')
     # Reset the custom ESN (backup of manual ESN from settings, used in settings_monitor.py)
     G.LOCAL_DB.set_value('custom_esn', '', TABLE_SETTINGS_MONITOR)
     # Save the new ESN
     G.LOCAL_DB.set_value('esn', generated_esn, TABLE_SESSION)
     # Reinitialize the MSL handler (delete msl data file, then reset everything)
     common.send_signal(signal=common.Signals.REINITIALIZE_MSL_HANDLER, data=True)
     # Show login notification
     ui.show_notification(common.get_local_string(30109))
     # Open root page
     common.container_update(G.BASE_URL, True)
Esempio n. 21
0
 def reset_esn(self, pathitems=None):  # pylint: disable=unused-argument
     """Reset the ESN stored (retrieved from website and manual)"""
     from resources.lib.database.db_utils import (TABLE_SESSION,
                                                  TABLE_SETTINGS_MONITOR)
     if not ui.ask_for_confirmation(common.get_local_string(30217),
                                    common.get_local_string(30218)):
         return
     # Reset the ESN obtained from website/generated
     g.LOCAL_DB.set_value('esn', '', TABLE_SESSION)
     # Reset the custom ESN (manual ESN from settings)
     g.settings_monitor_suspend(at_first_change=True)
     g.ADDON.setSetting('esn', '')
     # Reset the custom ESN (backup of manual ESN from settings, used in settings_monitor.py)
     g.LOCAL_DB.set_value('custom_esn', '', TABLE_SETTINGS_MONITOR)
     # Perform a new login to get/generate a new ESN
     api.login(ask_credentials=False)
     # Warning after login netflix switch to the main profile! so return to the main screen
     url = 'plugin://plugin.video.netflix/directory/root'
     xbmc.executebuiltin(
         'XBMC.Container.Update(path,replace)')  # Clean path history
     xbmc.executebuiltin(
         'Container.Update({})'.format(url))  # Open root page
Esempio n. 22
0
    def auto_update_library(self, sync_with_mylist, show_prg_dialog=True, show_nfo_dialog=False, clear_on_cancel=False,
                            update_profiles=False):
        """
        Perform an auto update of the exported items in to Kodi library.
        - The main purpose is check if there are new seasons/episodes.
        - In the case "Sync Kodi library with My list" feature is enabled, will be also synchronized with My List.
        :param sync_with_mylist: if True, sync the Kodi library with Netflix My List
        :param show_prg_dialog: if True, will be show a progress dialog window and the errors will be notified to user
        :param show_nfo_dialog: if True, ask to user if want export NFO files (override custom NFO actions for videoid)
        :param clear_on_cancel: if True, when the user cancel the operations will be cleared the entire library
        :param update_profiles: if True, before perform sync_with_mylist will be updated the profiles
        """
        if is_auto_update_library_running(show_prg_dialog):
            return
        LOG.info('Start auto-updating of Kodi library {}', '(with sync of My List)' if sync_with_mylist else '')
        G.SHARED_DB.set_value('library_auto_update_is_running', True)
        G.SHARED_DB.set_value('library_auto_update_start_time', datetime.now())
        try:
            # Get the full list of the exported tvshows/movies as id (VideoId.value)
            exp_tvshows_videoids_values = G.SHARED_DB.get_tvshows_id_list()
            exp_movies_videoids_values = G.SHARED_DB.get_movies_id_list()

            # Get the exported tv shows (to be updated) as dict (key=videoid, value=type of task)
            videoids_tasks = {
                common.VideoId.from_path([common.VideoId.SHOW, videoid_value]): self.export_new_item
                for videoid_value in G.SHARED_DB.get_tvshows_id_list(VidLibProp['exclude_update'], False)
            }
            if sync_with_mylist and update_profiles:
                # Before do the sync with My list try to update the profiles in the database,
                # to do a sanity check of the features that are linked to the profiles
                self.ext_func_req_profiles_info(update_database=True)  # pylint: disable=not-callable
                sync_with_mylist = G.ADDON.getSettingBool('lib_sync_mylist')
            # If enabled sync the Kodi library with Netflix My List
            if sync_with_mylist:
                self._sync_my_list_ops(videoids_tasks, exp_tvshows_videoids_values, exp_movies_videoids_values)

            # Show a warning message when there are more than 100 titles to be updated, making too many metadata
            # requests may cause blocking of http communication from the server or temporary ban of the account
            if show_prg_dialog:
                total_titles_upd = sum(task != self.remove_item for task in videoids_tasks.values())
                if total_titles_upd >= 100 and not ui.ask_for_confirmation(
                        common.get_local_string(30122),
                        common.get_local_string(30059).format(total_titles_upd)):
                    return
            # Start the update operations
            ret = self._update_library(videoids_tasks, exp_tvshows_videoids_values, show_prg_dialog, show_nfo_dialog,
                                       clear_on_cancel)
            if not ret:
                return
            request_kodi_library_update(scan=True, clean=True)
            # Save date for completed operation to compute next update schedule (used in library_updater.py)
            G.SHARED_DB.set_value('library_auto_update_last_start', datetime.now())
            LOG.info('Auto update of the Kodi library completed')
            if not G.ADDON.getSettingBool('lib_auto_upd_disable_notification'):
                ui.show_notification(common.get_local_string(30220), time=5000)
        except Exception as exc:  # pylint: disable=broad-except
            import traceback
            LOG.error('An error has occurred in the library auto update: {}', exc)
            LOG.error(G.py2_decode(traceback.format_exc(), 'latin-1'))
        finally:
            G.SHARED_DB.set_value('library_auto_update_is_running', False)
Esempio n. 23
0
 def purge(self, pathitems):
     """Delete all previously exported items from the Kodi library"""
     # pylint: disable=unused-argument
     if ui.ask_for_confirmation(common.get_local_string(30125),
                                common.get_local_string(30126)):
         library.purge()