Commits

Christian Axelsson  committed 1c8074f Merge

Merge with SearchService

  • Participants
  • Parent commits be1a4a9, 6b5ccf0

Comments (0)

Files changed (3)

File WebApplication/SearchService.asmx

+<%@ WebService Language="C#" CodeBehind="SearchService.asmx.cs" Class="ScrewTurn.Wiki.SearchService" %>

File WebApplication/SearchService.asmx.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Script.Services;
+using System.Web.Services;
+using ScrewTurn.Wiki.PluginFramework;
+using ScrewTurn.Wiki.SearchEngine;
+
+namespace ScrewTurn.Wiki
+{
+    /// <summary>
+    /// Summary description for SearchService
+    /// </summary>
+    [WebService(Namespace = "http://inside.triona.se/webservices")]
+    [ScriptService]
+    public class SearchService : WebService
+    {
+        private const int MaxResults = 30;
+
+        /// <summary>
+        /// Performs a search.
+        /// </summary>
+        /// <param name="query">The search query.</param>
+        /// <param name="mode">The search mode.</param>
+        /// <param name="selectedCategories">The selected categories.</param>
+        /// <param name="searchUncategorized">A value indicating whether to search uncategorized pages.</param>
+        /// <param name="searchInAllNamespacesAndCategories">A value indicating whether to search in all namespaces and categories.</param>
+        /// <param name="searchFilesAndAttachments">A value indicating whether to search files and attachments.</param>
+        [WebMethod(Description = "Performs a search in the wiki and returns the results", EnableSession = true)]
+        public List<SearchResultItem> SearchWiki(string query, SearchOptions mode, List<string> selectedCategories, bool searchUncategorized, bool searchInAllNamespacesAndCategories, bool searchFilesAndAttachments)
+        {
+            SearchResultCollection results;
+
+            try
+            {
+                results = SearchTools.Search(query, true, searchFilesAndAttachments, mode);
+            }
+            catch (ArgumentException ex)
+            {
+                Log.LogEntry("Search threw an exception\n" + ex, EntryType.Warning, SessionFacade.CurrentUsername);
+                results = new SearchResultCollection();
+            }
+
+            // Build a list of SearchResultRow
+            var rows = new List<SearchResultRow>(Math.Min(results.Count, MaxResults));
+
+            var currentUser = SessionFacade.GetCurrentUsername();
+            var currentGroups = SessionFacade.GetCurrentGroupNames();
+
+            int count = 0;
+            foreach (SearchResult res in results)
+            {
+                // Filter by category
+                PageInfo currentPage = null;
+                var pageCategories = new CategoryInfo[0];
+
+                if (res.Document.TypeTag == PageDocument.StandardTypeTag)
+                {
+                    currentPage = (res.Document as PageDocument).PageInfo;
+                    pageCategories = Pages.GetCategoriesForPage(currentPage);
+
+                    // Verify permissions
+                    bool canReadPage = AuthChecker.CheckActionForPage(currentPage,
+                        Actions.ForPages.ReadPage, currentUser, currentGroups);
+                    if (!canReadPage) continue; // Skip
+                }
+                else if (res.Document.TypeTag == MessageDocument.StandardTypeTag)
+                {
+                    currentPage = (res.Document as MessageDocument).PageInfo;
+                    pageCategories = Pages.GetCategoriesForPage(currentPage);
+
+                    // Verify permissions
+                    bool canReadDiscussion = AuthChecker.CheckActionForPage(currentPage,
+                        Actions.ForPages.ReadDiscussion, currentUser, currentGroups);
+                    if (!canReadDiscussion) continue; // Skip
+                }
+                else if (res.Document.TypeTag == PageAttachmentDocument.StandardTypeTag)
+                {
+                    currentPage = (res.Document as PageAttachmentDocument).Page;
+                    pageCategories = Pages.GetCategoriesForPage(currentPage);
+
+                    // Verify permissions
+                    bool canDownloadAttn = AuthChecker.CheckActionForPage(currentPage,
+                        Actions.ForPages.DownloadAttachments, currentUser, currentGroups);
+                    if (!canDownloadAttn) continue; // Skip
+                }
+                else if (res.Document.TypeTag == FileDocument.StandardTypeTag)
+                {
+                    string[] fields = ((FileDocument)res.Document).Name.Split('|');
+                    IFilesStorageProviderV30 provider = Collectors.FilesProviderCollector.GetProvider(fields[0]);
+                    string directory = Tools.GetDirectoryName(fields[1]);
+
+                    // Verify permissions
+                    bool canDownloadFiles = AuthChecker.CheckActionForDirectory(provider, directory,
+                        Actions.ForDirectories.DownloadFiles, currentUser, currentGroups);
+                    if (!canDownloadFiles) continue; // Skip
+                }
+
+                string currentNamespace = Tools.DetectCurrentNamespace();
+                if (string.IsNullOrEmpty(currentNamespace)) currentNamespace = null;
+
+                if (currentPage != null)
+                {
+                    // Check categories match, if page is set
+                    if (searchInAllNamespacesAndCategories ||
+                        Array.Find(pageCategories,
+                        delegate(CategoryInfo c)
+                        {
+                            return selectedCategories.Contains(c.FullName);
+                        }) != null || pageCategories.Length == 0 && searchUncategorized)
+                    {
+
+                        // ... then namespace
+                        if (searchInAllNamespacesAndCategories ||
+                            NameTools.GetNamespace(currentPage.FullName) == currentNamespace)
+                        {
+                            rows.Add(SearchResultRow.CreateInstance(res));
+                            count++;
+                        }
+                    }
+                }
+                else
+                {
+                    // No associated page (-> file), add result
+                    rows.Add(SearchResultRow.CreateInstance(res));
+                    count++;
+                }
+
+                if (count >= MaxResults) break;
+            }
+
+            return buildResults(rows);
+        }
+
+        private List<SearchResultItem> buildResults(IEnumerable<SearchResultRow> result)
+        {
+            var request = HttpContext.Current.Request;
+            var appUrl = request.Url.AbsoluteUri.Replace(request.Url.AbsolutePath, string.Empty) + request.ApplicationPath;
+
+            var res = result.Select(row => new SearchResultItem
+                                               {
+                                                   Link = appUrl + row.Link,
+                                                   FormattedExcerpt = row.FormattedExcerpt,
+                                                   Relevance = row.Relevance,
+                                                   Title = row.Title,
+                                                   Type = row.Type
+                                               }).ToList();
+
+            return res;
+        }
+    }
+
+    public class SearchResultItem
+    {
+		public const string Page = "page";
+		public const string Message = "message";
+		public const string File = "file";
+		public const string Attachment = "attachment";
+
+        /// <summary>
+        /// Gets the page.
+        /// </summary>
+        public string Link { get; set; }
+
+        /// <summary>
+        /// Gets the type of the result.
+        /// </summary>
+        public string Type { get; set; }
+
+        /// <summary>
+        /// Gets the title.
+        /// </summary>
+        public string Title { get; set; }
+
+        /// <summary>
+        /// Gets the relevance.
+        /// </summary>
+        public float Relevance { get; set; }
+
+        /// <summary>
+        /// Gets the formatted excerpt.
+        /// </summary>
+        public string FormattedExcerpt { get; set; }
+    }
+}

File WebApplication/WebApplication.csproj

     <Reference Include="System.Web.Extensions.Design, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
       <RequiredTargetFramework>3.5</RequiredTargetFramework>
     </Reference>
+    <Reference Include="System.Web.Services" />
     <Reference Include="System.Xml" />
     <Reference Include="System.Configuration" />
     <Reference Include="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
     <Compile Include="Search.aspx.designer.cs">
       <DependentUpon>Search.aspx</DependentUpon>
     </Compile>
+    <Compile Include="SearchService.asmx.cs">
+      <DependentUpon>SearchService.asmx</DependentUpon>
+      <SubType>Component</SubType>
+    </Compile>
     <Compile Include="SessionRefresh.aspx.cs">
       <DependentUpon>SessionRefresh.aspx</DependentUpon>
       <SubType>ASPXCodeBehind</SubType>
     <Content Include="Register.aspx" />
     <Content Include="robots.txt" />
     <Content Include="RSS.aspx" />
+    <Content Include="SearchService.asmx" />
     <Content Include="SessionRefresh.aspx" />
     <Content Include="Themes\Admin.css" />
     <Content Include="Themes\Elegant\Icon.ico" />