<commit_before>import logging
from flexget import validator
from flexget.manager import register_config_key
from flexget.plugin import priority, register_plugin, PluginError, register_parser_option, plugins as all_plugins

log = logging.getLogger('preset')


class PluginPreset(object):
    """
        Use presets.

        Example:

        preset: movies

        Example, list of presets:

        preset:
          - movies
          - imdb
    """

    def __init__(self):
        self.warned = False

    def validator(self):
        root = validator.factory()
        root.accept('text')
        root.accept('boolean')
        presets = root.accept('list')
        presets.accept('text')
        return root

    def prepare_config(self, config):
        if config is None or isinstance(config, bool):
            config = []
        elif isinstance(config, basestring):
            config = [config]
        return config

    @priority(255)
    def on_process_start(self, feed, config):
        if config is False: # handles 'preset: no' form to turn off preset on this feed
            return
        config = self.prepare_config(config)

        # implements --preset NAME
        if feed.manager.options.preset:
            if feed.manager.options.preset not in config:
                feed.enabled = False
                return

        # add global in except when disabled with no_global
        if 'no_global' in config:
            config.remove('no_global')
            if 'global' in config:
                config.remove('global')
        elif not 'global' in config:
            config.append('global')

        log.trace('presets: %s' % config)

        toplevel_presets = feed.manager.config.get('presets', {})

        # apply presets
        for preset in config:
            if preset not in toplevel_presets:
                if preset == 'global':
                    continue
                raise PluginError('Unable to find preset %s for feed %s' % (preset, feed.name), log)
            if toplevel_presets[preset] is None:
                log.warning('Preset `%s` is empty. Nothing to merge.' % preset)
                continue
            log.debug('Merging preset %s into feed %s' % (preset, feed.name))

            # We make a copy here because we need to remove
            preset_config = toplevel_presets[preset]
            # When there are presets within presets we remove the preset
            # key from the config and append it's items to our own
            if 'preset' in preset_config:
                nested_presets = self.prepare_config(preset_config['preset'])
                for nested_preset in nested_presets:
                    if nested_preset not in config:
                        config.append(nested_preset)
                    else:
                        log.warning('Presets contain eachother in a loop.')
                # Replace preset_config with a copy without the preset key, to avoid merging errors
                preset_config = dict(preset_config)
                del preset_config['preset']

            # merge
            from flexget.utils.tools import MergeException, merge_dict_from_to
            try:
                merge_dict_from_to(preset_config, feed.config)
            except MergeException, exc:
                raise PluginError('Failed to merge preset %s to feed %s due to %s' % (preset, feed.name, exc))


class DisablePlugin(object):
    """
    Allows disabling plugins when using presets.

    Example:

        presets:
          movies:<commit_msg>allow --preset to work with nested presets<commit_after>import logging
from flexget import validator
from flexget.manager import register_config_key
from flexget.plugin import priority, register_plugin, PluginError, register_parser_option, plugins as all_plugins

log = logging.getLogger('preset')


class PluginPreset(object):
    """
        Use presets.

        Example:

        preset: movies

        Example, list of presets:

        preset:
          - movies
          - imdb
    """

    def __init__(self):
        self.warned = False

    def validator(self):
        root = validator.factory()
        root.accept('text')
        root.accept('boolean')
        presets = root.accept('list')
        presets.accept('text')
        return root

    def prepare_config(self, config):
        if config is None or isinstance(config, bool):
            config = []
        elif isinstance(config, basestring):
            config = [config]
        return config

    @priority(255)
    def on_process_start(self, feed, config):
        if config is False: # handles 'preset: no' form to turn off preset on this feed
            return
        config = self.prepare_config(config)

        # add global in except when disabled with no_global
        if 'no_global' in config:
            config.remove('no_global')
            if 'global' in config:
                config.remove('global')
        elif not 'global' in config:
            config.append('global')

        toplevel_presets = feed.manager.config.get('presets', {})

        # apply presets
        for preset in config:
            if preset not in toplevel_presets:
                if preset == 'global':
                    continue
                raise PluginError('Unable to find preset %s for feed %s' % (preset, feed.name), log)
            if toplevel_presets[preset] is None:
                log.warning('Preset `%s` is empty. Nothing to merge.' % preset)
                continue
            log.debug('Merging preset %s into feed %s' % (preset, feed.name))

            # We make a copy here because we need to remove
            preset_config = toplevel_presets[preset]
            # When there are presets within presets we remove the preset
            # key from the config and append it's items to our own
            if 'preset' in preset_config:
                nested_presets = self.prepare_config(preset_config['preset'])
                for nested_preset in nested_presets:
                    if nested_preset not in config:
                        config.append(nested_preset)
                    else:
                        log.warning('Presets contain each other in a loop.')
                # Replace preset_config with a copy without the preset key, to avoid merging errors
                preset_config = dict(preset_config)
                del preset_config['preset']

            # merge
            from flexget.utils.tools import MergeException, merge_dict_from_to
            try:
                merge_dict_from_to(preset_config, feed.config)
            except MergeException, exc:
                raise PluginError('Failed to merge preset %s to feed %s due to %s' % (preset, feed.name, exc))

        log.trace('presets: %s' % config)

        # implements --preset NAME
        if feed.manager.options.preset:
            if feed.manager.options.preset not in config:
                feed.enabled = False
                return


class DisablePlugin(object):
    """
    Allows disabling plugins when using presets.

    Example:

        presets:
          movies:
{'fraction_non_alphanumeric': 0.07774347460005614, 'fraction_numerical': 0.0008419870895312938, 'mean_word_length': 1.8668543845534995, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4129713', 'n_tokens_mistral': 1940, 'n_tokens_neox': 1847, 'n_words': 592}