Пример #1
0
def get_text(page: pywikibot.page.BasePage, old: Optional[str],
             create: bool) -> str:
    """
    Get text on page. If old is not None, return old.

    :param page: The page to get text from
    :param old: If not None, return this rather than the page's text
    :param create: Declare that the page will be created if it doesn't exist
    :return: The page's text or the old parameter if not None
    """
    if old is not None:
        return old

    try:
        return page.get()
    except NoPageError:
        if create:
            pywikibot.output("{} doesn't exist, creating it!"
                             .format(page.title()))
            return ''
        else:
            pywikibot.output("{} doesn't exist, skip!".format(page.title()))
            return None
    except IsRedirectPageError:
        pywikibot.output('{} is a redirect, skip!'.format(page.title()))
        return None
def get_article_quality(page: pywikibot.page.BasePage) -> str:
    """Gets the content assement class from a wikiproject template"""
    if not page.isTalkPage():
        page = page.toggleTalkPage()

    classes = []
    valid_classes = {
        "fa": 1,
        "fl": 1,
        "a": 2,
        "ga": 3,
        "b": 4,
        "c": 5,
        "start": 6,
        "stub": 7,
        "list": 8,
        "draft": 8,
    }
    for value in page.templatesWithParams():
        for para in value[1]:
            key, sep, value = para.partition("=")
            if sep and key.lower() == "class" and value.lower(
            ) in valid_classes:
                classes.append(value.lower())

    classes = sorted(classes, key=valid_classes.__getitem__)
    if classes:
        return classes[0]
    else:
        return "unassessed"
def check_can_run(page: pywikibot.page.BasePage) -> bool:
    """Determinies if the bot should run on this page and returns a bool."""

    if ((page.title() in skip) or (not page.has_permission("edit"))
            or (not page.botMayEdit())
            or (not re.search("{{[iI][nN]aturalist[rR]eview}}", page.text))):
        return False
    else:
        return True
def get_article_metadata(page: pywikibot.page.BasePage) -> Article:
    """Returns article creator and content assesment class as a NamedTuple"""
    return Article(
        title=page.title(),
        quality=get_article_quality(page),
        author=page.oldest_revision.user,
    )
def fail_warning(page: pywikibot.page.BasePage,
                 review_license: str,
                 is_old: bool = False) -> None:
    user_talk = get_author_talk(page)
    message = string.Template(config["old_fail_warn"] if is_old else
                              config["fail_warn"]).safe_substitute(
                                  filename=page.title(with_ns=True),
                                  review_license=review_license)
    summary = string.Template(config["review_summary"]).safe_substitute(
        status="fail", review_license=review_license, version=__version__)
    if not simulate:
        utils.check_runpage(site, run_override)
        logger.info(f"Saving {user_talk.title()}")
        utils.retry(
            utils.save_page,
            3,
            text=message,
            page=user_talk,
            summary=summary,
            bot=False,
            minor=False,
            mode="append",
        )
    else:
        logger.info("Saving disabled")
        logger.info(summary)
        logger.info(message)
def find_com_license(page: pywikibot.page.BasePage) -> str:
    """Find the license template currently used on the Commons page

    Returns the first license template used on the page. If no templates
    are found, return an empty string.
    """
    category = pywikibot.Category(site,
                                  "Category:Primary license tags (flat list)")

    for template in page.itertemplates():
        if template in category.members(namespaces=10):
            return template.title(with_ns=False)
    else:
        return ""
def find_ina_id(
    page: pywikibot.page.BasePage,
) -> Tuple[Optional[iNaturalistID], Optional[iNaturalistID]]:
    """Returns an iNaturalistID tuple from wikitext"""
    photos = set()
    observations = set()
    for url in page.extlinks():
        url_id = parse_ina_url(url)
        if url_id is None:
            continue
        elif url_id.type == "observations":
            observations.add(url_id)
        elif url_id.type == "photos":
            photos.add(url_id)

    if photos and observations:
        return observations.pop(), photos.pop()
    elif observations:
        return observations.pop(), None
    elif photos:
        return None, photos.pop()
    else:
        return None, None
Пример #8
0
def put_text(page: pywikibot.page.BasePage, new: str, summary: str, count: int,
             asynchronous: bool = False) -> Optional[bool]:
    """
    Save the new text.

    :param page: The page to change the text of
    :param new: The new text for the page
    :param summary: Summary of the page change
    :param count: Maximum number of attempts to reach the server
    :param asynchronous: If True, saves the page asynchronously
    :return: True if successful, False if unsuccessful, and None if
        awaiting the server
    """
    page.text = new
    try:
        page.save(summary=summary, asynchronous=asynchronous,
                  minor=page.namespace() != 3)
    except EditConflictError:
        pywikibot.output('Edit conflict! skip!')
    except ServerError:
        if count <= config.max_retries:
            pywikibot.output('Server Error! Wait..')
            pywikibot.sleep(config.retry_wait)
            return None
        raise ServerError(
            'Server Error! Maximum retries exceeded')
    except SpamblacklistError as e:
        pywikibot.output(
            'Cannot change {} because of blacklist entry {}'
            .format(page.title(), e.url))
    except LockedPageError:
        pywikibot.output('Skipping {} (locked page)'.format(page.title()))
    except PageSaveRelatedError as error:
        pywikibot.output('Error putting page: {}'.format(error.args))
    else:
        return True
    return False
Пример #9
0
def add_text(page: pywikibot.page.BasePage, addText: str,
             summary: Optional[str] = None,
             regexSkip: Optional[str] = None,
             regexSkipUrl: Optional[str] = None,
             always: bool = False, up: bool = False,
             putText: bool = True, oldTextGiven: Optional[str] = None,
             reorderEnabled: bool = True, create: bool = False
             ) -> Union[Tuple[bool, bool, bool], Tuple[str, str, bool]]:
    """
    Add text to a page.

    :param page: The page to add text to
    :param addText: Text to add
    :param summary: Change summary, if None this uses the beginning of addText
    :param regexSkip: Abort if the text on the page matches this
    :param regexSkipUrl: Abort if the url matches this
    :param always: Edit without user confirmation
    :param up: Append text to the top of the page if True, otherwise the
        bottom
    :param putText: Save changes to the page if True, otherwise return
        (text, newtext, always)
    :param oldTextGiven: If None fetch page text, else use this text
    :param reorderEnabled: If True place text above categories and
        interwiki, else place at page bottom. No effect if up = False.
    :param create: Create the page if it does not exist
    :return: (success, success, always) if putText is True, otherwise
        (text, newtext, always)
    """
    site = page.site
    if not summary:
        summary = i18n.twtranslate(site, 'add_text-adding',
                                   {'adding': addText[:200]})
    if putText:
        pywikibot.output('Loading {}...'.format(page.title()))

    text = get_text(page, oldTextGiven, create)
    if text is None:
        return (False, False, always)

    # Understand if the bot has to skip the page or not
    # In this way you can use both -except and -excepturl
    if regexSkipUrl is not None:
        url = page.full_url()
        result = re.findall(regexSkipUrl, site.getUrl(url))
        if result != []:
            pywikibot.output(
                'Exception! regex (or word) used with -exceptUrl '
                'is in the page. Skip!\n'
                'Match was: {}'.format(result))
            return (False, False, always)
    if regexSkip is not None:
        result = re.findall(regexSkip, text)
        if result != []:
            pywikibot.output(
                'Exception! regex (or word) used with -except '
                'is in the page. Skip!\n'
                'Match was: {}'.format(result))
            return (False, False, always)
    # If not up, text put below
    if not up:
        newtext = text
        # Translating the \\n into binary \n
        addText = addText.replace('\\n', '\n')
        if reorderEnabled:
            # Getting the categories
            categoriesInside = textlib.getCategoryLinks(newtext, site)
            # Deleting the categories
            newtext = textlib.removeCategoryLinks(newtext, site)
            # Getting the interwiki
            interwikiInside = textlib.getLanguageLinks(newtext, site)
            # Removing the interwiki
            newtext = textlib.removeLanguageLinks(newtext, site)

            # Adding the text
            newtext += '\n' + addText
            # Reputting the categories
            newtext = textlib.replaceCategoryLinks(newtext,
                                                   categoriesInside, site,
                                                   True)
            # Adding the interwiki
            newtext = textlib.replaceLanguageLinks(newtext, interwikiInside,
                                                   site)
        else:
            newtext += '\n' + addText
    else:
        newtext = addText + '\n' + text

    if not putText:
        # If someone load it as module, maybe it's not so useful to put the
        # text in the page
        return (text, newtext, always)

    if text != newtext:
        pywikibot.output(color_format(
            '\n\n>>> {lightpurple}{0}{default} <<<', page.title()))
        pywikibot.showDiff(text, newtext)

    # Let's put the changes.
    error_count = 0
    while True:
        if not always:
            try:
                choice = pywikibot.input_choice(
                    'Do you want to accept these changes?',
                    [('Yes', 'y'), ('No', 'n'), ('All', 'a'),
                     ('open in Browser', 'b')], 'n')
            except QuitKeyboardInterrupt:
                sys.exit('User quit bot run.')

            if choice == 'a':
                always = True
            elif choice == 'n':
                return (False, False, always)
            elif choice == 'b':
                pywikibot.bot.open_webbrowser(page)
                continue

        # either always or choice == 'y' is selected
        result = put_text(page, newtext, summary, error_count,
                          asynchronous=not always)
        if result is not None:
            return (result, result, always)
        error_count += 1