'Walk providers for propers'

def _getProperList(self):

    propers = {}
    search_date = (datetime.datetime.today() - datetime.timedelta(days=2))
    origThreadName = threading.currentThread().name
    providers = [x for x in sickbeard.providers.sortedProviderList(sickbeard.RANDOMIZE_PROVIDERS) if x.is_active()]
    for curProvider in providers:
        threading.currentThread().name = (((origThreadName + u'    ::    [') + curProvider.name) + u']')
        logger.log((u'Searching    for    any    new    PROPER    releases    from    ' + curProvider.name))
        try:
            curPropers = curProvider.find_propers(search_date)
        except AuthException as e:
            logger.log((u'Authentication    error:    ' + ex(e)), logger.WARNING)
            continue
        except Exception as e:
            logger.log((((u'Exception    while    searching    propers    in    ' + curProvider.name) + u',    skipping:    ') + ex(e)), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            continue
        for x in curPropers:
            if (not re.search(u'\\b(proper|repack|real)\\b', x.name, re.I)):
                logger.log(u'find_propers    returned    a    non-proper,    we    have    caught    and    skipped    it.', logger.DEBUG)
                continue
            name = self._genericName(x.name)
            if (name not in propers):
                logger.log((u'Found    new    proper:    ' + x.name), logger.DEBUG)
                x.provider = curProvider
                propers[name] = x
        threading.currentThread().name = origThreadName
    sortedPropers = sorted(propers.values(), key=operator.attrgetter(u'date'), reverse=True)
    finalPropers = []
    for curProper in sortedPropers:
        try:
            parse_result = NameParser(False).parse(curProper.name)
        except (InvalidNameException, InvalidShowException) as error:
            logger.log(u'{0}'.format(error), logger.DEBUG)
            continue
        if (not parse_result.series_name):
            continue
        if (not parse_result.episode_numbers):
            logger.log(((u'Ignoring    ' + curProper.name) + u"    because    it's    for    a    full    season    rather    than    specific    episode"), logger.DEBUG)
            continue
        logger.log((((u'Successful    match!    Result    ' + parse_result.original_name) + u'    matched    to    show    ') + parse_result.show.name), logger.DEBUG)
        curProper.indexerid = parse_result.show.indexerid
        curProper.indexer = parse_result.show.indexer
        curProper.show = parse_result.show
        curProper.season = (parse_result.season_number if (parse_result.season_number is not None) else 1)
        curProper.episode = parse_result.episode_numbers[0]
        curProper.release_group = parse_result.release_group
        curProper.version = parse_result.version
        curProper.quality = Quality.nameQuality(curProper.name, parse_result.is_anime)
        curProper.content = None
        bestResult = pickBestResult(curProper, parse_result.show)
        if (not bestResult):
            logger.log(((u'Proper    ' + curProper.name) + u'    were    rejected    by    our    release    filters.'), logger.DEBUG)
            continue
        if (bestResult.show.is_anime and (not bestResult.release_group) and (bestResult.version == (-1))):
            logger.log(((u'Proper    ' + bestResult.name) + u"    doesn't    have    a    release    group    and    version,    ignoring    it"), logger.DEBUG)
            continue
        main_db_con = db.DBConnection()
        sql_results = main_db_con.select(u'SELECT    status    FROM    tv_episodes    WHERE    showid    =    ?    AND    season    =    ?    AND    episode    =    ?', [bestResult.indexerid, bestResult.season, bestResult.episode])
        if (not sql_results):
            continue
        (oldStatus, oldQuality) = Quality.splitCompositeStatus(int(sql_results[0]['status']))
        if ((oldStatus not in (DOWNLOADED, SNATCHED)) or (oldQuality != bestResult.quality)):
            continue
        if bestResult.show.is_anime:
            main_db_con = db.DBConnection()
            sql_results = main_db_con.select(u'SELECT    release_group,    version    FROM    tv_episodes    WHERE    showid    =    ?    AND    season    =    ?    AND    episode    =    ?', [bestResult.indexerid, bestResult.season, bestResult.episode])
            oldVersion = int(sql_results[0]['version'])
            oldRelease_group = sql_results[0]['release_group']
            if ((-1) < oldVersion < bestResult.version):
                logger.log((((u'Found    new    anime    v' + str(bestResult.version)) + u'    to    replace    existing    v') + str(oldVersion)))
            else:
                continue
            if (oldRelease_group != bestResult.release_group):
                logger.log((((u'Skipping    proper    from    release    group:    ' + bestResult.release_group) + u',    does    not    match    existing    release    group:    ') + oldRelease_group))
                continue
        if ((bestResult.indexerid != (-1)) and ((bestResult.indexerid, bestResult.season, bestResult.episode) not in {(p.indexerid, p.season, p.episode) for p in finalPropers})):
            logger.log((u'Found    a    proper    that    we    need:    ' + str(bestResult.name)))
            finalPropers.append(bestResult)
    return finalPropers
