public PackageSpec(string name, string exactVersion, string constraint = null, string fullSpec = null) : this(name, PackageVersion.TryParse(exactVersion), constraint, fullSpec) { }
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); } } }
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()); }