예제 #1
0
def get_library_subfolders(folder_name):
    """Returns all the subfolders contained in a folder of library path"""
    section_path = common.join_folders_paths(get_library_path(), folder_name)
    return [
        common.join_folders_paths(section_path, G.py2_decode(folder))
        for folder in common.list_dir(section_path)[0]
    ]
def get_library_subfolders(folder_name, custom_lib_path=None):
    """Returns all the subfolders contained in a folder of library path"""
    section_path = common.join_folders_paths(
        custom_lib_path or get_library_path(), folder_name)
    return [
        common.join_folders_paths(section_path, folder)
        for folder in common.list_dir(section_path)[0]
    ]
 def export_item(self, job_data, library_home):
     """Create strm file for an item and add it to the library"""
     # Paths must be legal to ensure NFS compatibility
     destination_folder = common.join_folders_paths(library_home,
                                                    job_data['root_folder_name'],
                                                    job_data['folder_name'])
     common.create_folder(destination_folder)
     if job_data['create_strm_file']:
         strm_file_path = common.join_folders_paths(destination_folder, job_data['filename'] + '.strm')
         insert_videoid_to_db(job_data['videoid'], strm_file_path, job_data['nfo_data'] is not None)
         common.write_strm_file(job_data['videoid'], strm_file_path)
     if job_data['create_nfo_file']:
         nfo_file_path = common.join_folders_paths(destination_folder, job_data['filename'] + '.nfo')
         common.write_nfo_file(job_data['nfo_data'], nfo_file_path)
     common.debug('Exported {}: {}', job_data['videoid'], job_data['title'])
예제 #4
0
    def remove_item(self, job_data, library_home=None):  # pylint: disable=unused-argument
        """Remove an item from the Kodi library, delete it from disk, remove add-on database references"""
        videoid = job_data['videoid']
        LOG.debug('Removing {} ({}) from add-on library', videoid,
                  job_data['title'])
        try:
            # Remove the STRM file exported
            exported_file_path = G.py2_decode(
                xbmc.translatePath(job_data['file_path']))
            common.delete_file_safe(exported_file_path)

            parent_folder = G.py2_decode(
                xbmc.translatePath(os.path.dirname(exported_file_path)))

            # Remove the NFO file of the related STRM file
            nfo_file = os.path.splitext(exported_file_path)[0] + '.nfo'
            common.delete_file_safe(nfo_file)

            dirs, files = common.list_dir(parent_folder)

            # Remove the tvshow NFO file (only when it is the last file in the folder)
            tvshow_nfo_file = common.join_folders_paths(
                parent_folder, 'tvshow.nfo')

            # (users have the option of removing even single seasons)
            if xbmcvfs.exists(tvshow_nfo_file) and not dirs and len(
                    files) == 1:
                xbmcvfs.delete(tvshow_nfo_file)
                # Delete parent folder
                xbmcvfs.rmdir(parent_folder)

            # Delete parent folder when empty
            if not dirs and not files:
                xbmcvfs.rmdir(parent_folder)

            # Remove videoid records from add-on database
            remove_videoid_from_db(videoid)
        except ItemNotFound:
            LOG.warn(
                'The videoid {} not exists in the add-on library database',
                videoid)
        except Exception as exc:  # pylint: disable=broad-except
            import traceback
            LOG.error(G.py2_decode(traceback.format_exc(), 'latin-1'))
            ui.show_addon_error_info(exc)
예제 #5
0
 def clear_library(self, show_prg_dialog=True):
     """
     Delete all exported items to the library
     :param show_prg_dialog: if True, will be show a progress dialog window
     """
     LOG.info('Start deleting exported library items')
     # This will clear all the add-on library data, to prevents possible inconsistencies when for some reason
     # such as improper use of the add-on, unexpected error or other has broken the library database data or files
     with ui.ProgressDialog(show_prg_dialog, common.get_local_string(30245), max_value=3) as progress_dlg:
         progress_dlg.perform_step()
         progress_dlg.set_wait_message()
         G.SHARED_DB.purge_library()
         for folder_name in [FOLDER_NAME_MOVIES, FOLDER_NAME_SHOWS]:
             progress_dlg.perform_step()
             progress_dlg.set_wait_message()
             section_root_dir = common.join_folders_paths(get_library_path(), folder_name)
             common.delete_folder_contents(section_root_dir, delete_subfolders=True)
     # Clean the Kodi library database
     common.clean_library(show_prg_dialog)
 def import_videoid_from_existing_strm(self, folder_path, folder_name):
     """
     Get a VideoId from an existing STRM file that was exported
     """
     for filename in common.list_dir(folder_path)[1]:
         filename = G.py2_decode(filename)
         if not filename.endswith('.strm'):
             continue
         file_path = common.join_folders_paths(folder_path, filename)
         # Only get a VideoId from the first file in each folder.
         # For tv shows all episodes will result in the same VideoId, the movies only contain one file.
         file_content = common.load_file(file_path)
         if not file_content:
             common.warn('Import error: folder "{}" skipped, STRM file empty or corrupted', folder_name)
             return None
         if 'action=play_video' in file_content:
             common.debug('Trying to import (v0.13.x): {}', file_path)
             return self._import_videoid_old(file_content, folder_name)
         common.debug('Trying to import: {}', file_path)
         return self._import_videoid(file_content, folder_name)
예제 #7
0
def _get_cdm_file_path():
    if common.get_system_platform() == 'linux':
        lib_filename = 'libwidevinecdm.so'
    elif common.get_system_platform() in ['windows', 'uwp']:
        lib_filename = 'widevinecdm.dll'
    elif common.get_system_platform() == 'osx':
        lib_filename = 'libwidevinecdm.dylib'
        # import ctypes.util
        # lib_filename = util.find_library('libwidevinecdm.dylib')
    else:
        lib_filename = None
    if not lib_filename:
        raise Exception(
            'Widevine library filename not mapped for this operative system')
    # Get the CDM path from inputstream.adaptive (such as: ../.kodi/cdm)
    from xbmcaddon import Addon
    addon = Addon('inputstream.adaptive')
    cdm_path = xbmcvfs.translatePath(addon.getSetting('DECRYPTERPATH'))
    if not common.folder_exists(cdm_path):
        raise Exception(f'The CDM path {cdm_path} not exists')
    return common.join_folders_paths(cdm_path, lib_filename)
예제 #8
0
def _save_system_info():
    # Ask to save to a file
    filename = 'NFSystemInfo.txt'
    path = ui.show_browse_dialog(
        f'{common.get_local_string(30603)} - {filename}')
    if not path:
        return
    # This collect the main data to allow verification checks for problems
    data = f'Netflix add-on version: {G.VERSION}'
    data += f'\nDebug enabled: {LOG.is_enabled}'
    data += f'\nSystem platform: {common.get_system_platform()}'
    data += f'\nMachine architecture: {common.get_machine()}'
    data += f'\nUser agent string: {common.get_user_agent()}'
    data += '\n\n#### Widevine info ####\n'
    if common.get_system_platform() == 'android':
        data += f'\nSystem ID: {G.LOCAL_DB.get_value("drm_system_id", "--not obtained--", TABLE_SESSION)}'
        data += f'\nSecurity level: {G.LOCAL_DB.get_value("drm_security_level", "--not obtained--", TABLE_SESSION)}'
        data += f'\nHDCP level: {G.LOCAL_DB.get_value("drm_hdcp_level", "--not obtained--", TABLE_SESSION)}'
        wv_force_sec_lev = G.LOCAL_DB.get_value('widevine_force_seclev',
                                                WidevineForceSecLev.DISABLED,
                                                TABLE_SESSION)
        data += f'\nForced security level setting is: {wv_force_sec_lev}'
    else:
        try:
            from ctypes import (CDLL, c_char_p)
            cdm_lib_file_path = _get_cdm_file_path()
            try:
                lib = CDLL(cdm_lib_file_path)
                data += '\nLibrary status: Correctly loaded'
                try:
                    lib.GetCdmVersion.restype = c_char_p
                    data += f'\nVersion: {lib.GetCdmVersion().decode("utf-8")}'
                except Exception:  # pylint: disable=broad-except
                    # This can happen if the endpoint 'GetCdmVersion' is changed
                    data += '\nVersion: Reading error'
            except Exception as exc:  # pylint: disable=broad-except
                # This should not happen but currently InputStream Helper does not perform any verification checks on
                # downloaded and installed files, so if due to an problem it installs a CDM for a different architecture
                # or the files are corrupted, the user can no longer play videos and does not know what to do
                data += '\nLibrary status: Error loading failed'
                data += '\n>>> It is possible that is installed a CDM of a wrong architecture or is corrupted'
                data += '\n>>> Suggested solutions:'
                data += '\n>>> - Restore a previous version of Widevine library from InputStream Helper add-on settings'
                data += '\n>>> - Report the problem to the GitHub of InputStream Helper add-on'
                data += f'\n>>> Error details: {exc}'
        except Exception as exc:  # pylint: disable=broad-except
            data += f'\nThe data could not be obtained. Error details: {exc}'
    data += '\n\n#### ESN ####\n'
    esn = get_esn() or '--not obtained--'
    data += f'\nUsed ESN: {common.censure(esn) if len(esn) > 50 else esn}'
    data += f'\nWebsite ESN: {get_website_esn() or "--not obtained--"}'
    data += f'\nAndroid generated ESN: {(generate_android_esn() or "--not obtained--")}'
    if common.get_system_platform() == 'android':
        data += '\n\n#### Device system info ####\n'
        try:
            import subprocess
            info = subprocess.check_output(['/system/bin/getprop'
                                            ]).decode('utf-8')
            data += f'\n{info}'
        except Exception as exc:  # pylint: disable=broad-except
            data += f'\nThe data could not be obtained. Error: {exc}'
    data += '\n'
    try:
        common.save_file(common.join_folders_paths(path, filename),
                         data.encode('utf-8'))
        ui.show_notification(
            f'{xbmc.getLocalizedString(35259)}: {filename}')  # 35259=Saved
    except Exception as exc:  # pylint: disable=broad-except
        LOG.error('save_file error: {}', exc)
        ui.show_notification('Error! Try another path')