TohaomgBot
Joined 7 July 2017
This user account is a bot operated by Tohaomg (talk). It is not a sock puppet, but rather an automated or semi-automated account for making repetitive edits that would be extremely tedious to do manually.
Administrators: if this bot is malfunctioning or causing harm, please block it. |
This bot replaces all inclusions of some raster image with its analogue of format SVG, e.g. "some_image.jpg" with "some_image.svg". The pair of images is determined manually. The code of the program can be seen below (I allow anyone to use, share or change it, but not to get any financial profit from it). Bot is written on C# programming language using DotNetWikiBot library.
Code
using System;
using System.Net;
using System.Threading;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using DotNetWikiBot;
class ImageReplacer:Bot
{
[STAThread]
public static void Main(string[] args)
{
string username = args[0], password = args[1];
string new_img;
List<string> sites_list = new List<string>();
Dictionary<string, string> summary = new Dictionary<string, string>();
int edits, rejects;
MatchCollection mc;
summary.Add("en", "BOT: Replaced raster image with an image of format SVG.");
summary.Add("de", "BOT: Ersetzt das Rasterbild mit einem Bild des Formats SVG.");
summary.Add("pt", "BOT: Substituição de imagem raster por formato SVG.");
summary.Add("uk", "БОТ: Замінено растрове зображення на зображення в форматі SVG.");
summary.Add("ru", "БОТ: Заменено растровое изображение на изображение в формате SVG.");
summary.Add("be", "БОТ: Заменены растравы малюнак на малюнак у фармаце SVG.");
summary.Add("pl", "BOT: Zamień grafikę rastrową na obraz w formacie SVG.");
summary.Add("sr", "BOT: Zamenjena rasterska slika sa slikom u formatu SVG.");
summary.Add("hr", "BOT: Zamijenjena rasterska slika slikom u formatu SVG.");
summary.Add("hu", "BOT: Kép(ek) cseréje SVG formátumú változatra.");
summary.Add("ar", "BOT: استبدال صورة نقطية بصورة متجهية متغيرة (SVG).");
summary.Add("fa", "BOT: جایگزینی پرونده با نسخهٔ برداری SVG");
summary.Add("nv", "BÉÉSH HINÁANII: Eʼelyaaígíí łahgo áyiilaa; SVG choolʼį́.");
beginning:
edits = 0;
//USER INPUT
Console.WriteLine("Replace: ");
string old_img = args.Length>=3?args[2]:Console.ReadLine();
if(args.Length>=3) {Console.WriteLine(old_img);}
if(old_img.StartsWith("id="))
{
Site commons_site = new Site("https://commons.wikimedia.org/", username, password);
Page commons_page = new Page(commons_site, Int64.Parse(old_img.Substring(3)));
commons_page.Load();
old_img = commons_page.title.Substring(5);
Console.WriteLine(old_img);
mc = Regex.Matches(commons_page.text, @"\|((.)+svg)");
new_img = mc[0].Groups[1].Value;
new_img = new_img.Replace("File:", "");
if(new_img.Contains("|")) {new_img = new_img.Substring(new_img.IndexOf("|")+1);}
if(new_img.Contains("_")) {new_img = new_img.Replace("_", " ");}
Console.WriteLine("\n"+"with: \n" + new_img);
}
else
{
Console.WriteLine("\n"+"with: ");
new_img = args.Length>=4?args[3]:Console.ReadLine();
if(args.Length>=4) {Console.WriteLine(new_img);}
if(new_img==old_img)
{Console.WriteLine("\nNew image can not be the same as the old one!\n"); goto beginning;}
}
string old_img_underlined = old_img.Replace(" ", "_");
Console.WriteLine();
//WHAT WIKIS TO PROCESS
string htmlCode;
string img_usage_list = "https://" + "commons.wikimedia.org/w/index.php?title=Special:GlobalUsage&limit=500&target=" +
old_img.Replace(" ", "+");
bool goto_next_page = true;
sites_list.Clear();
while(goto_next_page)
{
try {using (WebClient client = new WebClient()) {htmlCode = client.DownloadString(img_usage_list);}}
catch {Console.WriteLine("No page for this image found!"); goto beginning;}
mc = Regex.Matches(htmlCode, @"\s([-\w]+\.(\w)+\.org)");
if(mc.Count==0) {Console.WriteLine("No inclusions found!"); goto beginning;}
foreach (Match m in mc)
{
if(!sites_list.Contains(m.Groups[1].Value) && m.Groups[1].Value!="nl.wikipedia.org" && m.Groups[1].Value!="simple.wikipedia.org")
{sites_list.Add(m.Groups[1].Value);}
}
goto_next_page = !htmlCode.Contains("| next 500)");
if(goto_next_page)
{
mc = Regex.Matches(htmlCode, @"\|\s\<a href" + "=\"(/w/index.php" + @"\?title=Special:GlobalUsage&limit=500&from=" + "[^\"]+)\"");
img_usage_list = "https://" + "commons.wikimedia.org" + mc[0].Groups[1].Value.Replace("&", "&");
}
}
//PROCESSING
try
{
Site wiki_site; PageList inclusions; int site_counter = 1, page_counter; string lang;
foreach (string st_f in sites_list)
{
string st = st_f;
rejects = 0;
Console.WriteLine("\n" + site_counter + ". " + st);
try_connect_again:
try {wiki_site = new Site("https://" + st, username, password);}
catch(System.Net.WebException)
{
Console.WriteLine("No internet connection or wrong sitename!");
Console.WriteLine("Check the connection and type sitename again (type 'skip' to skip):");
st = Console.ReadLine();
if(st=="skip") {continue;}
goto try_connect_again;
}
catch(DotNetWikiBot.WikiBotException)
{Console.WriteLine("Failed to login! This site will be skipped."); continue;}
inclusions = new PageList(wiki_site);
inclusions.FillFromPagesUsingImage(old_img);
Console.WriteLine("\t" + inclusions.Count() + " inclusions found" + "\n");
lang = GetLang(st);
page_counter = 1;
foreach (Page wiki_page in inclusions)
{
Console.WriteLine("\t" + page_counter + ". " + wiki_page.title);
if(st_f=="www.wikidata.org")
{
System.Windows.Forms.Clipboard.SetText(new_img);
System.Diagnostics.Process.Start("http://" + "www.wikidata.org/wiki/" + wiki_page.title);
continue;
}
Console.Write("\t");
wiki_page.Load();
if(wiki_page.Exists() && (wiki_page.text.Contains(old_img) || wiki_page.text.Contains(old_img_underlined)))
{
wiki_page.text = wiki_page.text.Replace(old_img, new_img);
wiki_page.text = wiki_page.text.Replace(old_img_underlined, new_img);
Console.Write("\t");
try {edits++; wiki_page.Save(summary[lang], true); if(st.StartsWith("pt.")) {Thread.Sleep(10000);}}
catch (DotNetWikiBot.WikiBotException)
{
edits--;
Console.WriteLine("\t\t" + "Site did not allow this edit");
if(++rejects > 3)
{Console.WriteLine("\t" + "To many rejects. This site will be skipped"); break;}
}
catch(System.Net.WebException e)
{
Console.WriteLine("\t\t" + "Network error: ");
Console.WriteLine("\t\t" + e.Message);
Console.WriteLine("\t\t" + "Waiting one minute");
Thread.Sleep(60000);
}
catch(Exception e) {Console.WriteLine("\t\tUnhandled exception: " + e.GetType()); Console.WriteLine("\t\t" + e.Message);}
}
else {Console.WriteLine("\t\t" + "Image not present");}
page_counter++;
}
site_counter++;
}
}
catch(Exception e)
{
Console.WriteLine("Unhandled exception: " + e.GetType());
Console.WriteLine(e.Message);
Console.ReadKey();
}
//WRITING TO LOG
finally
{
if(edits>=3)
{
if(old_img.Length>64) {old_img = old_img.Substring(0,60) + "...";}
if(new_img.Length>64) {new_img = new_img.Substring(0,60) + "...";}
System.IO.StreamWriter outfile = new System.IO.StreamWriter("log.txt", true);
outfile.Write("\r\n" + old_img);
int tabs = (old_img.Length)/8;
tabs = 8 - tabs;
while (tabs!=0) {outfile.Write("\t"); tabs--;}
outfile.Write(new_img);
tabs = (new_img.Length)/8;
tabs = 8 - tabs;
while (tabs!=0) {outfile.Write("\t"); tabs--;}
outfile.Write(DateTime.Now.ToString("dd.MM.yyyy (HH:mm)"));
outfile.Write("\t{0,4}", edits);
outfile.Close();
}
Console.WriteLine("DONE! - " + edits + " edits done\n");
}
if(args.Length>=3) {return;}
goto beginning;
}
//CHOSING LANGUAGE OF EDIT SUMMARY
public static string GetLang(string site)
{
string[] rulangs = {"ru.", "kk.", "hy.", "uz.", "ky.", "tg.", "crh.", "gag.", "tt.", "av.",
"kbd.", "ab.", "ba.", "bxr.", "os.", "kv.", "krc.", "mrj.", "lbe.", "lez.",
"mdf.", "ce.", "mhr.", "koi.", "sah.", "cu.", "tyv.", "udm.", "xal.", "cv.",
"myv.", "ady"};
string[] delangs = {"de.", "lb.", "li.", "als.", "bar.", "ksh."};
string[] pllangs = {"pl.", "szl.", "csb.", "hsb.", "dsb."};
string[] srlangs = {"sr.", "sh.", "bs.", "mk."};
if (site.StartsWith("uk.") || site.StartsWith("rue.")) {return "uk";}
else if (site.StartsWith("be.") || site.StartsWith("be-tarask.")) {return "be";}
else if (site.StartsWith("hr.") || site.StartsWith("sl.")) {return "hr";}
else if (site.StartsWith("pt.") || site.StartsWith("es.") || site.StartsWith("gl.")) {return "pt";}
else if (site.StartsWith("hu.")) {return "hu";}
else if (site.StartsWith("ar.")) {return "ar";}
else if (site.StartsWith("fa.")) {return "fa";}
else if (site.StartsWith("nv.")) {return "nv";}
else if (Array.IndexOf(srlangs, site.Substring(0,3))>=0) {return "sr";}
else if (Array.IndexOf(pllangs, site.Substring(0,3))>=0 || Array.IndexOf(pllangs, site.Substring(0,4))>=0) {return "pl";}
else if (Array.IndexOf(delangs, site.Substring(0,3))>=0 || Array.IndexOf(delangs, site.Substring(0,4))>=0) {return "de";}
else if (Array.IndexOf(rulangs, site.Substring(0,3))>=0 || Array.IndexOf(rulangs, site.Substring(0,4))>=0) {return "ru";}
else {return "en";}
}
}