/// <summary> /// Serves GET requests to this controller. /// </summary> /// <param name="orderBy">What to order the search by.</param> /// <param name="build">The build to list plugins for.</param> /// <param name="max">The maximum number of results to return.</param> /// <param name="search">The search string.</param> /// <returns>The plugins compatible with the given IDE version.</returns> public ActionResult <IEnumerable <string> > Get(string orderBy, string build, int max, string search) { if (!IDEVersion.TryParse(build, out var ideVersion)) { return(BadRequest()); } return(new ActionResult <IEnumerable <string> >(GetResults(ideVersion, max, orderBy, search))); }
/// <summary> /// Serves GET requests to this controller. /// </summary> /// <param name="id">The ID of the plugin.</param> /// <param name="build">The build to list plugins for.</param> /// <returns>The plugins compatible with the given IDE version.</returns> public async Task <ActionResult <IEnumerable <string> > > Get(string id, string build) { if (!IDEVersion.TryParse(build, out var ideVersion)) { return(BadRequest()); } var plugin = await _database.Plugins .FirstOrDefaultAsync(p => p.PluginID.Equals(id, StringComparison.OrdinalIgnoreCase)); if (plugin is null) { return(NotFound()); } var compatibleRelease = plugin.Releases.FirstOrDefault(r => r.CompatibleWith.IsInRange(ideVersion)); if (compatibleRelease is null) { return(NotFound()); } const string testPath = "/run/media/jarl/seagate-expansion/repositories/jetbrains/plugins"; var pluginDataPath = Path.Combine ( testPath, plugin.Category.Name.GenerateSlug(), plugin.Name.GenerateSlug(), compatibleRelease.Version ); var dataFilePath = Directory.EnumerateFiles(pluginDataPath).FirstOrDefault(); if (dataFilePath is null) { return(NoContent()); } if (!System.IO.File.Exists(dataFilePath)) { return(NoContent()); } var stream = System.IO.File.OpenRead(dataFilePath); return(File(stream, "application/octet-stream", Path.GetFileName(dataFilePath))); }
private IEnumerable <string> GetResults(IDEVersion version, int max, string orderBy, string?search) { var compatibleIDs = new List <string>(); IQueryable <Plugin> plugins = _database.Plugins; switch (orderBy) { case "update date": { plugins = plugins.OrderByDescending(p => p.UpdatedAt); break; } case "downloads": { plugins = plugins .OrderByDescending(p => p.Releases.Sum(r => r.Downloads)); break; } case "rating": { plugins = plugins .OrderByDescending(p => p.Rating); break; } } foreach (var plugin in plugins) { if (compatibleIDs.Count >= max) { break; } if (!plugin.Releases.Any(r => r.CompatibleWith.IsInRange(version))) { continue; } if (search is null) { compatibleIDs.Add(plugin.PluginID); continue; } if (plugin.Name.Contains(search, StringComparison.OrdinalIgnoreCase)) { compatibleIDs.Add(plugin.PluginID); continue; } if (plugin.PluginID.Contains(search, StringComparison.OrdinalIgnoreCase)) { compatibleIDs.Add(plugin.PluginID); } } return(compatibleIDs); }
/// <summary> /// Serves GET requests to this controller. /// </summary> /// <param name="build">The build to list plugins for.</param> /// <returns>The plugins compatible with the given IDE version.</returns> public ActionResult <IdeaPluginRepository> Get(string build) { if (!IDEVersion.TryParse(build, out var ideVersion)) { return(BadRequest()); } var categories = _database.Categories.ToList(); var ideaCategories = categories.Select(c => new IdeaPluginCategory(c.Name)).ToList(); foreach (var category in _database.Categories) { var ideaCategory = ideaCategories.First(c => c.Name == category.Name); foreach (var plugin in category.Plugins) { var compatibleRelease = plugin.Releases .OrderBy(r => r.UploadedAt) .FirstOrDefault(r => r.CompatibleWith.IsInRange(ideVersion)); if (compatibleRelease is null) { continue; } var ideaPlugin = new IdeaPlugin ( plugin.Name, plugin.PluginID, plugin.Description, compatibleRelease.Version, new IdeaVendor { Email = plugin.Vendor.Email, Name = plugin.Vendor.Name, URL = plugin.Vendor.URL }, new IdeaVersion { UntilBuild = compatibleRelease.CompatibleWith.UntilBuild.IsValid ? compatibleRelease.CompatibleWith.UntilBuild.ToString() : null, SinceBuild = compatibleRelease.CompatibleWith.SinceBuild.IsValid ? compatibleRelease.CompatibleWith.SinceBuild.ToString() : null, }, compatibleRelease.ChangeNotes ) { ProjectURL = plugin.ProjectURL, Tags = plugin.Tags.Aggregate((a, b) => a + ";" + b), Depends = compatibleRelease.Dependencies, Downloads = compatibleRelease.Downloads, Size = compatibleRelease.Size, Rating = plugin.Rating, UploadDate = (compatibleRelease.UploadedAt.ToFileTimeUtc() / 10000).ToString(), UpdateDate = (plugin.Releases.Select(r => r.UploadedAt).OrderBy(d => d).First().ToFileTimeUtc() / 10000).ToString() }; ideaCategory.Plugins.Add(ideaPlugin); } } var ideaRepository = new IdeaPluginRepository(); ideaRepository.Categories = ideaCategories; return(new ActionResult <IdeaPluginRepository>(ideaRepository)); }
/// <summary> /// Maps the given <see cref="IdeaPlugin"/> to a <see cref="PluginRelease"/>. /// </summary> /// <param name="this">The IdeaPlugin.</param> /// <param name="dbPlugin">The plugin that the release belongs to.</param> /// <returns>The mapped release.</returns> public static PluginRelease ToReleaseEntity ( this IdeaPlugin @this, Plugin dbPlugin ) { string?SelectBestSinceValue(IdeaVersion version) { if (version.SinceBuild is null || version.SinceBuild == "n/a") { return(version.Min); } return(version.SinceBuild); } string?SelectBestUntilValue(IdeaVersion version) { if (version.UntilBuild is null || version.UntilBuild == "n/a") { return(version.Max); } return(version.UntilBuild); } DateTime ParseDateFromMilliseconds(string value) { var millis = long.Parse(value); return(DateTimeOffset.FromUnixTimeMilliseconds(millis).UtcDateTime); } var sinceBuildValue = SelectBestSinceValue(@this.IdeaVersion); IDEVersion?sinceBuild = null; if (!(sinceBuildValue is null)) { if (!IDEVersion.TryParse(sinceBuildValue, out sinceBuild)) { throw new InvalidDataException("Bad version string."); } } var untilBuildValue = SelectBestUntilValue(@this.IdeaVersion); IDEVersion?untilBuild = null; if (!(untilBuildValue is null)) { if (!IDEVersion.TryParse(untilBuildValue, out untilBuild)) { throw new InvalidDataException("Bad version string."); } } var versionRange = new IDEVersionRange ( sinceBuild ?? IDEVersion.Invalid, untilBuild ?? IDEVersion.Invalid ); // Get the file size and hash // TODO: refactor var basePath = Program.Options.InputFolder; var pluginFolder = Path.Combine ( basePath, "plugins", dbPlugin.Category.Name.GenerateSlug(), dbPlugin.Name.GenerateSlug(), @this.Version ); var pluginFile = Directory.EnumerateFiles(pluginFolder).FirstOrDefault(); if (pluginFile is null) { throw new FileNotFoundException("Couldn't find the released plugin file. Missing data?"); } string hash; using (var md5 = MD5.Create()) { using var file = File.OpenRead(pluginFile); var md5Sum = md5.ComputeHash(file); hash = BitConverter.ToString(md5Sum).Replace("-", string.Empty).ToLowerInvariant(); } var fileInfo = new FileInfo(pluginFile); var size = fileInfo.Length; var result = new PluginRelease ( dbPlugin, @this.ChangeNotes, size, ParseDateFromMilliseconds ( @this.UpdateDate ?? @this.UploadDate ?? throw new InvalidOperationException() ), hash, @this.Version, versionRange, @this.Depends ); result.Downloads = @this.Downloads; return(result); }