Участник:Ivan A. Krestinin/KrBotSource

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

Ниже приведён фрагмент исходного кода бота KrBot, демонстрирующий логику его работы.

bool CKrBot::AddTemplates(const std::string& page_name)
{
	m_log.Message("Processing page '" + page_name + "'.");
	try
	{
		std::vector<std::string> links_to  = m_site.GetBackLinks     (page_name, "0", 10);
		std::vector<std::string> links     = m_site.GetLinks         (page_name, "0", 10);
		std::vector<std::string> cats      = m_site.GetPageCategories(page_name, false);
		std::vector<std::string> templates = m_site.GetTemplates     (page_name, "");

		std::vector<std::string>::iterator it;
		while ((it = std::find(links_to.begin(), links_to.end(), page_name)) != links_to.end())
			links_to.erase(it); // recursive links

		m_log.Message("  " + int_to_str(cats.size()) + " categories, " + int_to_str(links.size()) + " links, " + int_to_str(links_to.size()) + " links to this page, " + int_to_str(templates.size()) + " templates");

		if (m_site.IsRedirect(page_name))
		{
			m_log.Message("  The page is redirect.");
			return true;
		}

		bool add_no_cat      = cats.size() == 0;
		bool add_no_links    = links.size() == 0;
		bool add_no_links_to = links_to.size() == 0;

		if (std::contains(templates, TX("Шаблон:Неоднозначность")) ||
		    std::contains(templates, TX("Шаблон:Фамилия")) ||
		    std::contains(templates, TX("Шаблон:Реки")) ||
		    std::contains(templates, TX("Шаблон:Однофамильцы-тёзки")) ||
		    std::contains(templates, TX("Шаблон:Одноимённые корабли")) ||
		    std::contains(templates, TX("Шаблон:Одноимённые населённые пункты")) ||
		    std::contains(templates, TX("Шаблон:Одноимённые площади")) ||
		    std::contains(templates, TX("Шаблон:Одноимённые станции метро")) ||
		    std::contains(templates, TX("Шаблон:Одноимённые улицы")) ||
		    std::contains(templates, TX("Шаблон:Одноимённые фильмы")))
		{
			add_no_cat      = false;
			add_no_links_to = false;
			m_log.Message("  The page is disambig.");
		}

		if (std::contains(templates, TX("Шаблон:Нет категорий")))
			add_no_cat = false;
		if (std::contains(templates, TX("Шаблон:Тупиковая статья")))
			add_no_links = false;
		if (std::contains(templates, TX("Шаблон:Изолированная статья")))
			add_no_links_to = false;

		if (std::contains(templates, TX("Шаблон:Rq")))
		{
			if (add_no_cat || add_no_links_to)
			{
				Wiki::CDocumentTree doc;
				doc.ParseString(m_site.GetPageSource(page_name));
				ITemplate* rq_tmpl;
				if (((rq_tmpl = doc.FindTemplate(TX("rq"))) == NULL) &&
				    ((rq_tmpl = doc.FindTemplate(TX("Rq"))) == NULL))
					throw CException("Rq template not found.");

				for (size_t i = 0; i < rq_tmpl->GetPropertyCount(); i++)
				{
					std::string value = to_lower_utf8(trim(rq_tmpl->GetPropertyValue(i)->GetRawText()));
					if (value == "cat")
						add_no_cat = false;
					else if (value == "linkless")
						add_no_links_to = false;
				}
			}
		}


		if (add_no_cat || add_no_links || add_no_links_to)
		{
			if (std::contains(templates, TX("Шаблон:Редактирую")))
			{
				m_log.Message("  The page is locked by another user.");
				return false;
			}

			if (std::contains(templates, TX("Шаблон:Nobots")) ||
					std::contains(templates, TX("Шаблон:Bots"  )))
			{
				m_log.Message("  The page is bot-protected.");
				return false;
			}


			std::string text;
			std::string summary;

			if (add_no_cat)
			{
				text += TX("\n{{нет категорий}}");
				if (summary != "")
					summary += ", ";
				summary += TX("+ {{нет категорий}}");
			}
			if (add_no_links)
			{
				text += TX("\n{{тупиковая статья}}");
				if (summary != "")
					summary += ", ";
				summary += TX("+ {{тупиковая статья}}");
			}
			if (add_no_links_to)
			{
				text += TX("\n{{изолированная статья}}");
				if (summary != "")
					summary += ", ";
				summary += TX("+ {{изолированная статья}}");
			}

			m_log.Message("  Edit summary: " + summary + ".");

			m_site.EditPage(page_name).AddTextToEnd(text, summary, true);
		}
		return true;
	}
	catch (const Wiki::CException& err)
	{
		m_log.Error("  ERROR: " + err.GetMessage());
		return false;
	}
}


void CKrBot::Run()
{
	m_site.Login("KrBot", "*********************");

	std::set<std::string> already_processed = LoadProcessedPages("processed_pages.txt");

	time_t stime;
	time(&stime);
	stime -= 4 * 60 * 60; // не раньше, чем через 4 часа после создания
	tm start_time = *gmtime(&stime);
	
	std::vector<std::string> pages = m_site.GetNewPages("0", 500, &start_time, NULL, no);
	for (size_t i = 0; i < pages.size(); i++)
	{
		if (already_processed.find(pages[i]) == already_processed.end())
		{
			if (AddTemplates(pages[i]))
			{
				already_processed.insert(pages[i]);
			}
			m_log.Flush();
		}
	}

	SaveProcessedPages("processed_pages.txt", already_processed);

	m_site.Logout();
}