Example #1
0
 public PackageSpec(string name, string exactVersion, string constraint = null, string fullSpec = null)
     : this(name, PackageVersion.TryParse(exactVersion), constraint, fullSpec)
 {
 }
Example #2
0
        public async Task <PackageSpec> GetPackageInfoAsync(PackageSpec entry, CancellationToken cancel)
        {
            string        description = null;
            List <string> versions    = null;

            bool useCache = IsInLiveCache(entry.Name);

            if (useCache)
            {
                using (await _cacheLock.LockAsync(cancel)) {
                    PackageSpec result;
                    if (_cache.TryGetValue(entry.Name, out result))
                    {
                        return(result.Clone());
                    }
                    else
                    {
                        return(new PackageSpec());
                    }
                }
            }

            TaskCompletionSource <PackageSpec> tcs = null;
            Task <PackageSpec> t = null;

            lock (_activeRequests) {
                if (_activeRequests.TryGetValue(entry.Name, out tcs))
                {
                    t = tcs.Task;
                }
                else
                {
                    _activeRequests[entry.Name] = tcs = new TaskCompletionSource <PackageSpec>();
                }
            }

            if (t != null)
            {
                return((await t).Clone());
            }

            try {
                using (var client = new WebClient()) {
                    Stream data;
                    client.Headers[HttpRequestHeader.UserAgent] = UserAgent;
                    try {
                        data = await client.OpenReadTaskAsync(new Uri(Index, entry.Name + "/json"))
                               .ConfigureAwait(false);
                    } catch (WebException) {
                        // No net access or no such package
                        AddToLiveCache(entry.Name);
                        return(new PackageSpec());
                    }

                    try {
                        using (var reader = JsonReaderWriterFactory.CreateJsonReader(data, new XmlDictionaryReaderQuotas())) {
                            var doc = XDocument.Load(reader);

                            // TODO: Get package URL
                            //url = (string)doc.Document
                            //    .Elements("root")
                            //    .Elements("info")
                            //    .Elements("package_url")
                            //    .FirstOrDefault();

                            description = (string)doc.Document
                                          .Elements("root")
                                          .Elements("info")
                                          .Elements("description")
                                          .FirstOrDefault();

                            versions = doc.Document
                                       .Elements("root")
                                       .Elements("releases")
                                       .Elements()
                                       .Attributes("item")
                                       .Select(a => a.Value)
                                       .ToList();
                        }
                    } catch (InvalidOperationException) {
                    }
                }

                bool        changed = false;
                PackageSpec result;

                using (await _cacheLock.LockAsync(cancel)) {
                    if (!_cache.TryGetValue(entry.Name, out result))
                    {
                        result = _cache[entry.Name] = new PackageSpec(entry.Name);
                    }

                    if (!string.IsNullOrEmpty(description))
                    {
                        var lines     = description.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
                        var firstLine = string.Join(
                            " ",
                            lines.TakeWhile(s => !IsSeparatorLine(s)).Select(s => s.Trim())
                            );
                        if (firstLine.Length > 500)
                        {
                            firstLine = firstLine.Substring(0, 497) + "...";
                        }
                        if (firstLine == "UNKNOWN")
                        {
                            firstLine = string.Empty;
                        }

                        result.Description = firstLine;
                        changed            = true;
                    }

                    if (versions != null)
                    {
                        var updateVersion = PackageVersion.TryParseAll(versions)
                                            .Where(v => v.IsFinalRelease)
                                            .OrderByDescending(v => v)
                                            .FirstOrDefault();
                        result.ExactVersion = updateVersion;
                        changed             = true;
                    }
                }

                if (changed)
                {
                    TriggerWriteCacheToDisk();
                    AddToLiveCache(entry.Name);
                }

                var r = result.Clone();

                // Inform other waiters that we have completed
                tcs.TrySetResult(r);

                return(r);
            } catch (Exception ex) {
                tcs.TrySetException(ex);
                throw;
            } finally {
                lock (_activeRequests) {
                    _activeRequests.Remove(entry.Name);
                }
            }
        }
Example #3
0
        public async Task <PackageSpec> GetPackageInfoAsync(PackageSpec entry, CancellationToken cancel)
        {
            string        description = null;
            List <string> versions    = null;

            lock (NotOnPyPI) {
                if (NotOnPyPI.Contains(entry.Name))
                {
                    return(new PackageSpec());
                }
            }

            using (var client = new WebClient()) {
                Stream data;
                try {
                    data = await client.OpenReadTaskAsync(new Uri(_index ?? DefaultIndex, entry.Name + "/json"));
                } catch (WebException ex) {
                    if ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound)
                    {
                        lock (NotOnPyPI) {
                            NotOnPyPI.Add(entry.Name);
                        }
                    }

                    // No net access or no such package
                    return(new PackageSpec());
                }

                try {
                    using (var reader = JsonReaderWriterFactory.CreateJsonReader(data, new XmlDictionaryReaderQuotas())) {
                        var doc = XDocument.Load(reader);

                        // TODO: Get package URL
                        //url = (string)doc.Document
                        //    .Elements("root")
                        //    .Elements("info")
                        //    .Elements("package_url")
                        //    .FirstOrDefault();

                        description = (string)doc.Document
                                      .Elements("root")
                                      .Elements("info")
                                      .Elements("description")
                                      .FirstOrDefault();

                        versions = doc.Document
                                   .Elements("root")
                                   .Elements("releases")
                                   .Elements()
                                   .Attributes("item")
                                   .Select(a => a.Value)
                                   .ToList();
                    }
                } catch (InvalidOperationException) {
                }
            }

            bool        changed = false;
            PackageSpec result;

            using (await _cacheLock.LockAsync(cancel)) {
                if (!_cache.TryGetValue(entry.Name, out result))
                {
                    result = _cache[entry.Name] = new PackageSpec(entry.Name);
                }

                if (!string.IsNullOrEmpty(description))
                {
                    var lines     = description.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
                    var firstLine = string.Join(
                        " ",
                        lines.TakeWhile(s => !IsSeparatorLine(s)).Select(s => s.Trim())
                        );
                    if (firstLine.Length > 500)
                    {
                        firstLine = firstLine.Substring(0, 497) + "...";
                    }
                    if (firstLine == "UNKNOWN")
                    {
                        firstLine = string.Empty;
                    }

                    result.Description = firstLine;
                    changed            = true;
                }

                if (versions != null)
                {
                    var updateVersion = PackageVersion.TryParseAll(versions)
                                        .Where(v => v.IsFinalRelease)
                                        .OrderByDescending(v => v)
                                        .FirstOrDefault();
                    result.ExactVersion = updateVersion;
                    changed             = true;
                }
            }

            if (changed)
            {
                TriggerWriteCacheToDisk();
            }

            return(result.Clone());
        }