mirror of
https://github.com/sphildreth/roadie
synced 2024-11-21 19:53:11 +00:00
updated to v1.1.0; resolves #35
This commit is contained in:
parent
15c0c04504
commit
6fc03268b6
142 changed files with 3063 additions and 1501 deletions
|
@ -25,7 +25,6 @@
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.1" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace Roadie.Library.Tests
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
var token = ServiceBase.TrackPlayToken(new ApplicationUser
|
var token = ServiceBase.TrackPlayToken(new User
|
||||||
{
|
{
|
||||||
Id = 1,
|
Id = 1,
|
||||||
CreatedDate = DateTime.UtcNow
|
CreatedDate = DateTime.UtcNow
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
using System;
|
namespace Roadie.Library.Configuration
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Roadie.Library.Configuration
|
|
||||||
{
|
{
|
||||||
public enum DbContexts : short
|
public enum DbContexts : short
|
||||||
{
|
{
|
||||||
MySQL = 1,
|
Unknown = 0,
|
||||||
File = 2
|
SQLite = 1,
|
||||||
|
File = 2,
|
||||||
|
MySQL = 3
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,7 +19,7 @@ namespace Roadie.Library.Configuration
|
||||||
{
|
{
|
||||||
DatabaseFormat = FileDatabaseFormat.BSON;
|
DatabaseFormat = FileDatabaseFormat.BSON;
|
||||||
DatabaseName = "roadie";
|
DatabaseName = "roadie";
|
||||||
DatabaseFolder = @"M:\db";
|
DatabaseFolder = "data/db";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,7 @@ namespace Roadie.Library.Configuration
|
||||||
var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "DiscogsConsumerKey");
|
var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "DiscogsConsumerKey");
|
||||||
if (keySetting != null)
|
if (keySetting != null)
|
||||||
return keySetting.Key;
|
return keySetting.Key;
|
||||||
Trace.WriteLine(
|
Trace.WriteLine("Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled", "Warning");
|
||||||
"Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,8 +31,7 @@ namespace Roadie.Library.Configuration
|
||||||
var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "DiscogsConsumerKey");
|
var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "DiscogsConsumerKey");
|
||||||
if (keySetting != null)
|
if (keySetting != null)
|
||||||
return keySetting.KeySecret;
|
return keySetting.KeySecret;
|
||||||
Trace.WriteLine(
|
Trace.WriteLine("Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled", "Warning");
|
||||||
"Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +75,7 @@ namespace Roadie.Library.Configuration
|
||||||
var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey");
|
var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey");
|
||||||
if (keySetting != null)
|
if (keySetting != null)
|
||||||
return keySetting.Key;
|
return keySetting.Key;
|
||||||
Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled");
|
Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled", "Warning");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +87,7 @@ namespace Roadie.Library.Configuration
|
||||||
var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey");
|
var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey");
|
||||||
if (keySetting != null)
|
if (keySetting != null)
|
||||||
return keySetting.KeySecret;
|
return keySetting.KeySecret;
|
||||||
Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled");
|
Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled", "Warning");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Roadie.Library.Configuration
|
||||||
{
|
{
|
||||||
public static string RoadieImageFolder = "__roadie_images";
|
public static string RoadieImageFolder = "__roadie_images";
|
||||||
|
|
||||||
public DbContexts DbContextToUse { get; set; }
|
public DbContexts DbContextToUse { get; set; } = DbContexts.SQLite;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If the artist name is found in the values then use the key.
|
/// If the artist name is found in the values then use the key.
|
||||||
|
@ -81,7 +81,6 @@ namespace Roadie.Library.Configuration
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageSize LargeImageSize { get; set; }
|
public ImageSize LargeImageSize { get; set; }
|
||||||
|
|
||||||
public string LibraryFolder { get; set; }
|
public string LibraryFolder { get; set; }
|
||||||
public string ListenAddress { get; set; }
|
public string ListenAddress { get; set; }
|
||||||
|
|
||||||
|
@ -151,7 +150,7 @@ namespace Roadie.Library.Configuration
|
||||||
|
|
||||||
public RoadieSettings()
|
public RoadieSettings()
|
||||||
{
|
{
|
||||||
DbContextToUse = DbContexts.MySQL;
|
DbContextToUse = DbContexts.SQLite;
|
||||||
ArtistNameReplace = new Dictionary<string, IEnumerable<string>>
|
ArtistNameReplace = new Dictionary<string, IEnumerable<string>>
|
||||||
{
|
{
|
||||||
{ "AC/DC", new List<string>{ "AC; DC", "AC;DC", "AC/ DC", "AC DC" }},
|
{ "AC/DC", new List<string>{ "AC; DC", "AC;DC", "AC/ DC", "AC DC" }},
|
||||||
|
@ -159,10 +158,10 @@ namespace Roadie.Library.Configuration
|
||||||
};
|
};
|
||||||
DefaultTimeZone = "US / Central";
|
DefaultTimeZone = "US / Central";
|
||||||
DontDoMetaDataProvidersSearchArtists = new List<string> { "Various Artists", "Sound Tracks" };
|
DontDoMetaDataProvidersSearchArtists = new List<string> { "Various Artists", "Sound Tracks" };
|
||||||
FileExtensionsToDelete = new List<string> { ".accurip", ".bmp", ".cue", ".dat", ".db", ".exe", ".gif", ".htm", ".html", ".ini", ".log", ".jpg", ".jpeg", ".par", ".par2", ".pdf", ".png", ".md5", ".mht", ".mpg", ".m3u", ".nfo", ".nzb", ".pls", ".sfv", ".srr", ".txt", ".url" };
|
FileExtensionsToDelete = new List<string> { ".accurip", ".cue", ".dat", ".db", ".exe", ".htm", ".html", ".ini", ".log", ".par", ".par2", ".pdf", ".md5", ".mht", ".mpg", ".m3u", ".nfo", ".nzb", ".pls", ".sfv", ".srr", ".txt", ".url" };
|
||||||
InboundFolder = "M:/inbound";
|
InboundFolder = "data/inbound";
|
||||||
LargeImageSize = new ImageSize { Width = 500, Height = 500 };
|
LargeImageSize = new ImageSize { Width = 500, Height = 500 };
|
||||||
LibraryFolder = "M:/library";
|
LibraryFolder = "data/library";
|
||||||
MaximumImageSize = new ImageSize { Width = 2048, Height = 2048 };
|
MaximumImageSize = new ImageSize { Width = 2048, Height = 2048 };
|
||||||
MediumImageSize = new ImageSize { Width = 320, Height = 320 };
|
MediumImageSize = new ImageSize { Width = 320, Height = 320 };
|
||||||
RecordNoResultSearches = true;
|
RecordNoResultSearches = true;
|
||||||
|
@ -174,7 +173,6 @@ namespace Roadie.Library.Configuration
|
||||||
SmtpFromAddress = "noreply@roadie.rocks";
|
SmtpFromAddress = "noreply@roadie.rocks";
|
||||||
SmtpPort = 587;
|
SmtpPort = 587;
|
||||||
SmtpUsername = "roadie";
|
SmtpUsername = "roadie";
|
||||||
SmtpHost = "smtp.roadie.rocks";
|
|
||||||
SmtpUseSSl = true;
|
SmtpUseSSl = true;
|
||||||
|
|
||||||
Inspector = new Inspector();
|
Inspector = new Inspector();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Roadie.Library.Enums;
|
using Roadie.Library.Enums;
|
||||||
using Roadie.Library.Imaging;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
@ -10,12 +9,18 @@ namespace Roadie.Library.Data
|
||||||
[Table("artist")]
|
[Table("artist")]
|
||||||
public partial class Artist : BeginAndEndNamedEntityBase
|
public partial class Artist : BeginAndEndNamedEntityBase
|
||||||
{
|
{
|
||||||
[Column("amgId")] [MaxLength(100)] public string AmgId { get; set; }
|
[Column("amgId")]
|
||||||
|
[MaxLength(100)]
|
||||||
|
public string AmgId { get; set; }
|
||||||
|
|
||||||
[Column("artistType", TypeName = "enum")]
|
[Column("artistType", TypeName = "enum")]
|
||||||
public string ArtistType { get; set; }
|
public string ArtistType { get; set; }
|
||||||
|
|
||||||
[InverseProperty("Artist")] public ICollection<ArtistAssociation> AssociatedArtists { get; set; }
|
/// <summary>
|
||||||
|
/// Artists who this Artist is Associated To
|
||||||
|
/// </summary>
|
||||||
|
[InverseProperty("Artist")]
|
||||||
|
public virtual ICollection<ArtistAssociation> AssociatedArtists { get; set; }
|
||||||
|
|
||||||
[Column("bandStatus", TypeName = "enum")]
|
[Column("bandStatus", TypeName = "enum")]
|
||||||
public BandStatus? BandStatus { get; set; }
|
public BandStatus? BandStatus { get; set; }
|
||||||
|
@ -27,46 +32,77 @@ namespace Roadie.Library.Data
|
||||||
[Column("birthDate", TypeName = "date")]
|
[Column("birthDate", TypeName = "date")]
|
||||||
public DateTime? BirthDate { get; set; }
|
public DateTime? BirthDate { get; set; }
|
||||||
|
|
||||||
public ICollection<Comment> Comments { get; set; }
|
[InverseProperty("Artist")]
|
||||||
|
public virtual ICollection<Comment> Comments { get; set; }
|
||||||
|
|
||||||
[Column("discogsId")] [MaxLength(50)] public string DiscogsId { get; set; }
|
[InverseProperty("Artist")]
|
||||||
|
public virtual ICollection<Credit> Credits { get; set; }
|
||||||
|
|
||||||
public ICollection<ArtistGenre> Genres { get; set; }
|
[Column("discogsId")]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string DiscogsId { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("Artist")]
|
||||||
|
public virtual ICollection<ArtistGenre> Genres { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Where the Artist is the Artist on the Track not on an Artist Release
|
||||||
|
/// </summary>
|
||||||
|
[InverseProperty("TrackArtist")]
|
||||||
|
public virtual ICollection<Track> Tracks { get; set; }
|
||||||
|
|
||||||
[Column("isniList", TypeName = "text")]
|
[Column("isniList", TypeName = "text")]
|
||||||
[MaxLength(65535)]
|
[MaxLength(65535)]
|
||||||
public string ISNI { get; set; }
|
public string ISNI { get; set; }
|
||||||
|
|
||||||
[Column("iTunesId")] [MaxLength(100)] public string ITunesId { get; set; }
|
[Column("iTunesId")]
|
||||||
|
[MaxLength(100)]
|
||||||
|
public string ITunesId { get; set; }
|
||||||
|
|
||||||
[Column("lastPlayed")] public DateTime? LastPlayed { get; set; }
|
[Column("lastPlayed")]
|
||||||
|
public DateTime? LastPlayed { get; set; }
|
||||||
|
|
||||||
[Column("musicBrainzId")]
|
[Column("musicBrainzId")]
|
||||||
[MaxLength(100)]
|
[MaxLength(100)]
|
||||||
public string MusicBrainzId { get; set; }
|
public string MusicBrainzId { get; set; }
|
||||||
|
|
||||||
[Column("playedCount")] public int? PlayedCount { get; set; }
|
[Column("playedCount")]
|
||||||
|
public int? PlayedCount { get; set; }
|
||||||
|
|
||||||
[Column("profile", TypeName = "text")]
|
[Column("profile", TypeName = "text")]
|
||||||
[MaxLength(65535)]
|
[MaxLength(65535)]
|
||||||
public string Profile { get; set; }
|
public string Profile { get; set; }
|
||||||
|
|
||||||
[Column("rank")] public decimal? Rank { get; set; }
|
[Column("rank")]
|
||||||
|
public decimal? Rank { get; set; }
|
||||||
|
|
||||||
[Column("rating")] public short? Rating { get; set; }
|
[Column("rating")]
|
||||||
|
public short? Rating { get; set; }
|
||||||
|
|
||||||
[Column("realName")] [MaxLength(500)] public string RealName { get; set; }
|
[Column("realName")]
|
||||||
|
[MaxLength(500)]
|
||||||
|
public string RealName { get; set; }
|
||||||
|
|
||||||
[Column("releaseCount")] public int? ReleaseCount { get; set; }
|
[Column("releaseCount")]
|
||||||
|
public int? ReleaseCount { get; set; }
|
||||||
|
|
||||||
//public List<Release> Releases { get; set; }
|
public virtual ICollection<Release> Releases { get; set; }
|
||||||
public ICollection<Release> Releases { get; set; }
|
|
||||||
|
|
||||||
[InverseProperty("Artist")] public ICollection<ArtistSimilar> SimilarArtists { get; set; }
|
/// <summary>
|
||||||
|
/// Artists who are similiar to this Artist
|
||||||
|
/// </summary>
|
||||||
|
[InverseProperty("Artist")]
|
||||||
|
public virtual ICollection<ArtistSimilar> SimilarArtists { get; set; }
|
||||||
|
|
||||||
[Column("spotifyId")] [MaxLength(100)] public string SpotifyId { get; set; }
|
[Column("spotifyId")]
|
||||||
|
[MaxLength(100)]
|
||||||
|
public string SpotifyId { get; set; }
|
||||||
|
|
||||||
[Column("trackCount")] public int? TrackCount { get; set; }
|
[Column("trackCount")]
|
||||||
|
public int? TrackCount { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("Artist")]
|
||||||
|
public virtual ICollection<UserArtist> UserArtists { get; set; }
|
||||||
|
|
||||||
public Artist()
|
public Artist()
|
||||||
{
|
{
|
||||||
|
@ -75,6 +111,8 @@ namespace Roadie.Library.Data
|
||||||
AssociatedArtists = new HashSet<ArtistAssociation>();
|
AssociatedArtists = new HashSet<ArtistAssociation>();
|
||||||
SimilarArtists = new HashSet<ArtistSimilar>();
|
SimilarArtists = new HashSet<ArtistSimilar>();
|
||||||
Comments = new HashSet<Comment>();
|
Comments = new HashSet<Comment>();
|
||||||
|
UserArtists = new HashSet<UserArtist>();
|
||||||
|
|
||||||
Rating = 0;
|
Rating = 0;
|
||||||
Status = Statuses.Ok;
|
Status = Statuses.Ok;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,20 @@ namespace Roadie.Library.Data
|
||||||
[Table("artistAssociation")]
|
[Table("artistAssociation")]
|
||||||
public class ArtistAssociation
|
public class ArtistAssociation
|
||||||
{
|
{
|
||||||
//[ForeignKey("artistId")]
|
[ForeignKey(nameof(ArtistId))]
|
||||||
public Artist Artist { get; set; }
|
[InverseProperty("AssociatedArtists")]
|
||||||
|
public virtual Artist Artist { get; set; }
|
||||||
|
|
||||||
[Column("artistId")] [Required] public int ArtistId { get; set; }
|
[Column("artistId")]
|
||||||
|
[Required]
|
||||||
|
public int ArtistId { get; set; }
|
||||||
|
|
||||||
//[ForeignKey("associatedArtistId")]
|
[ForeignKey(nameof(AssociatedArtistId))]
|
||||||
public Artist AssociatedArtist { get; set; }
|
public virtual Artist AssociatedArtist { get; set; }
|
||||||
|
|
||||||
[Column("associatedArtistId")] public int AssociatedArtistId { get; set; }
|
[Column("associatedArtistId")]
|
||||||
|
[Required]
|
||||||
|
public int AssociatedArtistId { get; set; }
|
||||||
|
|
||||||
[Key]
|
[Key]
|
||||||
[Column("id")]
|
[Column("id")]
|
||||||
|
|
|
@ -6,17 +6,25 @@ namespace Roadie.Library.Data
|
||||||
[Table("artistGenreTable")]
|
[Table("artistGenreTable")]
|
||||||
public class ArtistGenre
|
public class ArtistGenre
|
||||||
{
|
{
|
||||||
public Artist Artist { get; set; }
|
|
||||||
|
|
||||||
[Column("artistId")] [Required] public int ArtistId { get; set; }
|
|
||||||
|
|
||||||
public Genre Genre { get; set; }
|
|
||||||
|
|
||||||
[Column("genreId")] [Required] public int? GenreId { get; set; }
|
|
||||||
|
|
||||||
[Column("id")]
|
|
||||||
[Key]
|
[Key]
|
||||||
|
[Column("id")]
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[Column("artistId")]
|
||||||
|
[Required]
|
||||||
|
public int ArtistId { get; set; }
|
||||||
|
|
||||||
|
[Column("genreId")]
|
||||||
|
[Required]
|
||||||
|
public int GenreId { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(ArtistId))]
|
||||||
|
[InverseProperty("Genres")]
|
||||||
|
public virtual Artist Artist { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(GenreId))]
|
||||||
|
[InverseProperty("Artists")]
|
||||||
|
public virtual Genre Genre { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,8 +3,6 @@ using Roadie.Library.Utility;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
|
|
||||||
namespace Roadie.Library.Data
|
namespace Roadie.Library.Data
|
||||||
{
|
{
|
||||||
|
@ -29,8 +27,6 @@ namespace Roadie.Library.Data
|
||||||
|
|
||||||
public bool IsValid => !string.IsNullOrEmpty(Name);
|
public bool IsValid => !string.IsNullOrEmpty(Name);
|
||||||
|
|
||||||
public string SortNameValue => string.IsNullOrEmpty(SortName) ? Name : SortName;
|
|
||||||
|
|
||||||
public string GroupBy => SortNameValue.Substring(0, 1).ToUpper();
|
public string GroupBy => SortNameValue.Substring(0, 1).ToUpper();
|
||||||
|
|
||||||
public static string CacheRegionUrn(Guid Id)
|
public static string CacheRegionUrn(Guid Id)
|
||||||
|
@ -55,7 +51,7 @@ namespace Roadie.Library.Data
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"Id [{ Id }], Status [{ Status }], Name [{ Name }], SortName [{ SortNameValue}], RoadieId [{ RoadieId}]";
|
return $"Id [{ Id }], Status [{ Status }], Name [{ Name }], SortName [{ SortName }], RoadieId [{ RoadieId}]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,19 +6,23 @@ namespace Roadie.Library.Data
|
||||||
[Table("artistSimilar")]
|
[Table("artistSimilar")]
|
||||||
public class ArtistSimilar
|
public class ArtistSimilar
|
||||||
{
|
{
|
||||||
//[ForeignKey("artistId")]
|
[ForeignKey(nameof(ArtistId))]
|
||||||
public Artist Artist { get; set; }
|
[InverseProperty("SimilarArtists")]
|
||||||
|
public virtual Artist Artist { get; set; }
|
||||||
|
|
||||||
[Column("artistId")] [Required] public int ArtistId { get; set; }
|
[Column("artistId")]
|
||||||
|
[Required]
|
||||||
|
public int ArtistId { get; set; }
|
||||||
|
|
||||||
[Key]
|
[Key]
|
||||||
[Column("id")]
|
[Column("id")]
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
//[ForeignKey("associatedArtistId")]
|
[ForeignKey(nameof(SimilarArtistId))]
|
||||||
public Artist SimilarArtist { get; set; }
|
public virtual Artist SimilarArtist { get; set; }
|
||||||
|
|
||||||
[Column("similarArtistId")] public int SimilarArtistId { get; set; }
|
[Column("similarArtistId")]
|
||||||
|
public int SimilarArtistId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,6 +8,7 @@ namespace Roadie.Library.Data
|
||||||
[Column("beginDate", TypeName = "date")]
|
[Column("beginDate", TypeName = "date")]
|
||||||
public DateTime? BeginDate { get; set; }
|
public DateTime? BeginDate { get; set; }
|
||||||
|
|
||||||
[Column("endDate", TypeName = "date")] public DateTime? EndDate { get; set; }
|
[Column("endDate", TypeName = "date")]
|
||||||
|
public DateTime? EndDate { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,8 +5,10 @@ namespace Roadie.Library.Data
|
||||||
{
|
{
|
||||||
public abstract class BeginAndEndNamedEntityBase : NamedEntityBase
|
public abstract class BeginAndEndNamedEntityBase : NamedEntityBase
|
||||||
{
|
{
|
||||||
[Column("beginDate")] public DateTime? BeginDate { get; set; }
|
[Column("beginDate")]
|
||||||
|
public DateTime? BeginDate { get; set; }
|
||||||
|
|
||||||
[Column("endDate")] public DateTime? EndDate { get; set; }
|
[Column("endDate")]
|
||||||
|
public DateTime? EndDate { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,16 +8,27 @@ namespace Roadie.Library.Data
|
||||||
[Table("bookmark")]
|
[Table("bookmark")]
|
||||||
public partial class Bookmark : EntityBase
|
public partial class Bookmark : EntityBase
|
||||||
{
|
{
|
||||||
[Column("bookmarkTargetId")] public int BookmarkTargetId { get; set; }
|
[Column("bookmarkTargetId")]
|
||||||
|
public int BookmarkTargetId { get; set; }
|
||||||
|
|
||||||
// public short? Type { get; set; }
|
// public short? Type { get; set; }
|
||||||
|
|
||||||
[Column("bookmarkType")] public BookmarkType? BookmarkType { get; set; }
|
[Column("bookmarkType")]
|
||||||
|
public BookmarkType? BookmarkType { get; set; }
|
||||||
|
|
||||||
[Column("Comment")] [MaxLength(4000)] public string Comment { get; set; }
|
[Column("Comment")]
|
||||||
[Column("position")] public int? Position { get; set; }
|
[MaxLength(4000)]
|
||||||
public ApplicationUser User { get; set; }
|
public string Comment { get; set; }
|
||||||
|
|
||||||
[Column("userId")] [Required] public int UserId { get; set; }
|
[Column("position")]
|
||||||
|
public int? Position { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(UserId))]
|
||||||
|
[InverseProperty("Bookmarks")]
|
||||||
|
public virtual User User { get; set; }
|
||||||
|
|
||||||
|
[Column("userId")]
|
||||||
|
[Required]
|
||||||
|
public int UserId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -12,8 +12,12 @@ namespace Roadie.Library.Data
|
||||||
[MaxLength(5000)]
|
[MaxLength(5000)]
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
|
|
||||||
public ApplicationUser User { get; set; }
|
[ForeignKey(nameof(UserId))]
|
||||||
|
[InverseProperty("ChatMessages")]
|
||||||
|
public virtual User User { get; set; }
|
||||||
|
|
||||||
[Column("userId")] [Required] public int UserId { get; set; }
|
[Column("userId")]
|
||||||
|
[Required]
|
||||||
|
public int UserId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using Roadie.Library.Enums;
|
using Roadie.Library.Enums;
|
||||||
|
using Roadie.Library.Identity;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
@ -11,17 +12,18 @@ namespace Roadie.Library.Data
|
||||||
[Column("collectionCount")]
|
[Column("collectionCount")]
|
||||||
public int CollectionCount { get; set; }
|
public int CollectionCount { get; set; }
|
||||||
|
|
||||||
[Column("collectionType")]
|
[Column("collectionType")]
|
||||||
public CollectionType? CollectionType { get; set; }
|
public CollectionType? CollectionType { get; set; }
|
||||||
|
|
||||||
public ICollection<Comment> Comments { get; set; }
|
[InverseProperty("Collection")]
|
||||||
|
public virtual ICollection<Comment> Comments { get; set; }
|
||||||
|
|
||||||
[Column("description")]
|
[Column("description")]
|
||||||
[MaxLength(4000)]
|
[MaxLength(4000)]
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
|
||||||
[Column("edition")]
|
[Column("edition")]
|
||||||
[MaxLength(200)]
|
[MaxLength(200)]
|
||||||
public string Edition { get; set; }
|
public string Edition { get; set; }
|
||||||
|
|
||||||
[Column("listInCSV", TypeName = "text")]
|
[Column("listInCSV", TypeName = "text")]
|
||||||
|
@ -32,9 +34,17 @@ namespace Roadie.Library.Data
|
||||||
[MaxLength(200)]
|
[MaxLength(200)]
|
||||||
public string ListInCSVFormat { get; set; }
|
public string ListInCSVFormat { get; set; }
|
||||||
|
|
||||||
[Column("maintainerId")]
|
[Column("maintainerId")]
|
||||||
public int MaintainerId { get; set; }
|
public int MaintainerId { get; set; }
|
||||||
|
|
||||||
public ICollection<CollectionRelease> Releases { get; set; }
|
[ForeignKey(nameof(MaintainerId))]
|
||||||
|
[InverseProperty(nameof(User.Collections))]
|
||||||
|
public virtual User Maintainer { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("Collection")]
|
||||||
|
public virtual ICollection<CollectionRelease> Releases { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("Collection")]
|
||||||
|
public virtual ICollection<CollectionMissing> MissingReleases { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,18 +6,30 @@ namespace Roadie.Library.Data
|
||||||
[Table("collectionMissing")]
|
[Table("collectionMissing")]
|
||||||
public class CollectionMissing
|
public class CollectionMissing
|
||||||
{
|
{
|
||||||
[Column("artist")] [MaxLength(1000)] public string Artist { get; set; }
|
[Column("artist")]
|
||||||
|
[MaxLength(1000)]
|
||||||
|
public string Artist { get; set; }
|
||||||
|
|
||||||
[Column("collectionId")] public int CollectionId { get; set; }
|
[Column("collectionId")]
|
||||||
|
public int CollectionId { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(CollectionId))]
|
||||||
|
[InverseProperty("MissingReleases")]
|
||||||
|
public virtual Collection Collection { get; set; }
|
||||||
|
|
||||||
[Column("id")]
|
[Column("id")]
|
||||||
[Key]
|
[Key]
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
[Column("isArtistFound")] public bool IsArtistFound { get; set; }
|
[Column("isArtistFound")]
|
||||||
|
public bool IsArtistFound { get; set; }
|
||||||
|
|
||||||
[Column("position")] public int Position { get; set; }
|
[Column("position")]
|
||||||
[Column("release")] [MaxLength(1000)] public string Release { get; set; }
|
public int Position { get; set; }
|
||||||
|
|
||||||
|
[Column("release")]
|
||||||
|
[MaxLength(1000)]
|
||||||
|
public string Release { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -98,7 +98,9 @@ namespace Roadie.Library.Data
|
||||||
public Collection()
|
public Collection()
|
||||||
{
|
{
|
||||||
Releases = new HashSet<CollectionRelease>();
|
Releases = new HashSet<CollectionRelease>();
|
||||||
|
MissingReleases = new HashSet<CollectionMissing>();
|
||||||
Comments = new HashSet<Comment>();
|
Comments = new HashSet<Comment>();
|
||||||
|
|
||||||
ListInCSVFormat = "Position,Release,Artist";
|
ListInCSVFormat = "Position,Release,Artist";
|
||||||
CollectionType = Enums.CollectionType.Rank;
|
CollectionType = Enums.CollectionType.Rank;
|
||||||
}
|
}
|
||||||
|
@ -128,19 +130,21 @@ namespace Roadie.Library.Data
|
||||||
};
|
};
|
||||||
configuration.BadDataFound = context =>
|
configuration.BadDataFound = context =>
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"PositionArtistReleases: Bad data found on row '{context.RawRow}'");
|
Trace.WriteLine($"PositionArtistReleases: Bad data found on row '{context.RawRow}'", "Warning");
|
||||||
};
|
};
|
||||||
var csv = new CsvReader(sr, configuration);
|
using (var csv = new CsvReader(sr, configuration))
|
||||||
while (csv.Read())
|
|
||||||
{
|
{
|
||||||
index++;
|
while (csv.Read())
|
||||||
rows.Add(new PositionArtistRelease
|
|
||||||
{
|
{
|
||||||
Index = index,
|
index++;
|
||||||
Position = csv.GetField<int>(PositionColumn),
|
rows.Add(new PositionArtistRelease
|
||||||
Artist = SafeParser.ToString(csv.GetField<string>(ArtistColumn)),
|
{
|
||||||
Release = SafeParser.ToString(csv.GetField<string>(ReleaseColumn))
|
Index = index,
|
||||||
});
|
Position = csv.GetField<int>(PositionColumn),
|
||||||
|
Artist = SafeParser.ToString(csv.GetField<string>(ArtistColumn)),
|
||||||
|
Release = SafeParser.ToString(csv.GetField<string>(ReleaseColumn))
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,30 +160,5 @@ namespace Roadie.Library.Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class PositionArtistRelease
|
|
||||||
{
|
|
||||||
public string Artist { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is the index (position in the list regardless of the position number)
|
|
||||||
/// </summary>
|
|
||||||
[JsonIgnore]
|
|
||||||
public int Index { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is the position number for the list (can be a year "1984" can be a number "14")
|
|
||||||
/// </summary>
|
|
||||||
public int Position { get; set; }
|
|
||||||
|
|
||||||
public string Release { get; set; }
|
|
||||||
[JsonIgnore] public Statuses Status { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("Status")] public string StatusVerbose => Status.ToString();
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return string.Format("Position [{0}], Artist [{1}], Release [{2}]", Position, Artist, Release);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -6,14 +6,23 @@ namespace Roadie.Library.Data
|
||||||
[Table("collectionrelease")]
|
[Table("collectionrelease")]
|
||||||
public class CollectionRelease : EntityBase
|
public class CollectionRelease : EntityBase
|
||||||
{
|
{
|
||||||
public Collection Collection { get; set; }
|
[ForeignKey(nameof(CollectionId))]
|
||||||
|
[InverseProperty("Releases")]
|
||||||
|
public virtual Collection Collection { get; set; }
|
||||||
|
|
||||||
[Column("collectionId")] [Required] public int CollectionId { get; set; }
|
[Column("collectionId")]
|
||||||
|
[Required]
|
||||||
|
public int CollectionId { get; set; }
|
||||||
|
|
||||||
[Column("listNumber")] public int ListNumber { get; set; }
|
[Column("listNumber")]
|
||||||
|
public int ListNumber { get; set; }
|
||||||
|
|
||||||
public Release Release { get; set; }
|
[ForeignKey(nameof(ReleaseId))]
|
||||||
|
[InverseProperty("Collections")]
|
||||||
|
public virtual Release Release { get; set; }
|
||||||
|
|
||||||
[Column("releaseId")] [Required] public int ReleaseId { get; set; }
|
[Column("releaseId")]
|
||||||
|
[Required]
|
||||||
|
public int ReleaseId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,34 +9,76 @@ namespace Roadie.Library.Data
|
||||||
[Table("comment")]
|
[Table("comment")]
|
||||||
public partial class Comment : EntityBase
|
public partial class Comment : EntityBase
|
||||||
{
|
{
|
||||||
[Column("artistId")] public int? ArtistId { get; set; }
|
[Column("artistId")]
|
||||||
|
public int? ArtistId { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(ArtistId))]
|
||||||
|
[InverseProperty("Comments")]
|
||||||
|
public virtual Artist Artist { get; set; }
|
||||||
|
|
||||||
[Column("comment")]
|
[Column("comment")]
|
||||||
[MaxLength(25500)]
|
[MaxLength(25500)]
|
||||||
[Required]
|
[Required]
|
||||||
public string Cmt { get; set; }
|
public string Cmt { get; set; }
|
||||||
|
|
||||||
[Column("collectionId")] public int? CollectionId { get; set; }
|
[Column("collectionId")]
|
||||||
|
public int? CollectionId { get; set; }
|
||||||
|
|
||||||
[Column("genreId")] public int? GenreId { get; set; }
|
[ForeignKey(nameof(CollectionId))]
|
||||||
|
[InverseProperty("Comments")]
|
||||||
|
public virtual Collection Collection { get; set; }
|
||||||
|
|
||||||
[NotMapped] public new bool? IsLocked { get; set; }
|
[Column("genreId")]
|
||||||
|
public int? GenreId { get; set; }
|
||||||
|
|
||||||
[Column("labelId")] public int? LabelId { get; set; }
|
[ForeignKey(nameof(GenreId))]
|
||||||
|
[InverseProperty("Comments")]
|
||||||
|
public virtual Genre Genre { get; set; }
|
||||||
|
|
||||||
[Column("playlistId")] public int? PlaylistId { get; set; }
|
[NotMapped]
|
||||||
|
public new bool? IsLocked { get; set; }
|
||||||
|
|
||||||
public ICollection<CommentReaction> Reactions { get; set; }
|
[Column("labelId")]
|
||||||
|
public int? LabelId { get; set; }
|
||||||
|
|
||||||
[Column("releaseId")] public int? ReleaseId { get; set; }
|
[ForeignKey(nameof(LabelId))]
|
||||||
|
[InverseProperty("Comments")]
|
||||||
|
public virtual Label Label { get; set; }
|
||||||
|
|
||||||
[Column("replyToCommentId")] public int? ReplyToCommentId { get; set; }
|
[Column("playlistId")]
|
||||||
|
public int? PlaylistId { get; set; }
|
||||||
|
|
||||||
[Column("trackId")] public int? TrackId { get; set; }
|
[ForeignKey(nameof(PlaylistId))]
|
||||||
|
[InverseProperty("Comments")]
|
||||||
|
public virtual Playlist Playlist { get; set; }
|
||||||
|
|
||||||
public ApplicationUser User { get; set; }
|
[InverseProperty("Comment")]
|
||||||
|
public virtual ICollection<CommentReaction> Reactions { get; set; }
|
||||||
|
|
||||||
[Column("userId")] [Required] public int UserId { get; set; }
|
[Column("releaseId")]
|
||||||
|
public int? ReleaseId { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(ReleaseId))]
|
||||||
|
[InverseProperty("Comments")]
|
||||||
|
public virtual Release Release { get; set; }
|
||||||
|
|
||||||
|
[Column("replyToCommentId")]
|
||||||
|
public int? ReplyToCommentId { get; set; }
|
||||||
|
|
||||||
|
[Column("trackId")]
|
||||||
|
public int? TrackId { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(TrackId))]
|
||||||
|
[InverseProperty("Comments")]
|
||||||
|
public virtual Track Track { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(UserId))]
|
||||||
|
[InverseProperty("Comments")]
|
||||||
|
public virtual User User { get; set; }
|
||||||
|
|
||||||
|
[Column("userId")]
|
||||||
|
[Required]
|
||||||
|
public int UserId { get; set; }
|
||||||
|
|
||||||
public Comment()
|
public Comment()
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,14 +10,25 @@ namespace Roadie.Library.Data
|
||||||
{
|
{
|
||||||
public Comment Comment { get; set; }
|
public Comment Comment { get; set; }
|
||||||
|
|
||||||
[Column("commentId")] [Required] public int CommentId { get; set; }
|
[Column("commentId")]
|
||||||
[NotMapped] public new bool? IsLocked { get; set; }
|
[Required]
|
||||||
[Column("reaction")] public string Reaction { get; set; }
|
public int CommentId { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public new bool? IsLocked { get; set; }
|
||||||
|
|
||||||
|
[Column("reaction")]
|
||||||
|
public string Reaction { get; set; }
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public Enums.CommentReaction ReactionValue => SafeParser.ToEnum<Enums.CommentReaction>(Reaction ?? "Unknown");
|
public Enums.CommentReaction ReactionValue => SafeParser.ToEnum<Enums.CommentReaction>(Reaction ?? "Unknown");
|
||||||
|
|
||||||
public ApplicationUser User { get; set; }
|
[ForeignKey(nameof(UserId))]
|
||||||
[Column("userId")] [Required] public int UserId { get; set; }
|
[InverseProperty("CommentReactions")]
|
||||||
|
public virtual User User { get; set; }
|
||||||
|
|
||||||
|
[Column("userId")]
|
||||||
|
[Required]
|
||||||
|
public int UserId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
using FileContextCore;
|
using FileContextCore;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Pomelo.EntityFrameworkCore.MySql.Infrastructure;
|
|
||||||
using Roadie.Library.Configuration;
|
using Roadie.Library.Configuration;
|
||||||
using Roadie.Library.Data.Context.Implementation;
|
using Roadie.Library.Data.Context.Implementation;
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace Roadie.Library.Data.Context
|
namespace Roadie.Library.Data.Context
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,12 @@ namespace Roadie.Library.Data.Context
|
||||||
{
|
{
|
||||||
switch (configuration.DbContextToUse)
|
switch (configuration.DbContextToUse)
|
||||||
{
|
{
|
||||||
|
case DbContexts.SQLite:
|
||||||
|
var sqlLiteOptionsBuilder = new DbContextOptionsBuilder<SQLiteRoadieDbContext>();
|
||||||
|
var databaseName = Path.Combine(configuration.FileDatabaseOptions.DatabaseFolder, $"{ configuration.FileDatabaseOptions.DatabaseName }.db");
|
||||||
|
sqlLiteOptionsBuilder.UseSqlite($"Filename={databaseName}");
|
||||||
|
return new SQLiteRoadieDbContext(sqlLiteOptionsBuilder.Options);
|
||||||
|
|
||||||
case DbContexts.File:
|
case DbContexts.File:
|
||||||
var fileOptionsBuilder = new DbContextOptionsBuilder<MySQLRoadieDbContext>();
|
var fileOptionsBuilder = new DbContextOptionsBuilder<MySQLRoadieDbContext>();
|
||||||
fileOptionsBuilder.UseFileContextDatabase(configuration.FileDatabaseOptions.DatabaseFormat.ToString().ToLower(),
|
fileOptionsBuilder.UseFileContextDatabase(configuration.FileDatabaseOptions.DatabaseFormat.ToString().ToLower(),
|
||||||
|
@ -20,17 +26,19 @@ namespace Roadie.Library.Data.Context
|
||||||
location: configuration.FileDatabaseOptions.DatabaseFolder);
|
location: configuration.FileDatabaseOptions.DatabaseFolder);
|
||||||
return new FileRoadieDbContext(fileOptionsBuilder.Options);
|
return new FileRoadieDbContext(fileOptionsBuilder.Options);
|
||||||
|
|
||||||
default:
|
case DbContexts.MySQL:
|
||||||
var mysqlOptionsBuilder = new DbContextOptionsBuilder<MySQLRoadieDbContext>();
|
var mysqlOptionsBuilder = new DbContextOptionsBuilder<MySQLRoadieDbContext>();
|
||||||
mysqlOptionsBuilder.UseMySql(configuration.ConnectionString, mySqlOptions =>
|
mysqlOptionsBuilder.UseMySql(configuration.ConnectionString, mySqlOptions =>
|
||||||
{
|
{
|
||||||
mySqlOptions.ServerVersion(new Version(5, 5), ServerType.MariaDb);
|
|
||||||
mySqlOptions.EnableRetryOnFailure(
|
mySqlOptions.EnableRetryOnFailure(
|
||||||
10,
|
10,
|
||||||
TimeSpan.FromSeconds(30),
|
TimeSpan.FromSeconds(30),
|
||||||
null);
|
null);
|
||||||
});
|
});
|
||||||
return new MySQLRoadieDbContext(mysqlOptionsBuilder.Options);
|
return new MySQLRoadieDbContext(mysqlOptionsBuilder.Options);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException("Unknown DbContext Type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,8 @@ namespace Roadie.Library.Data.Context
|
||||||
DbSet<UserArtist> UserArtists { get; set; }
|
DbSet<UserArtist> UserArtists { get; set; }
|
||||||
DbSet<UserQue> UserQues { get; set; }
|
DbSet<UserQue> UserQues { get; set; }
|
||||||
DbSet<UserRelease> UserReleases { get; set; }
|
DbSet<UserRelease> UserReleases { get; set; }
|
||||||
DbSet<ApplicationRole> UserRoles { get; set; }
|
DbSet<UserRole> UserRoles { get; set; }
|
||||||
DbSet<ApplicationUser> Users { get; set; }
|
DbSet<User> Users { get; set; }
|
||||||
DbSet<UserTrack> UserTracks { get; set; }
|
DbSet<UserTrack> UserTracks { get; set; }
|
||||||
|
|
||||||
DbSet<InviteToken> InviteTokens { get; set; }
|
DbSet<InviteToken> InviteTokens { get; set; }
|
||||||
|
|
|
@ -169,11 +169,11 @@ namespace Roadie.Library.Data.Context.Implementation
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
randomReleases = await(from r in Releases
|
randomReleases = await (from r in Releases
|
||||||
join ur in UserReleases on r.Id equals ur.ReleaseId into urg
|
join ur in UserReleases on r.Id equals ur.ReleaseId into urg
|
||||||
from ur in urg.DefaultIfEmpty()
|
from ur in urg.DefaultIfEmpty()
|
||||||
where (ur == null || (ur.UserId == userId && ur.IsDisliked == false))
|
where (ur == null || (ur.UserId == userId && ur.IsDisliked == false))
|
||||||
select r)
|
select r)
|
||||||
.OrderBy(x => Guid.NewGuid())
|
.OrderBy(x => Guid.NewGuid())
|
||||||
.Take(randomLimit)
|
.Take(randomLimit)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
|
@ -188,7 +188,7 @@ namespace Roadie.Library.Data.Context.Implementation
|
||||||
WHERE ut.userId = {1} AND ut.isFavorite = 1) AND {2} = 1) OR {2} = 0)
|
WHERE ut.userId = {1} AND ut.isFavorite = 1) AND {2} = 1) OR {2} = 0)
|
||||||
order BY RIGHT( HEX( (1<<24) * (1+RAND()) ), 6)
|
order BY RIGHT( HEX( (1<<24) * (1+RAND()) ), 6)
|
||||||
LIMIT 0, {0}";
|
LIMIT 0, {0}";
|
||||||
var ids = await Releases.FromSqlRaw(sql, randomLimit, userId, doOnlyFavorites ? "1" : "0", doOnlyRated ? "1" : "0").Select(x => x.Id).ToListAsync();
|
var ids = await Tracks.FromSqlRaw(sql, randomLimit, userId, doOnlyFavorites ? "1" : "0", doOnlyRated ? "1" : "0").Select(x => x.Id).ToListAsync();
|
||||||
var dict = ids.Select((id, i) => new { key = i, value = id }).ToDictionary(x => x.key, x => x.value);
|
var dict = ids.Select((id, i) => new { key = i, value = id }).ToDictionary(x => x.key, x => x.value);
|
||||||
return new SortedDictionary<int, int>(dict);
|
return new SortedDictionary<int, int>(dict);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Roadie.Library.Data.Context.Implementation
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// SQLite implementation of DbContext
|
||||||
|
/// </summary>
|
||||||
|
public sealed class SQLiteRoadieDbContext : LinqDbContextBase
|
||||||
|
{
|
||||||
|
private static bool _created = false;
|
||||||
|
|
||||||
|
public SQLiteRoadieDbContext(DbContextOptions options)
|
||||||
|
: base(options)
|
||||||
|
{
|
||||||
|
if (!_created)
|
||||||
|
{
|
||||||
|
_created = true;
|
||||||
|
Database.EnsureCreated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<SortedDictionary<int, int>> RandomArtistIds(int userId, int randomLimit, bool doOnlyFavorites = false, bool doOnlyRated = false)
|
||||||
|
{
|
||||||
|
// TODO Rating?
|
||||||
|
var sql = @"SELECT a.id
|
||||||
|
FROM artist a
|
||||||
|
WHERE(a.id NOT IN(select artistId FROM userartist where userId = {1} and isDisliked = 1))
|
||||||
|
OR(a.id IN (select artistId FROM userartist where userId = {1} and isFavorite = 1)
|
||||||
|
AND {2} = 1)
|
||||||
|
order by random()
|
||||||
|
LIMIT 0, {0}";
|
||||||
|
var ids = await Artists.FromSqlRaw(sql, randomLimit, userId, doOnlyFavorites ? "1" : "0").Select(x => x.Id).ToListAsync();
|
||||||
|
var dict = ids.Select((id, i) => new { key = i, value = id }).ToDictionary(x => x.key, x => x.value);
|
||||||
|
return new SortedDictionary<int, int>(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<SortedDictionary<int, int>> RandomGenreIds(int userId, int randomLimit, bool doOnlyFavorites = false, bool doOnlyRated = false)
|
||||||
|
{
|
||||||
|
var sql = @"SELECT g.id
|
||||||
|
FROM genre g
|
||||||
|
order by random()
|
||||||
|
LIMIT 0, {0}";
|
||||||
|
var ids = await Genres.FromSqlRaw(sql, randomLimit).Select(x => x.Id).ToListAsync();
|
||||||
|
var dict = ids.Select((id, i) => new { key = i, value = id }).ToDictionary(x => x.key, x => x.value);
|
||||||
|
return new SortedDictionary<int, int>(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<SortedDictionary<int, int>> RandomLabelIds(int userId, int randomLimit, bool doOnlyFavorites = false, bool doOnlyRated = false)
|
||||||
|
{
|
||||||
|
var sql = @"SELECT l.id
|
||||||
|
FROM label l
|
||||||
|
order by random()
|
||||||
|
LIMIT 0, {0}";
|
||||||
|
var ids = await Labels.FromSqlRaw(sql, randomLimit).Select(x => x.Id).ToListAsync();
|
||||||
|
var dict = ids.Select((id, i) => new { key = i, value = id }).ToDictionary(x => x.key, x => x.value);
|
||||||
|
return new SortedDictionary<int, int>(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<SortedDictionary<int, int>> RandomReleaseIds(int userId, int randomLimit, bool doOnlyFavorites = false, bool doOnlyRated = false)
|
||||||
|
{
|
||||||
|
// TODO Rating?
|
||||||
|
var sql = @"SELECT r.id
|
||||||
|
FROM release r
|
||||||
|
WHERE (r.id NOT IN (select releaseId FROM userrelease where userId = {1} and isDisliked = 1))
|
||||||
|
OR (r.id IN (select releaseId FROM userrelease where userId = {1} and isFavorite = 1)
|
||||||
|
AND {2} = 1)
|
||||||
|
order by random()
|
||||||
|
LIMIT 0, {0}";
|
||||||
|
var ids = await Releases.FromSqlRaw(sql, randomLimit, userId, doOnlyFavorites ? "1" : "0").Select(x => x.Id).ToListAsync();
|
||||||
|
var dict = ids.Select((id, i) => new { key = i, value = id }).ToDictionary(x => x.key, x => x.value);
|
||||||
|
return new SortedDictionary<int, int>(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<SortedDictionary<int, int>> RandomTrackIds(int userId, int randomLimit, bool doOnlyFavorites = false, bool doOnlyRated = false)
|
||||||
|
{
|
||||||
|
// When using the regular 'FromSqlRaw' with parameters SQLite returns no records.
|
||||||
|
|
||||||
|
var df = doOnlyFavorites ? "1" : "0";
|
||||||
|
var dr = doOnlyRated ? "1" : "0";
|
||||||
|
var sql = @$"SELECT t.id
|
||||||
|
FROM track t
|
||||||
|
WHERE ((t.rating > 0 AND {dr} = 1) OR {dr} = 0)
|
||||||
|
AND ((t.id NOT IN (select tt.id
|
||||||
|
FROM track tt
|
||||||
|
JOIN releasemedia rm on (tt.releaseMediaId = rm.id)
|
||||||
|
JOIN userartist ua on (rm.id = ua.artistId)
|
||||||
|
WHERE ua.userId = {userId} AND ua.isDisliked = 1))
|
||||||
|
AND (t.id NOT IN (select tt.id
|
||||||
|
FROM track tt
|
||||||
|
JOIN releasemedia rm on (tt.releaseMediaId = rm.id)
|
||||||
|
JOIN userrelease ur on (rm.releaseId = ur.releaseId)
|
||||||
|
WHERE ur.userId = {userId} AND ur.isDisliked = 1))
|
||||||
|
AND (t.id NOT IN (select tt.id
|
||||||
|
FROM track tt
|
||||||
|
JOIN usertrack ut on (tt.id = ut.trackId)
|
||||||
|
WHERE ut.userId = {userId} AND ut.isDisliked = 1)))
|
||||||
|
AND ((t.id IN (select tt.id
|
||||||
|
FROM track tt
|
||||||
|
JOIN usertrack ut on (tt.id = ut.trackId)
|
||||||
|
WHERE ut.userId = {userId} AND ut.isFavorite = 1) AND {df} = 1) OR {df} = 0)
|
||||||
|
order by random()
|
||||||
|
LIMIT 0, {randomLimit}";
|
||||||
|
var ids = await Tracks.FromSqlRaw(sql, randomLimit).Select(x => x.Id).ToListAsync();
|
||||||
|
var dict = ids.Select((id, i) => new { key = i, value = id }).ToDictionary(x => x.key, x => x.value);
|
||||||
|
return new SortedDictionary<int, int>(dict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -65,9 +65,9 @@ namespace Roadie.Library.Data.Context
|
||||||
|
|
||||||
public DbSet<UserRelease> UserReleases { get; set; }
|
public DbSet<UserRelease> UserReleases { get; set; }
|
||||||
|
|
||||||
public DbSet<ApplicationRole> UserRoles { get; set; }
|
public DbSet<UserRole> UserRoles { get; set; }
|
||||||
|
|
||||||
public DbSet<ApplicationUser> Users { get; set; }
|
public DbSet<User> Users { get; set; }
|
||||||
|
|
||||||
public DbSet<UserTrack> UserTracks { get; set; }
|
public DbSet<UserTrack> UserTracks { get; set; }
|
||||||
public DbSet<InviteToken> InviteTokens { get; set; }
|
public DbSet<InviteToken> InviteTokens { get; set; }
|
||||||
|
@ -79,142 +79,737 @@ namespace Roadie.Library.Data.Context
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder builder)
|
protected override void OnModelCreating(ModelBuilder builder)
|
||||||
{
|
{
|
||||||
base.OnModelCreating(builder);
|
// base.OnModelCreating(builder);
|
||||||
|
|
||||||
//builder
|
builder.Entity<Artist>(entity =>
|
||||||
// .Entity<ScanHistory>()
|
{
|
||||||
// .Property(e => e.Status)
|
entity
|
||||||
// .HasConversion(
|
.Property(e => e.BandStatus)
|
||||||
// v => v.ToString(),
|
.HasConversion(
|
||||||
// v => string.IsNullOrEmpty(v) ? Statuses.Ok : (Statuses)Enum.Parse(typeof(Statuses), v))
|
v => v.ToString(),
|
||||||
// .HasDefaultValue(Statuses.Ok);
|
v => string.IsNullOrEmpty(v) ? BandStatus.Unknown : (BandStatus)Enum.Parse(typeof(BandStatus), v))
|
||||||
|
.HasDefaultValue(BandStatus.Unknown);
|
||||||
|
|
||||||
//builder
|
entity.HasIndex(e => e.Name)
|
||||||
// .Entity<Artist>()
|
.HasName("ix_artist_name")
|
||||||
// .Property(e => e.Status)
|
.IsUnique();
|
||||||
// .HasConversion(
|
|
||||||
// v => v.ToString(),
|
|
||||||
// v => string.IsNullOrEmpty(v) ? Statuses.Incomplete : (Statuses)Enum.Parse(typeof(Statuses), v))
|
|
||||||
// .HasDefaultValue(Statuses.Incomplete);
|
|
||||||
|
|
||||||
builder
|
entity.HasIndex(e => e.RoadieId)
|
||||||
.Entity<Release>()
|
.HasName("ix_artist_roadieId");
|
||||||
.Property(e => e.ReleaseType)
|
|
||||||
.HasConversion(
|
|
||||||
v => v.ToString(),
|
|
||||||
v => string.IsNullOrEmpty(v)
|
|
||||||
? ReleaseType.Unknown
|
|
||||||
: (ReleaseType)Enum.Parse(typeof(ReleaseType), v))
|
|
||||||
.HasDefaultValue(ReleaseType.Release);
|
|
||||||
|
|
||||||
builder
|
entity.HasIndex(e => e.SortName)
|
||||||
.Entity<Release>()
|
.HasName("ix_artist_sortname")
|
||||||
.Property(e => e.LibraryStatus)
|
.IsUnique();
|
||||||
.HasConversion(
|
});
|
||||||
v => v.ToString(),
|
|
||||||
v => string.IsNullOrEmpty(v)
|
|
||||||
? LibraryStatus.Incomplete
|
|
||||||
: (LibraryStatus)Enum.Parse(typeof(LibraryStatus), v))
|
|
||||||
.HasDefaultValue(LibraryStatus.Incomplete);
|
|
||||||
|
|
||||||
builder
|
builder.Entity<ArtistAssociation>(entity =>
|
||||||
.Entity<Collection>()
|
{
|
||||||
.Property(e => e.CollectionType)
|
entity.HasIndex(e => e.AssociatedArtistId)
|
||||||
.HasConversion(
|
.HasName("ix_associatedArtistId");
|
||||||
v => v.ToString(),
|
|
||||||
v => string.IsNullOrEmpty(v)
|
|
||||||
? CollectionType.Unknown
|
|
||||||
: (CollectionType)Enum.Parse(typeof(CollectionType), v))
|
|
||||||
.HasDefaultValue(CollectionType.Unknown);
|
|
||||||
|
|
||||||
builder
|
entity.HasIndex(e => new { e.ArtistId, e.AssociatedArtistId })
|
||||||
.Entity<Artist>()
|
.HasName("ix__artistAssociation");
|
||||||
.Property(e => e.BandStatus)
|
|
||||||
.HasConversion(
|
|
||||||
v => v.ToString(),
|
|
||||||
v => string.IsNullOrEmpty(v) ? BandStatus.Unknown : (BandStatus)Enum.Parse(typeof(BandStatus), v))
|
|
||||||
.HasDefaultValue(BandStatus.Unknown);
|
|
||||||
|
|
||||||
//builder
|
entity.HasOne(d => d.Artist)
|
||||||
// .Entity<Bookmark>()
|
.WithMany(p => p.AssociatedArtists)
|
||||||
// .Property(e => e.BookmarkType)
|
.HasForeignKey(d => d.ArtistId)
|
||||||
// .HasConversion(
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
// v => v.ToString(),
|
.HasConstraintName("artistAssociation_ibfk_1");
|
||||||
// v => string.IsNullOrEmpty(v) ? BookmarkType.Unknown : (BookmarkType)Enum.Parse(typeof(BookmarkType), v))
|
});
|
||||||
// .HasDefaultValue(BookmarkType.Unknown);
|
|
||||||
|
|
||||||
builder.Entity<Release>()
|
builder.Entity<ArtistGenre>(entity =>
|
||||||
.HasOne(d => d.Artist)
|
{
|
||||||
.WithMany(p => p.Releases)
|
entity.HasIndex(e => e.ArtistId)
|
||||||
.HasForeignKey(d => d.ArtistId)
|
.HasName("ix_artistGenreTable_artistId");
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.HasConstraintName("release_ibfk_1");
|
|
||||||
|
|
||||||
builder.Entity<ReleaseLabel>()
|
entity.HasIndex(e => e.GenreId)
|
||||||
.HasOne(rl => rl.Release)
|
.HasName("ix_artistGenre_genreId");
|
||||||
.WithMany(r => r.Labels)
|
|
||||||
.HasForeignKey(rl => rl.ReleaseId);
|
|
||||||
|
|
||||||
builder.Entity<ReleaseLabel>()
|
entity.HasIndex(e => new { e.ArtistId, e.GenreId })
|
||||||
.HasOne(rl => rl.Label)
|
.HasName("ix__artistGenreAssociation");
|
||||||
.WithMany(l => l.ReleaseLabels)
|
|
||||||
.HasForeignKey(rl => rl.LabelId);
|
|
||||||
|
|
||||||
builder.Entity<ReleaseMedia>()
|
entity.HasOne(d => d.Artist)
|
||||||
.HasMany(rm => rm.Tracks)
|
.WithMany(p => p.Genres)
|
||||||
.WithOne(t => t.ReleaseMedia)
|
.HasForeignKey(d => d.ArtistId)
|
||||||
.HasForeignKey(rm => rm.ReleaseMediaId);
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("artistGenreTable_ibfk_1");
|
||||||
|
|
||||||
builder.Entity<ReleaseMedia>()
|
entity.HasOne(d => d.Genre)
|
||||||
.HasOne(rm => rm.Release)
|
.WithMany(p => p.Artists)
|
||||||
.WithMany(r => r.Medias)
|
.HasForeignKey(d => d.GenreId)
|
||||||
.HasForeignKey(r => r.ReleaseId);
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("artistGenreTable_ibfk_2");
|
||||||
|
});
|
||||||
|
|
||||||
builder.Entity<ReleaseGenre>()
|
builder.Entity<ArtistSimilar>(entity =>
|
||||||
.HasKey(rg => new { rg.ReleaseId, rg.GenreId });
|
{
|
||||||
|
entity.HasIndex(e => e.SimilarArtistId)
|
||||||
|
.HasName("ix_similarArtistId");
|
||||||
|
|
||||||
builder.Entity<ReleaseGenre>()
|
entity.HasIndex(e => new { e.ArtistId, e.SimilarArtistId })
|
||||||
.HasOne(rg => rg.Release)
|
.HasName("ix_artistSimilar");
|
||||||
.WithMany(r => r.Genres)
|
|
||||||
.HasForeignKey(rg => rg.ReleaseId);
|
|
||||||
|
|
||||||
builder.Entity<ReleaseGenre>()
|
entity.HasOne(d => d.Artist)
|
||||||
.HasOne(rg => rg.Genre)
|
.WithMany(p => p.SimilarArtists)
|
||||||
.WithMany(g => g.Releases)
|
.HasForeignKey(d => d.ArtistId)
|
||||||
.HasForeignKey(rg => rg.GenreId);
|
.HasConstraintName("artistSimilar_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
builder.Entity<ArtistGenre>()
|
builder.Entity<Bookmark>(entity =>
|
||||||
.HasKey(rg => new { rg.ArtistId, rg.GenreId });
|
{
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_bookmark_roadieId");
|
||||||
|
|
||||||
builder.Entity<ArtistGenre>()
|
entity.HasIndex(e => e.UserId)
|
||||||
.HasOne(rg => rg.Artist)
|
.HasName("ix_bookmark_userId");
|
||||||
.WithMany(r => r.Genres)
|
|
||||||
.HasForeignKey(rg => rg.ArtistId);
|
|
||||||
|
|
||||||
builder.Entity<ArtistGenre>()
|
entity.HasIndex(e => new { e.BookmarkType, e.BookmarkTargetId, e.UserId })
|
||||||
.HasOne(rg => rg.Genre)
|
.HasName("ix_bookmark_bookmarkType")
|
||||||
.WithMany(g => g.Artists)
|
.IsUnique();
|
||||||
.HasForeignKey(rg => rg.GenreId);
|
|
||||||
|
|
||||||
builder.Entity<CollectionRelease>()
|
entity.HasOne(d => d.User)
|
||||||
.HasOne(cr => cr.Release)
|
.WithMany(p => p.Bookmarks)
|
||||||
.WithMany(r => r.Collections)
|
.HasForeignKey(d => d.UserId)
|
||||||
.HasForeignKey(cr => cr.ReleaseId);
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("bookmark_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
builder.Entity<CollectionRelease>()
|
builder.Entity<ChatMessage>(entity =>
|
||||||
.HasOne(cr => cr.Collection)
|
{
|
||||||
.WithMany(c => c.Releases)
|
entity.HasIndex(e => e.UserId)
|
||||||
.HasForeignKey(cr => cr.CollectionId);
|
.HasName("ix__chatMessage_user");
|
||||||
|
|
||||||
builder.Entity<Bookmark>()
|
entity.HasOne(d => d.User)
|
||||||
.HasOne(b => b.User)
|
.WithMany(p => p.ChatMessages)
|
||||||
.WithMany(u => u.Bookmarks)
|
.HasForeignKey(d => d.UserId)
|
||||||
.HasForeignKey(b => b.UserId);
|
.HasConstraintName("chatMessage_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
//builder.Entity<Track>()
|
builder.Entity<Collection>(entity =>
|
||||||
// .HasOne(t => t.TrackArtist)
|
{
|
||||||
// .WithMany(a => a.Tracks)
|
entity
|
||||||
// .HasForeignKey(t => t.ArtistId);
|
.Property(e => e.CollectionType)
|
||||||
|
.HasConversion(
|
||||||
|
v => v.ToString(),
|
||||||
|
v => string.IsNullOrEmpty(v)
|
||||||
|
? CollectionType.Unknown
|
||||||
|
: (CollectionType)Enum.Parse(typeof(CollectionType), v))
|
||||||
|
.HasDefaultValue(CollectionType.Unknown);
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.MaintainerId)
|
||||||
|
.HasName("ix_collection_maintainerId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.Name)
|
||||||
|
.HasName("ix_collection_name")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_collection_roadieId");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Maintainer)
|
||||||
|
.WithMany(p => p.Collections)
|
||||||
|
.HasForeignKey(d => d.MaintainerId)
|
||||||
|
.OnDelete(DeleteBehavior.SetNull)
|
||||||
|
.HasConstraintName("collection_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<CollectionMissing>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.CollectionId)
|
||||||
|
.HasName("ix_collection_collectionId");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Collection)
|
||||||
|
.WithMany(p => p.MissingReleases)
|
||||||
|
.HasForeignKey(d => d.CollectionId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("collection_missing_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<CollectionRelease>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.ReleaseId)
|
||||||
|
.HasName("ix_collectionrelease_releaseId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_collectionrelease_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => new { e.CollectionId, e.ReleaseId })
|
||||||
|
.HasName("ix__collection_release");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Collection)
|
||||||
|
.WithMany(p => p.Releases)
|
||||||
|
.HasForeignKey(d => d.CollectionId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("collectionrelease_ibfk_2");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Release)
|
||||||
|
.WithMany(p => p.Collections)
|
||||||
|
.HasForeignKey(d => d.ReleaseId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("collectionrelease_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<Comment>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.ArtistId)
|
||||||
|
.HasName("ix_commentartist_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.CollectionId)
|
||||||
|
.HasName("ix_commentcollection_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.GenreId)
|
||||||
|
.HasName("ix_commentgenre_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.LabelId)
|
||||||
|
.HasName("ix_commentlabel_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.PlaylistId)
|
||||||
|
.HasName("ix_commentplaylist_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.ReleaseId)
|
||||||
|
.HasName("ix_commentrelease_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_comment_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.TrackId)
|
||||||
|
.HasName("ix_commenttrack_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.UserId)
|
||||||
|
.HasName("ix_commentuser_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Artist)
|
||||||
|
.WithMany(p => p.Comments)
|
||||||
|
.HasForeignKey(d => d.ArtistId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("commentartist_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Collection)
|
||||||
|
.WithMany(p => p.Comments)
|
||||||
|
.HasForeignKey(d => d.CollectionId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("commentcollection_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Genre)
|
||||||
|
.WithMany(p => p.Comments)
|
||||||
|
.HasForeignKey(d => d.GenreId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("commentgenre_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Label)
|
||||||
|
.WithMany(p => p.Comments)
|
||||||
|
.HasForeignKey(d => d.LabelId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("commentlabel_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Playlist)
|
||||||
|
.WithMany(p => p.Comments)
|
||||||
|
.HasForeignKey(d => d.PlaylistId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("commentplaylist_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Release)
|
||||||
|
.WithMany(p => p.Comments)
|
||||||
|
.HasForeignKey(d => d.ReleaseId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("commentrelease_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Track)
|
||||||
|
.WithMany(p => p.Comments)
|
||||||
|
.HasForeignKey(d => d.TrackId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("commenttrack_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.User)
|
||||||
|
.WithMany(p => p.Comments)
|
||||||
|
.HasForeignKey(d => d.UserId)
|
||||||
|
.HasConstraintName("commentuser_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<CommentReaction>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.CommentId)
|
||||||
|
.HasName("ix_commentReactioncomment_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_commentReaction_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.UserId)
|
||||||
|
.HasName("ix_commentReactionuser_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasIndex(e => new { e.UserId, e.CommentId })
|
||||||
|
.HasName("ix_commentReaction_userId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Comment)
|
||||||
|
.WithMany(p => p.Reactions)
|
||||||
|
.HasForeignKey(d => d.CommentId)
|
||||||
|
.HasConstraintName("commentReactioncomment_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.User)
|
||||||
|
.WithMany(p => p.CommentReactions)
|
||||||
|
.HasForeignKey(d => d.UserId)
|
||||||
|
.HasConstraintName("commentReactionuser_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<Credit>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.ArtistId)
|
||||||
|
.HasName("ix_credit_artist_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.CreditCategoryId)
|
||||||
|
.HasName("ix_credit_category_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_credit_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => new { e.ReleaseId, e.Id })
|
||||||
|
.HasName("ix_creditCreditandRelease");
|
||||||
|
|
||||||
|
entity.HasIndex(e => new { e.TrackId, e.Id })
|
||||||
|
.HasName("ix_creditCreditandTrack");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Artist)
|
||||||
|
.WithMany(p => p.Credits)
|
||||||
|
.HasForeignKey(d => d.ArtistId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("credit_artist_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.CreditCategory)
|
||||||
|
.WithMany(p => p.Credits)
|
||||||
|
.HasForeignKey(d => d.CreditCategoryId)
|
||||||
|
.HasConstraintName("credit_category_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Release)
|
||||||
|
.WithMany(p => p.Credits)
|
||||||
|
.HasForeignKey(d => d.ReleaseId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("credit_release_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Track)
|
||||||
|
.WithMany(p => p.Credits)
|
||||||
|
.HasForeignKey(d => d.TrackId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("credit_track_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<CreditCategory>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_creditCategory_roadieId");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<Genre>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.Name)
|
||||||
|
.HasName("ix_genre_name")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.NormalizedName)
|
||||||
|
.HasName("ix_genre_normalizedName");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_genre_roadieId");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<InviteToken>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.CreatedByUserId)
|
||||||
|
.HasName("inviteToken_fk_1");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_inviteToken_roadieId");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.CreatedByUser)
|
||||||
|
.WithMany(p => p.InviteTokens)
|
||||||
|
.HasForeignKey(d => d.CreatedByUserId)
|
||||||
|
.HasConstraintName("inviteToken_fk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<Label>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.Name)
|
||||||
|
.HasName("ix_label_name")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_label_roadieId");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<Playlist>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_playlist_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.UserId)
|
||||||
|
.HasName("ix_playlist_userId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => new { e.Name, e.UserId })
|
||||||
|
.HasName("ix_playlist_name")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
entity.HasOne(d => d.User)
|
||||||
|
.WithMany(p => p.Playlists)
|
||||||
|
.HasForeignKey(d => d.UserId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("playlist_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<PlaylistTrack>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.PlayListId)
|
||||||
|
.HasName("ix_playListId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_playlisttrack_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.TrackId)
|
||||||
|
.HasName("trackId");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Playlist)
|
||||||
|
.WithMany(p => p.Tracks)
|
||||||
|
.HasForeignKey(d => d.PlayListId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("playlisttrack_ibfk_2");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Track)
|
||||||
|
.WithMany(p => p.Playlists)
|
||||||
|
.HasForeignKey(d => d.TrackId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("playlisttrack_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<Release>(entity =>
|
||||||
|
{
|
||||||
|
entity
|
||||||
|
.Property(e => e.ReleaseType)
|
||||||
|
.HasConversion(
|
||||||
|
v => v.ToString(),
|
||||||
|
v => string.IsNullOrEmpty(v)
|
||||||
|
? ReleaseType.Unknown
|
||||||
|
: (ReleaseType)Enum.Parse(typeof(ReleaseType), v))
|
||||||
|
.HasDefaultValue(ReleaseType.Release);
|
||||||
|
|
||||||
|
entity
|
||||||
|
.Property(e => e.LibraryStatus)
|
||||||
|
.HasConversion(
|
||||||
|
v => v.ToString(),
|
||||||
|
v => string.IsNullOrEmpty(v)
|
||||||
|
? LibraryStatus.Incomplete
|
||||||
|
: (LibraryStatus)Enum.Parse(typeof(LibraryStatus), v))
|
||||||
|
.HasDefaultValue(LibraryStatus.Incomplete);
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_release_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.Title)
|
||||||
|
.HasName("ix_release_title");
|
||||||
|
|
||||||
|
entity.HasIndex(e => new { e.ArtistId, e.Title })
|
||||||
|
.HasName("ix_releaseArtistAndTitle")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Artist)
|
||||||
|
.WithMany(p => p.Releases)
|
||||||
|
.HasForeignKey(d => d.ArtistId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("release_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<ReleaseGenre>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.GenreId)
|
||||||
|
.HasName("ix_releaseGenre_genreId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => new { e.ReleaseId, e.GenreId })
|
||||||
|
.HasName("ix_releaseGenreTableReleaseAndGenre");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Genre)
|
||||||
|
.WithMany(p => p.Releases)
|
||||||
|
.HasForeignKey(d => d.GenreId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("releaseGenreTable_ibfk_2");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Release)
|
||||||
|
.WithMany(p => p.Genres)
|
||||||
|
.HasForeignKey(d => d.ReleaseId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("releaseGenreTable_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<ReleaseLabel>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.LabelId)
|
||||||
|
.HasName("ix_releaselabel_labelId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_releaselabel_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => new { e.ReleaseId, e.LabelId })
|
||||||
|
.HasName("ix_release_label");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Label)
|
||||||
|
.WithMany(p => p.ReleaseLabels)
|
||||||
|
.HasForeignKey(d => d.LabelId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("releaselabel_ibfk_2");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Release)
|
||||||
|
.WithMany(p => p.Labels)
|
||||||
|
.HasForeignKey(d => d.ReleaseId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("releaselabel_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<ReleaseMedia>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_releasemedia_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => new { e.ReleaseId, e.MediaNumber })
|
||||||
|
.HasName("ix_releasemedia_releaseId");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Release)
|
||||||
|
.WithMany(p => p.Medias)
|
||||||
|
.HasForeignKey(d => d.ReleaseId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("releasemedia_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<Request>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_request_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.UserId)
|
||||||
|
.HasName("ix_requestartist_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.User)
|
||||||
|
.WithMany(p => p.Requests)
|
||||||
|
.HasForeignKey(d => d.UserId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("requestartist_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<ScanHistory>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_scanHistory_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.UserId)
|
||||||
|
.HasName("ix_rscanHistoryt_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<Submission>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_submission_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.UserId)
|
||||||
|
.HasName("ix_submission_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.User)
|
||||||
|
.WithMany(p => p.Submissions)
|
||||||
|
.HasForeignKey(d => d.UserId)
|
||||||
|
.OnDelete(DeleteBehavior.SetNull)
|
||||||
|
.HasConstraintName("submission_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<Track>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.ArtistId)
|
||||||
|
.HasName("ix_track_artistId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.Hash)
|
||||||
|
.HasName("ix_track_hash")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.ReleaseMediaId)
|
||||||
|
.HasName("ix_track_releaseMediaId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_track_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.Title)
|
||||||
|
.HasName("ix_track_title");
|
||||||
|
|
||||||
|
entity.HasIndex(e => new { e.ReleaseMediaId, e.TrackNumber })
|
||||||
|
.HasName("ix_track_unique_to_eleasemedia")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
entity.HasOne(d => d.TrackArtist)
|
||||||
|
.WithMany(p => p.Tracks)
|
||||||
|
.HasForeignKey(d => d.ArtistId)
|
||||||
|
.OnDelete(DeleteBehavior.SetNull)
|
||||||
|
.HasConstraintName("track_artist_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.ReleaseMedia)
|
||||||
|
.WithMany(p => p.Tracks)
|
||||||
|
.HasForeignKey(d => d.ReleaseMediaId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("track_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<UserQue>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.TrackId)
|
||||||
|
.HasName("ix_userQue_ibfk_2");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.UserId)
|
||||||
|
.HasName("ix_user");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Track)
|
||||||
|
.WithMany(p => p.UserQues)
|
||||||
|
.HasForeignKey(d => d.TrackId)
|
||||||
|
.HasConstraintName("userQue_ibfk_2");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.User)
|
||||||
|
.WithMany(p => p.UserQues)
|
||||||
|
.HasForeignKey(d => d.UserId)
|
||||||
|
.HasConstraintName("userQue_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<UserArtist>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.ArtistId)
|
||||||
|
.HasName("ix_userartist_artistId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_userartist_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => new { e.UserId, e.ArtistId })
|
||||||
|
.HasName("ix_userartist_userId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Artist)
|
||||||
|
.WithMany(p => p.UserArtists)
|
||||||
|
.HasForeignKey(d => d.ArtistId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("userartist_ibfk_2");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.User)
|
||||||
|
.WithMany(p => p.ArtistRatings)
|
||||||
|
.HasForeignKey(d => d.UserId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("userartist_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<UserRelease>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.ReleaseId)
|
||||||
|
.HasName("ix_userrelease_releaseId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_userrelease_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => new { e.UserId, e.ReleaseId })
|
||||||
|
.HasName("ix_userrelease_userId_ix")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Release)
|
||||||
|
.WithMany(p => p.UserRelases)
|
||||||
|
.HasForeignKey(d => d.ReleaseId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("userrelease_ibfk_2");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.User)
|
||||||
|
.WithMany(p => p.UserReleases)
|
||||||
|
.HasForeignKey(d => d.UserId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("userrelease_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<UserTrack>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_usertrack_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.TrackId)
|
||||||
|
.HasName("ix_usertrack_trackId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => new { e.UserId, e.TrackId })
|
||||||
|
.HasName("ix_usertrack_userId_ix")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Track)
|
||||||
|
.WithMany(p => p.UserTracks)
|
||||||
|
.HasForeignKey(d => d.TrackId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("usertrack_ibfk_2");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.User)
|
||||||
|
.WithMany(p => p.UserTracks)
|
||||||
|
.HasForeignKey(d => d.UserId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("usertrack_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<User>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.Email)
|
||||||
|
.HasName("ix_user_email")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_user_roadieId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.UserName)
|
||||||
|
.HasName("ix_user_username")
|
||||||
|
.IsUnique();
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<UserClaims>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.UserId)
|
||||||
|
.HasName("ix_userClaims_userId");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.User)
|
||||||
|
.WithMany(p => p.UserClaims)
|
||||||
|
.HasForeignKey(d => d.UserId)
|
||||||
|
.HasConstraintName("userClaims_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<UserRoleClaims>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.RoleId)
|
||||||
|
.HasName("ix_userRoleClaims_userRoleId");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.UserRole)
|
||||||
|
.WithMany(p => p.RoleClaims)
|
||||||
|
.HasForeignKey(d => d.RoleId)
|
||||||
|
.HasConstraintName("userRoleClaims_ibfk_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<UserRole>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.Name)
|
||||||
|
.HasName("ix_userrole_name")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoadieId)
|
||||||
|
.HasName("ix_userrole_roadieId");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<UsersInRoles>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasIndex(e => e.UserId)
|
||||||
|
.HasName("ix_usersInRoles_userId");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.RoleId)
|
||||||
|
.HasName("ix_usersInRoles_userRoleId");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.User)
|
||||||
|
.WithMany(p => p.UserRoles)
|
||||||
|
.HasForeignKey(d => d.UserId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("usersInRoles_ibfk_1");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Role)
|
||||||
|
.WithMany(p => p.UserRoles)
|
||||||
|
.HasForeignKey(d => d.RoleId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.HasConstraintName("usersInRoles_ibfk_2");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Task<EntityEntry> IRoadieDbContext.AddAsync(object entity, CancellationToken cancellationToken) => throw new NotImplementedException();
|
Task<EntityEntry> IRoadieDbContext.AddAsync(object entity, CancellationToken cancellationToken) => throw new NotImplementedException();
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
using Roadie.Library.Enums;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Roadie.Library.Data
|
namespace Roadie.Library.Data
|
||||||
|
@ -39,5 +37,21 @@ namespace Roadie.Library.Data
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public override string AlternateNames { get; set; }
|
public override string AlternateNames { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(ArtistId))]
|
||||||
|
[InverseProperty("Credits")]
|
||||||
|
public virtual Artist Artist { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(CreditCategoryId))]
|
||||||
|
[InverseProperty("Credits")]
|
||||||
|
public virtual CreditCategory CreditCategory { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(ReleaseId))]
|
||||||
|
[InverseProperty("Credits")]
|
||||||
|
public virtual Release Release { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(TrackId))]
|
||||||
|
[InverseProperty("Credits")]
|
||||||
|
public virtual Track Track { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Roadie.Library.Data
|
namespace Roadie.Library.Data
|
||||||
|
@ -16,5 +17,13 @@ namespace Roadie.Library.Data
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public override string SortName { get; set; }
|
public override string SortName { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("CreditCategory")]
|
||||||
|
public virtual ICollection<Credit> Credits { get; set; }
|
||||||
|
|
||||||
|
public CreditCategory()
|
||||||
|
{
|
||||||
|
Credits = new HashSet<Credit>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,7 +7,9 @@ namespace Roadie.Library.Data
|
||||||
{
|
{
|
||||||
public abstract class EntityBase
|
public abstract class EntityBase
|
||||||
{
|
{
|
||||||
[Column("createdDate")] [Required] public DateTime CreatedDate { get; set; }
|
[Column("createdDate")]
|
||||||
|
[Required]
|
||||||
|
public DateTime CreatedDate { get; set; }
|
||||||
|
|
||||||
[Column("id")]
|
[Column("id")]
|
||||||
[Key]
|
[Key]
|
||||||
|
@ -16,14 +18,14 @@ namespace Roadie.Library.Data
|
||||||
|
|
||||||
public virtual bool? IsLocked { get; set; }
|
public virtual bool? IsLocked { get; set; }
|
||||||
|
|
||||||
[Column("lastUpdated")]
|
[Column("lastUpdated")]
|
||||||
public DateTime? LastUpdated { get; set; }
|
public DateTime? LastUpdated { get; set; }
|
||||||
|
|
||||||
[Column("RoadieId")]
|
[Column("RoadieId")]
|
||||||
[Required]
|
[Required]
|
||||||
public Guid RoadieId { get; set; }
|
public Guid RoadieId { get; set; }
|
||||||
|
|
||||||
[Column("status")]
|
[Column("status")]
|
||||||
public Statuses? Status { get; set; }
|
public Statuses? Status { get; set; }
|
||||||
|
|
||||||
public EntityBase()
|
public EntityBase()
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
@ -8,12 +7,14 @@ namespace Roadie.Library.Data
|
||||||
[Table("genre")]
|
[Table("genre")]
|
||||||
public partial class Genre : EntityBase
|
public partial class Genre : EntityBase
|
||||||
{
|
{
|
||||||
public ICollection<ArtistGenre> Artists { get; set; }
|
[InverseProperty("Genre")]
|
||||||
|
public virtual ICollection<ArtistGenre> Artists { get; set; }
|
||||||
|
|
||||||
public ICollection<Comment> Comments { get; set; }
|
[InverseProperty("Genre")]
|
||||||
|
public virtual ICollection<Comment> Comments { get; set; }
|
||||||
|
|
||||||
[Column("name")]
|
[Column("name")]
|
||||||
[MaxLength(100)]
|
[MaxLength(100)]
|
||||||
[Required]
|
[Required]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
@ -35,14 +36,12 @@ namespace Roadie.Library.Data
|
||||||
[MaxLength(65535)]
|
[MaxLength(65535)]
|
||||||
public string Tags { get; set; }
|
public string Tags { get; set; }
|
||||||
|
|
||||||
[Obsolete("Images moved to file system")]
|
[Column("normalizedName")]
|
||||||
[Column("thumbnail", TypeName = "blob")]
|
[MaxLength(100)]
|
||||||
[MaxLength(65535)]
|
public string NormalizedName { get; set; }
|
||||||
public byte[] Thumbnail { get; set; }
|
|
||||||
|
|
||||||
[Column("normalizedName")] [MaxLength(100)] public string NormalizedName { get; set; }
|
[InverseProperty("Genre")]
|
||||||
|
public virtual ICollection<ReleaseGenre> Releases { get; set; }
|
||||||
public ICollection<ReleaseGenre> Releases { get; set; }
|
|
||||||
|
|
||||||
public Genre()
|
public Genre()
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,23 +26,13 @@ namespace Roadie.Library.Data
|
||||||
public string PathToImage(IRoadieSettings configuration, bool makeFolderIfNotExist = false)
|
public string PathToImage(IRoadieSettings configuration, bool makeFolderIfNotExist = false)
|
||||||
{
|
{
|
||||||
var folder = FolderPathHelper.GenrePath(configuration, SortNameValue);
|
var folder = FolderPathHelper.GenrePath(configuration, SortNameValue);
|
||||||
if(!Directory.Exists(folder) && makeFolderIfNotExist)
|
if (!Directory.Exists(folder) && makeFolderIfNotExist)
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(folder);
|
Directory.CreateDirectory(folder);
|
||||||
}
|
}
|
||||||
return Path.Combine(folder, $"{ SortNameValue.ToFileNameFriendly() } [{ Id }].jpg");
|
return Path.Combine(folder, $"{ SortNameValue.ToFileNameFriendly() } [{ Id }].jpg");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a full file path to the Label Image
|
|
||||||
/// </summary>
|
|
||||||
[Obsolete("This is only here for migration will be removed in future release.")]
|
|
||||||
public string OldPathToImage(IRoadieSettings configuration)
|
|
||||||
{
|
|
||||||
return Path.Combine(configuration.GenreImageFolder, $"{ SortNameValue.ToFileNameFriendly() } [{ Id }].jpg");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static string CacheRegionUrn(Guid Id)
|
public static string CacheRegionUrn(Guid Id)
|
||||||
{
|
{
|
||||||
return string.Format("urn:genre:{0}", Id);
|
return string.Format("urn:genre:{0}", Id);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using Roadie.Library.Identity;
|
using Roadie.Library.Identity;
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Roadie.Library.Data
|
namespace Roadie.Library.Data
|
||||||
|
@ -8,6 +7,10 @@ namespace Roadie.Library.Data
|
||||||
[Table("inviteToken")]
|
[Table("inviteToken")]
|
||||||
public class InviteToken : EntityBase
|
public class InviteToken : EntityBase
|
||||||
{
|
{
|
||||||
|
[ForeignKey(nameof(CreatedByUserId))]
|
||||||
|
[InverseProperty(nameof(User.InviteTokens))]
|
||||||
|
public virtual User CreatedByUser { get; set; }
|
||||||
|
|
||||||
[Column("createdByUserId")]
|
[Column("createdByUserId")]
|
||||||
public int CreatedByUserId { get; set; }
|
public int CreatedByUserId { get; set; }
|
||||||
|
|
||||||
|
@ -17,4 +20,4 @@ namespace Roadie.Library.Data
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public new bool IsLocked { get; set; }
|
public new bool IsLocked { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,13 +8,19 @@ namespace Roadie.Library.Data
|
||||||
[Table("label")]
|
[Table("label")]
|
||||||
public partial class Label : BeginAndEndNamedEntityBase
|
public partial class Label : BeginAndEndNamedEntityBase
|
||||||
{
|
{
|
||||||
[Column("artistCount")] public int? ArtistCount { get; set; }
|
[Column("artistCount")]
|
||||||
|
public int? ArtistCount { get; set; }
|
||||||
|
|
||||||
public ICollection<Comment> Comments { get; set; }
|
[InverseProperty("Label")]
|
||||||
|
public virtual ICollection<Comment> Comments { get; set; }
|
||||||
|
|
||||||
[Column("discogsId")] [MaxLength(50)] public string DiscogsId { get; set; }
|
[Column("discogsId")]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string DiscogsId { get; set; }
|
||||||
|
|
||||||
[Column("imageUrl")] [MaxLength(500)] public string ImageUrl { get; set; }
|
[Column("imageUrl")]
|
||||||
|
[MaxLength(500)]
|
||||||
|
public string ImageUrl { get; set; }
|
||||||
|
|
||||||
[Column("musicBrainzId")]
|
[Column("musicBrainzId")]
|
||||||
[MaxLength(100)]
|
[MaxLength(100)]
|
||||||
|
@ -24,11 +30,14 @@ namespace Roadie.Library.Data
|
||||||
[MaxLength(65535)]
|
[MaxLength(65535)]
|
||||||
public string Profile { get; set; }
|
public string Profile { get; set; }
|
||||||
|
|
||||||
[Column("releaseCount")] public int? ReleaseCount { get; set; }
|
[Column("releaseCount")]
|
||||||
|
public int? ReleaseCount { get; set; }
|
||||||
|
|
||||||
public ICollection<ReleaseLabel> ReleaseLabels { get; set; }
|
[InverseProperty("Label")]
|
||||||
|
public virtual ICollection<ReleaseLabel> ReleaseLabels { get; set; }
|
||||||
|
|
||||||
[Column("trackCount")] public int? TrackCount { get; set; }
|
[Column("trackCount")]
|
||||||
|
public int? TrackCount { get; set; }
|
||||||
|
|
||||||
public Label()
|
public Label()
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,10 +2,7 @@
|
||||||
using Roadie.Library.Extensions;
|
using Roadie.Library.Extensions;
|
||||||
using Roadie.Library.Utility;
|
using Roadie.Library.Utility;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
|
|
||||||
namespace Roadie.Library.Data
|
namespace Roadie.Library.Data
|
||||||
{
|
{
|
||||||
|
@ -23,8 +20,6 @@ namespace Roadie.Library.Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string SortNameValue => string.IsNullOrEmpty(SortName) ? Name : SortName;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a full file path to the Label Image
|
/// Returns a full file path to the Label Image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -38,15 +33,6 @@ namespace Roadie.Library.Data
|
||||||
return Path.Combine(folder, $"{ SortNameValue.ToFileNameFriendly() } [{ Id }].jpg");
|
return Path.Combine(folder, $"{ SortNameValue.ToFileNameFriendly() } [{ Id }].jpg");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a full file path to the Label Image
|
|
||||||
/// </summary>
|
|
||||||
[Obsolete("This is only here for migration will be removed in future release.")]
|
|
||||||
public string OldPathToImage(IRoadieSettings configuration)
|
|
||||||
{
|
|
||||||
return Path.Combine(configuration.LabelImageFolder, $"{ SortNameValue.ToFileNameFriendly() } [{ Id }].jpg");
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsValid => !string.IsNullOrEmpty(Name);
|
public bool IsValid => !string.IsNullOrEmpty(Name);
|
||||||
|
|
||||||
public static string CacheRegionUrn(Guid Id)
|
public static string CacheRegionUrn(Guid Id)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Roadie.Library.Data
|
namespace Roadie.Library.Data
|
||||||
|
@ -14,8 +13,8 @@ namespace Roadie.Library.Data
|
||||||
[Column("name")]
|
[Column("name")]
|
||||||
public virtual string Name { get; set; }
|
public virtual string Name { get; set; }
|
||||||
|
|
||||||
[Column("sortName")]
|
[Column("sortName")]
|
||||||
[MaxLength(250)]
|
[MaxLength(250)]
|
||||||
public virtual string SortName { get; set; }
|
public virtual string SortName { get; set; }
|
||||||
|
|
||||||
public virtual string SortNameValue => string.IsNullOrEmpty(SortName) ? Name : SortName;
|
public virtual string SortNameValue => string.IsNullOrEmpty(SortName) ? Name : SortName;
|
||||||
|
|
|
@ -8,31 +8,42 @@ namespace Roadie.Library.Data
|
||||||
[Table("playlist")]
|
[Table("playlist")]
|
||||||
public partial class Playlist : NamedEntityBase
|
public partial class Playlist : NamedEntityBase
|
||||||
{
|
{
|
||||||
public ICollection<Comment> Comments { get; set; }
|
[InverseProperty("Playlist")]
|
||||||
|
public virtual ICollection<Comment> Comments { get; set; }
|
||||||
|
|
||||||
[Column("Description")]
|
[Column("Description")]
|
||||||
[MaxLength(1000)]
|
[MaxLength(1000)]
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
|
||||||
[Column("duration")] public int? Duration { get; set; }
|
[Column("duration")]
|
||||||
|
public int? Duration { get; set; }
|
||||||
|
|
||||||
[Column("isPublic")] public bool IsPublic { get; set; }
|
[Column("isPublic")]
|
||||||
|
public bool IsPublic { get; set; }
|
||||||
|
|
||||||
[Column("releaseCount")] public short ReleaseCount { get; set; }
|
[Column("releaseCount")]
|
||||||
|
public short ReleaseCount { get; set; }
|
||||||
|
|
||||||
[NotMapped] public new string SortName { get; set; }
|
[NotMapped]
|
||||||
|
public new string SortName { get; set; }
|
||||||
|
|
||||||
[Column("trackCount")] public short TrackCount { get; set; }
|
[Column("trackCount")]
|
||||||
|
public short TrackCount { get; set; }
|
||||||
|
|
||||||
public ICollection<PlaylistTrack> Tracks { get; set; }
|
[InverseProperty("Playlist")]
|
||||||
|
public virtual ICollection<PlaylistTrack> Tracks { get; set; }
|
||||||
|
|
||||||
public ApplicationUser User { get; set; }
|
[ForeignKey(nameof(UserId))]
|
||||||
|
[InverseProperty("Playlists")]
|
||||||
|
public virtual User User { get; set; }
|
||||||
|
|
||||||
[Column("userId")] public int? UserId { get; set; }
|
[Column("userId")]
|
||||||
|
public int? UserId { get; set; }
|
||||||
|
|
||||||
public Playlist()
|
public Playlist()
|
||||||
{
|
{
|
||||||
Comments = new HashSet<Comment>();
|
Comments = new HashSet<Comment>();
|
||||||
|
Tracks = new HashSet<PlaylistTrack>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
using Roadie.Library.Configuration;
|
using Roadie.Library.Configuration;
|
||||||
using Roadie.Library.Extensions;
|
using Roadie.Library.Extensions;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Roadie.Library.Data
|
namespace Roadie.Library.Data
|
||||||
|
|
|
@ -6,14 +6,21 @@ namespace Roadie.Library.Data
|
||||||
[Table("playlisttrack")]
|
[Table("playlisttrack")]
|
||||||
public class PlaylistTrack : EntityBase
|
public class PlaylistTrack : EntityBase
|
||||||
{
|
{
|
||||||
[Column("listNumber")] [Required] public int ListNumber { get; set; }
|
[Column("listNumber")]
|
||||||
|
[Required]
|
||||||
|
public int ListNumber { get; set; }
|
||||||
|
|
||||||
public Playlist Playlist { get; set; }
|
[ForeignKey(nameof(PlayListId))]
|
||||||
|
[InverseProperty("Tracks")]
|
||||||
|
public virtual Playlist Playlist { get; set; }
|
||||||
|
|
||||||
[Column("playListId")] public int PlayListId { get; set; }
|
[Column("playListId")]
|
||||||
|
public int PlayListId { get; set; }
|
||||||
|
|
||||||
public Track Track { get; set; }
|
public virtual Track Track { get; set; }
|
||||||
|
|
||||||
[Column("trackId")] public int TrackId { get; set; }
|
[Column("trackId")]
|
||||||
|
[InverseProperty("PlaylistTracks")]
|
||||||
|
public int TrackId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
33
Roadie.Api.Library/Data/PositionArtistRelease.cs
Normal file
33
Roadie.Api.Library/Data/PositionArtistRelease.cs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
using Roadie.Library.Enums;
|
||||||
|
using System;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace Roadie.Library.Data
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class PositionArtistRelease
|
||||||
|
{
|
||||||
|
public string Artist { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is the index (position in the list regardless of the position number)
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public int Index { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is the position number for the list (can be a year "1984" can be a number "14")
|
||||||
|
/// </summary>
|
||||||
|
public int Position { get; set; }
|
||||||
|
|
||||||
|
public string Release { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public Statuses Status { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Status")]
|
||||||
|
public string StatusVerbose => Status.ToString();
|
||||||
|
|
||||||
|
public override string ToString() => string.Format("Position [{0}], Artist [{1}], Release [{2}]", Position, Artist, Release);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,78 +14,101 @@ namespace Roadie.Library.Data
|
||||||
[MaxLength(65535)]
|
[MaxLength(65535)]
|
||||||
public string AlternateNames { get; set; }
|
public string AlternateNames { get; set; }
|
||||||
|
|
||||||
[Column("amgId")] [MaxLength(50)] public string AmgId { get; set; }
|
[Column("amgId")]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string AmgId { get; set; }
|
||||||
|
|
||||||
public Artist Artist { get; set; }
|
public virtual Artist Artist { get; set; }
|
||||||
|
|
||||||
[Column("artistId")] [Required] public int ArtistId { get; set; }
|
[Column("artistId")]
|
||||||
|
[Required]
|
||||||
|
public int ArtistId { get; set; }
|
||||||
|
|
||||||
public ICollection<CollectionRelease> Collections { get; set; }
|
[InverseProperty("Release")]
|
||||||
|
public virtual ICollection<CollectionRelease> Collections { get; set; }
|
||||||
|
|
||||||
public ICollection<Comment> Comments { get; set; }
|
[InverseProperty("Release")]
|
||||||
|
public virtual ICollection<Comment> Comments { get; set; }
|
||||||
|
|
||||||
[Column("discogsId")] [MaxLength(50)] public string DiscogsId { get; set; }
|
[Column("discogsId")]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string DiscogsId { get; set; }
|
||||||
|
|
||||||
[Column("duration")] public int? Duration { get; set; }
|
[Column("duration")]
|
||||||
|
public int? Duration { get; set; }
|
||||||
|
|
||||||
public ICollection<ReleaseGenre> Genres { get; set; }
|
[InverseProperty("Release")]
|
||||||
|
public virtual ICollection<ReleaseGenre> Genres { get; set; }
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public IEnumerable<Imaging.IImage> Images { get; set; } = Enumerable.Empty<Imaging.IImage>();
|
public IEnumerable<Imaging.IImage> Images { get; set; } = Enumerable.Empty<Imaging.IImage>();
|
||||||
|
|
||||||
public Imaging.IImage ThumbnailImage => Images.OrderBy(x => x.SortOrder).FirstOrDefault();
|
public Imaging.IImage ThumbnailImage => Images.OrderBy(x => x.SortOrder).FirstOrDefault();
|
||||||
|
|
||||||
[Column("isVirtual")] public bool? IsVirtual { get; set; }
|
[Column("isVirtual")]
|
||||||
|
public bool? IsVirtual { get; set; }
|
||||||
|
|
||||||
[Column("itunesId")] [MaxLength(100)] public string ITunesId { get; set; }
|
[Column("itunesId")]
|
||||||
|
[MaxLength(100)]
|
||||||
|
public string ITunesId { get; set; }
|
||||||
|
|
||||||
public ICollection<ReleaseLabel> Labels { get; set; }
|
[InverseProperty("Release")]
|
||||||
|
public virtual ICollection<ReleaseLabel> Labels { get; set; }
|
||||||
|
|
||||||
[Column("lastFMId")] [MaxLength(50)] public string LastFMId { get; set; }
|
[Column("lastFMId")]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string LastFMId { get; set; }
|
||||||
|
|
||||||
[Column("lastFMSummary", TypeName = "text")]
|
[Column("lastFMSummary", TypeName = "text")]
|
||||||
[MaxLength(65535)]
|
[MaxLength(65535)]
|
||||||
public string LastFMSummary { get; set; }
|
public string LastFMSummary { get; set; }
|
||||||
|
|
||||||
[Column("lastPlayed")] public DateTime? LastPlayed { get; set; }
|
[Column("lastPlayed")]
|
||||||
|
public DateTime? LastPlayed { get; set; }
|
||||||
|
|
||||||
[Column("libraryStatus")] public LibraryStatus? LibraryStatus { get; set; }
|
[Column("libraryStatus")]
|
||||||
|
public LibraryStatus? LibraryStatus { get; set; }
|
||||||
|
|
||||||
[Column("mediaCount")] public short? MediaCount { get; set; }
|
[Column("mediaCount")]
|
||||||
|
public short? MediaCount { get; set; }
|
||||||
|
|
||||||
public ICollection<ReleaseMedia> Medias { get; set; }
|
[InverseProperty("Release")]
|
||||||
|
public virtual ICollection<ReleaseMedia> Medias { get; set; }
|
||||||
|
|
||||||
[Column("musicBrainzId")]
|
[Column("musicBrainzId")]
|
||||||
[MaxLength(100)]
|
[MaxLength(100)]
|
||||||
public string MusicBrainzId { get; set; }
|
public string MusicBrainzId { get; set; }
|
||||||
|
|
||||||
[Column("playedCount")] public int? PlayedCount { get; set; }
|
[Column("playedCount")]
|
||||||
|
public int? PlayedCount { get; set; }
|
||||||
|
|
||||||
[Column("profile", TypeName = "text")]
|
[Column("profile", TypeName = "text")]
|
||||||
[MaxLength(65535)]
|
[MaxLength(65535)]
|
||||||
public string Profile { get; set; }
|
public string Profile { get; set; }
|
||||||
|
|
||||||
[Column("rank")] public decimal? Rank { get; set; }
|
[Column("rank")]
|
||||||
|
public decimal? Rank { get; set; }
|
||||||
|
|
||||||
[Column("rating")] public short? Rating { get; set; }
|
[Column("rating")]
|
||||||
|
public short? Rating { get; set; }
|
||||||
|
|
||||||
[Column("releaseDate")] public DateTime? ReleaseDate { get; set; }
|
[Column("releaseDate")]
|
||||||
|
public DateTime? ReleaseDate { get; set; }
|
||||||
|
|
||||||
[Column("releaseType")] public ReleaseType? ReleaseType { get; set; }
|
[Column("releaseType")]
|
||||||
|
public ReleaseType? ReleaseType { get; set; }
|
||||||
|
|
||||||
[Column("spotifyId")] [MaxLength(100)] public string SpotifyId { get; set; }
|
[Column("spotifyId")]
|
||||||
|
[MaxLength(100)]
|
||||||
|
public string SpotifyId { get; set; }
|
||||||
|
|
||||||
[Column("submissionId")] public int? SubmissionId { get; set; }
|
[Column("submissionId")]
|
||||||
|
public int? SubmissionId { get; set; }
|
||||||
|
|
||||||
[Column("tags", TypeName = "text")]
|
[Column("tags", TypeName = "text")]
|
||||||
[MaxLength(65535)]
|
[MaxLength(65535)]
|
||||||
public string Tags { get; set; }
|
public string Tags { get; set; }
|
||||||
|
|
||||||
[Obsolete("Images moved to file system")]
|
|
||||||
[Column("thumbnail", TypeName = "blob")]
|
|
||||||
[MaxLength(65535)]
|
|
||||||
public byte[] Thumbnail { get; set; }
|
|
||||||
|
|
||||||
[MaxLength(250)]
|
[MaxLength(250)]
|
||||||
[Column("title")]
|
[Column("title")]
|
||||||
[Required]
|
[Required]
|
||||||
|
@ -97,21 +120,31 @@ namespace Roadie.Library.Data
|
||||||
|
|
||||||
public string SortTitleValue => string.IsNullOrEmpty(SortTitle) ? Title : SortTitle;
|
public string SortTitleValue => string.IsNullOrEmpty(SortTitle) ? Title : SortTitle;
|
||||||
|
|
||||||
[Column("trackCount")] public short TrackCount { get; set; }
|
[Column("trackCount")]
|
||||||
|
public short TrackCount { get; set; }
|
||||||
|
|
||||||
[Column("urls", TypeName = "text")]
|
[Column("urls", TypeName = "text")]
|
||||||
[MaxLength(65535)]
|
[MaxLength(65535)]
|
||||||
public string URLs { get; set; }
|
public string URLs { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("Release")]
|
||||||
|
public virtual ICollection<Credit> Credits { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("Release")]
|
||||||
|
public virtual ICollection<UserRelease> UserRelases { get; set; }
|
||||||
|
|
||||||
public Release()
|
public Release()
|
||||||
{
|
{
|
||||||
Rating = 0;
|
Rating = 0;
|
||||||
|
|
||||||
ReleaseType = Enums.ReleaseType.Release;
|
ReleaseType = Enums.ReleaseType.Release;
|
||||||
Medias = new HashSet<ReleaseMedia>();
|
Medias = new HashSet<ReleaseMedia>();
|
||||||
Labels = new HashSet<ReleaseLabel>();
|
Labels = new HashSet<ReleaseLabel>();
|
||||||
Collections = new HashSet<CollectionRelease>();
|
Collections = new HashSet<CollectionRelease>();
|
||||||
Genres = new HashSet<ReleaseGenre>();
|
Genres = new HashSet<ReleaseGenre>();
|
||||||
Comments = new HashSet<Comment>();
|
Comments = new HashSet<Comment>();
|
||||||
|
Credits = new HashSet<Credit>();
|
||||||
|
UserRelases = new HashSet<UserRelease>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,17 +6,25 @@ namespace Roadie.Library.Data
|
||||||
[Table("releaseGenreTable")]
|
[Table("releaseGenreTable")]
|
||||||
public class ReleaseGenre
|
public class ReleaseGenre
|
||||||
{
|
{
|
||||||
public Genre Genre { get; set; }
|
[ForeignKey(nameof(ReleaseId))]
|
||||||
|
[InverseProperty("Genres")]
|
||||||
|
public virtual Release Release { get; set; }
|
||||||
|
|
||||||
[Column("genreId")] [Required] public int? GenreId { get; set; }
|
[Column("releaseId")]
|
||||||
|
[Required]
|
||||||
|
public int ReleaseId { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(GenreId))]
|
||||||
|
[InverseProperty("Releases")]
|
||||||
|
public virtual Genre Genre { get; set; }
|
||||||
|
|
||||||
|
[Column("genreId")]
|
||||||
|
[Required]
|
||||||
|
public int GenreId { get; set; }
|
||||||
|
|
||||||
[Column("id")]
|
|
||||||
[Key]
|
[Key]
|
||||||
|
[Column("id")]
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
public Release Release { get; set; }
|
|
||||||
|
|
||||||
[Column("releaseId")] [Required] public int ReleaseId { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,14 +5,21 @@ namespace Roadie.Library.Data
|
||||||
[Table("releaselabel")]
|
[Table("releaselabel")]
|
||||||
public class ReleaseLabel : BeginAndEndEntityBase
|
public class ReleaseLabel : BeginAndEndEntityBase
|
||||||
{
|
{
|
||||||
[Column("catalogNumber")] public string CatalogNumber { get; set; }
|
[Column("catalogNumber")]
|
||||||
|
public string CatalogNumber { get; set; }
|
||||||
|
|
||||||
public Label Label { get; set; }
|
[ForeignKey(nameof(LabelId))]
|
||||||
|
[InverseProperty("ReleaseLabels")]
|
||||||
|
public virtual Label Label { get; set; }
|
||||||
|
|
||||||
[Column("labelId")] public int LabelId { get; set; }
|
[Column("labelId")]
|
||||||
|
public int LabelId { get; set; }
|
||||||
|
|
||||||
public Release Release { get; set; }
|
[ForeignKey(nameof(ReleaseId))]
|
||||||
|
[InverseProperty("Labels")]
|
||||||
|
public virtual Release Release { get; set; }
|
||||||
|
|
||||||
[Column("releaseId")] public int ReleaseId { get; set; }
|
[Column("releaseId")]
|
||||||
|
public int ReleaseId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,19 +7,26 @@ namespace Roadie.Library.Data
|
||||||
[Table("releasemedia")]
|
[Table("releasemedia")]
|
||||||
public class ReleaseMedia : EntityBase
|
public class ReleaseMedia : EntityBase
|
||||||
{
|
{
|
||||||
[Column("releaseMediaNumber")] public short MediaNumber { get; set; }
|
[Column("releaseMediaNumber")]
|
||||||
|
public short MediaNumber { get; set; }
|
||||||
|
|
||||||
public Release Release { get; set; }
|
[ForeignKey(nameof(ReleaseId))]
|
||||||
|
[InverseProperty("Medias")]
|
||||||
|
public virtual Release Release { get; set; }
|
||||||
|
|
||||||
[Column("releaseId")] public int ReleaseId { get; set; }
|
[Column("releaseId")]
|
||||||
|
public int ReleaseId { get; set; }
|
||||||
|
|
||||||
[Column("releaseSubTitle")]
|
[Column("releaseSubTitle")]
|
||||||
[MaxLength(500)]
|
[MaxLength(500)]
|
||||||
public string SubTitle { get; set; }
|
public string SubTitle { get; set; }
|
||||||
|
|
||||||
[Column("trackCount")] [Required] public short TrackCount { get; set; }
|
[Column("trackCount")]
|
||||||
|
[Required]
|
||||||
|
public short TrackCount { get; set; }
|
||||||
|
|
||||||
public ICollection<Track> Tracks { get; set; }
|
[InverseProperty("ReleaseMedia")]
|
||||||
|
public virtual ICollection<Track> Tracks { get; set; }
|
||||||
|
|
||||||
public ReleaseMedia()
|
public ReleaseMedia()
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,6 @@ using Roadie.Library.Utility;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Cryptography;
|
|
||||||
|
|
||||||
namespace Roadie.Library.Data
|
namespace Roadie.Library.Data
|
||||||
{
|
{
|
||||||
|
@ -106,7 +105,7 @@ namespace Roadie.Library.Data
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"Id [{Id}], Status [{ Status }], LibraryStatus [{ LibraryStatus }], Title [{Title}], SortTitle [{ SortTitleValue }], Release Date [{ReleaseYear}]";
|
return $"Id [{Id}], Status [{ Status }], LibraryStatus [{ LibraryStatus }], Title [{Title}], SortTitle [{ SortTitle }], Release Date [{ReleaseYear}]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -12,9 +12,14 @@ namespace Roadie.Library.Data
|
||||||
[Required]
|
[Required]
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
|
||||||
[NotMapped] public new bool? IsLocked { get; set; }
|
[NotMapped]
|
||||||
public ApplicationUser User { get; set; }
|
public new bool? IsLocked { get; set; }
|
||||||
|
|
||||||
[Column("userId")] public int? UserId { get; set; }
|
[ForeignKey(nameof(UserId))]
|
||||||
|
[InverseProperty("Requests")]
|
||||||
|
public virtual User User { get; set; }
|
||||||
|
|
||||||
|
[Column("userId")]
|
||||||
|
public int? UserId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,23 +7,31 @@ namespace Roadie.Library.Data
|
||||||
[Table("scanHistory")]
|
[Table("scanHistory")]
|
||||||
public class ScanHistory : EntityBase
|
public class ScanHistory : EntityBase
|
||||||
{
|
{
|
||||||
[Column("forArtistId")] public int? ForArtistId { get; set; }
|
[Column("forArtistId")]
|
||||||
|
public int? ForArtistId { get; set; }
|
||||||
|
|
||||||
[Column("forReleaseId")] public int? ForReleaseId { get; set; }
|
[Column("forReleaseId")]
|
||||||
|
public int? ForReleaseId { get; set; }
|
||||||
|
|
||||||
[NotMapped] public new bool? IsLocked { get; set; }
|
[NotMapped]
|
||||||
|
public new bool? IsLocked { get; set; }
|
||||||
|
|
||||||
[Column("newArtists")] public int? NewArtists { get; set; }
|
[Column("newArtists")]
|
||||||
|
public int? NewArtists { get; set; }
|
||||||
|
|
||||||
[Column("newReleases")] public int? NewReleases { get; set; }
|
[Column("newReleases")]
|
||||||
|
public int? NewReleases { get; set; }
|
||||||
|
|
||||||
[Column("newTracks")] public int? NewTracks { get; set; }
|
[Column("newTracks")]
|
||||||
|
public int? NewTracks { get; set; }
|
||||||
|
|
||||||
[Column("timeSpanInSeconds")] public int TimeSpanInSeconds { get; set; }
|
[Column("timeSpanInSeconds")]
|
||||||
|
public int TimeSpanInSeconds { get; set; }
|
||||||
|
|
||||||
public ApplicationUser User { get; set; }
|
public virtual User User { get; set; }
|
||||||
|
|
||||||
[Column("userId")] public int UserId { get; set; }
|
[Column("userId")]
|
||||||
|
public int UserId { get; set; }
|
||||||
|
|
||||||
public ScanHistory()
|
public ScanHistory()
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,8 +6,11 @@ namespace Roadie.Library.Data
|
||||||
[Table("submission")]
|
[Table("submission")]
|
||||||
public class Submission : EntityBase
|
public class Submission : EntityBase
|
||||||
{
|
{
|
||||||
public ApplicationUser User { get; set; }
|
[ForeignKey(nameof(UserId))]
|
||||||
|
[InverseProperty("Submissions")]
|
||||||
|
public virtual User User { get; set; }
|
||||||
|
|
||||||
[Column("userId")] public int UserId { get; set; }
|
[Column("userId")]
|
||||||
|
public int UserId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -12,27 +12,48 @@ namespace Roadie.Library.Data
|
||||||
[MaxLength(65535)]
|
[MaxLength(65535)]
|
||||||
public string AlternateNames { get; set; }
|
public string AlternateNames { get; set; }
|
||||||
|
|
||||||
[Column("amgId")] [MaxLength(50)] public string AmgId { get; set; }
|
[Column("amgId")]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string AmgId { get; set; }
|
||||||
|
|
||||||
[Column("artistId")] public int? ArtistId { get; set; }
|
[Column("artistId")]
|
||||||
|
public int? ArtistId { get; set; }
|
||||||
|
|
||||||
public ICollection<Comment> Comments { get; set; }
|
[ForeignKey(nameof(ArtistId))]
|
||||||
|
[InverseProperty("Tracks")]
|
||||||
|
public virtual Artist TrackArtist { get; set; }
|
||||||
|
|
||||||
[Column("duration")] public int? Duration { get; set; }
|
[InverseProperty("Track")]
|
||||||
|
public virtual ICollection<Comment> Comments { get; set; }
|
||||||
|
|
||||||
[Column("fileName")] [MaxLength(500)] public string FileName { get; set; }
|
[Column("duration")]
|
||||||
|
public int? Duration { get; set; }
|
||||||
|
|
||||||
[Column("filePath")] [MaxLength(1000)] public string FilePath { get; set; }
|
[Column("fileName")]
|
||||||
|
[MaxLength(500)]
|
||||||
|
public string FileName { get; set; }
|
||||||
|
|
||||||
[Column("fileSize")] public int? FileSize { get; set; }
|
[Column("filePath")]
|
||||||
|
[MaxLength(1000)]
|
||||||
|
public string FilePath { get; set; }
|
||||||
|
|
||||||
[Column("hash")] [MaxLength(32)] public string Hash { get; set; }
|
[Column("fileSize")]
|
||||||
|
public int? FileSize { get; set; }
|
||||||
|
|
||||||
[Column("isrc")] [MaxLength(15)] public string ISRC { get; set; }
|
[Column("hash")]
|
||||||
|
[MaxLength(32)]
|
||||||
|
public string Hash { get; set; }
|
||||||
|
|
||||||
[Column("lastFMId")] [MaxLength(50)] public string LastFMId { get; set; }
|
[Column("isrc")]
|
||||||
|
[MaxLength(15)]
|
||||||
|
public string ISRC { get; set; }
|
||||||
|
|
||||||
[Column("lastPlayed")] public DateTime? LastPlayed { get; set; }
|
[Column("lastFMId")]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string LastFMId { get; set; }
|
||||||
|
|
||||||
|
[Column("lastPlayed")]
|
||||||
|
public DateTime? LastPlayed { get; set; }
|
||||||
|
|
||||||
[Column("musicBrainzId")]
|
[Column("musicBrainzId")]
|
||||||
[MaxLength(100)]
|
[MaxLength(100)]
|
||||||
|
@ -42,34 +63,53 @@ namespace Roadie.Library.Data
|
||||||
[MaxLength(65535)]
|
[MaxLength(65535)]
|
||||||
public string PartTitles { get; set; }
|
public string PartTitles { get; set; }
|
||||||
|
|
||||||
[Column("playedCount")] public int? PlayedCount { get; set; }
|
[Column("playedCount")]
|
||||||
|
public int? PlayedCount { get; set; }
|
||||||
|
|
||||||
[Column("rating")] public short Rating { get; set; }
|
[Column("rating")]
|
||||||
|
public short Rating { get; set; }
|
||||||
|
|
||||||
public ReleaseMedia ReleaseMedia { get; set; }
|
public virtual ReleaseMedia ReleaseMedia { get; set; }
|
||||||
|
|
||||||
[Column("releaseMediaId")] public int ReleaseMediaId { get; set; }
|
[Column("releaseMediaId")]
|
||||||
|
public int ReleaseMediaId { get; set; }
|
||||||
|
|
||||||
[Column("spotifyId")] [MaxLength(100)] public string SpotifyId { get; set; }
|
[Column("spotifyId")]
|
||||||
|
[MaxLength(100)]
|
||||||
|
public string SpotifyId { get; set; }
|
||||||
|
|
||||||
[Column("tags", TypeName = "text")]
|
[Column("tags", TypeName = "text")]
|
||||||
[MaxLength(65535)]
|
[MaxLength(65535)]
|
||||||
public string Tags { get; set; }
|
public string Tags { get; set; }
|
||||||
|
|
||||||
[Obsolete("Images moved to file system")]
|
|
||||||
[Column("thumbnail", TypeName = "blob")]
|
|
||||||
public byte[] Thumbnail { get; set; }
|
|
||||||
|
|
||||||
[MaxLength(250)]
|
[MaxLength(250)]
|
||||||
[Column("title")]
|
[Column("title")]
|
||||||
[Required]
|
[Required]
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
|
|
||||||
[Column("trackNumber")] [Required] public short TrackNumber { get; set; }
|
[Column("trackNumber")]
|
||||||
|
[Required]
|
||||||
|
public short TrackNumber { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("Track")]
|
||||||
|
public virtual ICollection<Credit> Credits { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("Track")]
|
||||||
|
public virtual ICollection<PlaylistTrack> Playlists { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("Track")]
|
||||||
|
public virtual ICollection<UserQue> UserQues { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("Track")]
|
||||||
|
public virtual ICollection<UserTrack> UserTracks { get; set; }
|
||||||
|
|
||||||
public Track()
|
public Track()
|
||||||
{
|
{
|
||||||
Comments = new HashSet<Comment>();
|
Comments = new HashSet<Comment>();
|
||||||
|
Credits = new HashSet<Credit>();
|
||||||
|
Playlists = new HashSet<PlaylistTrack>();
|
||||||
|
UserQues = new HashSet<UserQue>();
|
||||||
|
UserTracks = new HashSet<UserTrack>();
|
||||||
Rating = 0;
|
Rating = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
|
|
||||||
namespace Roadie.Library.Data
|
namespace Roadie.Library.Data
|
||||||
{
|
{
|
||||||
|
@ -38,9 +36,11 @@ namespace Roadie.Library.Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Artist TrackArtist { get; set; }
|
/// <summary>
|
||||||
|
/// This is used when finding metadata, not storedin the database.
|
||||||
[NotMapped] public IEnumerable<string> TrackArtists { get; set; }
|
/// </summary>
|
||||||
|
[NotMapped]
|
||||||
|
public virtual IEnumerable<string> TrackArtists { get; set; }
|
||||||
|
|
||||||
public static string CacheRegionUrn(Guid Id)
|
public static string CacheRegionUrn(Guid Id)
|
||||||
{
|
{
|
||||||
|
@ -63,7 +63,7 @@ namespace Roadie.Library.Data
|
||||||
public bool DoesFileForTrackExist(IRoadieSettings configuration)
|
public bool DoesFileForTrackExist(IRoadieSettings configuration)
|
||||||
{
|
{
|
||||||
var trackPath = PathToTrack(configuration);
|
var trackPath = PathToTrack(configuration);
|
||||||
if(string.IsNullOrEmpty(trackPath))
|
if (string.IsNullOrEmpty(trackPath))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,19 +7,30 @@ namespace Roadie.Library.Data
|
||||||
[Table("userartist")]
|
[Table("userartist")]
|
||||||
public class UserArtist : EntityBase
|
public class UserArtist : EntityBase
|
||||||
{
|
{
|
||||||
public Artist Artist { get; set; }
|
[ForeignKey(nameof(ArtistId))]
|
||||||
|
[InverseProperty("UserArtists")]
|
||||||
|
public virtual Artist Artist { get; set; }
|
||||||
|
|
||||||
[Column("artistId")] [Required] public int ArtistId { get; set; }
|
[Column("artistId")]
|
||||||
|
[Required]
|
||||||
|
public int ArtistId { get; set; }
|
||||||
|
|
||||||
[Column("isDisliked")] public bool? IsDisliked { get; set; }
|
[Column("isDisliked")]
|
||||||
|
public bool? IsDisliked { get; set; }
|
||||||
|
|
||||||
[Column("isFavorite")] public bool? IsFavorite { get; set; }
|
[Column("isFavorite")]
|
||||||
|
public bool? IsFavorite { get; set; }
|
||||||
|
|
||||||
[Column("rating")] public short Rating { get; set; }
|
[Column("rating")]
|
||||||
|
public short Rating { get; set; }
|
||||||
|
|
||||||
public ApplicationUser User { get; set; }
|
[ForeignKey(nameof(UserId))]
|
||||||
|
[InverseProperty("ArtistRatings")]
|
||||||
|
public virtual User User { get; set; }
|
||||||
|
|
||||||
[Column("userId")] [Required] public int UserId { get; set; }
|
[Column("userId")]
|
||||||
|
[Required]
|
||||||
|
public int UserId { get; set; }
|
||||||
|
|
||||||
public UserArtist()
|
public UserArtist()
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,13 +7,30 @@ namespace Roadie.Library.Data
|
||||||
[Table("userQue")]
|
[Table("userQue")]
|
||||||
public class UserQue : EntityBase
|
public class UserQue : EntityBase
|
||||||
{
|
{
|
||||||
[Column("isCurrent")] public bool? IsCurrent { get; set; }
|
[Column("isCurrent")]
|
||||||
[Column("position")] public long? Position { get; set; }
|
public bool? IsCurrent { get; set; }
|
||||||
[Column("queSortOrder")] [Required] public short QueSortOrder { get; set; }
|
|
||||||
public Track Track { get; set; }
|
|
||||||
[Column("trackId")] [Required] public int TrackId { get; set; }
|
|
||||||
public ApplicationUser User { get; set; }
|
|
||||||
|
|
||||||
[Column("userId")] [Required] public int UserId { get; set; }
|
[Column("position")]
|
||||||
|
public long? Position { get; set; }
|
||||||
|
|
||||||
|
[Column("queSortOrder")]
|
||||||
|
[Required]
|
||||||
|
public short QueSortOrder { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(TrackId))]
|
||||||
|
[InverseProperty("UserQues")]
|
||||||
|
public virtual Track Track { get; set; }
|
||||||
|
|
||||||
|
[Column("trackId")]
|
||||||
|
[Required]
|
||||||
|
public int TrackId { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(UserId))]
|
||||||
|
[InverseProperty("UserQues")]
|
||||||
|
public virtual User User { get; set; }
|
||||||
|
|
||||||
|
[Column("userId")]
|
||||||
|
[Required]
|
||||||
|
public int UserId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,19 +7,30 @@ namespace Roadie.Library.Data
|
||||||
[Table("userrelease")]
|
[Table("userrelease")]
|
||||||
public class UserRelease : EntityBase
|
public class UserRelease : EntityBase
|
||||||
{
|
{
|
||||||
[Column("isDisliked")] public bool? IsDisliked { get; set; }
|
[Column("isDisliked")]
|
||||||
|
public bool? IsDisliked { get; set; }
|
||||||
|
|
||||||
[Column("isFavorite")] public bool? IsFavorite { get; set; }
|
[Column("isFavorite")]
|
||||||
|
public bool? IsFavorite { get; set; }
|
||||||
|
|
||||||
[Column("rating")] public short Rating { get; set; }
|
[Column("rating")]
|
||||||
|
public short Rating { get; set; }
|
||||||
|
|
||||||
public Release Release { get; set; }
|
[ForeignKey(nameof(ReleaseId))]
|
||||||
|
[InverseProperty("UserRelases")]
|
||||||
|
public virtual Release Release { get; set; }
|
||||||
|
|
||||||
[Column("releaseId")] [Required] public int ReleaseId { get; set; }
|
[Column("releaseId")]
|
||||||
|
[Required]
|
||||||
|
public int ReleaseId { get; set; }
|
||||||
|
|
||||||
public ApplicationUser User { get; set; }
|
[ForeignKey(nameof(UserId))]
|
||||||
|
[InverseProperty("UserReleases")]
|
||||||
|
public virtual User User { get; set; }
|
||||||
|
|
||||||
[Column("userId")] [Required] public int UserId { get; set; }
|
[Column("userId")]
|
||||||
|
[Required]
|
||||||
|
public int UserId { get; set; }
|
||||||
|
|
||||||
public UserRelease()
|
public UserRelease()
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,23 +8,36 @@ namespace Roadie.Library.Data
|
||||||
[Table("usertrack")]
|
[Table("usertrack")]
|
||||||
public class UserTrack : EntityBase
|
public class UserTrack : EntityBase
|
||||||
{
|
{
|
||||||
[Column("isDisliked")] public bool? IsDisliked { get; set; }
|
[Column("isDisliked")]
|
||||||
|
public bool? IsDisliked { get; set; }
|
||||||
|
|
||||||
[Column("isFavorite")] public bool? IsFavorite { get; set; }
|
[Column("isFavorite")]
|
||||||
|
public bool? IsFavorite { get; set; }
|
||||||
|
|
||||||
[Column("lastPlayed")] public DateTime? LastPlayed { get; set; }
|
[Column("lastPlayed")]
|
||||||
|
public DateTime? LastPlayed { get; set; }
|
||||||
|
|
||||||
[Column("playedCount")] public int? PlayedCount { get; set; }
|
[Column("playedCount")]
|
||||||
|
public int? PlayedCount { get; set; }
|
||||||
|
|
||||||
[Column("rating")] public short Rating { get; set; }
|
[Column("rating")]
|
||||||
|
public short Rating { get; set; }
|
||||||
|
|
||||||
public Track Track { get; set; }
|
[ForeignKey(nameof(TrackId))]
|
||||||
|
[InverseProperty("UserTracks")]
|
||||||
|
public virtual Track Track { get; set; }
|
||||||
|
|
||||||
[Column("trackId")] [Required] public int TrackId { get; set; }
|
[Column("trackId")]
|
||||||
|
[Required]
|
||||||
|
public int TrackId { get; set; }
|
||||||
|
|
||||||
public ApplicationUser User { get; set; }
|
[ForeignKey(nameof(UserId))]
|
||||||
|
[InverseProperty("UserTracks")]
|
||||||
|
public virtual User User { get; set; }
|
||||||
|
|
||||||
[Column("userId")] [Required] public int UserId { get; set; }
|
[Column("userId")]
|
||||||
|
[Required]
|
||||||
|
public int UserId { get; set; }
|
||||||
|
|
||||||
public UserTrack()
|
public UserTrack()
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,37 +87,38 @@ namespace Roadie.Library.Engines
|
||||||
if (artist.Id < 1 && addArtistResult.Entity.Id > 0) artist.Id = addArtistResult.Entity.Id;
|
if (artist.Id < 1 && addArtistResult.Entity.Id > 0) artist.Id = addArtistResult.Entity.Id;
|
||||||
if (inserted > 0 && artist.Id > 0)
|
if (inserted > 0 && artist.Id > 0)
|
||||||
{
|
{
|
||||||
if (artistGenreTables != null && artistGenreTables.Any(x => x.GenreId == null))
|
if (artistGenreTables != null)
|
||||||
{
|
{
|
||||||
foreach (var artistGenreTable in artistGenreTables)
|
if (artistGenreTables != null)
|
||||||
{
|
{
|
||||||
var genreName = artistGenreTable.Genre?.Name?.ToAlphanumericName();
|
foreach (var artistGenreTable in artistGenreTables.Select(x => x.Genre?.Name).Distinct())
|
||||||
if (string.IsNullOrEmpty(genreName)) continue;
|
|
||||||
if (artistGenreTable.Genre.Name.Length > 100)
|
|
||||||
{
|
{
|
||||||
var originalName = artistGenreTable.Genre.Name;
|
var genreName = artistGenreTable.ToAlphanumericName().ToTitleCase();
|
||||||
artistGenreTable.Genre.Name = artistGenreTable.Genre.Name.Substring(0, 99);
|
var normalizedName = genreName.ToUpper();
|
||||||
genreName = genreName.Substring(0, 99);
|
if (string.IsNullOrEmpty(genreName)) continue;
|
||||||
Logger.LogWarning($"Genre Name Too long was [{originalName}] truncated to [{artistGenreTable.Genre.Name}]");
|
if (genreName.Length > 100)
|
||||||
}
|
|
||||||
var genre = DbContext.Genres.FirstOrDefault(x => x.NormalizedName == genreName);
|
|
||||||
if (genre == null)
|
|
||||||
{
|
|
||||||
genre = new Genre
|
|
||||||
{
|
{
|
||||||
Name = artistGenreTable.Genre.Name,
|
var originalName = genreName;
|
||||||
NormalizedName = genreName
|
genreName = genreName.Substring(0, 99);
|
||||||
};
|
Logger.LogWarning($"Genre Name Too long was [{originalName}] truncated to [{genreName}]");
|
||||||
DbContext.Genres.Add(genre);
|
}
|
||||||
await DbContext.SaveChangesAsync();
|
var genre = DbContext.Genres.FirstOrDefault(x => x.NormalizedName == normalizedName);
|
||||||
}
|
if (genre == null)
|
||||||
if (genre != null && genre.Id > 0)
|
{
|
||||||
{
|
genre = new Genre
|
||||||
|
{
|
||||||
|
Name = genreName,
|
||||||
|
NormalizedName = normalizedName
|
||||||
|
};
|
||||||
|
DbContext.Genres.Add(genre);
|
||||||
|
await DbContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
DbContext.ArtistGenres.Add(new ArtistGenre
|
DbContext.ArtistGenres.Add(new ArtistGenre
|
||||||
{
|
{
|
||||||
ArtistId = artist.Id,
|
ArtistId = artist.Id,
|
||||||
GenreId = genre.Id
|
GenreId = genre.Id
|
||||||
});
|
});
|
||||||
|
await DbContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,7 +158,7 @@ namespace Roadie.Library.Engines
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.LogError(ex, ex.Serialize());
|
Logger.LogError(ex, $"Error Adding Artist `{ artist }`, Ex [{ ex.Serialize() }]");
|
||||||
}
|
}
|
||||||
return new OperationResult<Artist>
|
return new OperationResult<Artist>
|
||||||
{
|
{
|
||||||
|
|
|
@ -110,42 +110,36 @@ namespace Roadie.Library.Engines
|
||||||
if (inserted > 0 && release.Id > 0)
|
if (inserted > 0 && release.Id > 0)
|
||||||
{
|
{
|
||||||
_addedReleaseIds.Add(release.Id);
|
_addedReleaseIds.Add(release.Id);
|
||||||
if (releaseGenreTables != null && releaseGenreTables.Any(x => x.GenreId == null))
|
if (releaseGenreTables != null)
|
||||||
{
|
{
|
||||||
var addedGenreIds = new List<int>();
|
foreach (var releaseGenreTable in releaseGenreTables.Select(x => x.Genre?.Name).Distinct())
|
||||||
foreach (var releaseGenreTable in releaseGenreTables)
|
|
||||||
{
|
{
|
||||||
var genreName = releaseGenreTable.Genre?.Name?.ToAlphanumericName();
|
var genreName = releaseGenreTable.ToAlphanumericName().ToTitleCase();
|
||||||
|
var normalizedName = genreName.ToUpper();
|
||||||
if (string.IsNullOrEmpty(genreName)) continue;
|
if (string.IsNullOrEmpty(genreName)) continue;
|
||||||
if (releaseGenreTable.Genre.Name.Length > 100)
|
if (genreName.Length > 100)
|
||||||
{
|
{
|
||||||
var originalName = releaseGenreTable.Genre.Name;
|
var originalName = genreName;
|
||||||
releaseGenreTable.Genre.Name = releaseGenreTable.Genre.Name.Substring(0, 99);
|
|
||||||
genreName = genreName.Substring(0, 99);
|
genreName = genreName.Substring(0, 99);
|
||||||
Logger.LogWarning($"Genre Name Too long was [{originalName}] truncated to [{releaseGenreTable.Genre.Name}]");
|
Logger.LogWarning($"Genre Name Too long was [{originalName}] truncated to [{genreName}]");
|
||||||
}
|
}
|
||||||
var genre = DbContext.Genres.FirstOrDefault(x => x.NormalizedName == genreName);
|
var genre = DbContext.Genres.FirstOrDefault(x => x.NormalizedName == normalizedName);
|
||||||
if (genre == null)
|
if (genre == null)
|
||||||
{
|
{
|
||||||
genre = new Genre
|
genre = new Genre
|
||||||
{
|
{
|
||||||
Name = releaseGenreTable.Genre.Name,
|
Name = genreName,
|
||||||
NormalizedName = genreName
|
NormalizedName = normalizedName
|
||||||
};
|
};
|
||||||
DbContext.Genres.Add(genre);
|
DbContext.Genres.Add(genre);
|
||||||
await DbContext.SaveChangesAsync();
|
await DbContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
if (genre != null &&
|
DbContext.ReleaseGenres.Add(new ReleaseGenre
|
||||||
genre.Id > 0 &&
|
|
||||||
!addedGenreIds.Any(x => x == genre.Id))
|
|
||||||
{
|
{
|
||||||
DbContext.ReleaseGenres.Add(new ReleaseGenre
|
ReleaseId = release.Id,
|
||||||
{
|
GenreId = genre.Id
|
||||||
ReleaseId = release.Id,
|
});
|
||||||
GenreId = genre.Id
|
await DbContext.SaveChangesAsync();
|
||||||
});
|
|
||||||
addedGenreIds.Add(genre.Id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,32 +358,6 @@ namespace Roadie.Library.Engines
|
||||||
|
|
||||||
var release = DatabaseQueryForReleaseTitle(artist, metaData.Release);
|
var release = DatabaseQueryForReleaseTitle(artist, metaData.Release);
|
||||||
|
|
||||||
//var searchName = metaData.Release.NormalizeName().ToLower();
|
|
||||||
//var specialSearchName = metaData.Release.ToAlphanumericName();
|
|
||||||
|
|
||||||
//var altStart = $"{searchName}|";
|
|
||||||
//var altIn = $"|{searchName}|";
|
|
||||||
//var altEnds = $"|{searchName}";
|
|
||||||
|
|
||||||
//var altStartSpecial = $"{specialSearchName}|";
|
|
||||||
//var altInSpecial = $"|{specialSearchName}|";
|
|
||||||
//var altEndsSpecial = $"|{specialSearchName}";
|
|
||||||
|
|
||||||
//var release = (from r in DbContext.Releases
|
|
||||||
// where r.ArtistId == artist.Id
|
|
||||||
// where r.Title == searchName ||
|
|
||||||
// r.Title == specialSearchName ||
|
|
||||||
// r.AlternateNames == searchName ||
|
|
||||||
// r.AlternateNames == specialSearchName ||
|
|
||||||
// r.AlternateNames.Contains(altStart) ||
|
|
||||||
// r.AlternateNames.Contains(altIn) ||
|
|
||||||
// r.AlternateNames.Contains(altEnds) ||
|
|
||||||
// r.AlternateNames.Contains(altStartSpecial) ||
|
|
||||||
// r.AlternateNames.Contains(altInSpecial) ||
|
|
||||||
// r.AlternateNames.Contains(altEndsSpecial)
|
|
||||||
// select r
|
|
||||||
// ).FirstOrDefault();
|
|
||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
if (release == null || !release.IsValid)
|
if (release == null || !release.IsValid)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
|
|
||||||
namespace Roadie.Library.Identity
|
|
||||||
{
|
|
||||||
[Table("userrole")]
|
|
||||||
public class ApplicationRole : IdentityRole<int>
|
|
||||||
{
|
|
||||||
[Column("createdDate")] public DateTime? CreatedDate { get; set; }
|
|
||||||
|
|
||||||
[Column("description")]
|
|
||||||
[StringLength(200)]
|
|
||||||
public string Description { get; set; }
|
|
||||||
|
|
||||||
//[Column("id")]
|
|
||||||
//[Key]
|
|
||||||
//public override int Id { get; set; }
|
|
||||||
|
|
||||||
[Column("isLocked")] public bool? IsLocked { get; set; }
|
|
||||||
|
|
||||||
[Column("lastUpdated")] public DateTime? LastUpdated { get; set; }
|
|
||||||
|
|
||||||
[Column("name")]
|
|
||||||
[Required]
|
|
||||||
[StringLength(80)]
|
|
||||||
public override string Name { get; set; }
|
|
||||||
|
|
||||||
[Column("RoadieId")]
|
|
||||||
[StringLength(36)]
|
|
||||||
public string RoadieId { get; set; }
|
|
||||||
|
|
||||||
public virtual ICollection<ApplicationRoleClaim> RoleClaims { get; set; }
|
|
||||||
|
|
||||||
[Column("status")] public short? Status { get; set; }
|
|
||||||
|
|
||||||
public virtual ICollection<ApplicationUserRole> UserRoles { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
|
|
||||||
namespace Roadie.Library.Identity
|
|
||||||
{
|
|
||||||
[Table("userRoleClaims")]
|
|
||||||
public class ApplicationRoleClaim : IdentityRoleClaim<int>
|
|
||||||
{
|
|
||||||
public virtual ApplicationRole Role { get; set; }
|
|
||||||
|
|
||||||
[Column("userRoleId")] public override int RoleId { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,135 +0,0 @@
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using Roadie.Library.Data;
|
|
||||||
using Roadie.Library.Enums;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
|
|
||||||
namespace Roadie.Library.Identity
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Application User for Identity
|
|
||||||
/// <remarks>
|
|
||||||
/// As this is used by UserManager to get for each request in API *do not* lazy load properties as the object
|
|
||||||
/// is too heavy and requires multiple DB hits to poplate - which is data not needed to authenticate a user.
|
|
||||||
/// </remarks>
|
|
||||||
/// </summary>
|
|
||||||
[Table("user")]
|
|
||||||
public partial class ApplicationUser : IdentityUser<int>
|
|
||||||
{
|
|
||||||
[Column("apiToken")]
|
|
||||||
[StringLength(100)]
|
|
||||||
public string ApiToken { get; set; }
|
|
||||||
|
|
||||||
public ICollection<UserArtist> ArtistRatings { get; set; }
|
|
||||||
|
|
||||||
[Obsolete("Images moved to file system")]
|
|
||||||
[Column("avatar", TypeName = "blob")]
|
|
||||||
public byte[] Avatar { get; set; }
|
|
||||||
|
|
||||||
public ICollection<Bookmark> Bookmarks { get; set; }
|
|
||||||
|
|
||||||
public ICollection<ApplicationUserClaim> Claims { get; set; }
|
|
||||||
|
|
||||||
public ICollection<Comment> Comments { get; set; }
|
|
||||||
[Column("createdDate")] public DateTime? CreatedDate { get; set; }
|
|
||||||
|
|
||||||
[Column("doUseHtmlPlayer")] public bool? DoUseHtmlPlayer { get; set; }
|
|
||||||
|
|
||||||
[Column("email")]
|
|
||||||
[Required]
|
|
||||||
[StringLength(100)]
|
|
||||||
public override string Email { get; set; }
|
|
||||||
|
|
||||||
[Column("ftpDirectory")]
|
|
||||||
[StringLength(500)]
|
|
||||||
public string FtpDirectory { get; set; }
|
|
||||||
|
|
||||||
[Column("ftpPassword")]
|
|
||||||
[StringLength(500)]
|
|
||||||
public string FtpPassword { get; set; }
|
|
||||||
|
|
||||||
[Column("ftpUrl")] [StringLength(250)] public string FtpUrl { get; set; }
|
|
||||||
|
|
||||||
[Column("ftpUsername")]
|
|
||||||
[StringLength(50)]
|
|
||||||
public string FtpUsername { get; set; }
|
|
||||||
|
|
||||||
[Column("id")] [Key] public override int Id { get; set; }
|
|
||||||
|
|
||||||
[Column("isActive")] public bool? IsActive { get; set; }
|
|
||||||
|
|
||||||
[Column("isLocked")] public bool? IsLocked { get; set; }
|
|
||||||
|
|
||||||
[Column("isPrivate")] public bool? IsPrivate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is the last time a user access Roadie via an API (ie Subsonic or Plex or Apache)
|
|
||||||
/// </summary>
|
|
||||||
[Column("lastApiAccess")]
|
|
||||||
public DateTime? LastApiAccess { get; set; }
|
|
||||||
|
|
||||||
[Column("lastFMSessionKey")]
|
|
||||||
[StringLength(50)]
|
|
||||||
public string LastFMSessionKey { get; set; }
|
|
||||||
|
|
||||||
[Column("lastLogin")] public DateTime? LastLogin { get; set; }
|
|
||||||
|
|
||||||
[Column("lastUpdated")] public DateTime? LastUpdated { get; set; }
|
|
||||||
|
|
||||||
[Column("password")]
|
|
||||||
[Required]
|
|
||||||
[StringLength(100)]
|
|
||||||
public override string PasswordHash { get; set; }
|
|
||||||
|
|
||||||
[Column("playerTrackLimit")] public short? PlayerTrackLimit { get; set; }
|
|
||||||
|
|
||||||
public ICollection<Playlist> Playlists { get; set; }
|
|
||||||
|
|
||||||
[Column("profile", TypeName = "text")]
|
|
||||||
[StringLength(65535)]
|
|
||||||
public string Profile { get; set; }
|
|
||||||
|
|
||||||
[Column("randomReleaseLimit")] public short? RandomReleaseLimit { get; set; }
|
|
||||||
|
|
||||||
[Column("recentlyPlayedLimit")] public short? RecentlyPlayedLimit { get; set; }
|
|
||||||
|
|
||||||
[Column("registeredOn")] public DateTime? RegisteredOn { get; set; }
|
|
||||||
|
|
||||||
public ICollection<UserRelease> ReleaseRatings { get; set; }
|
|
||||||
|
|
||||||
[Column("removeTrackFromQueAfterPlayed")]
|
|
||||||
public bool? RemoveTrackFromQueAfterPlayed { get; set; }
|
|
||||||
|
|
||||||
public ICollection<Request> Requests { get; set; }
|
|
||||||
|
|
||||||
[Column("RoadieId")]
|
|
||||||
[StringLength(36)]
|
|
||||||
public Guid RoadieId { get; set; }
|
|
||||||
|
|
||||||
[Column("status")] public Statuses? Status { get; set; }
|
|
||||||
|
|
||||||
public ICollection<Submission> Submissions { get; set; }
|
|
||||||
|
|
||||||
[Column("timeformat")]
|
|
||||||
[StringLength(50)]
|
|
||||||
public string Timeformat { get; set; }
|
|
||||||
|
|
||||||
[Column("timezone")]
|
|
||||||
[StringLength(50)]
|
|
||||||
public string Timezone { get; set; }
|
|
||||||
|
|
||||||
[Column("defaultRowsPerPage")]
|
|
||||||
public short? DefaultRowsPerPage { get; set; }
|
|
||||||
|
|
||||||
public ICollection<UserTrack> TrackRatings { get; set; }
|
|
||||||
public ICollection<UserQue> UserQues { get; set; }
|
|
||||||
|
|
||||||
public ICollection<ApplicationUserRole> UserRoles { get; set; }
|
|
||||||
|
|
||||||
//public ICollection<ChatMessage> ChatMessages { get; set; }
|
|
||||||
//public ICollection<Collection> Collections { get; set; }
|
|
||||||
//public ICollection<Submission> Submission { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
|
|
||||||
namespace Roadie.Library.Identity
|
|
||||||
{
|
|
||||||
[Table("userClaims")]
|
|
||||||
public class ApplicationUserClaim : IdentityUserClaim<int>
|
|
||||||
{
|
|
||||||
public virtual ApplicationUser User { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,9 +5,9 @@ using Microsoft.EntityFrameworkCore;
|
||||||
namespace Roadie.Library.Identity
|
namespace Roadie.Library.Identity
|
||||||
{
|
{
|
||||||
public class ApplicationUserDbContext : IdentityDbContext<
|
public class ApplicationUserDbContext : IdentityDbContext<
|
||||||
ApplicationUser, ApplicationRole, int,
|
User, UserRole, int,
|
||||||
ApplicationUserClaim, ApplicationUserRole, IdentityUserLogin<int>,
|
UserClaims, UsersInRoles, IdentityUserLogin<int>,
|
||||||
ApplicationRoleClaim, IdentityUserToken<int>>
|
UserRoleClaims, IdentityUserToken<int>>
|
||||||
{
|
{
|
||||||
public ApplicationUserDbContext(DbContextOptions<ApplicationUserDbContext> options)
|
public ApplicationUserDbContext(DbContextOptions<ApplicationUserDbContext> options)
|
||||||
: base(options)
|
: base(options)
|
||||||
|
@ -18,46 +18,59 @@ namespace Roadie.Library.Identity
|
||||||
{
|
{
|
||||||
base.OnModelCreating(builder);
|
base.OnModelCreating(builder);
|
||||||
|
|
||||||
builder.Entity<ApplicationUser>(b =>
|
// The tables are setup in RoadieDBContext but the table mappings below are necessary for IdentityDbContext to work.
|
||||||
|
|
||||||
|
builder.Entity<User>(entity =>
|
||||||
{
|
{
|
||||||
b.ToTable("user");
|
entity.ToTable("user");
|
||||||
|
|
||||||
// Each User can have many UserClaims
|
// Each User can have many UserClaims
|
||||||
b.HasMany(e => e.Claims)
|
entity.HasMany(e => e.UserClaims)
|
||||||
.WithOne(e => e.User)
|
.WithOne(e => e.User)
|
||||||
.HasForeignKey(uc => uc.UserId)
|
.HasForeignKey(uc => uc.Id)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
// Each User can have many entries in the UserRole join table
|
// Each User can have many entries in the UserRole join table
|
||||||
b.HasMany(e => e.UserRoles)
|
entity.HasMany(e => e.UserRoles)
|
||||||
.WithOne(e => e.User)
|
.WithOne(e => e.User)
|
||||||
.HasForeignKey(ur => ur.UserId)
|
.HasForeignKey(ur => ur.UserId)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Entity<ApplicationRole>(b =>
|
builder.Entity<UserClaims>(entity =>
|
||||||
{
|
{
|
||||||
b.ToTable("userrole");
|
entity.ToTable("userClaims");
|
||||||
b.HasKey(ar => ar.Id);
|
});
|
||||||
|
|
||||||
|
builder.Entity<UserRoleClaims>(entity =>
|
||||||
|
{
|
||||||
|
entity.ToTable("userRoleClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<UserRole>(entity =>
|
||||||
|
{
|
||||||
|
entity.ToTable("userrole");
|
||||||
|
entity.HasKey(ar => ar.Id);
|
||||||
|
|
||||||
// Each Role can have many entries in the UserRole join table
|
// Each Role can have many entries in the UserRole join table
|
||||||
b.HasMany(e => e.UserRoles)
|
entity.HasMany(e => e.UserRoles)
|
||||||
.WithOne(e => e.Role)
|
.WithOne(e => e.Role)
|
||||||
.HasForeignKey(ur => ur.RoleId)
|
.HasForeignKey(ur => ur.RoleId)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
// Each Role can have many associated RoleClaims
|
// Each Role can have many associated RoleClaims
|
||||||
b.HasMany(e => e.RoleClaims)
|
entity.HasMany(e => e.RoleClaims)
|
||||||
.WithOne(e => e.Role)
|
.WithOne(e => e.UserRole)
|
||||||
.HasForeignKey(rc => rc.RoleId)
|
.HasForeignKey(rc => rc.RoleId)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Entity<ApplicationUserClaim>(b => { b.ToTable("userClaims"); });
|
builder.Entity<UsersInRoles>(entity =>
|
||||||
|
{
|
||||||
builder.Entity<ApplicationUserRole>(b => { b.ToTable("usersInRoles"); });
|
entity.ToTable("usersInRoles");
|
||||||
|
});
|
||||||
builder.Entity<ApplicationRoleClaim>(b => { b.ToTable("userRoleClaims"); });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,18 +0,0 @@
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
|
|
||||||
namespace Roadie.Library.Identity
|
|
||||||
{
|
|
||||||
[Table("usersInRoles")]
|
|
||||||
public class ApplicationUserRole : IdentityUserRole<int>
|
|
||||||
{
|
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
|
||||||
public int Id { get; set; }
|
|
||||||
|
|
||||||
public virtual ApplicationRole Role { get; set; }
|
|
||||||
|
|
||||||
[Column("userRoleId")] public override int RoleId { get; set; }
|
|
||||||
|
|
||||||
public virtual ApplicationUser User { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
168
Roadie.Api.Library/Identity/User.cs
Normal file
168
Roadie.Api.Library/Identity/User.cs
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Roadie.Library.Data;
|
||||||
|
using Roadie.Library.Enums;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Roadie.Library.Identity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Application User for Identity
|
||||||
|
/// <remarks>
|
||||||
|
/// As this is used by UserManager to get for each request in API *do not* lazy load properties as the object
|
||||||
|
/// is too heavy and requires multiple DB hits to poplate - which is data not needed to authenticate a user.
|
||||||
|
/// </remarks>
|
||||||
|
/// </summary>
|
||||||
|
[Table("user")]
|
||||||
|
public partial class User : IdentityUser<int>
|
||||||
|
{
|
||||||
|
[Column("id")]
|
||||||
|
[Key]
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
public override int Id { get; set; }
|
||||||
|
|
||||||
|
[Column("apiToken")]
|
||||||
|
[StringLength(100)]
|
||||||
|
public string ApiToken { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("User")]
|
||||||
|
public virtual ICollection<UserArtist> ArtistRatings { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("User")]
|
||||||
|
public virtual ICollection<Bookmark> Bookmarks { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("User")]
|
||||||
|
public virtual ICollection<ChatMessage> ChatMessages { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("User")]
|
||||||
|
public virtual ICollection<UserClaims> UserClaims { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("Maintainer")]
|
||||||
|
public virtual ICollection<Collection> Collections { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("User")]
|
||||||
|
public virtual ICollection<Comment> Comments { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("User")]
|
||||||
|
public virtual ICollection<Data.CommentReaction> CommentReactions { get; set; }
|
||||||
|
|
||||||
|
[Column("createdDate")]
|
||||||
|
public DateTime? CreatedDate { get; set; }
|
||||||
|
|
||||||
|
[Column("doUseHtmlPlayer")]
|
||||||
|
public bool? DoUseHtmlPlayer { get; set; }
|
||||||
|
|
||||||
|
[Column("email")]
|
||||||
|
[Required]
|
||||||
|
[StringLength(100)]
|
||||||
|
public override string Email { get; set; }
|
||||||
|
|
||||||
|
[Column("ftpDirectory")]
|
||||||
|
[StringLength(500)]
|
||||||
|
public string FtpDirectory { get; set; }
|
||||||
|
|
||||||
|
[Column("ftpPassword")]
|
||||||
|
[StringLength(500)]
|
||||||
|
public string FtpPassword { get; set; }
|
||||||
|
|
||||||
|
[Column("ftpUrl")]
|
||||||
|
[StringLength(250)]
|
||||||
|
public string FtpUrl { get; set; }
|
||||||
|
|
||||||
|
[Column("ftpUsername")]
|
||||||
|
[StringLength(50)]
|
||||||
|
public string FtpUsername { get; set; }
|
||||||
|
|
||||||
|
[Column("isActive")]
|
||||||
|
public bool? IsActive { get; set; }
|
||||||
|
|
||||||
|
[Column("isLocked")]
|
||||||
|
public bool? IsLocked { get; set; }
|
||||||
|
|
||||||
|
[Column("isPrivate")]
|
||||||
|
public bool? IsPrivate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is the last time a user access Roadie via an API (ie Subsonic or Plex or Apache)
|
||||||
|
/// </summary>
|
||||||
|
[Column("lastApiAccess")]
|
||||||
|
public DateTime? LastApiAccess { get; set; }
|
||||||
|
|
||||||
|
[Column("lastFMSessionKey")]
|
||||||
|
[StringLength(50)]
|
||||||
|
public string LastFMSessionKey { get; set; }
|
||||||
|
|
||||||
|
[Column("lastLogin")]
|
||||||
|
public DateTime? LastLogin { get; set; }
|
||||||
|
|
||||||
|
[Column("lastUpdated")]
|
||||||
|
public DateTime? LastUpdated { get; set; }
|
||||||
|
|
||||||
|
[Column("password")]
|
||||||
|
[Required]
|
||||||
|
[StringLength(100)]
|
||||||
|
public override string PasswordHash { get; set; }
|
||||||
|
|
||||||
|
[Column("playerTrackLimit")]
|
||||||
|
public short? PlayerTrackLimit { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<Playlist> Playlists { get; set; }
|
||||||
|
|
||||||
|
[Column("profile", TypeName = "text")]
|
||||||
|
[StringLength(65535)]
|
||||||
|
public string Profile { get; set; }
|
||||||
|
|
||||||
|
[Column("randomReleaseLimit")]
|
||||||
|
public short? RandomReleaseLimit { get; set; }
|
||||||
|
|
||||||
|
[Column("recentlyPlayedLimit")]
|
||||||
|
public short? RecentlyPlayedLimit { get; set; }
|
||||||
|
|
||||||
|
[Column("registeredOn")]
|
||||||
|
public DateTime? RegisteredOn { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("User")]
|
||||||
|
public virtual ICollection<UserRelease> UserReleases { get; set; }
|
||||||
|
|
||||||
|
[Column("removeTrackFromQueAfterPlayed")]
|
||||||
|
public bool? RemoveTrackFromQueAfterPlayed { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("CreatedByUser")]
|
||||||
|
public virtual ICollection<InviteToken> InviteTokens { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("User")]
|
||||||
|
public virtual ICollection<Request> Requests { get; set; }
|
||||||
|
|
||||||
|
[Column("RoadieId")]
|
||||||
|
[StringLength(36)]
|
||||||
|
public Guid RoadieId { get; set; }
|
||||||
|
|
||||||
|
[Column("status")]
|
||||||
|
public Statuses? Status { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("User")]
|
||||||
|
public virtual ICollection<Submission> Submissions { get; set; }
|
||||||
|
|
||||||
|
[Column("timeformat")]
|
||||||
|
[StringLength(50)]
|
||||||
|
public string Timeformat { get; set; }
|
||||||
|
|
||||||
|
[Column("timezone")]
|
||||||
|
[StringLength(50)]
|
||||||
|
public string Timezone { get; set; }
|
||||||
|
|
||||||
|
[Column("defaultRowsPerPage")]
|
||||||
|
public short? DefaultRowsPerPage { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("User")]
|
||||||
|
public virtual ICollection<UserTrack> UserTracks { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("User")]
|
||||||
|
public virtual ICollection<UserQue> UserQues { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("User")]
|
||||||
|
public virtual ICollection<UsersInRoles> UserRoles { get; set; }
|
||||||
|
}
|
||||||
|
}
|
33
Roadie.Api.Library/Identity/UserClaims.cs
Normal file
33
Roadie.Api.Library/Identity/UserClaims.cs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Roadie.Library.Identity
|
||||||
|
{
|
||||||
|
[Table("userClaims")]
|
||||||
|
public class UserClaims : IdentityUserClaim<int>
|
||||||
|
{
|
||||||
|
[Column("id")]
|
||||||
|
[Key]
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
public override int Id { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[Column("userId")]
|
||||||
|
public override int UserId { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[Column("claimType")]
|
||||||
|
[StringLength(200)]
|
||||||
|
public override string ClaimType { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[Column("claimValue")]
|
||||||
|
[StringLength(200)]
|
||||||
|
public override string ClaimValue { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(UserId))]
|
||||||
|
[InverseProperty("UserClaims")]
|
||||||
|
public virtual User User { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,12 +4,11 @@ using Roadie.Library.Enums;
|
||||||
using Roadie.Library.Extensions;
|
using Roadie.Library.Extensions;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Roadie.Library.Identity
|
namespace Roadie.Library.Identity
|
||||||
{
|
{
|
||||||
public partial class ApplicationUser
|
public partial class User
|
||||||
{
|
{
|
||||||
public string CacheKey => CacheUrn(RoadieId);
|
public string CacheKey => CacheUrn(RoadieId);
|
||||||
|
|
||||||
|
@ -30,7 +29,7 @@ namespace Roadie.Library.Identity
|
||||||
return Path.Combine(folder, $"{ UserName.ToFileNameFriendly() } [{ Id }].gif");
|
return Path.Combine(folder, $"{ UserName.ToFileNameFriendly() } [{ Id }].gif");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApplicationUser()
|
public User()
|
||||||
{
|
{
|
||||||
RoadieId = Guid.NewGuid();
|
RoadieId = Guid.NewGuid();
|
||||||
Status = Statuses.Ok;
|
Status = Statuses.Ok;
|
||||||
|
@ -45,16 +44,20 @@ namespace Roadie.Library.Identity
|
||||||
RecentlyPlayedLimit = 20;
|
RecentlyPlayedLimit = 20;
|
||||||
RandomReleaseLimit = 20;
|
RandomReleaseLimit = 20;
|
||||||
|
|
||||||
// Collections = new HashSet<Collection>();
|
ArtistRatings = new HashSet<UserArtist>();
|
||||||
|
Bookmarks = new HashSet<Bookmark>();
|
||||||
|
Collections = new HashSet<Collection>();
|
||||||
|
Comments = new HashSet<Comment>();
|
||||||
Playlists = new HashSet<Playlist>();
|
Playlists = new HashSet<Playlist>();
|
||||||
UserRoles = new HashSet<ApplicationUserRole>();
|
CommentReactions = new HashSet<Data.CommentReaction>();
|
||||||
|
InviteTokens = new HashSet<InviteToken>();
|
||||||
|
UserReleases = new HashSet<UserRelease>();
|
||||||
Requests = new HashSet<Request>();
|
Requests = new HashSet<Request>();
|
||||||
Submissions = new HashSet<Submission>();
|
Submissions = new HashSet<Submission>();
|
||||||
|
UserTracks = new HashSet<UserTrack>();
|
||||||
|
UserClaims = new HashSet<UserClaims>();
|
||||||
UserQues = new HashSet<UserQue>();
|
UserQues = new HashSet<UserQue>();
|
||||||
ArtistRatings = new HashSet<UserArtist>();
|
UserRoles = new HashSet<UsersInRoles>();
|
||||||
ReleaseRatings = new HashSet<UserRelease>();
|
|
||||||
TrackRatings = new HashSet<UserTrack>();
|
|
||||||
Comments = new HashSet<Comment>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string CacheRegionUrn(Guid Id)
|
public static string CacheRegionUrn(Guid Id)
|
51
Roadie.Api.Library/Identity/UserRole.cs
Normal file
51
Roadie.Api.Library/Identity/UserRole.cs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Roadie.Library.Identity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Definition of a User Role
|
||||||
|
/// </summary>
|
||||||
|
[Table("userrole")]
|
||||||
|
public class UserRole : IdentityRole<int>
|
||||||
|
{
|
||||||
|
[Column("id")]
|
||||||
|
[Key]
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
public override int Id { get; set; }
|
||||||
|
|
||||||
|
[Column("createdDate")]
|
||||||
|
public DateTime? CreatedDate { get; set; }
|
||||||
|
|
||||||
|
[Column("description")]
|
||||||
|
[StringLength(200)]
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
[Column("isLocked")]
|
||||||
|
public bool? IsLocked { get; set; }
|
||||||
|
|
||||||
|
[Column("lastUpdated")]
|
||||||
|
public DateTime? LastUpdated { get; set; }
|
||||||
|
|
||||||
|
[Column("name")]
|
||||||
|
[Required]
|
||||||
|
[StringLength(80)]
|
||||||
|
public override string Name { get; set; }
|
||||||
|
|
||||||
|
[Column("RoadieId")]
|
||||||
|
[StringLength(36)]
|
||||||
|
public string RoadieId { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("UserRole")]
|
||||||
|
public virtual ICollection<UserRoleClaims> RoleClaims { get; set; }
|
||||||
|
|
||||||
|
[Column("status")]
|
||||||
|
public short? Status { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("Role")]
|
||||||
|
public virtual ICollection<UsersInRoles> UserRoles { get; set; }
|
||||||
|
}
|
||||||
|
}
|
30
Roadie.Api.Library/Identity/UserRoleClaims.cs
Normal file
30
Roadie.Api.Library/Identity/UserRoleClaims.cs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Roadie.Library.Identity
|
||||||
|
{
|
||||||
|
[Table("userRoleClaims")]
|
||||||
|
public class UserRoleClaims : IdentityRoleClaim<int>
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
[Column("id")]
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
public override int Id { get; set; }
|
||||||
|
|
||||||
|
[Column("userRoleId")]
|
||||||
|
public override int RoleId { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[Column("claimType", TypeName = "varchar(200)")]
|
||||||
|
public new string ClaimType { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[Column("claimValue", TypeName = "varchar(200)")]
|
||||||
|
public new string ClaimValue { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(RoleId))]
|
||||||
|
[InverseProperty("RoleClaims")]
|
||||||
|
public virtual UserRole UserRole { get; set; }
|
||||||
|
}
|
||||||
|
}
|
34
Roadie.Api.Library/Identity/UsersInRoles.cs
Normal file
34
Roadie.Api.Library/Identity/UsersInRoles.cs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Roadie.Library.Identity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Users In Roles
|
||||||
|
/// </summary>
|
||||||
|
[Table("usersInRoles")]
|
||||||
|
public class UsersInRoles : IdentityUserRole<int>
|
||||||
|
{
|
||||||
|
[Column("id")]
|
||||||
|
[Key]
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(RoleId))]
|
||||||
|
[InverseProperty("UserRoles")]
|
||||||
|
public virtual UserRole Role { get; set; }
|
||||||
|
|
||||||
|
[Column("userRoleId")]
|
||||||
|
[Required]
|
||||||
|
public override int RoleId { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(UserId))]
|
||||||
|
[InverseProperty("UserRoles")]
|
||||||
|
public virtual User User { get; set; }
|
||||||
|
|
||||||
|
[Column("userId")]
|
||||||
|
[Required]
|
||||||
|
public override int UserId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
using Roadie.Library.Enums;
|
using Roadie.Library.Enums;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Roadie.Library.Imaging
|
namespace Roadie.Library.Imaging
|
||||||
|
@ -25,7 +26,15 @@ namespace Roadie.Library.Imaging
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return ImageHasher.AverageHash(Bytes).ToString();
|
try
|
||||||
|
{
|
||||||
|
return ImageHasher.AverageHash(Bytes).ToString();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.WriteLine($"Error Generating Signature Ex [{ ex }]", "Warning");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Image()
|
public Image()
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace Roadie.Library.Imaging
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"Error Converting Image to Jpg [{ ex.Message }]");
|
Trace.WriteLine($"Error Converting Image to Jpg [{ ex.Message }]", "Warning");
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ namespace Roadie.Library.Imaging
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"Error Converting Image to Gif [{ ex.Message }]");
|
Trace.WriteLine($"Error Converting Image to Gif [{ ex.Message }]", "Warning");
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,7 @@ namespace Roadie.Library.Imaging
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"Error Resizing Image [{ex}]");
|
Trace.WriteLine($"Error Resizing Image [{ex}]", "Warning");
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -312,7 +312,7 @@ namespace Roadie.Library.Imaging
|
||||||
var result = ImageHelper.ResizeImage(ImageHelper.ConvertToJpegFormat(imageBytes), width, height, true)?.Item2;
|
var result = ImageHelper.ResizeImage(ImageHelper.ConvertToJpegFormat(imageBytes), width, height, true)?.Item2;
|
||||||
if (result?.Length >= ImageHelper.MaximumThumbnailByteSize)
|
if (result?.Length >= ImageHelper.MaximumThumbnailByteSize)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"Thumbnail larger than maximum size after resizing to [{configuration.ThumbnailImageSize.Width}x{configuration.ThumbnailImageSize.Height}] Thumbnail Size [{result.Length}]");
|
Trace.WriteLine($"Thumbnail larger than maximum size after resizing to [{configuration.ThumbnailImageSize.Width}x{configuration.ThumbnailImageSize.Height}] Thumbnail Size [{result.Length}]", "Warning");
|
||||||
result = new byte[0];
|
result = new byte[0];
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace Roadie.Library.Models
|
||||||
|
|
||||||
[MaxLength(65535)] public string Profile { get; set; }
|
[MaxLength(65535)] public string Profile { get; set; }
|
||||||
|
|
||||||
public decimal? Rank { get; set; }
|
public double? Rank { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Position of this Artist as ranked against other Artists (highest ranking Artist is #1)
|
/// The Position of this Artist as ranked against other Artists (highest ranking Artist is #1)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Roadie.Library.Enums;
|
using Roadie.Library.Enums;
|
||||||
using Roadie.Library.Models.Users;
|
using Roadie.Library.Models.Users;
|
||||||
|
using Roadie.Library.Utility;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
@ -15,7 +16,7 @@ namespace Roadie.Library.Models
|
||||||
public DateTime? LastPlayed { get; set; }
|
public DateTime? LastPlayed { get; set; }
|
||||||
public IEnumerable<string> MissingReleasesForCollection { get; set; }
|
public IEnumerable<string> MissingReleasesForCollection { get; set; }
|
||||||
public int? PlayedCount { get; set; }
|
public int? PlayedCount { get; set; }
|
||||||
public decimal? Rank { get; set; }
|
public double? Rank { get; set; }
|
||||||
public short? Rating { get; set; }
|
public short? Rating { get; set; }
|
||||||
public int? ReleaseCount { get; set; }
|
public int? ReleaseCount { get; set; }
|
||||||
public Image Thumbnail { get; set; }
|
public Image Thumbnail { get; set; }
|
||||||
|
@ -37,7 +38,7 @@ namespace Roadie.Library.Models
|
||||||
},
|
},
|
||||||
Thumbnail = thumbnail,
|
Thumbnail = thumbnail,
|
||||||
Rating = artist.Rating,
|
Rating = artist.Rating,
|
||||||
Rank = artist.Rank,
|
Rank = SafeParser.ToNumber<double?>(artist.Rank),
|
||||||
CreatedDate = artist.CreatedDate,
|
CreatedDate = artist.CreatedDate,
|
||||||
LastUpdated = artist.LastUpdated,
|
LastUpdated = artist.LastUpdated,
|
||||||
LastPlayed = artist.LastPlayed,
|
LastPlayed = artist.LastPlayed,
|
||||||
|
|
|
@ -19,7 +19,10 @@ namespace Roadie.Library.Models.Playlists
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!Duration.HasValue) return "--:--";
|
if (!Duration.HasValue)
|
||||||
|
{
|
||||||
|
return "--:--";
|
||||||
|
}
|
||||||
return new TimeInfo(Duration.Value).ToFullFormattedString();
|
return new TimeInfo(Duration.Value).ToFullFormattedString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace Roadie.Library.Models.Playlists
|
||||||
public DataToken User { get; set; }
|
public DataToken User { get; set; }
|
||||||
public Image UserThumbnail { get; set; }
|
public Image UserThumbnail { get; set; }
|
||||||
|
|
||||||
public static PlaylistList FromDataPlaylist(Data.Playlist playlist, ApplicationUser user, Image playlistThumbnail, Image userThumbnail)
|
public static PlaylistList FromDataPlaylist(Data.Playlist playlist, User user, Image playlistThumbnail, Image userThumbnail)
|
||||||
{
|
{
|
||||||
return new PlaylistList
|
return new PlaylistList
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace Roadie.Library.Models.Releases
|
||||||
|
|
||||||
[MaxLength(65535)] public string Profile { get; set; }
|
[MaxLength(65535)] public string Profile { get; set; }
|
||||||
|
|
||||||
public decimal? Rank { get; set; }
|
public double? Rank { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Position of this Release as ranked against other Releases (highest ranking Release is #1)
|
/// The Position of this Release as ranked against other Releases (highest ranking Release is #1)
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace Roadie.Library.Models.Releases
|
||||||
|
|
||||||
public IEnumerable<ReleaseMediaList> Media { get; set; }
|
public IEnumerable<ReleaseMediaList> Media { get; set; }
|
||||||
public int? MediaCount { get; set; }
|
public int? MediaCount { get; set; }
|
||||||
public decimal? Rank { get; set; }
|
public double? Rank { get; set; }
|
||||||
public short? Rating { get; set; }
|
public short? Rating { get; set; }
|
||||||
public DataToken Release { get; set; }
|
public DataToken Release { get; set; }
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ namespace Roadie.Library.Models.Releases
|
||||||
LibraryStatus = release.LibraryStatus,
|
LibraryStatus = release.LibraryStatus,
|
||||||
MediaCount = release.MediaCount,
|
MediaCount = release.MediaCount,
|
||||||
Rating = release.Rating,
|
Rating = release.Rating,
|
||||||
Rank = release.Rank,
|
Rank = SafeParser.ToNumber<double?>(release.Rank),
|
||||||
ReleaseDateDateTime = release.ReleaseDate,
|
ReleaseDateDateTime = release.ReleaseDate,
|
||||||
ReleasePlayUrl = $"{baseUrl}/play/release/{release.RoadieId}",
|
ReleasePlayUrl = $"{baseUrl}/play/release/{release.RoadieId}",
|
||||||
Status = release.Status,
|
Status = release.Status,
|
||||||
|
|
|
@ -4,6 +4,6 @@ namespace Roadie.Library.Models.ThirdPartyApi.Subsonic
|
||||||
{
|
{
|
||||||
public class SubsonicAuthenticateResponse : Response
|
public class SubsonicAuthenticateResponse : Response
|
||||||
{
|
{
|
||||||
public ApplicationUser User { get; set; }
|
public Identity.User SubsonicUser { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@ namespace Roadie.Library.Models.Users
|
||||||
public Image Thumbnail { get; set; }
|
public Image Thumbnail { get; set; }
|
||||||
public DataToken User { get; set; }
|
public DataToken User { get; set; }
|
||||||
|
|
||||||
public static UserList FromDataUser(ApplicationUser user, Image thumbnail)
|
public static UserList FromDataUser(Identity.User user, Image thumbnail)
|
||||||
{
|
{
|
||||||
return new UserList
|
return new UserList
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<PackageReference Include="EFCore.BulkExtensions" Version="3.0.3" />
|
<PackageReference Include="EFCore.BulkExtensions" Version="3.0.3" />
|
||||||
<PackageReference Include="FluentFTP" Version="28.0.2" />
|
<PackageReference Include="FluentFTP" Version="28.0.2" />
|
||||||
<PackageReference Include="Hashids.net" Version="1.3.0" />
|
<PackageReference Include="Hashids.net" Version="1.3.0" />
|
||||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.16" />
|
<PackageReference Include="HtmlAgilityPack" Version="1.11.17" />
|
||||||
<PackageReference Include="IdSharp.Common" Version="1.0.1" />
|
<PackageReference Include="IdSharp.Common" Version="1.0.1" />
|
||||||
<PackageReference Include="IdSharp.Tagging" Version="1.0.0-rc3" />
|
<PackageReference Include="IdSharp.Tagging" Version="1.0.0-rc3" />
|
||||||
<PackageReference Include="Inflatable.Lastfm" Version="1.1.0.339" />
|
<PackageReference Include="Inflatable.Lastfm" Version="1.1.0.339" />
|
||||||
|
@ -22,13 +22,13 @@
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.0.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.Redis" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Caching.Redis" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.1" />
|
||||||
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="1.3.0" />
|
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="1.3.0" />
|
||||||
<PackageReference Include="Microsoft.Net.Http.Headers" Version="2.2.8" />
|
<PackageReference Include="Microsoft.Net.Http.Headers" Version="2.2.8" />
|
||||||
<PackageReference Include="Microsoft.PowerShell.SDK" Version="6.2.3" />
|
<PackageReference Include="Microsoft.PowerShell.SDK" Version="6.2.3" />
|
||||||
<PackageReference Include="MimeMapping" Version="1.0.1.17" />
|
<PackageReference Include="MimeMapping" Version="1.0.1.17" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
|
||||||
<PackageReference Include="NodaTime" Version="2.4.7" />
|
<PackageReference Include="NodaTime" Version="2.4.7" />
|
||||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.0.0" />
|
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.0.0" />
|
||||||
<PackageReference Include="RestSharp" Version="106.6.10" />
|
<PackageReference Include="RestSharp" Version="106.6.10" />
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
<PackageReference Include="System.Drawing.Common" Version="4.6.1" />
|
<PackageReference Include="System.Drawing.Common" Version="4.6.1" />
|
||||||
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="4.6.0" />
|
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="4.6.0" />
|
||||||
<PackageReference Include="System.Runtime.Caching" Version="4.6.0" />
|
<PackageReference Include="System.Runtime.Caching" Version="4.6.0" />
|
||||||
<PackageReference Include="z440.atl.core" Version="2.13.0" />
|
<PackageReference Include="z440.atl.core" Version="2.14.0" />
|
||||||
<PackageReference Include="zlib.net-mutliplatform" Version="1.0.4" />
|
<PackageReference Include="zlib.net-mutliplatform" Version="1.0.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -63,13 +63,13 @@ namespace Roadie.Library.MetaData.MusicBrainz
|
||||||
var response = ex.Response as HttpWebResponse;
|
var response = ex.Response as HttpWebResponse;
|
||||||
if(response?.StatusCode == HttpStatusCode.NotFound)
|
if(response?.StatusCode == HttpStatusCode.NotFound)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"GetAsync: 404 Response For url [{ url }]");
|
Trace.WriteLine($"GetAsync: 404 Response For url [{ url }]", "Warning");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"GetAsync: [{ ex.ToString() }]");
|
Trace.WriteLine($"GetAsync: [{ ex.ToString() }]", "Warning");
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace Roadie.Library.Utility
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"Error Reading Cue [{ cueFilename }] [{ ex }]");
|
Trace.WriteLine($"Error Reading Cue [{ cueFilename }] [{ ex }]", "Error");
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ namespace Roadie.Library.Utility
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"Error Reading Sfv [{ sfvFilename }] [{ ex }]");
|
Trace.WriteLine($"Error Reading Sfv [{ sfvFilename }] [{ ex }]", "Error");
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ namespace Roadie.Library.Utility
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"Error Reading Cue [{ m3uFilename }] [{ ex }]");
|
Trace.WriteLine($"Error Reading Cue [{ m3uFilename }] [{ ex }]", "Error");
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,18 +169,6 @@ namespace Roadie.Library.Utility
|
||||||
return directoryInfo.FullName;
|
return directoryInfo.FullName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Obsolete("This is only here for migration will be removed in future release.")]
|
|
||||||
public static string ArtistPathOld(IRoadieSettings configuration, string artistSortName)
|
|
||||||
{
|
|
||||||
SimpleContract.Requires<ArgumentException>(!string.IsNullOrEmpty(artistSortName),"Invalid Artist Sort Name");
|
|
||||||
|
|
||||||
var artistFolder = artistSortName.ToTitleCase(false);
|
|
||||||
var directoryInfo = new DirectoryInfo(Path.Combine(configuration.LibraryFolder, artistFolder.ToFolderNameFriendly()));
|
|
||||||
return directoryInfo.FullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Full path to Release folder using given full Artist folder
|
/// Full path to Release folder using given full Artist folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -222,17 +210,6 @@ namespace Roadie.Library.Utility
|
||||||
return directoryInfo.FullName;
|
return directoryInfo.FullName;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("This is only here for migration will be removed in future release.")]
|
|
||||||
public static string ReleasePathOld(string artistFolder, string releaseTitle, DateTime releaseDate)
|
|
||||||
{
|
|
||||||
SimpleContract.Requires<ArgumentException>(!string.IsNullOrEmpty(artistFolder), "Invalid Artist Folder");
|
|
||||||
SimpleContract.Requires<ArgumentException>(!string.IsNullOrEmpty(releaseTitle), "Invalid Release Title");
|
|
||||||
SimpleContract.Requires<ArgumentException>(releaseDate != DateTime.MinValue, "Invalid Release Date");
|
|
||||||
|
|
||||||
var directoryInfo = new DirectoryInfo(Path.Combine(artistFolder, string.Format("{1}{0}", releaseTitle.ToTitleCase(false).ToFolderNameFriendly(), string.Format("[{0}] ", releaseDate.ToString("yyyy")))));
|
|
||||||
return directoryInfo.FullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delete any empty folders in the given folder
|
/// Delete any empty folders in the given folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -260,7 +237,7 @@ namespace Roadie.Library.Utility
|
||||||
if (!folder.GetFiles("*.*", SearchOption.AllDirectories).Any())
|
if (!folder.GetFiles("*.*", SearchOption.AllDirectories).Any())
|
||||||
{
|
{
|
||||||
folder.Delete(true);
|
folder.Delete(true);
|
||||||
Trace.WriteLine($"Deleting Empty Folder [{folder.FullName}]", "Debug");
|
Trace.WriteLine($"Deleting Empty Folder [{folder.FullName}]", "Warning");
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,24 +245,24 @@ namespace Roadie.Library.Utility
|
||||||
catch (UnauthorizedAccessException)
|
catch (UnauthorizedAccessException)
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
Trace.WriteLine($"UnauthorizedAccessException Deleting Empty Folder [{folder.FullName}]", "Debug");
|
Trace.WriteLine($"UnauthorizedAccessException Deleting Empty Folder [{folder.FullName}]", "Warning");
|
||||||
}
|
}
|
||||||
catch (DirectoryNotFoundException)
|
catch (DirectoryNotFoundException)
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
Trace.WriteLine($"DirectoryNotFoundException Deleting Empty Folder [{folder.FullName}]", "Debug");
|
Trace.WriteLine($"DirectoryNotFoundException Deleting Empty Folder [{folder.FullName}]", "Warning");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (UnauthorizedAccessException)
|
catch (UnauthorizedAccessException)
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
Trace.WriteLine($"UnauthorizedAccessException Deleting Empty Folder [{processingFolder.FullName}]", "Debug");
|
Trace.WriteLine($"UnauthorizedAccessException Deleting Empty Folder [{processingFolder.FullName}]", "Warning");
|
||||||
}
|
}
|
||||||
catch (DirectoryNotFoundException)
|
catch (DirectoryNotFoundException)
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
Trace.WriteLine($"DirectoryNotFoundException Deleting Empty Folder [{processingFolder.FullName}]", "Debug");
|
Trace.WriteLine($"DirectoryNotFoundException Deleting Empty Folder [{processingFolder.FullName}]", "Warning");
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace Roadie.Library.Utility
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Trace.WriteLine(string.Format("Error with url [{0}] Exception [{1}]", url, ex));
|
Trace.WriteLine(string.Format("Error with url [{0}] Exception [{1}]", url, ex), "Warning");
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -90,7 +90,7 @@ namespace Roadie.Library.Utility
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"GetImageFromUrlAsync Url [{ url }], Exception [{ ex.ToString() }");
|
Trace.WriteLine($"GetImageFromUrlAsync Url [{ url }], Exception [{ ex.ToString() }", "Warning");
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ namespace Roadie.Library.Utility
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Trace.WriteLine(ex.ToString());
|
Trace.WriteLine(ex.ToString(), "Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Mapster;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
@ -40,6 +41,7 @@ namespace Roadie.Api.Services
|
||||||
private ILabelService LabelService { get; }
|
private ILabelService LabelService { get; }
|
||||||
private IArtistLookupEngine ArtistLookupEngine { get; }
|
private IArtistLookupEngine ArtistLookupEngine { get; }
|
||||||
private IReleaseLookupEngine ReleaseLookupEngine { get; }
|
private IReleaseLookupEngine ReleaseLookupEngine { get; }
|
||||||
|
private IBookmarkService BookmarkService { get; }
|
||||||
|
|
||||||
private IReleaseService ReleaseService { get; }
|
private IReleaseService ReleaseService { get; }
|
||||||
|
|
||||||
|
@ -47,7 +49,7 @@ namespace Roadie.Api.Services
|
||||||
IRoadieDbContext context, ICacheManager cacheManager, ILogger<ArtistService> logger,
|
IRoadieDbContext context, ICacheManager cacheManager, ILogger<ArtistService> logger,
|
||||||
IHubContext<ScanActivityHub> scanActivityHub, IFileDirectoryProcessorService fileDirectoryProcessorService, IArtistService artistService,
|
IHubContext<ScanActivityHub> scanActivityHub, IFileDirectoryProcessorService fileDirectoryProcessorService, IArtistService artistService,
|
||||||
IReleaseService releaseService, IArtistLookupEngine artistLookupEngine, IReleaseLookupEngine releaseLookupEngine,
|
IReleaseService releaseService, IArtistLookupEngine artistLookupEngine, IReleaseLookupEngine releaseLookupEngine,
|
||||||
ILabelService labelService, IGenreService genreService
|
ILabelService labelService, IGenreService genreService, IBookmarkService bookmarkService
|
||||||
)
|
)
|
||||||
: base(configuration, httpEncoder, context, cacheManager, logger, httpContext)
|
: base(configuration, httpEncoder, context, cacheManager, logger, httpContext)
|
||||||
{
|
{
|
||||||
|
@ -62,9 +64,10 @@ namespace Roadie.Api.Services
|
||||||
ArtistLookupEngine = artistLookupEngine;
|
ArtistLookupEngine = artistLookupEngine;
|
||||||
ReleaseLookupEngine = releaseLookupEngine;
|
ReleaseLookupEngine = releaseLookupEngine;
|
||||||
FileDirectoryProcessorService = fileDirectoryProcessorService;
|
FileDirectoryProcessorService = fileDirectoryProcessorService;
|
||||||
|
BookmarkService = bookmarkService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> DeleteArtist(ApplicationUser user, Guid artistId, bool deleteFolder)
|
public async Task<OperationResult<bool>> DeleteArtist(User user, Guid artistId, bool deleteFolder)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -105,7 +108,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> DeleteArtistReleases(ApplicationUser user, Guid artistId, bool doDeleteFiles = false)
|
public async Task<OperationResult<bool>> DeleteArtistReleases(User user, Guid artistId, bool doDeleteFiles = false)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -140,7 +143,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> DeleteArtistSecondaryImage(ApplicationUser user, Guid artistId, int index)
|
public async Task<OperationResult<bool>> DeleteArtistSecondaryImage(User user, Guid artistId, int index)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -181,7 +184,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> DeleteGenre(ApplicationUser user, Guid genreId)
|
public async Task<OperationResult<bool>> DeleteGenre(User user, Guid genreId)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -205,7 +208,7 @@ namespace Roadie.Api.Services
|
||||||
errors.Add(ex);
|
errors.Add(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
await LogAndPublish($"DeleteGenre `{genre}`, By User `{user}`", LogLevel.Information);
|
await LogAndPublish($"DeleteGenre `{genre}`, By User `{user}`", LogLevel.Information);
|
||||||
return new OperationResult<bool>
|
return new OperationResult<bool>
|
||||||
{
|
{
|
||||||
|
@ -216,7 +219,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> DeleteLabel(ApplicationUser user, Guid labelId)
|
public async Task<OperationResult<bool>> DeleteLabel(User user, Guid labelId)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -251,7 +254,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> DeleteRelease(ApplicationUser user, Guid releaseId, bool? doDeleteFiles)
|
public async Task<OperationResult<bool>> DeleteRelease(User user, Guid releaseId, bool? doDeleteFiles)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -266,7 +269,6 @@ namespace Roadie.Api.Services
|
||||||
await LogAndPublish($"DeleteRelease Unknown Release [{releaseId}]", LogLevel.Warning);
|
await LogAndPublish($"DeleteRelease Unknown Release [{releaseId}]", LogLevel.Warning);
|
||||||
return new OperationResult<bool>(true, $"Release Not Found [{releaseId}]");
|
return new OperationResult<bool>(true, $"Release Not Found [{releaseId}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
await ReleaseService.Delete(user, release, doDeleteFiles ?? false);
|
await ReleaseService.Delete(user, release, doDeleteFiles ?? false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -288,7 +290,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> DeleteReleaseSecondaryImage(ApplicationUser user, Guid releaseId, int index)
|
public async Task<OperationResult<bool>> DeleteReleaseSecondaryImage(User user, Guid releaseId, int index)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -329,7 +331,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> DeleteTracks(ApplicationUser user, IEnumerable<Guid> trackIds, bool? doDeleteFile)
|
public async Task<OperationResult<bool>> DeleteTracks(User user, IEnumerable<Guid> trackIds, bool? doDeleteFile)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -376,8 +378,8 @@ namespace Roadie.Api.Services
|
||||||
Logger.LogError(ex, string.Format("Error Deleting File [{0}] For Track [{1}] Exception [{2}]", trackPath, track.Id, ex.Serialize()));
|
Logger.LogError(ex, string.Format("Error Deleting File [{0}] For Track [{1}] Exception [{2}]", trackPath, track.Id, ex.Serialize()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await ReleaseService.ScanReleaseFolder(user, track.ReleaseMedia.Release.RoadieId, false, track.ReleaseMedia.Release);
|
await ReleaseService.ScanReleaseFolder(user, track.ReleaseMedia.Release.RoadieId, false, track.ReleaseMedia.Release);
|
||||||
|
await BookmarkService.RemoveAllBookmarksForItem(BookmarkType.Track, track.Id);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -399,7 +401,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> DeleteUser(ApplicationUser applicationUser, Guid userId)
|
public async Task<OperationResult<bool>> DeleteUser(User applicationUser, Guid userId)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -452,20 +454,31 @@ namespace Roadie.Api.Services
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is a very simple way to seed the database or setup configuration when the first (who becomes "Admin") user registers
|
/// This is a very simple way to seed the database or setup configuration when the first (who becomes "Admin") user registers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<OperationResult<bool>> DoInitialSetup(ApplicationUser user, UserManager<ApplicationUser> userManager)
|
public async Task<OperationResult<bool>> DoInitialSetup(User user, UserManager<User> userManager)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
|
||||||
// Create user roles
|
// Create user roles
|
||||||
DbContext.UserRoles.Add(new ApplicationRole
|
DbContext.UserRoles.Add(new UserRole
|
||||||
{
|
{
|
||||||
|
Id = 1,
|
||||||
|
Status = (short)Statuses.Ok,
|
||||||
|
CreatedDate = DateTime.UtcNow,
|
||||||
|
IsLocked = false,
|
||||||
|
RoadieId = Guid.NewGuid().ToString(),
|
||||||
Name = "Admin",
|
Name = "Admin",
|
||||||
Description = "Users with Administrative (full) access",
|
Description = "Users with Administrative (full) access",
|
||||||
NormalizedName = "ADMIN"
|
NormalizedName = "ADMIN"
|
||||||
});
|
});
|
||||||
DbContext.UserRoles.Add(new ApplicationRole
|
|
||||||
|
DbContext.UserRoles.Add(new UserRole
|
||||||
{
|
{
|
||||||
|
Id = 2,
|
||||||
|
Status = (short)Statuses.Ok,
|
||||||
|
CreatedDate = DateTime.UtcNow,
|
||||||
|
IsLocked = false,
|
||||||
|
RoadieId = Guid.NewGuid().ToString(),
|
||||||
Name = "Editor",
|
Name = "Editor",
|
||||||
Description = "Users who have Edit Permissions",
|
Description = "Users who have Edit Permissions",
|
||||||
NormalizedName = "EDITOR"
|
NormalizedName = "EDITOR"
|
||||||
|
@ -512,7 +525,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<OperationResult<Dictionary<string, List<string>>>> MissingCollectionReleases(ApplicationUser user)
|
public Task<OperationResult<Dictionary<string, List<string>>>> MissingCollectionReleases(User user)
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -606,6 +619,14 @@ namespace Roadie.Api.Services
|
||||||
Directory.CreateDirectory(Configuration.LabelImageFolder);
|
Directory.CreateDirectory(Configuration.LabelImageFolder);
|
||||||
Logger.LogInformation($"Created Label Image Folder [{Configuration.LabelImageFolder}]");
|
Logger.LogInformation($"Created Label Image Folder [{Configuration.LabelImageFolder}]");
|
||||||
}
|
}
|
||||||
|
if (Configuration.DbContextToUse != DbContexts.MySQL)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(Configuration.FileDatabaseOptions.DatabaseFolder))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Configuration.FileDatabaseOptions.DatabaseFolder);
|
||||||
|
Logger.LogInformation($"Created File Database Folder [{Configuration.FileDatabaseOptions.DatabaseFolder}]");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -619,14 +640,14 @@ namespace Roadie.Api.Services
|
||||||
Logger.LogInformation($"Administration startup tasks completed, elapsed time [{ sw.ElapsedMilliseconds }]");
|
Logger.LogInformation($"Administration startup tasks completed, elapsed time [{ sw.ElapsedMilliseconds }]");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> ScanAllCollections(ApplicationUser user, bool isReadOnly = false,
|
public async Task<OperationResult<bool>> ScanAllCollections(User user, bool isReadOnly = false,
|
||||||
bool doPurgeFirst = false)
|
bool doPurgeFirst = false)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
var errors = new List<Exception>();
|
var errors = new List<Exception>();
|
||||||
|
|
||||||
var collections = DbContext.Collections.Where(x => x.IsLocked == false).ToArray();
|
var collections = await DbContext.Collections.Where(x => x.IsLocked == false).ToArrayAsync();
|
||||||
var updatedReleaseIds = new List<int>();
|
var updatedReleaseIds = new List<int>();
|
||||||
foreach (var collection in collections)
|
foreach (var collection in collections)
|
||||||
try
|
try
|
||||||
|
@ -659,7 +680,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> ScanArtist(ApplicationUser user, Guid artistId, bool isReadOnly = false)
|
public async Task<OperationResult<bool>> ScanArtist(User user, Guid artistId, bool isReadOnly = false)
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
|
@ -702,7 +723,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> ScanArtists(ApplicationUser user, IEnumerable<Guid> artistIds, bool isReadOnly = false)
|
public async Task<OperationResult<bool>> ScanArtists(User user, IEnumerable<Guid> artistIds, bool isReadOnly = false)
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
|
@ -728,7 +749,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> ScanCollection(ApplicationUser user, Guid collectionId, bool isReadOnly = false, bool doPurgeFirst = false, bool doUpdateRanks = true)
|
public async Task<OperationResult<bool>> ScanCollection(User user, Guid collectionId, bool isReadOnly = false, bool doPurgeFirst = false, bool doUpdateRanks = true)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -749,7 +770,7 @@ namespace Roadie.Api.Services
|
||||||
if (doPurgeFirst)
|
if (doPurgeFirst)
|
||||||
{
|
{
|
||||||
await LogAndPublish($"ScanCollection Purging Collection [{collectionId}]", LogLevel.Warning);
|
await LogAndPublish($"ScanCollection Purging Collection [{collectionId}]", LogLevel.Warning);
|
||||||
var crs = DbContext.CollectionReleases.Where(x => x.CollectionId == collection.Id).ToArray();
|
var crs = await DbContext.CollectionReleases.Where(x => x.CollectionId == collection.Id).ToArrayAsync();
|
||||||
DbContext.CollectionReleases.RemoveRange(crs);
|
DbContext.CollectionReleases.RemoveRange(crs);
|
||||||
await DbContext.SaveChangesAsync();
|
await DbContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
@ -907,19 +928,19 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> ScanInboundFolder(ApplicationUser user, bool isReadOnly = false)
|
public async Task<OperationResult<bool>> ScanInboundFolder(User user, bool isReadOnly = false)
|
||||||
{
|
{
|
||||||
var d = new DirectoryInfo(Configuration.InboundFolder);
|
var d = new DirectoryInfo(Configuration.InboundFolder);
|
||||||
return await ScanFolder(user, d, isReadOnly);
|
return await ScanFolder(user, d, isReadOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> ScanLibraryFolder(ApplicationUser user, bool isReadOnly = false)
|
public async Task<OperationResult<bool>> ScanLibraryFolder(User user, bool isReadOnly = false)
|
||||||
{
|
{
|
||||||
var d = new DirectoryInfo(Configuration.LibraryFolder);
|
var d = new DirectoryInfo(Configuration.LibraryFolder);
|
||||||
return await ScanFolder(user, d, isReadOnly, false);
|
return await ScanFolder(user, d, isReadOnly, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> ScanRelease(ApplicationUser user, Guid releaseId, bool isReadOnly = false, bool wasDoneForInvalidTrackPlay = false)
|
public async Task<OperationResult<bool>> ScanRelease(User user, Guid releaseId, bool isReadOnly = false, bool wasDoneForInvalidTrackPlay = false)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -964,7 +985,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> ScanReleases(ApplicationUser user, IEnumerable<Guid> releaseIds, bool isReadOnly = false, bool wasDoneForInvalidTrackPlay = false)
|
public async Task<OperationResult<bool>> ScanReleases(User user, IEnumerable<Guid> releaseIds, bool isReadOnly = false, bool wasDoneForInvalidTrackPlay = false)
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
|
@ -1080,7 +1101,7 @@ namespace Roadie.Api.Services
|
||||||
await ScanActivityHub.Clients.All.SendAsync("SendSystemActivity", message);
|
await ScanActivityHub.Clients.All.SendAsync("SendSystemActivity", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<OperationResult<bool>> ScanFolder(ApplicationUser user, DirectoryInfo d, bool isReadOnly, bool doDeleteFiles = true)
|
private async Task<OperationResult<bool>> ScanFolder(User user, DirectoryInfo d, bool isReadOnly, bool doDeleteFiles = true)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace Roadie.Api.Services
|
||||||
FileDirectoryProcessorService = fileDirectoryProcessorService;
|
FileDirectoryProcessorService = fileDirectoryProcessorService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<Artist>> ById(User roadieUser, Guid id, IEnumerable<string> includes)
|
public async Task<OperationResult<Artist>> ById(Library.Models.Users.User roadieUser, Guid id, IEnumerable<string> includes)
|
||||||
{
|
{
|
||||||
var timings = new Dictionary<string, long>();
|
var timings = new Dictionary<string, long>();
|
||||||
var tsw = new Stopwatch();
|
var tsw = new Stopwatch();
|
||||||
|
@ -94,11 +94,10 @@ namespace Roadie.Api.Services
|
||||||
tsw.Stop();
|
tsw.Stop();
|
||||||
timings.Add("getArtist", tsw.ElapsedMilliseconds);
|
timings.Add("getArtist", tsw.ElapsedMilliseconds);
|
||||||
tsw.Restart();
|
tsw.Restart();
|
||||||
var userBookmarkResult =
|
var userBookmarkResult = await BookmarkService.List(roadieUser, new PagedRequest(), false, BookmarkType.Artist);
|
||||||
await BookmarkService.List(roadieUser, new PagedRequest(), false, BookmarkType.Artist);
|
|
||||||
if (userBookmarkResult.IsSuccess)
|
if (userBookmarkResult.IsSuccess)
|
||||||
{
|
{
|
||||||
result.Data.UserBookmarked = userBookmarkResult?.Rows?.FirstOrDefault(x => x.Bookmark.Value == artist.RoadieId.ToString()) != null;
|
result.Data.UserBookmarked = userBookmarkResult?.Rows?.FirstOrDefault(x => x?.Bookmark?.Value == artist?.RoadieId.ToString()) != null;
|
||||||
}
|
}
|
||||||
tsw.Stop();
|
tsw.Stop();
|
||||||
timings.Add("userBookmarkResult", tsw.ElapsedMilliseconds);
|
timings.Add("userBookmarkResult", tsw.ElapsedMilliseconds);
|
||||||
|
@ -148,7 +147,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> Delete(ApplicationUser user, data.Artist artist, bool deleteFolder)
|
public async Task<OperationResult<bool>> Delete(Library.Identity.User user, data.Artist artist, bool deleteFolder)
|
||||||
{
|
{
|
||||||
var isSuccess = false;
|
var isSuccess = false;
|
||||||
try
|
try
|
||||||
|
@ -159,9 +158,25 @@ namespace Roadie.Api.Services
|
||||||
await DbContext.SaveChangesAsync();
|
await DbContext.SaveChangesAsync();
|
||||||
if(deleteFolder)
|
if(deleteFolder)
|
||||||
{
|
{
|
||||||
|
// Delete all image files for Artist
|
||||||
|
foreach (var file in ImageHelper.ImageFilesInFolder(artist.ArtistFileFolder(Configuration), SearchOption.TopDirectoryOnly))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(file);
|
||||||
|
Logger.LogWarning("For Artist [{0}], Deleted File [{1}]", artist.Id, file);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError(ex, $"Error Deleting File [{file}] Exception [{ex}]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var artistDir = new DirectoryInfo(artist.ArtistFileFolder(Configuration));
|
var artistDir = new DirectoryInfo(artist.ArtistFileFolder(Configuration));
|
||||||
FolderPathHelper.DeleteEmptyFolders(artistDir.Parent);
|
FolderPathHelper.DeleteEmptyFolders(artistDir.Parent);
|
||||||
}
|
}
|
||||||
|
await BookmarkService.RemoveAllBookmarksForItem(BookmarkType.Artist, artist.Id);
|
||||||
|
await UpdatePlaylistCountsForArtist(artist.Id, DateTime.UtcNow);
|
||||||
CacheManager.ClearRegion(artist.CacheRegion);
|
CacheManager.ClearRegion(artist.CacheRegion);
|
||||||
Logger.LogWarning("User `{0}` deleted Artist `{1}]`", user, artist);
|
Logger.LogWarning("User `{0}` deleted Artist `{1}]`", user, artist);
|
||||||
isSuccess = true;
|
isSuccess = true;
|
||||||
|
@ -183,7 +198,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Library.Models.Pagination.PagedResult<ArtistList>> List(User roadieUser, PagedRequest request, bool? doRandomize = false, bool? onlyIncludeWithReleases = true)
|
public async Task<Library.Models.Pagination.PagedResult<ArtistList>> List(Library.Models.Users.User roadieUser, PagedRequest request, bool? doRandomize = false, bool? onlyIncludeWithReleases = true)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -287,7 +302,7 @@ namespace Roadie.Api.Services
|
||||||
},
|
},
|
||||||
Thumbnail = ImageHelper.MakeArtistThumbnailImage(Configuration, HttpContext, a.RoadieId),
|
Thumbnail = ImageHelper.MakeArtistThumbnailImage(Configuration, HttpContext, a.RoadieId),
|
||||||
Rating = a.Rating,
|
Rating = a.Rating,
|
||||||
Rank = a.Rank,
|
Rank = (double?)a.Rank,
|
||||||
CreatedDate = a.CreatedDate,
|
CreatedDate = a.CreatedDate,
|
||||||
LastUpdated = a.LastUpdated,
|
LastUpdated = a.LastUpdated,
|
||||||
LastPlayed = a.LastPlayed,
|
LastPlayed = a.LastPlayed,
|
||||||
|
@ -313,7 +328,7 @@ namespace Roadie.Api.Services
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string sortBy;
|
string sortBy;
|
||||||
if (request.ActionValue == User.ActionKeyUserRated)
|
if (request.ActionValue == Library.Models.Users.User.ActionKeyUserRated)
|
||||||
{
|
{
|
||||||
sortBy = string.IsNullOrEmpty(request.Sort)
|
sortBy = string.IsNullOrEmpty(request.Sort)
|
||||||
? request.OrderValue(new Dictionary<string, string> { { "Rating", "DESC" }, { "Artist.Text", "ASC" } })
|
? request.OrderValue(new Dictionary<string, string> { { "Rating", "DESC" }, { "Artist.Text", "ASC" } })
|
||||||
|
@ -380,7 +395,7 @@ namespace Roadie.Api.Services
|
||||||
/// <param name="artistToMerge">The Artist to be merged</param>
|
/// <param name="artistToMerge">The Artist to be merged</param>
|
||||||
/// <param name="artistToMergeInto">The Artist to merge into</param>
|
/// <param name="artistToMergeInto">The Artist to merge into</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<OperationResult<bool>> MergeArtists(ApplicationUser user, Guid artistToMergeId, Guid artistToMergeIntoId)
|
public async Task<OperationResult<bool>> MergeArtists(Library.Identity.User user, Guid artistToMergeId, Guid artistToMergeIntoId)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -434,7 +449,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> RefreshArtistMetadata(ApplicationUser user, Guid artistId)
|
public async Task<OperationResult<bool>> RefreshArtistMetadata(Library.Identity.User user, Guid artistId)
|
||||||
{
|
{
|
||||||
SimpleContract.Requires<ArgumentOutOfRangeException>(artistId != Guid.Empty, "Invalid ArtistId");
|
SimpleContract.Requires<ArgumentOutOfRangeException>(artistId != Guid.Empty, "Invalid ArtistId");
|
||||||
|
|
||||||
|
@ -498,7 +513,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> ScanArtistReleasesFolders(ApplicationUser user, Guid artistId, string destinationFolder, bool doJustInfo)
|
public async Task<OperationResult<bool>> ScanArtistReleasesFolders(Library.Identity.User user, Guid artistId, string destinationFolder, bool doJustInfo)
|
||||||
{
|
{
|
||||||
SimpleContract.Requires<ArgumentOutOfRangeException>(artistId != Guid.Empty, "Invalid ArtistId");
|
SimpleContract.Requires<ArgumentOutOfRangeException>(artistId != Guid.Empty, "Invalid ArtistId");
|
||||||
|
|
||||||
|
@ -581,12 +596,12 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<Library.Models.Image>> SetReleaseImageByUrl(ApplicationUser user, Guid id, string imageUrl)
|
public async Task<OperationResult<Library.Models.Image>> SetReleaseImageByUrl(Library.Identity.User user, Guid id, string imageUrl)
|
||||||
{
|
{
|
||||||
return await SaveImageBytes(user, id, WebHelper.BytesForImageUrl(imageUrl));
|
return await SaveImageBytes(user, id, WebHelper.BytesForImageUrl(imageUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> UpdateArtist(ApplicationUser user, Artist model)
|
public async Task<OperationResult<bool>> UpdateArtist(Library.Identity.User user, Artist model)
|
||||||
{
|
{
|
||||||
var didRenameArtist = false;
|
var didRenameArtist = false;
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
|
@ -853,7 +868,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<Library.Models.Image>> UploadArtistImage(ApplicationUser user, Guid id, IFormFile file)
|
public async Task<OperationResult<Library.Models.Image>> UploadArtistImage(Library.Identity.User user, Guid id, IFormFile file)
|
||||||
{
|
{
|
||||||
var bytes = new byte[0];
|
var bytes = new byte[0];
|
||||||
using (var ms = new MemoryStream())
|
using (var ms = new MemoryStream())
|
||||||
|
@ -890,7 +905,7 @@ namespace Roadie.Api.Services
|
||||||
? null
|
? null
|
||||||
: result.BirthDate;
|
: result.BirthDate;
|
||||||
result.RankPosition = result.Rank > 0
|
result.RankPosition = result.Rank > 0
|
||||||
? SafeParser.ToNumber<int?>(DbContext.Artists.Count(x => x.Rank > result.Rank) + 1)
|
? SafeParser.ToNumber<int?>(DbContext.Artists.Count(x => (double?)x.Rank > result.Rank) + 1)
|
||||||
: null;
|
: null;
|
||||||
tsw.Stop();
|
tsw.Stop();
|
||||||
timings.Add("adapt", tsw.ElapsedMilliseconds);
|
timings.Add("adapt", tsw.ElapsedMilliseconds);
|
||||||
|
@ -1044,7 +1059,7 @@ namespace Roadie.Api.Services
|
||||||
},
|
},
|
||||||
Thumbnail = ImageHelper.MakeArtistThumbnailImage(Configuration, HttpContext, a.RoadieId),
|
Thumbnail = ImageHelper.MakeArtistThumbnailImage(Configuration, HttpContext, a.RoadieId),
|
||||||
Rating = a.Rating,
|
Rating = a.Rating,
|
||||||
Rank = a.Rank,
|
Rank = (double?)a.Rank,
|
||||||
CreatedDate = a.CreatedDate,
|
CreatedDate = a.CreatedDate,
|
||||||
LastUpdated = a.LastUpdated,
|
LastUpdated = a.LastUpdated,
|
||||||
LastPlayed = a.LastPlayed,
|
LastPlayed = a.LastPlayed,
|
||||||
|
@ -1068,7 +1083,7 @@ namespace Roadie.Api.Services
|
||||||
},
|
},
|
||||||
Thumbnail = ImageHelper.MakeArtistThumbnailImage(Configuration, HttpContext, a.RoadieId),
|
Thumbnail = ImageHelper.MakeArtistThumbnailImage(Configuration, HttpContext, a.RoadieId),
|
||||||
Rating = a.Rating,
|
Rating = a.Rating,
|
||||||
Rank = a.Rank,
|
Rank = (double?)a.Rank,
|
||||||
CreatedDate = a.CreatedDate,
|
CreatedDate = a.CreatedDate,
|
||||||
LastUpdated = a.LastUpdated,
|
LastUpdated = a.LastUpdated,
|
||||||
LastPlayed = a.LastPlayed,
|
LastPlayed = a.LastPlayed,
|
||||||
|
@ -1100,7 +1115,7 @@ namespace Roadie.Api.Services
|
||||||
},
|
},
|
||||||
Thumbnail = ImageHelper.MakeArtistThumbnailImage(Configuration, HttpContext, a.RoadieId),
|
Thumbnail = ImageHelper.MakeArtistThumbnailImage(Configuration, HttpContext, a.RoadieId),
|
||||||
Rating = a.Rating,
|
Rating = a.Rating,
|
||||||
Rank = a.Rank,
|
Rank = (double?)a.Rank,
|
||||||
CreatedDate = a.CreatedDate,
|
CreatedDate = a.CreatedDate,
|
||||||
LastUpdated = a.LastUpdated,
|
LastUpdated = a.LastUpdated,
|
||||||
LastPlayed = a.LastPlayed,
|
LastPlayed = a.LastPlayed,
|
||||||
|
@ -1124,7 +1139,7 @@ namespace Roadie.Api.Services
|
||||||
},
|
},
|
||||||
Thumbnail = ImageHelper.MakeArtistThumbnailImage(Configuration, HttpContext, a.RoadieId),
|
Thumbnail = ImageHelper.MakeArtistThumbnailImage(Configuration, HttpContext, a.RoadieId),
|
||||||
Rating = a.Rating,
|
Rating = a.Rating,
|
||||||
Rank = a.Rank,
|
Rank = (double?)a.Rank,
|
||||||
CreatedDate = a.CreatedDate,
|
CreatedDate = a.CreatedDate,
|
||||||
LastUpdated = a.LastUpdated,
|
LastUpdated = a.LastUpdated,
|
||||||
LastPlayed = a.LastPlayed,
|
LastPlayed = a.LastPlayed,
|
||||||
|
@ -1283,7 +1298,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<OperationResult<data.Artist>> MergeArtists(ApplicationUser user, data.Artist artistToMerge, data.Artist artistToMergeInto)
|
private async Task<OperationResult<data.Artist>> MergeArtists(Library.Identity.User user, data.Artist artistToMerge, data.Artist artistToMergeInto)
|
||||||
{
|
{
|
||||||
SimpleContract.Requires<ArgumentNullException>(artistToMerge != null, "Invalid Artist");
|
SimpleContract.Requires<ArgumentNullException>(artistToMerge != null, "Invalid Artist");
|
||||||
SimpleContract.Requires<ArgumentNullException>(artistToMergeInto != null, "Invalid Artist");
|
SimpleContract.Requires<ArgumentNullException>(artistToMergeInto != null, "Invalid Artist");
|
||||||
|
@ -1437,7 +1452,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<OperationResult<Library.Models.Image>> SaveImageBytes(ApplicationUser user, Guid id, byte[] imageBytes)
|
private async Task<OperationResult<Library.Models.Image>> SaveImageBytes(Library.Identity.User user, Guid id, byte[] imageBytes)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Mapster;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Roadie.Library;
|
||||||
using Roadie.Library.Caching;
|
using Roadie.Library.Caching;
|
||||||
using Roadie.Library.Configuration;
|
using Roadie.Library.Configuration;
|
||||||
using Roadie.Library.Data.Context;
|
using Roadie.Library.Data.Context;
|
||||||
|
@ -25,14 +27,41 @@ namespace Roadie.Api.Services
|
||||||
{
|
{
|
||||||
public class BookmarkService : ServiceBase, IBookmarkService
|
public class BookmarkService : ServiceBase, IBookmarkService
|
||||||
{
|
{
|
||||||
|
private IUserService UserService { get; }
|
||||||
|
|
||||||
public BookmarkService(IRoadieSettings configuration,
|
public BookmarkService(IRoadieSettings configuration,
|
||||||
IHttpEncoder httpEncoder,
|
IHttpEncoder httpEncoder,
|
||||||
IHttpContext httpContext,
|
IHttpContext httpContext,
|
||||||
IRoadieDbContext context,
|
IRoadieDbContext context,
|
||||||
ICacheManager cacheManager,
|
ICacheManager cacheManager,
|
||||||
|
IUserService userService,
|
||||||
ILogger<BookmarkService> logger)
|
ILogger<BookmarkService> logger)
|
||||||
: base(configuration, httpEncoder, context, cacheManager, logger, httpContext)
|
: base(configuration, httpEncoder, context, cacheManager, logger, httpContext)
|
||||||
{
|
{
|
||||||
|
UserService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When a bookmarkable item gets deleted then delete any bookmarks to that item, since its a generic column there is not FK setup.
|
||||||
|
/// </summary>
|
||||||
|
public async Task<OperationResult<bool>> RemoveAllBookmarksForItem(BookmarkType type, int id)
|
||||||
|
{
|
||||||
|
var bookmarks = await DbContext.Bookmarks.Include(x => x.User)
|
||||||
|
.Where(x => x.BookmarkType == type && x.BookmarkTargetId == id)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var users = bookmarks.Select(x => x.User).ToList().Distinct();
|
||||||
|
DbContext.Bookmarks.RemoveRange(bookmarks);
|
||||||
|
await DbContext.SaveChangesAsync();
|
||||||
|
foreach(var user in users)
|
||||||
|
{
|
||||||
|
CacheManager.ClearRegion(user.CacheRegion);
|
||||||
|
}
|
||||||
|
return new OperationResult<bool>
|
||||||
|
{
|
||||||
|
IsSuccess = true,
|
||||||
|
Data = true
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Library.Models.Pagination.PagedResult<models.BookmarkList>> List(User roadieUser, PagedRequest request, bool? doRandomize = false, BookmarkType? filterType = null)
|
public async Task<Library.Models.Pagination.PagedResult<models.BookmarkList>> List(User roadieUser, PagedRequest request, bool? doRandomize = false, BookmarkType? filterType = null)
|
||||||
|
|
|
@ -77,8 +77,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<Collection>> ById(User roadieUser, Guid id,
|
public async Task<OperationResult<Collection>> ById(User roadieUser, Guid id, IEnumerable<string> includes = null)
|
||||||
IEnumerable<string> includes = null)
|
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -94,7 +93,7 @@ namespace Roadie.Api.Services
|
||||||
var userBookmarkResult = await BookmarkService.List(roadieUser, new PagedRequest(), false, BookmarkType.Collection);
|
var userBookmarkResult = await BookmarkService.List(roadieUser, new PagedRequest(), false, BookmarkType.Collection);
|
||||||
if (userBookmarkResult.IsSuccess)
|
if (userBookmarkResult.IsSuccess)
|
||||||
{
|
{
|
||||||
result.Data.UserBookmarked = userBookmarkResult?.Rows?.FirstOrDefault(x => x.Bookmark.Value == result.Data.Id.ToString()) != null;
|
result.Data.UserBookmarked = userBookmarkResult?.Rows?.FirstOrDefault(x => x?.Bookmark?.Value == result?.Data?.Id?.ToString()) != null;
|
||||||
}
|
}
|
||||||
if (result.Data.Comments.Any())
|
if (result.Data.Comments.Any())
|
||||||
{
|
{
|
||||||
|
@ -142,6 +141,7 @@ namespace Roadie.Api.Services
|
||||||
{
|
{
|
||||||
DbContext.Collections.Remove(collection);
|
DbContext.Collections.Remove(collection);
|
||||||
await DbContext.SaveChangesAsync();
|
await DbContext.SaveChangesAsync();
|
||||||
|
await BookmarkService.RemoveAllBookmarksForItem(BookmarkType.Collection, collection.Id);
|
||||||
var collectionImageFilename = collection.PathToImage(Configuration);
|
var collectionImageFilename = collection.PathToImage(Configuration);
|
||||||
if (File.Exists(collectionImageFilename))
|
if (File.Exists(collectionImageFilename))
|
||||||
{
|
{
|
||||||
|
@ -277,7 +277,7 @@ namespace Roadie.Api.Services
|
||||||
}
|
}
|
||||||
collection.IsLocked = model.IsLocked;
|
collection.IsLocked = model.IsLocked;
|
||||||
var oldPathToImage = collection.PathToImage(Configuration);
|
var oldPathToImage = collection.PathToImage(Configuration);
|
||||||
var didChangeName = collection.Name != model.Name;
|
var didChangeName = collection.Name != model.Name && !isNew;
|
||||||
collection.Name = model.Name;
|
collection.Name = model.Name;
|
||||||
collection.SortName = model.SortName;
|
collection.SortName = model.SortName;
|
||||||
collection.Edition = model.Edition;
|
collection.Edition = model.Edition;
|
||||||
|
@ -292,6 +292,21 @@ namespace Roadie.Api.Services
|
||||||
collection.AlternateNames = model.AlternateNamesList.ToDelimitedList();
|
collection.AlternateNames = model.AlternateNamesList.ToDelimitedList();
|
||||||
collection.CollectionCount = model.CollectionCount;
|
collection.CollectionCount = model.CollectionCount;
|
||||||
|
|
||||||
|
if (model.Maintainer?.Value != null)
|
||||||
|
{
|
||||||
|
var maintainer = DbContext.Users.FirstOrDefault(x => x.RoadieId == SafeParser.ToGuid(model.Maintainer.Value));
|
||||||
|
if (maintainer != null)
|
||||||
|
{
|
||||||
|
collection.MaintainerId = maintainer.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNew)
|
||||||
|
{
|
||||||
|
await DbContext.Collections.AddAsync(collection);
|
||||||
|
await DbContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
if (didChangeName)
|
if (didChangeName)
|
||||||
{
|
{
|
||||||
if (File.Exists(oldPathToImage))
|
if (File.Exists(oldPathToImage))
|
||||||
|
@ -306,18 +321,12 @@ namespace Roadie.Api.Services
|
||||||
// Save unaltered collection image
|
// Save unaltered collection image
|
||||||
File.WriteAllBytes(collection.PathToImage(Configuration, true), ImageHelper.ConvertToJpegFormat(collectionImage));
|
File.WriteAllBytes(collection.PathToImage(Configuration, true), ImageHelper.ConvertToJpegFormat(collectionImage));
|
||||||
}
|
}
|
||||||
if (model.Maintainer?.Value != null)
|
|
||||||
{
|
|
||||||
var maintainer = DbContext.Users.FirstOrDefault(x => x.RoadieId == SafeParser.ToGuid(model.Maintainer.Value));
|
|
||||||
if (maintainer != null) collection.MaintainerId = maintainer.Id;
|
|
||||||
}
|
|
||||||
|
|
||||||
collection.LastUpdated = now;
|
collection.LastUpdated = now;
|
||||||
|
|
||||||
if (isNew) await DbContext.Collections.AddAsync(collection);
|
|
||||||
await DbContext.SaveChangesAsync();
|
await DbContext.SaveChangesAsync();
|
||||||
|
|
||||||
CacheManager.ClearRegion(collection.CacheRegion);
|
CacheManager.ClearRegion(collection.CacheRegion);
|
||||||
Logger.LogInformation($"UpdateArtist `{collection}` By User `{user}`");
|
Logger.LogInformation($"UpdateCollection `{collection}` By User `{user}`");
|
||||||
return new OperationResult<bool>
|
return new OperationResult<bool>
|
||||||
{
|
{
|
||||||
IsSuccess = !errors.Any(),
|
IsSuccess = !errors.Any(),
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Microsoft.AspNetCore.Identity.UI.Services;
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
using Roadie.Library.Configuration;
|
using Roadie.Library.Configuration;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Mail;
|
using System.Net.Mail;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -17,6 +18,11 @@ namespace Roadie.Api.Services
|
||||||
|
|
||||||
public async Task SendEmailAsync(string email, string subject, string htmlMessage)
|
public async Task SendEmailAsync(string email, string subject, string htmlMessage)
|
||||||
{
|
{
|
||||||
|
if(string.IsNullOrEmpty(Configuration.SmtpHost))
|
||||||
|
{
|
||||||
|
Trace.WriteLine("Email Server (Configuration.SmtpHost) Not Configured", "Warning");
|
||||||
|
return;
|
||||||
|
}
|
||||||
using (var mail = new MailMessage(Configuration.SmtpFromAddress, email))
|
using (var mail = new MailMessage(Configuration.SmtpFromAddress, email))
|
||||||
{
|
{
|
||||||
using (var client = new SmtpClient())
|
using (var client = new SmtpClient())
|
||||||
|
|
|
@ -76,7 +76,7 @@ namespace Roadie.Api.Services
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> Process(ApplicationUser user, DirectoryInfo folder, bool doJustInfo, int? submissionId = null, bool doDeleteFiles = true)
|
public async Task<OperationResult<bool>> Process(User user, DirectoryInfo folder, bool doJustInfo, int? submissionId = null, bool doDeleteFiles = true)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -121,7 +121,7 @@ namespace Roadie.Api.Services
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perform any operations to the given folder and the plugin results after processing
|
/// Perform any operations to the given folder and the plugin results after processing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task<bool> PostProcessFolder(ApplicationUser user, DirectoryInfo inboundFolder, IEnumerable<PluginResultInfo> pluginResults, bool doJustInfo, bool doDeleteFiles = true)
|
private async Task<bool> PostProcessFolder(User user, DirectoryInfo inboundFolder, IEnumerable<PluginResultInfo> pluginResults, bool doJustInfo, bool doDeleteFiles = true)
|
||||||
{
|
{
|
||||||
SimpleContract.Requires<ArgumentNullException>(inboundFolder != null, "Invalid InboundFolder");
|
SimpleContract.Requires<ArgumentNullException>(inboundFolder != null, "Invalid InboundFolder");
|
||||||
if (pluginResults != null)
|
if (pluginResults != null)
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace Roadie.Api.Services
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<Genre>> ById(User roadieUser, Guid id, IEnumerable<string> includes = null)
|
public async Task<OperationResult<Genre>> ById(Library.Models.Users.User roadieUser, Guid id, IEnumerable<string> includes = null)
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -58,7 +58,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> Delete(ApplicationUser user, Guid id)
|
public async Task<OperationResult<bool>> Delete(Library.Identity.User user, Guid id)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -84,7 +84,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Library.Models.Pagination.PagedResult<GenreList>> List(User roadieUser, PagedRequest request, bool? doRandomize = false)
|
public async Task<Library.Models.Pagination.PagedResult<GenreList>> List(Library.Models.Users.User roadieUser, PagedRequest request, bool? doRandomize = false)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -161,12 +161,12 @@ namespace Roadie.Api.Services
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<Library.Models.Image>> SetGenreImageByUrl(User user, Guid id, string imageUrl)
|
public async Task<OperationResult<Library.Models.Image>> SetGenreImageByUrl(Library.Models.Users.User user, Guid id, string imageUrl)
|
||||||
{
|
{
|
||||||
return await SaveImageBytes(user, id, WebHelper.BytesForImageUrl(imageUrl));
|
return await SaveImageBytes(user, id, WebHelper.BytesForImageUrl(imageUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> UpdateGenre(User user, Genre model)
|
public async Task<OperationResult<bool>> UpdateGenre(Library.Models.Users.User user, Genre model)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -243,7 +243,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<Library.Models.Image>> UploadGenreImage(User user, Guid id, IFormFile file)
|
public async Task<OperationResult<Library.Models.Image>> UploadGenreImage(Library.Models.Users.User user, Guid id, IFormFile file)
|
||||||
{
|
{
|
||||||
var bytes = new byte[0];
|
var bytes = new byte[0];
|
||||||
using (var ms = new MemoryStream())
|
using (var ms = new MemoryStream())
|
||||||
|
@ -309,7 +309,7 @@ namespace Roadie.Api.Services
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<OperationResult<Library.Models.Image>> SaveImageBytes(User user, Guid id, byte[] imageBytes)
|
private async Task<OperationResult<Library.Models.Image>> SaveImageBytes(Library.Models.Users.User user, Guid id, byte[] imageBytes)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
|
|
@ -9,45 +9,45 @@ namespace Roadie.Api.Services
|
||||||
{
|
{
|
||||||
public interface IAdminService
|
public interface IAdminService
|
||||||
{
|
{
|
||||||
Task<OperationResult<bool>> DeleteArtist(ApplicationUser user, Guid artistId, bool deleteFolder);
|
Task<OperationResult<bool>> DeleteArtist(User user, Guid artistId, bool deleteFolder);
|
||||||
|
|
||||||
Task<OperationResult<bool>> DeleteArtistReleases(ApplicationUser user, Guid artistId, bool doDeleteFiles = false);
|
Task<OperationResult<bool>> DeleteArtistReleases(User user, Guid artistId, bool doDeleteFiles = false);
|
||||||
|
|
||||||
Task<OperationResult<bool>> DeleteArtistSecondaryImage(ApplicationUser user, Guid artistId, int index);
|
Task<OperationResult<bool>> DeleteArtistSecondaryImage(User user, Guid artistId, int index);
|
||||||
|
|
||||||
Task<OperationResult<bool>> DeleteGenre(ApplicationUser user, Guid genreId);
|
Task<OperationResult<bool>> DeleteGenre(User user, Guid genreId);
|
||||||
|
|
||||||
Task<OperationResult<bool>> DeleteLabel(ApplicationUser user, Guid labelId);
|
Task<OperationResult<bool>> DeleteLabel(User user, Guid labelId);
|
||||||
|
|
||||||
Task<OperationResult<bool>> DeleteRelease(ApplicationUser user, Guid releaseId, bool? doDeleteFiles);
|
Task<OperationResult<bool>> DeleteRelease(User user, Guid releaseId, bool? doDeleteFiles);
|
||||||
|
|
||||||
Task<OperationResult<bool>> DeleteReleaseSecondaryImage(ApplicationUser user, Guid releaseId, int index);
|
Task<OperationResult<bool>> DeleteReleaseSecondaryImage(User user, Guid releaseId, int index);
|
||||||
|
|
||||||
Task<OperationResult<bool>> DeleteTracks(ApplicationUser user, IEnumerable<Guid> trackIds, bool? doDeleteFile);
|
Task<OperationResult<bool>> DeleteTracks(User user, IEnumerable<Guid> trackIds, bool? doDeleteFile);
|
||||||
|
|
||||||
Task<OperationResult<bool>> DeleteUser(ApplicationUser applicationUser, Guid id);
|
Task<OperationResult<bool>> DeleteUser(User applicationUser, Guid id);
|
||||||
|
|
||||||
Task<OperationResult<bool>> DoInitialSetup(ApplicationUser user, UserManager<ApplicationUser> userManager);
|
Task<OperationResult<bool>> DoInitialSetup(User user, UserManager<User> userManager);
|
||||||
|
|
||||||
Task<OperationResult<Dictionary<string, List<string>>>> MissingCollectionReleases(ApplicationUser user);
|
Task<OperationResult<Dictionary<string, List<string>>>> MissingCollectionReleases(User user);
|
||||||
|
|
||||||
void PerformStartUpTasks();
|
void PerformStartUpTasks();
|
||||||
|
|
||||||
Task<OperationResult<bool>> ScanAllCollections(ApplicationUser user, bool isReadOnly = false, bool doPurgeFirst = false);
|
Task<OperationResult<bool>> ScanAllCollections(User user, bool isReadOnly = false, bool doPurgeFirst = false);
|
||||||
|
|
||||||
Task<OperationResult<bool>> ScanArtist(ApplicationUser user, Guid artistId, bool isReadOnly = false);
|
Task<OperationResult<bool>> ScanArtist(User user, Guid artistId, bool isReadOnly = false);
|
||||||
|
|
||||||
Task<OperationResult<bool>> ScanArtists(ApplicationUser user, IEnumerable<Guid> artistIds, bool isReadOnly = false);
|
Task<OperationResult<bool>> ScanArtists(User user, IEnumerable<Guid> artistIds, bool isReadOnly = false);
|
||||||
|
|
||||||
Task<OperationResult<bool>> ScanCollection(ApplicationUser user, Guid collectionId, bool isReadOnly = false, bool doPurgeFirst = false, bool doUpdateRanks = true);
|
Task<OperationResult<bool>> ScanCollection(User user, Guid collectionId, bool isReadOnly = false, bool doPurgeFirst = false, bool doUpdateRanks = true);
|
||||||
|
|
||||||
Task<OperationResult<bool>> ScanInboundFolder(ApplicationUser user, bool isReadOnly = false);
|
Task<OperationResult<bool>> ScanInboundFolder(User user, bool isReadOnly = false);
|
||||||
|
|
||||||
Task<OperationResult<bool>> ScanLibraryFolder(ApplicationUser user, bool isReadOnly = false);
|
Task<OperationResult<bool>> ScanLibraryFolder(User user, bool isReadOnly = false);
|
||||||
|
|
||||||
Task<OperationResult<bool>> ScanRelease(ApplicationUser user, Guid releaseIds, bool isReadOnly = false, bool wasDoneForInvalidTrackPlay = false);
|
Task<OperationResult<bool>> ScanRelease(User user, Guid releaseIds, bool isReadOnly = false, bool wasDoneForInvalidTrackPlay = false);
|
||||||
|
|
||||||
Task<OperationResult<bool>> ScanReleases(ApplicationUser user, IEnumerable<Guid> releaseId, bool isReadOnly = false, bool wasDoneForInvalidTrackPlay = false);
|
Task<OperationResult<bool>> ScanReleases(User user, IEnumerable<Guid> releaseId, bool isReadOnly = false, bool wasDoneForInvalidTrackPlay = false);
|
||||||
|
|
||||||
Task<OperationResult<bool>> UpdateInviteTokenUsed(Guid? tokenId);
|
Task<OperationResult<bool>> UpdateInviteTokenUsed(Guid? tokenId);
|
||||||
|
|
||||||
|
|
|
@ -12,22 +12,22 @@ namespace Roadie.Api.Services
|
||||||
{
|
{
|
||||||
public interface IArtistService
|
public interface IArtistService
|
||||||
{
|
{
|
||||||
Task<OperationResult<Artist>> ById(User user, Guid id, IEnumerable<string> includes);
|
Task<OperationResult<Artist>> ById(Library.Models.Users.User user, Guid id, IEnumerable<string> includes);
|
||||||
|
|
||||||
Task<OperationResult<bool>> Delete(ApplicationUser user, Library.Data.Artist Artist, bool deleteFolder);
|
Task<OperationResult<bool>> Delete(Library.Identity.User user, Library.Data.Artist Artist, bool deleteFolder);
|
||||||
|
|
||||||
Task<PagedResult<ArtistList>> List(User user, PagedRequest request, bool? doRandomize = false, bool? onlyIncludeWithReleases = true);
|
Task<PagedResult<ArtistList>> List(Library.Models.Users.User user, PagedRequest request, bool? doRandomize = false, bool? onlyIncludeWithReleases = true);
|
||||||
|
|
||||||
Task<OperationResult<bool>> MergeArtists(ApplicationUser user, Guid artistToMergeId, Guid artistToMergeIntoId);
|
Task<OperationResult<bool>> MergeArtists(Library.Identity.User user, Guid artistToMergeId, Guid artistToMergeIntoId);
|
||||||
|
|
||||||
Task<OperationResult<bool>> RefreshArtistMetadata(ApplicationUser user, Guid ArtistId);
|
Task<OperationResult<bool>> RefreshArtistMetadata(Library.Identity.User user, Guid ArtistId);
|
||||||
|
|
||||||
Task<OperationResult<bool>> ScanArtistReleasesFolders(ApplicationUser user, Guid artistId, string destinationFolder, bool doJustInfo);
|
Task<OperationResult<bool>> ScanArtistReleasesFolders(Library.Identity.User user, Guid artistId, string destinationFolder, bool doJustInfo);
|
||||||
|
|
||||||
Task<OperationResult<Image>> SetReleaseImageByUrl(ApplicationUser user, Guid id, string imageUrl);
|
Task<OperationResult<Image>> SetReleaseImageByUrl(Library.Identity.User user, Guid id, string imageUrl);
|
||||||
|
|
||||||
Task<OperationResult<bool>> UpdateArtist(ApplicationUser user, Artist artist);
|
Task<OperationResult<bool>> UpdateArtist(Library.Identity.User user, Artist artist);
|
||||||
|
|
||||||
Task<OperationResult<Image>> UploadArtistImage(ApplicationUser user, Guid id, IFormFile file);
|
Task<OperationResult<Image>> UploadArtistImage(Library.Identity.User user, Guid id, IFormFile file);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using Roadie.Library.Enums;
|
using Roadie.Library;
|
||||||
|
using Roadie.Library.Enums;
|
||||||
using Roadie.Library.Models;
|
using Roadie.Library.Models;
|
||||||
using Roadie.Library.Models.Pagination;
|
using Roadie.Library.Models.Pagination;
|
||||||
using Roadie.Library.Models.Users;
|
using Roadie.Library.Models.Users;
|
||||||
|
@ -8,7 +9,7 @@ namespace Roadie.Api.Services
|
||||||
{
|
{
|
||||||
public interface IBookmarkService
|
public interface IBookmarkService
|
||||||
{
|
{
|
||||||
Task<PagedResult<BookmarkList>> List(User roadieUser, PagedRequest request, bool? doRandomize = false,
|
Task<OperationResult<bool>> RemoveAllBookmarksForItem(BookmarkType type, int id);
|
||||||
BookmarkType? filterType = null);
|
Task<PagedResult<BookmarkList>> List(User roadieUser, PagedRequest request, bool? doRandomize = false, BookmarkType? filterType = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,6 +14,6 @@ namespace Roadie.Api.Services
|
||||||
|
|
||||||
int? ProcessLimit { get; set; }
|
int? ProcessLimit { get; set; }
|
||||||
|
|
||||||
Task<OperationResult<bool>> Process(ApplicationUser user, DirectoryInfo folder, bool doJustInfo, int? submissionId = null, bool doDeleteFiles = true);
|
Task<OperationResult<bool>> Process(User user, DirectoryInfo folder, bool doJustInfo, int? submissionId = null, bool doDeleteFiles = true);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -12,16 +12,16 @@ namespace Roadie.Api.Services
|
||||||
{
|
{
|
||||||
public interface IGenreService
|
public interface IGenreService
|
||||||
{
|
{
|
||||||
Task<OperationResult<Genre>> ById(User roadieUser, Guid id, IEnumerable<string> includes = null);
|
Task<OperationResult<Genre>> ById(Library.Models.Users.User roadieUser, Guid id, IEnumerable<string> includes = null);
|
||||||
|
|
||||||
Task<OperationResult<bool>> Delete(ApplicationUser user, Guid id);
|
Task<OperationResult<bool>> Delete(Library.Identity.User user, Guid id);
|
||||||
|
|
||||||
Task<PagedResult<GenreList>> List(User roadieUser, PagedRequest request, bool? doRandomize = false);
|
Task<PagedResult<GenreList>> List(Library.Models.Users.User roadieUser, PagedRequest request, bool? doRandomize = false);
|
||||||
|
|
||||||
Task<OperationResult<Image>> SetGenreImageByUrl(User user, Guid id, string imageUrl);
|
Task<OperationResult<Image>> SetGenreImageByUrl(Library.Models.Users.User user, Guid id, string imageUrl);
|
||||||
|
|
||||||
Task<OperationResult<bool>> UpdateGenre(User user, Genre model);
|
Task<OperationResult<bool>> UpdateGenre(Library.Models.Users.User user, Genre model);
|
||||||
|
|
||||||
Task<OperationResult<Image>> UploadGenreImage(User user, Guid id, IFormFile file);
|
Task<OperationResult<Image>> UploadGenreImage(Library.Models.Users.User user, Guid id, IFormFile file);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -12,18 +12,18 @@ namespace Roadie.Api.Services
|
||||||
{
|
{
|
||||||
public interface ILabelService
|
public interface ILabelService
|
||||||
{
|
{
|
||||||
Task<OperationResult<Label>> ById(User roadieUser, Guid id, IEnumerable<string> includes = null);
|
Task<OperationResult<Label>> ById(Library.Models.Users.User roadieUser, Guid id, IEnumerable<string> includes = null);
|
||||||
|
|
||||||
Task<OperationResult<bool>> Delete(ApplicationUser user, Guid id);
|
Task<OperationResult<bool>> Delete(Library.Identity.User user, Guid id);
|
||||||
|
|
||||||
Task<PagedResult<LabelList>> List(User roadieUser, PagedRequest request, bool? doRandomize = false);
|
Task<PagedResult<LabelList>> List(Library.Models.Users.User roadieUser, PagedRequest request, bool? doRandomize = false);
|
||||||
|
|
||||||
Task<OperationResult<bool>> MergeLabelsIntoLabel(ApplicationUser user, Guid intoLabelId, IEnumerable<Guid> labelIdsToMerge);
|
Task<OperationResult<bool>> MergeLabelsIntoLabel(Library.Identity.User user, Guid intoLabelId, IEnumerable<Guid> labelIdsToMerge);
|
||||||
|
|
||||||
Task<OperationResult<Image>> SetLabelImageByUrl(User user, Guid id, string imageUrl);
|
Task<OperationResult<Image>> SetLabelImageByUrl(Library.Models.Users.User user, Guid id, string imageUrl);
|
||||||
|
|
||||||
Task<OperationResult<bool>> UpdateLabel(User user, Label label);
|
Task<OperationResult<bool>> UpdateLabel(Library.Models.Users.User user, Label label);
|
||||||
|
|
||||||
Task<OperationResult<Image>> UploadLabelImage(User user, Guid id, IFormFile file);
|
Task<OperationResult<Image>> UploadLabelImage(Library.Models.Users.User user, Guid id, IFormFile file);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -15,26 +15,26 @@ namespace Roadie.Api.Services
|
||||||
{
|
{
|
||||||
IEnumerable<int> AddedTrackIds { get; }
|
IEnumerable<int> AddedTrackIds { get; }
|
||||||
|
|
||||||
Task<OperationResult<Release>> ById(User roadieUser, Guid id, IEnumerable<string> includes = null);
|
Task<OperationResult<Release>> ById(Library.Models.Users.User roadieUser, Guid id, IEnumerable<string> includes = null);
|
||||||
|
|
||||||
Task<OperationResult<bool>> Delete(ApplicationUser user, Library.Data.Release release, bool doDeleteFiles = false, bool doUpdateArtistCounts = true);
|
Task<OperationResult<bool>> Delete(Library.Identity.User user, Library.Data.Release release, bool doDeleteFiles = false, bool doUpdateArtistCounts = true);
|
||||||
|
|
||||||
Task<OperationResult<bool>> DeleteReleases(ApplicationUser user, IEnumerable<Guid> releaseIds, bool doDeleteFiles = false);
|
Task<OperationResult<bool>> DeleteReleases(Library.Identity.User user, IEnumerable<Guid> releaseIds, bool doDeleteFiles = false);
|
||||||
|
|
||||||
Task<PagedResult<ReleaseList>> List(User user, PagedRequest request, bool? doRandomize = false, IEnumerable<string> includes = null);
|
Task<PagedResult<ReleaseList>> List(Library.Models.Users.User user, PagedRequest request, bool? doRandomize = false, IEnumerable<string> includes = null);
|
||||||
|
|
||||||
Task<OperationResult<bool>> MergeReleases(ApplicationUser user, Guid releaseToMergeId, Guid releaseToMergeIntoId, bool addAsMedia);
|
Task<OperationResult<bool>> MergeReleases(Library.Identity.User user, Guid releaseToMergeId, Guid releaseToMergeIntoId, bool addAsMedia);
|
||||||
|
|
||||||
Task<OperationResult<bool>> MergeReleases(ApplicationUser user, Library.Data.Release releaseToMerge, Library.Data.Release releaseToMergeInto, bool addAsMedia);
|
Task<OperationResult<bool>> MergeReleases(Library.Identity.User user, Library.Data.Release releaseToMerge, Library.Data.Release releaseToMergeInto, bool addAsMedia);
|
||||||
|
|
||||||
Task<FileOperationResult<byte[]>> ReleaseZipped(User roadieUser, Guid id);
|
Task<FileOperationResult<byte[]>> ReleaseZipped(Library.Models.Users.User roadieUser, Guid id);
|
||||||
|
|
||||||
Task<OperationResult<bool>> ScanReleaseFolder(ApplicationUser user, Guid releaseId, bool doJustInfo, Library.Data.Release releaseToScan = null);
|
Task<OperationResult<bool>> ScanReleaseFolder(Library.Identity.User user, Guid releaseId, bool doJustInfo, Library.Data.Release releaseToScan = null);
|
||||||
|
|
||||||
Task<OperationResult<Image>> SetReleaseImageByUrl(ApplicationUser user, Guid id, string imageUrl);
|
Task<OperationResult<Image>> SetReleaseImageByUrl(Library.Identity.User user, Guid id, string imageUrl);
|
||||||
|
|
||||||
Task<OperationResult<bool>> UpdateRelease(ApplicationUser user, Release release, string originalReleaseFolder = null);
|
Task<OperationResult<bool>> UpdateRelease(Library.Identity.User user, Release release, string originalReleaseFolder = null);
|
||||||
|
|
||||||
Task<OperationResult<Image>> UploadReleaseImage(ApplicationUser user, Guid id, IFormFile file);
|
Task<OperationResult<Image>> UploadReleaseImage(Library.Identity.User user, Guid id, IFormFile file);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,6 +6,6 @@ namespace Roadie.Api.Services
|
||||||
{
|
{
|
||||||
public interface ITokenService
|
public interface ITokenService
|
||||||
{
|
{
|
||||||
Task<string> GenerateToken(ApplicationUser user, UserManager<ApplicationUser> userManager);
|
Task<string> GenerateToken(User user, UserManager<User> userManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -178,7 +178,7 @@ namespace Roadie.Api.Services
|
||||||
public async Task<FileOperationResult<IImage>> UserImage(Guid id, int? width, int? height, EntityTagHeaderValue etag = null)
|
public async Task<FileOperationResult<IImage>> UserImage(Guid id, int? width, int? height, EntityTagHeaderValue etag = null)
|
||||||
{
|
{
|
||||||
return await GetImageFileOperation("UserById",
|
return await GetImageFileOperation("UserById",
|
||||||
ApplicationUser.CacheRegionUrn(id),
|
User.CacheRegionUrn(id),
|
||||||
id,
|
id,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
|
@ -206,7 +206,7 @@ namespace Roadie.Api.Services
|
||||||
artistFolder = artist.ArtistFileFolder(Configuration);
|
artistFolder = artist.ArtistFileFolder(Configuration);
|
||||||
if (!Directory.Exists(artistFolder))
|
if (!Directory.Exists(artistFolder))
|
||||||
{
|
{
|
||||||
Logger.LogTrace($"Artist Folder [{artistFolder}], Not Found For Artist `{artist}`");
|
Logger.LogWarning($"Artist Folder [{artistFolder}], Not Found For Artist `{artist}`");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -257,7 +257,7 @@ namespace Roadie.Api.Services
|
||||||
artistFolder = artist.ArtistFileFolder(Configuration);
|
artistFolder = artist.ArtistFileFolder(Configuration);
|
||||||
if (!Directory.Exists(artistFolder))
|
if (!Directory.Exists(artistFolder))
|
||||||
{
|
{
|
||||||
Logger.LogTrace($"Artist Folder [{artistFolder}], Not Found For Artist `{artist}`");
|
Logger.LogWarning($"Artist Folder [{artistFolder}], Not Found For Artist `{artist}`");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -545,7 +545,7 @@ namespace Roadie.Api.Services
|
||||||
artistFolder = release.Artist.ArtistFileFolder(Configuration);
|
artistFolder = release.Artist.ArtistFileFolder(Configuration);
|
||||||
if (!Directory.Exists(artistFolder))
|
if (!Directory.Exists(artistFolder))
|
||||||
{
|
{
|
||||||
Logger.LogTrace($"Artist Folder [{artistFolder}], Not Found For Artist `{release.Artist}`");
|
Logger.LogWarning($"Artist Folder [{artistFolder}], Not Found For Artist `{release.Artist}`");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -605,7 +605,7 @@ namespace Roadie.Api.Services
|
||||||
artistFolder = release.Artist.ArtistFileFolder(Configuration);
|
artistFolder = release.Artist.ArtistFileFolder(Configuration);
|
||||||
if (!Directory.Exists(artistFolder))
|
if (!Directory.Exists(artistFolder))
|
||||||
{
|
{
|
||||||
Logger.LogTrace($"Artist Folder [{artistFolder}], Not Found For Artist `{release.Artist}`");
|
Logger.LogWarning($"Artist Folder [{artistFolder}], Not Found For Artist `{release.Artist}`");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace Roadie.Api.Services
|
||||||
BookmarkService = bookmarkService;
|
BookmarkService = bookmarkService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<Label>> ById(User roadieUser, Guid id, IEnumerable<string> includes = null)
|
public async Task<OperationResult<Label>> ById(Library.Models.Users.User roadieUser, Guid id, IEnumerable<string> includes = null)
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -57,7 +57,7 @@ namespace Roadie.Api.Services
|
||||||
var userBookmarkResult = await BookmarkService.List(roadieUser, new PagedRequest(), false, BookmarkType.Label);
|
var userBookmarkResult = await BookmarkService.List(roadieUser, new PagedRequest(), false, BookmarkType.Label);
|
||||||
if (userBookmarkResult.IsSuccess)
|
if (userBookmarkResult.IsSuccess)
|
||||||
{
|
{
|
||||||
result.Data.UserBookmarked = userBookmarkResult?.Rows?.FirstOrDefault(x => x.Bookmark.Value == result.Data.Id.ToString()) != null;
|
result.Data.UserBookmarked = userBookmarkResult?.Rows?.FirstOrDefault(x => x?.Bookmark?.Value == result?.Data?.Id?.ToString()) != null;
|
||||||
}
|
}
|
||||||
if (result.Data.Comments.Any())
|
if (result.Data.Comments.Any())
|
||||||
{
|
{
|
||||||
|
@ -85,7 +85,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> Delete(ApplicationUser user, Guid id)
|
public async Task<OperationResult<bool>> Delete(Library.Identity.User user, Guid id)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -99,7 +99,7 @@ namespace Roadie.Api.Services
|
||||||
{
|
{
|
||||||
File.Delete(labelImageFilename);
|
File.Delete(labelImageFilename);
|
||||||
}
|
}
|
||||||
|
await BookmarkService.RemoveAllBookmarksForItem(BookmarkType.Label, label.Id);
|
||||||
Logger.LogWarning("User `{0}` deleted Label `{1}]`", user, label);
|
Logger.LogWarning("User `{0}` deleted Label `{1}]`", user, label);
|
||||||
CacheManager.ClearRegion(label.CacheRegion);
|
CacheManager.ClearRegion(label.CacheRegion);
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
|
@ -111,7 +111,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Library.Models.Pagination.PagedResult<LabelList>> List(User roadieUser, PagedRequest request,
|
public async Task<Library.Models.Pagination.PagedResult<LabelList>> List(Library.Models.Users.User roadieUser, PagedRequest request,
|
||||||
bool? doRandomize = false)
|
bool? doRandomize = false)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
|
@ -198,7 +198,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> MergeLabelsIntoLabel(ApplicationUser user, Guid intoLabelId, IEnumerable<Guid> labelIdsToMerge)
|
public async Task<OperationResult<bool>> MergeLabelsIntoLabel(Library.Identity.User user, Guid intoLabelId, IEnumerable<Guid> labelIdsToMerge)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -258,12 +258,12 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<Library.Models.Image>> SetLabelImageByUrl(User user, Guid id, string imageUrl)
|
public async Task<OperationResult<Library.Models.Image>> SetLabelImageByUrl(Library.Models.Users.User user, Guid id, string imageUrl)
|
||||||
{
|
{
|
||||||
return await SaveImageBytes(user, id, WebHelper.BytesForImageUrl(imageUrl));
|
return await SaveImageBytes(user, id, WebHelper.BytesForImageUrl(imageUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<bool>> UpdateLabel(User user, Label model)
|
public async Task<OperationResult<bool>> UpdateLabel(Library.Models.Users.User user, Label model)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
@ -344,7 +344,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OperationResult<Library.Models.Image>> UploadLabelImage(User user, Guid id, IFormFile file)
|
public async Task<OperationResult<Library.Models.Image>> UploadLabelImage(Library.Models.Users.User user, Guid id, IFormFile file)
|
||||||
{
|
{
|
||||||
var bytes = new byte[0];
|
var bytes = new byte[0];
|
||||||
using (var ms = new MemoryStream())
|
using (var ms = new MemoryStream())
|
||||||
|
@ -452,7 +452,7 @@ namespace Roadie.Api.Services
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<OperationResult<Library.Models.Image>> SaveImageBytes(User user, Guid id, byte[] imageBytes)
|
private async Task<OperationResult<Library.Models.Image>> SaveImageBytes(Library.Models.Users.User user, Guid id, byte[] imageBytes)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue