# Buggy code
def run(self, force=False):  # pylint: disable=too-many-branches, too-many-statements, too-many-locals
    """Checks for needed subtitles for users' shows

    :param force: True if a force search needs to be executed
    :type force: bool
    """
    if not sickbeard.USE_SUBTITLES:
        return

    if not sickbeard.subtitles.enabled_service_list():
        logger.warning(
            "Not enough services selected. At least 1 service is required to search subtitles in the "
            "background"
        )
        return

    self.amActive = True

    def dhm(td):
        days = td.days
        hours = td.seconds // 60**2
        minutes = (td.seconds // 60) % 60
        ret = (
            ("", "{} days, ".format(days))[days > 0]
            + ("", "{} hours, ".format(hours))[hours > 0]
            + ("", "{} minutes".format(minutes))[minutes > 0]
        )
        if days == 1:
            ret = ret.replace("days", "day")
        if hours == 1:
            ret = ret.replace("hours", "hour")
        if minutes == 1:
            ret = ret.replace("minutes", "minute")
        return ret.rstrip(", ")

    if sickbeard.SUBTITLES_DOWNLOAD_IN_PP:
        self.subtitles_download_in_pp()

    logger.info("Checking for missed subtitles")

    database = db.DBConnection()
    # Shows with air date <= 30 days, have a limit of 100 results
    # Shows with air date > 30 days, have a limit of 200 results
    sql_args = [
        {"age_comparison": "<=", "limit": 100},
        {"age_comparison": ">", "limit": 200},
    ]
    sql_like_languages = (
        "%" + ",".join(sorted(wanted_languages())) + "%"
        if sickbeard.SUBTITLES_MULTI
        else "%und%"
    )
    sql_results = []
    for args in sql_args:
        sql_results += database.select(
            "SELECT "
            "   s.show_name, "
            "   e.showid, "
            "   e.season, "
            "   e.episode,"
            "   e.release_name, "
            "   e.status, "
            "   e.subtitles, "
            "   e.subtitles_searchcount AS searchcount, "
            "   e.subtitles_lastsearch AS lastsearch, "
            "   e.location, (? - e.airdate) as age "
            "FROM "
            "   tv_episodes AS e "
            "INNER JOIN "
            "   tv_shows AS s "
            "ON (e.showid = s.indexer_id) "
            "WHERE"
            "   s.subtitles = 1 "
            "   AND (e.status LIKE '%4' OR e.status LIKE '%6') "
            "   AND e.season > 0 "
            "   AND e.location != '' "
            "   AND age {} 30 "
            "   AND e.subtitles NOT LIKE ? "
            "ORDER BY "
            "   lastsearch ASC "
            "LIMIT {}".format(args["age_comparison"], args["limit"]),
            [datetime.datetime.now().toordinal(), sql_like_languages],
        )

    if not sql_results:
        logger.info("No subtitles to download")
        self.amActive = False
        return

    for ep_to_sub in sql_results:
        ep_num = episode_num(ep_to_sub["season"], ep_to_sub["episode"]) or episode_num(
            ep_to_sub["season"], ep_to_sub["episode"], numbering="absolute"
        )
        subtitle_path = encode(
            ep_to_sub["location"], encoding=sickbeard.SYS_ENCODING, fallback="utf-8"
        )
        if not os.path.isfile(subtitle_path):
            logger.debug(
                "Episode file does not exist, cannot download subtitles for %s %s",
                ep_to_sub["show_name"],
                ep_num,
            )
            continue

        if not needs_subtitles(ep_to_sub["subtitles"]):
            logger.debug(
                "Episode already has all needed subtitles, skipping %s %s",
                ep_to_sub["show_name"],
                ep_num,
            )
            continue

        try:
            lastsearched = datetime.datetime.strptime(
                ep_to_sub["lastsearch"], dateTimeFormat
            )
        except ValueError:
            lastsearched = datetime.datetime.min

        try:
            if not force:
                now = datetime.datetime.now()
                days = int(ep_to_sub["age"])
                delay_time = datetime.timedelta(
                    hours=1 if days <= 10 else 8 if days <= 30 else 30 * 24
                )
                delay = lastsearched + delay_time - now

                # Search every hour until 10 days pass
                # After 10 days, search every 8 hours, after 30 days search once a month
                # Will always try an episode regardless of age for 3 times
                # The time resolution is minute
                # Only delay is the it's bigger than one minute and avoid wrongly skipping the search slot.
                if delay.total_seconds() > 60 and int(ep_to_sub["searchcount"]) > 2:
                    logger.debug(
                        "Subtitle search for %s %s delayed for %s",
                        ep_to_sub["show_name"],
                        ep_num,
                        dhm(delay),
                    )
                    continue

            show_object = Show.find(sickbeard.showList, int(ep_to_sub["showid"]))
            if not show_object:
                logger.debug(
                    "Show with ID %s not found in the database", ep_to_sub["showid"]
                )
                continue

            episode_object = show_object.getEpisode(
                ep_to_sub["season"], ep_to_sub["episode"]
            )
            if isinstance(episode_object, str):
                logger.debug(
                    "%s %s not found in the database", ep_to_sub["show_name"], ep_num
                )
                continue

            try:
                episode_object.download_subtitles()
            except Exception as error:
                logger.error(
                    "Unable to find subtitles for %s %s. Error: %s",
                    ep_to_sub["show_name"],
                    ep_num,
                    ex(error),
                )
                continue

        except Exception as error:
            logger.warning(
                "Error while searching subtitles for %s %s. Error: %s",
                ep_to_sub["show_name"],
                ep_num,
                ex(error),
            )
            continue

    logger.info("Finished checking for missed subtitles")
    self.amActive = False


# Traceback (UnicodeEncodeError)
FINDSUBTITLES :: [d47493d] Traceback (most recent call last):
File "/home/home/SickRage/sickbeard/subtitles.py", line 338, in download_best_subs
save_subtitles(video, found_subtitles, directory=subtitles_dir, single=not sickbeard.SUBTITLES_MULTI)
File "/home/home/SickRage/lib/subliminal/core.py", line 695, in save_subtitles
with io.open(subtitle_path, 'wb') as f:
UnicodeEncodeError: 'ascii' codec can't encode character u'\xea' in position 93: ordinal not in range(128)
Traceback (most recent call last):
File "/home/home/SickRage/sickbeard/subtitles.py", line 338, in download_best_subs
save_subtitles(video, found_subtitles, directory=subtitles_dir, single=not sickbeard.SUBTITLES_MULTI)
File "/home/home/SickRage/lib/subliminal/core.py", line 695, in save_subtitles
with io.open(subtitle_path, 'wb') as f:
UnicodeEncodeError: 'ascii' codec can't encode character u'\xea' in position 93: ordinal not in range(128)

# Fixed code
def run(self, force=False):  # pylint: disable=too-many-branches, too-many-statements, too-many-locals
    """Check for needed subtitles for users' shows.

    :param force: True if a force search needs to be executed
    :type force: bool
    """
    if not sickbeard.USE_SUBTITLES:
        return

    if not sickbeard.subtitles.enabled_service_list():
        logger.warning(
            "Not enough services selected. At least 1 service is required to search subtitles in the "
            "background"
        )
        return

    self.amActive = True

    def dhm(td):
        days = td.days
        hours = td.seconds // 60**2
        minutes = (td.seconds // 60) % 60
        ret = (
            ("", "{} days, ".format(days))[days > 0]
            + ("", "{} hours, ".format(hours))[hours > 0]
            + ("", "{} minutes".format(minutes))[minutes > 0]
        )
        if days == 1:
            ret = ret.replace("days", "day")
        if hours == 1:
            ret = ret.replace("hours", "hour")
        if minutes == 1:
            ret = ret.replace("minutes", "minute")
        return ret.rstrip(", ")

    if sickbeard.SUBTITLES_DOWNLOAD_IN_PP:
        self.subtitles_download_in_pp()

    logger.info("Checking for missed subtitles")

    database = db.DBConnection()
    # Shows with air date <= 30 days, have a limit of 100 results
    # Shows with air date > 30 days, have a limit of 200 results
    sql_args = [
        {"age_comparison": "<=", "limit": 100},
        {"age_comparison": ">", "limit": 200},
    ]
    sql_like_languages = (
        "%" + ",".join(sorted(wanted_languages())) + "%"
        if sickbeard.SUBTITLES_MULTI
        else "%und%"
    )
    sql_results = []
    for args in sql_args:
        sql_results += database.select(
            "SELECT "
            "   s.show_name, "
            "   e.showid, "
            "   e.season, "
            "   e.episode,"
            "   e.release_name, "
            "   e.status, "
            "   e.subtitles, "
            "   e.subtitles_searchcount AS searchcount, "
            "   e.subtitles_lastsearch AS lastsearch, "
            "   e.location, (? - e.airdate) as age "
            "FROM "
            "   tv_episodes AS e "
            "INNER JOIN "
            "   tv_shows AS s "
            "ON (e.showid = s.indexer_id) "
            "WHERE"
            "   s.subtitles = 1 "
            "   AND (e.status LIKE '%4' OR e.status LIKE '%6') "
            "   AND e.season > 0 "
            "   AND e.location != '' "
            "   AND age {} 30 "
            "   AND e.subtitles NOT LIKE ? "
            "ORDER BY "
            "   lastsearch ASC "
            "LIMIT {}".format(args["age_comparison"], args["limit"]),
            [datetime.datetime.now().toordinal(), sql_like_languages],
        )

    if not sql_results:
        logger.info("No subtitles to download")
        self.amActive = False
        return

    for ep_to_sub in sql_results:
        ep_num = episode_num(ep_to_sub["season"], ep_to_sub["episode"]) or episode_num(
            ep_to_sub["season"], ep_to_sub["episode"], numbering="absolute"
        )
        subtitle_path = _encode(
            ep_to_sub["location"], encoding=sickbeard.SYS_ENCODING, fallback="utf-8"
        )
        if not os.path.isfile(subtitle_path):
            logger.debug(
                "Episode file does not exist, cannot download subtitles for %s %s",
                ep_to_sub["show_name"],
                ep_num,
            )
            continue

        if not needs_subtitles(ep_to_sub["subtitles"]):
            logger.debug(
                "Episode already has all needed subtitles, skipping %s %s",
                ep_to_sub["show_name"],
                ep_num,
            )
            continue

        try:
            lastsearched = datetime.datetime.strptime(
                ep_to_sub["lastsearch"], dateTimeFormat
            )
        except ValueError:
            lastsearched = datetime.datetime.min

        try:
            if not force:
                now = datetime.datetime.now()
                days = int(ep_to_sub["age"])
                delay_time = datetime.timedelta(
                    hours=1 if days <= 10 else 8 if days <= 30 else 30 * 24
                )
                delay = lastsearched + delay_time - now

                # Search every hour until 10 days pass
                # After 10 days, search every 8 hours, after 30 days search once a month
                # Will always try an episode regardless of age for 3 times
                # The time resolution is minute
                # Only delay is the it's bigger than one minute and avoid wrongly skipping the search slot.
                if delay.total_seconds() > 60 and int(ep_to_sub["searchcount"]) > 2:
                    logger.debug(
                        "Subtitle search for %s %s delayed for %s",
                        ep_to_sub["show_name"],
                        ep_num,
                        dhm(delay),
                    )
                    continue

            show_object = Show.find(sickbeard.showList, int(ep_to_sub["showid"]))
            if not show_object:
                logger.debug(
                    "Show with ID %s not found in the database", ep_to_sub["showid"]
                )
                continue

            episode_object = show_object.getEpisode(
                ep_to_sub["season"], ep_to_sub["episode"]
            )
            if isinstance(episode_object, str):
                logger.debug(
                    "%s %s not found in the database", ep_to_sub["show_name"], ep_num
                )
                continue

            try:
                episode_object.download_subtitles()
            except Exception as error:
                logger.error(
                    "Unable to find subtitles for %s %s. Error: %s",
                    ep_to_sub["show_name"],
                    ep_num,
                    ex(error),
                )
                continue

        except Exception as error:
            logger.warning(
                "Error while searching subtitles for %s %s. Error: %s",
                ep_to_sub["show_name"],
                ep_num,
                ex(error),
            )
            continue

    logger.info("Finished checking for missed subtitles")
    self.amActive = False