Esempio n. 1
0
    def __init__(self,
                 page: 'pywikibot.page.Page',
                 message: Optional[str] = None) -> None:
        """
        Initializer.

        :param page: Page that caused the exception
        """
        if message:
            self.message = message

        if self.message is None:
            raise Error("PageRelatedError is abstract. Can't instantiate it!")

        self.page = page
        self.title = page.title(as_link=True)
        self.site = page.site

        if re.search(r'\{\w+\}', self.message):
            msg = self.message.format_map(self.__dict__)
        elif re.search(r'%\(\w+\)s', self.message):
            issue_deprecation_warning(
                "'%' style messages are deprecated, "
                'please use str.format() style instead',
                since='20210504')
            msg = self.message % self.__dict__
        elif '%s' in self.message:
            msg = self.message % page
        else:
            msg = self.message.format(page)

        super().__init__(msg)
Esempio n. 2
0
    def _get_baserevid(self, claim, baserevid):
        """Check that claim.on_item is set and matches baserevid if used."""
        if not claim.on_item:
            issue_deprecation_warning('claim without on_item set',
                                      depth=3,
                                      warning_class=FutureWarning,
                                      since='20160309')
            if not baserevid:
                warn('Neither claim.on_item nor baserevid provided',
                     UserWarning, 3)
            return baserevid

        if not baserevid:
            return claim.on_item.latest_revision_id

        issue_deprecation_warning('Site method with baserevid',
                                  'claim with on_item set',
                                  depth=3,
                                  since='20150910')
        if baserevid != claim.on_item.latest_revision_id:
            warn(
                'Using baserevid {} instead of claim baserevid {}'.format(
                    baserevid, claim.on_item.latest_revision_id), UserWarning,
                3)

        return baserevid
Esempio n. 3
0
    def _handle_dry_param(self, **kwargs):
        """
        Read the dry parameter and set the simulate variable instead.

        This is a private method. It prints a deprecation warning for old
        -dry paramter and sets the global simulate variable and informs
        the user about this setting.

        The constuctor of the super class ignores it because it is not
        part of self.availableOptions.

        @note: You should ommit this method in your own application.

        @keyword dry: deprecated option to prevent changes on live wiki.
            Use -simulate instead.
        @type dry: bool
        """
        if 'dry' in kwargs:
            issue_deprecation_warning('dry argument',
                                      'pywikibot.config.simulate',
                                      1,
                                      warning_class=FutureWarning,
                                      since='20160124')
            # use simulate variable instead
            pywikibot.config.simulate = True
            pywikibot.output('config.simulate was set to True')
Esempio n. 4
0
    def replace_plural(match):
        selector = match.group(1)
        variants = match.group(2)
        num = parameters[selector]
        if not isinstance(num, int):
            issue_deprecation_warning(
                'type {0} for value {1} ({2})'.format(type(num), selector,
                                                      num), 'an int', 1)
            num = int(num)

        plural_entries = []
        specific_entries = {}
        for number, plural in re.findall(r'\|?(?: *(\d+) *= *)?([^|]+)',
                                         variants):
            if number:
                specific_entries[int(number)] = plural
            else:
                assert not specific_entries, \
                    'generic entries defined after specific in "{0}"'.format(variants)
                plural_entries += [plural]

        if num in specific_entries:
            return specific_entries[num]

        index = plural_value(num)
        if rule['nplurals'] == 1:
            assert index == 0

        if index >= len(plural_entries):
            raise IndexError(
                'requested plural {0} for {1} but only {2} ("{3}") '
                'provided'.format(index, selector, len(plural_entries),
                                  '", "'.join(plural_entries)))
        return plural_entries[index]
Esempio n. 5
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    options = {}
    local_args = pywikibot.handle_args(args)

    issue_deprecation_warning('featured.py script',
                              'Wikibase Client extension', 0, UserWarning)

    for arg in local_args:
        if arg.startswith('-fromlang:'):
            options[arg[1:9]] = arg[10:].split(",")
        elif arg.startswith('-after:'):
            options['afterpage'] = arg[7:]
        elif arg.startswith('-nocache:'):
            options[arg[1:8]] = arg[9:].split(",")
        else:
            options[arg[1:].lower()] = True

    bot = FeaturedBot(**options)
    bot.run()
 def _handle_dry_param(self, **kwargs):
     if 'dry' in kwargs:
         issue_deprecation_warning('dry argument',
                                   'pywikibot.config.simulate', 1)
         # use simulate variable instead
         pywikibot.config.simulate = True
         pywikibot.output('config.simulate was set to True')
Esempio n. 7
0
    def _clean_args(self, args: tuple, kwargs: dict):
        """Cleanup positional arguments.

        Replace positional arguments with keyword arguments for
        backwards compatibility.
        @param: args: tuple of positional arguments
        @param: kwargs: mutable dict of keyword arguments to be updated
        """
        keys = (  # postional argument keys by old order
            'revid', 'timestamp', 'user', 'anon', 'comment', 'text', 'minor',
            'rollbacktoken', 'parentid', 'contentmodel', 'sha1', 'slots'
        )

        # replace positional arguments with keyword arguments
        for i, (arg, key) in enumerate(zip(args, keys)):  # pragma: no cover
            issue_deprecation_warning('Positional argument {} ({})'
                                      .format(i + 1, arg),
                                      'keyword argument "{}={}"'
                                      .format(key, arg),
                                      warning_class=FutureWarning,
                                      since='20200802')
            if key in kwargs:
                warning('"{}" is given as keyword argument "{}" already; '
                        'ignoring "{}"'.format(key, arg, kwargs[key]))
            else:
                kwargs[key] = arg
Esempio n. 8
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: str
    """
    options = {}

    for arg in pywikibot.handle_args(args):
        if arg == '-replacealways':
            options['replace'] = True
            options['replacealways'] = True
        elif arg == '-hash':  # T132303
            raise NotImplementedError(
                "The '-hash' argument is not implemented anymore.")
        elif arg == '-autonomous':
            issue_deprecation_warning('-autonomous',
                                      '-always',
                                      2,
                                      ArgumentDeprecationWarning,
                                      since='20140724')
            options['always'] = True
        elif arg.startswith('-'):
            if arg[1:] in ('always', 'replace', 'replaceloose', 'replaceonly'):
                options[arg[1:]] = True

    bot = NowCommonsDeleteBot(**options)
    bot.run()
Esempio n. 9
0
def output(text, decoder=None, newline=True, toStdout=False, **kwargs):
    r"""Output a message to the user via the userinterface.

    Works like print, but uses the encoding used by the user's console
    (console_encoding in the configuration file) instead of ASCII.

    If decoder is None, text should be a unicode string. Otherwise it
    should be encoded in the given encoding.

    If newline is True, a line feed will be added after printing the text.

    If toStdout is True, the text will be sent to standard output,
    so that it can be piped to another process. All other text will
    be sent to stderr. See: https://en.wikipedia.org/wiki/Pipeline_%28Unix%29

    text can contain special sequences to create colored output. These
    consist of the escape character \03 and the color name in curly braces,
    e. g. \03{lightpurple}. \03{default} resets the color. By using the
    color_format method from pywikibot.tools.formatter, the escape character
    may be omitted.

    Other keyword arguments are passed unchanged to the logger; so far, the
    only argument that is useful is "exc_info=True", which causes the
    log message to include an exception traceback.
    """
    if toStdout:  # maintained for backwards-compatibity only
        from pywikibot.tools import issue_deprecation_warning
        issue_deprecation_warning('"toStdout" parameter', 'pywikibot.stdout()',
                                  2)
        logoutput(text, decoder, newline, STDOUT, **kwargs)
    else:
        logoutput(text, decoder, newline, INFO, **kwargs)
Esempio n. 10
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    options = {}
    local_args = pywikibot.handle_args(args)

    issue_deprecation_warning(
        'featured.py script', 'Wikibase Client extension',
        0, UserWarning)

    for arg in local_args:
        if arg.startswith('-fromlang:'):
            options[arg[1:9]] = arg[10:].split(",")
        elif arg.startswith('-after:'):
            options['afterpage'] = arg[7:]
        elif arg.startswith('-nocache:'):
            options[arg[1:8]] = arg[9:].split(",")
        else:
            options[arg[1:].lower()] = True

    bot = FeaturedBot(**options)
    bot.run()
Esempio n. 11
0
    def replace_plural(match):
        selector = match.group(1)
        variants = match.group(2)
        num = parameters[selector]
        if not isinstance(num, int):
            issue_deprecation_warning("type {0} for value {1} ({2})".format(type(num), selector, num), "an int", 1)
            num = int(num)

        plural_entries = []
        specific_entries = {}
        for number, plural in re.findall(r"\|?(?: *(\d+) *= *)?([^|]+)", variants):
            if number:
                specific_entries[int(number)] = plural
            else:
                assert not specific_entries, 'generic entries defined after specific in "{0}"'.format(variants)
                plural_entries += [plural]

        if num in specific_entries:
            return specific_entries[num]

        index = plural_value(num)
        if rule["nplurals"] == 1:
            assert index == 0

        if index >= len(plural_entries):
            raise IndexError(
                'requested plural {0} for {1} but only {2} ("{3}") '
                "provided".format(index, selector, len(plural_entries), '", "'.join(plural_entries))
            )
        return plural_entries[index]
Esempio n. 12
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    # Process global arguments to determine desired site
    local_args = pywikibot.handle_args(args)

    # This factory is responsible for processing command line arguments
    # that are also used by other scripts and that determine on which pages
    # to work on.
    genFactory = pagegenerators.GeneratorFactory()

    # Parse command line arguments
    for arg in local_args:
        if arg == '-dry':
            issue_deprecation_warning('-dry option', '-simulate', 1)
            pywikibot.config.simulate = True
        else:
            genFactory.handleArg(arg)

    gen = genFactory.getCombinedGenerator()
    if gen:
        # The preloading generator is responsible for downloading multiple
        # pages from the wiki simultaneously.
        gen = pagegenerators.PreloadingGenerator(gen)
        bot = BasicBot(gen)
        bot.run()
    else:
        pywikibot.showHelp()
Esempio n. 13
0
def output(text, decoder=None, newline=True, toStdout=False, **kwargs):
    r"""Output a message to the user via the userinterface.

    Works like print, but uses the encoding used by the user's console
    (console_encoding in the configuration file) instead of ASCII.

    If decoder is None, text should be a unicode string. Otherwise it
    should be encoded in the given encoding.

    If newline is True, a line feed will be added after printing the text.

    If toStdout is True, the text will be sent to standard output,
    so that it can be piped to another process. All other text will
    be sent to stderr. See: https://en.wikipedia.org/wiki/Pipeline_%28Unix%29

    text can contain special sequences to create colored output. These
    consist of the escape character \03 and the color name in curly braces,
    e. g. \03{lightpurple}. \03{default} resets the color. By using the
    color_format method from pywikibot.tools.formatter, the escape character
    may be omitted.

    Other keyword arguments are passed unchanged to the logger; so far, the
    only argument that is useful is "exc_info=True", which causes the
    log message to include an exception traceback.
    """
    if toStdout:  # maintained for backwards-compatibity only
        from pywikibot.tools import issue_deprecation_warning  # noqa
        issue_deprecation_warning('"toStdout" parameter',
                                  'pywikibot.stdout()', 2)
        logoutput(text, decoder, newline, STDOUT, **kwargs)
    else:
        logoutput(text, decoder, newline, INFO, **kwargs)
Esempio n. 14
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: str
    """
    options = {}
    gen = None

    local_args = pywikibot.handle_args(args)

    # This factory is responsible for processing command line arguments
    # that are also used by other scripts and that determine on which pages
    # to work on.
    gen_factory = pagegenerators.GeneratorFactory(positional_arg_name='page')

    for arg in local_args:
        option, sep, value = arg.partition(':')
        if option == '-xml':
            filename = value or pywikibot.input(
                "Please enter the XML dump's filename:")
            gen = TableXmlDumpPageGenerator(filename)
        elif option == '-auto':
            issue_deprecation_warning(
                'The usage of "-auto"', '-always',
                1, ArgumentDeprecationWarning, since='20170205')
            options['always'] = True
        elif option in ['-always', '-quiet', '-skipwarning']:
            options[option[1:]] = True
        else:
            if option in ('-sql', '-mysqlquery'):
                if option == '-sql':
                    issue_deprecation_warning(
                        'The usage of "-sql"', '-mysqlquery',
                        1, ArgumentDeprecationWarning, since='20170205')

                query = value or """
SELECT page_namespace, page_title
FROM page JOIN text ON (page_id = old_id)
WHERE old_text LIKE '%<table%'
"""
                arg = '-mysqlquery:' + query
            gen_factory.handleArg(arg)

    if gen:
        gen = pagegenerators.NamespaceFilterPageGenerator(
            gen, gen_factory.namespaces)
    else:
        gen = gen_factory.getCombinedGenerator()

    if gen:
        if not gen_factory.nopreload:
            gen = pagegenerators.PreloadingGenerator(gen)
        bot = Table2WikiRobot(generator=gen, **options)
        bot.run()
    else:
        suggest_help(missing_generator=True)
Esempio n. 15
0
def checkstr(string: str) -> Tuple[str, str]:
    """
    Return the key and duration extracted from the string.

    @param string: a string defining a time period

    Examples::

        300s - 300 seconds
        36h - 36 hours
        7d - 7 days
        2w - 2 weeks (14 days)
        1y - 1 year

    @return: key and duration extracted form the string
    """
    if string.isdigit():
        key = 's'
        duration = string
        issue_deprecation_warning('Time period without qualifier',
                                  string + key,
                                  1,
                                  FutureWarning,
                                  since='20161009')
    else:
        key = string[-1]
        duration = string[:-1]
    return key, duration
Esempio n. 16
0
def checkstr(string):
    """
    Return the key and duration extracted from the string.

    @param string: a string defining a time period:
        300s - 300 seconds
        36h - 36 hours
        7d - 7 days
        2w - 2 weeks (14 days)
        1y - 1 year
    @type string: str
    @return: key and duration extracted form the string
    @rtype: (str, str)
    """
    key = string[-1]
    if string.isdigit():
        key = 's'
        duration = string
        issue_deprecation_warning('Time period without qualifier',
                                  string + key,
                                  1,
                                  UserWarning,
                                  since='20161009')
    else:
        duration = string[:-1]
    return key, duration
Esempio n. 17
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    generator = None

    local_args = pywikibot.handle_args(args)

    site = pywikibot.Site()

    if site.code != 'commons' or site.family.name != 'commons':
        pywikibot.warning(
            'This script is primarily written for Wikimedia '
            'Commons, but has been invoked with site {0}. It '
            'might work for other sites but there is no '
            'guarantee that it does the right thing.'.format(site))
        choice = pywikibot.input_choice(
            'How do you want to continue?',
            (('Continue using {0}'.format(site), 'c'),
             ('Switch to Wikimedia Commons', 's'), ('Quit', 'q')),
            automatic_quit=False)
        if choice == 's':
            site = pywikibot.Site('commons', 'commons')
        elif choice == 'q':
            return False

    genFactory = pagegenerators.GeneratorFactory(site)

    for arg in local_args:
        if arg.startswith('-yesterday'):
            generator = uploadedYesterday(site)
            issue_deprecation_warning(
                'The usage of "-yesterday"',
                '-logevents:"upload,,YYYYMMDD,YYYYMMDD"', 2,
                ArgumentDeprecationWarning)
        elif arg.startswith('-recentchanges'):
            generator = recentChanges(site=site, delay=120)
        else:
            genFactory.handleArg(arg)

    generator = genFactory.getCombinedGenerator(gen=generator)
    if not generator:
        pywikibot.bot.suggest_help(missing_generator=True)
        return False
    else:
        pregenerator = pagegenerators.PreloadingGenerator(generator)
        site.login()
        for page in pregenerator:
            pywikibot.output(page.title())
            if page.exists() and (page.namespace() == 6) \
                    and (not page.isRedirectPage()):
                if isUncat(page):
                    addUncat(page)
        return True
Esempio n. 18
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    generator = None

    local_args = pywikibot.handle_args(args)

    site = pywikibot.Site()

    if site.code != 'commons' or site.family.name != 'commons':
        pywikibot.warning('This script is primarily written for Wikimedia '
                          'Commons, but has been invoked with site {0}. It '
                          'might work for other sites but there is no '
                          'guarantee that it does the right thing.'.format(site))
        choice = pywikibot.input_choice(
            'How do you want to continue?',
            (('Continue using {0}'.format(site), 'c'),
             ('Switch to Wikimedia Commons', 's'),
             ('Quit', 'q')),
            automatic_quit=False)
        if choice == 's':
            site = pywikibot.Site('commons', 'commons')
        elif choice == 'q':
            return False

    genFactory = pagegenerators.GeneratorFactory(site)

    for arg in local_args:
        if arg.startswith('-yesterday'):
            generator = uploadedYesterday(site)
            issue_deprecation_warning(
                'The usage of "-yesterday"',
                '-logevents:"upload,,YYYYMMDD,YYYYMMDD"',
                2, ArgumentDeprecationWarning)
        elif arg.startswith('-recentchanges'):
            generator = recentChanges(site=site, delay=120)
        else:
            genFactory.handleArg(arg)

    generator = genFactory.getCombinedGenerator(gen=generator)
    if not generator:
        pywikibot.bot.suggest_help(missing_generator=True)
        return False
    else:
        pregenerator = pagegenerators.PreloadingGenerator(generator)
        site.login()
        for page in pregenerator:
            pywikibot.output(page.title())
            if page.exists() and (page.namespace() == 6) \
                    and (not page.isRedirectPage()):
                if isUncat(page):
                    addUncat(page)
        return True
Esempio n. 19
0
def request(site=None,
            uri=None,
            method='GET',
            params=None,
            body=None,
            headers=None,
            data=None,
            **kwargs):
    """
    Request to Site with default error handling and response decoding.

    See L{requests.Session.request} for additional parameters.

    If the site argument is provided, the uri is a relative uri from
    and including the document root '/'.

    If the site argument is None, the uri must be absolute.

    @param site: The Site to connect to
    @type site: L{pywikibot.site.BaseSite}
    @param uri: the URI to retrieve
    @type uri: str
    @keyword charset: Either a valid charset (usable for str.decode()) or None
        to automatically chose the charset from the returned header (defaults
        to latin-1)
    @type charset: CodecInfo, str, None
    @return: The received data
    @rtype: a unicode string
    """
    # body and data parameters both map to the data parameter of
    # requests.Session.request.
    if data:
        body = data

    assert (site or uri)
    if not site:
        # +1 because of @deprecate_arg
        issue_deprecation_warning(
            'Invoking http.request without argument site',
            'http.fetch()',
            3,
            since='20150814')
        r = fetch(uri, method, params, body, headers, **kwargs)
        return r.text

    kwargs.setdefault('disable_ssl_certificate_validation',
                      site.ignore_certificate_error())

    if not headers:
        headers = {}
        format_string = None
    else:
        format_string = headers.get('user-agent')
    headers['user-agent'] = user_agent(site, format_string)

    baseuri = site.base_url(uri)
    r = fetch(baseuri, method, params, body, headers, **kwargs)
    site.throttle.retry_after = int(r.response_headers.get('retry-after', 0))
    return r.text
Esempio n. 20
0
 def out(self) -> str:
     """Return the contents."""
     if not hasattr(self._outputter, 'out'):
         issue_deprecation_warning('{} without "out" property'
                                   .format(self.__class__.__name__),
                                   since='6.2.0')
         self._outputter.output()
         return ''
     return self._outputter.out
Esempio n. 21
0
 def __call__(self, key='general', force=False, dump=False):
     """DEPRECATED: Return the entry for key or dump the complete cache."""
     issue_deprecation_warning('Calling siteinfo',
                               'itself as a dictionary',
                               since='20161221',
                               warning_class=FutureWarning)
     result = self.get(key, expiry=force)
     if not dump:
         return result
     return self._cache
Esempio n. 22
0
 def __init__(self, title: str, _now=None, timestripper=None) -> None:
     """Initializer."""
     if _now is not None:
         issue_deprecation_warning(
             'Argument "now" in DiscussionThread.__init__()',
             warning_class=FutureWarning,
             since='20200727')
     assert timestripper is not None
     self.title = title
     self.ts = timestripper
     self.code = self.ts.site.code
     self.content = ''
     self.timestamp = None
Esempio n. 23
0
def request(site=None, uri=None, method='GET', params=None, body=None,
            headers=None, data=None, **kwargs):
    """
    Request to Site with default error handling and response decoding.

    See L{requests.Session.request} for additional parameters.

    If the site argument is provided, the uri is a relative uri from
    and including the document root '/'.

    If the site argument is None, the uri must be absolute.

    @param site: The Site to connect to
    @type site: L{pywikibot.site.BaseSite}
    @param uri: the URI to retrieve
    @type uri: str
    @param charset: Either a valid charset (usable for str.decode()) or None
        to automatically chose the charset from the returned header (defaults
        to latin-1)
    @type charset: CodecInfo, str, None
    @return: The received data
    @rtype: a unicode string
    """
    # body and data parameters both map to the data parameter of
    # requests.Session.request.
    if data:
        body = data

    assert(site or uri)
    if not site:
        # +1 because of @deprecate_arg
        issue_deprecation_warning(
            'Invoking http.request without argument site', 'http.fetch()', 3)
        r = fetch(uri, method, params, body, headers, **kwargs)
        return r.content

    baseuri = site.base_url(uri)

    kwargs.setdefault("disable_ssl_certificate_validation",
                      site.ignore_certificate_error())

    if not headers:
        headers = {}
        format_string = None
    else:
        format_string = headers.get('user-agent', None)

    headers['user-agent'] = user_agent(site, format_string)

    r = fetch(baseuri, method, params, body, headers, **kwargs)
    return r.content
Esempio n. 24
0
    def __init__(self, generator, dry=False, **kwargs):
        """
        Constructor.

        @param generator: the page generator that determines on which pages
            to work
        @type generator: generator
        @param dry: if True, doesn't do any real changes, but only shows
            what would have been changed
        @type dry: bool
        """
        if dry:
            issue_deprecation_warning('dry argument', 'pywikibot.config.simulate', 1)
            pywikibot.config.simulate = True
        super(BasicBot, self).__init__(site=True, **kwargs)
        self.generator = generator

        # Set the edit summary message
        self.summary = i18n.twtranslate(self.site, 'basic-changing')
Esempio n. 25
0
    def __init__(self, generator, dry=False, **kwargs):
        """
        Constructor.

        @param generator: the page generator that determines on which pages
            to work
        @type generator: generator
        @param dry: if True, doesn't do any real changes, but only shows
            what would have been changed
        @type dry: bool
        """
        if dry:
            issue_deprecation_warning('dry argument',
                                      'pywikibot.config.simulate', 1)
            pywikibot.config.simulate = True
        super(BasicBot, self).__init__(site=True, **kwargs)
        self.generator = generator

        # Set the edit summary message
        self.summary = i18n.twtranslate(self.site, 'basic-changing')
Esempio n. 26
0
def request(site,
            uri: Optional[str] = None,
            headers: Optional[dict] = None,
            **kwargs) -> requests.Response:
    """
    Request to Site with default error handling and response decoding.

    See L{requests.Session.request} for additional parameters.

    The optional uri is a relative uri from site base uri including the
    document root '/'.

    @param site: The Site to connect to
    @type: site: pywikibot.site.BaseSite
    @param uri: the URI to retrieve
    @keyword charset: Either a valid charset (usable for str.decode()) or None
        to automatically chose the charset from the returned header (defaults
        to latin-1)
    @type charset: CodecInfo, str, None
    @return: The received data Response
    """
    kwargs.setdefault('verify', site.verify_SSL_certificate())
    old_validation = kwargs.pop('disable_ssl_certificate_validation', None)
    if old_validation is not None:
        issue_deprecation_warning('disable_ssl_certificate_validation',
                                  instead='verify',
                                  warning_class=FutureWarning,
                                  since='20201220')
        kwargs.update(verify=not old_validation)

    if not headers:
        headers = {}
        format_string = None
    else:
        format_string = headers.get('user-agent')
    headers['user-agent'] = user_agent(site, format_string)

    baseuri = site.base_url(uri)
    r = fetch(baseuri, headers=headers, **kwargs)
    site.throttle.retry_after = int(r.headers.get('retry-after', 0))
    return r
Esempio n. 27
0
    def replace_plural(match):
        selector = match.group(1)
        variants = match.group(2)
        num = parameters[selector]
        if not isinstance(num, int):
            issue_deprecation_warning('type {0} for value {1} ({2})'.format(
                type(num), selector, num),
                                      'an int',
                                      1,
                                      since='20151009')
            num = int(num)

        plural_entries = []
        specific_entries = {}
        # A plural entry can not start at the end of the variants list,
        # and must end with | or the end of the variants list.
        for number, plural in re.findall(
                r'(?!$)(?: *(\d+) *= *)?(.*?)(?:\||$)', variants):
            if number:
                specific_entries[int(number)] = plural
            else:
                assert not specific_entries, (
                    'generic entries defined after specific in "{0}"'.format(
                        variants))
                plural_entries += [plural]

        if num in specific_entries:
            return specific_entries[num]

        index = plural_value(num)
        needed = rule['nplurals']
        if needed == 1:
            assert index == 0

        if index >= len(plural_entries):
            raise IndexError(
                'language "{}" requires {} plural variants for "{}" but '
                'only {} ("{}") provided'.format(code, needed, selector,
                                                 len(plural_entries),
                                                 '", "'.join(plural_entries)))
        return plural_entries[index]
Esempio n. 28
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: unicode
    """
    gen = None
    options = {}

    # Process global args and prepare generator args parser
    local_args = pywikibot.handle_args(args)
    gen_factory = pagegenerators.GeneratorFactory()

    bot_class = TouchBot
    for arg in local_args:
        if gen_factory.handleArg(arg):
            continue
        if arg == '-purge':
            bot_class = PurgeBot
        elif arg == '-redir':
            issue_deprecation_warning('\n-redir',
                                      None,
                                      1,
                                      ArgumentDeprecationWarning,
                                      since='20150514')
        elif arg.startswith('-'):
            options[arg[1:].lower()] = True

    gen = gen_factory.getCombinedGenerator(preload=True)
    if gen:
        bot = bot_class(generator=gen, **options)
        pywikibot.Site().login()
        bot.run()
        return True
    else:
        pywikibot.bot.suggest_help(missing_generator=True)
        return False
Esempio n. 29
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: str
    """
    options = {}
    total = None

    local_args = pywikibot.handle_args(args)

    for arg in local_args:
        arg, sep, value = arg.partition(':')
        if arg == '-limit':
            total = value
        elif arg == '-total':
            total = value
            issue_deprecation_warning('The usage of "{0}"'.format(arg),
                                      '-limit',
                                      2,
                                      ArgumentDeprecationWarning,
                                      since='20190120')
        else:
            options[arg[1:]] = True

    site = pywikibot.Site()
    gen = pagegenerators.UnusedFilesGenerator(total=total, site=site)
    gen = pagegenerators.PreloadingGenerator(gen)

    bot = UnusedFilesBot(site=site, generator=gen, **options)
    try:
        bot.run()
    except pywikibot.Error as e:
        pywikibot.bot.suggest_help(exception=e)
        return False
    else:
        return True
Esempio n. 30
0
    def replace_plural(match):
        selector = match.group(1)
        variants = match.group(2)
        num = parameters[selector]
        if not isinstance(num, int):
            issue_deprecation_warning(
                'type {} for value {} ({})'
                .format(type(num), selector, num),
                'an int', 1,
                warning_class=FutureWarning, since='20151009')
            num = int(num)

        plural_entries = []
        specific_entries = {}
        # A plural entry cannot start at the end of the variants list,
        # and must end with | or the end of the variants list.
        for number, plural in re.findall(
            r'(?!$)(?: *(\d+) *= *)?(.*?)(?:\||$)', variants
        ):
            if number:
                specific_entries[int(number)] = plural
            else:
                assert not specific_entries, (
                    'generic entries defined after specific in "{}"'
                    .format(variants))
                plural_entries += [plural]

        if num in specific_entries:
            return specific_entries[num]

        index = plural_value(num)
        needed = rule['nplurals']
        if needed == 1:
            assert index == 0

        if index >= len(plural_entries):
            # take the last entry in that case, see
            # https://translatewiki.net/wiki/Plural#Plural_syntax_in_MediaWiki
            index = -1
        return plural_entries[index]
Esempio n. 31
0
    def replace_plural(match):
        selector = match.group(1)
        variants = match.group(2)
        num = parameters[selector]
        if not isinstance(num, int):
            issue_deprecation_warning(
                'type {0} for value {1} ({2})'
                .format(type(num), selector, num),
                'an int', 1, since='20151009')
            num = int(num)

        plural_entries = []
        specific_entries = {}
        # A plural entry can not start at the end of the variants list,
        # and must end with | or the end of the variants list.
        for number, plural in re.findall(
            r'(?!$)(?: *(\d+) *= *)?(.*?)(?:\||$)', variants
        ):
            if number:
                specific_entries[int(number)] = plural
            else:
                assert not specific_entries, (
                    'generic entries defined after specific in "{0}"'
                    .format(variants))
                plural_entries += [plural]

        if num in specific_entries:
            return specific_entries[num]

        index = plural_value(num)
        needed = rule['nplurals']
        if needed == 1:
            assert index == 0

        if index >= len(plural_entries):
            # take the last entry in that case, see
            # https://translatewiki.net/wiki/Plural#Plural_syntax_in_MediaWiki
            index = -1
        return plural_entries[index]
Esempio n. 32
0
    def _handle_dry_param(self, **kwargs):
        """
        Read the dry parameter and set the simulate variable instead.

        This is a private method. It prints a deprecation warning for old
        -dry paramter and sets the global simulate variable and informs
        the user about this setting.

        The constuctor of the super class ignores it because it is not
        part of self.availableOptions.

        @note: You should ommit this method in your own application.

        @keyword dry: deprecated option to prevent changes on live wiki.
            Use -simulate instead.
        @type dry: bool
        """
        if "dry" in kwargs:
            issue_deprecation_warning("dry argument", "pywikibot.config.simulate", 1)
            # use simulate variable instead
            pywikibot.config.simulate = True
            pywikibot.output("config.simulate was set to True")
Esempio n. 33
0
def checkstr(string):
    """
    Return the key and duration extracted from the string.

    @param string: a string defining a time period:
        300s - 300 seconds
        36h - 36 hours
        7d - 7 days
        2w - 2 weeks (14 days)
        1y - 1 year
    @type string: str
    @return: key and duration extracted form the string
    @rtype: (str, str)
    """
    key = string[-1]
    if string.isdigit():
        key = 's'
        duration = string
        issue_deprecation_warning('Time period without qualifier',
                                  string + key, 1, UserWarning)
    else:
        duration = string[:-1]
    return key, duration
Esempio n. 34
0
    def replace_plural(match):
        selector = match.group(1)
        variants = match.group(2)
        num = parameters[selector]
        if not isinstance(num, int):
            issue_deprecation_warning(
                'type {0} for value {1} ({2})'.format(type(num), selector, num),
                'an int', 1)
            num = int(num)

        plural_entries = []
        specific_entries = {}
        # A plural entry can not start at the end of the variants list,
        # and must end with | or the end of the variants list.
        for number, plural in re.findall(r'(?!$)(?: *(\d+) *= *)?(.*?)(?:\||$)',
                                         variants):
            if number:
                specific_entries[int(number)] = plural
            else:
                assert not specific_entries, \
                    'generic entries defined after specific in "{0}"'.format(variants)
                plural_entries += [plural]

        if num in specific_entries:
            return specific_entries[num]

        index = plural_value(num)
        if rule['nplurals'] == 1:
            assert index == 0

        if index >= len(plural_entries):
            raise IndexError(
                'requested plural {0} for {1} but only {2} ("{3}") '
                'provided'.format(
                    index, selector, len(plural_entries),
                    '", "'.join(plural_entries)))
        return plural_entries[index]
Esempio n. 35
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    # Process global arguments to determine desired site
    local_args = pywikibot.handle_args(args)

    # This factory is responsible for processing command line arguments
    # that are also used by other scripts and that determine on which pages
    # to work on.
    genFactory = pagegenerators.GeneratorFactory()

    # Parse command line arguments
    for arg in local_args:
        if arg == '-dry':
            issue_deprecation_warning('-dry option', '-simulate', 1)
            pywikibot.config.simulate = True
        else:
            genFactory.handleArg(arg)

    gen = genFactory.getCombinedGenerator()
    if gen:
        # The preloading generator is responsible for downloading multiple
        # pages from the wiki simultaneously.
        gen = pagegenerators.PreloadingGenerator(gen)
        bot = BasicBot(gen)
        bot.run()
        return True
    else:
        pywikibot.bot.suggest_help(missing_generator=True)
        return False
Esempio n. 36
0
def fetch(uri: str,
          method: str = 'GET',
          headers: Optional[dict] = None,
          default_error_handling: bool = True,
          use_fake_user_agent: Union[bool, str] = False,
          **kwargs):
    """
    HTTP request.

    See :py:obj:`requests.Session.request` for parameters.

    :param uri: URL to send
    :param method: HTTP method of the request (default: GET)
    :param headers: dictionary of headers of the request
    :param default_error_handling: Use default error handling
    :param use_fake_user_agent: Set to True to use fake UA, False to use
        pywikibot's UA, str to specify own UA. This behaviour might be
        overridden by domain in config.

    :keyword charset: Either a valid charset (usable for str.decode()) or None
        to automatically chose the charset from the returned header (defaults
        to latin-1)
    :type charset: CodecInfo, str, None
    :keyword verify: verify the SSL certificate (default is True)
    :type verify: bool or path to certificates
    :keyword callbacks: Methods to call once data is fetched
    :type callbacks: list of callable
    :rtype: :py:obj:`requests.Response`
    """
    # Change user agent depending on fake UA settings.
    # Set header to new UA if needed.
    headers = headers or {}
    headers.update(config.extra_headers.copy() or {})

    def assign_fake_user_agent(use_fake_user_agent, uri):
        uri_domain = urlparse(uri).netloc
        use_fake_user_agent = config.fake_user_agent_exceptions.get(
            uri_domain, use_fake_user_agent)

        if use_fake_user_agent is False:
            return user_agent()
        if use_fake_user_agent is True:
            return fake_user_agent()
        if use_fake_user_agent and isinstance(use_fake_user_agent, str):
            return use_fake_user_agent  # Custom UA.
        raise ValueError('Invalid parameter: '
                         'use_fake_user_agent={}'.format(use_fake_user_agent))

    def assign_user_agent(user_agent_format_string):
        if not user_agent_format_string or '{' in user_agent_format_string:
            return user_agent(None, user_agent_format_string)
        # do nothing, it is already a UA
        return user_agent_format_string

    # If not already specified.
    if 'user-agent' not in headers:
        # Get fake UA exceptions from `fake_user_agent_exceptions` config.
        headers['user-agent'] = assign_fake_user_agent(use_fake_user_agent,
                                                       uri)
    # Already specified.
    else:
        headers['user-agent'] = assign_user_agent(headers.get('user-agent'))

    callbacks = kwargs.pop('callbacks', [])
    # error_handling_callback will be executed first.
    if default_error_handling:
        callbacks.insert(0, error_handling_callback)

    charset = kwargs.pop('charset', None)

    auth = get_authentication(uri)
    if auth is not None and len(auth) == 4:
        if isinstance(requests_oauthlib, ImportError):
            warn(str(requests_oauthlib), ImportWarning)
            error('OAuth authentication not supported: {}'.format(
                requests_oauthlib))
            auth = None
        else:
            auth = requests_oauthlib.OAuth1(*auth)

    timeout = config.socket_timeout
    old_validation = kwargs.pop('disable_ssl_certificate_validation', None)
    if old_validation is not None:
        issue_deprecation_warning('disable_ssl_certificate_validation',
                                  instead='verify',
                                  since='20201220')
        kwargs.update(verify=not old_validation)

    try:
        # Note that the connections are pooled which mean that a future
        # HTTPS request can succeed even if the certificate is invalid and
        # verify=True, when a request with verify=False happened before
        response = session.request(method,
                                   uri,
                                   headers=headers,
                                   auth=auth,
                                   timeout=timeout,
                                   **kwargs)
    except Exception as e:
        response = e
    else:
        response.encoding = _decide_encoding(response, charset)

    for callback in callbacks:
        callback(response)

    return response
Esempio n. 37
0
def main(*args: Tuple[str, ...]) -> None:
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    """
    # If none, the var is set only for check purpose.
    summary = None
    addText = None
    regexSkipUrl = None
    always = False
    textfile = None
    talkPage = False
    reorderEnabled = True

    # Put the text above or below the text?
    up = False

    # Process global args and prepare generator args parser
    local_args = pywikibot.handle_args(args)
    genFactory = pagegenerators.GeneratorFactory()

    # Loading the arguments
    for arg in local_args:
        option, sep, value = arg.partition(':')
        if option == '-textfile':
            textfile = value or pywikibot.input(
                'Which textfile do you want to add?')
        elif option == '-text':
            addText = value or pywikibot.input('What text do you want to add?')
        elif option == '-summary':
            summary = value or pywikibot.input(
                'What summary do you want to use?')
        elif option == '-excepturl':
            regexSkipUrl = value or pywikibot.input('What text should I skip?')
        elif option == '-except':
            new_arg = ''.join(['-grepnot', sep, value])
            issue_deprecation_warning(arg,
                                      new_arg,
                                      2,
                                      ArgumentDeprecationWarning,
                                      since='20201224')
            genFactory.handle_arg(new_arg)
        elif option == '-up':
            up = True
        elif option == '-noreorder':
            reorderEnabled = False
        elif option == '-always':
            always = True
        elif option in ('-talk', '-talkpage'):
            talkPage = True
        else:
            genFactory.handle_arg(arg)

    if textfile and not addText:
        with codecs.open(textfile, 'r', config.textfile_encoding) as f:
            addText = f.read()

    generator = genFactory.getCombinedGenerator()
    additional_text = '' if addText else "The text to add wasn't given."
    if pywikibot.bot.suggest_help(missing_generator=not generator,
                                  additional_text=additional_text):
        return

    if talkPage:
        generator = pagegenerators.PageWithTalkPageGenerator(generator, True)
    for page in generator:
        (_, newtext, _) = add_text(page,
                                   addText,
                                   summary,
                                   regexSkipUrl=regexSkipUrl,
                                   always=always,
                                   up=up,
                                   reorderEnabled=reorderEnabled,
                                   create=talkPage)
Esempio n. 38
0
    else:
        import _winreg as winreg


# Normalize old PYWIKIBOT2 environment variables and issue a deprecation warn.
for env_name in (
    'PYWIKIBOT2_DIR', 'PYWIKIBOT2_DIR_PWB', 'PYWIKIBOT2_NO_USER_CONFIG',
):
    if env_name not in environ:
        continue
    env_value = environ[env_name]
    new_env_name = env_name.replace('PYWIKIBOT2_', 'PYWIKIBOT_')
    del environ[env_name]
    if new_env_name not in environ:
        environ[new_env_name] = env_value
    issue_deprecation_warning(
        env_name + ' environment variable', new_env_name, 0, since='20180803')


# This frozen set should contain all imported modules/variables, so it must
# occur directly after the imports. At that point globals() only contains the
# names and some magic variables (like __name__)
_imports = frozenset(name for name in globals() if not name.startswith('_'))

__no_user_config = getenv('PYWIKIBOT_NO_USER_CONFIG')
if __no_user_config == '0':
    __no_user_config = None


class _ConfigurationDeprecationWarning(UserWarning):

    """Feature that is no longer supported."""
Esempio n. 39
0
if OSWIN32:
    import winreg


# Normalize old PYWIKIBOT2 environment variables and issue a deprecation warn.
for env_name in (
    'PYWIKIBOT2_DIR', 'PYWIKIBOT2_DIR_PWB', 'PYWIKIBOT2_NO_USER_CONFIG',
):
    if env_name not in environ:
        continue
    env_value = environ[env_name]
    new_env_name = env_name.replace('PYWIKIBOT2_', 'PYWIKIBOT_')
    del environ[env_name]
    if new_env_name not in environ:
        environ[new_env_name] = env_value
    issue_deprecation_warning(
        env_name + ' environment variable', new_env_name, 0, since='20180803')


# This frozen set should contain all imported modules/variables, so it must
# occur directly after the imports. At that point globals() only contains the
# names and some magic variables (like __name__)
_imports = frozenset(name for name in globals() if not name.startswith('_'))

__no_user_config = getenv('PYWIKIBOT_NO_USER_CONFIG')
if __no_user_config == '0':
    __no_user_config = None


class _ConfigurationDeprecationWarning(UserWarning):

    """Feature that is no longer supported."""
Esempio n. 40
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: unicode
    """
    oldName = None
    options = {}
    fromToPairs = []

    # Process global args and prepare generator args parser
    local_args = pywikibot.handle_args(args)
    genFactory = pagegenerators.GeneratorFactory()

    for arg in local_args:
        if arg == '-pairs' or arg.startswith('-pairs:'):
            issue_deprecation_warning(
                '-pairs',
                '-pairsfile',
                2, ArgumentDeprecationWarning, since='20160304')
        elif arg.startswith('-pairsfile'):
            if len(arg) == len('-pairsfile'):
                filename = pywikibot.input(
                    'Enter the name of the file containing pairs:')
            else:
                filename = arg[len('-pairsfile:'):]
            oldName1 = None
            for page in pagegenerators.TextfilePageGenerator(filename):
                if oldName1:
                    fromToPairs.append([oldName1, page.title()])
                    oldName1 = None
                else:
                    oldName1 = page.title()
            if oldName1:
                pywikibot.warning(
                    'file {0} contains odd number of links'.format(filename))
        elif arg == '-noredirect':
            options['noredirect'] = True
        elif arg == '-notalkpage':
            options['movetalkpage'] = False
        elif arg == '-always':
            options['always'] = True
        elif arg == '-skipredirects':
            options['skipredirects'] = True
        elif arg.startswith('-from:'):
            if oldName:
                pywikibot.warning('-from:{0} without -to:'.format(oldName))
            oldName = arg[len('-from:'):]
        elif arg.startswith('-to:'):
            if oldName:
                fromToPairs.append([oldName, arg[len('-to:'):]])
                oldName = None
            else:
                pywikibot.warning('{0} without -from'.format(arg))
        elif arg.startswith('-prefix'):
            if len(arg) == len('-prefix'):
                options['prefix'] = pywikibot.input('Enter the prefix:')
            else:
                options['prefix'] = arg[8:]
        elif arg.startswith('-summary'):
            if len(arg) == len('-summary'):
                options['summary'] = pywikibot.input('Enter the summary:')
            else:
                options['summary'] = arg[9:]
        else:
            genFactory.handleArg(arg)

    if oldName:
        pywikibot.warning('-from:{0} without -to:'.format(oldName))
    site = pywikibot.Site()
    for pair in fromToPairs:
        page = pywikibot.Page(site, pair[0])
        bot = MovePagesBot(None, **options)
        bot.moveOne(page, pair[1])

    gen = genFactory.getCombinedGenerator(preload=True)
    if gen:
        bot = MovePagesBot(gen, **options)
        bot.run()
        return True

    if not fromToPairs:
        pywikibot.bot.suggest_help(missing_generator=True)
        return False
    else:
        return True
Esempio n. 41
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    options = {}
    gen_options = {}
    # what the bot should do (either resolve double redirs, or process broken
    # redirs)
    action = None
    namespaces = []
    source = set()

    for arg in pywikibot.handle_args(args):
        arg, sep, value = arg.partition(':')
        option = arg.partition('-')[2]
        # bot options
        if arg == 'do':
            action = 'double'
        elif arg == 'br':
            action = 'broken'
        elif arg in ('both', 'broken', 'double'):
            action = arg
        elif option in ('always', 'delete'):
            options[option] = True
        elif option == 'total':
            options[option] = gen_options[option] = int(value)
        elif option == 'sdtemplate':
            options['sdtemplate'] = value or pywikibot.input(
                'Which speedy deletion template to use?')
        # generator options
        elif option in ('fullscan', 'moves'):
            gen_options[option] = True
            source.add(arg)
        elif option == 'xml':
            gen_options[option] = value or i18n.input(
                'pywikibot-enter-xml-filename')
            source.add(arg)
        elif option == 'namespace':
            # "-namespace:" does NOT yield -namespace:0 further down the road!
            ns = value or i18n.input('pywikibot-enter-namespace-number')
            # TODO: at least for some generators enter a namespace by its name
            # or number
            if ns == '':
                ns = '0'
            try:
                ns = int(ns)
            except ValueError:
                # -namespace:all Process all namespaces.
                # Only works with the API read interface.
                pass
            if ns not in namespaces:
                namespaces.append(ns)
        elif option == 'offset':
            gen_options[option] = int(value)
        elif option in ('page', 'start', 'until'):
            gen_options[option] = value
        # deprecated or unknown options
        elif option == 'step':
            issue_deprecation_warning('The usage of "{0}"'.format(arg),
                                      2, ArgumentDeprecationWarning)
        else:
            pywikibot.output(u'Unknown argument: %s' % arg)

    gen_options['namespaces'] = namespaces

    if len(source) > 1:
        problem = 'You can only use one of {0} options.'.format(
            ' or '.join(source))
        pywikibot.bot.suggest_help(additional_text=problem,
                                   missing_action=not action)
        return
    if not action:
        pywikibot.bot.suggest_help(missing_action=True)
    else:
        pywikibot.Site().login()
        options['generator'] = RedirectGenerator(action, **gen_options)
        bot = RedirectRobot(action, **options)
        bot.run()
Esempio n. 42
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    options = {}
    # what the bot should do (either resolve double redirs, or delete broken
    # redirs)
    action = None
    # where the bot should get his infos from (either None to load the
    # maintenance special page from the live wiki, or the filename of a
    # local XML dump file)
    xmlFilename = None
    # Which namespace should be processed when using a XML dump
    # default to -1 which means all namespaces will be processed
    namespaces = []
    # at which redirect shall we start searching double redirects again
    # (only with dump); default to -1 which means all redirects are checked
    offset = -1
    moved_pages = False
    fullscan = False
    start = ''
    until = ''
    number = None
    pagename = None

    for arg in pywikibot.handle_args(args):
        arg, sep, value = arg.partition(':')
        option = arg[1:]
        # bot options
        if arg == 'do':
            action = 'double'
        elif arg == 'br':
            action = 'broken'
        elif arg in ('both', 'broken', 'double'):
            action = arg
        elif option in ('always', 'delete'):
            options[option] = True
        elif option == 'total':
            options['number'] = number = int(value)
        # generator options
        elif option == 'fullscan':
            fullscan = True
        elif option == 'xml':
            xmlFilename = value or i18n.input('pywikibot-enter-xml-filename')
        elif option == 'moves':
            moved_pages = True
        elif option == 'namespace':
            # "-namespace:" does NOT yield -namespace:0 further down the road!
            ns = value or i18n.input('pywikibot-enter-namespace-number')
            # TODO: at least for some generators enter a namespace by its name
            # or number
            if ns == '':
                ns = '0'
            try:
                ns = int(ns)
            except ValueError:
                # -namespace:all Process all namespaces.
                # Only works with the API read interface.
                pass
            if ns not in namespaces:
                namespaces.append(ns)
        elif option == 'offset':
            offset = int(value)
        elif option == 'start':
            start = value
        elif option == 'until':
            until = value
        elif option == 'page':
            pagename = value
        # deprecated or unknown options
        elif option == 'step':
            issue_deprecation_warning('The usage of "{0}"'.format(arg),
                                      2, ArgumentDeprecationWarning)
        else:
            pywikibot.output(u'Unknown argument: {0!s}'.format(arg))

    if not action or xmlFilename and (moved_pages or fullscan):
        problems = []
        if xmlFilename and moved_pages:
            problems += ['Either use a XML file or the moved pages from the API']
        if xmlFilename and fullscan:
            problems += ['Either use a XML file or do a full scan using the API']
        pywikibot.bot.suggest_help(additional_text='\n'.join(problems),
                                   missing_action=not action)
    else:
        pywikibot.Site().login()
        gen = RedirectGenerator(xmlFilename, namespaces, offset, moved_pages,
                                fullscan, start, until, number, pagename)
        bot = RedirectRobot(action, gen, **options)
        bot.run()
Esempio n. 43
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    options = {}
    # what the bot should do (either resolve double redirs, or process broken
    # redirs)
    action = None
    # where the bot should get his infos from (either None to load the
    # maintenance special page from the live wiki, or the filename of a
    # local XML dump file)
    xmlFilename = None
    # Which namespace should be processed when using a XML dump
    # default to -1 which means all namespaces will be processed
    namespaces = []
    # at which redirect shall we start searching double redirects again
    # (only with dump); default to -1 which means all redirects are checked
    offset = -1
    moved_pages = False
    fullscan = False
    start = ""
    until = ""
    number = None
    pagename = None

    for arg in pywikibot.handle_args(args):
        arg, sep, value = arg.partition(":")
        option = arg[1:]
        # bot options
        if arg == "do":
            action = "double"
        elif arg == "br":
            action = "broken"
        elif arg in ("both", "broken", "double"):
            action = arg
        elif option in ("always", "delete"):
            options[option] = True
        elif option == "total":
            options["number"] = number = int(value)
        # generator options
        elif option == "fullscan":
            fullscan = True
        elif option == "xml":
            xmlFilename = value or i18n.input("pywikibot-enter-xml-filename")
        elif option == "moves":
            moved_pages = True
        elif option == "namespace":
            # "-namespace:" does NOT yield -namespace:0 further down the road!
            ns = value or i18n.input("pywikibot-enter-namespace-number")
            # TODO: at least for some generators enter a namespace by its name
            # or number
            if ns == "":
                ns = "0"
            try:
                ns = int(ns)
            except ValueError:
                # -namespace:all Process all namespaces.
                # Only works with the API read interface.
                pass
            if ns not in namespaces:
                namespaces.append(ns)
        elif option == "offset":
            offset = int(value)
        elif option == "start":
            start = value
        elif option == "until":
            until = value
        elif option == "page":
            pagename = value
        # deprecated or unknown options
        elif option == "step":
            issue_deprecation_warning('The usage of "{0}"'.format(arg), 2, ArgumentDeprecationWarning)
        else:
            pywikibot.output("Unknown argument: %s" % arg)

    if not action or xmlFilename and (moved_pages or fullscan):
        problems = []
        if xmlFilename and moved_pages:
            problems += ["Either use a XML file or the moved pages from the API"]
        if xmlFilename and fullscan:
            problems += ["Either use a XML file or do a full scan using the API"]
        pywikibot.bot.suggest_help(additional_text="\n".join(problems), missing_action=not action)
    else:
        pywikibot.Site().login()
        gen = RedirectGenerator(xmlFilename, namespaces, offset, moved_pages, fullscan, start, until, number, pagename)
        bot = RedirectRobot(action, gen, **options)
        bot.run()
Esempio n. 44
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    gen = None
    oldName = None
    options = {}
    fromToPairs = []

    # Process global args and prepare generator args parser
    local_args = pywikibot.handle_args(args)
    genFactory = pagegenerators.GeneratorFactory()

    for arg in local_args:
        if arg.startswith('-pairs'):
            issue_deprecation_warning(
                '-pairs',
                '-pairsfile',
                2, ArgumentDeprecationWarning)
        elif arg.startswith('-pairsfile'):
            if len(arg) == len('-pairsfile'):
                filename = pywikibot.input(
                    u'Enter the name of the file containing pairs:')
            else:
                filename = arg[len('-pairsfile:'):]
            oldName1 = None
            for page in pagegenerators.TextfilePageGenerator(filename):
                if oldName1:
                    fromToPairs.append([oldName1, page.title()])
                    oldName1 = None
                else:
                    oldName1 = page.title()
            if oldName1:
                pywikibot.warning(
                    u'file %s contains odd number of links' % filename)
        elif arg == '-noredirect':
            options['noredirect'] = True
        elif arg == '-notalkpage':
            options['movetalkpage'] = False
        elif arg == '-always':
            options['always'] = True
        elif arg == '-skipredirects':
            options['skipredirects'] = True
        elif arg.startswith('-from:'):
            if oldName:
                pywikibot.warning(u'-from:%s without -to:' % oldName)
            oldName = arg[len('-from:'):]
        elif arg.startswith('-to:'):
            if oldName:
                fromToPairs.append([oldName, arg[len('-to:'):]])
                oldName = None
            else:
                pywikibot.warning(u'%s without -from' % arg)
        elif arg.startswith('-prefix'):
            if len(arg) == len('-prefix'):
                options['prefix'] = pywikibot.input(u'Enter the prefix:')
            else:
                options['prefix'] = arg[8:]
        elif arg.startswith('-summary'):
            if len(arg) == len('-summary'):
                options['summary'] = pywikibot.input(u'Enter the summary:')
            else:
                options['summary'] = arg[9:]
        else:
            genFactory.handleArg(arg)

    if oldName:
        pywikibot.warning(u'-from:%s without -to:' % oldName)
    site = pywikibot.Site()
    for pair in fromToPairs:
        page = pywikibot.Page(site, pair[0])
        bot = MovePagesBot(None, **options)
        bot.moveOne(page, pair[1])

    if not gen:
        gen = genFactory.getCombinedGenerator()
    if gen:
        preloadingGen = pagegenerators.PreloadingGenerator(gen)
        bot = MovePagesBot(preloadingGen, **options)
        bot.run()
        return True

    if not fromToPairs:
        pywikibot.bot.suggest_help(missing_generator=True)
        return False
    else:
        return True
Esempio n. 45
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    options = {}
    gen = None

    local_args = pywikibot.handle_args(args)

    # This factory is responsible for processing command line arguments
    # that are also used by other scripts and that determine on which pages
    # to work on.
    genFactory = pagegenerators.GeneratorFactory(positional_arg_name='page')

    for arg in local_args:
        option, sep, value = arg.partition(':')
        if option == '-xml':
            filename = value or pywikibot.input(
                "Please enter the XML dump's filename:")
            gen = TableXmlDumpPageGenerator(filename)
        elif option == '-auto':
            issue_deprecation_warning(
                'The usage of "-auto"', '-always',
                1, ArgumentDeprecationWarning)
            options['always'] = True
        elif option in ['-always', '-quiet', '-skipwarning']:
            options[option[1:]] = True
        else:
            if option in ['-sql', '-mysqlquery']:
                if not (has_module('oursql') or has_module('MySQLdb')):
                    raise NotImplementedError(
                        'Neither "oursql" nor "MySQLdb" library is installed.')
                if option == '-sql':
                    issue_deprecation_warning(
                        'The usage of "-sql"', '-mysqlquery',
                        1, ArgumentDeprecationWarning)

                query = value or """
SELECT page_namespace, page_title
FROM page JOIN text ON (page_id = old_id)
WHERE old_text LIKE '%<table%'
"""
                arg = '-mysqlquery:' + query
            genFactory.handleArg(arg)

    if gen:
        gen = pagegenerators.NamespaceFilterPageGenerator(
            gen, genFactory.namespaces)
    else:
        gen = genFactory.getCombinedGenerator()

    if gen:
        if not genFactory.nopreload:
            gen = pagegenerators.PreloadingGenerator(gen)
        bot = Table2WikiRobot(generator=gen, **options)
        bot.run()
        return True
    else:
        suggest_help(missing_generator=True)
        return False
Esempio n. 46
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    add_cat = None
    gen = None
    # summary message
    edit_summary = ""
    # Array which will collect commandline parameters.
    # First element is original text, second element is replacement text.
    commandline_replacements = []
    # A list of 2-tuples of original text and replacement text.
    replacements = []
    # Don't edit pages which contain certain texts.
    exceptions = {
        "title": [],
        "text-contains": [],
        "inside": [],
        "inside-tags": [],
        "require-title": [],  # using a seperate requirements dict needs some
    }  # major refactoring of code.

    # Should the elements of 'replacements' and 'exceptions' be interpreted
    # as regular expressions?
    regex = False
    # Predefined fixes from dictionary 'fixes' (see above).
    fixes_set = []
    # the dump's path, either absolute or relative, which will be used
    # if -xml flag is present
    xmlFilename = None
    useSql = False
    # will become True when the user presses a ('yes to all') or uses the
    # -always flag.
    acceptall = False
    # Will become True if the user inputs the commandline parameter -nocase
    caseInsensitive = False
    # Will become True if the user inputs the commandline parameter -dotall
    dotall = False
    # Will become True if the user inputs the commandline parameter -multiline
    multiline = False
    # Do all hits when they overlap
    allowoverlap = False
    # Do not recurse replacement
    recursive = False
    # Between a regex and another (using -fix) sleep some time (not to waste
    # too much CPU
    sleep = None
    # Request manual replacements even if replacements are already defined
    manual_input = False
    # Replacements loaded from a file
    replacement_file = None
    replacement_file_arg_misplaced = False

    # Read commandline parameters.

    local_args = pywikibot.handle_args(args)
    genFactory = pagegenerators.GeneratorFactory()

    for arg in local_args:
        if genFactory.handleArg(arg):
            continue
        if arg == "-regex":
            regex = True
        elif arg.startswith("-xmlstart"):
            if len(arg) == 9:
                xmlStart = pywikibot.input("Please enter the dumped article to start with:")
            else:
                xmlStart = arg[10:]
        elif arg.startswith("-xml"):
            if len(arg) == 4:
                xmlFilename = i18n.input("pywikibot-enter-xml-filename")
            else:
                xmlFilename = arg[5:]
        elif arg == "-sql":
            useSql = True
        elif arg.startswith("-excepttitle:"):
            exceptions["title"].append(arg[13:])
        elif arg.startswith("-requiretitle:"):
            exceptions["require-title"].append(arg[14:])
        elif arg.startswith("-excepttext:"):
            exceptions["text-contains"].append(arg[12:])
        elif arg.startswith("-exceptinside:"):
            exceptions["inside"].append(arg[14:])
        elif arg.startswith("-exceptinsidetag:"):
            exceptions["inside-tags"].append(arg[17:])
        elif arg.startswith("-fix:"):
            fixes_set += [arg[5:]]
        elif arg.startswith("-sleep:"):
            sleep = float(arg[7:])
        elif arg == "-always":
            acceptall = True
        elif arg == "-recursive":
            recursive = True
        elif arg == "-nocase":
            caseInsensitive = True
        elif arg == "-dotall":
            dotall = True
        elif arg == "-multiline":
            multiline = True
        elif arg.startswith("-addcat:"):
            add_cat = arg[8:]
        elif arg.startswith("-summary:"):
            edit_summary = arg[9:]
        elif arg.startswith("-automaticsummary"):
            edit_summary = True
        elif arg.startswith("-allowoverlap"):
            allowoverlap = True
        elif arg.startswith("-manualinput"):
            manual_input = True
        elif arg.startswith("-replacementfile"):
            issue_deprecation_warning("-replacementfile", "-pairsfile", 2, ArgumentDeprecationWarning)
        elif arg.startswith("-pairsfile"):
            if len(commandline_replacements) % 2:
                replacement_file_arg_misplaced = True

            if arg == "-pairsfile":
                replacement_file = pywikibot.input("Please enter the filename to read replacements from:")
            else:
                replacement_file = arg[len("-pairsfile:") :]
        else:
            commandline_replacements.append(arg)

    site = pywikibot.Site()

    if len(commandline_replacements) % 2:
        pywikibot.error("Incomplete command line pattern replacement pair.")
        return False

    if replacement_file_arg_misplaced:
        pywikibot.error("-pairsfile used between a pattern replacement pair.")
        return False

    if replacement_file:
        try:
            with codecs.open(replacement_file, "r", "utf-8") as f:
                # strip newlines, but not other characters
                file_replacements = f.read().splitlines()
        except (IOError, OSError) as e:
            pywikibot.error("Error loading {0}: {1}".format(replacement_file, e))
            return False

        if len(file_replacements) % 2:
            pywikibot.error("{0} contains an incomplete pattern replacement pair.".format(replacement_file))
            return False

        # Strip BOM from first line
        file_replacements[0].lstrip("\uFEFF")
        commandline_replacements.extend(file_replacements)

    if not (commandline_replacements or fixes_set) or manual_input:
        old = pywikibot.input("Please enter the text that should be replaced:")
        while old:
            new = pywikibot.input("Please enter the new text:")
            commandline_replacements += [old, new]
            old = pywikibot.input("Please enter another text that should be replaced," "\nor press Enter to start:")

    # The summary stored here won't be actually used but is only an example
    single_summary = None
    for i in range(0, len(commandline_replacements), 2):
        replacement = Replacement(commandline_replacements[i], commandline_replacements[i + 1])
        if not single_summary:
            single_summary = i18n.twtranslate(
                site, "replace-replacing", {"description": " (-%s +%s)" % (replacement.old, replacement.new)}
            )
        replacements.append(replacement)

    # Perform one of the predefined actions.
    missing_fixes_summaries = []  # which a fixes/replacements miss a summary
    for fix_name in fixes_set:
        try:
            fix = fixes.fixes[fix_name]
        except KeyError:
            pywikibot.output("Available predefined fixes are: %s" % ", ".join(fixes.fixes.keys()))
            if not fixes.user_fixes_loaded:
                pywikibot.output("The user fixes file could not be found: " "{0}".format(fixes.filename))
            return
        if not fix["replacements"]:
            pywikibot.warning("No replacements defined for fix " '"{0}"'.format(fix_name))
            continue
        if "msg" in fix:
            if isinstance(fix["msg"], basestring):
                set_summary = i18n.twtranslate(site, str(fix["msg"]))
            else:
                set_summary = i18n.translate(site, fix["msg"], fallback=True)
        else:
            set_summary = None
        replacement_set = ReplacementList(
            fix.get("regex"), fix.get("exceptions"), fix.get("nocase"), set_summary, name=fix_name
        )
        # Whether some replacements have a summary, if so only show which
        # have none, otherwise just mention the complete fix
        missing_fix_summaries = []
        for index, replacement in enumerate(fix["replacements"], start=1):
            summary = None if len(replacement) < 3 else replacement[2]
            if not set_summary and not summary:
                missing_fix_summaries.append('"{0}" (replacement #{1})'.format(fix_name, index))
            if chars.contains_invisible(replacement[0]):
                pywikibot.warning(
                    'The old string "{0}" contains formatting '
                    "characters like U+200E".format(chars.replace_invisible(replacement[0]))
                )
            if not callable(replacement[1]) and chars.contains_invisible(replacement[1]):
                pywikibot.warning(
                    'The new string "{0}" contains formatting '
                    "characters like U+200E".format(chars.replace_invisible(replacement[1]))
                )
            replacement_set.append(
                ReplacementListEntry(
                    old=replacement[0], new=replacement[1], fix_set=replacement_set, edit_summary=summary
                )
            )

        if replacement_set:
            replacements.extend(replacement_set)

        if len(fix["replacements"]) == len(missing_fix_summaries):
            missing_fixes_summaries.append('"{0}" (all replacements)'.format(fix_name))
        else:
            missing_fixes_summaries += missing_fix_summaries

    if (not edit_summary or edit_summary is True) and (missing_fixes_summaries or single_summary):
        if single_summary:
            pywikibot.output(
                "The summary message for the command line " "replacements will be something like: %s" % single_summary
            )
        if missing_fixes_summaries:
            pywikibot.output(
                "The summary will not be used when the fix has "
                "one defined but the following fix(es) do(es) not "
                "have a summary defined: "
                "{0}".format(", ".join(missing_fixes_summaries))
            )
        if edit_summary is not True:
            edit_summary = pywikibot.input(
                "Press Enter to use this automatic message, or enter a "
                "description of the\nchanges your bot will make:"
            )
        else:
            edit_summary = ""

    # Set the regular expression flags
    flags = re.UNICODE
    if caseInsensitive:
        flags = flags | re.IGNORECASE
    if dotall:
        flags = flags | re.DOTALL
    if multiline:
        flags = flags | re.MULTILINE

    # Pre-compile all regular expressions here to save time later
    for replacement in replacements:
        replacement.compile(regex, flags)

    precompile_exceptions(exceptions, regex, flags)

    if xmlFilename:
        try:
            xmlStart
        except NameError:
            xmlStart = None
        gen = XmlDumpReplacePageGenerator(xmlFilename, xmlStart, replacements, exceptions, site)
    elif useSql:
        whereClause = "WHERE (%s)" % " OR ".join(
            [
                "old_text RLIKE '%s'" % prepareRegexForMySQL(old_regexp.pattern)
                for (old_regexp, new_text) in replacements
            ]
        )
        if exceptions:
            exceptClause = "AND NOT (%s)" % " OR ".join(
                ["old_text RLIKE '%s'" % prepareRegexForMySQL(exc.pattern) for exc in exceptions]
            )
        else:
            exceptClause = ""
        query = """
SELECT page_namespace, page_title
FROM page
JOIN text ON (page_id = old_id)
%s
%s
LIMIT 200""" % (
            whereClause,
            exceptClause,
        )
        gen = pagegenerators.MySQLPageGenerator(query)

    gen = genFactory.getCombinedGenerator(gen)

    if not gen:
        pywikibot.bot.suggest_help(missing_generator=True)
        return False

    preloadingGen = pagegenerators.PreloadingGenerator(gen)
    bot = ReplaceRobot(
        preloadingGen,
        replacements,
        exceptions,
        allowoverlap,
        recursive,
        add_cat,
        sleep,
        edit_summary,
        always=acceptall,
        site=site,
    )
    site.login()
    bot.run()

    # Explicitly call pywikibot.stopme().
    # It will make sure the callback is triggered before replace.py is unloaded.
    pywikibot.stopme()
    pywikibot.output("\n%s pages changed." % bot.changed_pages)
Esempio n. 47
0
def translate(code, xdict, parameters=None, fallback=False):
    """Return the most appropriate translation from a translation dict.

    Given a language code and a dictionary, returns the dictionary's value for
    key 'code' if this key exists; otherwise tries to return a value for an
    alternative language that is most applicable to use on the wiki in
    language 'code' except fallback is False.

    The language itself is always checked first, then languages that
    have been defined to be alternatives, and finally English. If none of
    the options gives result, we just take the one language from xdict which may
    not be always the same. When fallback is iterable it'll return None if no
    code applies (instead of returning one).

    For PLURAL support have a look at the twtranslate method.

    @param code: The language code
    @type code: string or Site object
    @param xdict: dictionary with language codes as keys or extended dictionary
                  with family names as keys containing language dictionaries or
                  a single (unicode) string. May contain PLURAL tags as
                  described in twtranslate
    @type xdict: dict, string, unicode
    @param parameters: For passing (plural) parameters
    @type parameters: dict, string, unicode, int
    @param fallback: Try an alternate language code. If it's iterable it'll
        also try those entries and choose the first match.
    @type fallback: boolean or iterable
    @raise IndexError: If the language supports and requires more plurals than
        defined for the given translation template.
    """
    family = pywikibot.config.family
    # If a site is given instead of a code, use its language
    if hasattr(code, 'code'):
        family = code.family.name
        code = code.code

    # Check whether xdict has multiple projects
    if isinstance(xdict, dict):
        if family in xdict:
            xdict = xdict[family]
        elif 'wikipedia' in xdict:
            xdict = xdict['wikipedia']

    # Get the translated string
    if not isinstance(xdict, dict):
        trans = xdict
    elif not xdict:
        trans = None
    else:
        codes = [code]
        if fallback is True:
            codes += _altlang(code) + ['_default', 'en']
        elif fallback is not False:
            codes += list(fallback)
        for code in codes:
            if code in xdict:
                trans = xdict[code]
                break
        else:
            if fallback is not True:
                # this shouldn't simply return "any one" code but when fallback
                # was True before 65518573d2b0, it did just that. When False it
                # did just return None. It's now also returning None in the new
                # iterable mode.
                return
            code = list(xdict.keys())[0]
            trans = xdict[code]
    if trans is None:
        return  # return None if we have no translation found
    if parameters is None:
        return trans

    if not isinstance(parameters, Mapping):
        issue_deprecation_warning('parameters not being a mapping', None, 2)
        plural_parameters = _PluralMappingAlias(parameters)
    else:
        plural_parameters = parameters

    # else we check for PLURAL variants
    trans = _extract_plural(code, trans, plural_parameters)
    if parameters:
        try:
            return trans % parameters
        except (KeyError, TypeError):
            # parameter is for PLURAL variants only, don't change the string
            pass
    return trans
Esempio n. 48
0
def twtranslate(source, twtitle, parameters=None, fallback=True,
                only_plural=False):
    """
    Translate a message using JSON files in messages_package_name.

    fallback parameter must be True for i18n and False for L10N or testing
    purposes.

    Support for plural is implemented like in MediaWiki extension. If the
    TranslateWiki message contains a plural tag inside which looks like::

        {{PLURAL:<number>|<variant1>|<variant2>[|<variantn>]}}

    it takes that variant calculated by the plural_rules depending on the number
    value. Multiple plurals are allowed.

    As an examples, if we had several json dictionaries in test folder like:

    en.json::

      {
          "test-plural": "Bot: Changing %(num)s {{PLURAL:%(num)d|page|pages}}.",
      }

    fr.json::

      {
          "test-plural": "Robot: Changer %(descr)s {{PLURAL:num|une page|quelques pages}}.",
      }

    and so on.

    >>> from pywikibot import i18n
    >>> i18n.set_messages_package('tests.i18n')
    >>> # use a dictionary
    >>> str(i18n.twtranslate('en', 'test-plural', {'num':2}))
    'Bot: Changing 2 pages.'
    >>> # use additional format strings
    >>> str(i18n.twtranslate('fr', 'test-plural', {'num': 1, 'descr': 'seulement'}))
    'Robot: Changer seulement une page.'
    >>> # use format strings also outside
    >>> str(i18n.twtranslate('fr', 'test-plural', {'num': 10}, only_plural=True)
    ...     % {'descr': 'seulement'})
    'Robot: Changer seulement quelques pages.'

    @param source: When it's a site it's using the lang attribute and otherwise
        it is using the value directly.
    @type source: BaseSite or str
    @param twtitle: The TranslateWiki string title, in <package>-<key> format
    @param parameters: For passing parameters. It should be a mapping but for
        backwards compatibility can also be a list, tuple or a single value.
        They are also used for plural entries in which case they must be a
        Mapping and will cause a TypeError otherwise.
    @param fallback: Try an alternate language code
    @type fallback: boolean
    @param only_plural: Define whether the parameters should be only applied to
        plural instances. If this is False it will apply the parameters also
        to the resulting string. If this is True the placeholders must be
        manually applied afterwards.
    @type only_plural: bool
    @raise IndexError: If the language supports and requires more plurals than
        defined for the given translation template.
    """
    if not messages_available():
        raise TranslationError(
            'Unable to load messages package %s for bundle %s'
            '\nIt can happen due to lack of i18n submodule or files. '
            'Read %s/i18n'
            % (_messages_package_name, twtitle, __url__))

    source_needed = False
    # If a site is given instead of a lang, use its language
    if hasattr(source, 'lang'):
        lang = source.lang
    # check whether we need the language code back
    elif isinstance(source, list):
        # For backwards compatibility still support lists, when twntranslate
        # was not deprecated and needed a way to get the used language code back
        warn('The source argument should not be a list but either a BaseSite '
             'or a str/unicode.', DeprecationWarning, 2)
        lang = source.pop()
        source_needed = True
    else:
        lang = source

    # There are two possible failure modes: the translation dict might not have
    # the language altogether, or a specific key could be untranslated. Both
    # modes are caught with the KeyError.
    langs = [lang]
    if fallback:
        langs += _altlang(lang) + ['en']
    for alt in langs:
        trans = _get_translation(alt, twtitle)
        if trans:
            break
    else:
        raise TranslationError(
            'No %s translation has been defined for TranslateWiki key'
            ' %r\nIt can happen due to lack of i18n submodule or files. '
            'Read https://mediawiki.org/wiki/PWB/i18n'
            % ('English' if 'en' in langs else "'%s'" % lang,
               twtitle))
    # send the language code back via the given mutable list parameter
    if source_needed:
        source.append(alt)

    if '{{PLURAL:' in trans:
        # _extract_plural supports in theory non-mappings, but they are
        # deprecated
        if not isinstance(parameters, Mapping):
            raise TypeError('parameters must be a mapping.')
        trans = _extract_plural(alt, trans, parameters)

    # this is only the case when called in twntranslate, and that didn't apply
    # parameters when it wasn't a dict
    if isinstance(parameters, _PluralMappingAlias):
        # This is called due to the old twntranslate function which ignored
        # KeyError. Instead only_plural should be used.
        if isinstance(parameters.source, dict):
            try:
                trans %= parameters.source
            except KeyError:
                pass
        parameters = None

    if parameters is not None and not isinstance(parameters, Mapping):
        issue_deprecation_warning('parameters not being a Mapping', None, 2)

    if not only_plural and parameters:
        return trans % parameters
    else:
        return trans
Esempio n. 49
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    for arg in pywikibot.handle_args(args):
        arg, sep, val = arg.partition(':')
        if arg == '-edit':
            globalvar.attachEditCount = int(val or pywikibot.input(
                'After how many edits would you like to welcome new users? '
                '(0 is allowed)'))
        elif arg == '-timeoffset':
            globalvar.timeoffset = int(val or pywikibot.input(
                'Which time offset (in minutes) for new users would you like '
                'to use?'))
        elif arg == '-time':
            globalvar.timeRecur = int(val or pywikibot.input(
                'For how many seconds would you like to bot to sleep before '
                'checking again?'))
        elif arg == '-offset':
            if not val:
                val = pywikibot.input(
                    'Which time offset for new users would you like to use? '
                    '(yyyymmddhhmmss)')
            try:
                globalvar.offset = pywikibot.Timestamp.fromtimestampformat(val)
            except ValueError:
                # upon request, we might want to check for software version here
                raise ValueError(
                    "Mediawiki has changed, -offset:# is not supported "
                    "anymore, but -offset:TIMESTAMP is, assuming TIMESTAMP "
                    "is yyyymmddhhmmss. -timeoffset is now also supported. "
                    "Please read this script source header for documentation.")
        elif arg == '-file':
            globalvar.randomSign = True
            globalvar.signFileName = val or pywikibot.input(
                'Where have you saved your signatures?')
        elif arg == '-sign':
            globalvar.defaultSign = val or pywikibot.input(
                'Which signature to use?')
            globalvar.defaultSign += timeselected
        elif arg == '-break':
            globalvar.recursive = False
        elif arg == '-nlog':
            globalvar.makeWelcomeLog = False
        elif arg == '-ask':
            globalvar.confirm = True
        elif arg == '-filter':
            globalvar.filtBadName = True
        elif arg == '-savedata':
            globalvar.saveSignIndex = True
        elif arg == '-random':
            globalvar.randomSign = True
        elif arg == '-sul':
            globalvar.welcomeAuto = True
        elif arg == '-limit':
            globalvar.queryLimit = int(val or pywikibot.input(
                u'How many of the latest new users would you like to load?'))
        elif arg == '-numberlog':
            globalvar.dumpToLog = int(val or pywikibot.input(
                'After how many welcomed users would you like to update the '
                'welcome log?'))
        elif arg == '-quiet':
            globalvar.quiet = True
        elif arg == '-quick':
            issue_deprecation_warning('The usage of "-quick" option', None, 2)

    # Filename and Pywikibot path
    # file where is stored the random signature index
    filename = pywikibot.config.datafilepath('welcome-%s-%s.data'
                                             % (pywikibot.Site().family.name,
                                                pywikibot.Site().code))
    if globalvar.offset and globalvar.timeoffset:
        pywikibot.warning(
            'both -offset and -timeoffset were provided, ignoring -offset')
        globalvar.offset = 0

    try:
        bot = WelcomeBot()
    except KeyError as error:
        # site not managed by welcome.py
        pywikibot.bot.suggest_help(exception=error)
        return False

    try:
        bot.run()
    except KeyboardInterrupt:
        if bot.welcomed_users:
            showStatus()
            pywikibot.output("Put welcomed users before quit...")
            bot.makelogpage(bot.welcomed_users)
        pywikibot.output("\nQuitting...")
    finally:
        # If there is the savedata, the script must save the number_user.
        if globalvar.randomSign and globalvar.saveSignIndex and \
           bot.welcomed_users:
            if sys.version_info[0] > 2:
                import pickle as cPickle
            else:
                import cPickle
            with open(filename, 'wb') as f:
                cPickle.dump(bot.welcomed_users, f, protocol=config.pickle_protocol)
Esempio n. 50
0
def main(*args):
    """
    Process command line arguments and invoke bot.

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

    @param args: command line arguments
    @type args: list of unicode
    """
    index = None
    pages = '1-'
    options = {}

    # Parse command line arguments.
    local_args = pywikibot.handle_args(args)
    for arg in local_args:
        arg, sep, value = arg.partition(':')
        if arg == '-index':
            index = value
        elif arg == '-pages':
            pages = value
        elif arg == '-showdiff':
            issue_deprecation_warning('The usage of -showdiff option', None, 0)
        elif arg == '-summary':
            options['summary'] = value
        elif arg == '-force':
            issue_deprecation_warning('The usage of -force option', None, 0)
        elif arg == '-always':
            options['always'] = True
        else:
            pywikibot.output('Unknown argument %s' % arg)

    # index is mandatory.
    if not index:
        pywikibot.bot.suggest_help(missing_parameters=['-index'])
        return False

    site = pywikibot.Site()
    if not site.has_extension('ProofreadPage'):
        pywikibot.error('Site %s must have ProofreadPage extension.' % site)
        return False

    index = IndexPage(site, index)

    if not index.exists():
        pywikibot.error("Page %s doesn't exist." % index)
        return False

    # Parse pages param.
    # Create a list of (start, end) tuples.
    pages = pages.split(',')
    for interval in range(len(pages)):
        start, sep, end = pages[interval].partition('-')
        start = 1 if not start else int(start)
        if not sep:
            end = start
        else:
            end = int(end) if end else index.num_pages
        pages[interval] = (start, end)

    gen_list = []
    for start, end in sorted(pages):
        gen = index.page_gen(start=start, end=end,
                             filter_ql=[1], content=False)
        gen_list.append(gen)

    gen = itertools.chain(*gen_list)

    pywikibot.output('\nUploading text to %s\n' % index.title(asLink=True))

    bot = UploadTextBot(gen, site=index.site, **options)
    bot.run()