Ejemplo n.º 1
0
def main(*args: str) -> None:
    """
    Process command line arguments and invoke bot.

    If args is an empty list, sys.argv is used.

    :param args: command line arguments
    """
    template_names = []
    templates = {}
    options = {}
    # If xmlfilename is None, references will be loaded from the live wiki.
    xmlfilename = None
    user = None
    skip = False
    timestamp = None

    # read command line parameters
    local_args = pywikibot.handle_args(args)

    site = pywikibot.Site()
    gen_factory = pagegenerators.GeneratorFactory()
    for arg in local_args:
        if arg == '-remove':
            options['remove'] = True
        elif arg.startswith('-subst'):
            options['subst'] = arg[len('-subst:'):] + 'subst'
            assert options['subst'] in ('subst', 'safesubst')
        elif arg == '-assubst':
            options['subst'] = 'subst'
            options['remove'] = True
        elif arg == '-always':
            options['always'] = True
        elif arg.startswith('-xml'):
            if len(arg) == 4:
                xmlfilename = pywikibot.input(
                    "Please enter the XML dump's filename: ")
            else:
                xmlfilename = arg[5:]
        elif arg.startswith('-addcat:'):
            options['addcat'] = arg[len('-addcat:'):]
        elif arg.startswith('-summary:'):
            options['summary'] = arg[len('-summary:'):]
        elif arg.startswith('-onlyuser:'******'-onlyuser:'******'-skipuser:'******'-skipuser:'******'-timestamp:'):
            timestamp = arg[len('-timestamp:'):]
        else:
            if not gen_factory.handle_arg(arg):
                template_name = pywikibot.Page(site, arg, ns=10)
                template_names.append(template_name.title(with_ns=False))

    if not template_names:
        pywikibot.bot.suggest_help(missing_parameters=['templates'])
        return

    if bool(options.get('subst', False)) ^ options.get('remove', False):
        for template_name in template_names:
            templates[template_name] = None
    else:
        try:
            for i in range(0, len(template_names), 2):
                templates[template_names[i]] = template_names[i + 1]
        except IndexError:
            pywikibot.output('Unless using solely -subst or -remove, '
                             'you must give an even number of template names.')
            return

    old_templates = [pywikibot.Page(site, template_name, ns=10)
                     for template_name in templates]

    if xmlfilename:
        builder = textlib.MultiTemplateMatchBuilder(site)
        predicate = builder.search_any_predicate(old_templates)

        gen = XMLDumpPageGenerator(
            xmlfilename, site=site, text_predicate=predicate)
    else:
        gen = gen_factory.getCombinedGenerator()

    if not gen:
        gens = (
            t.getReferences(only_template_inclusion=True,
                            follow_redirects=False)
            for t in old_templates
        )
        gen = roundrobin_generators(*gens)
        gen = filter_unique(gen, key=lambda p: '{}:{}:{}'.format(*p._cmpkey()))
    if user:
        gen = pagegenerators.UserEditFilterGenerator(gen, user, timestamp,
                                                     skip,
                                                     max_revision_depth=100,
                                                     show_filtered=True)

    if not gen_factory.gens:
        # make sure that proper namespace filtering etc. is handled
        gen = gen_factory.getCombinedGenerator(gen)

    if not gen_factory.nopreload:
        gen = pagegenerators.PreloadingGenerator(gen)

    bot = TemplateRobot(gen, templates, site=site, **options)
    bot.run()
Ejemplo n.º 2
0
    def __init__(self, generator, templates: dict, **kwargs) -> None:
        """
        Initializer.

        :param generator: the pages to work on
        :type generator: iterable
        :param templates: a dictionary which maps old template names to
            their replacements. If remove or subst is True, it maps the
            names of the templates that should be removed/resolved to None.
        """
        SingleSiteBot.__init__(self, **kwargs)

        self.templates = templates

        # get edit summary message if it's empty
        if not self.opt.summary:
            comma = self.site.mediawiki_message('comma-separator')
            params = {'list': comma.join(self.templates.keys()),
                      'num': len(self.templates)}

            if self.opt.remove:
                tw_key = 'template-removing'
            elif self.opt.subst:
                tw_key = 'template-substituting'
            else:
                tw_key = 'template-changing'
            self.opt.summary = i18n.twtranslate(self.site, tw_key, params)

        replacements = []
        exceptions = {}
        builder = textlib.MultiTemplateMatchBuilder(self.site)
        for old, new in self.templates.items():
            template_regex = builder.pattern(old)

            if self.opt.subst and self.opt.remove:
                replacements.append((template_regex,
                                     r'{{subst:%s\g<parameters>}}' % new))
                exceptions['inside-tags'] = ['ref', 'gallery', 'poem',
                                             'pagelist', ]
            elif self.opt.subst:
                replacements.append(
                    (template_regex, r'{{%s:%s\g<parameters>}}' %
                     (self.opt.subst, old)))
                exceptions['inside-tags'] = ['ref', 'gallery', 'poem',
                                             'pagelist', ]
            elif self.opt.remove:
                separate_line_regex = re.compile(
                    r'^[*#:]* *{} *\n'.format(template_regex.pattern),
                    re.DOTALL | re.MULTILINE)
                replacements.append((separate_line_regex, ''))

                spaced_regex = re.compile(
                    r' +{} +'.format(template_regex.pattern),
                    re.DOTALL)
                replacements.append((spaced_regex, ' '))

                replacements.append((template_regex, ''))
            else:
                template = pywikibot.Page(self.site, new, ns=10)
                if not template.exists():
                    pywikibot.warning('Template "{}" does not exist.'
                                      .format(new))
                    if not pywikibot.input_yn('Do you want to proceed anyway?',
                                              default=False,
                                              automatic_quit=False):
                        continue
                replacements.append((template_regex,
                                     r'{{%s\g<parameters>}}' % new))

        super().__init__(
            generator, replacements, exceptions,
            always=self.opt.always,
            addcat=self.opt.addcat,
            summary=self.opt.summary)