mirror of
https://github.com/reactos/reactos.git
synced 2025-06-12 01:08:30 +00:00
- Moved commands outside TechBot.Library to TechBot.Commands.Common and TechBot.Commands.MSDN except for Command base classes
- Made TechBot more configurable through .config files - Code refactoring - Removed automatic parameter parsing support to make everyone happy svn path=/trunk/; revision=33586
This commit is contained in:
parent
6d51a10a1b
commit
ac77d9d3a6
47 changed files with 1783 additions and 489 deletions
310
irc/TechBot/TechBot.Commands.MSDN/ApiCommand.cs
Normal file
310
irc/TechBot/TechBot.Commands.MSDN/ApiCommand.cs
Normal file
|
@ -0,0 +1,310 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Data;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using HtmlHelp;
|
||||
using HtmlHelp.ChmDecoding;
|
||||
|
||||
using TechBot.Library;
|
||||
|
||||
namespace TechBot.Commands.MSDN
|
||||
{
|
||||
[Command("api", Help = "!api <apiname>")]
|
||||
public class ApiCommand : Command
|
||||
{
|
||||
private bool IsVerbose = false;
|
||||
|
||||
private HtmlHelpSystem chm;
|
||||
private string name;
|
||||
|
||||
public ApiCommand()
|
||||
{
|
||||
Run();
|
||||
}
|
||||
|
||||
[CommandParameter("api", "The API name")]
|
||||
public string API
|
||||
{
|
||||
get { return Parameters; }
|
||||
set { Parameters = value; }
|
||||
}
|
||||
|
||||
private void WriteIfVerbose(string message)
|
||||
{
|
||||
if (IsVerbose)
|
||||
Say(message);
|
||||
}
|
||||
|
||||
private void Run()
|
||||
{
|
||||
string CHMFilename = Path.Combine(Settings.Default.ChmPath, Settings.Default.MainChm);
|
||||
chm = new HtmlHelpSystem();
|
||||
chm.OpenFile(CHMFilename, null);
|
||||
|
||||
Console.WriteLine(String.Format("Loaded main CHM: {0}",
|
||||
Path.GetFileName(CHMFilename)));
|
||||
foreach (string filename in Directory.GetFiles(Settings.Default.ChmPath))
|
||||
{
|
||||
if (!Path.GetExtension(filename).ToLower().Equals(".chm"))
|
||||
continue;
|
||||
if (Path.GetFileName(filename).ToLower().Equals(Settings.Default.MainChm))
|
||||
continue;
|
||||
|
||||
Console.WriteLine(String.Format("Loading CHM: {0}",
|
||||
Path.GetFileName(filename)));
|
||||
try
|
||||
{
|
||||
chm.MergeFile(filename);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(String.Format("Could not load CHM: {0}. Exception {1}",
|
||||
Path.GetFileName(filename),
|
||||
ex));
|
||||
}
|
||||
}
|
||||
Console.WriteLine(String.Format("Loaded {0} CHMs",
|
||||
chm.FileList.Length));
|
||||
}
|
||||
|
||||
public override void ExecuteCommand()
|
||||
{
|
||||
if (Name.Trim().Equals(String.Empty))
|
||||
{
|
||||
Say("Please give me a keyword.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Search(Name);
|
||||
}
|
||||
}
|
||||
|
||||
private bool SearchIndex(
|
||||
string keyword)
|
||||
{
|
||||
if (chm.HasIndex)
|
||||
{
|
||||
IndexItem item = chm.Index.SearchIndex(keyword,
|
||||
IndexType.KeywordLinks);
|
||||
if (item != null && item.Topics.Count > 0)
|
||||
{
|
||||
WriteIfVerbose(String.Format("Keyword {0} found in index",
|
||||
item.KeyWord));
|
||||
IndexTopic indexTopic = item.Topics[0] as IndexTopic;
|
||||
return DisplayResult( keyword,
|
||||
indexTopic);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteIfVerbose(String.Format("Keyword {0} not found in index",
|
||||
keyword));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private void SearchFullText(string keyword)
|
||||
{
|
||||
string sort = "Rating ASC";
|
||||
WriteIfVerbose(String.Format("Searching fulltext database for {0}",
|
||||
keyword));
|
||||
|
||||
bool partialMatches = false;
|
||||
bool titlesOnly = true;
|
||||
int maxResults = 100;
|
||||
DataTable results = chm.PerformSearch(keyword,
|
||||
maxResults,
|
||||
partialMatches,
|
||||
titlesOnly);
|
||||
WriteIfVerbose(String.Format("results.Rows.Count = {0}",
|
||||
results != null ?
|
||||
results.Rows.Count.ToString() : "(none)"));
|
||||
if (results != null && results.Rows.Count > 0)
|
||||
{
|
||||
results.DefaultView.Sort = sort;
|
||||
if (!DisplayResult(keyword,
|
||||
results))
|
||||
{
|
||||
Say("No result");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Say("No result");
|
||||
}
|
||||
}
|
||||
|
||||
private void Search(string keyword)
|
||||
{
|
||||
if (!SearchIndex(keyword))
|
||||
SearchFullText(keyword);
|
||||
}
|
||||
|
||||
private bool DisplayResult(string keyword,
|
||||
IndexTopic indexTopic)
|
||||
{
|
||||
keyword = keyword.Trim().ToLower();
|
||||
string url = indexTopic.URL;
|
||||
WriteIfVerbose(String.Format("URL from index search {0}",
|
||||
url));
|
||||
string prototype = ExtractPrototype(url);
|
||||
if (prototype == null || prototype.Trim().Equals(String.Empty))
|
||||
return false;
|
||||
string formattedPrototype = FormatPrototype(prototype);
|
||||
Say(formattedPrototype);
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool DisplayResult(string keyword,
|
||||
DataTable results)
|
||||
{
|
||||
keyword = keyword.Trim().ToLower();
|
||||
for (int i = 0; i < results.DefaultView.Count; i++)
|
||||
{
|
||||
DataRowView row = results.DefaultView[i];
|
||||
string title = row["Title"].ToString();
|
||||
WriteIfVerbose(String.Format("Examining {0}", title));
|
||||
if (title.Trim().ToLower().Equals(keyword))
|
||||
{
|
||||
string location = row["Location"].ToString();
|
||||
string rating = row["Rating"].ToString();
|
||||
string url = row["Url"].ToString();
|
||||
string prototype = ExtractPrototype(url);
|
||||
if (prototype == null || prototype.Trim().Equals(String.Empty))
|
||||
continue;
|
||||
string formattedPrototype = FormatPrototype(prototype);
|
||||
Say(formattedPrototype);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void DisplayNoResult(MessageContext context,
|
||||
string keyword)
|
||||
{
|
||||
TechBot.ServiceOutput.WriteLine(context,
|
||||
String.Format("I don't know about keyword {0}",
|
||||
keyword));
|
||||
}
|
||||
|
||||
private string ReplaceComments(string s)
|
||||
{
|
||||
return Regex.Replace(s, "//(.+)\r\n", "");
|
||||
}
|
||||
|
||||
private string ReplaceLineEndings(string s)
|
||||
{
|
||||
return Regex.Replace(s, "(\r\n)+", " ");
|
||||
}
|
||||
|
||||
private string ReplaceSpaces(string s)
|
||||
{
|
||||
return Regex.Replace(s, @" +", " ");
|
||||
}
|
||||
|
||||
private string ReplaceSpacesBeforeLeftParenthesis(string s)
|
||||
{
|
||||
return Regex.Replace(s, @"\( ", @"(");
|
||||
}
|
||||
|
||||
private string ReplaceSpacesBeforeRightParenthesis(string s)
|
||||
{
|
||||
return Regex.Replace(s, @" \)", @")");
|
||||
}
|
||||
|
||||
private string ReplaceSemicolon(string s)
|
||||
{
|
||||
return Regex.Replace(s, @";", @"");
|
||||
}
|
||||
|
||||
private string FormatPrototype(string prototype)
|
||||
{
|
||||
string s = ReplaceComments(prototype);
|
||||
s = ReplaceLineEndings(s);
|
||||
s = ReplaceSpaces(s);
|
||||
s = ReplaceSpacesBeforeLeftParenthesis(s);
|
||||
s = ReplaceSpacesBeforeRightParenthesis(s);
|
||||
s = ReplaceSemicolon(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
private string ExtractPrototype(string url)
|
||||
{
|
||||
string page = GetPage(url);
|
||||
Match match = Regex.Match(page,
|
||||
"<PRE class=\"?syntax\"?>(.+)</PRE>",
|
||||
RegexOptions.Multiline |
|
||||
RegexOptions.Singleline);
|
||||
if (match.Groups.Count > 1)
|
||||
{
|
||||
string prototype = match.Groups[1].ToString();
|
||||
return StripHtml(StripAfterSlashPre(prototype));
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private string StripAfterSlashPre(string html)
|
||||
{
|
||||
int index = html.IndexOf("</PRE>");
|
||||
if (index != -1)
|
||||
{
|
||||
return html.Substring(0, index);
|
||||
}
|
||||
else
|
||||
return html;
|
||||
}
|
||||
|
||||
private string StripHtml(string html)
|
||||
{
|
||||
return Regex.Replace(html, @"<(.|\n)*?>", String.Empty);
|
||||
}
|
||||
|
||||
private string GetPage(string url)
|
||||
{
|
||||
string CHMFileName = "";
|
||||
string topicName = "";
|
||||
string anchor = "";
|
||||
CHMStream.CHMStream baseStream;
|
||||
if (!chm.BaseStream.GetCHMParts(url, ref CHMFileName, ref topicName, ref anchor))
|
||||
{
|
||||
baseStream = chm.BaseStream;
|
||||
CHMFileName = baseStream.CHMFileName;
|
||||
topicName = url;
|
||||
anchor = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
baseStream = GetBaseStreamFromCHMFileName(CHMFileName);
|
||||
}
|
||||
|
||||
if ((topicName == "") || (CHMFileName == "") || (baseStream == null))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return baseStream.ExtractTextFile(topicName);
|
||||
}
|
||||
|
||||
private CHMStream.CHMStream GetBaseStreamFromCHMFileName(string CHMFileName)
|
||||
{
|
||||
foreach (CHMFile file in chm.FileList)
|
||||
{
|
||||
WriteIfVerbose(String.Format("Compare: {0} <> {1}",
|
||||
file.ChmFilePath,
|
||||
CHMFileName));
|
||||
if (file.ChmFilePath.ToLower().Equals(CHMFileName.ToLower()))
|
||||
{
|
||||
return file.BaseStream;
|
||||
}
|
||||
}
|
||||
WriteIfVerbose(String.Format("Could not find loaded CHM file in list: {0}",
|
||||
CHMFileName));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue