Участник:VasilievVV/WikiAccess/0.1/Namespaces.cs
Перейти к навигации
Перейти к поиску
/**********************************************************************************
* Namespace utils of WikiAcces Library *
* Copyright (C) 2007 Vasiliev V. V. *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*
**********************************************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
namespace WikiTools.Access
{
/// <summary>
/// Namespace utils
/// </summary>
public class Namespaces
{
static Regex NamespaceFromMeta = new Regex("<ns id=\"(-?\\d{1,3})\">(.+?)</ns>", RegexOptions.Compiled);
#region Load and save
/// <summary>
/// Loads namespaces from live wiki
/// </summary>
/// <param name="wiki">Source of namespaces</param>
/// <returns>Namespace ID:Name list</returns>
public static SortedList<int, string> GetNamespaces(Wiki wiki)
{
string uri = wiki.WikiURI + "/api.php?action=query&meta=siteinfo&siprop=namespaces&format=xml";
WebRequest rq = WebRequest.Create(uri);
string str = new StreamReader(rq.GetResponse().GetResponseStream(), Encoding.UTF8).ReadToEnd();
SortedList<int, string> result = new SortedList<int, string>();
result.Add(0, "");
MatchCollection matches = NamespaceFromMeta.Matches(str);
foreach (Match match in matches)
{
result.Add(Int32.Parse(match.Groups[1].Value), match.Groups[2].Value);
}
return result;
}
/// <summary>
/// Loads namespaces from file
/// </summary>
/// <param name="fname">File name</param>
/// <returns>Namespace ID:Name list</returns>
public static SortedList<int, string> LoadFromFile(string fname)
{
string[] lines = File.ReadAllLines(fname, Encoding.UTF8);
SortedList<int, string> result = new SortedList<int, string>();
foreach (string cline in lines)
{
string[] parts = cline.Split(':');
result.Add(Int32.Parse(parts[0]), parts[1]);
}
return result;
}
/// <summary>
/// Saves namespaces to file
/// </summary>
/// <param name="fname">File name</param>
/// <param name="ns">Namespaces list</param>
public static void SaveToFile(string fname, SortedList<int, string> ns)
{
List<string> result = new List<string>();
foreach (KeyValuePair<int, string> ckp in ns)
result.Add(ckp.Key + ":" + ckp.Value);
File.WriteAllLines(fname, result.ToArray(), Encoding.UTF8);
}
/// <summary>
/// Makes name for cache file
/// </summary>
/// <param name="uri">URI of wiki</param>
/// <returns>File name</returns>
public static string MkName(string uri)
{
return (new Uri(uri).Host) + ".namespaces";
}
#endregion
/// <summary>
/// Gets canonical namespaces list
/// </summary>
/// <returns>Canonical namespaces list</returns>
public SortedList<int, string> GetStandardNamespaces()
{
SortedList<int, string> result = new SortedList<int, string>();
result.Add(-2, "Media");
result.Add(-1, "Special");
result.Add(0, "");
result.Add(1, "Talk");
result.Add(2, "User");
result.Add(3, "User talk");
result.Add(4, "Project");
result.Add(5, "Project talk");
result.Add(6, "Image");
result.Add(7, "Image talk");
result.Add(8, "MediaWiki");
result.Add(9, "MediaWiki talk");
result.Add(10, "Template");
result.Add(11, "Template talk");
result.Add(12, "Help");
result.Add(13, "Help talk");
result.Add(14, "Category");
result.Add(15, "Category talk");
return result;
}
SortedList<int, string> namespaces;
/// <summary>
/// Initializes new instance of object from file
/// </summary>
/// <param name="fpath">File name</param>
public Namespaces(string fpath)
{
namespaces = Namespaces.LoadFromFile(fpath);
}
/// <summary>
/// Initializes new instance of object from live wiki
/// </summary>
/// <param name="wiki">Wiki</param>
public Namespaces(Wiki wiki)
{
namespaces = Namespaces.GetNamespaces(wiki);
}
/// <summary>
/// Gets IF of specified namespace
/// </summary>
/// <param name="nsName"></param>
/// <returns></returns>
public int GetNamespaceID(string nsName)
{
if (namespaces.ContainsValue(nsName))
return namespaces.Keys[namespaces.Values.IndexOf(nsName)];
else if (GetStandardNamespaces().ContainsValue(nsName))
return GetStandardNamespaces().Keys[GetStandardNamespaces().Values.IndexOf(nsName)];
else return 0;
}
/// <summary>
/// Extracts namespace from title
/// </summary>
/// <param name="title">Page title</param>
/// <returns>Namespace ID</returns>
public int GetNamespaceByTitle(string title)
{
return GetNamespaceID(title.Split(':')[0]);
}
/// <summary>
/// Saves namespaces to file
/// </summary>
/// <param name="fname">File name</param>
public void SaveToFile(string fname)
{
Namespaces.SaveToFile(fname, namespaces);
}
/// <summary>
/// Gets namespace by ID
/// </summary>
/// <param name="ID">Namespace ID</param>
/// <returns>Namespace name</returns>
public string GetNamespaceByID(int ID)
{
return namespaces[ID];
}
/// <summary>
/// Get talk title of specified page
/// </summary>
/// <param name="title">Page title</param>
/// <returns>Talk title</returns>
public string TitleToTalk(string title)
{
int nid = GetNamespaceByTitle(title);
if (IsTalkNamespace(title) | nid < 0) return title;
if (nid == 0) return namespaces[1] + ":" + title;
else if (title.StartsWith(namespaces[nid]))
return namespaces[nid + 1] + title.Substring(title.IndexOf(":"));
else
return GetStandardNamespaces()[nid + 1] + title.Substring(title.IndexOf(":"));
}
/// <summary>
/// Get page title of specified talk page
/// </summary>
/// <param name="title">Talk title</param>
/// <returns>Page title</returns>
public string TitleFromTalk(string title)
{
if (!IsTalkNamespace(title)) return title;
int nid = GetNamespaceByTitle(title);
if (nid == 1) return title.Substring(title.IndexOf(":") + 1);
else if (title.StartsWith(namespaces[nid]))
return namespaces[nid - 1] + title.Substring(title.IndexOf(":"));
else
return GetStandardNamespaces()[nid - 1] + title.Substring(title.IndexOf(":"));
}
/// <summary>
/// Checks if page is in talk namespace
/// </summary>
/// <param name="title">Page title</param>
/// <returns>Is talk namespace</returns>
public bool IsTalkNamespace(string title)
{
return GetNamespaceByTitle(title) > 0 && GetNamespaceByTitle(title) % 2 == 1;
}
}
}