Участник:BsivkoBot/Перевести

Описание

Мотивация

Для читателей Википедии, как и для писателей, существует шаблон {{перевести}}, показывающий, что в соседнем языковом разделе существует более полная статья. Первые его могут использовать для того, чтобы например обратить на неё внимание, перейти и получить более полную информацию о предмете, например с помощью автоматизированного переводчика. Вторые используют навигацию по подобному шаблону, позволяющего найти статьи, которые могут быть улучшены с помощью перевода с конкретного языка. Помимо этого, пистали могут обратить внимание для дополнения статьи во время работы над её текстом. Очевидно, что шаблон проставляется в случаях, когда статья в русскоязычном разделе небольшая, а в другом разделе она значительно превосходит по объёму. Соответственно, сравнив объемы можно попробовать установить факт соотношения и необходимости перевода.

Формализовать подобный процесс понятно чрезвычайно сложно, но можно проставить такие параметры выбора, что статья практически наверняка попадёт в описываемую категорию. Соответственно, подобная задача ставится боту — простановка шаблона {{перевести}} тогда, когда случаи явны.

Реализация

Бот обращает внимание только на статьи, которые больше 500 байт по объему и менее 20 000 байт. Таким образом, если статья в русскоязычном разделе уже занимает 20 000 байт, то бот считает её достаточно полной и без участника уже не берётся.

Бот перебирает наиболее полные разделы проекта (так как технически этот список лучше ограничить). В этот перечень входят английский, шведский, немецкий, итальянский, испанский, португальнский, японский, китайский, французский, нидерландский, варайский, вьетнамский разделы проекта (см. список по объёму наполнения). Объём в байтах зависит от языка, так как например, один символ кириллицы занимает 2 байта, в то время как латиницы 1 байт. Поэтому для каждого из языков введён фактор, умножающий объём при оценке. В первом приближении япоский, китайский и вьетнамский разделы сравниваются как 1 к 1, а другие разделы с умножением в 1.5 раза. Далее, после умножения находится максимальный объем из перечисленных разделов, и если он более чем в 8 раз превышает объем русскоязычной статьи, то проставляется шаблон {{перевести}} на соответствующий языковой раздел.

Во время расчёта иноязычной статьи считается размер текста без шаблонов, так как могут быть статьи с большим количеством вики-технической информации. Для этого оценивается число байт в шаблонах (любых) и кроме них. Если текста , менее 20%, то такие статьи к оценке боту не допускаются.

Страницы с шаблоном {{неоднозначность}} игнорируются.

Шаблон проставляется в конец статьи перед категориями.

Исходный код

import mwparserfromhell
import pywikibot

from external_sources.add import add_template_to_end_before_categories
from wiki_requests.get_wikidata import get_sitelinks_dictionary
from wiki_template_processing.template_collector import template_or_its_redirect_is_present

TASK_DESCRIPTION_TO_TRANSLATE = u"перевести"

MIN_TEXT_SIZE = 500
MAX_TEXT_SIZE = 20000
BIGGER_IN_TIMES = 8

TEXT_PERCENTAGE_REQUIRED = 0.2

TRANSLATE_LANGUAGES_TO_CHECK = [
    {
        "id": "en",
        "mult_factor": 1.5
    },
    {
        "id": "sv",
        "mult_factor": 1.5
    },
    {
        "id": "de",
        "mult_factor": 1.5
    },
    {
        "id": "fr",
        "mult_factor": 1.5
    },
    {
        "id": "it",
        "mult_factor": 1.5
    },
    {
        "id": "nl",
        "mult_factor": 1.5
    },
    {
        "id": "es",
        "mult_factor": 1.5
    },
    {
        "id": "pl",
        "mult_factor": 1.5
    },
    {
        "id": "war",
        "mult_factor": 1.5
    },
    {
        "id": "vi",
        "mult_factor": 1
    },
    {
        "id": "ja",
        "mult_factor": 1
    },
    {
        "id": "zh",
        "mult_factor": 1
    },
    {
        "id": "pt",
        "mult_factor": 1.5
    }
]

sites_cached = {}


def text_percentage_access(text):

    parsed = mwparserfromhell.parse(text)

    template_length = 0

    for template in parsed.ifilter_templates():
        template_length += len(str(template))

    return 1 - (template_length + 0.0) / len(text)


def get_site_by_language(language):
    global sites

    if language in sites_cached:
        return sites_cached[language]

    sites_cached[language] = pywikibot.Site(language, 'wikipedia')

    return sites_cached[language]


def get_size_of_page(language, title):
    result = {}
    result['language'] = language

    site = get_site_by_language(language)
    page = pywikibot.Page(site, title)

    result['size'] = len(page.text)
    result['title'] = title
    result['percent'] = text_percentage_access(page.text)

    return result


def get_sitelinks_from_wikidata(title):
    sitelinks = get_sitelinks_dictionary("ru", title)

    if sitelinks is None:
        return None

    return sitelinks


def get_maximum_external_language_pages(title):
    max_size = 0
    result = None

    sitelinks = get_sitelinks_from_wikidata(title)

    for i in TRANSLATE_LANGUAGES_TO_CHECK:
        key = i['id'] + "wiki"
        if key in sitelinks:
            r = get_size_of_page(i['id'], sitelinks[key])

            if r['percent'] < TEXT_PERCENTAGE_REQUIRED:
                continue

            r['size'] *= i['mult_factor']

            if r['size'] > max_size:
                max_size = r['size']
                result = r

    return result


def add_to_translate(text, title):
    if len(text) < MIN_TEXT_SIZE:
        return text

    if len(text) > MAX_TEXT_SIZE:
        return text

    if template_or_its_redirect_is_present(text, "перевести"):
        return text

    if template_or_its_redirect_is_present(text, "неоднозначность"):
        return text

    max_founded = get_maximum_external_language_pages(title)
    if max_founded is None:
        return text
    if max_founded['size'] > len(text) * BIGGER_IN_TIMES:
        return add_template_to_end_before_categories(text, "{{перевести|" + max_founded['language'] + "|" + max_founded[
            'title'] + "}}")

    return text

Тестирование

import pywikibot

from to_translate.add_to_translate import add_to_translate, get_site_by_language, text_percentage_access


def test_add_to_translate():

    assert add_to_translate("text", "title") == "text"

    pass


def test_get_maximum_external_language_pages():

    site = get_site_by_language("fr")
    page = pywikibot.Page(site, 'Peptide C')
    x = text_percentage_access(page.text)

    assert text_percentage_access("{{text|a=1}} text") < 0.3

    pass

Состояние и развитие

  • Первые запуски. Bsivko (обс.) 19:41, 1 июля 2019 (UTC)
  • Коэф. увеличенс 7 до 8. Добавлена проверка на содержание текста. Например, статья содержит менее 1% по её оценке и не должна попадать в категорию для перевода. После эмпирических исследований установлена планка в 20%. Bsivko (обс.) 15:37, 2 июля 2019 (UTC)
  • Отключен. Bsivko (обс.) 08:01, 26 апреля 2020 (UTC)

Обсуждение