flexget.plugins.filter_exists_series
Covered: 84 lines
Missed: 3 lines
Skipped 21 lines
Percent: 96 %
  1
import copy
  2
import os
  3
import logging
  4
from flexget.plugin import register_plugin, priority, PluginWarning
  5
from flexget.utils.titles import SeriesParser, ParseWarning
  7
log = logging.getLogger('exists_series')
 10
class FilterExistsSeries(object):
 11
    """
 12
        Intelligent series aware exists rejecting.
 14
        Example:
 16
        exists_series: /storage/series/
 17
    """
 19
    def validator(self):
 20
        from flexget import validator
 21
        root = validator.factory()
 22
        root.accept('path')
 23
        bundle = root.accept('list')
 24
        bundle.accept('path')
 25
        advform = root.accept('dict')
 26
        advform.accept('boolean', key='allow_different_qualities')
 27
        advform.accept('path', key='path')
 28
        advform.accept('list', key='path').accept('path')
 29
        return root
 31
    def get_config(self, feed):
 32
        config = feed.config.get('exists_series', [])
 34
        if not isinstance(config, dict):
 35
            config = {'path': config}
 37
        if isinstance(config['path'], basestring):
 38
            config['path'] = [config['path']]
 39
        return config
 41
    @priority(-1)
 42
    def on_feed_filter(self, feed):
 43
        accepted_series = {}
 44
        for entry in feed.accepted:
 45
            if 'series_parser' in entry:
 46
                if entry['series_parser'].valid:
 47
                    accepted_series.setdefault(entry['series_parser'].name, []).append(entry)
 48
                else:
 49
                    log.debug('entry %s series_parser invalid' % entry['title'])
 50
        if not accepted_series:
 51
            if feed.accepted:
 52
                log.warning('No accepted entries have series information. exists_series cannot filter them')
 53
            else:
 54
                log.debug('Scanning not needed')
 55
            return
 57
        config = self.get_config(feed)
 58
        for path in config.get('path'):
 59
            feed.verbose_progress('Scanning %s' % path, log)
 61
            path = str(os.path.expanduser(path))
 62
            if not os.path.exists(path):
 63
                raise PluginWarning('Path %s does not exist' % path, log)
 65
            for root, dirs, files in os.walk(path):
 67
                dirs = [x.decode('utf-8', 'ignore') for x in dirs]
 68
                files = [x.decode('utf-8', 'ignore') for x in files]
 70
                for series in accepted_series:
 72
                    disk_parser = copy.copy(accepted_series[series][0]['series_parser'])
 73
                    for name in files + dirs:
 75
                        disk_parser.data = name
 76
                        try:
 77
                            disk_parser.parse(data=name)
 78
                        except ParseWarning, pw:
 79
                            from flexget.utils.log import log_once
 80
                            log_once(pw.value, logger=log)
 81
                        if disk_parser.valid:
 82
                            log.debug('name %s is same series as %s' % (name, series))
 83
                            log.debug('disk_parser.identifier = %s' % disk_parser.identifier)
 84
                            log.debug('disk_parser.quality = %s' % disk_parser.quality)
 85
                            log.debug('disk_parser.proper = %s' % disk_parser.proper)
 87
                            for entry in accepted_series[series]:
 88
                                log.debug('series_parser.identifier = %s' % entry['series_parser'].identifier)
 89
                                if disk_parser.identifier != entry['series_parser'].identifier:
 90
                                    log.debugall('wrong identifier')
 91
                                    continue
 92
                                log.debug('series_parser.quality = %s' % entry['series_parser'].quality)
 93
                                if config.get('allow_different_qualities') and \
 94
                                   disk_parser.quality != entry['series_parser'].quality:
 95
                                    log.debugall('wrong quality')
 96
                                    continue
 97
                                log.debug('entry parser.proper = %s' % entry['series_parser'].proper)
 98
                                if disk_parser.proper and not entry['series_parser'].proper:
 99
                                    feed.reject(entry, 'proper already exists')
100
                                    continue
101
                                if entry['series_parser'].proper and not disk_parser.proper:
102
                                    log.debugall('new one is proper, disk is not')
103
                                    continue
105
                                feed.reject(entry, 'episode already exists')
107
register_plugin(FilterExistsSeries, 'exists_series', groups=['exists'])