refact
This commit is contained in:
parent
5de53a3cba
commit
476d35ae8a
270 changed files with 477 additions and 401 deletions
|
|
@ -1,243 +0,0 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
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;
|
||||
|
||||
namespace nuget_host.Controllers
|
||||
{
|
||||
|
||||
[AllowAnonymous]
|
||||
public partial class PackagesController : Controller
|
||||
{
|
||||
private readonly ILogger<PackagesController> logger;
|
||||
private readonly IDataProtector protector;
|
||||
|
||||
private readonly NugetSettings nugetSettings;
|
||||
ApplicationDbContext dbContext;
|
||||
|
||||
public PackagesController(
|
||||
ILoggerFactory loggerFactory,
|
||||
IDataProtectionProvider provider,
|
||||
IOptions<NugetSettings> nugetOptions,
|
||||
ApplicationDbContext dbContext)
|
||||
{
|
||||
logger = loggerFactory.CreateLogger<PackagesController>();
|
||||
nugetSettings = nugetOptions.Value;
|
||||
protector = provider.CreateProtector(nugetSettings.ProtectionTitle);
|
||||
this.dbContext = dbContext;
|
||||
}
|
||||
|
||||
const string defaultSemVer = "2.0.0";
|
||||
// dotnet add . package -s http://localhost:5000/packages applec
|
||||
// packages/FindPackagesById()?id='applec'&semVerLevel=2.0.0
|
||||
|
||||
// Search
|
||||
// GET {@id}?q={QUERY}&skip={SKIP}&take={TAKE}&prerelease={PRERELEASE}&semVerLevel={SEMVERLEVEL}&packageType={PACKAGETYPE}
|
||||
|
||||
|
||||
private readonly Resource[] ressources = {
|
||||
new Resource {
|
||||
id = "package/index.json",
|
||||
type ="SearchAutocompleteService/3.5.0",
|
||||
comment = "Auto complete service"
|
||||
},
|
||||
new Resource {
|
||||
id = "package/index.json",
|
||||
type ="SearchQueryService/3.5.0",
|
||||
comment = "Search Query service"
|
||||
},
|
||||
new Resource {
|
||||
id = "package",
|
||||
type ="PackagePublish/2.0.0",
|
||||
comment = "Package Publish service"
|
||||
},
|
||||
new Resource {
|
||||
id = "package",
|
||||
type = "PackageBaseAddress/3.0.0",
|
||||
comment = "Package Base Address service"
|
||||
}
|
||||
};
|
||||
const string _pkgRootPrefix = "~/package";
|
||||
[HttpGet("~/index.json")]
|
||||
public IActionResult ApiIndex()
|
||||
{
|
||||
return Ok(ressources);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet(_pkgRootPrefix + "/index.json")]
|
||||
public IActionResult Index(
|
||||
string q,
|
||||
string semVerLevel = defaultSemVer,
|
||||
bool prerelease = false,
|
||||
string packageType = null,
|
||||
int skip = 0,
|
||||
int take = 25)
|
||||
{
|
||||
if (string.IsNullOrEmpty(q))
|
||||
{
|
||||
ModelState.AddModelError("q", "no value");
|
||||
}
|
||||
if (take > maxTake)
|
||||
{
|
||||
ModelState.AddModelError("take", "Maximum exceeded");
|
||||
}
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
|
||||
var scope = dbContext.Packages
|
||||
.Include(p => p.Versions)
|
||||
.Where(
|
||||
p => (CamelCaseMatch(p.Id, q) || SeparatedByMinusMatch(p.Id, q))
|
||||
&& (prerelease || p.Versions.Any(v => !v.IsPrerelease))
|
||||
&& (packageType == null || p.Versions.Any(v => v.Type == packageType))
|
||||
);
|
||||
var result = new
|
||||
{
|
||||
totalHits = scope.Count(),
|
||||
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)
|
||||
{
|
||||
// Assert.False (q==null);
|
||||
string query = q;
|
||||
if (query.Length == 0) return false;
|
||||
|
||||
while (id.Length > 0)
|
||||
{
|
||||
int i = 0;
|
||||
while (id.Length > i && char.IsLower(id[i])) i++;
|
||||
if (i == 0) break;
|
||||
id = id.Substring(i);
|
||||
if (id.StartsWith(q, System.StringComparison.OrdinalIgnoreCase)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
protected static bool SeparatedByMinusMatch(string id, string q)
|
||||
{
|
||||
foreach (var part in id.Split('-'))
|
||||
{
|
||||
if (part.StartsWith(q, System.StringComparison.OrdinalIgnoreCase)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const int maxTake = 100;
|
||||
// GET /autocomplete?id=nuget.protocol&prerelease=true
|
||||
[HttpGet(_pkgRootPrefix + "/autocomplete")]
|
||||
public IActionResult AutoComplete(
|
||||
string id,
|
||||
string semVerLevel = defaultSemVer,
|
||||
bool prerelease = false,
|
||||
string packageType = null,
|
||||
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(_pkgRootPrefix + "/{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
|
||||
{
|
||||
// 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)
|
||||
&& (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
|
||||
[HttpGet(_pkgRootPrefix + "/{id}/{lower}/{idf}.{lowerf}.nupkg")]
|
||||
public IActionResult GetPackage(
|
||||
[FromRoute] string id, [FromRoute] string lower,
|
||||
[FromRoute] string idf, [FromRoute] string lowerf)
|
||||
{
|
||||
var pkgpath = Path.Combine(nugetSettings.PackagesRootDir,
|
||||
id, lower, $"{idf}.{lowerf}.nupkg"
|
||||
);
|
||||
|
||||
FileInfo pkgfi = new FileInfo(pkgpath);
|
||||
return File(pkgfi.OpenRead(), "application/zip; charset=binary");
|
||||
}
|
||||
|
||||
// TODO GET {@id}/{LOWER_ID}/{LOWER_VERSION}/{LOWER_ID}.nuspec
|
||||
// response 200 : the nuspec
|
||||
[HttpGet(_pkgRootPrefix + "/{id}/{lower}/{idf}.{lowerf}.nuspec")]
|
||||
public IActionResult GetNuspec(
|
||||
[FromRoute][SafeName][Required] string id,
|
||||
[FromRoute][SafeName][Required] string lower,
|
||||
[FromRoute][SafeName][Required] string idf,
|
||||
[FromRoute][SafeName][Required] string lowerf)
|
||||
{
|
||||
var pkgpath = Path.Combine(nugetSettings.PackagesRootDir,
|
||||
id, lower, $"{idf}.{lowerf}.nuspec");
|
||||
|
||||
FileInfo pkgfi = new FileInfo(pkgpath);
|
||||
return File(pkgfi.OpenRead(), "text/xml; charset=utf-8");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue