Cmdlets/src/XpandPwsh.Cmdlets/Nuget/Get-NugetPackageDownloadsCount.cs
using System;
using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Management.Automation; using System.Net; using System.Reactive.Linq; using System.Reactive.Threading.Tasks; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using XpandPwsh.CmdLets; namespace XpandPwsh.Cmdlets.Nuget{ [Cmdlet(VerbsCommon.Get, "NugetPackageDownloadsCount")] [CmdletBinding] [CmdLetTag(CmdLetTag.Nuget,CmdLetTag.Reactive,CmdLetTag.RX)][PublicAPI] public class GetNugetPackageDownloadsCount : XpandCmdlet{ private ConcurrentBag<string> _packages; [Parameter(ValueFromPipeline = true, Mandatory = true)] public string Id{ get; set; } [Parameter] public SwitchParameter Latest{ get; set; } [Parameter] public Version Version{ get; set; } protected override Task BeginProcessingAsync(){ _packages = new ConcurrentBag<string>(); return base.BeginProcessingAsync(); } protected override Task ProcessRecordAsync(){ _packages.Add(Id); return Task.CompletedTask; } protected override async Task EndProcessingAsync(CancellationToken cancellationToken){ var concurrentBag = _packages; var downloads = Downloads(concurrentBag,Latest,Version); var sum = await downloads; WriteObject(sum); } public static IObservable<int> Downloads(IEnumerable<string> packages,bool latest=false,Version version=null){ var query = packages.ToObservable() .SelectMany(id => Observable.Using(() => new WebClient(), client => client .DownloadStringTaskAsync( $"https://api-v2v3search-0.nuget.org/query?q=packageid:{id}").ToObservable())); var downloads = query .Sum(json => { var data = JsonConvert.DeserializeObject<dynamic>(json).data; if (data.Count == 0) return 0; data = data[0]; if (latest){ return data.versions.Last.downloads; } if (version != null){ return ((dynamic) ((JArray) data.versions).Children<JObject>().First(o => o["version"].ToString() ==version.ToString())).downloads; } return (int) data.totalDownloads; }); return downloads; } } } |