The class encapsulates the list of the index hits
Наследование: System.Collections.CollectionBase, IEnumerable, IEnumerator
Пример #1
0
        /// <summary>
        /// Executes the search using the currently entered text
        /// </summary>
        private void LaunchSearch(bool interactive)
        {
            if (indexes.Count == 0)
            {
                return;
            }

            searchStatusLabel.Text = String.Format(Properties.Resources.SearchingForTerm, searchBox.Text);

            searchLaunched = true;

            searchIdentifier++;

            if (!interactive)
            {
                SearchItem si = new SearchItem();

                si.SearchIdentifier = searchIdentifier;
                si.SearchText       = searchBox.Text;

                ThreadPool.QueueUserWorkItem(BackgroundSearch, si);

                return;
            }

            HitCollection hits = Indexer.Search(searchBox.Text, indexes.Values, Indexer.MAX_SEARCH_HITS);

            searchStatusLabel.Text = String.Empty;

            if (String.IsNullOrEmpty(hits.ErrorMessages))
            {
                loadingResults = true;

                hitsBox.DataSource   = hits;
                hitsBox.SelectedItem = null;

                loadingResults = false;

                if (hits.HadMoreHits)
                {
                    searchStatusLabel.Text = String.Format(Properties.Resources.ShowingXTopResults, Indexer.MAX_SEARCH_HITS.ToString());
                }

                if (hits.Count > 0)
                {
                    hitsBox.SetSelected(0, true);

                    PageInfo page = hitsBox.SelectedItem as PageInfo;

                    webBrowser.Navigate(WebServer.Instance.GenerateUrl(page));
                }
            }
            else
            {
                MessageBox.Show(this, hits.ErrorMessages, Properties.Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Пример #2
0
        /// <summary>
        /// Sends the frame page to the client.
        /// GET request will be sent to request/result.xml?n=5&p=1&s=searchstring where
        /// n is the maximum number of items per page, the number of <item> allowed in this file
        /// p is the current page number, if there are multipage pages, page number starts from 1, 2, 3...,
        /// s is the search query string
        /// </summary>
        void ServeRCResultPage()
        {
            // Parse parameters
            NameValueCollection qscoll = Util.ParseHtmlQuery(RequestUri);
            int numItemsPerPage = Int32.Parse(qscoll.Get("n"));
            int pageNumber = Int32.Parse(qscoll.Get("p"));
            string queryString = qscoll.Get("s");

            string resultsString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

            List<Lucene.Net.Documents.Document> tempLuceneResults = new List<Lucene.Net.Documents.Document>();
            List<Lucene.Net.Documents.Document> filteredLuceneResults = new List<Lucene.Net.Documents.Document>();
            HitCollection wikiResults = new HitCollection();
            int currentItemNumber = 0;
            if (queryString.Trim().Length > 0)
            {
                // Query the Wiki index
                wikiResults = Indexer.Search(queryString, RCLocalProxy.WikiIndices.Values, Indexer.MAX_SEARCH_HITS);

                // Query our RuralCafe index
                List<Lucene.Net.Documents.Document> luceneResults = IndexWrapper.Query(((RCLocalProxy)_proxy).IndexPath, queryString);

                // remove duplicates
                foreach (Lucene.Net.Documents.Document document in luceneResults)
                {
                    string documentUri = document.Get("uri");
                    string documentTitle = document.Get("title");

                    // ignore blacklisted domains
                    if (IsBlacklisted(documentUri))
                    {
                        continue;
                    }

                    bool exists = false;
                    foreach (Lucene.Net.Documents.Document tempDocument in tempLuceneResults)
                    {
                        string documentUri2 = tempDocument.Get("uri");
                        string documentTitle2 = tempDocument.Get("title");
                        if (String.Compare (documentUri, documentUri2) == 0 || String.Compare (documentTitle, documentTitle2)==0)
                        {
                            exists = true;
                            break;
                        }
                    }
                    if (exists == false)
                    {
                        currentItemNumber++;
                        tempLuceneResults.Add(document);
                        if ((currentItemNumber  > ((pageNumber - 1) * numItemsPerPage)) &&
                            (currentItemNumber < (pageNumber * numItemsPerPage) + 1))
                        {
                            filteredLuceneResults.Add(document);
                        }
                    }

                }
            }

            LogDebug(filteredLuceneResults.Count + " results");

            resultsString = resultsString + "<search total=\"" + currentItemNumber + "\">"; //laura: total should be the total number of results
            // Local Search Results
            for (int i = 0; i < filteredLuceneResults.Count; i++)
            {
                Lucene.Net.Documents.Document result = filteredLuceneResults.ElementAt(i);

                string uri = System.Security.SecurityElement.Escape(result.Get("uri")); // escape xml string
                string title = System.Security.SecurityElement.Escape(result.Get("title")); //escape xml string
                string displayUri = uri;
                string contentSnippet = "";

                // JAY: find content snippet here
                //contentSnippet =
                if (uri.StartsWith("http://")) //laura: obmit http://
                    uri=uri.Substring(7);
                resultsString = resultsString +
                                "<item>" +
                                "<title>" + title + "</title>" +
                                "<url>" + uri + "</url>" +
                                "<snippet>" + contentSnippet + "</snippet>" +
                                "</item>";
            }

            resultsString = resultsString + "</search>";

            SendOkHeaders("text/xml", "Cache-Control: no-cache" + "\r\n" +
                                      "Pragma: no-cache" + "\r\n" +
                                      "Expires: -1" + "\r\n");
            SendMessage(resultsString);
        }
Пример #3
0
        /// <summary>
        /// Searches for the specified term in the index.
        /// </summary>
        /// <param name="term">The term.</param>
        public static HitCollection Search(string term, IEnumerable<Indexer> indexers, int maxResults)
        {
            foreach (Indexer ixr in indexers)
            {
                if (!ixr.indexExists ||
                    ixr.searcher == null)
                {
                    throw new Exception("The index does not exist for " + ixr.filePath);
                }
            }

            string searchRequest = String.Format("title:{0} AND -\"Image:\"", term);

            HitCollection ret = new HitCollection();

            SearchItem si = new SearchItem();

            si.Hits = ret;
            si.SearchRequest = searchRequest;
            si.MaxResults = maxResults;

            // I can't really be sure about the thread safety of Lucene

            lock (typeof(Indexer))
            {
                foreach (Indexer ixr in indexers)
                {
                    int i = 0;

                    while (ixr.searchRunning &&
                        i < 30)
                    {
                        Thread.Sleep(100);

                        i++;
                    }

                    if (i >= 30)
                    {
                        throw new Exception("Failed starting the search work item due to timeout");
                    }

                    ixr.searchRunning = true;
                }

                foreach (Indexer ixr in indexers)
                {
                    ThreadPool.QueueUserWorkItem(ixr.Search, si);
                }

                foreach (Indexer ixr in indexers)
                {
                    int i = 0;

                    while (ixr.searchRunning &&
                        i < 100)
                    {
                        Thread.Sleep(100);

                        i++;
                    }

                    if (i >= 30)
                    {
                        throw new Exception("Failed finishing the search work item due to timeout");
                    }
                }
            }

            return ret;
        }
Пример #4
0
        /// <summary>
        /// Gets called whenever the browser control requests a URL from the web server
        /// </summary>
        /// <param name="sender">Web server instance</param>
        /// <param name="e">Request parameters</param>
        private void Web_UrlRequested(object sender, UrlRequestedEventArgs e)
        {
            string response = "Not found";
            string redirect = String.Empty;

            if (!String.IsNullOrEmpty(e.TeXEquation))
            {
                return;
            }

            string topic = e.TopicName.Replace('_', ' ').Trim();

            if (topic.Contains("#"))
            {
                topic = topic.Substring(0, topic.IndexOf('#')).Trim();
            }

            PageInfo page = hitsBox.SelectedItem as PageInfo;

            if (page != null &&
                topic.Equals(page.Name, StringComparison.InvariantCultureIgnoreCase) &&
                e.IndexName.Equals(page.Indexer.File, StringComparison.InvariantCultureIgnoreCase) &&
                !IsCircularRedirect(page))
            {
                response = page.GetFormattedContent();
                redirect = page.RedirectToTopic;
            }
            else
            {
                List <Indexer> searchArea = new List <Indexer>();

                // This is an internal link

                if (String.IsNullOrEmpty(e.IndexName))
                {
                    if (page != null)
                    {
                        searchArea.Add(page.Indexer);
                    }
                    else
                    {
                        foreach (Indexer ixr in indexes.Values)
                        {
                            searchArea.Add(ixr);
                        }
                    }
                }
                else
                {
                    foreach (Indexer ixr in indexes.Values)
                    {
                        if (ixr.File.Equals(e.IndexName, StringComparison.InvariantCultureIgnoreCase))
                        {
                            searchArea.Add(ixr);

                            break;
                        }
                    }
                }

                if (searchArea.Count > 0)
                {
                    HitCollection hits = Indexer.Search(topic, searchArea, 100);

                    bool exactTopicLocated = false;

                    foreach (PageInfo pi in hits)
                    {
                        if (pi.Name.Trim().Equals(topic, StringComparison.InvariantCultureIgnoreCase) &&
                            !IsCircularRedirect(pi))
                        {
                            response = pi.GetFormattedContent();
                            redirect = pi.RedirectToTopic;

                            exactTopicLocated = true;

                            break;
                        }
                    }

                    if (hits.Count > 0 &&
                        !exactTopicLocated)
                    {
                        foreach (PageInfo pi in hits)
                        {
                            if (String.IsNullOrEmpty(pi.RedirectToTopic))
                            {
                                response = pi.GetFormattedContent();
                                redirect = pi.RedirectToTopic;

                                exactTopicLocated = true;

                                break;
                            }
                        }

                        if (!exactTopicLocated)
                        {
                            foreach (PageInfo pi in hits)
                            {
                                if (!IsCircularRedirect(pi))
                                {
                                    response = pi.GetFormattedContent();
                                    redirect = pi.RedirectToTopic;

                                    break;
                                }
                            }
                        }
                    }
                }
            }

            e.Redirect       = !String.IsNullOrEmpty(redirect);
            e.RedirectTarget = redirect;
            e.Response       = Encoding.UTF8.GetBytes(response);
            e.MimeType       = "text/html";

            if (String.IsNullOrEmpty(redirect))
            {
                autoRedirects.Clear();
            }
            else
            {
                autoRedirects.Push(redirect);
            }
        }
Пример #5
0
        /// <summary>
        /// Searches for the specified term in the index.
        /// </summary>
        /// <param name="term">The term.</param>
        public static HitCollection Search(string queryString, IEnumerable <Indexer> indexers, int maxResults)
        {
            foreach (Indexer ixr in indexers)
            {
                if (!ixr.indexExists ||
                    ixr.searcher == null)
                {
                    throw new Exception(String.Format(Properties.Resources.IndexDoesNotExist, ixr.filePath));
                }
            }

            HitCollection ret = new HitCollection();

            SearchItem si = new SearchItem();

            si.Hits          = ret;
            si.SearchRequest = queryString;
            si.MaxResults    = maxResults;
            si.Errors        = new Queue <Exception>();

            int indexersNumber = 0;

            // I can't really be sure about the thread safety of Lucene

            try
            {
                lock (typeof(Indexer))
                {
                    foreach (Indexer ixr in indexers)
                    {
                        indexersNumber++;

                        int i = 0;

                        while (ixr.searchRunning &&
                               i < 30)
                        {
                            Thread.Sleep(100);

                            i++;
                        }

                        if (i >= 30)
                        {
                            throw new Exception(Properties.Resources.FailedStartingSearch);
                        }

                        ixr.searchRunning = true;
                    }

                    foreach (Indexer ixr in indexers)
                    {
                        ThreadPool.QueueUserWorkItem(ixr.Search, si);
                    }

                    foreach (Indexer ixr in indexers)
                    {
                        int i = 0;

                        while (ixr.searchRunning &&
                               i < 30)
                        {
                            Thread.Sleep(100);

                            i++;
                        }

                        if (i >= 30)
                        {
                            throw new Exception(Properties.Resources.FailedFinishingSearch);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                lock (si.Errors)
                {
                    si.Errors.Enqueue(ex);
                }
            }

            StringCollection sc = new StringCollection();

            lock (si.Errors)
            {
                while (si.Errors.Count > 0)
                {
                    Exception ex = si.Errors.Dequeue();

                    if (!sc.Contains(ex.Message))
                    {
                        sc.Add(ex.Message);
                    }
                }
            }

            StringBuilder sb = new StringBuilder();

            foreach (string message in sc)
            {
                sb.AppendLine(message);
            }

            ret.ErrorMessages = sb.Length > 0 ? sb.ToString() : String.Empty;

            if (indexersNumber > 1)
            {
                PageInfo[] arr = new PageInfo[ret.Count];

                for (int i = 0; i < ret.Count; i++)
                {
                    arr[i] = ret[i];
                }

                Array.Sort <PageInfo>(arr,
                                      delegate(PageInfo a, PageInfo b)
                {
                    return(a.Score < b.Score ? 1 : (a.Score > b.Score ? -1 : 0));
                });

                ret.Clear();

                foreach (PageInfo pi in arr)
                {
                    ret.Add(pi);
                }
            }

            return(ret);
        }
Пример #6
0
        /// <summary>
        /// Searches for the specified term in the index.
        /// </summary>
        /// <param name="term">The term.</param>
        public static HitCollection Search(string queryString, IEnumerable<Indexer> indexers, int maxResults)
        {
            foreach (Indexer ixr in indexers)
            {
                if (!ixr.indexExists ||
                    ixr.searcher == null)
                {
                    throw new Exception(String.Format(Properties.Resources.IndexDoesNotExist, ixr.filePath));
                }
            }

            HitCollection ret = new HitCollection();

            SearchItem si = new SearchItem();

            si.Hits = ret;
            si.SearchRequest = queryString;
            si.MaxResults = maxResults;
            si.Errors = new Queue<Exception>();

            int indexersNumber = 0;

            // I can't really be sure about the thread safety of Lucene

            try
            {
                lock (typeof(Indexer))
                {
                    foreach (Indexer ixr in indexers)
                    {
                        indexersNumber++;

                        int i = 0;

                        while (ixr.searchRunning &&
                            i < 30)
                        {
                            Thread.Sleep(100);

                            i++;
                        }

                        if (i >= 30)
                        {
                            throw new Exception(Properties.Resources.FailedStartingSearch);
                        }

                        ixr.searchRunning = true;
                    }

                    foreach (Indexer ixr in indexers)
                    {
                        ThreadPool.QueueUserWorkItem(ixr.Search, si);
                    }

                    foreach (Indexer ixr in indexers)
                    {
                        int i = 0;

                        while (ixr.searchRunning &&
                            i < 30)
                        {
                            Thread.Sleep(100);

                            i++;
                        }

                        if (i >= 30)
                        {
                            throw new Exception(Properties.Resources.FailedFinishingSearch);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                lock (si.Errors)
                {
                    si.Errors.Enqueue(ex);
                }
            }

            StringCollection sc = new StringCollection();

            lock (si.Errors)
            {
                while (si.Errors.Count > 0)
                {
                    Exception ex = si.Errors.Dequeue();

                    if (!sc.Contains(ex.Message))
                    {
                        sc.Add(ex.Message);
                    }
                }
            }

            StringBuilder sb = new StringBuilder();

            foreach (string message in sc)
            {
                sb.AppendLine(message);
            }

            ret.ErrorMessages = sb.Length > 0 ? sb.ToString() : String.Empty;

            if (indexersNumber > 1)
            {
                PageInfo[] arr = new PageInfo[ret.Count];

                for (int i = 0; i < ret.Count; i++)
                {
                    arr[i] = ret[i];
                }

                Array.Sort<PageInfo>(arr,
                    delegate(PageInfo a, PageInfo b)
                    {
                        return (a.Score < b.Score ? 1 : (a.Score > b.Score ? -1 : 0));
                    });

                ret.Clear();

                foreach (PageInfo pi in arr)
                {
                    ret.Add(pi);
                }
            }

            return ret;
        }