예제 #1
0
        protected static SearchFilter GetSearchFilter(bool allVersionsInIndex, string url, string searchTerm, bool includePrerelease)
        {
            if (url == null)
            {
                return(SearchFilter.Empty());
            }

            int indexOfQuestionMark = url.IndexOf('?');

            if (indexOfQuestionMark == -1)
            {
                return(SearchFilter.Empty());
            }

            string path  = url.Substring(0, indexOfQuestionMark);
            string query = url.Substring(indexOfQuestionMark + 1);

            if (string.IsNullOrEmpty(query))
            {
                return(SearchFilter.Empty());
            }

            var searchFilter = new SearchFilter()
            {
                // The way the default paging works is WCF attempts to read up to the MaxPageSize elements. If it finds as many, it'll assume there
                // are more elements to be paged and generate a continuation link. Consequently we'll always ask to pull MaxPageSize elements so WCF generates the
                // link for us and then allow it to do a Take on the results. Further down, we'll also parse $skiptoken as a custom IDataServicePagingProvider
                // sneakily injects the Skip value in the continuation token.
                Take              = MaxPageSize,
                Skip              = 0,
                CountOnly         = path.EndsWith("$count", StringComparison.Ordinal),
                IsValid           = true,
                SearchTerm        = searchTerm,
                IncludePrerelease = includePrerelease,
            };

            string[] props = query.Split('&');

            IDictionary <string, string> queryTerms = new Dictionary <string, string>();

            foreach (string prop in props)
            {
                string[] nameValue = prop.Split('=');
                if (nameValue.Length == 2)
                {
                    queryTerms[nameValue[0]] = nameValue[1];
                }
            }
            searchFilter.QueryTerms = queryTerms;

            string filter;

            if (queryTerms.TryGetValue("$filter", out filter))
            {
                if (!(filter.Equals("IsLatestVersion", StringComparison.Ordinal) || filter.Equals("IsAbsoluteLatestVersion", StringComparison.Ordinal) ||
                      filter.Contains("IsLatestVersion") || filter.Contains("IsAbsoluteLatestVersion")))
                {
                    searchFilter.IncludeAllVersions = true;
                }
            }
            else
            {
                searchFilter.IncludeAllVersions = true;
            }

            // We'll only use the index if we the query searches for latest \ latest-stable packages
            // if all versions are not available in the index
            if (searchFilter.IncludeAllVersions && !allVersionsInIndex)
            {
                searchFilter.IsValid             = false;
                searchFilter.FilterInvalidReason = SearchFilterInvalidReason.DueToAllVersionsRequested;
            }

            string skipStr;

            if (queryTerms.TryGetValue("$skip", out skipStr))
            {
                int skip;
                if (int.TryParse(skipStr, out skip))
                {
                    searchFilter.Skip = skip;
                }
            }

            string topStr;

            if (queryTerms.TryGetValue("$top", out topStr))
            {
                int top;
                if (int.TryParse(topStr, out top))
                {
                    searchFilter.Take = Math.Min(top, MaxPageSize);
                }
            }

            string skipTokenStr;

            if (queryTerms.TryGetValue("$skiptoken", out skipTokenStr))
            {
                var skipTokenParts = skipTokenStr.Split(',');
                if (skipTokenParts.Length == 3)  // this means our custom IDataServicePagingProvider did its magic by sneaking the Skip value into the SkipToken
                {
                    int skip;
                    if (int.TryParse(skipTokenParts[2], out skip))
                    {
                        searchFilter.Skip = skip;
                    }
                }
            }

            //  only certain orderBy clauses are supported from the Lucene search
            string orderBy;

            if (queryTerms.TryGetValue("$orderby", out orderBy))
            {
                if (string.IsNullOrEmpty(orderBy))
                {
                    searchFilter.SortProperty = SortProperty.Relevance;
                }
                else if (orderBy.StartsWith("DownloadCount", StringComparison.Ordinal))
                {
                    searchFilter.SortProperty = SortProperty.DownloadCount;
                }
                else if (orderBy.StartsWith("Published", StringComparison.Ordinal))
                {
                    searchFilter.SortProperty = SortProperty.Recent;
                }
                else if (orderBy.StartsWith("LastEdited", StringComparison.Ordinal))
                {
                    searchFilter.SortProperty = SortProperty.Recent;
                }
                else if (orderBy.StartsWith("Id", StringComparison.Ordinal))
                {
                    searchFilter.SortProperty = SortProperty.DisplayName;
                }
                else if (orderBy.StartsWith("concat", StringComparison.Ordinal))
                {
                    searchFilter.SortProperty = SortProperty.DisplayName;

                    if (orderBy.Contains("%20desc"))
                    {
                        searchFilter.SortDirection = SortDirection.Descending;
                    }
                }
                else
                {
                    searchFilter.IsValid = false;
                }
            }
            else
            {
                searchFilter.SortProperty = SortProperty.Relevance;
            }

            return(searchFilter);
        }
        public IQueryable <V2FeedPackage> Search(string searchTerm, string targetFramework, bool includePrerelease)
        {
            var packages        = PackageRepo.GetAll().Where(p => p.StatusForDatabase == PackageStatusType.Submitted.GetDescriptionOrValue());
            var packageVersions = SearchCore(packages, searchTerm, targetFramework, includePrerelease, SearchFilter.Empty()).ToV2FeedPackageQuery(GetSiteRoot()).ToList();

            if (!includePrerelease)
            {
                return(packageVersions.Where(p => !p.IsPrerelease).AsQueryable());
            }

            return(packageVersions.AsQueryable());
        }