Label merge and delete implemented, many changes for images, several bugs squashed.

This commit is contained in:
Steven Hildreth 2019-07-31 11:44:25 -05:00
parent 87ab8785b4
commit 5e01190500
26 changed files with 617 additions and 112 deletions

View file

@ -195,5 +195,33 @@ namespace Roadie.Library.Tests
// context.SaveChanges();
// }
//}
//[Fact]
//public void Update_Label_Special_Name()
//{
// var optionsBuilder = new DbContextOptionsBuilder<RoadieDbContext>();
// optionsBuilder.UseMySql("server=viking;userid=roadie;password=MenAtW0rk668;persistsecurityinfo=True;database=roadie;ConvertZeroDateTime=true");
// using (var context = new RoadieDbContext(optionsBuilder.Options))
// {
// var now = DateTime.UtcNow;
// foreach (var label in context.Labels)
// {
// var labelModel = label.Adapt<Roadie.Library.Models.Label>();
// var specialLabelName = labelModel.Name.ToAlphanumericName();
// if (!labelModel.AlternateNamesList.Contains(specialLabelName, StringComparer.OrdinalIgnoreCase))
// {
// var alt = new List<string>(labelModel.AlternateNamesList)
// {
// specialLabelName
// };
// label.AlternateNames = alt.ToDelimitedList();
// label.LastUpdated = now;
// }
// }
// context.SaveChanges();
// }
//}
}
}

View file

@ -115,9 +115,11 @@ namespace Roadie.Library.Tests
[InlineData("001 Love.Mp3")]
[InlineData("01 - Love.Mp3")]
[InlineData("Love.Mp3")]
[InlineData("LOVE.Mp3")]
[InlineData("love.mp3")]
public void CleanString_Track(string input)
{
Assert.Equal("Love.Mp3", input.CleanString(Configuration, Configuration.Processing.TrackRemoveStringsRegex));
Assert.Equal("Love.Mp3", input.CleanString(Configuration, Configuration.Processing.TrackRemoveStringsRegex).ToTitleCase());
}
[Theory]

View file

@ -18,6 +18,11 @@ namespace Roadie.Library.Configuration
Integrations Integrations { get; set; }
ImageSize LargeImageSize { get; set; }
string LibraryFolder { get; set; }
string ImageFolder { get; set; }
string LabelImageFolder { get; }
string CollectionImageFolder { get; }
string PlaylistImageFolder { get; }
string UserImageFolder { get; }
string ListenAddress { get; set; }
ImageSize MaximumImageSize { get; set; }
ImageSize MediumImageSize { get; set; }

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace Roadie.Library.Configuration
{
@ -44,6 +45,40 @@ namespace Roadie.Library.Configuration
public string LibraryFolder { get; set; }
public string ImageFolder { get; set; }
public string LabelImageFolder
{
get
{
return Path.Combine(ImageFolder ?? LibraryFolder, "__roadie_images", "labels");
}
}
public string CollectionImageFolder
{
get
{
return Path.Combine(ImageFolder ?? LibraryFolder, "__roadie_images", "collections");
}
}
public string PlaylistImageFolder
{
get
{
return Path.Combine(ImageFolder ?? LibraryFolder, "__roadie_images", "playlists");
}
}
public string UserImageFolder
{
get
{
return Path.Combine(LibraryFolder, "__roadie_images", "users");
}
}
public string ListenAddress { get; set; }
public ImageSize MaximumImageSize { get; set; }

View file

@ -1,6 +1,8 @@
using CsvHelper;
using Newtonsoft.Json;
using Roadie.Library.Configuration;
using Roadie.Library.Enums;
using Roadie.Library.Extensions;
using Roadie.Library.Utility;
using System;
using System.Collections.Generic;
@ -39,6 +41,14 @@ namespace Roadie.Library.Data
public string CacheRegion => CacheRegionUrn(RoadieId);
/// <summary>
/// Returns a full file path to the Collection Image
/// </summary>
public string PathToImage(IRoadieSettings configuration)
{
return Path.Combine(configuration.CollectionImageFolder, $"{ (SortName ?? Name).ToFileNameFriendly() } [{ Id }].jpg");
}
public int PositionColumn
{
get

View file

@ -1,4 +1,8 @@
using System;
using Roadie.Library.Configuration;
using Roadie.Library.Extensions;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
@ -24,6 +28,14 @@ namespace Roadie.Library.Data
}
}
/// <summary>
/// Returns a full file path to the Label Image
/// </summary>
public string PathToImage(IRoadieSettings configuration)
{
return Path.Combine(configuration.LabelImageFolder, $"{ (SortName ?? Name).ToFileNameFriendly() } [{ Id }].jpg");
}
public bool IsValid => !string.IsNullOrEmpty(Name);
public static string CacheRegionUrn(Guid Id)

View file

@ -1,4 +1,8 @@
using System;
using Roadie.Library.Configuration;
using Roadie.Library.Extensions;
using System;
using System.Diagnostics;
using System.IO;
namespace Roadie.Library.Data
{
@ -18,6 +22,14 @@ namespace Roadie.Library.Data
return $"urn:playlist_by_id:{Id}";
}
/// <summary>
/// Returns a full file path to the Playlist Image
/// </summary>
public string PathToImage(IRoadieSettings configuration)
{
return Path.Combine(configuration.PlaylistImageFolder, $"{ (SortName ?? Name).ToFileNameFriendly() } [{ Id }].jpg");
}
public override string ToString()
{
return $"Id [{Id}], Name [{Name}], RoadieId [{RoadieId}]";

View file

@ -39,34 +39,57 @@ namespace Roadie.Library.Extensions
public static string AddToDelimitedList(this string input, IEnumerable<string> values, char delimiter = '|')
{
if (string.IsNullOrEmpty(input) && (values == null || !values.Any())) return null;
if (string.IsNullOrEmpty(input)) return string.Join(delimiter.ToString(), values);
if (values == null || !values.Any()) return input;
if (string.IsNullOrEmpty(input) && (values == null || !values.Any()))
{
return null;
}
if (string.IsNullOrEmpty(input))
{
return string.Join(delimiter.ToString(), values);
}
if (values == null || !values.Any())
{
return input;
}
foreach (var value in values)
{
if (string.IsNullOrEmpty(value)) continue;
if (string.IsNullOrEmpty(value))
{
continue;
}
if (!input.IsValueInDelimitedList(value, delimiter))
{
if (!input.EndsWith(delimiter.ToString())) input = input + delimiter;
input = input + value;
if (!input.EndsWith(delimiter.ToString()))
{
input += delimiter;
}
input += value;
}
}
return input;
}
public static string CleanString(this string input, IRoadieSettings settings, string removeStringsRegex = null)
{
if (string.IsNullOrEmpty(input) || settings == null) return input;
if (string.IsNullOrEmpty(input) || settings == null)
{
return input;
}
var result = input;
foreach (var kvp in settings.Processing.ReplaceStrings.OrderBy(x => x.Order).ThenBy(x => x.Key))
{
result = result.Replace(kvp.Key, kvp.ReplaceWith, StringComparison.OrdinalIgnoreCase);
}
result = result.Trim().ToTitleCase(false);
if (string.IsNullOrEmpty(result)) return input;
if (string.IsNullOrEmpty(result))
{
return input;
}
var rs = removeStringsRegex ?? settings.Processing.RemoveStringsRegex;
if (!string.IsNullOrEmpty(rs)) result = Regex.Replace(result, rs, "", RegexOptions.IgnoreCase);
if (!string.IsNullOrEmpty(rs))
{
result = Regex.Replace(result, rs, "", RegexOptions.IgnoreCase);
}
if (result.Length > 5)
{
var extensionStart = result.Substring(result.Length - 5, 2);

View file

@ -1,7 +1,11 @@
using Roadie.Library.Data;
using Roadie.Library.Configuration;
using Roadie.Library.Data;
using Roadie.Library.Enums;
using Roadie.Library.Extensions;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
namespace Roadie.Library.Identity
{
@ -13,6 +17,14 @@ namespace Roadie.Library.Identity
public string CacheRegion => CacheRegionUrn(RoadieId);
/// <summary>
/// Returns a full file path to the User Image
/// </summary>
public string PathToImage(IRoadieSettings configuration)
{
return Path.Combine(configuration.UserImageFolder, $"{ UserName.ToFileNameFriendly() } [{ Id }].gif");
}
public ApplicationUser()
{
RoadieId = Guid.NewGuid();

View file

@ -20,7 +20,6 @@ namespace Roadie.Library.Imaging
{
public static string ArtistImageFilename = "artist.jpg";
public static string ArtistSecondaryImageFilename = "artist {0}.jpg";
public static string LabelImageFilename = "label.jpg";
public static int MaximumThumbnailByteSize = 50000;
// Replace with counter of image
@ -42,6 +41,21 @@ namespace Roadie.Library.Imaging
}
}
public static byte[] ConvertToGifFormat(byte[] imageBytes)
{
if (imageBytes == null) return null;
using (var outStream = new MemoryStream())
{
IImageFormat imageFormat = null;
using (var image = Image.Load(imageBytes, out imageFormat))
{
image.Save(outStream, ImageFormats.Gif);
}
return outStream.ToArray();
}
}
public static IEnumerable<FileInfo> FindImagesByName(DirectoryInfo directory, string name,
SearchOption folderSearchOptions = SearchOption.AllDirectories)
{

View file

@ -67,6 +67,7 @@ namespace Roadie.Library.Models.Users
[AdaptMember("RoadieId")] public Guid UserId { get; set; }
[Required] [MaxLength(20)] public string UserName { get; set; }
public Image MediumThumbnail { get; set; }
public override string ToString()
{

View file

@ -40,10 +40,6 @@
<PackageReference Include="zlib.net-mutliplatform" Version="1.0.4" />
</ItemGroup>
<ItemGroup>
<Folder Include="Models\Subsonic\" />
</ItemGroup>
<ItemGroup>
<Reference Include="IdSharp.AudioInfo-core">
<HintPath>..\libraries\IdSharp.AudioInfo-core.dll</HintPath>

View file

@ -41,10 +41,12 @@ namespace Roadie.Api.Services
private IReleaseService ReleaseService { get; }
private ILabelService LabelService { get; }
public AdminService(IRoadieSettings configuration, IHttpEncoder httpEncoder, IHttpContext httpContext,
data.IRoadieDbContext context, ICacheManager cacheManager, ILogger<ArtistService> logger,
IHubContext<ScanActivityHub> scanActivityHub, IFileDirectoryProcessorService fileDirectoryProcessorService, IArtistService artistService,
IReleaseService releaseService, IReleaseLookupEngine releaseLookupEngine
IReleaseService releaseService, IReleaseLookupEngine releaseLookupEngine, ILabelService labelService
)
: base(configuration, httpEncoder, context, cacheManager, logger, httpContext)
{
@ -54,6 +56,7 @@ namespace Roadie.Api.Services
ArtistService = artistService;
ReleaseService = releaseService;
LabelService = labelService;
ReleaseLookupEngine = releaseLookupEngine;
FileDirectoryProcessorService = fileDirectoryProcessorService;
}
@ -135,6 +138,52 @@ namespace Roadie.Api.Services
};
}
/// <summary>
/// Perform checks/setup on start of application
/// </summary>
public void PerformStartUpTasks()
{
var sw = Stopwatch.StartNew();
#region Setup Configured storage folders
try
{
if (!Directory.Exists(Configuration.LibraryFolder))
{
Directory.CreateDirectory(Configuration.LibraryFolder);
Logger.LogInformation($"Created Library Folder [{Configuration.LibraryFolder }]");
}
if (!Directory.Exists(Configuration.UserImageFolder))
{
Directory.CreateDirectory(Configuration.UserImageFolder);
Logger.LogInformation($"Created User Image Folder [{Configuration.UserImageFolder }]");
}
if (!Directory.Exists(Configuration.PlaylistImageFolder))
{
Directory.CreateDirectory(Configuration.PlaylistImageFolder);
Logger.LogInformation($"Created Playlist Image Folder [{Configuration.PlaylistImageFolder }]");
}
if (!Directory.Exists(Configuration.CollectionImageFolder))
{
Directory.CreateDirectory(Configuration.CollectionImageFolder);
Logger.LogInformation($"Created Collection Image Folder [{Configuration.CollectionImageFolder }]");
}
if (!Directory.Exists(Configuration.LabelImageFolder))
{
Directory.CreateDirectory(Configuration.LabelImageFolder);
Logger.LogInformation($"Created Label Image Folder [{Configuration.LabelImageFolder}]");
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Error setting up storage folders. Ensure application has create folder permissions.");
throw;
}
#endregion
sw.Stop();
Logger.LogInformation($"Administration startup tasks completed, elapsed time [{ sw.ElapsedMilliseconds }]");
}
public async Task<OperationResult<bool>> ValidateInviteToken(Guid? tokenId)
{
var sw = new Stopwatch();
@ -195,6 +244,40 @@ namespace Roadie.Api.Services
};
}
public async Task<OperationResult<bool>> DeleteLabel(ApplicationUser user, Guid labelId)
{
var sw = new Stopwatch();
sw.Start();
var errors = new List<Exception>();
var label = DbContext.Labels.FirstOrDefault(x => x.RoadieId == labelId);
if (label == null)
{
await LogAndPublish($"DeleteLabel Unknown Label [{labelId}]", LogLevel.Warning);
return new OperationResult<bool>(true, $"Label Not Found [{labelId}]");
}
try
{
await LabelService.Delete(user, labelId);
CacheManager.ClearRegion(label.CacheRegion);
}
catch (Exception ex)
{
Logger.LogError(ex);
await LogAndPublish("Error deleting artist secondary image.");
errors.Add(ex);
}
sw.Stop();
await LogAndPublish($"DeleteLabel `{label}`, By User `{user}`", LogLevel.Information);
return new OperationResult<bool>
{
IsSuccess = !errors.Any(),
Data = true,
OperationTime = sw.ElapsedMilliseconds,
Errors = errors
};
}
public async Task<OperationResult<bool>> DeleteArtistSecondaryImage(ApplicationUser user, Guid artistId, int index)
{
@ -413,6 +496,11 @@ namespace Roadie.Api.Services
DbContext.Users.Remove(user);
await DbContext.SaveChangesAsync();
var userImageFilename = user.PathToImage(Configuration);
if (File.Exists(userImageFilename))
{
File.Delete(userImageFilename);
}
}
catch (Exception ex)
{

View file

@ -183,17 +183,18 @@ namespace Roadie.Api.Services
};
}
public async Task<OperationResult<bool>> Delete(ApplicationUser user, data.Artist Artist)
public async Task<OperationResult<bool>> Delete(ApplicationUser user, data.Artist artist)
{
var isSuccess = false;
try
{
if (Artist != null)
if (artist != null)
{
DbContext.Artists.Remove(Artist);
DbContext.Artists.Remove(artist);
await DbContext.SaveChangesAsync();
CacheManager.ClearRegion(Artist.CacheRegion);
Logger.LogInformation(string.Format("x DeleteArtist [{0}]", Artist.Id));
// TODO delete artist folder if empty?
CacheManager.ClearRegion(artist.CacheRegion);
Logger.LogInformation(string.Format("x DeleteArtist [{0}]", artist.Id));
isSuccess = true;
}
}
@ -461,22 +462,25 @@ namespace Roadie.Api.Services
var sw = new Stopwatch();
sw.Start();
artistToMergeInto.RealName = artistToMerge.RealName ?? artistToMergeInto.RealName;
artistToMergeInto.MusicBrainzId = artistToMerge.MusicBrainzId ?? artistToMergeInto.MusicBrainzId;
artistToMergeInto.ITunesId = artistToMerge.ITunesId ?? artistToMergeInto.ITunesId;
artistToMergeInto.AmgId = artistToMerge.AmgId ?? artistToMergeInto.AmgId;
artistToMergeInto.SpotifyId = artistToMerge.SpotifyId ?? artistToMergeInto.SpotifyId;
artistToMergeInto.Thumbnail = artistToMerge.Thumbnail ?? artistToMergeInto.Thumbnail;
artistToMergeInto.Profile = artistToMerge.Profile ?? artistToMergeInto.Profile;
artistToMergeInto.BirthDate = artistToMerge.BirthDate ?? artistToMergeInto.BirthDate;
artistToMergeInto.BeginDate = artistToMerge.BeginDate ?? artistToMergeInto.BeginDate;
artistToMergeInto.EndDate = artistToMerge.EndDate ?? artistToMergeInto.EndDate;
var artistToMergeFolder = artistToMerge.ArtistFileFolder(Configuration);
var artistToMergeIntoFolder = artistToMergeInto.ArtistFileFolder(Configuration);
artistToMergeInto.RealName = artistToMergeInto.RealName ?? artistToMerge.RealName;
artistToMergeInto.MusicBrainzId = artistToMergeInto.MusicBrainzId ?? artistToMerge.MusicBrainzId;
artistToMergeInto.ITunesId = artistToMergeInto.ITunesId ?? artistToMerge.ITunesId;
artistToMergeInto.AmgId = artistToMergeInto.AmgId ?? artistToMerge.AmgId;
artistToMergeInto.SpotifyId = artistToMergeInto.SpotifyId ?? artistToMerge.SpotifyId;
artistToMergeInto.Thumbnail = artistToMergeInto.Thumbnail ?? artistToMerge.Thumbnail;
artistToMergeInto.Profile = artistToMergeInto.Profile ?? artistToMerge.Profile;
artistToMergeInto.BirthDate = artistToMergeInto.BirthDate ?? artistToMerge.BirthDate;
artistToMergeInto.BeginDate = artistToMergeInto.BeginDate ?? artistToMerge.BeginDate;
artistToMergeInto.EndDate = artistToMergeInto.EndDate ?? artistToMerge.EndDate;
if (!string.IsNullOrEmpty(artistToMerge.ArtistType) && !artistToMerge.ArtistType.Equals("Other", StringComparison.OrdinalIgnoreCase))
{
artistToMergeInto.ArtistType = artistToMerge.ArtistType;
artistToMergeInto.ArtistType = artistToMergeInto.ArtistType ?? artistToMerge.ArtistType;
}
artistToMergeInto.BioContext = artistToMerge.BioContext ?? artistToMergeInto.BioContext;
artistToMergeInto.DiscogsId = artistToMerge.DiscogsId ?? artistToMergeInto.DiscogsId;
artistToMergeInto.BioContext = artistToMergeInto.BioContext ?? artistToMerge.BioContext;
artistToMergeInto.DiscogsId = artistToMergeInto.DiscogsId ?? artistToMerge.DiscogsId;
artistToMergeInto.Tags = artistToMergeInto.Tags.AddToDelimitedList(artistToMerge.Tags.ToListFromDelimited());
var altNames = artistToMerge.AlternateNames.ToListFromDelimited().ToList();
altNames.Add(artistToMerge.Name);
@ -514,6 +518,51 @@ namespace Roadie.Api.Services
artistImage.ArtistId = artistToMergeInto.Id;
}
}
try
{
// Move any Artist and Artist Secondary images from ArtistToMerge into ArtistToMergeInto folder
if (Directory.Exists(artistToMergeFolder))
{
var artistToMergeImages = ImageHelper.FindImageTypeInDirectory(new DirectoryInfo(artistToMergeFolder), ImageType.Artist);
var artistToMergeSecondaryImages = ImageHelper.FindImageTypeInDirectory(new DirectoryInfo(artistToMergeFolder), ImageType.ArtistSecondary).ToList();
// Primary Artist image
if (artistToMergeImages.Any())
{
// If the ArtistToMergeInto already has a primary image then the ArtistToMerge primary image becomes a secondary image
var artistToMergeIntoPrimaryImage = ImageHelper.FindImageTypeInDirectory(new DirectoryInfo(artistToMergeIntoFolder), ImageType.Artist).FirstOrDefault();
if (artistToMergeIntoPrimaryImage != null)
{
artistToMergeSecondaryImages.Add(artistToMergeImages.First());
}
else
{
var artistImageFilename = Path.Combine(artistToMergeIntoFolder, ImageHelper.ArtistImageFilename);
artistToMergeImages.First().MoveTo(artistImageFilename);
}
}
// Secondary Artist images
if (artistToMergeSecondaryImages.Any())
{
var looper = 0;
foreach (var artistSecondaryImage in artistToMergeSecondaryImages)
{
var artistImageFilename = Path.Combine(artistToMergeIntoFolder, string.Format(ImageHelper.ArtistSecondaryImageFilename, looper.ToString("00")));
while (File.Exists(artistImageFilename))
{
looper++;
artistImageFilename = Path.Combine(artistToMergeIntoFolder, string.Format(ImageHelper.ArtistSecondaryImageFilename, looper.ToString("00")));
}
artistSecondaryImage.MoveTo(artistImageFilename);
}
}
}
}
catch (Exception ex)
{
Logger.LogError(ex, "MergeArtists: Error Moving Artist Primary and Secondary Images");
}
var userArtists = DbContext.UserArtists.Where(x => x.ArtistId == artistToMerge.Id).ToArray();
if (artistImages != null)
{
@ -553,10 +602,9 @@ namespace Roadie.Api.Services
Logger.LogWarning(ex.ToString());
}
var artistFolder = artistToMerge.ArtistFileFolder(Configuration);
foreach (var release in DbContext.Releases.Include("Artist").Where(x => x.ArtistId == artistToMerge.Id).ToArray())
{
var originalReleaseFolder = release.ReleaseFileFolder(artistFolder);
var originalReleaseFolder = release.ReleaseFileFolder(artistToMergeFolder);
await ReleaseService.UpdateRelease(user, release.Adapt<Release>(), originalReleaseFolder);
}
await DbContext.SaveChangesAsync();
@ -664,7 +712,9 @@ namespace Roadie.Api.Services
var specialArtistName = model.Name.ToAlphanumericName();
var alt = new List<string>(model.AlternateNamesList);
if (!model.AlternateNamesList.Contains(specialArtistName, StringComparer.OrdinalIgnoreCase))
{
alt.Add(specialArtistName);
}
artist.AlternateNames = alt.ToDelimitedList();
artist.ArtistType = model.ArtistType;
artist.AmgId = model.AmgId;

View file

@ -18,6 +18,7 @@ using Roadie.Library.Utility;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
@ -138,6 +139,11 @@ namespace Roadie.Api.Services
{
DbContext.Collections.Remove(collection);
await DbContext.SaveChangesAsync();
var collectionImageFilename = collection.PathToImage(Configuration);
if (File.Exists(collectionImageFilename))
{
File.Delete(collectionImageFilename);
}
}
catch (Exception ex)
{
@ -228,7 +234,9 @@ namespace Roadie.Api.Services
{
collection = DbContext.Collections.FirstOrDefault(x => x.RoadieId == model.Id);
if (collection == null)
{
return new OperationResult<bool>(true, string.Format("Collection Not Found [{0}]", model.Id));
}
}
collection.IsLocked = model.IsLocked;
@ -249,6 +257,9 @@ namespace Roadie.Api.Services
var collectionImage = ImageHelper.ImageDataFromUrl(model.NewThumbnailData);
if (collectionImage != null)
{
// Save unaltered collection image
File.WriteAllBytes(collection.PathToImage(Configuration), ImageHelper.ConvertToJpegFormat(collectionImage));
// Update Thumbnail
collection.Thumbnail = ImageHelper.ResizeToThumbnail(collectionImage, Configuration);
}
@ -296,8 +307,7 @@ namespace Roadie.Api.Services
result.Tags = collection.Tags;
result.URLs = collection.URLs;
result.Thumbnail = MakeCollectionThumbnailImage(collection.RoadieId);
result.MediumThumbnail = MakeThumbnailImage(id, "collection", Configuration.MediumImageSize.Width,
Configuration.MediumImageSize.Height);
result.MediumThumbnail = MakeThumbnailImage(id, "collection", Configuration.MediumImageSize.Width, Configuration.MediumImageSize.Height);
result.CollectionFoundCount = (from crc in DbContext.CollectionReleases
where crc.CollectionId == collection.Id
select crc.Id).Count();

View file

@ -9,6 +9,8 @@ namespace Roadie.Api.Services
{
public interface IAdminService
{
void PerformStartUpTasks();
Task<OperationResult<bool>> DeleteArtist(ApplicationUser user, Guid artistId);
Task<OperationResult<bool>> DeleteArtistReleases(ApplicationUser user, Guid artistId,
@ -16,6 +18,8 @@ namespace Roadie.Api.Services
Task<OperationResult<bool>> DeleteArtistSecondaryImage(ApplicationUser user, Guid artistId, int index);
Task<OperationResult<bool>> DeleteLabel(ApplicationUser user, Guid labelId);
Task<OperationResult<bool>> DeleteRelease(ApplicationUser user, Guid releaseId, bool? doDeleteFiles);
Task<OperationResult<bool>> DeleteReleaseSecondaryImage(ApplicationUser user, Guid releaseId, int index);

View file

@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Http;
using Roadie.Library;
using Roadie.Library.Identity;
using Roadie.Library.Models;
using Roadie.Library.Models.Pagination;
using Roadie.Library.Models.Users;
@ -15,6 +16,10 @@ namespace Roadie.Api.Services
Task<PagedResult<LabelList>> List(User roadieUser, PagedRequest request, bool? doRandomize = false);
Task<OperationResult<bool>> Delete(ApplicationUser user, Guid id);
Task<OperationResult<bool>> MergeLabelsIntoLabel(ApplicationUser user, Guid intoLabelId, IEnumerable<Guid> labelIdsToMerge);
Task<OperationResult<Image>> SetLabelImageByUrl(User user, Guid id, string imageUrl);
Task<OperationResult<bool>> UpdateLabel(User user, Label label);

View file

@ -321,16 +321,31 @@ namespace Roadie.Api.Services
{
var collection = GetCollection(id);
if (collection == null)
return Task.FromResult(new FileOperationResult<Image>(true,
string.Format("Collection Not Found [{0}]", id)));
{
return Task.FromResult(new FileOperationResult<Image>(true, string.Format("Collection Not Found [{0}]", id)));
}
var image = new data.Image
{
Bytes = collection.Thumbnail,
CreatedDate = collection.CreatedDate,
LastUpdated = collection.LastUpdated
};
var collectionImageFilename = collection.PathToImage(Configuration);
try
{
if (File.Exists(collectionImageFilename))
{
image.Bytes = File.ReadAllBytes(collectionImageFilename);
}
}
catch (Exception ex)
{
Logger.LogError(ex, $"Error Reading Image File [{collectionImageFilename}]");
}
if (collection.Thumbnail == null || !collection.Thumbnail.Any())
{
image = DefaultNotFoundImages.Collection;
}
return Task.FromResult(GenerateFileOperationResult(id, image, etag));
}
catch (Exception ex)
@ -439,7 +454,22 @@ namespace Roadie.Api.Services
CreatedDate = label.CreatedDate,
LastUpdated = label.LastUpdated
};
if (label.Thumbnail == null || !label.Thumbnail.Any()) image = DefaultNotFoundImages.Label;
var labelImageFilename = label.PathToImage(Configuration);
try
{
if(File.Exists(labelImageFilename))
{
image.Bytes = File.ReadAllBytes(labelImageFilename);
}
}
catch (Exception ex)
{
Logger.LogError(ex, $"Error Reading Image File [{labelImageFilename}]");
}
if (label.Thumbnail == null || !label.Thumbnail.Any())
{
image = DefaultNotFoundImages.Label;
}
return Task.FromResult(GenerateFileOperationResult(id, image, etag));
}
catch (Exception ex)
@ -464,7 +494,22 @@ namespace Roadie.Api.Services
CreatedDate = playlist.CreatedDate,
LastUpdated = playlist.LastUpdated
};
if (playlist.Thumbnail == null || !playlist.Thumbnail.Any()) image = DefaultNotFoundImages.Playlist;
var playlistImageFilename = playlist.PathToImage(Configuration);
try
{
if (File.Exists(playlistImageFilename))
{
image.Bytes = File.ReadAllBytes(playlistImageFilename);
}
}
catch (Exception ex)
{
Logger.LogError(ex, $"Error Reading Image File [{playlistImageFilename}]");
}
if (playlist.Thumbnail == null || !playlist.Thumbnail.Any())
{
image = DefaultNotFoundImages.Playlist;
}
return Task.FromResult(GenerateFileOperationResult(id, image, etag));
}
catch (Exception ex)
@ -638,15 +683,31 @@ namespace Roadie.Api.Services
{
var user = GetUser(id);
if (user == null)
return Task.FromResult(new FileOperationResult<Image>(true,
string.Format("User Not Found [{0}]", id)));
{
return Task.FromResult(new FileOperationResult<Image>(true, string.Format("User Not Found [{0}]", id)));
}
var image = new data.Image
{
Bytes = user.Avatar,
CreatedDate = user.CreatedDate.Value,
LastUpdated = user.LastUpdated
};
if (user.Avatar == null || !user.Avatar.Any()) image = DefaultNotFoundImages.User;
var userImageFilename = user.PathToImage(Configuration);
try
{
if (File.Exists(userImageFilename))
{
image.Bytes = File.ReadAllBytes(userImageFilename);
}
}
catch (Exception ex)
{
Logger.LogError(ex, $"Error Reading Image File [{userImageFilename}]");
}
if (!(image?.Bytes?.Any() ?? false))
{
image = DefaultNotFoundImages.User;
}
return Task.FromResult(GenerateFileOperationResult(id, image, etag, "image/png"));
}
catch (Exception ex)

View file

@ -8,6 +8,7 @@ using Roadie.Library.Configuration;
using Roadie.Library.Encoding;
using Roadie.Library.Enums;
using Roadie.Library.Extensions;
using Roadie.Library.Identity;
using Roadie.Library.Imaging;
using Roadie.Library.Models;
using Roadie.Library.Models.Pagination;
@ -43,6 +44,32 @@ namespace Roadie.Api.Services
BookmarkService = bookmarkService;
}
public async Task<OperationResult<bool>> Delete(ApplicationUser user, Guid id)
{
var sw = new Stopwatch();
sw.Start();
var label = DbContext.Labels.FirstOrDefault(x => x.RoadieId == id);
if (label == null) return new OperationResult<bool>(true, string.Format("Label Not Found [{0}]", id));
DbContext.Labels.Remove(label);
await DbContext.SaveChangesAsync();
var labelImageFilename = label.PathToImage(Configuration);
if(File.Exists(labelImageFilename))
{
File.Delete(labelImageFilename);
}
Logger.LogInformation("User `{0}` deleted Label `{1}]`", user, label);
CacheManager.ClearRegion(label.CacheRegion);
sw.Stop();
return new OperationResult<bool>
{
IsSuccess = true,
Data = true,
OperationTime = sw.ElapsedMilliseconds
};
}
public async Task<OperationResult<Label>> ById(User roadieUser, Guid id, IEnumerable<string> includes = null)
{
var sw = Stopwatch.StartNew();
@ -103,10 +130,11 @@ namespace Roadie.Api.Services
? request.FilterValue.ToAlphanumericName()
: null;
var result = from l in DbContext.Labels
where request.FilterValue.Length == 0 || request.FilterValue.Length > 0 && (
l.Name != null && l.Name.Contains(request.FilterValue) ||
l.AlternateNames != null && l.AlternateNames.Contains(request.FilterValue) ||
l.AlternateNames != null && l.AlternateNames.Contains(normalizedFilterValue)
where request.FilterValue == "" || (
l.Name.Contains(request.FilterValue) ||
l.SortName.Contains(request.FilterValue) ||
l.AlternateNames.Contains(request.FilterValue) ||
l.AlternateNames.Contains(normalizedFilterValue)
)
select new LabelList
{
@ -116,7 +144,7 @@ namespace Roadie.Api.Services
{
Text = l.Name,
Value = l.RoadieId.ToString()
},
},
SortName = l.SortName,
CreatedDate = l.CreatedDate,
LastUpdated = l.LastUpdated,
@ -132,7 +160,6 @@ namespace Roadie.Api.Services
var randomLimit = roadieUser?.RandomReleaseLimit ?? 100;
request.Limit = request.LimitValue > randomLimit ? randomLimit : request.LimitValue;
rows = result.OrderBy(x => x.RandomSortId).Take(request.LimitValue).ToArray();
}
else
{
@ -153,6 +180,67 @@ namespace Roadie.Api.Services
});
}
public async Task<OperationResult<bool>> MergeLabelsIntoLabel(ApplicationUser user, Guid intoLabelId, IEnumerable<Guid> labelIdsToMerge)
{
var sw = new Stopwatch();
sw.Start();
var errors = new List<Exception>();
var label = DbContext.Labels.FirstOrDefault(x => x.RoadieId == intoLabelId);
if (label == null)
{
return new OperationResult<bool>(true, string.Format("Merge Into Label Not Found [{0}]", intoLabelId));
}
var now = DateTime.UtcNow;
var labelsToMerge = (from l in DbContext.Labels
join ltm in labelIdsToMerge on l.RoadieId equals ltm
select l);
foreach (var labelToMerge in labelsToMerge)
{
label.MusicBrainzId = label.MusicBrainzId ?? labelToMerge.MusicBrainzId;
label.SortName = label.SortName ?? labelToMerge.SortName;
label.Thumbnail = label.Thumbnail ?? labelToMerge.Thumbnail;
label.Profile = label.Profile ?? labelToMerge.Profile;
label.BeginDate = label.BeginDate ?? labelToMerge.BeginDate;
label.EndDate = label.EndDate ?? labelToMerge.EndDate;
label.Profile = label.Profile ?? labelToMerge.Profile;
label.DiscogsId = label.DiscogsId ?? labelToMerge.DiscogsId;
label.ImageUrl = label.ImageUrl ?? labelToMerge.ImageUrl;
label.Tags = label.Tags.AddToDelimitedList(labelToMerge.Tags.ToListFromDelimited());
var altNames = labelToMerge.AlternateNames.ToListFromDelimited().ToList();
altNames.Add(labelToMerge.Name);
altNames.Add(labelToMerge.SortName);
altNames.Add(labelToMerge.Name.ToAlphanumericName());
label.AlternateNames = label.AlternateNames.AddToDelimitedList(altNames);
label.URLs = label.URLs.AddToDelimitedList(labelToMerge.URLs.ToListFromDelimited());
var labelToMergeReleases = (from rl in DbContext.ReleaseLabels
where rl.LabelId == labelToMerge.Id
select rl);
foreach (var labelToMergeRelease in labelToMergeReleases)
{
labelToMergeRelease.LabelId = label.Id;
labelToMergeRelease.LastUpdated = now;
}
label.LastUpdated = now;
await DbContext.SaveChangesAsync();
}
await UpdateLabelCounts(label.Id, now);
CacheManager.ClearRegion(label.CacheRegion);
Logger.LogInformation($"MergeLabelsIntoLabel `{label}`, Merged Label Ids [{ string.Join(",", labelIdsToMerge) }] By User `{user}`");
sw.Stop();
return new OperationResult<bool>
{
IsSuccess = !errors.Any(),
Data = !errors.Any(),
OperationTime = sw.ElapsedMilliseconds,
Errors = errors
};
}
public async Task<OperationResult<Image>> SetLabelImageByUrl(User user, Guid id, string imageUrl)
{
return await SaveImageBytes(user, id, WebHelper.BytesForImageUrl(imageUrl));
@ -168,7 +256,11 @@ namespace Roadie.Api.Services
try
{
var now = DateTime.UtcNow;
label.AlternateNames = model.AlternateNamesList.ToDelimitedList();
var specialArtistName = model.Name.ToAlphanumericName();
var alt = new List<string>(model.AlternateNamesList);
if (!model.AlternateNamesList.Contains(specialArtistName, StringComparer.OrdinalIgnoreCase))
alt.Add(specialArtistName);
label.AlternateNames = alt.ToDelimitedList();
label.BeginDate = model.BeginDate;
label.DiscogsId = model.DiscogsId;
label.EndDate = model.EndDate;
@ -184,7 +276,8 @@ namespace Roadie.Api.Services
var labelImage = ImageHelper.ImageDataFromUrl(model.NewThumbnailData);
if (labelImage != null)
{
// Resize to store in database as thumbnail
// Save unaltered label image
File.WriteAllBytes(label.PathToImage(Configuration), ImageHelper.ConvertToJpegFormat(labelImage));
label.Thumbnail = ImageHelper.ResizeToThumbnail(labelImage, Configuration);
}
@ -319,7 +412,8 @@ namespace Roadie.Api.Services
label.Thumbnail = imageBytes;
if (label.Thumbnail != null)
{
// Ensure is jpeg first
// Save unaltered label image
File.WriteAllBytes(label.PathToImage(Configuration), ImageHelper.ConvertToJpegFormat(imageBytes));
label.Thumbnail = ImageHelper.ResizeToThumbnail(label.Thumbnail, Configuration);
}

View file

@ -17,6 +17,7 @@ using Roadie.Library.Utility;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
@ -176,6 +177,13 @@ namespace Roadie.Api.Services
DbContext.Playlists.Remove(playlist);
await DbContext.SaveChangesAsync();
var playlistImageFilename = playlist.PathToImage(Configuration);
if (File.Exists(playlistImageFilename))
{
File.Delete(playlistImageFilename);
}
Logger.LogInformation("User `{0}` deleted Playlist `{1}]`", user, playlist);
CacheManager.ClearRegion(playlist.CacheRegion);
sw.Stop();
@ -295,7 +303,9 @@ namespace Roadie.Api.Services
var playlistImage = ImageHelper.ImageDataFromUrl(model.NewThumbnailData);
if (playlistImage != null)
{
// Ensure is jpeg first
// Save unaltered playlist image
File.WriteAllBytes(playlist.PathToImage(Configuration), ImageHelper.ConvertToJpegFormat(playlistImage));
// Update thumbnail
playlist.Thumbnail = ImageHelper.ResizeToThumbnail(playlistImage, Configuration);
}

View file

@ -569,10 +569,8 @@ namespace Roadie.Api.Services
releaseToMergeInto.MediaCount = releaseToMergeInto.MediaCount ?? 0;
var now = DateTime.UtcNow;
var releaseToMergeReleaseMedia =
DbContext.ReleaseMedias.Where(x => x.ReleaseId == releaseToMerge.Id).ToList();
var releaseToMergeIntoReleaseMedia =
DbContext.ReleaseMedias.Where(x => x.ReleaseId == releaseToMergeInto.Id).ToList();
var releaseToMergeReleaseMedia = DbContext.ReleaseMedias.Where(x => x.ReleaseId == releaseToMerge.Id).ToList();
var releaseToMergeIntoReleaseMedia = DbContext.ReleaseMedias.Where(x => x.ReleaseId == releaseToMergeInto.Id).ToList();
var releaseToMergeIntoLastMediaNumber = releaseToMergeIntoReleaseMedia.Max(x => x.MediaNumber);
// Add new ReleaseMedia
@ -628,37 +626,29 @@ namespace Roadie.Api.Services
else
{
// Track does exist merge two tracks together
existingTrack.MusicBrainzId =
existingTrack.MusicBrainzId ?? mergeTrack.MusicBrainzId;
existingTrack.MusicBrainzId = existingTrack.MusicBrainzId ?? mergeTrack.MusicBrainzId;
existingTrack.SpotifyId = existingTrack.SpotifyId ?? mergeTrack.SpotifyId;
existingTrack.AmgId = existingTrack.AmgId ?? mergeTrack.AmgId;
existingTrack.ISRC = existingTrack.ISRC ?? mergeTrack.ISRC;
existingTrack.AmgId = existingTrack.AmgId ?? mergeTrack.AmgId;
existingTrack.LastFMId = existingTrack.LastFMId ?? mergeTrack.LastFMId;
existingTrack.PartTitles = existingTrack.PartTitles ?? mergeTrack.PartTitles;
existingTrack.PlayedCount =
(existingTrack.PlayedCount ?? 0) + (mergeTrack.PlayedCount ?? 0);
existingTrack.PlayedCount = (existingTrack.PlayedCount ?? 0) + (mergeTrack.PlayedCount ?? 0);
if (mergeTrack.LastPlayed.HasValue && existingTrack.LastPlayed.HasValue &&
mergeTrack.LastPlayed > existingTrack.LastPlayed)
existingTrack.LastPlayed = mergeTrack.LastPlayed;
existingTrack.Thumbnail = existingTrack.Thumbnail ?? mergeTrack.Thumbnail;
existingTrack.MusicBrainzId =
existingTrack.MusicBrainzId ?? mergeTrack.MusicBrainzId;
existingTrack.Tags =
existingTrack.Tags.AddToDelimitedList(mergeTrack.Tags.ToListFromDelimited());
existingTrack.MusicBrainzId = existingTrack.MusicBrainzId ?? mergeTrack.MusicBrainzId;
existingTrack.Tags = existingTrack.Tags.AddToDelimitedList(mergeTrack.Tags.ToListFromDelimited());
if (!mergeTrack.Title.Equals(existingTrack.Title,
StringComparison.OrdinalIgnoreCase))
existingTrack.AlternateNames =
existingTrack.AlternateNames.AddToDelimitedList(new[]
{mergeTrack.Title, mergeTrack.Title.ToAlphanumericName()});
existingTrack.AlternateNames =
existingTrack.AlternateNames.AddToDelimitedList(mergeTrack.AlternateNames
.ToListFromDelimited());
existingTrack.AlternateNames = existingTrack.AlternateNames.AddToDelimitedList(mergeTrack.AlternateNames.ToListFromDelimited());
existingTrack.LastUpdated = now;
var mergedTrackFileName =
mergeTrack.PathToTrack(Configuration);
var trackFileName =
existingTrack.PathToTrack(Configuration);
var mergedTrackFileName = mergeTrack.PathToTrack(Configuration);
var trackFileName = existingTrack.PathToTrack(Configuration);
if (!trackFileName.Equals(mergedTrackFileName, StringComparison.Ordinal) &&
File.Exists(trackFileName)) mergedFilesToDelete.Add(mergedTrackFileName);
}
@ -805,8 +795,7 @@ namespace Roadie.Api.Services
};
}
public async Task<OperationResult<bool>> Delete(ApplicationUser user, data.Release release, bool doDeleteFiles = false,
bool doUpdateArtistCounts = true)
public async Task<OperationResult<bool>> Delete(ApplicationUser user, data.Release release, bool doDeleteFiles = false, bool doUpdateArtistCounts = true)
{
SimpleContract.Requires<ArgumentNullException>(release != null, "Invalid Release");
SimpleContract.Requires<ArgumentNullException>(release.Artist != null, "Invalid Artist");

View file

@ -19,6 +19,7 @@ using Roadie.Library.Utility;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
@ -408,8 +409,20 @@ namespace Roadie.Api.Services
{
var imageData = ImageHelper.ImageDataFromUrl(userBeingUpdatedModel.AvatarData);
if (imageData != null)
user.Avatar = ImageHelper.ResizeImage(imageData, Configuration.ThumbnailImageSize.Width,
Configuration.ThumbnailImageSize.Height);
{
imageData = ImageHelper.ConvertToGifFormat(imageData);
// Save unaltered user image
File.WriteAllBytes(user.PathToImage(Configuration), imageData);
// Update thumbnail
user.Avatar = ImageHelper.ResizeImage(imageData, Configuration.ThumbnailImageSize.Width, Configuration.ThumbnailImageSize.Height);
if(user.Avatar.Length >= ImageHelper.MaximumThumbnailByteSize)
{
user.Avatar = null;
}
}
}
await DbContext.SaveChangesAsync();
@ -518,21 +531,20 @@ namespace Roadie.Api.Services
{
var user = GetUser(id);
if (user == null)
{
return Task.FromResult(new OperationResult<User>(true, string.Format("User Not Found [{0}]", id)));
}
var model = user.Adapt<User>();
model.MediumThumbnail = MakeThumbnailImage(id, "user", Configuration.MediumImageSize.Width, Configuration.MediumImageSize.Height);
model.IsAdmin = user.UserRoles?.Any(x => x.Role?.NormalizedName == "ADMIN") ?? false;
model.IsEditor = model.IsAdmin ? true : user.UserRoles?.Any(x => x.Role?.NormalizedName == "EDITOR") ?? false;
if (includes != null && includes.Any())
{
if (includes.Contains("stats"))
{
var userArtists =
DbContext.UserArtists.Include(x => x.Artist).Where(x => x.UserId == user.Id).ToArray() ??
new data.UserArtist[0];
var userReleases =
DbContext.UserReleases.Include(x => x.Release).Where(x => x.UserId == user.Id).ToArray() ??
new data.UserRelease[0];
var userTracks =
DbContext.UserTracks.Include(x => x.Track).Where(x => x.UserId == user.Id).ToArray() ??
new data.UserTrack[0];
var userArtists = DbContext.UserArtists.Include(x => x.Artist).Where(x => x.UserId == user.Id).ToArray() ?? new data.UserArtist[0];
var userReleases = DbContext.UserReleases.Include(x => x.Release).Where(x => x.UserId == user.Id).ToArray() ?? new data.UserRelease[0];
var userTracks = DbContext.UserTracks.Include(x => x.Track).Where(x => x.UserId == user.Id).ToArray() ?? new data.UserTrack[0];
var mostPlayedArtist = (from a in DbContext.Artists
join r in DbContext.Releases on a.Id equals r.ArtistId
join rm in DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
@ -548,7 +560,6 @@ namespace Roadie.Api.Services
})
.OrderByDescending(x => x.Played)
.FirstOrDefault();
var mostPlayedReleaseId = (from r in DbContext.Releases
join rm in DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
join t in DbContext.Tracks on rm.Id equals t.ReleaseMediaId
@ -564,9 +575,7 @@ namespace Roadie.Api.Services
.OrderByDescending(x => x.Played)
.Select(x => x.Release.RoadieId)
.FirstOrDefault();
var mostPlayedRelease = GetRelease(mostPlayedReleaseId);
var mostPlayedTrackUserTrack = userTracks
.OrderByDescending(x => x.PlayedCount)
.FirstOrDefault();
@ -620,7 +629,7 @@ namespace Roadie.Api.Services
DislikedTracks = userTracks.Where(x => x.IsDisliked ?? false).Count()
};
}
}
return Task.FromResult(new OperationResult<User>
{
IsSuccess = true,

View file

@ -73,6 +73,15 @@ namespace Roadie.Api.Controllers
return Ok(result);
}
[HttpPost("delete/label/{id}")]
[ProducesResponseType(200)]
public async Task<IActionResult> DeleteLabel(Guid id)
{
var result = await AdminService.DeleteLabel(await UserManager.GetUserAsync(User), id);
if (!result.IsSuccess) return StatusCode((int)HttpStatusCode.InternalServerError);
return Ok(result);
}
[HttpPost("delete/releasesecondaryimage/{id}/{index}")]
[ProducesResponseType(200)]
public async Task<IActionResult> DeleteReleaseSecondaryImage(Guid id, int index)

View file

@ -138,8 +138,7 @@ namespace Roadie.Api.Controllers
[ProducesResponseType(404)]
public async Task<IActionResult> ReleaseImage(Guid id, int? width, int? height)
{
var result = await ImageService.ReleaseImage(id, width ?? RoadieSettings.ThumbnailImageSize.Width,
height ?? RoadieSettings.ThumbnailImageSize.Height);
var result = await ImageService.ReleaseImage(id, width ?? RoadieSettings.ThumbnailImageSize.Width, height ?? RoadieSettings.ThumbnailImageSize.Height);
if (result == null || result.IsNotFoundResult) return NotFound();
if (!result.IsSuccess) return StatusCode((int)HttpStatusCode.InternalServerError);
return File(result.Data.Bytes,
@ -203,8 +202,7 @@ namespace Roadie.Api.Controllers
[ProducesResponseType(404)]
public async Task<IActionResult> TrackImage(Guid id, int? width, int? height)
{
var result = await ImageService.TrackImage(id, width ?? RoadieSettings.ThumbnailImageSize.Width,
height ?? RoadieSettings.ThumbnailImageSize.Height);
var result = await ImageService.TrackImage(id, width ?? RoadieSettings.ThumbnailImageSize.Width, height ?? RoadieSettings.ThumbnailImageSize.Height);
if (result == null || result.IsNotFoundResult) return NotFound();
if (!result.IsSuccess) return StatusCode((int)HttpStatusCode.InternalServerError);
return File(result.Data.Bytes,
@ -215,20 +213,19 @@ namespace Roadie.Api.Controllers
}
/// <summary>
/// NOTE that user images/avatars are PNG not JPG this is so it looks better in the menus/applications
/// NOTE that user images/avatars are GIF not JPG this is so it looks better in the menus/applications
/// </summary>
[HttpGet("user/{id}/{width:int?}/{height:int?}/{cacheBuster?}")]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public async Task<IActionResult> UserImage(Guid id, int? width, int? height)
{
var result = await ImageService.UserImage(id, width ?? RoadieSettings.ThumbnailImageSize.Width,
height ?? RoadieSettings.ThumbnailImageSize.Height);
var result = await ImageService.UserImage(id, width ?? RoadieSettings.ThumbnailImageSize.Width, height ?? RoadieSettings.ThumbnailImageSize.Height);
if (result == null || result.IsNotFoundResult) return NotFound();
if (!result.IsSuccess) return StatusCode((int)HttpStatusCode.InternalServerError);
return File(result.Data.Bytes,
result.ContentType,
$"{result.Data.Caption ?? id.ToString()}.png",
$"{result.Data.Caption ?? id.ToString()}.gif",
result.LastModified,
result.ETag);
}

View file

@ -68,16 +68,39 @@ namespace Roadie.Api.Controllers
return StatusCode((int)HttpStatusCode.InternalServerError);
}
[HttpPost("mergeLabels/{labelToMergeId}/{labelToMergeIntoId}")]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
[Authorize(Policy = "Editor")]
public async Task<IActionResult> MergeLabels(Guid labelToMergeId, Guid labelToMergeIntoId)
{
var result = await LabelService.MergeLabelsIntoLabel(await UserManager.GetUserAsync(User), labelToMergeIntoId, new Guid[1] { labelToMergeId });
if (result == null || result.IsNotFoundResult)
{
return NotFound();
}
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
return Ok(result);
}
[HttpPost("setImageByUrl/{id}/{imageUrl}")]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
[Authorize(Policy = "Editor")]
public async Task<IActionResult> SetLabelImageByUrl(Guid id, string imageUrl)
{
var result =
await LabelService.SetLabelImageByUrl(await CurrentUserModel(), id, HttpUtility.UrlDecode(imageUrl));
if (result == null || result.IsNotFoundResult) return NotFound();
if (!result.IsSuccess) return StatusCode((int)HttpStatusCode.InternalServerError);
var result = await LabelService.SetLabelImageByUrl(await CurrentUserModel(), id, HttpUtility.UrlDecode(imageUrl));
if (result == null || result.IsNotFoundResult)
{
return NotFound();
}
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
return Ok(result);
}

View file

@ -228,7 +228,7 @@ namespace Roadie.Api
services.AddScoped<ILookupService, LookupService>();
services.AddScoped<ICommentService, CommentService>();
var securityKey = new SymmetricSecurityKey(Encoding.Default.GetBytes(_configuration["Tokens:PrivateKey"]));
var securityKey = new SymmetricSecurityKey(Encoding.Default.GetBytes(_configuration["Tokens:PrivateKey"]));
services.AddAuthentication(options =>
{
@ -288,11 +288,17 @@ namespace Roadie.Api
services.AddHttpContextAccessor();
services.AddScoped<IHttpContext>(factory =>
{
var actionContext = factory.GetService<IActionContextAccessor>()
.ActionContext;
var actionContext = factory.GetService<IActionContextAccessor>().ActionContext;
if(actionContext == null)
{
return null;
}
return new HttpContext(factory.GetService<IRoadieSettings>(), new UrlHelper(actionContext));
});
var sp = services.BuildServiceProvider();
var adminService = sp.GetService<IAdminService>();
adminService.PerformStartUpTasks();
}
private class IntegrationKey