Польꙃєватєл҄ь:TohaomgBot

Википєдїѩ · отврьстꙑ єнкѷклопєдїѩ · страница
Jump to navigation Jump to search

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&amp;limit=500&amp;from=" + "[^\"]+)\"");
    img_usage_list = "https://" + "commons.wikimedia.org" + mc[0].Groups[1].Value.Replace("&amp;", "&");
   }
  }


  //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";}
 }
}