Участник:AJZBot/Код: различия между версиями
Перейти к навигации
Перейти к поиску
Содержимое удалено Содержимое добавлено
→Код: print -> wikipedia.output |
Putnik (обсуждение | вклад) →Код: fix: при повторной проверке не заменялся текст замечаний |
||
Строка 451: | Строка 451: | ||
#77 = 26 + 51, где 26 - длина строки 'AJZBot/Завершающая фраза}}' |
#77 = 26 + 51, где 26 - длина строки 'AJZBot/Завершающая фраза}}' |
||
#а 51 - длина подписи бота |
#а 51 - длина подписи бота |
||
self.TalkPageText.replace(self.TalkPageText[(ReqStart):(ReqFinish+77)],\ |
self.TalkPageText = self.TalkPageText.replace(self.TalkPageText[(ReqStart):(ReqFinish+77)],\ |
||
self.ReqText) |
self.ReqText) |
||
else: |
else: |
Версия от 02:49, 28 июля 2012
Бот использует следующие служебные страницы в качестве шаблонов:
- Участник:AJZBot/Вводная фраза
- Участник:AJZBot/Нет категорий
- Участник:AJZBot/Недостаточная категоризация
- Участник:AJZBot/Желательны сноски
- Участник:AJZBot/Тег br
- Участник:AJZBot/Привязка ко времени
- Участник:AJZBot/Привязка к государству
- Участник:AJZBot/Украина
- Участник:AJZBot/Проблемы с файлами
- Участник:AJZBot/Стиль
- Участник:AJZBot/Нет внутренних ссылок
- Участник:AJZBot/Стаб
- Участник:AJZBot/Найдена подпись
- Участник:AJZBot/Нейтральность
- Участник:AJZBot/Неправильные ссылки
- Участник:AJZBot/Завершающая фраза
Ниже приведён снабжённый комментариями исполняемый код бота. Если у вас есть замечания, предложения по улучшению или исправлению кода, вопросы или любая другая причина вступить в контакт с ботовладельцем, обращайтесь сюда. Любый изменения этой страницы никак не повлияют на работу бота, так как здесь представлена копия кода, а не сам код. Правьте эту страницу, конструктивные улучшения будут учтены при дальнейшем развитии бота.
Код
# -*- coding: cp1251 -*-
import add_text, wikipedia, catlib
#список фраз, привязывающих статью к настоящему времени
TimeList = [u'в настоящее время',u'в наши дни',u'в прошлом году',\
u'в следующем году', u'недавно',u'скоро',u'с тех пор',\
u'на сегодняшний день',u'на данный момент',u'наши дни']
#список ненейтральных слов и выражений
StyleList = [u'уникальн',u'замечательн',u'превосходн',u'божественн',\
u'великолепн',u'эксклюзивн',u'восхитительн',u'изумительн',\
u'безупречн',u'лучш',u'ведущ',u'авторитетн',\
u'популярн',u'престижн',u'уважаем',u'велик',\
u'огромн',u'эффективн',u'крупнейш',u'отвратительн',\
u'кошмарн',u'безоразн',u'успешн',u'мастерств',\
u'феноменальн',u'знаменит',u'виртуозн',u'мастерск',\
u'выдающ',u'самоотвержен',u'талантливейш',\
u'жаждущ',u'гениальн',u'колоссальн',u'высококачеств',\
u'долгожданн',u'исключительн',u'беззаветн',u'ошеломительн',\
u'богатый опыт',u'неповторим',u'долгожданн']
#список фраз, указывающих на территориальную принадлежность читателя
OutLandList = [u'за рубежом',u'зарубежом',u'зарубежн', u'отечествен', \
u'за бугром',u'забугорн']
#список всевозможных ссылок на действующие правила о значимости
#по-моему тут люди немного перестарались
NatabilityLinks = [u'[[ВП:ПОЛИТИКИ',u'[[ВП:СПОРТСМЕНЫ',u'[[ВП:КЗМ', \
u'[[ВП:МУЗЫКАНТЫ',u'[[ВП:ПИСАТЕЛИ',u'[[ВП:АКТЕРЫ', \
u'[[ВП:АРТИСТЫ',u'[[ВП:КЗДИ',u'[[Википедия:Значимость', \
u'[[Википедия:Критерии значимости персоналий', \
u'[[Википедия:Критерии значимости веб-сайтов', \
u'[[Википедия:Кавалеры высших наград государства', \
u'[[Википедия:Критерии значимости программ', \
u'[[Википедия:Критерии значимости футболистов', \
u'[[Википедия:Критерии значимости аниме и манги', \
u'[[Википедия:Списки',u'[[ВП:КЗЖ',u'[[ВП:УЧ', \
u'[[ВП:УЧЕНЫЕ',u'[[ВП:РД',u'[[ВП:НЯ', \
u'[[ВП:КЗПУ',u'[[ВП:ВОЕННЫЕ',u'[[ВП:БИЗ', \
u'[[ВП:ЗН',u'[[ВП:КЗ',u'[[ВП:ОКЗ',u'[[ВП:НЕНОВОСТИ', \
u'[[ВП:ВЕБ',u'[[ВП:КЗС',u'[[ВП:КЗВС', \
u'[[ВП:ЗП',u'[[ВП:СОФТ',u'[[ВП:МТЗП',u'[[ВП:ФУТ', \
u'[[ВП:ВНГ',u'[[ВП:С',u'[[ВП:СПИСКИ',u'[[ВП:ИНФСП', \
u'|anime',u'|bio',u'|okz',u'|org',u'|po', \
u'[[ВП:КОСП',u'|notability',u'|nb=0']
#список комбинаций символов, которые однозначно указывают на проблемы
#с изображением
ImageProblemTemplate = [u'{{speedydelete',u'{{delete', \
u'{{template deletion request',u'{{no ', \
u'{{speedydelete',u'{{изображение/нет ', \
u'{{disputed',u'{{db-',u'{{к удалению', \
u'remove this line and insert a license instead']
#то, что нужно вырезать перед проверкой
ArtifactList = [u'[[Википедия:Сноски]]', \
u'примеры использования тэгов <ref></ref>', \
u'[[:Категория вместо [[Категория',u'[[en:название статьи]]', \
u'[[файл:Example.jpg]]',u'[[:Категория:]]',u'[[:en:]]']
class TRequirement:
def __Init__(self, page):
#страница
self.Page = page
#страница обсуждения страницы Page
self.TalkPage = page.toggleTalkPage()
#текст замечания
self.ReqText = ''
#текст отчёта о проверке
self.Report = u'== Отчёт о проведённой проверке ==\n'
#текст страницы обсуждения статьи
self.TalkPageText = ''
#True, если в статье есть шаблон {{редактирую}}
self.InWork = False
#True, если найдены недочёты
self.NeedRequirement = False
#True, если нет категорий
self.NoCategory = False
#True, если нужно уточнить категории
self.OneCategory = False
#True, если в тексте нет ни одной внутренней ссылки
self.NotWikifyed = False
#Длина (размер) статьи
self.Length = 0
#True, если статья очень маленькая
self.Stub = False
#True, если есть теги <br>
self.HasBr = False
#True, если нет сносок
self.Refless = False
#True, если статья подписана
self.Signed = False
#True, если статья привязана к времени
self.Temporal = False
#количество плохих слов в статье
self.Epithet = 0
#True, если есть фразы, указывающие на территориальную принадлежность читателя
self.OutLand = False
#True, если есть пробелы в начале строки
self.HasSpace = False
#True, если есть пробелы с изображениями
self.BadImage = False
#True, если есть неправильно оформленные ссылки
self.BadLink = False
#True, если есть "в Украине"
self.InUkraine = False
#определяет, нужно ли писать замечания
def Need(self):
if ((self.NoCategory or self.NotWikifyed or self.Stub or self.HasBr or \
self.Refless or self.Signed or (self.Epithet > 2) or self.Temporal \
or self.HasSpace or self.OutLand or self.BadImage or self.BadLink or \
self.InUkraine or self.OneCategory)
and not self.InWork):
nnn = True
else:
nnn = False
return nnn
#проверяет статью
def CheckPage(self):
#проверяет статью, если она существует
if self.Page.exists():
pagetext = self.Page.get()
#вырезает артефакты шаблонной страницы, могущих исказать
#результаты проверки
for art in ArtifactList:
pagetext = pagetext.replace(art,'')
#если есть шаблон {{редактирую}}, то статья вообще не проверяется
self.InWork = (pagetext.find(u'{{редактирую|') != -1)
#проверяет размер (длину) статьи, если он меньше 1000, то Stub становится True
self.Length=len(pagetext)+1
if self.Length < 1000:
self.Stub = True
self.Report += u'* Длина статьи: '+str(self.Length)+\
u'. Статья оценена как короткая.\n'
else:
self.Report += u'* Длина статьи: '+str(self.Length)+\
u'. Размер статьи достаточен.\n'
#проверяет наличие ссылок вида http://ru.wikipedia.org/...
search = pagetext.find(u'http://ru.wikipedia.org/')
if search != -1:
self.BadLink = True
self.Report += u'* Найдены неформатные ссылки. Количество:'+\
str(pagetext.count(u'http://ru.wikipedia.org/'))+\
u'. Первое вхождение начинается с символа '+str(search)+u'.\n'
else:
self.Report += u'* Неформатные ссылки не найдены.\n'
#проверяет, есть ли в статье категории, если нет, то NoCategory
#становится True
if pagetext.find(u'Категория:') == -1:
self.NoCategory = True
self.Report += u'* Категории не найдены.\n'
else:
self.Report += u'* Статья категоризована.\n'
#Проверяет, есть ли в статье категория Персоналии по алфавиту
#Если она есть и других категорий нет, то OneCategory становится True
if not self.NoCategory:
if pagetext.find(u'[[Категория:Персоналии по алфавиту]]') != -1:
pagetext.replace(u'[[Категория:Персоналии по алфавиту]]',u'')
if pagetext.find(u'Категория:') == -1:
self.OneCategory = True
self.Report += u'* Категоризация статьи недостаточна.\n'
else:
self.Report += u'* Предположительно, категоризация статьи достаточна.\n'
else:
self.Report += u'* Предположительно, категоризация статьи достаточна.\n'
#проверяет наличие тегов br, если они есть, то HasBr становится True
#считаем количество тегов
search = pagetext.count(u'<br/>') + pagetext.count(u'<br>') +\
pagetext.count(u'<br />')
if search != 0:
self.HasBr = True
self.Report += u'* Теги br присутствуют. Всего их '+str(search)+u'.\n'
else:
self.Report += u'* Теги br не найдены.\n'
#проверяет наличие сносок, если их нет, то Refless становится True
if pagetext.find(u'<ref') == -1 and pagetext.find(u'{{sfn|}}') == -1:
self.Refless = True
self.Report += u'* Сносок нет.\n'
else:
self.Report += u'* Сноски есть.\n'
#проверяет наличие подписи в самой статье, если она есть, то Signed
#становится True
search = pagetext.find(u'[[Участник:')
if search == -1:
search = pagetext.find(u'[[User:')
if search != -1:
self.Signed = True
self.Report += u'* В статье найдена подпись. Начинается с символа '+\
+u'номер '+str(search)+u'.\n'
else:
self.Report += u'* В статье не найдена подпись.\n'
#проверяет наличие пробелов в начале строки, если они есть, то HasSpace
#становится True
#???
#составляет список изображений в статье
ImageList = self.Page.imagelinks()
if ImageList != []:
self.Report += u'* В статье есть иллюстрации.\n'
#перебор изображений по списку
for img in ImageList:
if not self.BadImage: #чтобы не проверять лишний раз
#если изображение есть, но не существует, значит оно на Викискладе
if not img.exists():
#достаём изображение с Викисклада
img = wikipedia.Page(comm, img.title().replace(u'Файл',u'File'))
if img.exists():
#чтение текста страницы изображения с опусканием шрифта для
#последующего поиска в нём шаблонов
if not img.isRedirectPage():
imgText = img.get().lower()
else:
imgText = '';
#поиск шаблонов, сообщающих о проблемах
for ipt in ImageProblemTemplate:
if not self.BadImage:
if imgText.find(ipt) != -1:
self.BadImage = True
self.Report += u'**Изображение <nowiki>'+img.title()+\
u'</nowiki> - проблемы.\n'
if not self.BadImage:
self.Report += u'**Изображение <nowiki>'+img.title()+\
u'</nowiki> - нет проблем.\n'
else:
self.Report += u'**Ошибка, изображения <nowiki>'+img.title()+\
u'</nowiki> не существует.\n'
else:
self.Report += u'**Изображение <nowiki>'+img.title()+\
u'</nowiki> - не проверялось из соображений производительности.\n'
#удаляет подпись (если она есть) перед проверкой на наличие внутренних
#ссылок, если они есть
if self.Signed:
pagetext = pagetext.replace(u'[[Участник:','')
pagetext = pagetext.replace(u'[[User:','')
#проверяет, есть ли в статье внутренние ссылки, если нет, то NotWikifyed
#становится True
if (pagetext.find(u'[[') == -1) or (pagetext.find(u']]') == -1):
self.NotWikifyed = True
self.Report += u'* Не найдено внутренних ссылок.\n'
else:
self.Report += u'* Есть минимальная викификация.\n'
#приводит текст к нижнему регистру для дальнейшей проверки по спискам
#слов и выражений
pagetext = pagetext.lower()
#проверяет наличие словосочетания "в Украине"
if pagetext.find(u'в украине') != -1:
self.InUkraine = True
self.Report += u'* Найдена фраза «в Украине».\n'
else:
self.Report += u'* Фраза «в Украине» не найдена.\n'
#проверяет наличие фраз, выдающих привязку к настоящему времени, если
#они есть, то Temporal становится True
for substr in TimeList:
if pagetext.find(substr) != -1:
self.Temporal = True
self.Report += u'* Найдено предположительно неуместное выражение «'+\
substr+u'».\n'
#проверяет наличие фраз, указывающих на территориальную принадлежность
#читателя, если они есть, то OutLand становится True
for substr in OutLandList:
if pagetext.find(substr) != -1:
self.OutLand = True
self.Report += u'* Найдено предположительно неуместное выражение «'+\
substr+u'».\n'
#проверяет наличие ненейтральных слов, их количество записывается
#в Epithet
for substr in StyleList:
self.Epithet += pagetext.count(substr)
self.Report += u'* Количество ненейтральных слов и выражений:'+\
str(self.Epithet)+u'.\n'
#если бот нашёл ошибки, в обратном случае проверять СО не надо
if self.Need():
#проверяет страницу обсуждения, если она существует
if self.TalkPage.exists():
self.TalkPageText = self.TalkPage.get()
#проверяет, нет ли тех же замечаний в составе шаблона irm,
#расположенном на СО
if self.TalkPageText.find(u'{{irm|') != -1:
if self.NoCategory:
if self.TalkPageText.find(u'|cat') != -1:
self.NoCategory = False
if self.OneCategory:
if self.TalkPageText.find(u'|recat') != -1:
self.OneCategory = False
if self.NotWikifyed:
if self.TalkPageText.find(u'|wikify') != -1:
self.NotWikifyed = False
self.HasBr = False
self.BadLink = False
if self.Stub:
if self.TalkPageText.find(u'|stub') != -1:
self.Stub = False
if self.Refless:
if self.TalkPageText.find(u'|ref') != -1:
self.Refless = False
if self.Temporal:
if self.TalkPageText.find(u'|ethernal') != -1:
self.Temporal = False
if self.BadImage:
if self.TalkPageText.find(u'|img') != -1:
self.BadImage = False
if self.OneCategory:
if self.TalkPageText.find(u'|recat') != -1:
self.OneCategory = False
if self.Epithet > 2:
if (self.TalkPageText.find(u'|style') != -1) or \
(self.TalkPageText.find(u'|ntz') != -1):
self.Epithet = 0
#проверяет, нужно ли оставлять замечания, результат проверки
#записывается в NeedRequirement
#если замечания есть и нет команды не проверять статью
if (self.Need()) and \
(self.TalkPageText.find(u'Бот, не проверяй статью.') == -1):
self.Report += u'В ходе проверки статьи были обнаружены недостатки. '
self.NeedRequirement = True
for nb in NatabilityLinks:
if self.NeedRequirement:
if pagetext.find(nb)!= -1:
self.NeedRequirement = False #то выписывается замечание
else:
self.Report += u'Высказаны претензии к значимости предмета статьи. \
Согласно текущему консенсусу, в этом случае замечания бота не \
публикуются.'
else:
self.Report += u'В ходе автоматической проверки статьи недостатки \
обнаружены не были или была получена инструкция не проверять данную \
статью.'
#генерирует текст с замечаниями
def CreateRequirement(self):
#начало замечания
self.ReqText=u'{{Участник:AJZBot/Вводная фраза}}\n'
#если нет категорий
if self.NoCategory:
self.ReqText +=u'{{Участник:AJZBot/Нет категорий}}\n'
#если недостаточно категорий
if self.OneCategory:
self.ReqText +=u'{{Участник:AJZBot/Недостаточная категоризация}}\n'
#если нет внутренних ссылок
if self.NotWikifyed:
self.ReqText +=u'{{Участник:AJZBot/Нет внутренних ссылок}}\n'
#неправильно оформленные внутренние ссылки
if self.BadLink:
self.ReqText +=u'{{Участник:AJZBot/Неправильные ссылки}}\n'
#если нет сносок
if self.Refless:
self.ReqText +=u'{{Участник:AJZBot/Желательны сноски}}\n'
#если статья слишком мальнькая
if self.Stub:
self.ReqText +=u'{{Участник:AJZBot/Стаб}}\n'
#если есть теги br
if self.HasBr:
self.ReqText +=u'{{Участник:AJZBot/Тег br}}\n'
#если есть подпись
if self.Signed:
self.ReqText +=u'{{Участник:AJZBot/Найдена подпись}}\n'
#если есть фразы типа 'в настоящее время'
if self.Temporal:
self.ReqText +=u'{{Участник:AJZBot/Привязка ко времени}}\n'
#если есть фразы типа 'за рубежом'
if self.OutLand:
self.ReqText +=u'{{Участник:AJZBot/Привязка к государству}}\n'
#если есть словосочетания "в Украине"
if self.InUkraine:
self.ReqText +=u'{{Участник:AJZBot/Украина}}\n'
#если есть проблемы с файлами
if self.BadImage:
self.ReqText +=u'{{Участник:AJZBot/Проблемы с файлами}}\n'
#если есть существенные проблемы со стилем (больше 1 плохого слова на 3333 единиц размера)
if self.Epithet/self.Length > 0.0003:
self.ReqText +=u'{{Участник:AJZBot/Нейтральность}}\n'
#если есть незначительные проблемы со стилем (больше 3 плохих слов)
elif self.Epithet > 3:
self.ReqText +=u'{{Участник:AJZBot/Стиль}}\n'
#конец замечания
self.ReqText +=u'{{Участник:AJZBot/Завершающая фраза}} --~~~~'
#очистка страницы обсуждения от результатов предшествующей деятельности бота
def ClearTalkPage(self):
#ищем начало предыдущего замечания
ReqStart=self.TalkPageText.rfind(u'{{Участник:AJZBot/Вводная фраза}}')
#ищем конец предыдущего замечания
ReqFinish=self.TalkPageText.rfind(u'AJZBot/Завершающая фраза}}')
#если начало и конец найдены т.е. замечание было
if (ReqStart != -1) and (ReqFinish != -1):
#вставляем новое замечание на место предыдущего
#77 = 26 + 51, где 26 - длина строки 'AJZBot/Завершающая фраза}}'
#а 51 - длина подписи бота
self.TalkPageText = self.TalkPageText.replace(self.TalkPageText[(ReqStart):(ReqFinish+77)],\
self.ReqText)
else:
#вставляем новое замечание в отдельный раздел в конец страницы
self.TalkPageText += u'\n \n== Замечания по статье ==\n' + self.ReqText
#помещает текст с замечаниями на СО статьи
def PrintRequirement(self):
if self.TalkPage.exists():
#очистка страницы обсуждения от результатов предшествующей деятельности бота
self.ClearTalkPage()
#проверяет, нужно ли публиковать отчёт о проверке
if self.TalkPageText.rfind(u'Бот, отчёт о проверке.') > \
self.TalkPageText.rfind(u'<s>Бот, отчёт о проверке.</s>'):
self.TalkPageText.replace(u'<s>Бот, отчёт о проверке.</s>',u'Бот, отчёт о проверке.')
self.TalkPageText.replace(u'Бот, отчёт о проверке.',u'<s>Бот, отчёт о проверке.</s>')
self.ReqText += u'\n\n'+self.Report+u'\n--~~~~'
self.TalkPage.put(self.TalkPageText,comment=u'Замечания по статье',\
minorEdit=False)
else:
#помещает результат на СО статьи, не создавая раздела, так как страница
#пустая
self.TalkPage.put(self.ReqText,comment=u'Замечания по статье',\
minorEdit=False)
#помещает информирующий шаблон вверху самой статьи
add_text.add_text(self.Page,u'{{Инкубатор, автопроверка}}',\
summary=u'Уведомление о проверке',up=True,\
always = True)
class TBotController:
def __Init__(self,page):
#страница, на которой находятся инструкции для управления
self.Page = page
#Удалось ли получить инструкции со страницы Page
self.Instructed = False
#Работает ли бот
self.Working = True
#Список проверяемых каждый раз статей
self.Always = []
#Список не проверяемых статей
self.Never = []
#Начало списка проверяемых каждый раз статей
self.beginAlways = -1
#Конец списка проверяемых каждый раз статей
self.endAlways = -1
#Начало списка не проверяемых статей
self.beginNever = -1
#Конец списка не проверяемых статей
self.endNever = -1
#читает инструкции
def ReadInstructions(self):
if self.Page.exists():
wikipedia.output(u'Центр управления существует')
pagetext = self.Page.get()
self.beginAlways = pagetext.find(u'== Каждый раз проверять статьи ==')
self.endAlways = pagetext.find(u'== Не проверять статьи ==')
self.beginNever = self.endAlways
self.endNever = len(pagetext)
if (self.beginAlways>-1) and (self.endAlways>-1) and\
(self.beginNever>-1) and (self.endNever>-1):
self.Instructed = True
if (pagetext.find(u'Бот работает? <!-- (Да или Нет) --> Да') != -1):
self.Working = True
wikipedia.output(u'Получено разрешение на проверку')
elif (pagetext.find(u'Бот работает? <!-- (Да или Нет) --> Нет') != -1):
self.Working = False
wikipedia.output(u'Разрешение на проверку не получено')
else:
self.Instructed = False
wikipedia.output(u'Инструкции не получены')
def InstructionRead(self):
answer = (self.Instructed and self.Working)
if answer:
wikipedia.output(u'Начата проверка')
else:
wikipedia.output(u'Проверка отменена')
return answer
site = wikipedia.getSite() #Википедия
comm = wikipedia.getSite('commons','commons') #Викисклад
Controller=TBotController()
#перебор статей, входящих в GoodCategory и не входящих в BadCategory
#одновременно
Controller.__Init__(wikipedia.Page(site,u'ru:Участник:AJZBot/Центр управления'))
Controller.ReadInstructions()
if Controller.InstructionRead():
GoodCategory = set(catlib.Category(site, u"Категория:Википедия:Прошу \
проверить мою статью на соответствие правилам").articles())
BadCategory = set(catlib.Category(site, u"Категория:Википедия:Статьи \
инкубатора, проверенные ботом").articles())
Requirement=TRequirement()
for page in GoodCategory.difference(BadCategory):
try: #на всякий случай
#если страница существует и не является редиректом
if page.exists() and not page.isRedirectPage():
Requirement.__Init__(page)
if Requirement.Page.namespace()==102 and \
Requirement.TalkPage.namespace()==103 and \
Requirement.Page.exists():
Requirement.CheckPage() #проверка статьи
if Requirement.NeedRequirement: #если нужны замечания
Requirement.CreateRequirement() #создать текст замечания
#поместить текст замечания на СО и шаблон в статью
Requirement.PrintRequirement()
wikipedia.output(u'Есть замечания по статье ')
else:
wikipedia.output(u'Нет замечаний по статье')
print(page)
except:
wikipedia.output(u'Не получилось со статьёй ')
print(page)
wikipedia.output(u'Проверка завершена')