#include "adabot.h"
#include "credentials.h"
#include <bits/stdc++.h>
using namespace std;
using namespace adabot;
r_client rcl("ruwiki_p", "ruwiki.labsdb", db_login, db_password, 3306);
w_client wcl("ru.wikipedia.org");
r_pages recents(rcl);
cl_graph cg(rcl);
const vector<string> templates = {
// "Участник:NirvanaBot/Новые статьи",
"Участник:ClaymoreBot/Новые статьи"
};
const unordered_set<string> aliases = {
// "Участник:NirvanaBot/Новые статьи",
// "User:NirvanaBot/Новые статьи",
"Участник:ClaymoreBot/Новые статьи",
"User:ClaymoreBot/Новые статьи"
};
const int def_depth = 6;
const int def_elems = 20;
const int def_space = 0;
const int def_recent = 350;
const string def_format = "[[%(название)]]";
const string def_separator = "\n";
const string def_header = "";
const string def_bottom = "\n<noinclude> "
"[[Категория:Википедия:Списки новых статей по темам|"
"{{PAGENAME}}]] </noinclude>";
const string time_pat = "%(дата)";
const string title_pat = "%(название)";
const string actor_pat = "%(автор)";
void update_page(string page, vector<tuple<string, string, string>> pages,
string format, string separator,
string header, string bottom) {
string result = header;
vector<string> page_list;
for(auto it: pages) {
string time, title, actor;
tie(time, title, actor) = it;
time = time.substr(0, 4) + "-" + time.substr(4, 2) + "-" // convert SQL
+ time.substr(6, 2) + "T" + time.substr(8, 2) + ":" // format to
+ time.substr(10, 2) + ":" + time.substr(12) + "Z"; // API format
string row = format;
row = str::replace(row, time_pat, time);
row = str::replace(row, title_pat, title);
row = str::replace(row, actor_pat, actor);
page_list.push_back(row);
}
result += str::join(utils::map(page_list,
str::replacer('_', " ")),
separator);
result += bottom;
result = str::replace(result, "\\n", "\n");
result = str::replace(result, "&", "%26");
wcl.edit(page, result, "обновление списка новых страниц");
}
void process(string str, bool triage = true) {
auto parsed = w_parser::parse(str);
for(auto it: parsed.get_tokens()) {
if(it.get_type() == w_token::w_template &&
aliases.count(it.get_name())) {
auto args = it.get_args();
string page = args["страница"].to_wikitext();
if(page.empty()) {
cerr << "No page in this template, skipping it..." << endl;
continue;
}
auto cats = args["категории"].to_wikitext().size()
? str::split(args["категории"].to_wikitext(), ',')
: args["категория"].to_wikitext().size()
? str::split(args["категория"].to_wikitext(), ',')
: vector<string>{};
if(cats.empty()) {
cerr << "Skipping page " << page
<< ", no root categories provided" << endl;
continue;
}
auto forb = str::split(args["игнорировать"].to_wikitext(), ',');
auto dequoter = [](string x) {
if(x[0] == '"' && x.back() == '"') {
x = x.substr(1);
x.pop_back();
}
return x;
};
auto trimmer = [&](string x) {
x = dequoter(str::replace(str::trim(x), ' ', "_"));
size_t idx = x.find('#');
if(idx != string::npos) {
x.erase(idx);
}
return x;
};
cats = utils::map(cats, trimmer);
forb = utils::map(forb, trimmer);
int depth = args["глубина"].to_wikitext().size()
? stol(args["глубина"].to_wikitext())
: def_depth;
int space = args["пространство имён"].to_wikitext().size()
? stol(args["пространство имён"].to_wikitext())
: def_space;
size_t elems = args["элементов"].to_wikitext().size()
? stol(args["элементов"].to_wikitext())
: def_elems;
string type = args["тип"].to_wikitext();
if(type != "новые статьи" && type != "список новых статей") {
cerr << "Skipping page " << page << ", type "
<< type << " is not supported yet" << endl;
continue;
}
string header = args.count("шапка")
? dequoter(args["шапка"].to_wikitext())
: def_header;
string format = args.count("формат элемента")
? dequoter(args["формат элемента"].to_wikitext())
: def_format;
string separator = args.count("разделитель")
? dequoter(args["разделитель"].to_wikitext())
: def_separator;
string bottom = args.count("подвал")
? dequoter(args["подвал"].to_wikitext())
: def_bottom;
auto subcats = cg.get_subcats(cats, forb, depth);
auto pages = recents.pages(subcats, space);
if(pages.size() > elems) {
pages.resize(elems);
}
if(triage) {
page = "Участник:AdamantBot/Песочница/" + page;
}
update_page(page, pages, format, separator, header, bottom);
}
}
}
int main(int argc, char *argv[]) {
freopen("log_recent.txt", "w", stderr);
wcl.login(botlogin, newpages_bot, botpass.at(newpages_bot));
auto transcludes = wcl.transcludedin(templates);
vector<string> pages;
for(auto it: transcludes) {
pages.insert(end(pages), begin(it.second), end(it.second));
}
auto texts = wcl.wikitext(pages);
int count = 5000;
for(auto it: pages) {
cerr << "Processing params on " << it << "..." << endl;
process(texts[it], false);
if(count-- == 0) {
break;
}
}
}