Source code for flexget.components.bittorrent.torrent_scrub

from loguru import logger

from flexget import plugin
from flexget.event import event
from flexget.utils import bittorrent

try:
    # NOTE: Importing other plugins is discouraged!
    from flexget.components.bittorrent import torrent as plugin_torrent
except ImportError:
    raise plugin.DependencyError(issued_by=__name__, missing='torrent')

logger = logger.bind(name='torrent_scrub')


[docs] class TorrentScrub: """Scrubs torrents from unwanted keys. Example: tasks: rutorrent-fast-resume-infected-task: torrent_scrub: resume """ # Scrub at high level, but BELOW "torrent" SCRUB_PRIO = plugin_torrent.TorrentFilename.TORRENT_PRIO - 10 # Scrubbing modes SCRUB_MODES = ('off', 'on', 'all', 'resume', 'rtorrent') # Keys of rTorrent / ruTorrent session data RT_KEYS = ('libtorrent_resume', 'log_callback', 'err_callback', 'rtorrent') schema = { 'oneOf': [ {'type': 'boolean'}, {'type': 'string', 'enum': list(SCRUB_MODES)}, {'type': 'array', 'items': {'type': 'string'}}, # list of keys to scrub ] }
[docs] @plugin.priority(SCRUB_PRIO) def on_task_modify(self, task, config): """Scrub items that are torrents, if they're affected.""" if isinstance(config, list): mode = 'fields' else: mode = str(config).lower() if mode in ('off', 'false'): logger.debug('Plugin configured, but disabled') return for entry in task.entries: # Skip non-torrents if 'torrent' not in entry: continue # Scrub keys as configured modified = set() metainfo = entry['torrent'].content infohash = entry['torrent'].info_hash if mode in ('on', 'all', 'true'): modified = bittorrent.clean_meta( metainfo, including_info=(mode == 'all'), log_func=logger.debug ) elif mode in ('resume', 'rtorrent'): if mode == 'resume': self.RT_KEYS = self.RT_KEYS[:1] for key in self.RT_KEYS: if key in metainfo: logger.debug("Removing key '{}'...", key) del metainfo[key] modified.add(key) elif mode == 'fields': # Scrub all configured fields for key in config: fieldname = key # store for logging key = bittorrent.Torrent.KEY_TYPE(key) field = metainfo while field and '.' in key: name, key = key.split('.', 1) try: field = field[name] except KeyError: # Key not found in this entry field = None logger.trace((key, field)) if field and key in field: logger.debug("Removing key '{}'...", fieldname) del field[key] modified.add(fieldname) else: raise ValueError(f'INTERNAL ERROR: Unknown mode {mode!r}') # Commit any changes back into entry if modified: entry['torrent'].content = metainfo entry['torrent'].modified = True logger.info( "{} {} {} scrubbed from torrent '{}'!", 'Key' if len(modified) == 1 else 'Keys', ', '.join(sorted(modified)), 'was' if len(modified) == 1 else 'were', entry['title'], ) new_infohash = entry['torrent'].info_hash if infohash != new_infohash: logger.warning( "Info hash changed from #{} to #{} in '{}'", infohash, new_infohash, entry['filename'], )
[docs] @event('plugin.register') def register_plugin(): plugin.register(TorrentScrub, interfaces=['task', 'torrent'], api_ver=2)