예제 #1
0
    def initialize(self):
        self.fs_encoding = get_viable_encoding()
        self.version = self.get_version()
        self.full_version = u"%s %s" % (PLUGIN_NAME, self.version)

        self.set_plugin_mode()
        self.set_plugin_lock()

        self.lang_list = self.get_lang_list()
        self.subtitle_destination_folder = self.get_subtitle_destination_folder(
        )
        self.providers = self.get_providers()
        self.provider_settings = self.get_provider_settings()
        self.max_recent_items_per_library = int_or_default(
            Prefs["scheduler.max_recent_items_per_library"], 2000)
        self.sections = list(Plex["library"].sections())
        self.missing_permissions = []
        self.ignore_sz_files = cast_bool(Prefs["subtitles.ignore_fs"])
        self.ignore_paths = self.parse_ignore_paths()
        self.enabled_sections = self.check_enabled_sections()
        self.permissions_ok = self.check_permissions()
        self.notify_executable = self.check_notify_executable()
        self.enforce_encoding = cast_bool(Prefs['subtitles.enforce_encoding'])
        self.chmod = self.check_chmod()
        self.forced_only = cast_bool(Prefs["subtitles.only_foreign"])
        self.initialized = True
예제 #2
0
    def check_permissions(self):
        if not cast_bool(Prefs["subtitles.save.filesystem"]) or not cast_bool(
                Prefs["check_permissions"]):
            return True

        self.missing_permissions = []
        use_ignore_fs = Prefs["subtitles.ignore_fs"]
        all_permissions_ok = True
        for section in self.sections:
            if section.key not in self.enabled_sections:
                continue

            title = section.title
            for location in section:
                path_str = location.path
                if isinstance(path_str, unicode):
                    path_str = path_str.encode(self.fs_encoding)

                if use_ignore_fs:
                    # check whether we've got an ignore file inside the section path
                    if self.is_physically_ignored(path_str):
                        continue

                if self.is_path_ignored(path_str):
                    # is the path in our ignored paths setting?
                    continue

                # section not ignored, check for write permissions
                if not check_write_permissions(path_str):
                    # not enough permissions
                    self.missing_permissions.append((title, location.path))
                    all_permissions_ok = False

        return all_permissions_ok
예제 #3
0
def save_subtitles(scanned_video_part_map, downloaded_subtitles, mode="a", bare_save=False, mods=None,
                   set_current=True):
    """
     
    :param set_current: save the subtitle as the current one
    :param scanned_video_part_map:
    :param downloaded_subtitles: 
    :param mode: 
    :param bare_save: don't trigger anything; don't store information
    :param mods: enabled mods
    :return: 
    """
    meta_fallback = False
    save_successful = False

    # big fixme: scanned_video_part_map isn't needed to the current extent. rewrite.

    if mods:
        for video, video_subtitles in downloaded_subtitles.items():
            if not video_subtitles:
                continue

            for subtitle in video_subtitles:
                Log.Info("Applying mods: %s to %s", mods, subtitle)
                subtitle.mods = mods
                subtitle.plex_media_fps = video.fps

    storage = "metadata"
    save_to_fs = cast_bool(Prefs['subtitles.save.filesystem'])
    if save_to_fs:
        storage = "filesystem"

    if set_current:
        if save_to_fs:
            try:
                Log.Debug("Using filesystem as subtitle storage")
                save_subtitles_to_file(downloaded_subtitles)
            except OSError:
                if cast_bool(Prefs["subtitles.save.metadata_fallback"]):
                    meta_fallback = True
                    storage = "metadata"
                else:
                    raise
            else:
                save_successful = True

        if not save_to_fs or meta_fallback:
            if meta_fallback:
                Log.Debug("Using metadata as subtitle storage, because filesystem storage failed")
            else:
                Log.Debug("Using metadata as subtitle storage")
            save_successful = save_subtitles_to_metadata(scanned_video_part_map, downloaded_subtitles)

        if not bare_save and save_successful and config.notify_executable:
            notify_executable(config.notify_executable, scanned_video_part_map, downloaded_subtitles, storage)

    if (not bare_save and save_successful) or not set_current:
        store_subtitle_info(scanned_video_part_map, downloaded_subtitles, storage, mode=mode, set_current=set_current)

    return save_successful
예제 #4
0
def save_subtitles(scanned_video_part_map, downloaded_subtitles, mode="a", bare_save=False, mods=None,
                   set_current=True):
    """
     
    :param set_current: save the subtitle as the current one
    :param scanned_video_part_map:
    :param downloaded_subtitles: 
    :param mode: 
    :param bare_save: don't trigger anything; don't store information
    :param mods: enabled mods
    :return: 
    """
    meta_fallback = False
    save_successful = False

    # big fixme: scanned_video_part_map isn't needed to the current extent. rewrite.

    if mods:
        for video, video_subtitles in downloaded_subtitles.items():
            if not video_subtitles:
                continue

            for subtitle in video_subtitles:
                Log.Info("Applying mods: %s to %s", mods, subtitle)
                subtitle.mods = mods
                subtitle.plex_media_fps = video.fps

    storage = "metadata"
    save_to_fs = cast_bool(Prefs['subtitles.save.filesystem'])
    if save_to_fs:
        storage = "filesystem"

    if set_current:
        if save_to_fs:
            try:
                Log.Debug("Using filesystem as subtitle storage")
                save_subtitles_to_file(downloaded_subtitles)
            except OSError:
                if cast_bool(Prefs["subtitles.save.metadata_fallback"]):
                    meta_fallback = True
                    storage = "metadata"
                else:
                    raise
            else:
                save_successful = True

        if not save_to_fs or meta_fallback:
            if meta_fallback:
                Log.Debug("Using metadata as subtitle storage, because filesystem storage failed")
            else:
                Log.Debug("Using metadata as subtitle storage")
            save_successful = save_subtitles_to_metadata(scanned_video_part_map, downloaded_subtitles)

        if not bare_save and save_successful and config.notify_executable:
            notify_executable(config.notify_executable, scanned_video_part_map, downloaded_subtitles, storage)

    if (not bare_save and save_successful) or not set_current:
        store_subtitle_info(scanned_video_part_map, downloaded_subtitles, storage, mode=mode, set_current=set_current)

    return save_successful
예제 #5
0
    def get_provider_settings(self):
        os_use_https = self.advanced.providers.opensubtitles.use_https \
            if self.advanced.providers.opensubtitles.use_https != None else True
        provider_settings = {
            'addic7ed': {
                'username':
                Prefs['provider.addic7ed.username'],
                'password':
                Prefs['provider.addic7ed.password'],
                'use_random_agents':
                cast_bool(Prefs['provider.addic7ed.use_random_agents1']),
            },
            'opensubtitles': {
                'username': Prefs['provider.opensubtitles.username'],
                'password': Prefs['provider.opensubtitles.password'],
                'use_tag_search': self.exact_filenames,
                'only_foreign': self.forced_only,
                'is_vip': cast_bool(Prefs['provider.opensubtitles.is_vip']),
                'use_ssl': os_use_https,
                'timeout': self.advanced.providers.opensubtitles.timeout or 15
            },
            'podnapisi': {
                'only_foreign': self.forced_only,
            },
            'legendastv': {
                'username': Prefs['provider.legendastv.username'],
                'password': Prefs['provider.legendastv.password'],
            }
        }

        return provider_settings
예제 #6
0
    def get_provider_settings(self):
        provider_settings = {
            'addic7ed': {
                'username':
                Prefs['provider.addic7ed.username'],
                'password':
                Prefs['provider.addic7ed.password'],
                'use_random_agents':
                cast_bool(Prefs['provider.addic7ed.use_random_agents']),
            },
            'opensubtitles': {
                'username': Prefs['provider.opensubtitles.username'],
                'password': Prefs['provider.opensubtitles.password'],
                'use_tag_search': self.exact_filenames,
                'only_foreign': self.forced_only,
                'is_vip': cast_bool(Prefs['provider.opensubtitles.is_vip'])
            },
            'podnapisi': {
                'only_foreign': self.forced_only,
            },
            'legendastv': {
                'username': Prefs['provider.legendastv.username'],
                'password': Prefs['provider.legendastv.password'],
            }
        }

        return provider_settings
예제 #7
0
    def get_provider_settings(self):
        provider_settings = {
            'addic7ed': {
                'username':
                Prefs['provider.addic7ed.username'],
                'password':
                Prefs['provider.addic7ed.password'],
                'use_random_agents':
                cast_bool(Prefs['provider.addic7ed.use_random_agents']),
            },
            'opensubtitles': {
                'username':
                Prefs['provider.opensubtitles.username'],
                'password':
                Prefs['provider.opensubtitles.password'],
                'use_tag_search':
                cast_bool(Prefs['provider.opensubtitles.use_tags']),
                'only_foreign':
                cast_bool(Prefs['subtitles.only_foreign'])
            },
            'podnapisi': {
                'only_foreign': cast_bool(Prefs['subtitles.only_foreign'])
            },
            'legendastv': {
                'username': Prefs['provider.legendastv.username'],
                'password': Prefs['provider.legendastv.password'],
            },
        }

        return provider_settings
예제 #8
0
    def get_provider_settings(self):
        os_use_https = self.advanced.providers.opensubtitles.get(
            "use_https", True)
        os_skip_wrong_fps = self.advanced.providers.opensubtitles.get(
            "skip_wrong_fps", True)

        provider_settings = {
            'addic7ed': {
                'username': Prefs['provider.addic7ed.username'],
                'password': Prefs['provider.addic7ed.password'],
                'is_vip': cast_bool(Prefs['provider.addic7ed.is_vip']),
            },
            'opensubtitles': {
                'username': Prefs['provider.opensubtitles.username'],
                'password': Prefs['provider.opensubtitles.password'],
                'use_tag_search': self.exact_filenames,
                'only_foreign': self.forced_only,
                'also_foreign': self.forced_also,
                'is_vip': cast_bool(Prefs['provider.opensubtitles.is_vip']),
                'use_ssl': os_use_https,
                'timeout': self.advanced.providers.opensubtitles.timeout or 15,
                'skip_wrong_fps': os_skip_wrong_fps,
            },
            'podnapisi': {
                'only_foreign': self.forced_only,
                'also_foreign': self.forced_also,
            },
            'titlovi': {
                'username': Prefs['provider.titlovi.username'],
                'password': Prefs['provider.titlovi.password'],
            },
            'napisy24': {
                'username': Prefs['provider.napisy24.username'],
                'password': Prefs['provider.napisy24.password'],
            },
            'subscene': {
                'only_foreign': self.forced_only,
                'username': Prefs['provider.subscene.username'],
                'password': Prefs['provider.subscene.password'],
            },
            'legendastv': {
                'username': Prefs['provider.legendastv.username'],
                'password': Prefs['provider.legendastv.password'],
            },
            'assrt': {
                'token': Prefs['provider.assrt.token'],
            },
            'ktuvit': {
                'username': Prefs['provider.ktuvit.username'],
                'password': Prefs['provider.ktuvit.password'],
            },
        }

        return provider_settings
예제 #9
0
    def get_providers(self):
        providers = {
            'opensubtitles':
            cast_bool(Prefs['provider.opensubtitles.enabled']),
            # 'thesubdb': Prefs['provider.thesubdb.enabled'],
            'podnapisi': cast_bool(Prefs['provider.podnapisi.enabled']),
            'titlovi': cast_bool(Prefs['provider.titlovi.enabled']),
            'addic7ed': cast_bool(Prefs['provider.addic7ed.enabled']),
            'tvsubtitles': cast_bool(Prefs['provider.tvsubtitles.enabled']),
            'legendastv': cast_bool(Prefs['provider.legendastv.enabled']),
            'napiprojekt': cast_bool(Prefs['provider.napiprojekt.enabled']),
            'shooter': cast_bool(Prefs['provider.shooter.enabled']),
            'subscenter': False,
        }

        # ditch non-forced-subtitles-reporting providers
        if self.forced_only:
            providers["addic7ed"] = False
            providers["tvsubtitles"] = False
            providers["legendastv"] = False
            providers["napiprojekt"] = False
            providers["shooter"] = False
            providers["titlovi"] = False
            providers["subscenter"] = False

        return filter(lambda prov: providers[prov], providers)
예제 #10
0
def save_subtitles_to_file(subtitles):
    fld_custom = Prefs["subtitles.save.subFolder.Custom"].strip() \
        if Prefs["subtitles.save.subFolder.Custom"] else None

    for video, video_subtitles in subtitles.items():
        if not video_subtitles:
            continue

        fld = None
        if fld_custom or Prefs["subtitles.save.subFolder"] != "current folder":
            # specific subFolder requested, create it if it doesn't exist
            fld_base = os.path.split(video.name)[0]
            if fld_custom:
                if fld_custom.startswith("/"):
                    # absolute folder
                    fld = fld_custom
                else:
                    fld = os.path.join(fld_base, fld_custom)
            else:
                fld = os.path.join(fld_base, Prefs["subtitles.save.subFolder"])
            fld = force_unicode(fld)
            if not os.path.exists(fld):
                os.makedirs(fld)
        subliminal.api.save_subtitles(
            video,
            video_subtitles,
            directory=fld,
            single=cast_bool(Prefs['subtitles.only_one']),
            encode_with=force_utf8 if config.enforce_encoding else None,
            chmod=config.chmod,
            forced_tag=config.forced_only,
            path_decoder=force_unicode)
    return True
예제 #11
0
def match_ietf_language(s):
    language_match = re.match(".+\.([^\.]+)$" if not helpers.cast_bool(Prefs["subtitles.language.ietf_display"])
                              else IETF_MATCH, s)
    if language_match and len(language_match.groups()) == 1:
        language = language_match.groups()[0]
        return language
    return s
예제 #12
0
    def get_provider_settings(self):
        os_use_https = self.advanced.providers.opensubtitles.use_https \
            if self.advanced.providers.opensubtitles.use_https is not None else True

        os_skip_wrong_fps = self.advanced.providers.opensubtitles.skip_wrong_fps \
            if self.advanced.providers.opensubtitles.skip_wrong_fps is not None else True

        provider_settings = {'addic7ed': {'username': Prefs['provider.addic7ed.username'],
                                          'password': Prefs['provider.addic7ed.password'],
                                          },
                             'opensubtitles': {'username': Prefs['provider.opensubtitles.username'],
                                               'password': Prefs['provider.opensubtitles.password'],
                                               'use_tag_search': self.exact_filenames,
                                               'only_foreign': self.forced_only,
                                               'also_foreign': self.forced_also,
                                               'is_vip': cast_bool(Prefs['provider.opensubtitles.is_vip']),
                                               'use_ssl': os_use_https,
                                               'timeout': self.advanced.providers.opensubtitles.timeout or 15,
                                               'skip_wrong_fps': os_skip_wrong_fps,
                                               },
                             'podnapisi': {
                                 'only_foreign': self.forced_only,
                                 'also_foreign': self.forced_also,
                             },
                             'subscene': {
                                 'only_foreign': self.forced_only,
                             },
                             'legendastv': {'username': Prefs['provider.legendastv.username'],
                                            'password': Prefs['provider.legendastv.password'],
                                            },
                             'assrt': {'token': Prefs['provider.assrt.token'], }
                             }

        return provider_settings
예제 #13
0
    def get_providers(self):
        providers = {
            'opensubtitles':
            cast_bool(Prefs['provider.opensubtitles.enabled']),
            #'thesubdb': Prefs['provider.thesubdb.enabled'],
            'podnapisi': cast_bool(Prefs['provider.podnapisi.enabled']),
            'addic7ed': cast_bool(Prefs['provider.addic7ed.enabled']),
            'tvsubtitles': cast_bool(Prefs['provider.tvsubtitles.enabled'])
        }

        # ditch non-forced-subtitles-reporting providers
        if cast_bool(Prefs['subtitles.only_foreign']):
            providers["addic7ed"] = False
            providers["tvsubtitles"] = False

        return filter(lambda prov: providers[prov], providers)
예제 #14
0
def match_ietf_language(s):
    language_match = re.match(".+\.([^\.]+)$" if not helpers.cast_bool(Prefs["subtitles.language.ietf"])
                              else IETF_MATCH, s)
    if language_match and len(language_match.groups()) == 1:
        language = language_match.groups()[0]
        return language
    return s
예제 #15
0
    def initialize(self):
        self.libraries_root = os.path.abspath(
            os.path.join(get_root_path(), ".."))
        self.init_libraries()

        self.fs_encoding = get_viable_encoding()
        self.plugin_info = self.get_plugin_info()
        self.is_development = self.get_dev_mode()
        self.version = self.get_version()
        self.full_version = u"%s %s" % (PLUGIN_NAME, self.version)
        self.set_log_paths()
        self.app_support_path = Core.app_support_path
        self.data_path = getattr(Data, "_core").storage.data_path
        self.data_items_path = os.path.join(self.data_path, "DataItems")
        self.universal_plex_token = self.get_universal_plex_token()
        self.plex_token = os.environ.get("PLEXTOKEN",
                                         self.universal_plex_token)

        os.environ["SZ_USER_AGENT"] = self.get_user_agent()

        self.providers = self.get_providers()

        self.set_plugin_mode()
        self.set_plugin_lock()
        self.set_activity_modes()

        self.lang_list = self.get_lang_list()
        self.subtitle_destination_folder = self.get_subtitle_destination_folder(
        )
        self.subtitle_formats = self.get_subtitle_formats()
        self.forced_only = cast_bool(Prefs["subtitles.only_foreign"])
        self.provider_settings = self.get_provider_settings()
        self.max_recent_items_per_library = int_or_default(
            Prefs["scheduler.max_recent_items_per_library"], 2000)
        self.sections = list(Plex["library"].sections())
        self.missing_permissions = []
        self.ignore_sz_files = cast_bool(Prefs["subtitles.ignore_fs"])
        self.ignore_paths = self.parse_ignore_paths()
        self.enabled_sections = self.check_enabled_sections()
        self.permissions_ok = self.check_permissions()
        self.notify_executable = self.check_notify_executable()
        self.remove_hi = cast_bool(Prefs['subtitles.remove_hi'])
        self.fix_ocr = cast_bool(Prefs['subtitles.fix_ocr'])
        self.fix_common = cast_bool(Prefs['subtitles.fix_common'])
        self.colors = Prefs['subtitles.colors'] if Prefs[
            'subtitles.colors'] != "don't change" else None
        self.chmod = self.check_chmod()
        self.exotic_ext = cast_bool(Prefs["subtitles.scan.exotic_ext"])
        self.treat_und_as_first = cast_bool(
            Prefs["subtitles.language.treat_und_as_first"])
        self.ext_match_strictness = self.determine_ext_sub_strictness()
        self.default_mods = self.get_default_mods()
        self.debug_mods = cast_bool(Prefs['log_debug_mods'])
        self.subtitles_save_to = Prefs['subtitles.save.filesystem']
        self.no_refresh = os.environ.get("SZ_NO_REFRESH", False)
        self.initialized = True
예제 #16
0
    def get_subtitle_destination_folder(self):
        if not Prefs["subtitles.save.filesystem"]:
            return

        fld_custom = Prefs["subtitles.save.subFolder.Custom"].strip() if cast_bool(
            Prefs["subtitles.save.subFolder.Custom"]) else None
        return fld_custom or (
            Prefs["subtitles.save.subFolder"] if Prefs["subtitles.save.subFolder"] != "current folder" else None)
예제 #17
0
    def get_subtitle_destination_folder(self):
        if not Prefs["subtitles.save.filesystem"]:
            return

        fld_custom = Prefs["subtitles.save.subFolder.Custom"].strip() if cast_bool(
            Prefs["subtitles.save.subFolder.Custom"]) else None
        return fld_custom or (
            Prefs["subtitles.save.subFolder"] if Prefs["subtitles.save.subFolder"] != "current folder" else None)
예제 #18
0
def subtitle_helpers(filename):
    filename = helpers.unicodize(filename)
    helper_classes = [DefaultSubtitleHelper]

    if helpers.cast_bool(Prefs["subtitles.scan.exotic_ext"]):
        helper_classes.insert(0, VobSubSubtitleHelper)

    for cls in helper_classes:
        if cls.is_helper_for(filename):
            return cls(filename)
    return None
예제 #19
0
def subtitle_helpers(filename):
    filename = helpers.unicodize(filename)
    helper_classes = [DefaultSubtitleHelper]

    if helpers.cast_bool(Prefs["subtitles.scan.exotic_ext"]):
        helper_classes.insert(0, VobSubSubtitleHelper)

    for cls in helper_classes:
        if cls.is_helper_for(filename):
            return cls(filename)
    return None
예제 #20
0
 def init_subliminal_patches(self):
     # configure custom subtitle destination folders for scanning pre-existing subs
     Log.Debug("Patching subliminal ...")
     dest_folder = self.subtitle_destination_folder
     subliminal_patch.patch_video.CUSTOM_PATHS = [dest_folder
                                                  ] if dest_folder else []
     subliminal_patch.patch_video.INCLUDE_EXOTIC_SUBS = cast_bool(
         Prefs["subtitles.scan.exotic_ext"])
     subliminal_patch.patch_provider_pool.DOWNLOAD_TRIES = int(
         Prefs['subtitles.try_downloads'])
     subliminal.video.Episode.scores["addic7ed_boost"] = int(
         Prefs['provider.addic7ed.boost_by'])
예제 #21
0
    def parse_rename_mode(self):
        # fixme: exact_filenames should be determined via callback combined with info about the current video
        # (original_name)

        mode = str(Prefs["media_rename1"])
        self.refiner_settings = {}

        if cast_bool(Prefs['use_file_info_file']):
            self.refiner_settings["file_info_file"] = True
            self.exact_filenames = True

        if mode == "none of the above":
            return

        elif mode == "Symlink to original file":
            self.refiner_settings["symlinks"] = True
            self.exact_filenames = True
            return

        elif mode == "I keep the original filenames":
            self.exact_filenames = True
            return

        if mode in ("Filebot", "Sonarr/Radarr/Filebot"):
            self.refiner_settings["filebot"] = True

        if mode in ("Sonarr/Radarr (fill api info below)",
                    "Sonarr/Radarr/Filebot"):
            if Prefs["drone_api.sonarr.url"] and Prefs[
                    "drone_api.sonarr.api_key"]:
                self.refiner_settings["sonarr"] = {
                    "base_url": Prefs["drone_api.sonarr.url"],
                    "api_key": Prefs["drone_api.sonarr.api_key"],
                }
                if self.advanced.refiners.sonarr:
                    self.refiner_settings["sonarr"].update(
                        self.advanced.refiners.sonarr)

                self.exact_filenames = True

            if Prefs["drone_api.radarr.url"] and Prefs[
                    "drone_api.radarr.api_key"]:
                self.refiner_settings["radarr"] = {
                    "base_url": Prefs["drone_api.radarr.url"],
                    "api_key": Prefs["drone_api.radarr.api_key"]
                }
                if self.advanced.refiners.radarr:
                    self.refiner_settings["radarr"].update(
                        self.advanced.refiners.radarr)

                self.exact_filenames = True
예제 #22
0
def save_subtitles_to_file(subtitles, tags=None):
    for video, video_subtitles in subtitles.items():
        if not video_subtitles:
            continue

        if not isinstance(video, types.StringTypes):
            file_path = video.name
        else:
            file_path = video

        fld = get_target_folder(file_path)
        subliminal_save_subtitles(file_path, video_subtitles, directory=fld, single=cast_bool(Prefs['subtitles.only_one']),
                                  chmod=config.chmod, path_decoder=force_unicode,
                                  debug_mods=config.debug_mods, formats=config.subtitle_formats, tags=tags)
    return True
예제 #23
0
def save_subtitles_to_file(subtitles, tags=None):
    for video, video_subtitles in subtitles.items():
        if not video_subtitles:
            continue

        if not isinstance(video, types.StringTypes):
            file_path = video.name
        else:
            file_path = video

        fld = get_target_folder(file_path)
        subliminal_save_subtitles(file_path, video_subtitles, directory=fld, single=cast_bool(Prefs['subtitles.only_one']),
                                  chmod=config.chmod, path_decoder=force_unicode,
                                  debug_mods=config.debug_mods, formats=config.subtitle_formats, tags=tags)
    return True
예제 #24
0
    def get_subtitle_sub_dir(self):
        """

        :return: folder, is_absolute
        """
        if not cast_bool(Prefs['subtitles.save.filesystem']):
            return None, None

        if Prefs["subtitles.save.subFolder.Custom"]:
            return Prefs["subtitles.save.subFolder.Custom"], os.path.isabs(Prefs["subtitles.save.subFolder.Custom"])

        if Prefs["subtitles.save.subFolder"] == "current folder":
            return ".", False

        return Prefs["subtitles.save.subFolder"], False
예제 #25
0
    def check_permissions(self):
        if not cast_bool(Prefs["subtitles.save.filesystem"]) or not cast_bool(Prefs["check_permissions"]):
            return True

        self.missing_permissions = []
        use_include_exclude_fs = self.include_exclude_sz_files
        all_permissions_ok = True
        for section in self.sections:
            if section.key not in self.enabled_sections:
                continue

            title = section.title
            for location in section:
                path_str = location.path
                if isinstance(path_str, unicode):
                    path_str = path_str.encode(self.fs_encoding)

                if not os.path.exists(path_str):
                    continue

                if use_include_exclude_fs:
                    # check whether we've got an ignore file inside the section path
                    if not self.is_physically_wanted(path_str):
                        continue

                if not self.is_path_wanted(path_str):
                    # is the path in our ignored paths setting?
                    continue

                # section not ignored, check for write permissions
                if not check_write_permissions(path_str):
                    # not enough permissions
                    self.missing_permissions.append((title, location.path))
                    all_permissions_ok = False

        return all_permissions_ok
예제 #26
0
    def get_subtitle_sub_dir(self):
        """

        :return: folder, is_absolute
        """
        if not cast_bool(Prefs['subtitles.save.filesystem']):
            return None, None

        if Prefs["subtitles.save.subFolder.Custom"]:
            return Prefs["subtitles.save.subFolder.Custom"], os.path.isabs(Prefs["subtitles.save.subFolder.Custom"])

        if Prefs["subtitles.save.subFolder"] == "current folder":
            return ".", False

        return Prefs["subtitles.save.subFolder"], False
예제 #27
0
    def parse_rename_mode(self):
        # fixme: exact_filenames should be determined via callback combined with info about the current video
        # (original_name)

        mode = str(Prefs["media_rename1"])
        self.refiner_settings = {}

        if cast_bool(Prefs['use_file_info_file']):
            self.refiner_settings["file_info_file"] = True
            self.exact_filenames = True

        if mode == "none of the above":
            return

        elif mode == "Symlink to original file":
            self.refiner_settings["symlinks"] = True
            self.exact_filenames = True
            return

        elif mode == "I keep the original filenames":
            self.exact_filenames = True
            return

        if mode in ("Filebot", "Sonarr/Radarr/Filebot"):
            self.refiner_settings["filebot"] = True

        if mode in ("Sonarr/Radarr (fill api info below)", "Sonarr/Radarr/Filebot"):
            if Prefs["drone_api.sonarr.url"] and Prefs["drone_api.sonarr.api_key"]:
                self.refiner_settings["sonarr"] = {
                    "base_url": Prefs["drone_api.sonarr.url"],
                    "api_key": Prefs["drone_api.sonarr.api_key"],
                }
                if self.advanced.refiners.sonarr:
                    self.refiner_settings["sonarr"].update(self.advanced.refiners.sonarr)

                self.exact_filenames = True

            if Prefs["drone_api.radarr.url"] and Prefs["drone_api.radarr.api_key"]:
                self.refiner_settings["radarr"] = {
                    "base_url": Prefs["drone_api.radarr.url"],
                    "api_key": Prefs["drone_api.radarr.api_key"]
                }
                if self.advanced.refiners.radarr:
                    self.refiner_settings["radarr"].update(self.advanced.refiners.radarr)

                self.exact_filenames = True
예제 #28
0
 def provider_pool(self):
     if cast_bool(Prefs['providers.multithreading']):
         return subliminal_patch.core.SZAsyncProviderPool
     return subliminal_patch.core.SZProviderPool
예제 #29
0
    def get_providers(self, media_type="series"):
        providers = {
            'opensubtitles':
            cast_bool(Prefs['provider.opensubtitles.enabled']),
            # 'thesubdb': Prefs['provider.thesubdb.enabled'],
            'podnapisi': cast_bool(Prefs['provider.podnapisi.enabled']),
            'titlovi': cast_bool(Prefs['provider.titlovi.enabled']),
            'addic7ed': cast_bool(Prefs['provider.addic7ed.enabled']),
            'tvsubtitles': cast_bool(Prefs['provider.tvsubtitles.enabled']),
            'legendastv': cast_bool(Prefs['provider.legendastv.enabled']),
            'napiprojekt': cast_bool(Prefs['provider.napiprojekt.enabled']),
            'hosszupuska': cast_bool(Prefs['provider.hosszupuska.enabled']),
            'shooter': False,
            'subscene': cast_bool(Prefs['provider.subscene.enabled']),
            'argenteam': cast_bool(Prefs['provider.argenteam.enabled']),
            'subscenter': False,
        }

        providers_by_prefs = copy.deepcopy(providers)

        # disable subscene for movies by default
        if media_type == "movies":
            providers["subscene"] = False

        # ditch non-forced-subtitles-reporting providers
        if self.forced_only:
            providers["addic7ed"] = False
            providers["tvsubtitles"] = False
            providers["legendastv"] = False
            providers["napiprojekt"] = False
            providers["shooter"] = False
            providers["hosszupuska"] = False
            providers["titlovi"] = False
            providers["argenteam"] = False

        if not self.unrar and providers["legendastv"]:
            providers["legendastv"] = False
            Log.Info("Disabling LegendasTV, because UnRAR wasn't found")

        # advanced settings
        if media_type and self.advanced.providers:
            for provider, data in self.advanced.providers.iteritems():
                if provider not in providers or not providers_by_prefs[
                        provider]:
                    continue

                if data["enabled_for"] is not None:
                    providers[provider] = media_type in data["enabled_for"]

        if "provider_throttle" not in Dict:
            Dict["provider_throttle"] = {}

        changed = False
        for provider, enabled in dict(providers).iteritems():
            reason, until, throttle_desc = Dict["provider_throttle"].get(
                provider, (None, None, None))
            if reason:
                now = datetime.datetime.now()
                if now < until:
                    Log.Info("Not using %s until %s, because of: %s", provider,
                             until.strftime("%y/%m/%d %H:%M"), reason)
                    providers[provider] = False
                else:
                    Log.Info("Using %s again after %s, (disabled because: %s)",
                             provider, throttle_desc, reason)
                    del Dict["provider_throttle"][provider]
                    changed = True

        if changed:
            Dict.Save()

        return filter(lambda prov: providers[prov], providers)
예제 #30
0
    def initialize(self):
        self.libraries_root = os.path.abspath(
            os.path.join(get_root_path(), ".."))
        self.init_libraries()

        if is_windows_special_path:
            Log.Warn(
                "The Plex metadata folder is residing inside a folder with special characters. "
                "Multithreading and playback activities will be disabled.")

        self.fs_encoding = get_viable_encoding()
        self.plugin_info = self.get_plugin_info()
        self.is_development = self.get_dev_mode()
        self.version = self.get_version()
        self.full_version = u"%s %s" % (PLUGIN_NAME, self.version)
        self.set_log_paths()
        self.app_support_path = Core.app_support_path
        self.data_path = getattr(Data, "_core").storage.data_path
        self.data_items_path = os.path.join(self.data_path, "DataItems")
        self.universal_plex_token = self.get_universal_plex_token()
        self.plex_token = os.environ.get("PLEXTOKEN",
                                         self.universal_plex_token)
        subzero.constants.DEFAULT_TIMEOUT = lib.DEFAULT_TIMEOUT = self.pms_request_timeout = \
            min(cast_int(Prefs['pms_request_timeout'], 15), 45)
        self.low_impact_mode = cast_bool(Prefs['low_impact_mode'])
        self.new_style_cache = cast_bool(Prefs['new_style_cache'])
        self.pack_cache_dir = self.get_pack_cache_dir()
        self.advanced = self.get_advanced_config()

        os.environ["SZ_USER_AGENT"] = self.get_user_agent()

        self.setup_proxies()
        self.set_plugin_mode()
        self.set_plugin_lock()
        self.set_activity_modes()
        self.parse_rename_mode()

        self.subtitle_destination_folder = self.get_subtitle_destination_folder(
        )
        self.subtitle_formats = self.get_subtitle_formats()
        self.forced_only = cast_bool(Prefs["subtitles.only_foreign"])
        self.max_recent_items_per_library = int_or_default(
            Prefs["scheduler.max_recent_items_per_library"], 2000)
        self.sections = list(Plex["library"].sections())
        self.missing_permissions = []
        self.ignore_sz_files = cast_bool(Prefs["subtitles.ignore_fs"])
        self.ignore_paths = self.parse_ignore_paths()
        self.enabled_sections = self.check_enabled_sections()
        self.permissions_ok = self.check_permissions()
        self.notify_executable = self.check_notify_executable()
        self.remove_hi = cast_bool(Prefs['subtitles.remove_hi'])
        self.remove_tags = cast_bool(Prefs['subtitles.remove_tags'])
        self.fix_ocr = cast_bool(Prefs['subtitles.fix_ocr'])
        self.fix_common = cast_bool(Prefs['subtitles.fix_common'])
        self.reverse_rtl = cast_bool(Prefs['subtitles.reverse_rtl'])
        self.colors = Prefs['subtitles.colors'] if Prefs[
            'subtitles.colors'] != "don't change" else None
        self.chmod = self.check_chmod()
        self.exotic_ext = cast_bool(Prefs["subtitles.scan.exotic_ext"])
        self.treat_und_as_first = cast_bool(
            Prefs["subtitles.language.treat_und_as_first"])
        self.subtitle_sub_dir = self.get_subtitle_sub_dir()
        self.ext_match_strictness = self.determine_ext_sub_strictness()
        self.default_mods = self.get_default_mods()
        self.debug_mods = cast_bool(Prefs['log_debug_mods'])
        self.no_refresh = os.environ.get("SZ_NO_REFRESH", False)
        self.plex_transcoder = self.get_plex_transcoder()
        self.only_one = cast_bool(Prefs['subtitles.only_one'])
        self.embedded_auto_extract = cast_bool(
            Prefs["subtitles.embedded.autoextract"])
        self.ietf_as_alpha3 = cast_bool(
            Prefs["subtitles.language.ietf_normalize"])
        self.initialized = True
예제 #31
0
def find_subtitles(part):
    lang_sub_map = {}
    part_filename = helpers.unicodize(part.file)
    part_basename = os.path.splitext(os.path.basename(part_filename))[0]
    use_filesystem = helpers.cast_bool(Prefs["subtitles.save.filesystem"])
    paths = [os.path.dirname(part_filename)] if use_filesystem else []

    global_subtitle_folder = None

    global_folders = []

    if use_filesystem:
        # Check for local subtitles subdirectory
        sub_dir_base = paths[0]

        sub_dir_list = []

        if Prefs["subtitles.save.subFolder"] != "current folder":
            # got selected subfolder
            sub_dir_list.append(
                os.path.join(sub_dir_base, Prefs["subtitles.save.subFolder"]))

        sub_dir_custom = Prefs["subtitles.save.subFolder.Custom"].strip() \
            if Prefs["subtitles.save.subFolder.Custom"] else None

        if sub_dir_custom:
            # got custom subfolder
            sub_dir_custom = os.path.normpath(sub_dir_custom)
            if os.path.isdir(sub_dir_custom) and os.path.isabs(sub_dir_custom):
                # absolute folder
                sub_dir_list.append(sub_dir_custom)
                global_folders.append(sub_dir_custom)
            else:
                # relative folder
                fld = os.path.join(sub_dir_base, sub_dir_custom)
                sub_dir_list.append(fld)

        for sub_dir in sub_dir_list:
            if os.path.isdir(sub_dir):
                paths.append(sub_dir)

        # Check for a global subtitle location
        global_subtitle_folder = os.path.join(Core.app_support_path,
                                              'Subtitles')
        if os.path.exists(global_subtitle_folder):
            paths.append(global_subtitle_folder)
            global_folders.append(global_subtitle_folder)

    # normalize all paths
    paths = [
        os.path.normpath(os.path.realpath(helpers.unicodize(path)))
        for path in paths
    ]

    # We start by building a dictionary of files to their absolute paths. We also need to know
    # the number of media files that are actually present, in case the found local media asset
    # is limited to a single instance per media file.
    #
    file_paths = {}
    total_media_files = 0
    media_files = []
    for path in paths:
        for file_path_listing in os.listdir(path.encode(
                sz_config.fs_encoding)):
            # When using os.listdir with a unicode path, it will always return a string using the
            # NFD form. However, we internally are using the form NFC and therefore need to convert
            # it to allow correct regex / comparisons to be performed.
            #
            file_path_listing = helpers.unicodize(file_path_listing)
            if os.path.isfile(
                    os.path.join(path, file_path_listing).encode(
                        sz_config.fs_encoding)):
                file_paths[file_path_listing.lower()] = os.path.join(
                    path, file_path_listing)

            # If we've found an actual media file, we should record it.
            (root, ext) = os.path.splitext(file_path_listing)
            if ext.lower()[1:] in config.VIDEO_EXTS:
                total_media_files += 1

                # collect found media files
                media_files.append(root)

    # cleanup any leftover subtitle if no associated media file was found
    if helpers.cast_bool(Prefs["subtitles.autoclean"]):
        for path in paths:
            # we can't housekeep the global subtitle folders as we don't know about *all* media files
            # in a library; skip them
            skip_path = False
            for fld in global_folders:
                if path.startswith(fld):
                    Log.Info("Skipping housekeeping of folder: %s", path)
                    skip_path = True
                    break

            if skip_path:
                continue

            for file_path_listing in os.listdir(
                    path.encode(sz_config.fs_encoding)):
                file_path_listing = helpers.unicodize(file_path_listing)
                enc_fn = os.path.join(path, file_path_listing).encode(
                    sz_config.fs_encoding)

                if os.path.isfile(enc_fn):
                    (root, ext) = os.path.splitext(file_path_listing)
                    # it's a subtitle file
                    if ext.lower()[1:] in config.SUBTITLE_EXTS:
                        # get fn without forced/default/normal tag
                        split_tag = root.rsplit(".", 1)
                        if len(split_tag) > 1 and split_tag[1].lower() in [
                                'forced', 'normal', 'default'
                        ]:
                            root = split_tag[0]

                        # get associated media file name without language
                        sub_fn = subtitlehelpers.ENDSWITH_LANGUAGECODE_RE.sub(
                            "", root)

                        # subtitle basename and basename without possible language tag  not found in collected
                        # media files? kill.
                        if root not in media_files and sub_fn not in media_files:
                            Log.Info("Removing leftover subtitle: %s",
                                     os.path.join(path, file_path_listing))
                            try:
                                os.remove(enc_fn)
                            except (OSError, IOError):
                                Log.Error("Removing failed")

    Log('Looking for subtitle media in %d paths with %d media files.',
        len(paths), total_media_files)
    Log('Paths: %s', ", ".join([helpers.unicodize(p) for p in paths]))

    for file_path in file_paths.values():
        local_filename = os.path.basename(file_path)
        bn, ext = os.path.splitext(local_filename)
        local_basename = helpers.unicodize(bn)

        # get fn without forced/default/normal tag
        split_tag = local_basename.rsplit(".", 1)
        if len(split_tag) > 1 and split_tag[1].lower() in [
                'forced', 'normal', 'default'
        ]:
            local_basename = split_tag[0]

        # split off possible language tag
        local_basename2 = local_basename.rsplit('.', 1)[0]
        filename_matches_part = local_basename == part_basename or local_basename2 == part_basename
        filename_contains_part = part_basename in local_basename

        if not ext.lower()[1:] in config.SUBTITLE_EXTS:
            continue

        # if the file is located within the global subtitle folders and its name doesn't match exactly, ignore it
        if global_folders and not filename_matches_part:
            skip_path = False
            for fld in global_folders:
                if file_path.startswith(fld):
                    skip_path = True
                    break

            if skip_path:
                continue

        # determine whether to pick up the subtitle based on our match strictness
        elif not filename_matches_part:
            if sz_config.ext_match_strictness == "strict" or (
                    sz_config.ext_match_strictness == "loose"
                    and not filename_contains_part):

                Log.Debug("%s doesn't match %s, skipping" %
                          (helpers.unicodize(local_filename),
                           helpers.unicodize(part_basename)))
                continue

        subtitle_helper = subtitlehelpers.subtitle_helpers(file_path)
        if subtitle_helper is not None:
            local_lang_map = subtitle_helper.process_subtitles(part)
            for new_language, subtitles in local_lang_map.items():

                # Add the possible new language along with the located subtitles so that we can validate them
                # at the end...
                #
                if not lang_sub_map.has_key(new_language):
                    lang_sub_map[new_language] = []
                lang_sub_map[
                    new_language] = lang_sub_map[new_language] + subtitles

    # add known metadata subs to our sub list
    if not use_filesystem:
        for language, sub_list in subtitlehelpers.get_subtitles_from_metadata(
                part).iteritems():
            if sub_list:
                if language not in lang_sub_map:
                    lang_sub_map[language] = []
                lang_sub_map[language] = lang_sub_map[language] + sub_list

    # Now whack subtitles that don't exist anymore.
    for language in lang_sub_map.keys():
        part.subtitles[language].validate_keys(lang_sub_map[language])

    # Now whack the languages that don't exist anymore.
    for language in list(
            set(part.subtitles.keys()) - set(lang_sub_map.keys())):
        part.subtitles[language].validate_keys({})
예제 #32
0
    def initialize(self):
        self.libraries_root = os.path.abspath(os.path.join(get_root_path(), ".."))
        self.init_libraries()

        if is_windows_special_path:
            Log.Warn("The Plex metadata folder is residing inside a folder with special characters. "
                     "Multithreading and playback activities will be disabled.")

        self.fs_encoding = get_viable_encoding()
        self.plugin_info = self.get_plugin_info()
        self.is_development = self.get_dev_mode()
        self.version = self.get_version()
        self.full_version = u"%s %s" % (PLUGIN_NAME, self.version)
        self.set_log_paths()
        self.app_support_path = Core.app_support_path
        self.data_path = getattr(Data, "_core").storage.data_path
        self.data_items_path = os.path.join(self.data_path, "DataItems")
        self.universal_plex_token = self.get_universal_plex_token()
        self.plex_token = os.environ.get("PLEXTOKEN", self.universal_plex_token)
        self.new_style_cache = cast_bool(Prefs['new_style_cache'])
        self.pack_cache_dir = self.get_pack_cache_dir()
        try:
            self.migrate_prefs()
        except:
            Log.Exception("Catastrophic failure when running prefs migration")

        subzero.constants.DEFAULT_TIMEOUT = lib.DEFAULT_TIMEOUT = self.pms_request_timeout = \
            min(cast_int(Prefs['pms_request_timeout'], 15), 45)
        self.low_impact_mode = cast_bool(Prefs['low_impact_mode'])
        self.advanced = self.get_advanced_config()
        self.debug_i18n = self.advanced.debug_i18n

        os.environ["SZ_USER_AGENT"] = self.get_user_agent()
        os.environ["ANTICAPTCHA_ACCOUNT_KEY"] = self.anticaptcha_token = str(Prefs["anticaptcha.api_key"]) or ""
        acs = str(Prefs["anticaptcha.service"])
        if acs and acs != "none":
            os.environ["ANTICAPTCHA_CLASS"] = self.anticaptcha_cls = acs
        self.has_anticaptcha = self.anticaptcha_token and self.anticaptcha_cls

        self.setup_proxies()
        self.set_plugin_mode()
        self.set_plugin_lock()
        self.set_activity_modes()
        self.parse_rename_mode()

        self.normal_subs = Prefs["subtitles.when"] != "Never"
        self.forced_also = self.normal_subs and Prefs["subtitles.when_forced"] != "Never"
        self.forced_only = not self.normal_subs and Prefs["subtitles.when_forced"] != "Never"
        self.include = \
            Prefs["subtitles.include_exclude_mode"] == "disable SZ for all items by default, use include lists"
        self.subtitle_destination_folder = self.get_subtitle_destination_folder()
        self.subtitle_formats = self.get_subtitle_formats()
        self.max_recent_items_per_library = int_or_default(Prefs["scheduler.max_recent_items_per_library"], 2000)
        self.sections = list(Plex["library"].sections())
        self.missing_permissions = []
        self.include_exclude_sz_files = cast_bool(Prefs["subtitles.include_exclude_fs"])
        self.include_exclude_paths = self.parse_include_exclude_paths()
        self.enabled_sections = self.check_enabled_sections()
        self.permissions_ok = self.check_permissions()
        self.notify_executable = self.check_notify_executable()
        self.remove_hi = cast_bool(Prefs['subtitles.remove_hi'])
        self.remove_tags = cast_bool(Prefs['subtitles.remove_tags'])
        self.fix_ocr = cast_bool(Prefs['subtitles.fix_ocr'])
        self.fix_common = cast_bool(Prefs['subtitles.fix_common'])
        self.fix_upper = cast_bool(Prefs['subtitles.fix_only_uppercase'])
        self.reverse_rtl = cast_bool(Prefs['subtitles.reverse_rtl'])
        self.colors = Prefs['subtitles.colors'] if Prefs['subtitles.colors'] != "don't change" else None
        self.chmod = self.check_chmod()
        self.exotic_ext = cast_bool(Prefs["subtitles.scan.exotic_ext"])
        self.treat_und_as_first = cast_bool(Prefs["subtitles.language.treat_und_as_first"])
        self.subtitle_sub_dir = self.get_subtitle_sub_dir()
        self.ext_match_strictness = self.determine_ext_sub_strictness()
        self.default_mods = self.get_default_mods()
        self.debug_mods = cast_bool(Prefs['log_debug_mods'])
        self.no_refresh = os.environ.get("SZ_NO_REFRESH", False)
        self.plex_transcoder = self.get_plex_transcoder()
        self.only_one = cast_bool(Prefs['subtitles.only_one'])
        self.any_language_is_enough = Prefs['subtitles.any_language_is_enough']
        self.embedded_auto_extract = cast_bool(Prefs["subtitles.embedded.autoextract"])
        self.ietf_as_alpha3 = cast_bool(Prefs["subtitles.language.ietf_normalize"])
        self.use_custom_dns = self.parse_custom_dns()
        self.initialized = True
예제 #33
0
def find_subtitles(part, ignore_parts_cleanup=None):
    lang_sub_map = {}
    ignore_parts_cleanup = ignore_parts_cleanup or []
    part_filename = helpers.unicodize(part.file)
    part_basename = os.path.splitext(os.path.basename(part_filename))[0]
    use_filesystem = helpers.cast_bool(Prefs["subtitles.save.filesystem"])
    sub_dir_custom = Prefs["subtitles.save.subFolder.Custom"].strip() \
        if Prefs["subtitles.save.subFolder.Custom"] else None

    use_sub_subfolder = Prefs["subtitles.save.subFolder"] != "current folder" and not sub_dir_custom
    autoclean = helpers.cast_bool(Prefs["subtitles.autoclean"])
    sub_subfolder = None
    paths = [os.path.dirname(part_filename)] if use_filesystem else []

    global_folders = []

    if use_filesystem:
        # Check for local subtitles subdirectory
        sub_dir_base = paths[0]
        sub_dir_list = []

        if use_sub_subfolder:
            # got selected subfolder
            sub_subfolder = os.path.join(sub_dir_base, Prefs["subtitles.save.subFolder"])
            sub_dir_list.append(sub_subfolder)
            sub_subfolder = os.path.normpath(helpers.unicodize(sub_subfolder))

        if sub_dir_custom:
            # got custom subfolder
            sub_dir_custom = os.path.normpath(sub_dir_custom)
            if os.path.isdir(sub_dir_custom) and os.path.isabs(sub_dir_custom):
                # absolute folder
                sub_dir_list.append(sub_dir_custom)
                global_folders.append(sub_dir_custom)
            else:
                # relative folder
                fld = os.path.join(sub_dir_base, sub_dir_custom)
                sub_dir_list.append(fld)

        for sub_dir in sub_dir_list:
            if os.path.isdir(sub_dir):
                paths.append(sub_dir)

        # Check for a global subtitle location
        global_subtitle_folder = os.path.join(Core.app_support_path, 'Subtitles')
        if os.path.exists(global_subtitle_folder):
            paths.append(global_subtitle_folder)
            global_folders.append(global_subtitle_folder)

    # normalize all paths
    paths = [os.path.normpath(helpers.unicodize(path)) for path in paths]

    # We start by building a dictionary of files to their absolute paths. We also need to know
    # the number of media files that are actually present, in case the found local media asset
    # is limited to a single instance per media file.
    #
    file_paths = {}
    total_media_files = 0
    media_files = []
    for path in paths:
        for file_path_listing in os.listdir(path.encode(sz_config.fs_encoding)):
            # When using os.listdir with a unicode path, it will always return a string using the
            # NFD form. However, we internally are using the form NFC and therefore need to convert
            # it to allow correct regex / comparisons to be performed.
            #
            file_path_listing = helpers.unicodize(file_path_listing)
            if os.path.isfile(os.path.join(path, file_path_listing).encode(sz_config.fs_encoding)):
                file_paths[file_path_listing.lower()] = os.path.join(path, file_path_listing)

            # If we've found an actual media file, we should record it.
            (root, ext) = os.path.splitext(file_path_listing)
            if ext.lower()[1:] in config.VIDEO_EXTS:
                total_media_files += 1

                # collect found media files
                media_files.append(root)

    # cleanup any leftover subtitle if no associated media file was found
    if autoclean and ignore_parts_cleanup:
        Log.Info("Skipping housekeeping of: %s", paths)

    if use_filesystem and autoclean and not ignore_parts_cleanup:
        for path in paths:
            # only housekeep in sub_subfolder if sub_subfolder is used
            if use_sub_subfolder and path != sub_subfolder and not sz_config.advanced.thorough_cleaning:
                continue

            # we can't housekeep the global subtitle folders as we don't know about *all* media files
            # in a library; skip them
            skip_path = False
            for fld in global_folders:
                if path.startswith(fld):
                    Log.Info("Skipping housekeeping of folder: %s", path)
                    skip_path = True
                    break

            if skip_path:
                continue

            for file_path_listing in os.listdir(path.encode(sz_config.fs_encoding)):
                file_path_listing = helpers.unicodize(file_path_listing)
                enc_fn = os.path.join(path, file_path_listing).encode(sz_config.fs_encoding)

                if os.path.isfile(enc_fn):
                    (root, ext) = os.path.splitext(file_path_listing)
                    # it's a subtitle file
                    if ext.lower()[1:] in config.SUBTITLE_EXTS_BASE:
                        # get fn without forced/default/normal tag
                        split_tag = root.rsplit(".", 1)
                        if len(split_tag) > 1 and split_tag[1].lower() in SECONDARY_TAGS:
                            root = split_tag[0]

                        # get associated media file name without language
                        sub_fn = subtitlehelpers.ENDSWITH_LANGUAGECODE_RE.sub("", root)

                        # subtitle basename and basename without possible language tag  not found in collected
                        # media files? kill.
                        if root not in media_files and sub_fn not in media_files:
                            Log.Info("Removing leftover subtitle: %s", os.path.join(path, file_path_listing))
                            try:
                                os.remove(enc_fn)
                            except (OSError, IOError):
                                Log.Error("Removing failed")

    Log('Looking for subtitle media in %d paths with %d media files.', len(paths), total_media_files)
    Log('Paths: %s', ", ".join([helpers.unicodize(p) for p in paths]))

    for file_path in file_paths.values():
        local_filename = os.path.basename(file_path)
        bn, ext = os.path.splitext(local_filename)
        local_basename = helpers.unicodize(bn)

        # get fn without forced/default/normal tag
        split_tag = local_basename.rsplit(".", 1)
        has_additional_tag = False
        if len(split_tag) > 1 and split_tag[1].lower() in SECONDARY_TAGS:
            local_basename = split_tag[0]
            has_additional_tag = True

        # split off possible language tag
        local_basename2 = local_basename.rsplit('.', 1)[0]
        filename_matches_part = local_basename == part_basename or local_basename2 == part_basename
        filename_contains_part = part_basename in local_basename

        if not ext.lower()[1:] in config.SUBTITLE_EXTS:
            continue

        # if the file is located within the global subtitle folders and its name doesn't match exactly, ignore it
        if global_folders and not filename_matches_part:
            skip_path = False
            for fld in global_folders:
                if file_path.startswith(fld):
                    skip_path = True
                    break

            if skip_path:
                continue

        # determine whether to pick up the subtitle based on our match strictness
        if not filename_matches_part:
            if sz_config.ext_match_strictness == "strict" or (
                            sz_config.ext_match_strictness == "loose" and not filename_contains_part):
                # Log.Debug("%s doesn't match %s, skipping" % (helpers.unicodize(local_filename),
                #                                             helpers.unicodize(part_basename)))
                continue

        subtitle_helper = subtitlehelpers.subtitle_helpers(file_path)
        if subtitle_helper is not None:
            local_lang_map = subtitle_helper.process_subtitles(part)
            for new_language, subtitles in local_lang_map.items():

                # Add the possible new language along with the located subtitles so that we can validate them
                # at the end...
                #
                if not lang_sub_map.has_key(new_language):
                    lang_sub_map[new_language] = []
                lang_sub_map[new_language] = lang_sub_map[new_language] + subtitles

    # add known metadata subs to our sub list
    if not use_filesystem:
        for language, sub_list in subtitlehelpers.get_subtitles_from_metadata(part).iteritems():
            if sub_list:
                if language not in lang_sub_map:
                    lang_sub_map[language] = []
                lang_sub_map[language] = lang_sub_map[language] + sub_list

    # Now whack subtitles that don't exist anymore.
    for language in lang_sub_map.keys():
        part.subtitles[language].validate_keys(lang_sub_map[language])

    # Now whack the languages that don't exist anymore.
    for language in list(set(part.subtitles.keys()) - set(lang_sub_map.keys())):
        part.subtitles[language].validate_keys({})
예제 #34
0
 def providers_by_prefs(self):
     return {'opensubtitles': cast_bool(Prefs['provider.opensubtitles.enabled']),
                  # 'thesubdb': Prefs['provider.thesubdb.enabled'],
                  'podnapisi': cast_bool(Prefs['provider.podnapisi.enabled']),
                  'titlovi': cast_bool(Prefs['provider.titlovi.enabled']),
                  'addic7ed': cast_bool(Prefs['provider.addic7ed.enabled']) and self.has_anticaptcha,
                  'tvsubtitles': cast_bool(Prefs['provider.tvsubtitles.enabled']),
                  'legendastv': cast_bool(Prefs['provider.legendastv.enabled']),
                  'napiprojekt': cast_bool(Prefs['provider.napiprojekt.enabled']),
                  'hosszupuska': cast_bool(Prefs['provider.hosszupuska.enabled']),
                  'supersubtitles': cast_bool(Prefs['provider.supersubtitles.enabled']),
                  'shooter': False,
                  'subscene': cast_bool(Prefs['provider.subscene.enabled']),
                  'argenteam': cast_bool(Prefs['provider.argenteam.enabled']),
                  'subscenter': False,
                  'assrt': cast_bool(Prefs['provider.assrt.enabled']),
                  }
예제 #35
0
    def process_subtitles(self, part):

        lang_sub_map = {}

        if not os.path.exists(self.filename):
            return lang_sub_map

        basename = os.path.basename(self.filename)
        (file, ext) = os.path.splitext(self.filename)

        # Remove the initial '.' from the extension
        ext = ext[1:]

        forced = ''
        default = ''
        split_tag = file.rsplit('.', 1)
        if len(split_tag) > 1 and split_tag[1].lower() in ['forced', 'normal', 'default', 'embedded', 'custom']:
            file = split_tag[0]
            # don't do anything with 'normal', we don't need it
            if 'forced' == split_tag[1].lower():
                forced = '1'
            if 'default' == split_tag[1].lower():
                default = '1'

        # Attempt to extract the language from the filename (e.g. Avatar (2009).eng)
        # IETF support thanks to
        # https://github.com/hpsbranco/LocalMedia.bundle/commit/4fad9aefedece78a1fa96401304351347f644369
        language = Locale.Language.Match(match_ietf_language(file))

        # skip non-SRT if wanted
        if not helpers.cast_bool(Prefs["subtitles.scan.exotic_ext"]) and ext not in ["srt", "ass", "ssa", "vtt"]:
            return lang_sub_map

        codec = None
        format = None
        if ext in ['txt', 'sub']:
            try:

                file_contents = Core.storage.load(self.filename)
                lines = [line.strip() for line in file_contents.splitlines(True)]
                if re.match('^\{[0-9]+\}\{[0-9]*\}', lines[1]):
                    format = 'microdvd'
                elif re.match('^[0-9]{1,2}:[0-9]{2}:[0-9]{2}[:=,]', lines[1]):
                    format = 'txt'
                elif '[SUBTITLE]' in lines[1]:
                    format = 'subviewer'
                else:
                    Log("The subtitle file does not have a known format, skipping... : " + self.filename)
                    return lang_sub_map
            except:
                Log("An error occurred while attempting to parse the subtitle file, skipping... : " + self.filename)
                return lang_sub_map

        if codec is None and ext in ['ass', 'ssa', 'smi', 'srt', 'psb', 'vtt']:
            codec = ext.replace('ass', 'ssa')

        if format is None:
            format = codec

        Log('Found subtitle file: ' + self.filename + ' language: ' + language + ' codec: ' + str(
            codec) + ' format: ' + str(format) + ' default: ' + default + ' forced: ' + forced)
        part.subtitles[language][basename] = Proxy.LocalFile(self.filename, codec=codec, format=format, default=default,
                                                             forced=forced)

        lang_sub_map[language] = [basename]
        return lang_sub_map
예제 #36
0
 def provider_pool(self):
     if cast_bool(Prefs['providers.multithreading']):
         return subliminal_patch.core.SZAsyncProviderPool
     return subliminal_patch.core.SZProviderPool