From eba75d0db4a3392bd6db994ba01da3066d470847 Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Tue, 22 Jun 2021 01:25:28 +0100 Subject: [PATCH] getversions --- .../Controllers/PackagesController.Put.cs | 4 +- .../Controllers/PackagesController.cs | 78 +++++++++++++++++-- 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/nuget-host/Controllers/PackagesController.Put.cs b/src/nuget-host/Controllers/PackagesController.Put.cs index a27912b..9018f97 100644 --- a/src/nuget-host/Controllers/PackagesController.Put.cs +++ b/src/nuget-host/Controllers/PackagesController.Put.cs @@ -55,7 +55,7 @@ namespace nuget_host.Controllers var archive = new ZipArchive(fw); var nuspec = archive.Entries.FirstOrDefault(e => e.FullName.EndsWith(".nuspec")); - if (nuspec == null) return BadRequest("no nuspec from archive"); + if (nuspec == null) return BadRequest(new { error = "no nuspec from archive" }); string pkgpath; NuGetVersion version; string pkgid; @@ -105,7 +105,7 @@ namespace nuget_host.Controllers ViewData["msg"] = "existant"; ViewData["ecode"] = 1; logger.LogWarning("400 : existant"); - return BadRequest(ViewData); + return base.BadRequest(new { error = ModelState }); } else { diff --git a/src/nuget-host/Controllers/PackagesController.cs b/src/nuget-host/Controllers/PackagesController.cs index 12c9616..12ecfe5 100644 --- a/src/nuget-host/Controllers/PackagesController.cs +++ b/src/nuget-host/Controllers/PackagesController.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using NuGet.Versioning; using nuget_host.Data; using nuget_host.Entities; @@ -40,7 +41,8 @@ namespace nuget_host.Controllers // Search // GET {@id}?q={QUERY}&skip={SKIP}&take={TAKE}&prerelease={PRERELEASE}&semVerLevel={SEMVERLEVEL}&packageType={PACKAGETYPE} - [HttpGet("~/search/index.json")] + const string _apiPrefix = "~/package"; + [HttpGet(_apiPrefix + "/index.json")] public IActionResult Index( string q, string semVerLevel = defaultSemVer, @@ -52,10 +54,14 @@ namespace nuget_host.Controllers if (string.IsNullOrEmpty(q)) { ModelState.AddModelError("q", "no value"); - return NotFound(ModelState); } - else + if (take > maxTake) { + ModelState.AddModelError("take", "Maximum exceeded"); + } + if (ModelState.IsValid) + { + var scope = dbContext.Packages .Include(p => p.Versions) .Where( @@ -66,10 +72,13 @@ namespace nuget_host.Controllers var result = new { totalHits = scope.Count(), - data = scope.Skip(skip).Take(take).ToArray() + data = scope.OrderBy(p => p.Id) + .Skip(skip).Take(take).ToArray() }; return Ok(result); + } + return BadRequest(new { error = ModelState }); } protected static bool CamelCaseMatch(string id, string q) @@ -96,8 +105,9 @@ namespace nuget_host.Controllers } return false; } + const int maxTake = 100; // GET /autocomplete?id=nuget.protocol&prerelease=true - [HttpGet("~/autocomplete")] + [HttpGet(_apiPrefix + "/autocomplete")] public IActionResult AutoComplete( string id, string semVerLevel = defaultSemVer, @@ -106,18 +116,72 @@ namespace nuget_host.Controllers int skip = 0, int take = 25) { + if (take > maxTake) + { + ModelState.AddModelError("take", "Maximum exceeded"); + return BadRequest(ModelState); + } + var scope = dbContext.PackageVersions.Where( + v => v.PackageId == id + && (prerelease || !v.IsPrerelease) + && (packageType == null || v.Type == packageType) + ) + .OrderBy(v => v.FullString); + return Ok(new + { + data =scope.Select(v => v.FullString) + .Skip(skip).Take(take).ToArray(), + totalHits = scope.Count() + }); + } + // TODO GET {@id}/{LOWER_ID}/index.json + // LOWER_ID URL string yes The package ID, lowercased + // response : versions array of strings yes The versions available + [HttpGet(_apiPrefix + "/{id}/{lower}/index.json")] + public IActionResult GetVersions( + string id, + string lower, + bool prerelease = false, + string packageType = null, + int skip = 0, + int take = 25) + { + if (take > maxTake) + { + ModelState.AddModelError("take", "Maximum exceeded"); + } + // NugetVersion + if (!NuGetVersion.TryParse(lower, out NuGetVersion parsedVersion)) + { + ModelState.AddModelError("lower", "invalid version string"); + } + if (!ModelState.IsValid) + { + return BadRequest(ModelState); + } return Ok(new { - data = + // TODO stocker MetaData plutôt que FullString en base, + // et en profiter pour corriger ce listing + versions = dbContext.PackageVersions.Where( v => v.PackageId == id && (prerelease || !v.IsPrerelease) && (packageType == null || v.Type == packageType) - ).Select(v => v.FullString) + && (parsedVersion.CompareTo(new SemanticVersion(v.Major, v.Minor, v.Patch)) < 0) + ) + .OrderBy(v => v.FullString) + .Select(v => v.FullString) .Skip(skip).Take(take).ToArray() }); } + // TODO GET GET {@id}/{LOWER_ID}/{LOWER_VERSION}/{LOWER_ID}.{LOWER_VERSION}.nupkg + // LOWER_ID URL string yes The package ID, lowercase + // LOWER_VERSION URL string yes The package version, normalized and lowercased + // response 200 : the package + // TODO GET {@id}/{LOWER_ID}/{LOWER_VERSION}/{LOWER_ID}.nuspec + // response 200 : the nuspec } } \ No newline at end of file