mirror of
https://github.com/sphildreth/roadie
synced 2024-11-10 06:44:12 +00:00
Add project files.
This commit is contained in:
parent
adebe383a9
commit
0430305ebe
77 changed files with 3299 additions and 0 deletions
78
Roadie.Api.Data/Models/Artist.cs
Normal file
78
Roadie.Api.Data/Models/Artist.cs
Normal file
|
@ -0,0 +1,78 @@
|
|||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Roadie.Api.Data.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class Artist : EntityModelBase
|
||||
{
|
||||
[MaxLength(100)]
|
||||
public string AmgId { get; set; }
|
||||
|
||||
public string ArtistType { get; set; }
|
||||
|
||||
public string BandStatus { get; set; }
|
||||
|
||||
[MaxLength(65535)]
|
||||
public string BioContext { get; set; }
|
||||
|
||||
public DateTime? BirthDate { get; set; }
|
||||
|
||||
[MaxLength(50)]
|
||||
public string DiscogsId { get; set; }
|
||||
|
||||
[MaxLength(65535)]
|
||||
[JsonIgnore]
|
||||
[IgnoreDataMember]
|
||||
public string ISNIList { get; set; }
|
||||
|
||||
[JsonProperty("isniList")]
|
||||
public IEnumerable<string> ISNIListList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.ISNIList))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return this.ISNIList.Split('|');
|
||||
}
|
||||
}
|
||||
|
||||
[MaxLength(100)]
|
||||
public string ITunesId { get; set; }
|
||||
|
||||
[MaxLength(100)]
|
||||
public string MusicBrainzId { get; set; }
|
||||
|
||||
[MaxLength(250)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[MaxLength(65535)]
|
||||
public string Profile { get; set; }
|
||||
|
||||
public short? Rating { get; set; }
|
||||
|
||||
[MaxLength(500)]
|
||||
public string RealName { get; set; }
|
||||
|
||||
[MaxLength(100)]
|
||||
public string SpotifyId { get; set; }
|
||||
|
||||
public string Tooltip
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Name;
|
||||
}
|
||||
}
|
||||
|
||||
public Artist()
|
||||
{
|
||||
this.BandStatus = "1";
|
||||
}
|
||||
}
|
||||
}
|
23
Roadie.Api.Data/Models/Collection.cs
Normal file
23
Roadie.Api.Data/Models/Collection.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Api.Data.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class Collection : EntityModelBase
|
||||
{
|
||||
public int CollectionCount { get; set; }
|
||||
|
||||
[MaxLength(1000)]
|
||||
public string Description { get; set; }
|
||||
|
||||
[MaxLength(200)]
|
||||
public string Edition { get; set; }
|
||||
|
||||
public int MaintainerId { get; set; }
|
||||
|
||||
public string CollectionType { get; set; }
|
||||
}
|
||||
}
|
16
Roadie.Api.Data/Models/CollectionRelease.cs
Normal file
16
Roadie.Api.Data/Models/CollectionRelease.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Api.Data.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class CollectionRelease
|
||||
{
|
||||
public Collection Collection { get; set; }
|
||||
|
||||
public int ListNumber { get; set; }
|
||||
|
||||
}
|
||||
}
|
91
Roadie.Api.Data/Models/EntityModelBase.cs
Normal file
91
Roadie.Api.Data/Models/EntityModelBase.cs
Normal file
|
@ -0,0 +1,91 @@
|
|||
using Mapster;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Roadie.Api.Data.Models
|
||||
{
|
||||
public abstract class EntityModelBase
|
||||
{
|
||||
[MaxLength(65535)]
|
||||
[JsonIgnore]
|
||||
[IgnoreDataMember]
|
||||
public string AlternateNames { get; set; }
|
||||
|
||||
public IEnumerable<string> AlternateNamesList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.AlternateNames))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return this.AlternateNames.Split('|');
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime? BeginDate { get; set; }
|
||||
|
||||
[Required]
|
||||
public DateTime CreatedDate { get; set; }
|
||||
|
||||
public DateTime? LastUpdated { get; set; }
|
||||
|
||||
public DateTime? EndDate { get; set; }
|
||||
|
||||
[Key]
|
||||
[Required]
|
||||
[AdaptMember("RoadieId")]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public bool? IsLocked { get; set; }
|
||||
|
||||
[MaxLength(250)]
|
||||
public string SortName { get; set; }
|
||||
|
||||
public int? Status { get; set; }
|
||||
|
||||
[MaxLength(65535)]
|
||||
[JsonIgnore]
|
||||
[IgnoreDataMember]
|
||||
public string Tags { get; set; }
|
||||
|
||||
public IEnumerable<string> TagsList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.Tags))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return this.Tags.Split('|');
|
||||
}
|
||||
}
|
||||
|
||||
[MaxLength(65535)]
|
||||
[JsonIgnore]
|
||||
[IgnoreDataMember]
|
||||
public string URLs { get; set; }
|
||||
|
||||
public IEnumerable<string> URLsList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.URLs))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return this.URLs.Split('|');
|
||||
}
|
||||
}
|
||||
|
||||
public EntityModelBase()
|
||||
{
|
||||
this.Id = Guid.NewGuid();
|
||||
this.CreatedDate = DateTime.UtcNow;
|
||||
this.Status = 0;
|
||||
}
|
||||
}
|
||||
}
|
14
Roadie.Api.Data/Models/Genre.cs
Normal file
14
Roadie.Api.Data/Models/Genre.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Api.Data.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class Genre : EntityModelBase
|
||||
{
|
||||
[MaxLength(100)]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
38
Roadie.Api.Data/Models/Info.cs
Normal file
38
Roadie.Api.Data/Models/Info.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Api.Data.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic Info for a child item on a Detail record. Like a Label on a Release, or an Artist on a Release, or a Label for an Artist
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Info
|
||||
{
|
||||
/// <summary>
|
||||
/// The Id for the Info (like ArtistId, Or ReleaseId)
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
/// <summary>
|
||||
/// Display name for the Info (like Artist Name or Release Title)
|
||||
/// </summary>
|
||||
public string DisplayName { get; set; }
|
||||
/// <summary>
|
||||
/// Any tooltip to use with the DisplayName
|
||||
/// </summary>
|
||||
public string Tooltip { get; set; }
|
||||
/// <summary>
|
||||
/// Url to the Image to show for the Info
|
||||
/// </summary>
|
||||
public string ImageUrl { get; set; }
|
||||
/// <summary>
|
||||
/// Url to see full details
|
||||
/// </summary>
|
||||
public string DetailUrl { get; set; }
|
||||
/// <summary>
|
||||
/// Any CSS class to apply
|
||||
/// </summary>
|
||||
public string CssClass { get; set; }
|
||||
}
|
||||
}
|
28
Roadie.Api.Data/Models/Label.cs
Normal file
28
Roadie.Api.Data/Models/Label.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Roadie.Api.Data.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class Label : EntityModelBase
|
||||
{
|
||||
[MaxLength(65535)]
|
||||
public string BioContext { get; set; }
|
||||
|
||||
public DateTime? BirthDate { get; set; }
|
||||
|
||||
[MaxLength(50)]
|
||||
public string DiscogsId { get; set; }
|
||||
|
||||
[MaxLength(100)]
|
||||
public string MusicBrainzId { get; set; }
|
||||
|
||||
[MaxLength(250)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[MaxLength(65535)]
|
||||
public string Profile { get; set; }
|
||||
|
||||
}
|
||||
}
|
66
Roadie.Api.Data/Models/Release.cs
Normal file
66
Roadie.Api.Data/Models/Release.cs
Normal file
|
@ -0,0 +1,66 @@
|
|||
using Mapster;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Roadie.Api.Data.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class Release : EntityModelBase
|
||||
{
|
||||
[MaxLength(50)]
|
||||
public string AmgId { get; set; }
|
||||
|
||||
public Artist Artist { get; set; }
|
||||
|
||||
[MaxLength(50)]
|
||||
public string DiscogsId { get; set; }
|
||||
|
||||
public bool? IsVirtual { get; set; }
|
||||
|
||||
[MaxLength(100)]
|
||||
public string ITunesId { get; set; }
|
||||
|
||||
[MaxLength(50)]
|
||||
public string LastFMId { get; set; }
|
||||
|
||||
[MaxLength(65535)]
|
||||
public string LastFMSummary { get; set; }
|
||||
|
||||
public string LibraryStatus { get; set; }
|
||||
|
||||
public short? MediaCount { get; set; }
|
||||
|
||||
[MaxLength(100)]
|
||||
public string MusicBrainzId { get; set; }
|
||||
|
||||
[MaxLength(65535)]
|
||||
public string Profile { get; set; }
|
||||
|
||||
[Required]
|
||||
public DateTime ReleaseDate { get; set; }
|
||||
|
||||
public string ReleaseType { get; set; }
|
||||
|
||||
[MaxLength(100)]
|
||||
public string SpotifyId { get; set; }
|
||||
|
||||
public int? SubmissionId { get; set; }
|
||||
|
||||
[MaxLength(250)]
|
||||
[Required]
|
||||
public string Title { get; set; }
|
||||
|
||||
public short TrackCount { get; set; }
|
||||
|
||||
public List<ReleaseLabel> Labels { get; set; }
|
||||
|
||||
public List<ReleaseMedia> Medias { get; set; }
|
||||
|
||||
public List<ReleaseGenre> Genres { get; set; }
|
||||
|
||||
public List<CollectionRelease> Collections { get; set; }
|
||||
|
||||
}
|
||||
}
|
13
Roadie.Api.Data/Models/ReleaseGenre.cs
Normal file
13
Roadie.Api.Data/Models/ReleaseGenre.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Api.Data.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class ReleaseGenre : EntityModelBase
|
||||
{
|
||||
public Genre Genre { get; set; }
|
||||
}
|
||||
}
|
15
Roadie.Api.Data/Models/ReleaseLabel.cs
Normal file
15
Roadie.Api.Data/Models/ReleaseLabel.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Api.Data.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class ReleaseLabel : EntityModelBase
|
||||
{
|
||||
public string CatalogNumber { get; set; }
|
||||
|
||||
public Label Label { get; set; }
|
||||
|
||||
}
|
||||
}
|
20
Roadie.Api.Data/Models/ReleaseMedia.cs
Normal file
20
Roadie.Api.Data/Models/ReleaseMedia.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Api.Data.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class ReleaseMedia : EntityModelBase
|
||||
{
|
||||
public int MediaNumber { get; set; }
|
||||
public string SubTitle { get; set; }
|
||||
|
||||
[Required]
|
||||
public short TrackCount { get; set; }
|
||||
|
||||
public List<Track> Tracks { get; set; }
|
||||
|
||||
}
|
||||
}
|
52
Roadie.Api.Data/Models/Track.cs
Normal file
52
Roadie.Api.Data/Models/Track.cs
Normal file
|
@ -0,0 +1,52 @@
|
|||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Roadie.Api.Data.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class Track : EntityModelBase
|
||||
{
|
||||
[MaxLength(50)]
|
||||
public string AmgId { get; set; }
|
||||
|
||||
// public Artist Artist { get; set; }
|
||||
|
||||
public int ArtistId { get; set; }
|
||||
|
||||
public int Duration { get; set; }
|
||||
|
||||
[MaxLength(32)]
|
||||
public string Hash { get; set; }
|
||||
|
||||
[MaxLength(15)]
|
||||
public string ISRC { get; set; }
|
||||
|
||||
[MaxLength(50)]
|
||||
public string LastFMId { get; set; }
|
||||
|
||||
public DateTime? LastPlayed { get; set; }
|
||||
|
||||
[MaxLength(100)]
|
||||
public string MusicBrainzId { get; set; }
|
||||
|
||||
[MaxLength(65535)]
|
||||
public string PartTitles { get; set; }
|
||||
|
||||
public int PlayedCount { get; set; }
|
||||
|
||||
public short Rating { get; set; }
|
||||
|
||||
public string ReleaseMediaId { get; set; }
|
||||
|
||||
[MaxLength(100)]
|
||||
public string SpotifyId { get; set; }
|
||||
|
||||
[MaxLength(250)]
|
||||
[Required]
|
||||
public string Title { get; set; }
|
||||
|
||||
[Required]
|
||||
public short TrackNumber { get; set; }
|
||||
}
|
||||
}
|
12
Roadie.Api.Data/Roadie.Api.Data.csproj
Normal file
12
Roadie.Api.Data/Roadie.Api.Data.csproj
Normal file
|
@ -0,0 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Mapster" Version="3.2.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
51
RoadieApi.sln
Normal file
51
RoadieApi.sln
Normal file
|
@ -0,0 +1,51 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27130.2010
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Roadie.Api", "RoadieApi\Roadie.Api.csproj", "{68C80416-0D72-409D-B727-3FEA7AB7FD2C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Roadie.Library", "RoadieLibrary\Roadie.Library.csproj", "{99DE01E6-A61C-4D7C-9DF7-513AD365D5E0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Roadie.Api.Data", "Roadie.Api.Data\Roadie.Api.Data.csproj", "{36070276-BE53-4D7B-98ED-4F3644B93336}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{68C80416-0D72-409D-B727-3FEA7AB7FD2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{68C80416-0D72-409D-B727-3FEA7AB7FD2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{68C80416-0D72-409D-B727-3FEA7AB7FD2C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{68C80416-0D72-409D-B727-3FEA7AB7FD2C}.Debug|x64.Build.0 = Debug|x64
|
||||
{68C80416-0D72-409D-B727-3FEA7AB7FD2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{68C80416-0D72-409D-B727-3FEA7AB7FD2C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{68C80416-0D72-409D-B727-3FEA7AB7FD2C}.Release|x64.ActiveCfg = Release|x64
|
||||
{68C80416-0D72-409D-B727-3FEA7AB7FD2C}.Release|x64.Build.0 = Release|x64
|
||||
{99DE01E6-A61C-4D7C-9DF7-513AD365D5E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{99DE01E6-A61C-4D7C-9DF7-513AD365D5E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{99DE01E6-A61C-4D7C-9DF7-513AD365D5E0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{99DE01E6-A61C-4D7C-9DF7-513AD365D5E0}.Debug|x64.Build.0 = Debug|x64
|
||||
{99DE01E6-A61C-4D7C-9DF7-513AD365D5E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{99DE01E6-A61C-4D7C-9DF7-513AD365D5E0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{99DE01E6-A61C-4D7C-9DF7-513AD365D5E0}.Release|x64.ActiveCfg = Release|x64
|
||||
{99DE01E6-A61C-4D7C-9DF7-513AD365D5E0}.Release|x64.Build.0 = Release|x64
|
||||
{36070276-BE53-4D7B-98ED-4F3644B93336}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{36070276-BE53-4D7B-98ED-4F3644B93336}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{36070276-BE53-4D7B-98ED-4F3644B93336}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{36070276-BE53-4D7B-98ED-4F3644B93336}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{36070276-BE53-4D7B-98ED-4F3644B93336}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{36070276-BE53-4D7B-98ED-4F3644B93336}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{36070276-BE53-4D7B-98ED-4F3644B93336}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{36070276-BE53-4D7B-98ED-4F3644B93336}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {6023B6DB-4256-42E3-B993-9D1EC04A39CD}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
147
RoadieApi/Controllers/AccountController.cs
Normal file
147
RoadieApi/Controllers/AccountController.cs
Normal file
|
@ -0,0 +1,147 @@
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Roadie.Api.Models;
|
||||
using Roadie.Api.Services;
|
||||
using Roadie.Library.Identity;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Api.Controllers
|
||||
{
|
||||
[Produces("application/json")]
|
||||
[Route("auth")]
|
||||
[ApiController]
|
||||
[AllowAnonymous]
|
||||
public class AccountController : ControllerBase
|
||||
{
|
||||
private readonly IConfiguration configuration;
|
||||
private readonly ILogger<AccountController> logger;
|
||||
private readonly SignInManager<ApplicationUser> signInManager;
|
||||
private readonly ITokenService tokenService;
|
||||
private readonly UserManager<ApplicationUser> userManager;
|
||||
|
||||
public AccountController(
|
||||
UserManager<ApplicationUser> userManager,
|
||||
SignInManager<ApplicationUser> signInManager,
|
||||
IConfiguration configuration,
|
||||
ILogger<AccountController> logger,
|
||||
ITokenService tokenService)
|
||||
{
|
||||
this.userManager = userManager;
|
||||
this.signInManager = signInManager;
|
||||
this.configuration = configuration;
|
||||
this.logger = logger;
|
||||
this.tokenService = tokenService;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("token")]
|
||||
public async Task<IActionResult> CreateToken([FromBody]LoginModel model)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
try
|
||||
{
|
||||
//var u = await userManager.FindByNameAsync(model.Username);
|
||||
//u.PasswordHash = userManager.PasswordHasher.HashPassword(u, model.Password);
|
||||
//u.LastUpdated = DateTime.UtcNow;
|
||||
//await userManager.UpdateAsync(u);
|
||||
|
||||
// Login user
|
||||
var loginResult = await signInManager.PasswordSignInAsync(model.Username, model.Password, isPersistent: false, lockoutOnFailure: false);
|
||||
if (!loginResult.Succeeded)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
// If successful login return OK with generated token
|
||||
var user = await userManager.FindByNameAsync(model.Username);
|
||||
return Ok(this.tokenService.GenerateToken(user));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "Eror in CreateToken");
|
||||
return BadRequest();
|
||||
}
|
||||
}
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[HttpPost]
|
||||
[Route("refreshtoken")]
|
||||
public async Task<IActionResult> RefreshToken()
|
||||
{
|
||||
var username = User.Identity.Name ??
|
||||
User.Claims.Where(c => c.Properties.ContainsKey("unique_name")).Select(c => c.Value).FirstOrDefault();
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(username))
|
||||
{
|
||||
var user = await userManager.FindByNameAsync(username);
|
||||
return Ok(this.tokenService.GenerateToken(user));
|
||||
}
|
||||
else
|
||||
{
|
||||
ModelState.AddModelError("Authentication", "Authentication failed!");
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("register")]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> Register([FromBody] RegisterModel registerModel)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
var user = new ApplicationUser
|
||||
{
|
||||
UserName = registerModel.Username,
|
||||
Email = registerModel.Email,
|
||||
CreatedDate = DateTime.UtcNow
|
||||
};
|
||||
|
||||
var identityResult = await this.userManager.CreateAsync(user, registerModel.Password);
|
||||
if (identityResult.Succeeded)
|
||||
{
|
||||
await signInManager.SignInAsync(user, isPersistent: false);
|
||||
return Ok(this.tokenService.GenerateToken(user));
|
||||
}
|
||||
else
|
||||
{
|
||||
return BadRequest(identityResult.Errors);
|
||||
}
|
||||
}
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> ResetPassword([FromBody] ResetPasswordModel resetPasswordModel)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
var user = new ApplicationUser
|
||||
{
|
||||
UserName = resetPasswordModel.Username,
|
||||
Email = resetPasswordModel.Email,
|
||||
CreatedDate = DateTime.UtcNow
|
||||
};
|
||||
|
||||
var identityResult = await this.userManager.ResetPasswordAsync(user, resetPasswordModel.Token, resetPasswordModel.Password);
|
||||
if (identityResult.Succeeded)
|
||||
{
|
||||
await signInManager.SignInAsync(user, isPersistent: false);
|
||||
return Ok(this.tokenService.GenerateToken(user));
|
||||
}
|
||||
else
|
||||
{
|
||||
return BadRequest(identityResult.Errors);
|
||||
}
|
||||
}
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
}
|
||||
}
|
57
RoadieApi/Controllers/ArtistController.cs
Normal file
57
RoadieApi/Controllers/ArtistController.cs
Normal file
|
@ -0,0 +1,57 @@
|
|||
using Mapster;
|
||||
using Microsoft.AspNet.OData;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using roadie.Library.Setttings;
|
||||
using Roadie.Library.Caching;
|
||||
using Roadie.Library.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using models = Roadie.Api.Data.Models;
|
||||
|
||||
namespace Roadie.Api.Controllers
|
||||
{
|
||||
[Produces("application/json")]
|
||||
[Route("artist")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class ArtistController : EntityControllerBase
|
||||
{
|
||||
public ArtistController(IRoadieDbContext roadieDbContext, ILoggerFactory logger, ICacheManager cacheManager, IConfiguration configuration, IRoadieSettings roadieSettings)
|
||||
: base(roadieDbContext, cacheManager, configuration, roadieSettings)
|
||||
{
|
||||
this._logger = logger.CreateLogger("RoadieApi.Controllers.ArtistController"); ;
|
||||
}
|
||||
|
||||
[EnableQuery]
|
||||
public IActionResult Get()
|
||||
{
|
||||
return Ok(this._roadieDbContext.Artists.ProjectToType<models.Artist>());
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult Get(Guid id)
|
||||
{
|
||||
var key = id.ToString();
|
||||
var result = this._cacheManager.Get<models.Artist>(key, () =>
|
||||
{
|
||||
var d = this._roadieDbContext.Artists.FirstOrDefault(x => x.RoadieId == id);
|
||||
if (d != null)
|
||||
{
|
||||
return d.Adapt<models.Artist>();
|
||||
}
|
||||
return null;
|
||||
}, key);
|
||||
if (result == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
}
|
28
RoadieApi/Controllers/EntityControllerBase.cs
Normal file
28
RoadieApi/Controllers/EntityControllerBase.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using Microsoft.AspNet.OData;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using roadie.Library.Setttings;
|
||||
using Roadie.Library.Caching;
|
||||
using Roadie.Library.Data;
|
||||
|
||||
namespace Roadie.Api.Controllers
|
||||
{
|
||||
public abstract class EntityControllerBase : ODataController
|
||||
{
|
||||
protected readonly ICacheManager _cacheManager;
|
||||
protected readonly IConfiguration _configuration;
|
||||
protected readonly IRoadieDbContext _roadieDbContext;
|
||||
protected readonly IRoadieSettings _roadieSettings;
|
||||
|
||||
protected ILogger _logger;
|
||||
|
||||
public EntityControllerBase(IRoadieDbContext roadieDbContext, ICacheManager cacheManager, IConfiguration configuration, IRoadieSettings roadieSettings)
|
||||
{
|
||||
this._roadieDbContext = roadieDbContext;
|
||||
this._cacheManager = cacheManager;
|
||||
this._configuration = configuration;
|
||||
this._roadieSettings = roadieSettings;
|
||||
}
|
||||
}
|
||||
}
|
56
RoadieApi/Controllers/LabelController.cs
Normal file
56
RoadieApi/Controllers/LabelController.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
using Mapster;
|
||||
using Microsoft.AspNet.OData;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using roadie.Library.Setttings;
|
||||
using Roadie.Library.Caching;
|
||||
using Roadie.Library.Data;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using models = Roadie.Api.Data.Models;
|
||||
|
||||
namespace Roadie.Api.Controllers
|
||||
{
|
||||
[Produces("application/json")]
|
||||
[Route("label")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class LabelController : EntityControllerBase
|
||||
{
|
||||
public LabelController(IRoadieDbContext roadieDbContext, ILoggerFactory logger, ICacheManager cacheManager, IConfiguration configuration, IRoadieSettings roadieSettings)
|
||||
: base(roadieDbContext, cacheManager, configuration, roadieSettings)
|
||||
{
|
||||
this._logger = logger.CreateLogger("RoadieApi.Controllers.LabelController"); ;
|
||||
}
|
||||
|
||||
[EnableQuery]
|
||||
public IActionResult Get()
|
||||
{
|
||||
return Ok(this._roadieDbContext.Labels.ProjectToType<models.Label>());
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult Get(Guid id)
|
||||
{
|
||||
var key = id.ToString();
|
||||
var result = this._cacheManager.Get<models.Label>(key, () =>
|
||||
{
|
||||
var d = this._roadieDbContext.Labels.FirstOrDefault(x => x.RoadieId == id);
|
||||
if (d != null)
|
||||
{
|
||||
return d.Adapt<models.Label>();
|
||||
}
|
||||
return null;
|
||||
}, key);
|
||||
if (result == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
}
|
64
RoadieApi/Controllers/ReleaseController.cs
Normal file
64
RoadieApi/Controllers/ReleaseController.cs
Normal file
|
@ -0,0 +1,64 @@
|
|||
using Mapster;
|
||||
using Microsoft.AspNet.OData;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using roadie.Library.Setttings;
|
||||
using Roadie.Library.Caching;
|
||||
using Roadie.Library.Data;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using models = Roadie.Api.Data.Models;
|
||||
|
||||
namespace Roadie.Api.Controllers
|
||||
{
|
||||
[Produces("application/json")]
|
||||
[Route("release")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class ReleaseController : EntityControllerBase
|
||||
{
|
||||
public ReleaseController(IRoadieDbContext roadieDbContext, ILoggerFactory logger, ICacheManager cacheManager, IConfiguration configuration, IRoadieSettings roadieSettings)
|
||||
: base(roadieDbContext, cacheManager, configuration, roadieSettings)
|
||||
{
|
||||
this._logger = logger.CreateLogger("RoadieApi.Controllers.ReleaseController"); ;
|
||||
}
|
||||
|
||||
[EnableQuery]
|
||||
public IActionResult Get()
|
||||
{
|
||||
return Ok(this._roadieDbContext.Releases.ProjectToType<models.Release>());
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult Get(Guid id)
|
||||
{
|
||||
var key = id.ToString();
|
||||
var result = this._cacheManager.Get<models.Release>(key, () =>
|
||||
{
|
||||
var d = this._roadieDbContext
|
||||
.Releases
|
||||
.Include(x => x.Artist)
|
||||
.Include(x => x.Labels).Include("Labels.Label")
|
||||
.Include(x => x.Medias).Include("Medias.Tracks")
|
||||
.Include(x => x.Genres).Include("Genres.Genre")
|
||||
.Include(x => x.Collections).Include("Collections.Collection")
|
||||
.FirstOrDefault(x => x.RoadieId == id);
|
||||
if (d != null)
|
||||
{
|
||||
return d.Adapt<models.Release>();
|
||||
}
|
||||
return null;
|
||||
}, key);
|
||||
if (result == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
}
|
56
RoadieApi/Controllers/TrackController.cs
Normal file
56
RoadieApi/Controllers/TrackController.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
using Mapster;
|
||||
using Microsoft.AspNet.OData;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using roadie.Library.Setttings;
|
||||
using Roadie.Library.Caching;
|
||||
using Roadie.Library.Data;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using models = Roadie.Api.Data.Models;
|
||||
|
||||
namespace Roadie.Api.Controllers
|
||||
{
|
||||
[Produces("application/json")]
|
||||
[Route("track")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class TrackController : EntityControllerBase
|
||||
{
|
||||
public TrackController(IRoadieDbContext roadieDbContext, ILoggerFactory logger, ICacheManager cacheManager, IConfiguration configuration, IRoadieSettings roadieSettings)
|
||||
: base(roadieDbContext, cacheManager, configuration, roadieSettings)
|
||||
{
|
||||
this._logger = logger.CreateLogger("RoadieApi.Controllers.TrackController"); ;
|
||||
}
|
||||
|
||||
[EnableQuery]
|
||||
public IActionResult Get()
|
||||
{
|
||||
return Ok(this._roadieDbContext.Tracks.ProjectToType<models.Track>());
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult Get(Guid id)
|
||||
{
|
||||
var key = id.ToString();
|
||||
var result = this._cacheManager.Get<models.Track>(key, () =>
|
||||
{
|
||||
var d = this._roadieDbContext.Tracks.FirstOrDefault(x => x.RoadieId == id);
|
||||
if (d != null)
|
||||
{
|
||||
return d.Adapt<models.Track>();
|
||||
}
|
||||
return null;
|
||||
}, key);
|
||||
if (result == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
}
|
17
RoadieApi/Models/LoginModel.cs
Normal file
17
RoadieApi/Models/LoginModel.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Api.Models
|
||||
{
|
||||
public class LoginModel
|
||||
{
|
||||
[Required]
|
||||
public string Username { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
17
RoadieApi/Models/RegisterModel.cs
Normal file
17
RoadieApi/Models/RegisterModel.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Roadie.Api.Models
|
||||
{
|
||||
public class RegisterModel : LoginModel
|
||||
{
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
public String Email { get; set; }
|
||||
|
||||
[Required]
|
||||
[Compare("Password")]
|
||||
[RegularExpression("^((?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])|(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[^a-zA-Z0-9])|(?=.*?[A-Z])(?=.*?[0-9])(?=.*?[^a-zA-Z0-9])|(?=.*?[a-z])(?=.*?[0-9])(?=.*?[^a-zA-Z0-9])).{8,}$", ErrorMessage = "Passwords must be at least 8 characters and contain at 3 of 4 of the following: upper case (A-Z), lower case (a-z), number (0-9) and special character (e.g. !@#$%^&*)")]
|
||||
public String PasswordConfirmation { get; set; }
|
||||
}
|
||||
}
|
14
RoadieApi/Models/ResetPasswordModel.cs
Normal file
14
RoadieApi/Models/ResetPasswordModel.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Api.Models
|
||||
{
|
||||
public class ResetPasswordModel : RegisterModel
|
||||
{
|
||||
[Required]
|
||||
public string Token { get; set; }
|
||||
}
|
||||
}
|
50
RoadieApi/Program.cs
Normal file
50
RoadieApi/Program.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Roadie.Api
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateWebHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.UseStartup<Startup>();
|
||||
|
||||
|
||||
//public static void Main(string[] args)
|
||||
//{
|
||||
// var config = new ConfigurationBuilder()
|
||||
// .SetBasePath(Directory.GetCurrentDirectory())
|
||||
// .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||
// .AddJsonFile("appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
|
||||
// .AddCommandLine(args)
|
||||
// .Build();
|
||||
|
||||
// var host = new WebHostBuilder()
|
||||
// .UseKestrel()
|
||||
// .UseConfiguration(config)
|
||||
// .UseContentRoot(Directory.GetCurrentDirectory())
|
||||
// .ConfigureLogging((hostingContext, logging) =>
|
||||
// {
|
||||
// logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
|
||||
// })
|
||||
// .UseStartup<Startup>()
|
||||
// .Build();
|
||||
|
||||
// host.Run();
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
11
RoadieApi/Properties/launchSettings.json
Normal file
11
RoadieApi/Properties/launchSettings.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"profiles": {
|
||||
"Roadie.Api": {
|
||||
"commandName": "Project",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "http://localhost:5123/"
|
||||
}
|
||||
}
|
||||
}
|
28
RoadieApi/Roadie.Api.csproj
Normal file
28
RoadieApi/Roadie.Api.csproj
Normal file
|
@ -0,0 +1,28 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Mapster" Version="3.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.1.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OData" Version="7.0.1" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Roadie.Api.Data\Roadie.Api.Data.csproj" />
|
||||
<ProjectReference Include="..\RoadieLibrary\Roadie.Library.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
14
RoadieApi/Services/ITokenService.cs
Normal file
14
RoadieApi/Services/ITokenService.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using Roadie.Library.Data;
|
||||
using Roadie.Library.Identity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Api.Services
|
||||
{
|
||||
public interface ITokenService
|
||||
{
|
||||
string GenerateToken(ApplicationUser user);
|
||||
}
|
||||
}
|
49
RoadieApi/Services/TokenService.cs
Normal file
49
RoadieApi/Services/TokenService.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using Roadie.Library.Data;
|
||||
using Roadie.Library.Identity;
|
||||
using System;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace Roadie.Api.Services
|
||||
{
|
||||
public class TokenService : ITokenService
|
||||
{
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
public TokenService(IConfiguration configuration)
|
||||
{
|
||||
this._configuration = configuration;
|
||||
}
|
||||
|
||||
public string GenerateToken(ApplicationUser user)
|
||||
{
|
||||
var utcNow = DateTime.UtcNow;
|
||||
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
|
||||
var claims = new Claim[]
|
||||
{
|
||||
new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
|
||||
new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
||||
new Claim(JwtRegisteredClaimNames.Iat, utcNow.ToString())
|
||||
};
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(this._configuration.GetValue<String>("Tokens:PrivateKey")));
|
||||
var signingCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(securityKey, Microsoft.IdentityModel.Tokens.SecurityAlgorithms.HmacSha256Signature);
|
||||
|
||||
var jwt = new JwtSecurityToken(
|
||||
signingCredentials: signingCredentials,
|
||||
claims: claims,
|
||||
notBefore: utcNow,
|
||||
expires: utcNow.AddSeconds(this._configuration.GetValue<int>("Tokens:Lifetime")),
|
||||
audience: this._configuration.GetValue<String>("Tokens:Audience"),
|
||||
issuer: this._configuration.GetValue<String>("Tokens:Issuer")
|
||||
);
|
||||
|
||||
return new JwtSecurityTokenHandler().WriteToken(jwt);
|
||||
}
|
||||
}
|
||||
}
|
176
RoadieApi/Startup.cs
Normal file
176
RoadieApi/Startup.cs
Normal file
|
@ -0,0 +1,176 @@
|
|||
using Mapster;
|
||||
using Microsoft.AspNet.OData.Builder;
|
||||
using Microsoft.AspNet.OData.Extensions;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Microsoft.OData.Edm;
|
||||
using Newtonsoft.Json;
|
||||
using roadie.Library.Setttings;
|
||||
using Roadie.Api.Services;
|
||||
using Roadie.Library.Caching;
|
||||
using Roadie.Library.Data;
|
||||
using Roadie.Library.Identity;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using models = Roadie.Api.Data.Models;
|
||||
|
||||
namespace Roadie.Api
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
|
||||
public Startup(IConfiguration configuration, ILoggerFactory loggerFactory)
|
||||
{
|
||||
this._configuration = configuration;
|
||||
this._loggerFactory = loggerFactory;
|
||||
TypeAdapterConfig.GlobalSettings.Default.PreserveReference(true);
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IHostingEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
loggerFactory.AddConsole(LogLevel.Trace);
|
||||
|
||||
app.UseCors("Cors");
|
||||
app.UseAuthentication();
|
||||
//app.UseSwagger();
|
||||
//app.UseSwaggerUI(c =>
|
||||
//{
|
||||
// c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyComics API v1");
|
||||
// c.RoutePrefix = string.Empty;
|
||||
//});
|
||||
app.UseMvc(b =>
|
||||
{
|
||||
b.Select().Expand().Filter().OrderBy().MaxTop(100).Count();
|
||||
b.MapODataServiceRoute("odata", "odata", GetEdmModel());
|
||||
});
|
||||
}
|
||||
|
||||
public static string AssemblyDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
|
||||
var uri = new UriBuilder(codeBase);
|
||||
string path = Uri.UnescapeDataString(uri.Path);
|
||||
return Path.GetDirectoryName(path);
|
||||
}
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddCors(options => options.AddPolicy("Cors", builder =>
|
||||
{
|
||||
builder
|
||||
.AllowAnyOrigin()
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyHeader();
|
||||
}));
|
||||
|
||||
services.AddSingleton<ITokenService, TokenService>();
|
||||
|
||||
services.AddSingleton<IRoadieSettings, RoadieSettings>(options =>
|
||||
{
|
||||
var settingsPath = Path.Combine(AssemblyDirectory, "settings.json");
|
||||
var settings = new RoadieSettings();
|
||||
if (File.Exists(settingsPath))
|
||||
{
|
||||
var settingsFileContents = File.ReadAllText(settingsPath);
|
||||
var fromSettingsFile = Newtonsoft.Json.JsonConvert.DeserializeObject<RoadieSettings>(settingsFileContents);
|
||||
if (fromSettingsFile != null)
|
||||
{
|
||||
settings.MergeWith(fromSettingsFile);
|
||||
}
|
||||
}
|
||||
return settings;
|
||||
});
|
||||
|
||||
var cacheManager = new MemoryCacheManager(this._loggerFactory.CreateLogger<MemoryCacheManager>(), new CachePolicy(TimeSpan.FromHours(1)));
|
||||
services.AddSingleton<ICacheManager>(cacheManager);
|
||||
|
||||
services.AddEntityFrameworkMySql().AddDbContext<ApplicationUserDbContext>(options =>
|
||||
options.UseMySql(this._configuration.GetConnectionString("RoadieDatabaseConnection")));
|
||||
|
||||
services.AddEntityFrameworkMySql().AddDbContext<IRoadieDbContext, RoadieDbContext>(options =>
|
||||
options.UseMySql(this._configuration.GetConnectionString("RoadieDatabaseConnection")));
|
||||
|
||||
services.AddIdentity<ApplicationUser, ApplicationRole>()
|
||||
.AddEntityFrameworkStores<ApplicationUserDbContext>()
|
||||
.AddClaimsPrincipalFactory<ApplicationClaimsFactory>();
|
||||
|
||||
services.AddAuthorization(options =>
|
||||
{
|
||||
options.AddPolicy("Admin", policy => policy.RequireClaim("Admin"));
|
||||
options.AddPolicy("Editor", policy => policy.RequireClaim("Editor"));
|
||||
});
|
||||
|
||||
services.Configure<IConfiguration>(this._configuration);
|
||||
|
||||
var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(this._configuration["Tokens:PrivateKey"]));
|
||||
services.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
}).AddJwtBearer(config =>
|
||||
{
|
||||
config.RequireHttpsMetadata = false;
|
||||
config.SaveToken = true;
|
||||
config.TokenValidationParameters = new TokenValidationParameters()
|
||||
{
|
||||
IssuerSigningKey = securityKey,
|
||||
ValidateAudience = true,
|
||||
ValidAudience = this._configuration["Tokens:Audience"],
|
||||
ValidateIssuer = true,
|
||||
ValidIssuer = this._configuration["Tokens:Issuer"],
|
||||
ValidateLifetime = true,
|
||||
ValidateIssuerSigningKey = true
|
||||
};
|
||||
});
|
||||
|
||||
//services.AddSwaggerGen(c =>
|
||||
//{
|
||||
// c.SwaggerDoc("v1", new Info
|
||||
// {
|
||||
// Title = "Roadie API",
|
||||
// Version = "v1"
|
||||
// });
|
||||
//});
|
||||
|
||||
services.AddOData();
|
||||
|
||||
services.AddMvc()
|
||||
.AddJsonOptions(options =>
|
||||
{
|
||||
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
|
||||
})
|
||||
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
|
||||
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel()
|
||||
{
|
||||
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
|
||||
builder.EntitySet<models.Artist>("Artist");
|
||||
builder.EntitySet<models.Label>("Label");
|
||||
builder.EntitySet<models.Release>("Release");
|
||||
return builder.GetEdmModel();
|
||||
}
|
||||
}
|
||||
}
|
10
RoadieApi/appsettings.Development.json
Normal file
10
RoadieApi/appsettings.Development.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
}
|
54
RoadieApi/appsettings.json
Normal file
54
RoadieApi/appsettings.json
Normal file
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
"urls": "http://localhost:5123",
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"Console": {
|
||||
"LogLevel": {
|
||||
"Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
|
||||
"Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
|
||||
"Microsoft.AspNetCore.Mvc.Razor": "Error",
|
||||
"Default": "Trace"
|
||||
}
|
||||
},
|
||||
"LogLevel": {
|
||||
"Information": "Debug"
|
||||
}
|
||||
},
|
||||
"Tokens": {
|
||||
"PrivateKey": "!1232bcdb4bebc80a0d080883d6deefuxlsh8bfc920c2a8cskeuxd8349sk412aa785662e594b4df48cb46aa3c652b40b3#",
|
||||
"PublicKey": "91i4874y24134E50sz7dges68AB08",
|
||||
"Lifetime": "86400",
|
||||
"Issuer": "http://localhost:5123",
|
||||
"Audience": "http://localhost:5500"
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RoadieDatabaseConnection": "server=voyager;userid=roadie;password=MenAtW0rk668;persistsecurityinfo=True;database=roadie;ConvertZeroDateTime=true"
|
||||
},
|
||||
"Settings": {
|
||||
"SecretKey": "a9kf^!y@rd-ci0&7l#da6ko$(l@_$9(y^r^a@2j+8!7zpk!zw88wi069",
|
||||
"SiteName": "Roadie",
|
||||
"InboundFolder": "Z:/incoming/",
|
||||
"LibraryFolder": "Z:/library/",
|
||||
"SingleArtistHoldingFolder": "Z:/single_holding/",
|
||||
"ArtistNameReplace": {
|
||||
"AC/DC": [ "AC; DC", "AC;DC", "AC/ DC", "AC DC" ],
|
||||
"Love/Hate": [ "Love; Hate", "Love;Hate", "Love/ Hate", "Love Hate" ]
|
||||
},
|
||||
"ApiKeys": [
|
||||
{
|
||||
"ApiName": "BingImageSearch",
|
||||
"Key": "<KEY HERE>"
|
||||
},
|
||||
{
|
||||
"ApiName": "LastFMApiKey",
|
||||
"Key": "<KEY HERE>",
|
||||
"KeySecret": "<SECRET HERE>"
|
||||
},
|
||||
{
|
||||
"ApiName": "DiscogsConsumerKey",
|
||||
"Key": "<KEY HERE>",
|
||||
"KeySecret": "<SECRET HERE>"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
74
RoadieLibrary/Caching/CacheManagerBase.cs
Normal file
74
RoadieLibrary/Caching/CacheManagerBase.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
namespace Roadie.Library.Caching
|
||||
{
|
||||
public abstract class CacheManagerBase : ICacheManager
|
||||
{
|
||||
protected readonly CachePolicy _defaultPolicy = null;
|
||||
protected readonly ILogger _logger = null;
|
||||
protected readonly JsonSerializerSettings _serializerSettings = null;
|
||||
|
||||
public CacheManagerBase(ILogger logger, CachePolicy defaultPolicy)
|
||||
{
|
||||
this._logger = logger;
|
||||
this._defaultPolicy = defaultPolicy;
|
||||
this._serializerSettings = new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new IgnoreJsonAttributesResolver(),
|
||||
Formatting = Formatting.Indented
|
||||
};
|
||||
}
|
||||
|
||||
public abstract bool Add<TCacheValue>(string key, TCacheValue value);
|
||||
|
||||
public abstract bool Add<TCacheValue>(string key, TCacheValue value, CachePolicy policy);
|
||||
|
||||
public abstract bool Add<TCacheValue>(string key, TCacheValue value, string region, CachePolicy policy);
|
||||
|
||||
public abstract void Clear();
|
||||
|
||||
public abstract void ClearRegion(string region);
|
||||
|
||||
public abstract void Dispose();
|
||||
|
||||
public abstract bool Exists<TOut>(string key);
|
||||
|
||||
public abstract bool Exists<TOut>(string key, string region);
|
||||
|
||||
public abstract TOut Get<TOut>(string key);
|
||||
|
||||
public abstract TOut Get<TOut>(string key, string region);
|
||||
|
||||
public abstract TOut Get<TOut>(string key, Func<TOut> getItem, string region);
|
||||
|
||||
public abstract TOut Get<TOut>(string key, Func<TOut> getItem, string region, CachePolicy policy);
|
||||
|
||||
public abstract bool Remove(string key);
|
||||
|
||||
public abstract bool Remove(string key, string region);
|
||||
|
||||
protected TOut Deserialize<TOut>(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s))
|
||||
{
|
||||
return default(TOut);
|
||||
}
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<TOut>(s, this._serializerSettings);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this._logger.LogError(ex, null, null);
|
||||
}
|
||||
return default(TOut);
|
||||
}
|
||||
|
||||
protected string Serialize(object o)
|
||||
{
|
||||
return JsonConvert.SerializeObject(o, this._serializerSettings);
|
||||
}
|
||||
}
|
||||
}
|
24
RoadieLibrary/Caching/CachePolicy.cs
Normal file
24
RoadieLibrary/Caching/CachePolicy.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Caching
|
||||
{
|
||||
public sealed class CachePolicy
|
||||
{
|
||||
private readonly TimeSpan expiresAfter;
|
||||
private readonly bool renewLeaseOnAccess;
|
||||
|
||||
public CachePolicy(TimeSpan expiresAfter, bool renewLeaseOnAccess = false)
|
||||
{
|
||||
this.expiresAfter = expiresAfter;
|
||||
this.renewLeaseOnAccess = renewLeaseOnAccess;
|
||||
}
|
||||
|
||||
public TimeSpan ExpiresAfter { get { return this.expiresAfter; } }
|
||||
/// <summary>
|
||||
/// If specified, each read of the item from the cache will reset the expiration time
|
||||
/// </summary>
|
||||
public bool RenewLeaseOnAccess { get { return this.renewLeaseOnAccess; } }
|
||||
}
|
||||
}
|
33
RoadieLibrary/Caching/ICacheManager.cs
Normal file
33
RoadieLibrary/Caching/ICacheManager.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
|
||||
namespace Roadie.Library.Caching
|
||||
{
|
||||
public interface ICacheManager : IDisposable
|
||||
{
|
||||
bool Add<TCacheValue>(string key, TCacheValue value);
|
||||
|
||||
bool Add<TCacheValue>(string key, TCacheValue value, CachePolicy policy);
|
||||
|
||||
bool Add<TCacheValue>(string key, TCacheValue value, string region, CachePolicy policy);
|
||||
|
||||
void Clear();
|
||||
|
||||
void ClearRegion(string region);
|
||||
|
||||
bool Exists<TOut>(string key);
|
||||
|
||||
bool Exists<TOut>(string key, string region);
|
||||
|
||||
TOut Get<TOut>(string key, string region);
|
||||
|
||||
TOut Get<TOut>(string key);
|
||||
|
||||
TOut Get<TOut>(string key, Func<TOut> getItem, string region);
|
||||
|
||||
TOut Get<TOut>(string key, Func<TOut> getItem, string region, CachePolicy policy);
|
||||
|
||||
bool Remove(string key);
|
||||
|
||||
bool Remove(string key, string region);
|
||||
}
|
||||
}
|
111
RoadieLibrary/Caching/MemoryCacheManager.cs
Normal file
111
RoadieLibrary/Caching/MemoryCacheManager.cs
Normal file
|
@ -0,0 +1,111 @@
|
|||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using StackExchange.Redis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Caching
|
||||
{
|
||||
public class MemoryCacheManager : CacheManagerBase
|
||||
{
|
||||
private MemoryCache _cache;
|
||||
|
||||
public MemoryCacheManager(ILogger logger, CachePolicy defaultPolicy)
|
||||
: base(logger, defaultPolicy)
|
||||
{
|
||||
|
||||
this._cache = new MemoryCache(new MemoryCacheOptions());
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value)
|
||||
{
|
||||
using (var entry = _cache.CreateEntry(key))
|
||||
{
|
||||
_cache.Set(key, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value, CachePolicy policy)
|
||||
{
|
||||
using (var entry = _cache.CreateEntry(key))
|
||||
{
|
||||
_cache.Set(key, value, new MemoryCacheEntryOptions
|
||||
{
|
||||
AbsoluteExpiration = DateTimeOffset.UtcNow.Add(policy.ExpiresAfter) // new DateTimeOffset(DateTime.UtcNow, policy.ExpiresAfter)
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value, string region, CachePolicy policy)
|
||||
{
|
||||
return this.Add(key, value, policy);
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
this._cache = new MemoryCache(new MemoryCacheOptions());
|
||||
}
|
||||
|
||||
public override void ClearRegion(string region)
|
||||
{
|
||||
this.Clear();
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
// throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool Exists<TOut>(string key)
|
||||
{
|
||||
return this.Get<TOut>(key) != null;
|
||||
}
|
||||
|
||||
public override bool Exists<TOut>(string key, string region)
|
||||
{
|
||||
return this.Exists<TOut>(key);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key)
|
||||
{
|
||||
return this._cache.Get<TOut>(key);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key, string region)
|
||||
{
|
||||
return this.Get<TOut>(key);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key, Func<TOut> getItem, string region)
|
||||
{
|
||||
return this.Get<TOut>(key, getItem, region, this._defaultPolicy);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key, Func<TOut> getItem, string region, CachePolicy policy)
|
||||
{
|
||||
var r = this.Get<TOut>(key, region);
|
||||
if (r == null)
|
||||
{
|
||||
r = getItem();
|
||||
this.Add(key, r, region, policy);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public override bool Remove(string key)
|
||||
{
|
||||
this._cache.Remove(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Remove(string key, string region)
|
||||
{
|
||||
return this.Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
189
RoadieLibrary/Caching/RedisCacheManager.cs
Normal file
189
RoadieLibrary/Caching/RedisCacheManager.cs
Normal file
|
@ -0,0 +1,189 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using StackExchange.Redis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Caching
|
||||
{
|
||||
/// <summary>
|
||||
/// Redis Cache implemention
|
||||
/// </summary>
|
||||
/// <typeparam name="TCacheValue"></typeparam>
|
||||
public class RedisCacheManager : CacheManagerBase
|
||||
{
|
||||
private bool _doTraceLogging = true;
|
||||
|
||||
private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
|
||||
{
|
||||
return ConnectionMultiplexer.Connect("192.168.1.253:6379,allowAdmin=true");
|
||||
});
|
||||
|
||||
public static ConnectionMultiplexer Connection
|
||||
{
|
||||
get
|
||||
{
|
||||
return lazyConnection.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private IDatabase _redis = null;
|
||||
private IDatabase Redis
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._redis ?? (this._redis = Connection.GetDatabase());
|
||||
}
|
||||
}
|
||||
|
||||
public RedisCacheManager(ILogger logger, CachePolicy defaultPolicy)
|
||||
: base(logger, defaultPolicy)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value)
|
||||
{
|
||||
return this.Add(key, value, this._defaultPolicy);
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value, CachePolicy policy)
|
||||
{
|
||||
return this.Add(key, value, null, this._defaultPolicy);
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value, string region, CachePolicy policy)
|
||||
{
|
||||
if (this._doTraceLogging)
|
||||
{
|
||||
this._logger.LogTrace("Added [{0}], Region [{1}]", key, region);
|
||||
}
|
||||
return this.Redis.StringSet(key, this.Serialize(value));
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
var endpoints = Connection.GetEndPoints();
|
||||
var server = Connection.GetServer(endpoints[0]);
|
||||
server.FlushAllDatabases();
|
||||
if (this._doTraceLogging)
|
||||
{
|
||||
this._logger.LogTrace("Cleared Cache");
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearRegion(string region)
|
||||
{
|
||||
this.Clear();
|
||||
}
|
||||
|
||||
// Dispose() calls Dispose(true)
|
||||
public override void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection.Close();
|
||||
Connection.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
// free native resources here if there are any
|
||||
}
|
||||
|
||||
public override bool Exists<TOut>(string key)
|
||||
{
|
||||
return this.Exists<TOut>(key, null);
|
||||
}
|
||||
|
||||
public override bool Exists<TOut>(string key, string region)
|
||||
{
|
||||
return this.Redis.KeyExists(key);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key)
|
||||
{
|
||||
return this.Get<TOut>(key, null);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key, string region)
|
||||
{
|
||||
return this.Get<TOut>(key, region, this._defaultPolicy);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key, Func<TOut> getItem, string region)
|
||||
{
|
||||
return this.Get<TOut>(key, getItem, region, this._defaultPolicy);
|
||||
}
|
||||
|
||||
private TOut Get<TOut>(string key, string region, CachePolicy policy)
|
||||
{
|
||||
var result = this.Deserialize<TOut>(this.Redis.StringGet(key));
|
||||
if (result == null)
|
||||
{
|
||||
if (this._doTraceLogging)
|
||||
{
|
||||
this._logger.LogTrace("Get Cache Miss Key [{0}], Region [{1}]", key, region);
|
||||
}
|
||||
}
|
||||
else if (this._doTraceLogging)
|
||||
{
|
||||
this._logger.LogTrace("Get Cache Hit Key [{0}], Region [{1}]", key, region);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public override TOut Get<TOut>(string key, Func<TOut> getItem, string region, CachePolicy policy)
|
||||
{
|
||||
var r = this.Get<TOut>(key, region);
|
||||
if(r == null)
|
||||
{
|
||||
r = getItem();
|
||||
this.Add(key, r, region, policy);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
public override bool Remove(string key)
|
||||
{
|
||||
return this.Remove(key, null);
|
||||
}
|
||||
|
||||
|
||||
public override bool Remove(string key, string region)
|
||||
{
|
||||
if (this.Redis.KeyExists(key))
|
||||
{
|
||||
this.Redis.KeyDelete(key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class IgnoreJsonAttributesResolver : DefaultContractResolver
|
||||
{
|
||||
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
|
||||
{
|
||||
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
|
||||
foreach (var prop in props)
|
||||
{
|
||||
prop.Ignored = false; // Ignore [JsonIgnore]
|
||||
prop.Converter = null; // Ignore [JsonConverter]
|
||||
prop.PropertyName = prop.UnderlyingName; // restore original property name
|
||||
}
|
||||
return props;
|
||||
}
|
||||
}
|
||||
}
|
20
RoadieLibrary/Configuration/ApiKey.cs
Normal file
20
RoadieLibrary/Configuration/ApiKey.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace roadie.Library.Setttings
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a Api Key used by Roadie to interact with an API (ie KeyName is "BingImageSearch" and its key is the BingImageSearch Key)
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ApiKey
|
||||
{
|
||||
public string ApiName { get; set; }
|
||||
public string Key { get; set; }
|
||||
public string Secret { get; set; }
|
||||
|
||||
}
|
||||
}
|
25
RoadieLibrary/Configuration/Converting.cs
Normal file
25
RoadieLibrary/Configuration/Converting.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace roadie.Library.Setttings
|
||||
{
|
||||
[Serializable]
|
||||
public class Converting
|
||||
{
|
||||
public bool DoDeleteAfter { get; set; }
|
||||
public string M4AConvertCommand { get; set; }
|
||||
public string OGGConvertCommand { get; set; }
|
||||
public string APEConvertCommand { get; set; }
|
||||
|
||||
public Converting()
|
||||
{
|
||||
this.DoDeleteAfter = true;
|
||||
this.M4AConvertCommand = "ffmpeg -i \"{0}\" -acodec libmp3lame -q:a 0 \"{1}\"";
|
||||
this.OGGConvertCommand = "ffmpeg -i \"{0}\" -acodec libmp3lame -q:a 0 \"{1}\"";
|
||||
this.APEConvertCommand = "ffmpeg -i \"{0}\" \"{1}\"";
|
||||
}
|
||||
}
|
||||
}
|
36
RoadieLibrary/Configuration/IRoadieSettings.cs
Normal file
36
RoadieLibrary/Configuration/IRoadieSettings.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace roadie.Library.Setttings
|
||||
{
|
||||
public interface IRoadieSettings
|
||||
{
|
||||
List<ApiKey> ApiKeys { get; set; }
|
||||
Dictionary<string, List<string>> ArtistNameReplace { get; set; }
|
||||
Converting Converting { get; set; }
|
||||
string DefaultTimeZone { get; set; }
|
||||
string DiagnosticsPassword { get; set; }
|
||||
IEnumerable<string> DontDoMetaDataProvidersSearchArtists { get; set; }
|
||||
IEnumerable<string> FileExtensionsToDelete { get; set; }
|
||||
string InboundFolder { get; set; }
|
||||
Integrations Integrations { get; set; }
|
||||
string LibraryFolder { get; set; }
|
||||
Processing Processing { get; set; }
|
||||
bool RecordNoResultSearches { get; set; }
|
||||
RedisCache Redis { get; set; }
|
||||
string SecretKey { get; set; }
|
||||
string SingleArtistHoldingFolder { get; set; }
|
||||
string SiteName { get; set; }
|
||||
string SmtpFromAddress { get; set; }
|
||||
string SmtpHost { get; set; }
|
||||
string SmtpPassword { get; set; }
|
||||
int SmtpPort { get; set; }
|
||||
string SmtpUsername { get; set; }
|
||||
bool SmtpUseSSl { get; set; }
|
||||
Thumbnails Thumbnails { get; set; }
|
||||
Dictionary<string, string> TrackPathReplace { get; set; }
|
||||
bool UseSSLBehindProxy { get; set; }
|
||||
string WebsocketAddress { get; set; }
|
||||
|
||||
void MergeWith(RoadieSettings secondary);
|
||||
}
|
||||
}
|
159
RoadieLibrary/Configuration/Integrations.cs
Normal file
159
RoadieLibrary/Configuration/Integrations.cs
Normal file
|
@ -0,0 +1,159 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace roadie.Library.Setttings
|
||||
{
|
||||
public class Integrations
|
||||
{
|
||||
private bool _lastFmEnabled = true;
|
||||
private bool _discogsEnabled = true;
|
||||
|
||||
private string _lastFMApiKey = null;
|
||||
private string _lastFMSecret = null;
|
||||
|
||||
private string _discogsConsumerKey = null;
|
||||
private string _discogsConsumerSecret = null;
|
||||
|
||||
public string LastFMApiKey
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this._lastFMApiKey))
|
||||
{
|
||||
// TODO
|
||||
//var keySetting = SettingsHelper.Instance.ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey");
|
||||
//if (keySetting != null)
|
||||
//{
|
||||
// this._lastFMApiKey = keySetting.Key;
|
||||
// this._lastFMSecret = keySetting.Secret;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled");
|
||||
//}
|
||||
}
|
||||
return this._lastFMApiKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string LastFmApiSecret
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this._lastFMSecret))
|
||||
{
|
||||
// TODO
|
||||
//var keySetting = SettingsHelper.Instance.ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey");
|
||||
//if (keySetting != null)
|
||||
//{
|
||||
// this._lastFMApiKey = keySetting.Key;
|
||||
// this._lastFMSecret = keySetting.Secret;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled");
|
||||
//}
|
||||
}
|
||||
return this._lastFMSecret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string DiscogsConsumerKey
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this._discogsConsumerKey))
|
||||
{
|
||||
// TODO
|
||||
//var keySetting = SettingsHelper.Instance.ApiKeys.FirstOrDefault(x => x.ApiName == "DiscogsConsumerKey");
|
||||
//if (keySetting != null)
|
||||
//{
|
||||
// this._discogsConsumerKey = keySetting.Key;
|
||||
// this._discogsConsumerSecret = keySetting.Secret;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Trace.WriteLine("Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled");
|
||||
//}
|
||||
}
|
||||
return this._discogsConsumerKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string DiscogsConsumerSecret
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this._discogsConsumerSecret))
|
||||
{
|
||||
// TODO
|
||||
//var keySetting = SettingsHelper.Instance.ApiKeys.FirstOrDefault(x => x.ApiName == "DiscogsConsumerKey");
|
||||
//if (keySetting != null)
|
||||
//{
|
||||
// this._discogsConsumerKey = keySetting.Key;
|
||||
// this._discogsConsumerSecret = keySetting.Secret;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Trace.WriteLine("Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled");
|
||||
//}
|
||||
}
|
||||
return this._discogsConsumerSecret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public short? DiscogsReadWriteTimeout { get; set; }
|
||||
public short? DiscogsTimeout { get; set; }
|
||||
|
||||
public bool ITunesProviderEnabled { get; set; }
|
||||
public bool MusicBrainzProviderEnabled { get; set; }
|
||||
public bool SpotifyProviderEnabled { get; set; }
|
||||
public bool DiscogsProviderEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
if(string.IsNullOrEmpty(this.DiscogsConsumerKey) || string.IsNullOrEmpty(this.DiscogsConsumerSecret))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this._discogsEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
this._discogsEnabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool LastFmProviderEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.LastFMApiKey) || string.IsNullOrEmpty(this.LastFmApiSecret))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this._lastFmEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
this._lastFmEnabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Integrations()
|
||||
{
|
||||
this.ITunesProviderEnabled = true;
|
||||
this.MusicBrainzProviderEnabled = true;
|
||||
this.SpotifyProviderEnabled = true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
55
RoadieLibrary/Configuration/Processing.cs
Normal file
55
RoadieLibrary/Configuration/Processing.cs
Normal file
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace roadie.Library.Setttings
|
||||
{
|
||||
[Serializable]
|
||||
public class Processing
|
||||
{
|
||||
public bool DoAudioCleanup { get; set; }
|
||||
public bool DoClearComments { get; set; }
|
||||
public bool DoDeleteUnknowns { get; set; }
|
||||
public bool DoFolderArtistNameSet { get; set; }
|
||||
public bool DoMoveUnknowns { get; set; }
|
||||
public bool DoParseFromDiscogsDB { get; private set; }
|
||||
public bool DoParseFromDiscogsDBFindingTrackForArtist { get; private set; }
|
||||
public bool DoParseFromFileName { get; set; }
|
||||
public bool DoParseFromLastFM { get; private set; }
|
||||
public bool DoParseFromMusicBrainz { get; private set; }
|
||||
public bool DoSaveEditsToTags { get; set; }
|
||||
public Dictionary<string,string> ReplaceStrings { get; set; }
|
||||
public int MaximumArtistImagesToAdd { get; set; }
|
||||
public int MaximumReleaseImagesToAdd { get; set; }
|
||||
public string RemoveStringsRegex { get; set; }
|
||||
public string UnknownFolder { get; set; }
|
||||
|
||||
public Processing()
|
||||
{
|
||||
this.DoAudioCleanup = true;
|
||||
this.DoSaveEditsToTags = true;
|
||||
this.DoClearComments = true;
|
||||
this.ReplaceStrings = new Dictionary<string, string>();
|
||||
this.ReplaceStrings.Add("-OBSERVER", "");
|
||||
this.ReplaceStrings.Add("[Torrent Tatty]", "");
|
||||
this.ReplaceStrings.Add("^", "");
|
||||
this.ReplaceStrings.Add("_", " ");
|
||||
this.ReplaceStrings.Add("-", " ");
|
||||
this.ReplaceStrings.Add("~", ",");
|
||||
|
||||
this.RemoveStringsRegex = @"\b[0-9]+\s#\s\b";
|
||||
|
||||
this.MaximumArtistImagesToAdd = 12;
|
||||
this.MaximumReleaseImagesToAdd = 12;
|
||||
|
||||
this.DoParseFromFileName = true;
|
||||
this.DoParseFromDiscogsDBFindingTrackForArtist = true;
|
||||
this.DoParseFromDiscogsDB = true;
|
||||
this.DoParseFromMusicBrainz = true;
|
||||
this.DoParseFromLastFM = true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
14
RoadieLibrary/Configuration/RedisCache.cs
Normal file
14
RoadieLibrary/Configuration/RedisCache.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace roadie.Library.Setttings
|
||||
{
|
||||
[Serializable]
|
||||
public class RedisCache
|
||||
{
|
||||
public string ConnectionString { get; set; }
|
||||
}
|
||||
}
|
80
RoadieLibrary/Configuration/RoadieSettings.cs
Normal file
80
RoadieLibrary/Configuration/RoadieSettings.cs
Normal file
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace roadie.Library.Setttings
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class RoadieSettings : IRoadieSettings
|
||||
{
|
||||
public bool UseSSLBehindProxy { get; set; }
|
||||
public string SecretKey { get; set; }
|
||||
public string WebsocketAddress { get; set; }
|
||||
public string SiteName { get; set; }
|
||||
public string InboundFolder { get; set; }
|
||||
public string LibraryFolder { get; set; }
|
||||
public Dictionary<string, string> TrackPathReplace { get; set; }
|
||||
public string SingleArtistHoldingFolder { get; set; }
|
||||
public string DefaultTimeZone { get; set; }
|
||||
public Thumbnails Thumbnails { get; set; }
|
||||
public List<ApiKey> ApiKeys { get; set; }
|
||||
public Converting Converting { get; set; }
|
||||
public Processing Processing { get; set; }
|
||||
public Integrations Integrations { get; set; }
|
||||
public string DiagnosticsPassword { get; set; }
|
||||
|
||||
public string SmtpFromAddress { get; set; }
|
||||
public int SmtpPort { get; set; }
|
||||
public string SmtpPassword { get; set; }
|
||||
public string SmtpUsername { get; set; }
|
||||
public string SmtpHost { get; set; }
|
||||
public bool SmtpUseSSl { get; set; }
|
||||
|
||||
public IEnumerable<string> DontDoMetaDataProvidersSearchArtists { get; set; }
|
||||
public IEnumerable<string> FileExtensionsToDelete { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the artist name is found in the values then use the key.
|
||||
/// <remark>This was desgined to handle 'AC/DC' type names as they contain the ID3 v2.3 spec artist seperator</remark>
|
||||
/// </summary>
|
||||
public Dictionary<string, List<string>> ArtistNameReplace { get; set; }
|
||||
|
||||
public bool RecordNoResultSearches { get; set; }
|
||||
|
||||
public RedisCache Redis { get; set; }
|
||||
|
||||
public RoadieSettings()
|
||||
{
|
||||
this.SiteName = "Roadie";
|
||||
this.DefaultTimeZone = "US/Central";
|
||||
this.DiagnosticsPassword = this.SiteName;
|
||||
this.WebsocketAddress = "ws://localhost:3579/websocket";
|
||||
this.TrackPathReplace = new Dictionary<string, string>();
|
||||
this.Thumbnails = new Thumbnails();
|
||||
this.Converting = new Converting();
|
||||
this.Processing = new Processing();
|
||||
this.Integrations = new Integrations();
|
||||
this.ApiKeys = new List<ApiKey>();
|
||||
this.DontDoMetaDataProvidersSearchArtists = new string[] { "Various Artists", "Sound Tracks" };
|
||||
this.FileExtensionsToDelete = new string[] { ".cue", ".db", ".gif", ".html", ".ini", ".jpg", ".jpeg", ".log", ".mpg", ".m3u", ".png", ".nfo", ".nzb", ".sfv", ".srr", ".txt", ".url" };
|
||||
this.ArtistNameReplace = new Dictionary<string, List<string>>();
|
||||
this.RecordNoResultSearches = true;
|
||||
|
||||
}
|
||||
|
||||
public void MergeWith(RoadieSettings secondary)
|
||||
{
|
||||
foreach (var pi in typeof(RoadieSettings).GetProperties())
|
||||
{
|
||||
var priValue = pi.GetGetMethod().Invoke(this, null);
|
||||
var secValue = pi.GetGetMethod().Invoke(secondary, null);
|
||||
if (secValue != null && pi.CanWrite)
|
||||
{
|
||||
pi.GetSetMethod().Invoke(this, new object[] { secValue });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
21
RoadieLibrary/Configuration/Thumbnails.cs
Normal file
21
RoadieLibrary/Configuration/Thumbnails.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace roadie.Library.Setttings
|
||||
{
|
||||
[Serializable]
|
||||
public class Thumbnails
|
||||
{
|
||||
public short Height { get; set; }
|
||||
public short Width { get; set; }
|
||||
|
||||
public Thumbnails()
|
||||
{
|
||||
this.Height = 80;
|
||||
this.Width = 80;
|
||||
}
|
||||
}
|
||||
}
|
65
RoadieLibrary/Data/Artist.cs
Normal file
65
RoadieLibrary/Data/Artist.cs
Normal file
|
@ -0,0 +1,65 @@
|
|||
using Roadie.Library.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("artist")]
|
||||
public partial class Artist : BeginAndEndNamedEntityBase
|
||||
{
|
||||
[Column("amgId")]
|
||||
[MaxLength(100)]
|
||||
public string AmgId { get; set; }
|
||||
|
||||
[Column("artistType", TypeName = "enum")]
|
||||
public string ArtistType { get; set; }
|
||||
|
||||
[Column("bandStatus", TypeName = "enum")]
|
||||
public BandStatus? BandStatus { get; set; }
|
||||
|
||||
[Column("bioContext", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string BioContext { get; set; }
|
||||
|
||||
[Column("birthDate", TypeName = "date")]
|
||||
public DateTime? BirthDate { get; set; }
|
||||
|
||||
[Column("discogsId")]
|
||||
[MaxLength(50)]
|
||||
public string DiscogsId { get; set; }
|
||||
|
||||
[Column("isniList", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string ISNIList { get; set; }
|
||||
|
||||
[Column("iTunesId")]
|
||||
[MaxLength(100)]
|
||||
public string ITunesId { get; set; }
|
||||
|
||||
[Column("musicBrainzId")]
|
||||
[MaxLength(100)]
|
||||
public string MusicBrainzId { get; set; }
|
||||
|
||||
[Column("profile", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string Profile { get; set; }
|
||||
|
||||
[Column("rating")]
|
||||
public short? Rating { get; set; }
|
||||
|
||||
[Column("realName")]
|
||||
[MaxLength(500)]
|
||||
public string RealName { get; set; }
|
||||
|
||||
[Column("spotifyId")]
|
||||
[MaxLength(100)]
|
||||
public string SpotifyId { get; set; }
|
||||
|
||||
[Column("thumbnail", TypeName = "blob")]
|
||||
public byte[] Thumbnail { get; set; }
|
||||
|
||||
public List<Release> Releases { get; set; }
|
||||
}
|
||||
}
|
16
RoadieLibrary/Data/BeginAndEndEntityBase.cs
Normal file
16
RoadieLibrary/Data/BeginAndEndEntityBase.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public abstract class BeginAndEndEntityBase : EntityBase
|
||||
{
|
||||
[Column("beginDate", TypeName = "date")]
|
||||
public DateTime? BeginDate { get; set; }
|
||||
|
||||
[Column("endDate", TypeName = "date")]
|
||||
public DateTime? EndDate { get; set; }
|
||||
}
|
||||
}
|
18
RoadieLibrary/Data/BeginAndEndNamedEntityBase.cs
Normal file
18
RoadieLibrary/Data/BeginAndEndNamedEntityBase.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public abstract class BeginAndEndNamedEntityBase : NamedEntityBase
|
||||
{
|
||||
[Column("beginDate", TypeName = "date")]
|
||||
public DateTime? BeginDate { get; set; }
|
||||
|
||||
[Column("endDate", TypeName = "date")]
|
||||
public DateTime? EndDate { get; set; }
|
||||
|
||||
}
|
||||
}
|
41
RoadieLibrary/Data/Collection.cs
Normal file
41
RoadieLibrary/Data/Collection.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
using Roadie.Library.Enums;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("collection")]
|
||||
public partial class Collection : NamedEntityBase
|
||||
{
|
||||
[Column("collectionCount")]
|
||||
public int CollectionCount { get; set; }
|
||||
|
||||
[Column("description")]
|
||||
[MaxLength(1000)]
|
||||
public string Description { get; set; }
|
||||
|
||||
[Column("edition")]
|
||||
[MaxLength(200)]
|
||||
public string Edition { get; set; }
|
||||
|
||||
[Column("listInCSV", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string ListInCSV { get; set; }
|
||||
|
||||
[Column("listInCSVFormat")]
|
||||
[MaxLength(200)]
|
||||
public string ListInCSVFormat { get; set; }
|
||||
|
||||
[Column("maintainerId")]
|
||||
public int MaintainerId { get; set; }
|
||||
|
||||
[Column("thumbnail", TypeName = "blob")]
|
||||
public byte[] Thumbnail { get; set; }
|
||||
|
||||
[Column("collectionType")]
|
||||
public CollectionType? CollectionType { get; set; }
|
||||
|
||||
public ICollection<CollectionRelease> Releases { get; set; }
|
||||
}
|
||||
}
|
24
RoadieLibrary/Data/CollectionRelease.cs
Normal file
24
RoadieLibrary/Data/CollectionRelease.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("collectionrelease")]
|
||||
public partial class CollectionRelease : EntityBase
|
||||
{
|
||||
public Collection Collection { get; set; }
|
||||
|
||||
[Column("collectionId")]
|
||||
[Required]
|
||||
public int CollectionId { get; set; }
|
||||
|
||||
[Column("listNumber")]
|
||||
public int ListNumber { get; set; }
|
||||
|
||||
public Release Release { get; set; }
|
||||
|
||||
[Column("releaseId")]
|
||||
[Required]
|
||||
public int ReleaseId { get; set; }
|
||||
}
|
||||
}
|
31
RoadieLibrary/Data/EntityBase.cs
Normal file
31
RoadieLibrary/Data/EntityBase.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using Roadie.Library.Enums;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public abstract class EntityBase
|
||||
{
|
||||
[Column("createdDate")]
|
||||
[Required]
|
||||
public DateTime CreatedDate { get; set; }
|
||||
|
||||
[Column("id")]
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
public bool? IsLocked { get; set; }
|
||||
|
||||
[Column("lastUpdated")]
|
||||
[Required]
|
||||
public DateTime? LastUpdated { get; set; }
|
||||
|
||||
[Column("roadieId")]
|
||||
[Required]
|
||||
public Guid RoadieId { get; set; }
|
||||
|
||||
[Column("status", TypeName = "enum")]
|
||||
public Statuses Status { get; set; }
|
||||
}
|
||||
}
|
18
RoadieLibrary/Data/Genre.cs
Normal file
18
RoadieLibrary/Data/Genre.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("genre")]
|
||||
public partial class Genre : EntityBase
|
||||
{
|
||||
[Column("name")]
|
||||
[MaxLength(100)]
|
||||
public string Name { get; set; }
|
||||
|
||||
public ICollection<ReleaseGenre> Releases { get; set; }
|
||||
}
|
||||
}
|
17
RoadieLibrary/Data/IRoadieDbContext.cs
Normal file
17
RoadieLibrary/Data/IRoadieDbContext.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public interface IRoadieDbContext
|
||||
{
|
||||
DbSet<Artist> Artists { get; set; }
|
||||
DbSet<CollectionRelease> CollectionReleases { get; set; }
|
||||
DbSet<Collection> Collections { get; set; }
|
||||
DbSet<Label> Labels { get; set; }
|
||||
DbSet<Playlist> Playlists { get; set; }
|
||||
DbSet<ReleaseGenre> ReleaseGenres { get; set; }
|
||||
DbSet<ReleaseMedia> ReleaseMedias { get; set; }
|
||||
DbSet<Release> Releases { get; set; }
|
||||
DbSet<Track> Tracks { get; set; }
|
||||
}
|
||||
}
|
24
RoadieLibrary/Data/Label.cs
Normal file
24
RoadieLibrary/Data/Label.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("label")]
|
||||
public partial class Label : BeginAndEndNamedEntityBase
|
||||
{
|
||||
[Column("discogsId")]
|
||||
[MaxLength(50)]
|
||||
public string DiscogsId { get; set; }
|
||||
|
||||
[Column("musicBrainzId")]
|
||||
[MaxLength(100)]
|
||||
public string MusicBrainzId { get; set; }
|
||||
|
||||
[Column("profile", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string Profile { get; set; }
|
||||
|
||||
public List<ReleaseLabel> ReleaseLabels { get; set; }
|
||||
}
|
||||
}
|
31
RoadieLibrary/Data/NamedEntityBase.cs
Normal file
31
RoadieLibrary/Data/NamedEntityBase.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public abstract class NamedEntityBase : EntityBase
|
||||
{
|
||||
[Column("sortName")]
|
||||
[MaxLength(250)]
|
||||
public string SortName { get; set; }
|
||||
|
||||
[MaxLength(250)]
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("alternateNames", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string AlternateNames { get; set; }
|
||||
|
||||
[Column("tags", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string Tags { get; set; }
|
||||
|
||||
[Column("urls", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string URLs { get; set; }
|
||||
}
|
||||
}
|
31
RoadieLibrary/Data/Playlist.cs
Normal file
31
RoadieLibrary/Data/Playlist.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using Roadie.Library.Identity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("playlist")]
|
||||
public partial class Playlist : NamedEntityBase
|
||||
{
|
||||
|
||||
[Column("isPublic")]
|
||||
public bool IsPublic { get; set; }
|
||||
|
||||
[Column("Description")]
|
||||
[MaxLength(1000)]
|
||||
public string Description { get; set; }
|
||||
|
||||
[Column("userId")]
|
||||
public int? UserId { get; set; }
|
||||
|
||||
[Column("thumbnail", TypeName = "blob")]
|
||||
public byte[] Thumbnail { get; set; }
|
||||
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
public ICollection<PlaylistTrack> Tracks { get; set; }
|
||||
}
|
||||
}
|
23
RoadieLibrary/Data/PlaylistTrack.cs
Normal file
23
RoadieLibrary/Data/PlaylistTrack.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("playlisttrack")]
|
||||
public partial class PlaylistTrack : EntityBase
|
||||
{
|
||||
[Column("listNumber")]
|
||||
[Required]
|
||||
public int ListNumber { get; set; }
|
||||
[Column("trackId")]
|
||||
public int TrackId { get; set; }
|
||||
[Column("playListId")]
|
||||
public int PlayListId { get; set; }
|
||||
|
||||
public Track Track { get; set; }
|
||||
public Playlist Playlist { get; set; }
|
||||
}
|
||||
}
|
90
RoadieLibrary/Data/Release.cs
Normal file
90
RoadieLibrary/Data/Release.cs
Normal file
|
@ -0,0 +1,90 @@
|
|||
using Roadie.Library.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("release")]
|
||||
public partial class Release : EntityBase
|
||||
{
|
||||
[Column("amgId")]
|
||||
[MaxLength(50)]
|
||||
public string AmgId { get; set; }
|
||||
|
||||
[Column("artistId")]
|
||||
[Required]
|
||||
|
||||
public int ArtistId { get; set; }
|
||||
|
||||
public Artist Artist { get; set; }
|
||||
|
||||
[Column("discogsId")]
|
||||
[MaxLength(50)]
|
||||
public string DiscogsId { get; set; }
|
||||
|
||||
[Column("isVirtual")]
|
||||
public bool? IsVirtual { get; set; }
|
||||
|
||||
[Column("itunesId")]
|
||||
[MaxLength(100)]
|
||||
public string ITunesId { get; set; }
|
||||
|
||||
[Column("lastFMId")]
|
||||
[MaxLength(50)]
|
||||
public string LastFMId { get; set; }
|
||||
|
||||
[Column("lastFMSummary", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string LastFMSummary { get; set; }
|
||||
|
||||
[Column("libraryStatus")]
|
||||
public LibraryStatus? LibraryStatus { get; set; }
|
||||
|
||||
[Column("mediaCount")]
|
||||
public short? MediaCount { get; set; }
|
||||
|
||||
[Column("musicBrainzId")]
|
||||
[MaxLength(100)]
|
||||
public string MusicBrainzId { get; set; }
|
||||
|
||||
[Column("profile", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string Profile { get; set; }
|
||||
|
||||
[Column("releaseDate")]
|
||||
[Required]
|
||||
public DateTime ReleaseDate { get; set; }
|
||||
|
||||
[Column("releaseType")]
|
||||
public ReleaseType? ReleaseType { get; set; }
|
||||
|
||||
[Column("spotifyId")]
|
||||
[MaxLength(100)]
|
||||
public string SpotifyId { get; set; }
|
||||
|
||||
[Column("submissionId")]
|
||||
public int? SubmissionId { get; set; }
|
||||
|
||||
[MaxLength(250)]
|
||||
[Column("title")]
|
||||
[Required]
|
||||
public string Title { get; set; }
|
||||
|
||||
[Column("trackCount")]
|
||||
public short TrackCount { get; set; }
|
||||
|
||||
[Column("thumbnail", TypeName = "blob")]
|
||||
public byte[] Thumbnail { get; set; }
|
||||
|
||||
public ICollection<ReleaseLabel> Labels { get; set; }
|
||||
|
||||
public ICollection<ReleaseMedia> Medias { get; set; }
|
||||
|
||||
public ICollection<ReleaseGenre> Genres { get; set; }
|
||||
|
||||
public ICollection<CollectionRelease> Collections { get; set; }
|
||||
|
||||
}
|
||||
}
|
28
RoadieLibrary/Data/ReleaseGenre.cs
Normal file
28
RoadieLibrary/Data/ReleaseGenre.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("releaseGenreTable")]
|
||||
public partial class ReleaseGenre
|
||||
{
|
||||
[Column("id")]
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("releaseId")]
|
||||
[Required]
|
||||
public int ReleaseId { get; set; }
|
||||
|
||||
public Release Release { get; set; }
|
||||
|
||||
[Column("genreId")]
|
||||
[Required]
|
||||
public int GenreId { get; set; }
|
||||
|
||||
public Genre Genre { get; set; }
|
||||
}
|
||||
}
|
27
RoadieLibrary/Data/ReleaseLabel.cs
Normal file
27
RoadieLibrary/Data/ReleaseLabel.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using Roadie.Library.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("releaselabel")]
|
||||
public class ReleaseLabel : BeginAndEndEntityBase
|
||||
{
|
||||
[Column("releaseId")]
|
||||
public int ReleaseId { get; set; }
|
||||
|
||||
public Release Release { get; set; }
|
||||
|
||||
[Column("labelId")]
|
||||
public int LabelId { get; set; }
|
||||
|
||||
public Label Label { get; set; }
|
||||
|
||||
[Column("catalogNumber")]
|
||||
public string CatalogNumber { get; set; }
|
||||
|
||||
}
|
||||
}
|
32
RoadieLibrary/Data/ReleaseMedia.cs
Normal file
32
RoadieLibrary/Data/ReleaseMedia.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
using Roadie.Library.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("releasemedia")]
|
||||
public class ReleaseMedia : EntityBase
|
||||
{
|
||||
[Column("releaseId")]
|
||||
public int ReleaseId { get; set; }
|
||||
|
||||
public Release Release { get; set; }
|
||||
|
||||
[Column("releaseSubTitle")]
|
||||
[MaxLength(500)]
|
||||
public string SubTitle { get; set; }
|
||||
|
||||
[Column("trackCount")]
|
||||
[Required]
|
||||
public short TrackCount { get; set; }
|
||||
|
||||
[Column("releaseMediaNumber")]
|
||||
public short MediaNumber { get; set; }
|
||||
|
||||
public ICollection<Track> Tracks { get; set; }
|
||||
|
||||
}
|
||||
}
|
95
RoadieLibrary/Data/RoadieDbContext.cs
Normal file
95
RoadieLibrary/Data/RoadieDbContext.cs
Normal file
|
@ -0,0 +1,95 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Roadie.Library.Enums;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public class RoadieDbContext : DbContext, IRoadieDbContext
|
||||
{
|
||||
public DbSet<Artist> Artists { get; set; }
|
||||
public DbSet<Label> Labels { get; set; }
|
||||
public DbSet<Release> Releases { get; set; }
|
||||
public DbSet<Track> Tracks { get; set; }
|
||||
public DbSet<ReleaseGenre> ReleaseGenres { get; set; }
|
||||
public DbSet<ReleaseMedia> ReleaseMedias { get; set; }
|
||||
public DbSet<Collection> Collections { get; set; }
|
||||
public DbSet<CollectionRelease> CollectionReleases { get; set; }
|
||||
public DbSet<Playlist> Playlists { get; set; }
|
||||
|
||||
public RoadieDbContext(DbContextOptions<RoadieDbContext> options)
|
||||
: base(options)
|
||||
{
|
||||
}
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
builder
|
||||
.Entity<Release>()
|
||||
.Property(e => e.ReleaseType)
|
||||
.HasConversion(
|
||||
v => v.ToString(),
|
||||
v => string.IsNullOrEmpty(v) ? ReleaseType.Unknown : (ReleaseType)Enum.Parse(typeof(ReleaseType), v))
|
||||
.HasDefaultValue(ReleaseType.Unknown);
|
||||
|
||||
builder
|
||||
.Entity<Release>()
|
||||
.Property(e => e.LibraryStatus)
|
||||
.HasConversion(
|
||||
v => v.ToString(),
|
||||
v => (LibraryStatus)Enum.Parse(typeof(LibraryStatus), v))
|
||||
.HasDefaultValue(LibraryStatus.Incomplete);
|
||||
|
||||
builder
|
||||
.Entity<Collection>()
|
||||
.Property(e => e.CollectionType)
|
||||
.HasConversion(
|
||||
v => v.ToString(),
|
||||
v => (CollectionType)Enum.Parse(typeof(CollectionType), v))
|
||||
.HasDefaultValue(CollectionType.Unknown);
|
||||
|
||||
builder.Entity<ReleaseLabel>()
|
||||
.HasOne(rl => rl.Release)
|
||||
.WithMany(r => r.Labels)
|
||||
.HasForeignKey(rl => rl.ReleaseId);
|
||||
|
||||
builder.Entity<ReleaseLabel>()
|
||||
.HasOne(rl => rl.Label)
|
||||
.WithMany(l => l.ReleaseLabels)
|
||||
.HasForeignKey(rl => rl.LabelId);
|
||||
|
||||
builder.Entity<ReleaseMedia>()
|
||||
.HasMany(rm => rm.Tracks)
|
||||
.WithOne(t => t.ReleaseMedia)
|
||||
.HasForeignKey(rm => rm.ReleaseMediaId);
|
||||
|
||||
builder.Entity<ReleaseMedia>()
|
||||
.HasOne(rm => rm.Release)
|
||||
.WithMany(r => r.Medias)
|
||||
.HasForeignKey(r => r.ReleaseId);
|
||||
|
||||
builder.Entity<ReleaseGenre>()
|
||||
.HasKey(rg => new { rg.ReleaseId, rg.GenreId });
|
||||
|
||||
builder.Entity<ReleaseGenre>()
|
||||
.HasOne(rg => rg.Release)
|
||||
.WithMany(r => r.Genres)
|
||||
.HasForeignKey(rg => rg.ReleaseId);
|
||||
|
||||
builder.Entity<ReleaseGenre>()
|
||||
.HasOne(rg => rg.Genre)
|
||||
.WithMany(g => g.Releases)
|
||||
.HasForeignKey(rg => rg.GenreId);
|
||||
|
||||
builder.Entity<CollectionRelease>()
|
||||
.HasOne(cr => cr.Release)
|
||||
.WithMany(r => r.Collections)
|
||||
.HasForeignKey(cr => cr.ReleaseId);
|
||||
|
||||
builder.Entity<CollectionRelease>()
|
||||
.HasOne(cr => cr.Collection)
|
||||
.WithMany(c => c.Releases)
|
||||
.HasForeignKey(cr => cr.CollectionId);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
89
RoadieLibrary/Data/Track.cs
Normal file
89
RoadieLibrary/Data/Track.cs
Normal file
|
@ -0,0 +1,89 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("track")]
|
||||
public partial class Track : EntityBase
|
||||
{
|
||||
[Column("alternateNames", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string AlternateNames { get; set; }
|
||||
|
||||
[Column("amgId")]
|
||||
[MaxLength(50)]
|
||||
public string AmgId { get; set; }
|
||||
|
||||
public Artist Artist { get; set; }
|
||||
|
||||
[Column("artistId")]
|
||||
public int? ArtistId { get; set; }
|
||||
|
||||
[Column("duration")]
|
||||
public int Duration { get; set; }
|
||||
|
||||
[Column("fileName")]
|
||||
[MaxLength(500)]
|
||||
public string FileName { get; set; }
|
||||
|
||||
[Column("filePath")]
|
||||
[MaxLength(1000)]
|
||||
public string FilePath { get; set; }
|
||||
|
||||
[Column("fileSize")]
|
||||
public int FileSize { get; set; }
|
||||
|
||||
[Column("hash")]
|
||||
[MaxLength(32)]
|
||||
public string Hash { get; set; }
|
||||
|
||||
[Column("isrc")]
|
||||
[MaxLength(15)]
|
||||
public string ISRC { get; set; }
|
||||
|
||||
[Column("lastFMId")]
|
||||
[MaxLength(50)]
|
||||
public string LastFMId { get; set; }
|
||||
|
||||
[Column("lastPlayed")]
|
||||
public DateTime? LastPlayed { get; set; }
|
||||
|
||||
[Column("musicBrainzId")]
|
||||
[MaxLength(100)]
|
||||
public string MusicBrainzId { get; set; }
|
||||
|
||||
[Column("partTitles", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string PartTitles { get; set; }
|
||||
|
||||
[Column("playedCount")]
|
||||
public int PlayedCount { get; set; }
|
||||
|
||||
[Column("rating")]
|
||||
public short Rating { get; set; }
|
||||
|
||||
[Column("releaseMediaId")]
|
||||
public int ReleaseMediaId { get; set; }
|
||||
|
||||
public ReleaseMedia ReleaseMedia { get; set; }
|
||||
|
||||
[Column("spotifyId")]
|
||||
[MaxLength(100)]
|
||||
public string SpotifyId { get; set; }
|
||||
|
||||
[Column("tags", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string Tags { get; set; }
|
||||
|
||||
[MaxLength(250)]
|
||||
[Column("title")]
|
||||
[Required]
|
||||
public string Title { get; set; }
|
||||
|
||||
[Column("trackNumber")]
|
||||
[Required]
|
||||
public short TrackNumber { get; set; }
|
||||
|
||||
}
|
||||
}
|
19
RoadieLibrary/Enums/ArtistType.cs
Normal file
19
RoadieLibrary/Enums/ArtistType.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Enums
|
||||
{
|
||||
public enum ArtistType : int
|
||||
{
|
||||
Unknown = 0,
|
||||
Person,
|
||||
Group,
|
||||
Orchestra,
|
||||
Choir,
|
||||
Character,
|
||||
Other
|
||||
}
|
||||
}
|
16
RoadieLibrary/Enums/BandStatus.cs
Normal file
16
RoadieLibrary/Enums/BandStatus.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Enums
|
||||
{
|
||||
public enum BandStatus
|
||||
{
|
||||
Active,
|
||||
OnHold,
|
||||
SplitUp,
|
||||
ChangedName
|
||||
}
|
||||
}
|
18
RoadieLibrary/Enums/BookmarkType.cs
Normal file
18
RoadieLibrary/Enums/BookmarkType.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Enums
|
||||
{
|
||||
public enum BookmarkType : short
|
||||
{
|
||||
Artist = 1,
|
||||
Release = 2,
|
||||
Track = 3,
|
||||
Playlist = 4,
|
||||
Collection = 5,
|
||||
Label = 6
|
||||
}
|
||||
}
|
14
RoadieLibrary/Enums/CollectionType.cs
Normal file
14
RoadieLibrary/Enums/CollectionType.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Enums
|
||||
{
|
||||
public enum CollectionType : short
|
||||
{
|
||||
Unknown = 0,
|
||||
Collection,
|
||||
Chart,
|
||||
Rank
|
||||
}
|
||||
}
|
14
RoadieLibrary/Enums/LibraryStatus.cs
Normal file
14
RoadieLibrary/Enums/LibraryStatus.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Enums
|
||||
{
|
||||
public enum LibraryStatus : short
|
||||
{
|
||||
Incomplete = 0,
|
||||
Complete,
|
||||
Missing,
|
||||
Wishlist
|
||||
}
|
||||
}
|
14
RoadieLibrary/Enums/QueMessageType.cs
Normal file
14
RoadieLibrary/Enums/QueMessageType.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Enums
|
||||
{
|
||||
public enum QueMessageType
|
||||
{
|
||||
ArtistFolder,
|
||||
ReleaseFolder
|
||||
}
|
||||
}
|
14
RoadieLibrary/Enums/ReleaseType.cs
Normal file
14
RoadieLibrary/Enums/ReleaseType.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Enums
|
||||
{
|
||||
public enum ReleaseType : short
|
||||
{
|
||||
Unknown = 0,
|
||||
Release,
|
||||
EP,
|
||||
Single
|
||||
}
|
||||
}
|
14
RoadieLibrary/Enums/RequestStatus.cs
Normal file
14
RoadieLibrary/Enums/RequestStatus.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Enums
|
||||
{
|
||||
public enum RequestStatus
|
||||
{
|
||||
New = 0,
|
||||
Processed = 1
|
||||
}
|
||||
}
|
19
RoadieLibrary/Enums/Statuses.cs
Normal file
19
RoadieLibrary/Enums/Statuses.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Enums
|
||||
{
|
||||
public enum Statuses : short
|
||||
{
|
||||
Ok = 0,
|
||||
New = 1,
|
||||
Complete = 2,
|
||||
Incomplete = 3,
|
||||
Missing = 4,
|
||||
Wishlist =5,
|
||||
Deleted = 99
|
||||
}
|
||||
}
|
38
RoadieLibrary/Identity/ApplicationClaimsFactory.cs
Normal file
38
RoadieLibrary/Identity/ApplicationClaimsFactory.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Identity
|
||||
{
|
||||
public class ApplicationClaimsFactory : UserClaimsPrincipalFactory<ApplicationUser, ApplicationRole>
|
||||
{
|
||||
public const string SecurityClaimRoleType = "req-security-claim";
|
||||
|
||||
private readonly ApplicationUserDbContext _applicationUserDbContext = null;
|
||||
|
||||
public ApplicationClaimsFactory(
|
||||
ApplicationUserDbContext applicationUserDbContext,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
RoleManager<ApplicationRole> roleManager,
|
||||
IOptions<IdentityOptions> optionsAccessor) : base(userManager, roleManager, optionsAccessor)
|
||||
{
|
||||
_applicationUserDbContext = applicationUserDbContext;
|
||||
}
|
||||
|
||||
public override async Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
|
||||
{
|
||||
var usersRoles = (from ur in _applicationUserDbContext.UsersInRoles.Where(x => x.UserId == user.Id)
|
||||
join r in _applicationUserDbContext.Roles on ur.UserRoleId equals r.Id
|
||||
select r);
|
||||
IEnumerable<Claim> userClaims = null;
|
||||
if (usersRoles.Any())
|
||||
{
|
||||
userClaims = usersRoles.Select(x => new Claim(SecurityClaimRoleType, x.Name));
|
||||
}
|
||||
return new ClaimsPrincipal(new ClaimsIdentity(userClaims, "Password"));
|
||||
}
|
||||
}
|
||||
}
|
40
RoadieLibrary/Identity/ApplicationRole.cs
Normal file
40
RoadieLibrary/Identity/ApplicationRole.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Identity
|
||||
{
|
||||
[Table("userrole")]
|
||||
public partial 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; }
|
||||
|
||||
[Column("status")]
|
||||
public short? Status { get; set; }
|
||||
}
|
||||
}
|
112
RoadieLibrary/Identity/ApplicationUser.cs
Normal file
112
RoadieLibrary/Identity/ApplicationUser.cs
Normal file
|
@ -0,0 +1,112 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Roadie.Library.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Identity
|
||||
{
|
||||
[Table("user")]
|
||||
public partial class ApplicationUser : IdentityUser<int>
|
||||
{
|
||||
[Column("apiToken")]
|
||||
[StringLength(100)]
|
||||
public string ApiToken { get; set; }
|
||||
|
||||
[Column("avatar", TypeName = "blob")]
|
||||
public byte[] Avatar { 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; }
|
||||
|
||||
[Column("lastApiAccess")]
|
||||
public DateTime? LastApiAccess { 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; }
|
||||
|
||||
[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; }
|
||||
|
||||
[Column("roadieId")]
|
||||
[StringLength(36)]
|
||||
public string RoadieId { get; set; }
|
||||
|
||||
[Column("status")]
|
||||
public short? Status { get; set; }
|
||||
|
||||
[Column("timeformat")]
|
||||
[StringLength(50)]
|
||||
public string Timeformat { get; set; }
|
||||
|
||||
[Column("timezone")]
|
||||
[StringLength(50)]
|
||||
public string Timezone { get; set; }
|
||||
|
||||
[Column("username")]
|
||||
[Required]
|
||||
[StringLength(20)]
|
||||
public string Username { get; set; }
|
||||
|
||||
public ICollection<Playlist> Playlists { get; set; }
|
||||
}
|
||||
}
|
25
RoadieLibrary/Identity/ApplicationUserDbContext.cs
Normal file
25
RoadieLibrary/Identity/ApplicationUserDbContext.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Identity
|
||||
{
|
||||
public class ApplicationUserDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int>
|
||||
{
|
||||
public DbSet<UsersInRoles> UsersInRoles { get; set; }
|
||||
|
||||
public ApplicationUserDbContext(DbContextOptions<ApplicationUserDbContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
modelBuilder.Entity<ApplicationUser>().ToTable("user");
|
||||
modelBuilder.Entity<ApplicationRole>().ToTable("userrole");
|
||||
}
|
||||
}
|
||||
}
|
20
RoadieLibrary/Identity/UsersInRoles.cs
Normal file
20
RoadieLibrary/Identity/UsersInRoles.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Identity
|
||||
{
|
||||
[Table("usersInRoles")]
|
||||
public class UsersInRoles
|
||||
{
|
||||
[Column("id")]
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
[Column("userId")]
|
||||
public int UserId { get; set; }
|
||||
[Column("userRoleId")]
|
||||
public int UserRoleId { get; set; }
|
||||
}
|
||||
}
|
16
RoadieLibrary/Roadie.Library.csproj
Normal file
16
RoadieLibrary/Roadie.Library.csproj
Normal file
|
@ -0,0 +1,16 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.1.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Redis" Version="2.1.2" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.1.2" />
|
||||
<PackageReference Include="System.Runtime.Caching" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
Loading…
Reference in a new issue