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):
12
Intelligent series aware exists rejecting.
16
exists_series: /storage/series/
20
from flexget import validator
21
root = validator.factory()
23
bundle = root.accept('list')
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')
31
def get_config(self, feed):
32
config = feed.config.get('exists_series', [])
33
# if config is not a dict, assign value to 'path' key
34
if not isinstance(config, dict):
35
config = {'path': config}
36
# if only a single path is passed turn it into a 1 element list
37
if isinstance(config['path'], basestring):
38
config['path'] = [config['path']]
42
def on_feed_filter(self, feed):
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)
49
log.debug('entry %s series_parser invalid' % entry['title'])
50
if not accepted_series:
52
log.warning('No accepted entries have series information. exists_series cannot filter them')
54
log.debug('Scanning not needed')
57
config = self.get_config(feed)
58
for path in config.get('path'):
59
feed.verbose_progress('Scanning %s' % path, log)
60
# crashes on some paths with unicode
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):
66
# convert filelists into utf-8 to avoid unicode problems
67
dirs = [x.decode('utf-8', 'ignore') for x in dirs]
68
files = [x.decode('utf-8', 'ignore') for x in files]
69
# For speed, only test accepted entries since our priority should be after everything is accepted.
70
for series in accepted_series:
71
# make new parser from parser in entry
72
disk_parser = copy.copy(accepted_series[series][0]['series_parser'])
73
for name in files + dirs:
74
# run parser on filename data
75
disk_parser.data = name
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)
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')
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')
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')
101
if entry['series_parser'].proper and not disk_parser.proper:
102
log.debugall('new one is proper, disk is not')
105
feed.reject(entry, 'episode already exists')
107
register_plugin(FilterExistsSeries, 'exists_series', groups=['exists'])