Source code for flexget.plugins.filter.unique
from loguru import logger
from flexget import plugin
from flexget.config_schema import one_or_more
from flexget.event import event
logger = logger.bind(name='unique')
[docs]
class Unique:
"""Take action on entries with duplicate fields, except for the first item.
Reject the second+ instance of every movie::
unique:
field:
- imdb_id
- movie_name
action: reject
"""
schema = {
'type': 'object',
'properties': {
'field': one_or_more({'type': 'string'}),
'action': {'enum': ['accept', 'reject']},
},
'required': ['field'],
'additionalProperties': False,
}
[docs]
def prepare_config(self, config):
if isinstance(config, bool) or config is None:
config = {}
config.setdefault('action', 'reject')
if not isinstance(config['field'], list):
config['field'] = [config['field']]
return config
[docs]
def should_ignore(self, item, action):
return (item.accepted and action == 'accept') or (item.rejected and action == 'reject')
[docs]
def on_task_filter(self, task, config):
config = self.prepare_config(config)
field_names = config['field']
entries = list(task.entries)
for i, entry in enumerate(entries):
# Ignore already processed entries
if self.should_ignore(entry, config['action']):
continue
try:
entry_fields = self.extract_fields(entry, field_names)
# Ignore if a field is missing
except KeyError:
continue
# Iterate over next items, try to find a similar item
for prospect in entries[i + 1 :]:
# Ignore processed prospects
if self.should_ignore(prospect, config['action']):
continue
try:
prospect_fields = self.extract_fields(prospect, field_names)
# Ignore if a field is missing
except KeyError:
continue
if entry_fields and entry_fields == prospect_fields:
msg = 'Field {} value {} equals on {} and {}'.format(
field_names, entry_fields, entry['title'], prospect['title']
)
# Mark prospect
if config['action'] == 'accept':
prospect.accept(msg)
else:
prospect.reject(msg)
[docs]
@event('plugin.register')
def register_plugin():
plugin.register(Unique, 'unique', api_ver=2)