User:WJ-Bot/Core
本代码为WJ-Bot的支持类,用于控制刷新频率、检查Bot模板以及避免重复更新操作。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Text;
using System.Text.RegularExpressions;
namespace WJBot
{
public class BotWorker
{
public delegate string PageModifier(DotNetWikiBot.Page page);
public event EventHandler PageUpdated;
public event EventHandler PageLoaded;
public int TotalPages { get; private set; }
public int EditedPages { get; private set; }
public int LoadedPages { get; private set; }
public int LingerTime { get; set; }
public string EditSummary { get; set; }
public BotWorker()
{
LingerTime = 60000;
EditSummary = string.Empty;
}
private Thread _thread;
private bool AllowBots(string text, string user)
{
return !Regex.IsMatch(text, @"\{\{(nobots|bots\|(allow=none|deny=(?!none).*(" + user.Normalize() + @"|all)|optout=all))\}\}", RegexOptions.IgnoreCase);
}
/// <summary>
/// Main bot function
/// </summary>
/// <param name="Pages">Page list for editing.</param>
/// <param name="TitleSelector">Title selection delegate.</param>
/// <param name="Modifier">Page modifier delegate.</param>
/// <param name="IsTest">True if results are not submitted.</param>
public void Start(DotNetWikiBot.PageList Pages, Func<string, bool> TitleSelector, PageModifier Modifier, bool IsTest)
{
if (EditSummary == string.Empty)
{
throw new ArgumentException("No edit summary");
}
if (_thread != null)
_thread.Abort();
_thread = new Thread(() =>
{
try
{
TotalPages = Pages.Count();
LoadedPages = 0; EditedPages = 0;
HashSet<string> visited_list = new HashSet<string>();
if (File.Exists("visited.txt"))
{
StreamReader vs_reader = new StreamReader("visited.txt");
while (true)
{
string line = vs_reader.ReadLine();
if (line == null) break;
visited_list.Add(line.Trim('\r', '\n', ' '));
}
vs_reader.Close();
}
DateTime last_submission = DateTime.Now;
using (StreamWriter vs_writer = new StreamWriter("visited.txt", true))
{
foreach (DotNetWikiBot.Page pg_iter in Pages)
{
if (visited_list.Contains(pg_iter.title)) continue;
if (!TitleSelector(pg_iter.title)) continue;
pg_iter.Load();
LoadedPages++;
if (PageLoaded != null)
{
PageLoaded(this, new EventArgs());
}
visited_list.Add(pg_iter.title);
vs_writer.WriteLine(pg_iter.title);
vs_writer.Flush();
if (pg_iter.text == null) continue;
if (!AllowBots(pg_iter.text, pg_iter.site.userName)) continue;
string old_text = pg_iter.text;
string new_text = Modifier(pg_iter);
if (new_text != null && new_text != old_text)
{
EditedPages++;
StreamWriter stwriter = new StreamWriter("Depository\\" + pg_iter.title.Replace("/", "_").Replace(":", "_") + ".txt");
stwriter.Write(new_text);
stwriter.Close();
if (!IsTest)
{
long linger = (long)(DateTime.Now - last_submission).TotalMilliseconds;
if (linger < LingerTime)
{
Thread.Sleep((int)(LingerTime + 100 - linger));
}
try
{
pg_iter.Save(new_text, "机器人:" + EditSummary, true);
}
catch (Exception) { }
}
if (PageUpdated != null)
{
PageUpdated(this, new EventArgs());
}
last_submission = DateTime.Now;
}
}
}
}
catch (ThreadAbortException)
{
}
});
_thread.Start();
}
}
}