Summary
Problem: FlexGet's discover builds search queries in the INPUT phase and hands each
query entry to the search plugin (e.g. search_rss). search_rss substitutes
only {{search_term}} into the URL, and that term comes from
entry['search_strings'] (falling back to entry['title']).
Gap: The stock movie_list input emits imdb_id but NOT search_strings, and the
set: plugin runs in the METAINFO phase — too late for discover. So there is no
config-only way to search Prowlarr/Torznab by imdbid= from a movie_list.
A potential plugin closes that gap: it could wrap any input plugin (typically movie_list),
runs it during the input phase, and sets search_strings = [imdb_id] on each
produced entry. Discover then receives query entries whose {{search_term}} is
the IMDb id, so ...&t=movie&imdbid={{search_term}} renders to
...&imdbid=tt6857112.
Something like this (what I use as a custom plugin to overcome this gap)
from loguru import logger
from flexget import plugin
from flexget.event import event
logger = logger.bind(name='imdb_search_input')
RESERVED = ('field', 'require')
class ImdbSearchInput:
# Permissive schema: one wrapped-input mapping plus optional field/require.
# additionalProperties allows the wrapped input key (e.g. movie_list).
schema = {
'type': 'object',
'properties': {
'field': {'type': 'string'},
'require': {'type': 'boolean'},
},
'additionalProperties': True,
}
def _resolve(self, config):
"""Return (input_name, input_config, field, require)."""
field = config.get('field', 'imdb_id')
require = config.get('require', True)
items = {k: v for k, v in config.items() if k not in RESERVED}
if len(items) != 1:
raise plugin.PluginError(
'imdb_search_input: expected exactly one wrapped input plugin '
f'(plus optional {RESERVED}), got keys: {list(config.keys())}'
)
input_name, input_config = next(iter(items.items()))
return input_name, input_config, field, require
def on_task_input(self, task, config):
input_name, input_config, field, require = self._resolve(config)
try:
wrapped = plugin.get_plugin_by_name(input_name)
except plugin.DependencyError:
raise plugin.PluginError(
f'imdb_search_input: unknown input plugin "{input_name}"'
)
input_handler = wrapped.phase_handlers.get('input')
if input_handler is None:
raise plugin.PluginError(
f'imdb_search_input: plugin "{input_name}" is not an input plugin'
)
produced = input_handler(task, input_config) or []
out = []
missing = 0
for entry in produced:
value = entry.get(field)
if not value:
missing += 1
if require:
logger.debug(
'Dropping "{}" — no {} to search by', entry.get('title'), field
)
continue
out.append(entry) # keep; search_rss falls back to title
continue
entry['search_strings'] = [str(value)]
out.append(entry)
if missing:
logger.verbose(
'{} of {} entries had no {} ({})',
missing,
len(produced),
field,
'dropped' if require else 'kept, search by title',
)
logger.verbose('Produced {} search entries via {}', len(out), input_name)
return out
@event('plugin.register')
def register_plugin():
plugin.register(ImdbSearchInput, 'imdb_search_input', api_ver=2, interfaces=['task'])
Summary
Problem: FlexGet's
discoverbuilds search queries in the INPUT phase and hands eachquery entry to the search plugin (e.g.
search_rss).search_rsssubstitutesonly
{{search_term}}into the URL, and that term comes fromentry['search_strings'](falling back toentry['title']).Gap: The stock
movie_listinput emitsimdb_idbut NOTsearch_strings, and theset:plugin runs in the METAINFO phase — too late for discover. So there is noconfig-only way to search Prowlarr/Torznab by
imdbid=from a movie_list.A potential plugin closes that gap: it could wrap any input plugin (typically
movie_list),runs it during the input phase, and sets
search_strings = [imdb_id]on eachproduced entry. Discover then receives query entries whose
{{search_term}}isthe IMDb id, so
...&t=movie&imdbid={{search_term}}renders to...&imdbid=tt6857112.Something like this (what I use as a custom plugin to overcome this gap)