From: <pb...@us...> - 2007-03-27 09:07:34
|
Revision: 232 http://mp-plugins.svn.sourceforge.net/mp-plugins/?rev=232&view=rev Author: pbb72 Date: 2007-03-27 02:07:31 -0700 (Tue, 27 Mar 2007) Log Message: ----------- Documentation plugin to browse MP wiki from within MediaPortal. Based on Wikipedia plugin. Added Paths: ----------- trunk/plugins/Documentation plugin/ trunk/plugins/Documentation plugin/Documentation.cs trunk/plugins/Documentation plugin/Documentation.csproj trunk/plugins/Documentation plugin/DocumentationImage.cs trunk/plugins/Documentation plugin/DocumentationPage.cs Added: trunk/plugins/Documentation plugin/Documentation.cs =================================================================== --- trunk/plugins/Documentation plugin/Documentation.cs (rev 0) +++ trunk/plugins/Documentation plugin/Documentation.cs 2007-03-27 09:07:31 UTC (rev 232) @@ -0,0 +1,407 @@ +#region Copyright (C) 2005-2007 Team MediaPortal + +/* + * Copyright (C) 2005-2007 Team MediaPortal + * http://www.team-mediaportal.com + * + * 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, 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 GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#endregion + +using System; +using System.ComponentModel; +using System.Windows.Forms; +using System.Net; +using System.IO; +using System.Text; +using System.Threading; +using System.Collections; +using MediaPortal.GUI.Library; +using MediaPortal.Dialogs; +using MediaPortal.Util; +using MediaPortal.Configuration; + +namespace Wikipedia +{ + /// <summary> + /// Windowplugin to search in Wikipedia and display articles using the MP Wikipedia Classes. + /// </summary> + public class GUIWikipedia : GUIWindow, ISetupForm + { + #region SkinControls + [SkinControlAttribute(10)] + protected GUIButtonControl buttonSearch = null; + [SkinControlAttribute(11)] + protected GUIButtonControl buttonLocal = null; + [SkinControlAttribute(14)] + protected GUIButtonControl buttonBack = null; + [SkinControlAttribute(12)] + protected GUIButtonControl buttonLinks = null; + [SkinControlAttribute(13)] + protected GUIButtonControl buttonImages = null; + + [SkinControlAttribute(4)] + protected GUILabelControl searchtermLabel = null; + [SkinControlAttribute(5)] + protected GUILabelControl imagedescLabel = null; + [SkinControlAttribute(20)] + protected GUITextControl txtArticle = null; + + [SkinControlAttribute(25)] + protected GUIImage imageControl = null; + #endregion + + private string language = "Default"; + private string articletext = string.Empty; + private ArrayList linkArray = new ArrayList(); + private ArrayList imagenameArray = new ArrayList(); + private ArrayList imagedescArray = new ArrayList(); + + + public GUIWikipedia() + { + GetID = (int)GUIWindow.Window.WINDOW_WIKIPEDIA; + } + #region ISetupForm Members + + // Returns the name of the plugin which is shown in the plugin menu + public string PluginName() + { + return "Wikipedia"; + } + + // Returns the description of the plugin is shown in the plugin menu + public string Description() + { + return "A Plugin to search in Wikipedia"; + } + + // Returns the author of the plugin which is shown in the plugin menu + public string Author() + { + return "Maschine"; + } + + // show the setup dialog + public void ShowPlugin() + { + MessageBox.Show("Edit the wikipedia.xml file in MP's root directory to add new sites."); + } + + // Indicates whether plugin can be enabled/disabled + public bool CanEnable() + { + return true; + } + + // get ID of windowplugin belonging to this setup + public int GetWindowId() + { + return 4711; + } + + // Indicates if plugin is enabled by default; + public bool DefaultEnabled() + { + return false; + } + + // indicates if a plugin has its own setup screen + public bool HasSetup() + { + return false; + } + + /// <summary> + /// If the plugin should have its own button on the main menu of Media Portal then it + /// should return true to this method, otherwise if it should not be on home + /// it should return false + /// </summary> + /// <param name="strButtonText">text the button should have</param> + /// <param name="strButtonImage">image for the button, or empty for default</param> + /// <param name="strButtonImageFocus">image for the button, or empty for default</param> + /// <param name="strPictureImage">subpicture for the button or empty for none</param> + /// <returns>true : plugin needs its own button on home + /// false : plugin does not need its own button on home</returns> + public bool GetHome(out string strButtonText, out string strButtonImage, out string strButtonImageFocus, out string strPictureImage) + { + strButtonText = GUILocalizeStrings.Get(2516); + strButtonImage = ""; + strButtonImageFocus = ""; + strPictureImage = ""; + return true; + } + #endregion + + public override bool Init() + { + return Load(GUIGraphicsContext.Skin + @"\wikipedia.xml"); + } + + protected override void OnClicked(int controlId, GUIControl control, MediaPortal.GUI.Library.Action.ActionType actionType) + { + // we don't want the user to start another search while one is already active + if (_workerCompleted == false) + return; + + // Here we want to open the OSD Keyboard to enter the searchstring + if (control == buttonSearch) + { + // If the search Button was clicked we need to bring up the search keyboard. + VirtualKeyboard keyboard = (VirtualKeyboard)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_VIRTUAL_KEYBOARD); + if (null == keyboard) return; + string searchterm = string.Empty; + keyboard.IsSearchKeyboard = true; + keyboard.Reset(); + keyboard.Text = ""; + keyboard.DoModal(GetID); // show it... + + Log.Info("Wikipedia: OSD keyboard loaded!"); + + // If input is finished, the string is saved to the searchterm var. + if (keyboard.IsConfirmed) + searchterm = keyboard.Text; + + // If there was a string entered try getting the article. + if (searchterm != "") + { + Log.Info("Wikipedia: Searchterm gotten from OSD keyboard: {0}", searchterm); + GetAndDisplayArticle(searchterm); + } + // Else display an error dialog. + else + { + GUIDialogOK dlg = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK); + dlg.SetHeading(GUILocalizeStrings.Get(257)); // Error + dlg.SetLine(1, GUILocalizeStrings.Get(2500)); // No searchterm entered! + dlg.SetLine(2, String.Empty); + dlg.SetLine(3, GUILocalizeStrings.Get(2501)); // Please enter a valid searchterm! + dlg.DoModal(GUIWindowManager.ActiveWindow); + } + } + // This is the control to select the local Wikipedia site. + if (control == buttonLocal) + { + // Create a new selection dialog. + GUIDialogMenu pDlgOK = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU); + if (pDlgOK != null) + { + pDlgOK.Reset(); + pDlgOK.SetHeading(GUILocalizeStrings.Get(2502)); //Select your local Wikipedia: + + // Add all the local sites we want to be displayed starting with int 0. + MediaPortal.Profile.Settings langreader = new MediaPortal.Profile.Settings(Config.GetFile(Config.Dir.Config, "wikipedia.xml")); + String allsites = langreader.GetValueAsString("Allsites", "sitenames", ""); + Log.Info("Wikipedia: available sites: " + allsites); + String[] siteArray = allsites.Split(','); + for (int i = 0; i < siteArray.Length; i++) + { + int stringno = langreader.GetValueAsInt(siteArray[i], "string", 2006); + pDlgOK.Add(GUILocalizeStrings.Get(stringno)); //English, German, French ... + } + + pDlgOK.DoModal(GetID); + if (pDlgOK.SelectedLabel >= 0) + { + SelectLocalWikipedia(pDlgOK.SelectedLabel, siteArray); + } + } + } + // The Button holding the Links to other articles + if (control == buttonLinks) + { + if (linkArray.Count > 0) + { + // Create a new selection dialog. + GUIDialogMenu pDlgOK = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU); + if (pDlgOK != null) + { + pDlgOK.Reset(); + pDlgOK.SetHeading(GUILocalizeStrings.Get(2505)); //Links to other articles: + + // Add all the links from the linkarray. + foreach (string link in linkArray) + { + pDlgOK.Add(link); + } + pDlgOK.DoModal(GetID); + if (pDlgOK.SelectedLabel >= 0) + { + Log.Info("Wikipedia: new search from the links array: {0}", pDlgOK.SelectedLabelText); + GetAndDisplayArticle(pDlgOK.SelectedLabelText); + } + } + } + else + { + GUIDialogOK dlg = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK); + dlg.SetHeading(GUILocalizeStrings.Get(257)); // Error + dlg.SetLine(1, GUILocalizeStrings.Get(2506)); // No Links from this article. + dlg.DoModal(GUIWindowManager.ActiveWindow); + } + + } + // The Button containing a list of all images from the article + if (control == buttonImages) + { + if (imagedescArray.Count > 0) + { + // Create a new selection dialog. + GUIDialogMenu pDlgOK = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU); + if (pDlgOK != null) + { + pDlgOK.Reset(); + pDlgOK.SetHeading(GUILocalizeStrings.Get(2507)); //Images from this article + + // Add all the images from the imagearray. + foreach (string image in imagedescArray) + { + pDlgOK.Add(image); + } + pDlgOK.DoModal(GetID); + if (pDlgOK.SelectedLabel >= 0) + { + Log.Info("Wikipedia: new search from the image array: {0}", imagedescArray[pDlgOK.SelectedId - 1]); + GetAndDisplayImage(imagenameArray[pDlgOK.SelectedId - 1].ToString(), imagedescArray[pDlgOK.SelectedId - 1].ToString()); + } + } + } + else + { + GUIDialogOK dlg = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK); + dlg.SetHeading(GUILocalizeStrings.Get(257)); // Error + dlg.SetLine(1, GUILocalizeStrings.Get(2508)); // No Images referenced in this article. + dlg.DoModal(GUIWindowManager.ActiveWindow); + } + } + // Back to the text button to switch from image view + if (control == buttonBack) + { + if (!txtArticle.IsVisible) + GUIControl.ShowControl(GetID, txtArticle.GetID); + if (imageControl.IsVisible) + GUIControl.HideControl(GetID, imageControl.GetID); + if (!searchtermLabel.IsVisible) + GUIControl.ShowControl(GetID, searchtermLabel.GetID); + if (imagedescLabel.IsVisible) + GUIControl.HideControl(GetID, imagedescLabel.GetID); + if (buttonBack.IsVisible) + GUIControl.HideControl(GetID, buttonBack.GetID); + } + base.OnClicked(controlId, control, actionType); + } + + // Depending on which Entry was selected from the listbox we chose the language here. + private void SelectLocalWikipedia(int labelnumber, String[] siteArray) + { + MediaPortal.Profile.Settings langreader = new MediaPortal.Profile.Settings(Config.GetFile(Config.Dir.Config, "wikipedia.xml")); + language = siteArray[labelnumber]; + + if (searchtermLabel.Label != string.Empty && searchtermLabel.Label != "Wikipedia") + { + Log.Info("Wikipedia: language changed to {0}. Display article {1} again.", language, searchtermLabel.Label); + GetAndDisplayArticle(searchtermLabel.Label); + } + } + + private void GetAndDisplayImage(string imagename, string imagedesc) + { + WikipediaImage image = new WikipediaImage(imagename, language); + string imagefilename = image.GetImageFilename(); + Log.Info("Wikipedia: Trying to display image file: {0}", imagefilename); + + if (imagefilename != string.Empty && System.IO.File.Exists(imagefilename)) + { + if (txtArticle.IsVisible) + GUIControl.HideControl(GetID, txtArticle.GetID); + if (!imageControl.IsVisible) + GUIControl.ShowControl(GetID, imageControl.GetID); + if (searchtermLabel.IsVisible) + GUIControl.HideControl(GetID, searchtermLabel.GetID); + if (!imagedescLabel.IsVisible) + GUIControl.ShowControl(GetID, imagedescLabel.GetID); + if (!buttonBack.IsVisible) + GUIControl.ShowControl(GetID, buttonBack.GetID); + imagedescLabel.Label = imagedesc; + imageControl.SetFileName(imagefilename); + } + else + { + GUIDialogOK dlg = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK); + dlg.SetHeading(GUILocalizeStrings.Get(257)); // Error + dlg.SetLine(1, GUILocalizeStrings.Get(2512)); // Can't display image. + dlg.SetLine(2, GUILocalizeStrings.Get(2513)); // Please have a look at the logfile. + dlg.DoModal(GUIWindowManager.ActiveWindow); + } + } + + // The main function. + void GetAndDisplayArticle(string searchterm) + { + BackgroundWorker worker = new BackgroundWorker(); + + worker.DoWork += new DoWorkEventHandler(DownloadWorker); + worker.RunWorkerAsync(searchterm); + + while (_workerCompleted == false) + GUIWindowManager.Process(); + } + + // All kind of stuff because of the wait cursor ;-) + void DownloadWorker(object sender, DoWorkEventArgs e) + { + _workerCompleted = false; + + using (WaitCursor cursor = new WaitCursor()) + lock (this) + { + if (!txtArticle.IsVisible) + GUIControl.ShowControl(GetID, txtArticle.GetID); + if (imageControl.IsVisible) + GUIControl.HideControl(GetID, imageControl.GetID); + if (!searchtermLabel.IsVisible) + GUIControl.ShowControl(GetID, searchtermLabel.GetID); + if (imagedescLabel.IsVisible) + GUIControl.HideControl(GetID, imagedescLabel.GetID); + if (buttonBack.IsVisible) + GUIControl.HideControl(GetID, buttonBack.GetID); + linkArray.Clear(); + imagenameArray.Clear(); + imagedescArray.Clear(); + searchtermLabel.Label = e.Argument.ToString(); + WikipediaArticle article = new WikipediaArticle(e.Argument.ToString(), language); + articletext = article.GetArticleText(); + linkArray = article.GetLinkArray(); + imagenameArray = article.GetImageArray(); + imagedescArray = article.GetImagedescArray(); + language = article.GetLanguage(); + + if (articletext == "REDIRECT") + txtArticle.Label = GUILocalizeStrings.Get(2509) + "\n" + GUILocalizeStrings.Get(2510); //This page is only a redirect. Please chose the redirect aim from the link list. + else if (articletext == string.Empty) + txtArticle.Label = GUILocalizeStrings.Get(2504); //Sorry, no Article was found for your searchterm... + else + txtArticle.Label = articletext; + } + + _workerCompleted = true; + } + + volatile bool _workerCompleted = true; + } +} \ No newline at end of file Added: trunk/plugins/Documentation plugin/Documentation.csproj =================================================================== --- trunk/plugins/Documentation plugin/Documentation.csproj (rev 0) +++ trunk/plugins/Documentation plugin/Documentation.csproj 2007-03-27 09:07:31 UTC (rev 232) @@ -0,0 +1,52 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{B3A735EA-AE81-430A-AB33-214D11F5BE6E}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Documentation</RootNamespace> + <AssemblyName>Documentation</AssemblyName> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="Core, Version=1.0.2588.17924, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>D:\Apps\Desktop\MediaPortal\Core.DLL</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Windows.Forms" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Class1.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file Added: trunk/plugins/Documentation plugin/DocumentationImage.cs =================================================================== --- trunk/plugins/Documentation plugin/DocumentationImage.cs (rev 0) +++ trunk/plugins/Documentation plugin/DocumentationImage.cs 2007-03-27 09:07:31 UTC (rev 232) @@ -0,0 +1,196 @@ +#region Copyright (C) 2005-2007 Team MediaPortal + +/* + * Copyright (C) 2005-2007 Team MediaPortal + * http://www.team-mediaportal.com + * + * 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, 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 GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#endregion + +using System; +using System.ComponentModel; +using System.Windows.Forms; +using System.Net; +using System.IO; +using System.Text; +using System.Threading; +using System.Collections; +using MediaPortal.GUI.Library; +using MediaPortal.Util; +using MediaPortal.Configuration; + +namespace Wikipedia +{ + /// <summary> + /// This class holds all the logic to get an image from Wikipedia for further using in MP. + /// </summary> + public class WikipediaImage + { + #region vars + private string WikipediaURL = "http://en.wikipedia.org/wiki/Special:Export/"; + private string imagename = string.Empty; + private string imagedesc = string.Empty; + private string imageurl = string.Empty; + private string imagelocal = string.Empty; + + #endregion + + #region constructors + /// <summary>This constructor creates a new WikipediaImage</summary> + /// <summary>The name of the image and language need to be given</summary> + /// <param name="imagename">The internal name of the image like "Bild_478.jpg" in "http://de.wikipedia.org/wiki/Bild:Bild_478.jpg"</param> + /// <param name="language">Language of the Wikipedia page</param> + public WikipediaImage(string imagename, string language) + { + SetLanguage(language); + this.imagename = imagename; + GetImageUrl(); + GetImageFile(); + } + + /// <summary>This constructor creates a new WikipediaArticle.</summary> + /// <summary>Only called with a title string, language set to default.</summary> + /// <param name="title">The article's title</param> + public WikipediaImage(string imagename) + : this(imagename, "Default") + { + } + + /// <summary>This constructor creates a new WikipediaArticle if no parameter is given.</summary> + /// <summary>Uses an empty searchterm and the default language.</summary> + public WikipediaImage() + : this(string.Empty, "Default") + { + } + #endregion + + #region class methods + /// <summary>Gets the current MP language from mediaportal.xml and sets the Wikipedia URL accordingly</summary> + private void SetLanguage(string language) + { + if (language == "Default") + { + MediaPortal.Profile.Settings xmlreader = new MediaPortal.Profile.Settings(Config.GetFile(Config.Dir.Config, "MediaPortal.xml")); + language = xmlreader.GetValueAsString("skin", "language", "English"); + } + + MediaPortal.Profile.Settings detailxmlreader = new MediaPortal.Profile.Settings(Config.GetFile(Config.Dir.Config, "wikipedia.xml")); + this.WikipediaURL = detailxmlreader.GetValueAsString(language, "imageurl", "http://en.wikipedia.org/wiki/Image:"); + Log.Info("Wikipedia: Image language set to " + language + "."); + } + + /// <summary>Get the local filename of the downloaded image.</summary> + /// <returns>String: filename of the downloaded image.</returns> + public string GetImageFilename() + { + string imagelocal = Config.GetFile(Config.Dir.Thumbs, @"wikipedia\" + imagename); + return imagelocal; + } + + /// <summary>Getting the link to the full-size image.</summary> + /// <returns>String: parsed article</returns> + private void GetImageUrl() + { + string imagepage = string.Empty; + + // Build the URL to the Image page + System.Uri url = new System.Uri(WikipediaURL + this.imagename); + Log.Info("Wikipedia: Trying to get following Image page: {0}", url.ToString()); + + // Here we get the content from the web and put it to a string + try + { + WebClient client = new WebClient(); + client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"); + Stream data = client.OpenRead(url); + StreamReader reader = new StreamReader(data); + imagepage = reader.ReadToEnd(); + reader.Close(); + Log.Info("Wikipedia: Success! Downloaded all data from the image page."); + } + catch (Exception e) + { + Log.Info("Wikipedia: Exception during downloading image page:"); + Log.Info(e.ToString()); + } + + //We're searching for something like this: + //<div class="fullImageLink" id="file"><a href="http://upload.wikimedia.org/wikipedia/commons/7/7d/Bild_478.jpg"> + if (imagepage.IndexOf("class=\"fullImageLink\"") >= 0) + { + Log.Info("Wikipedia: Extracting link to full-size image."); + int iStart = imagepage.IndexOf("class=\"fullImageLink\""); + imagepage = imagepage.Substring(iStart, 1000); + + iStart = imagepage.IndexOf("href") + 6; + int iEnd = imagepage.IndexOf("\"", iStart); + + this.imageurl = imagepage.Substring(iStart, iEnd - iStart); + Log.Info("Wikipedia: URL of full-size image extracted."); + Log.Info(imageurl); + } + else + this.imageurl = string.Empty; + } + + /// <summary>Downloads the full-size image from the wikipedia page</summary> + private void GetImageFile() + { + if (imageurl != "") + { + //Check if we already have the file. + string thumbspath = Config.GetSubFolder(Config.Dir.Thumbs, @"wikipedia\"); + + //Create the wikipedia subdir in thumbs when it not exists. + if (!System.IO.Directory.Exists(thumbspath)) + System.IO.Directory.CreateDirectory(thumbspath); + + if (!System.IO.File.Exists(thumbspath + imagename)) + { + + Log.Info("Wikipedia: Trying to get following URL: {0}", imageurl); + // Here we get the image from the web and save it to disk + try + { + WebClient client = new WebClient(); + client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"); + client.DownloadFile(imageurl, thumbspath + imagename); + Log.Info("Wikipedia: Success! Image downloaded."); + } + catch (Exception e) + { + Log.Info("Wikipedia: Exception during downloading:"); + Log.Info(e.ToString()); + } + } + else + { + Log.Info("Wikipedia: Image exists, no need to redownload!"); + } + } + else + { + Log.Info("Wikipedia: No imageurl. Can't download file."); + } + } + + #endregion + } + +} \ No newline at end of file Added: trunk/plugins/Documentation plugin/DocumentationPage.cs =================================================================== --- trunk/plugins/Documentation plugin/DocumentationPage.cs (rev 0) +++ trunk/plugins/Documentation plugin/DocumentationPage.cs 2007-03-27 09:07:31 UTC (rev 232) @@ -0,0 +1,553 @@ +#region Copyright (C) 2005-2007 Team MediaPortal + +/* + * Copyright (C) 2005-2007 Team MediaPortal + * http://www.team-mediaportal.com + * + * 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, 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 GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#endregion + +using System; +using System.ComponentModel; +using System.Windows.Forms; +using System.Net; +using System.IO; +using System.Text; +using System.Threading; +using System.Collections; +using MediaPortal.GUI.Library; +using MediaPortal.Util; +using MediaPortal.Configuration; + +namespace Wikipedia +{ + /// <summary> + /// This class holds all the logic to get info from Wikipedia and parse it for further using in MP. + /// </summary> + public class WikipediaArticle + { + #region vars + private string WikipediaURL = "http://en.wikipedia.org/wiki/Special:Export/"; + private string imagePattern = "Image"; + private string title = string.Empty; + private string unparsedArticle = string.Empty; + private string parsedArticle = string.Empty; + private string language = "Default"; + private ArrayList linkArray = new ArrayList(); + private ArrayList imageArray = new ArrayList(); + private ArrayList imagedescArray = new ArrayList(); + #endregion + + #region constructors + /// <summary>This constructor creates a new WikipediaArticle</summary> + /// <summary>Searchterm and language need to be given</summary> + /// <param name="title">The article's title</param> + /// <param name="language">Language of the Wikipedia page</param> + public WikipediaArticle(string title, string language) + { + SetLanguage(language); + this.title = title; + GetWikipediaXML(); + ParseWikipediaArticle(); + ParseLinksAndImages(); + } + + /// <summary>This constructor creates a new WikipediaArticle.</summary> + /// <summary>Only called with a title string, language set to default.</summary> + /// <param name="title">The article's title</param> + public WikipediaArticle(string title) + : this(title, "Default") + { + } + + /// <summary>This constructor creates a new WikipediaArticle if no parameter is given.</summary> + /// <summary>Uses an empty searchterm and the default language.</summary> + public WikipediaArticle() + : this(string.Empty, "Default") + { + } + #endregion + + /// <summary>Gets the current MP language from mediaportal.xml and sets the Wikipedia URL accordingly</summary> + private void SetLanguage(string language) + { + if (language == "Default") + { + MediaPortal.Profile.Settings xmlreader = new MediaPortal.Profile.Settings(Config.GetFile(Config.Dir.Config, "MediaPortal.xml")); + language = xmlreader.GetValueAsString("skin", "language", "English"); + } + + this.language = language; + + MediaPortal.Profile.Settings detailxmlreader = new MediaPortal.Profile.Settings(Config.GetFile(Config.Dir.Config, "wikipedia.xml")); + this.WikipediaURL = detailxmlreader.GetValueAsString(language, "url", "http://en.wikipedia.org/wiki/Special:Export/"); + this.imagePattern = detailxmlreader.GetValueAsString(language, "imagepattern", "Image"); + Log.Info("Wikipedia: Language set to " + language + "."); + } + + /// <summary>Returns the parsed article text.</summary> + /// <returns>String: parsed article</returns> + public string GetArticleText() + { + return parsedArticle; + } + + /// <summary>Returns the title of the article. Can differ from the passed parameter on redirects for example.</summary> + /// <returns>String: title of the article</returns> + public string GetTitle() + { + return title; + } + + /// <summary>Returns all names of images.</summary> + /// <returns>StringArray: images used in this article</returns> + public ArrayList GetImageArray() + { + return imageArray; + } + + /// <summary>Returns all descriptions of images.</summary> + /// <returns>StringArray: images used in this article</returns> + public ArrayList GetImagedescArray() + { + return imagedescArray; + } + + /// <summary>Returns the titles of all linked articles.</summary> + /// <returns>StringArray: titles of linked (internal) Wikipedia articles</returns> + public ArrayList GetLinkArray() + { + return linkArray; + } + + /// <summary>Returns the currently active language.</summary> + /// <returns>String: language</returns> + public string GetLanguage() + { + return language; + } + + /// <summary>Downloads the xml content from Wikipedia and cuts metadata like version info.</summary> + private void GetWikipediaXML() + { + string wikipediaXML = string.Empty; + // Build the URL to the Wikipedia page + System.Uri url = new System.Uri(WikipediaURL + this.title); + Log.Info("Wikipedia: Trying to get following URL: {0}", url.ToString()); + + // Here we get the content from the web and put it to a string + try + { + WebClient client = new WebClient(); + client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"); + Stream data = client.OpenRead(url); + StreamReader reader = new StreamReader(data); + wikipediaXML = reader.ReadToEnd(); + reader.Close(); + Log.Info("Wikipedia: Success! Downloaded all data."); + } + catch (Exception e) + { + Log.Info("Wikipedia: Exception during downloading:"); + Log.Info(e.ToString()); + } + + if (wikipediaXML.IndexOf("<text xml:space=\"preserve\">") > 0) + { + Log.Info("Wikipedia: Extracting unparsed string."); + int iStart = 0; + int iEnd = wikipediaXML.Length; + // Start of the Entry + iStart = wikipediaXML.IndexOf("<text xml:space=\"preserve\">") + 27; + // End of the Entry + iEnd = wikipediaXML.IndexOf("</text>"); + // Extract the Text and update the var + this.unparsedArticle = wikipediaXML.Substring(iStart, iEnd - iStart); + Log.Info("Wikipedia: Unparsed string extracted."); + } + else + this.unparsedArticle = string.Empty; + } + + /// <summary>Cuts all special wiki syntax from the article to display plain text</summary> + private void ParseWikipediaArticle() + { + string tempParsedArticle = this.unparsedArticle; + + // Check if the article is empty, if so do not parse. + if (tempParsedArticle == string.Empty) + { + Log.Info("Wikipedia: Empty article found. Try another Searchterm."); + this.unparsedArticle = string.Empty; + } + // Here we check if there is only a redirect as article to handle it as a special article type + else if (tempParsedArticle.IndexOf("#REDIRECT") == 0) + { + Log.Info("Wikipedia: #REDIRECT found."); + int iStart = tempParsedArticle.IndexOf("[[") + 2; + int iEnd = tempParsedArticle.IndexOf("]]", iStart); + // Extract the Text + string keyword = tempParsedArticle.Substring(iStart, iEnd - iStart); + this.unparsedArticle = string.Empty; + this.title = keyword; + GetWikipediaXML(); + ParseWikipediaArticle(); + } + // Finally a well-formed article ;-) + else + { + Log.Info("Wikipedia: Starting parsing."); + StringBuilder builder = new StringBuilder(tempParsedArticle); + int iStart = 0; + int iEnd = 0; + + // Remove HTML comments + Log.Debug("Wikipedia: Remove HTML comments."); + while (tempParsedArticle.IndexOf("<!--") >= 0) + { + builder = new StringBuilder(tempParsedArticle); + iStart = tempParsedArticle.IndexOf("<!--"); + iEnd = tempParsedArticle.IndexOf("-->", iStart) + 6; + + try + { + builder.Remove(iStart, iEnd - iStart); + } + catch (Exception e) + { + Log.Error(e.ToString()); + Log.Error(builder.ToString()); + } + tempParsedArticle = builder.ToString(); + } + + // surrounded by {{ and }} is (atm) unusable stuff. + //Log.Debug("Wikipedia: Remove stuff between {{ and }}."); + while (tempParsedArticle.IndexOf("{{") >= 0) + { + builder = new StringBuilder(tempParsedArticle); + iStart = tempParsedArticle.IndexOf("{{"); + int iStart2 = iStart; + iEnd = tempParsedArticle.IndexOf("}}") + 2; + + // Between {{ and }} we can again have inner sets of {{ and }} + while (tempParsedArticle.IndexOf("{{", iStart2 + 2) >= 0 && tempParsedArticle.IndexOf("{{", iStart2 + 2) < iEnd) + { + iStart2 = tempParsedArticle.IndexOf("{{", iStart2 + 2); + iEnd = tempParsedArticle.IndexOf("}}", iStart2) + 2; + iEnd = tempParsedArticle.IndexOf("}}", iEnd) + 2; + } + + try + { + builder.Remove(iStart, iEnd - iStart); + } + catch (Exception e) + { + Log.Error(e.ToString()); + Log.Error(builder.ToString()); + } + + tempParsedArticle = builder.ToString(); + } + + // surrounded by {| and |} is (atm) unusable stuff. + //Log.Debug("Wikipedia: Remove stuff between {| and |}."); + while (tempParsedArticle.IndexOf("{|") >= 0) + { + builder = new StringBuilder(tempParsedArticle); + iStart = tempParsedArticle.IndexOf("{|"); + iEnd = tempParsedArticle.IndexOf("|}") + 2; + + try + { + builder.Remove(iStart, iEnd - iStart); + } + catch (Exception e) + { + Log.Error(e.ToString()); + Log.Error(builder.ToString()); + } + + tempParsedArticle = builder.ToString(); + } + + // Remove audio links. + Log.Debug("Wikipedia: Remove audio links."); + while (tempParsedArticle.IndexOf("<span") >= 0) + { + builder = new StringBuilder(tempParsedArticle); + iStart = tempParsedArticle.IndexOf("<span"); + iEnd = tempParsedArticle.IndexOf("</span>") + 13; + + try + { + builder.Remove(iStart, iEnd - iStart); + } + catch (Exception e) + { + Log.Error(e.ToString()); + Log.Error(builder.ToString()); + } + + tempParsedArticle = builder.ToString(); + } + + // Remove web references. + Log.Debug("Wikipedia: Remove web references."); + while (tempParsedArticle.IndexOf("<ref>") >= 0) + { + builder = new StringBuilder(tempParsedArticle); + iStart = tempParsedArticle.IndexOf("<ref"); + iEnd = tempParsedArticle.IndexOf("</ref>") + 12; + + try + { + builder.Remove(iStart, iEnd - iStart); + } + catch (Exception e) + { + Log.Error(e.ToString()); + Log.Error(builder.ToString()); + } + + tempParsedArticle = builder.ToString(); + } + + // Remove <br /> + Log.Debug("Wikipedia: Remove <br />."); + builder.Replace("<br />", "\n"); + builder.Replace("<br style="clear:both"/>", "\n"); + builder.Replace("<br style="clear:left"/>", "\n"); + builder.Replace("<br style="clear:right"/>", "\n"); + + // Remove <sup> + Log.Debug("Wikipedia: Remove <sup>."); + builder.Replace("<sup>", "^"); + builder.Replace("</sup>", ""); + + // surrounded by ''' and ''' is bold text, atm also unusable. + Log.Debug("Wikipedia: Remove \'\'\'."); + builder.Replace("'''", ""); + + // surrounded by '' and '' is italic text, atm also unusable. + Log.Debug("Wikipedia: Remove \'\'."); + builder.Replace("''", ""); + + // Display === as newlines (meaning new line for every ===). + Log.Debug("Wikipedia: Display === as 1 newlines."); + builder.Replace("===", "\n"); + + // Display == as newlines (meaning new line for every ==). + Log.Debug("Wikipedia: Display == as 1 newline."); + builder.Replace("==", "\n"); + + // Display * as list (meaning new line for every *). + Log.Debug("Wikipedia: Display * as list."); + builder.Replace("*", "\n +"); + + // Remove HTML whitespace. + Log.Debug("Wikipedia: Remove HTML whitespace."); + builder.Replace(" ", " "); + + // Display " as ". + Log.Debug("Wikipedia: Remove Quotations."); + builder.Replace(""", "\""); + + // Display — as -. + Log.Debug("Wikipedia: Remove —."); + builder.Replace("—", "-"); + + // Remove gallery tags. + Log.Debug("Wikipedia: Remove gallery tags."); + builder.Replace("<gallery>", ""); + builder.Replace("</gallery>", ""); + + // Remove gallery tags. + Log.Debug("Wikipedia: Remove &."); + builder.Replace("&", "&"); + + // Remove (too many) newlines + Log.Debug("Wikipedia: Remove (too many) newlines."); + builder.Replace("\n\n\n\n", "\n"); + builder.Replace("\n\n\n", "\n"); + builder.Replace("\n\n", "\n"); + + // Remove (too many) newlines + Log.Debug("Wikipedia: Remove (too many) whitespaces."); + builder.Replace(" ", " "); + builder.Replace(" ", " "); + builder.Replace(" ", " "); + + tempParsedArticle = builder.ToString(); + + // The text shouldn't start with a newline. + if (tempParsedArticle.IndexOf("\n") == 0) + tempParsedArticle.Remove(0, 2); + + // For Debug purposes it is nice to see how the whole article text is parsed until here + //Log.Debug(tempParsedArticle); + + Log.Info("Wikipedia: Finished parsing."); + this.unparsedArticle = tempParsedArticle; + } + } + + /// <summary>Gets Links out of the article. External links are thrown away, links to other wikipedia articles get into the link array, images to the image array</summary> + private void ParseLinksAndImages() + { + Log.Info("Wikipedia: Starting parsing of links and images."); + string tempParsedArticle = this.unparsedArticle; + int iStart = 0, iEnd = 0, iPipe = 0; + + // Surrounded by [[IMAGEPATTERN: and ]] are the links to IMAGES. + // We need to check for the localized image keyword but also for the English as this is commonly used in some local sites. + // Example: [[Bild:H_NeuesRathaus1.jpg|left|thumb|Das [[Neues Rathaus (Hannover)|Neue Rathaus]] mit Maschteich]] + while ((iStart = tempParsedArticle.IndexOf("[[" + imagePattern + ":", iStart)) >= 0 || (iStart = tempParsedArticle.IndexOf("[[Image:")) >= 0) + { + iEnd = tempParsedArticle.IndexOf("]]", (iStart + 2)) + 2; + int disturbingLink = iStart; + + // Descriptions of images can contain links! + // [[Bild:Hannover Merian.png|thumb|[[Matth?us Merian|Merian]]-Kupferstich um 1650, im Vordergrund Windm?hle auf dem [[Lindener Berg]]]] + while (tempParsedArticle.IndexOf("[[", disturbingLink + 2) >= 0 && tempParsedArticle.IndexOf("[[", disturbingLink + 2) < iEnd) + { + disturbingLink = tempParsedArticle.IndexOf("[[", disturbingLink + 2); + iEnd = tempParsedArticle.IndexOf("]]", disturbingLink) + 2; + iEnd = tempParsedArticle.IndexOf("]]", iEnd) + 2; + } + // Extract the Text + string keyword = tempParsedArticle.Substring(iStart, iEnd - iStart); + + //Remove all links from the image description. + while (keyword.IndexOf("[[", 2) >= 0) + { + int iStartlink = keyword.IndexOf("[[", 2); + int iEndlink = keyword.IndexOf("]]", iStartlink) + 2; + // Extract the Text + string linkkeyword = keyword.Substring(iStartlink, iEndlink - iStartlink); + + // Parse Links to other keywords. + // 1st type of keywords is like [[article|displaytext]] + // for the 2nd the article and displayed text are equal [[article]]. + if (linkkeyword.IndexOf("|") > 0) + linkkeyword = linkkeyword.Substring(linkkeyword.IndexOf("|") + 1, linkkeyword.IndexOf("]]") - linkkeyword.IndexOf("|") - 1); + else + linkkeyword = linkkeyword.Substring(linkkeyword.IndexOf("[[") + 2, linkkeyword.IndexOf("]]") - linkkeyword.IndexOf("[[") - 2); + + keyword = keyword.Substring(0, iStartlink) + linkkeyword + keyword.Substring(iEndlink, keyword.Length - iEndlink); + } + + int iStartname = keyword.IndexOf(":") + 1; + int iEndname = keyword.IndexOf("|"); + string imagename = keyword.Substring(iStartname, iEndname - iStartname); + + //Image names must not contain spaces! + imagename = imagename.Replace(" ", "_"); + + int iStartdesc = keyword.LastIndexOf("|") + 1; + int iEnddesc = keyword.LastIndexOf("]]"); + string imagedesc = keyword.Substring(iStartdesc, iEnddesc - iStartdesc); ; + + this.imageArray.Add(imagename); + this.imagedescArray.Add(imagedesc); + Log.Debug("Wikipedia: Image added: {0}, {1}", imagedesc, imagename); + + tempParsedArticle = tempParsedArticle.Substring(0, iStart) + tempParsedArticle.Substring(iEnd, tempParsedArticle.Length - iEnd); + } + + // surrounded by [[ and ]] are the links to other articles. + Log.Debug("Wikipedia: Starting Link parsing."); + string parsedKeyword, parsedLink; + iStart = iEnd = 0; + try + { + while ((iStart = tempParsedArticle.IndexOf("[[", iStart)) >= 0) + { + iEnd = tempParsedArticle.IndexOf("]]") + 2; + // Extract the Text + string keyword = tempParsedArticle.Substring(iStart, iEnd - iStart); + + // Parse Links to other keywords. + // 1st type of keywords is like [[article|displaytext]] + if ((iPipe = keyword.IndexOf("|")) > 0) + { + parsedKeyword = keyword.Substring(iPipe + 1, keyword.Length - iPipe - 3); + parsedLink = keyword.Substring(2, iPipe - 2); + if (!this.linkArray.Contains(parsedLink)) + { + this.linkArray.Add(parsedLink); + //Log.Debug("Wikipedia: Link added: {0}, {1}", parsedLink, parsedKeyword); + } + } + else if (keyword.IndexOf(":") > 0) + { + // for the 2nd a ":" is a link to the article in another language. + // TODO Add links to other languages!!! + parsedKeyword = String.Empty; + } + else + { + // for the 3rd the article and displayed text are equal [[article]]. + parsedKeyword = keyword.Substring(2, keyword.Length - 4); + if (!this.linkArray.Contains(parsedKeyword)) + { + this.linkArray.Add(parsedKeyword); + //Log.Debug("Wikipedia: Link added: {0}", parsedKeyword); + } + } + + StringBuilder builder = new StringBuilder(tempParsedArticle); + builder.Remove(iStart, iEnd - iStart); + builder.Insert(iStart, parsedKeyword); + tempParsedArticle = builder.ToString(); + } + } + catch (Exception e) + { + Log.Error("Wikipedia: {0}", e.ToString()); + Log.Error("Wikipedia: tempArticle: {0}", tempParsedArticle); + } + Log.Debug("Wikipedia: Finished Link parsing: {0} Links added.", linkArray.Count); + + // surrounded by [ and ] are external Links. Need to be removed. + Log.Debug("Wikipedia: Removing external links"); + iStart = -1; + try + { + while ((iStart = tempParsedArticle.IndexOf("[")) >= 0) + { + iEnd = tempParsedArticle.IndexOf("]") + 1; + + StringBuilder builder = new StringBuilder(tempParsedArticle); + builder.Remove(iStart, iEnd - iStart); + tempParsedArticle = builder.ToString(); + } + } + catch (Exception e) + { + Log.Error("Wikipedia: {0}", e.ToString()); + Log.Error("Parsing Error: " + tempParsedArticle + "\nSTART: " + iStart + "\nEND: " + iEnd); + } + + Log.Info("Wikipedia: Finished parsing of links and images."); + this.parsedArticle = tempParsedArticle; + } + } +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |