mirror of
https://github.com/sphildreth/roadie
synced 2025-02-17 21:48:27 +00:00
Lots of cleanup, removals of 'this'.
This commit is contained in:
parent
6bb4e8671c
commit
2fcf82db36
272 changed files with 6674 additions and 9496 deletions
Roadie.Api.Library
Caching
CacheManagerBase.csCachePolicy.csDictionaryCacheManager.csICacheManager.csMemoryCacheManager.csRedisCacheManager.cs
Configuration
ApiKey.csConverting.csIConverting.csIRoadieSettings.csInspector.csIntegrations.csProcessing.csReplacementString.csRoadieSettings.csThumbnails.cs
Data
Artist.csArtistAssociation.csArtistGenre.csArtistPartial.csArtistSimiliar.csBeginAndEndEntityBase.csBeginAndEndNamedEntityBase.csBookmark.csBookmarkPartial.csChatMessage.csCollection.csCollectionMissing.csCollectionPartial.csCollectionRelease.csComment.csCommentPartial.csCommentReaction.csEntityBase.csGenre.csGenrePartial.csIRoadieDbContext.csImage.csImagePartial.csLabel.csLabelPartial.csNamedEntityBase.csPlaylist.csPlaylistPartial.csPlaylistTrack.csRelease.csReleaseGenre.csReleaseLabel.csReleaseMedia.csReleasePartial.csRequest.csRoadieDbContext.csScanHistory.csSubmission.csTrack.csTrackPartial.csUserArtist.csUserQue.csUserRelease.csUserTrack.cs
Encoding
Engines
ArtistLookupEngine.csIArtistLookupEngine.csILabelLookupEngine.csIReleaseLookupEngine.csLabelLookupEngine.csLookupEngineBase.csReleaseLookupEngine.cs
Enums
EventMessage.csExtensions
ByteExt.csDateTimeExt.csDecimalExt.csExceptionExt.csGenericExt.csIntEx.csListExt.csLoggerExt.csLongExt.csShortExt.csStringExt.csTimeSpanExt.cs
Factories
ArtistFactory.csFactoryBase.csIArtistFactory.csILabelFactory.csIReleaseFactory.csImageFactory.csLabelFactory.csPlaylistFactory.csReleaseFactory.cs
FileOperationResult.csFilePlugins
Identity
|
@ -9,15 +9,16 @@ namespace Roadie.Library.Caching
|
|||
{
|
||||
public const string SystemCacheRegionUrn = "urn:system";
|
||||
|
||||
protected readonly CachePolicy _defaultPolicy = null;
|
||||
protected readonly CachePolicy _defaultPolicy;
|
||||
protected readonly JsonSerializerSettings _serializerSettings;
|
||||
|
||||
protected ILogger Logger { get; }
|
||||
protected readonly JsonSerializerSettings _serializerSettings = null;
|
||||
|
||||
public CacheManagerBase(ILogger logger, CachePolicy defaultPolicy)
|
||||
{
|
||||
this.Logger = logger;
|
||||
this._defaultPolicy = defaultPolicy;
|
||||
this._serializerSettings = new JsonSerializerSettings
|
||||
Logger = logger;
|
||||
_defaultPolicy = defaultPolicy;
|
||||
_serializerSettings = new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new IgnoreJsonAttributesResolver(),
|
||||
Formatting = Formatting.Indented
|
||||
|
@ -56,26 +57,22 @@ namespace Roadie.Library.Caching
|
|||
|
||||
protected TOut Deserialize<TOut>(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s))
|
||||
{
|
||||
return default(TOut);
|
||||
}
|
||||
if (string.IsNullOrEmpty(s)) return default(TOut);
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<TOut>(s, this._serializerSettings);
|
||||
return JsonConvert.DeserializeObject<TOut>(s, _serializerSettings);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex);
|
||||
Logger.LogError(ex);
|
||||
}
|
||||
|
||||
return default(TOut);
|
||||
}
|
||||
|
||||
protected string Serialize(object o)
|
||||
{
|
||||
return JsonConvert.SerializeObject(o, this._serializerSettings);
|
||||
return JsonConvert.SerializeObject(o, _serializerSettings);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -4,20 +4,17 @@ namespace Roadie.Library.Caching
|
|||
{
|
||||
public sealed class CachePolicy
|
||||
{
|
||||
private readonly TimeSpan expiresAfter;
|
||||
private readonly bool renewLeaseOnAccess;
|
||||
|
||||
public TimeSpan ExpiresAfter { get { return this.expiresAfter; } }
|
||||
public TimeSpan ExpiresAfter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// If specified, each read of the item from the cache will reset the expiration time
|
||||
/// If specified, each read of the item from the cache will reset the expiration time
|
||||
/// </summary>
|
||||
public bool RenewLeaseOnAccess { get { return this.renewLeaseOnAccess; } }
|
||||
public bool RenewLeaseOnAccess { get; }
|
||||
|
||||
public CachePolicy(TimeSpan expiresAfter, bool renewLeaseOnAccess = false)
|
||||
{
|
||||
this.expiresAfter = expiresAfter;
|
||||
this.renewLeaseOnAccess = renewLeaseOnAccess;
|
||||
ExpiresAfter = expiresAfter;
|
||||
RenewLeaseOnAccess = renewLeaseOnAccess;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,57 +1,52 @@
|
|||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Caching
|
||||
{
|
||||
public class DictionaryCacheManager : CacheManagerBase
|
||||
{
|
||||
static readonly object padlock = new object();
|
||||
private static readonly object padlock = new object();
|
||||
|
||||
private Dictionary<string, object> Cache { get; }
|
||||
|
||||
public DictionaryCacheManager(ILogger logger, CachePolicy defaultPolicy)
|
||||
: base(logger, defaultPolicy)
|
||||
: base(logger, defaultPolicy)
|
||||
{
|
||||
this.Cache = new Dictionary<string, object>();
|
||||
Cache = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value)
|
||||
{
|
||||
lock (padlock)
|
||||
{
|
||||
if (this.Cache.ContainsKey(key))
|
||||
{
|
||||
this.Cache.Remove(key);
|
||||
}
|
||||
this.Cache.Add(key, value);
|
||||
if (Cache.ContainsKey(key)) Cache.Remove(key);
|
||||
Cache.Add(key, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value, string region)
|
||||
{
|
||||
return this.Add(key, value);
|
||||
return Add(key, value);
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value, CachePolicy policy)
|
||||
{
|
||||
return this.Add(key, value);
|
||||
return Add(key, value);
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value, string region, CachePolicy policy)
|
||||
{
|
||||
return this.Add(key, value);
|
||||
return Add(key, value);
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
lock (padlock)
|
||||
{
|
||||
this.Cache.Clear();
|
||||
Cache.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +54,7 @@ namespace Roadie.Library.Caching
|
|||
{
|
||||
lock (padlock)
|
||||
{
|
||||
this.Clear();
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +62,7 @@ namespace Roadie.Library.Caching
|
|||
{
|
||||
lock (padlock)
|
||||
{
|
||||
return this.Cache.ContainsKey(key);
|
||||
return Cache.ContainsKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +70,7 @@ namespace Roadie.Library.Caching
|
|||
{
|
||||
lock (padlock)
|
||||
{
|
||||
return this.Exists<TOut>(key);
|
||||
return Exists<TOut>(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,11 +78,8 @@ namespace Roadie.Library.Caching
|
|||
{
|
||||
lock (padlock)
|
||||
{
|
||||
if (!this.Cache.ContainsKey(key))
|
||||
{
|
||||
return default(TOut);
|
||||
}
|
||||
return (TOut)this.Cache[key];
|
||||
if (!Cache.ContainsKey(key)) return default(TOut);
|
||||
return (TOut)Cache[key];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,55 +90,53 @@ namespace Roadie.Library.Caching
|
|||
|
||||
public override TOut Get<TOut>(string key, Func<TOut> getItem, string region)
|
||||
{
|
||||
return Get<TOut>(key, getItem, region, this._defaultPolicy);
|
||||
return Get(key, getItem, region, _defaultPolicy);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key, Func<TOut> getItem, string region, CachePolicy policy)
|
||||
{
|
||||
lock (padlock)
|
||||
{
|
||||
var r = this.Get<TOut>(key, region);
|
||||
var r = Get<TOut>(key, region);
|
||||
if (r == null)
|
||||
{
|
||||
r = getItem();
|
||||
this.Add(key, r, region, policy);
|
||||
Add(key, r, region, policy);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<TOut> GetAsync<TOut>(string key, Func<Task<TOut>> getItem, string region)
|
||||
{
|
||||
var r = Get<TOut>(key, region);
|
||||
if (r == null)
|
||||
{
|
||||
r = await getItem();
|
||||
Add(key, r, region);
|
||||
Logger.LogTrace($"-+> Cache Miss for Key [{key}], Region [{region}]");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogTrace($"-!> Cache Hit for Key [{key}], Region [{region}]");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public override bool Remove(string key)
|
||||
{
|
||||
lock (padlock)
|
||||
{
|
||||
if (this.Cache.ContainsKey(key))
|
||||
{
|
||||
this.Cache.Remove(key);
|
||||
}
|
||||
if (Cache.ContainsKey(key)) Cache.Remove(key);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Remove(string key, string region)
|
||||
{
|
||||
return this.Remove(key);
|
||||
}
|
||||
|
||||
public async override Task<TOut> GetAsync<TOut>(string key, Func<Task<TOut>> getItem, string region)
|
||||
{
|
||||
var r = this.Get<TOut>(key, region);
|
||||
if (r == null)
|
||||
{
|
||||
r = await getItem();
|
||||
this.Add(key, r, region);
|
||||
this.Logger.LogTrace($"-+> Cache Miss for Key [{ key }], Region [{ region }]");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Logger.LogTrace($"-!> Cache Hit for Key [{ key }], Region [{ region }]");
|
||||
}
|
||||
return r;
|
||||
|
||||
return Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Roadie.Library.Caching
|
||||
{
|
||||
public interface ICacheManager
|
||||
public interface ICacheManager
|
||||
{
|
||||
bool Add<TCacheValue>(string key, TCacheValue value);
|
||||
|
||||
|
@ -25,12 +25,12 @@ namespace Roadie.Library.Caching
|
|||
|
||||
TOut Get<TOut>(string key);
|
||||
|
||||
Task<TOut> GetAsync<TOut>(string key, Func<Task<TOut>> getItem, string region);
|
||||
|
||||
TOut Get<TOut>(string key, Func<TOut> getItem, string region);
|
||||
|
||||
TOut Get<TOut>(string key, Func<TOut> getItem, string region, CachePolicy policy);
|
||||
|
||||
Task<TOut> GetAsync<TOut>(string key, Func<Task<TOut>> getItem, string region);
|
||||
|
||||
bool Remove(string key);
|
||||
|
||||
bool Remove(string key, string region);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Caching
|
||||
|
@ -13,7 +12,7 @@ namespace Roadie.Library.Caching
|
|||
public MemoryCacheManager(ILogger logger, CachePolicy defaultPolicy)
|
||||
: base(logger, defaultPolicy)
|
||||
{
|
||||
this._cache = new MemoryCache(new MemoryCacheOptions());
|
||||
_cache = new MemoryCache(new MemoryCacheOptions());
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value)
|
||||
|
@ -24,7 +23,7 @@ namespace Roadie.Library.Caching
|
|||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value, string region)
|
||||
{
|
||||
_cache.Set(key, value, this._defaultPolicy.ExpiresAfter);
|
||||
_cache.Set(key, value, _defaultPolicy.ExpiresAfter);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -32,87 +31,91 @@ namespace Roadie.Library.Caching
|
|||
{
|
||||
_cache.Set(key, value, new MemoryCacheEntryOptions
|
||||
{
|
||||
AbsoluteExpiration = DateTimeOffset.UtcNow.Add(policy.ExpiresAfter) // new DateTimeOffset(DateTime.UtcNow, policy.ExpiresAfter)
|
||||
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);
|
||||
return Add(key, value, policy);
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
this._cache = new MemoryCache(new MemoryCacheOptions());
|
||||
_cache = new MemoryCache(new MemoryCacheOptions());
|
||||
}
|
||||
|
||||
public override void ClearRegion(string region)
|
||||
{
|
||||
this.Clear();
|
||||
Clear();
|
||||
}
|
||||
|
||||
public override bool Exists<TOut>(string key)
|
||||
{
|
||||
return this.Get<TOut>(key) != null;
|
||||
return Get<TOut>(key) != null;
|
||||
}
|
||||
|
||||
public override bool Exists<TOut>(string key, string region)
|
||||
{
|
||||
return this.Exists<TOut>(key);
|
||||
return Exists<TOut>(key);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key)
|
||||
{
|
||||
return this._cache.Get<TOut>(key);
|
||||
return _cache.Get<TOut>(key);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key, string region)
|
||||
{
|
||||
return this.Get<TOut>(key);
|
||||
return Get<TOut>(key);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key, Func<TOut> getItem, string region)
|
||||
{
|
||||
return this.Get<TOut>(key, getItem, region, this._defaultPolicy);
|
||||
return Get(key, getItem, region, _defaultPolicy);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key, Func<TOut> getItem, string region, CachePolicy policy)
|
||||
{
|
||||
var r = this.Get<TOut>(key, region);
|
||||
var r = Get<TOut>(key, region);
|
||||
if (r == null)
|
||||
{
|
||||
r = getItem();
|
||||
this.Add(key, r, region, policy);
|
||||
Add(key, r, region, policy);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public override async Task<TOut> GetAsync<TOut>(string key, Func<Task<TOut>> getItem, string region)
|
||||
{
|
||||
var r = Get<TOut>(key, region);
|
||||
if (r == null)
|
||||
{
|
||||
r = await getItem();
|
||||
Add(key, r, region);
|
||||
Logger.LogInformation($"-+> Cache Miss for Key [{key}], Region [{region}]");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogInformation($"-!> Cache Hit for Key [{key}], Region [{region}]");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public override bool Remove(string key)
|
||||
{
|
||||
this._cache.Remove(key);
|
||||
_cache.Remove(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Remove(string key, string region)
|
||||
{
|
||||
return this.Remove(key);
|
||||
}
|
||||
|
||||
public async override Task<TOut> GetAsync<TOut>(string key, Func<Task<TOut>> getItem, string region)
|
||||
{
|
||||
var r = this.Get<TOut>(key, region);
|
||||
if (r == null)
|
||||
{
|
||||
r = await getItem();
|
||||
this.Add(key, r, region);
|
||||
this.Logger.LogInformation($"-+> Cache Miss for Key [{ key }], Region [{ region }]");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Logger.LogInformation($"-!> Cache Hit for Key [{ key }], Region [{ region }]");
|
||||
}
|
||||
return r;
|
||||
return Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,62 +9,47 @@ using System.Threading.Tasks;
|
|||
namespace Roadie.Library.Caching
|
||||
{
|
||||
/// <summary>
|
||||
/// Redis Cache implemention
|
||||
/// Redis Cache implemention
|
||||
/// </summary>
|
||||
/// <typeparam name="TCacheValue"></typeparam>
|
||||
public class RedisCacheManager : CacheManagerBase
|
||||
{
|
||||
private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
|
||||
private static readonly Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
|
||||
{
|
||||
return ConnectionMultiplexer.Connect("192.168.1.253:6379,allowAdmin=true");
|
||||
});
|
||||
|
||||
private bool _doTraceLogging = true;
|
||||
private IDatabase _redis = null;
|
||||
private readonly bool _doTraceLogging = true;
|
||||
private IDatabase _redis;
|
||||
|
||||
public static ConnectionMultiplexer Connection
|
||||
{
|
||||
get
|
||||
{
|
||||
return lazyConnection.Value;
|
||||
}
|
||||
}
|
||||
public static ConnectionMultiplexer Connection => lazyConnection.Value;
|
||||
|
||||
private IDatabase Redis
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._redis ?? (this._redis = Connection.GetDatabase());
|
||||
}
|
||||
}
|
||||
private IDatabase Redis => _redis ?? (_redis = Connection.GetDatabase());
|
||||
|
||||
public RedisCacheManager(ILogger logger, CachePolicy defaultPolicy)
|
||||
: base(logger, defaultPolicy)
|
||||
: base(logger, defaultPolicy)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value)
|
||||
{
|
||||
return this.Add(key, value, null, this._defaultPolicy);
|
||||
return Add(key, value, null, _defaultPolicy);
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value, string region)
|
||||
{
|
||||
return this.Add(key, value, region, null);
|
||||
return Add(key, value, region, null);
|
||||
}
|
||||
|
||||
public override bool Add<TCacheValue>(string key, TCacheValue value, CachePolicy policy)
|
||||
{
|
||||
return this.Add(key, value, null, this._defaultPolicy);
|
||||
return Add(key, value, null, _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));
|
||||
if (_doTraceLogging) Logger.LogTrace("Added [{0}], Region [{1}]", key, region);
|
||||
return Redis.StringSet(key, Serialize(value));
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
|
@ -72,71 +57,70 @@ namespace Roadie.Library.Caching
|
|||
var endpoints = Connection.GetEndPoints();
|
||||
var server = Connection.GetServer(endpoints[0]);
|
||||
server.FlushAllDatabases();
|
||||
if (this._doTraceLogging)
|
||||
{
|
||||
this.Logger.LogTrace("Cleared Cache");
|
||||
}
|
||||
if (_doTraceLogging) Logger.LogTrace("Cleared Cache");
|
||||
}
|
||||
|
||||
public override void ClearRegion(string region)
|
||||
{
|
||||
this.Clear();
|
||||
Clear();
|
||||
}
|
||||
|
||||
public override bool Exists<TOut>(string key)
|
||||
{
|
||||
return this.Exists<TOut>(key, null);
|
||||
return Exists<TOut>(key, null);
|
||||
}
|
||||
|
||||
public override bool Exists<TOut>(string key, string region)
|
||||
{
|
||||
return this.Redis.KeyExists(key);
|
||||
return Redis.KeyExists(key);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key)
|
||||
{
|
||||
return this.Get<TOut>(key, null);
|
||||
return Get<TOut>(key, null);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key, string region)
|
||||
{
|
||||
return this.Get<TOut>(key, region, this._defaultPolicy);
|
||||
return Get<TOut>(key, region, _defaultPolicy);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key, Func<TOut> getItem, string region)
|
||||
{
|
||||
return this.Get<TOut>(key, getItem, region, this._defaultPolicy);
|
||||
return Get(key, getItem, region, _defaultPolicy);
|
||||
}
|
||||
|
||||
public override TOut Get<TOut>(string key, Func<TOut> getItem, string region, CachePolicy policy)
|
||||
{
|
||||
var r = this.Get<TOut>(key, region);
|
||||
var r = Get<TOut>(key, region);
|
||||
if (r == null)
|
||||
{
|
||||
r = getItem();
|
||||
this.Add(key, r, region, policy);
|
||||
Add(key, r, region, policy);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public override Task<TOut> GetAsync<TOut>(string key, Func<Task<TOut>> getItem, string region)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool Remove(string key)
|
||||
{
|
||||
return this.Remove(key, null);
|
||||
return Remove(key, null);
|
||||
}
|
||||
|
||||
public override bool Remove(string key, string region)
|
||||
{
|
||||
if (this.Redis.KeyExists(key))
|
||||
{
|
||||
this.Redis.KeyDelete(key);
|
||||
}
|
||||
if (Redis.KeyExists(key)) Redis.KeyDelete(key);
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection.Close();
|
||||
|
@ -145,30 +129,23 @@ namespace Roadie.Library.Caching
|
|||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// free native resources here if there are any
|
||||
}
|
||||
|
||||
private TOut Get<TOut>(string key, string region, CachePolicy policy)
|
||||
{
|
||||
var result = this.Deserialize<TOut>(this.Redis.StringGet(key));
|
||||
var result = Deserialize<TOut>(Redis.StringGet(key));
|
||||
if (result == null)
|
||||
{
|
||||
if (this._doTraceLogging)
|
||||
{
|
||||
this.Logger.LogTrace("Get Cache Miss Key [{0}], Region [{1}]", key, region);
|
||||
}
|
||||
if (_doTraceLogging) Logger.LogTrace("Get Cache Miss Key [{0}], Region [{1}]", key, region);
|
||||
}
|
||||
else if (this._doTraceLogging)
|
||||
else if (_doTraceLogging)
|
||||
{
|
||||
this.Logger.LogTrace("Get Cache Hit Key [{0}], Region [{1}]", key, region);
|
||||
Logger.LogTrace("Get Cache Hit Key [{0}], Region [{1}]", key, region);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public override Task<TOut> GetAsync<TOut>(string key, Func<Task<TOut>> getItem, string region)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,13 +153,14 @@ namespace Roadie.Library.Caching
|
|||
{
|
||||
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
|
||||
{
|
||||
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
|
||||
var 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
|
||||
prop.Ignored = false; // Ignore [JsonIgnore]
|
||||
prop.Converter = null; // Ignore [JsonConverter]
|
||||
prop.PropertyName = prop.UnderlyingName; // restore original property name
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
namespace Roadie.Library.Configuration
|
||||
{
|
||||
/// <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)
|
||||
/// 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 : IApiKey
|
||||
|
|
|
@ -8,8 +8,8 @@ namespace Roadie.Library.Configuration
|
|||
public string APEConvertCommand { get; set; }
|
||||
public bool ConvertingEnabled { get; set; }
|
||||
public bool DoDeleteAfter { get; set; }
|
||||
public string FLACConvertCommand { get; set; }
|
||||
public string M4AConvertCommand { get; set; }
|
||||
public string OGGConvertCommand { get; set; }
|
||||
public string FLACConvertCommand { get; set; }
|
||||
}
|
||||
}
|
|
@ -2,8 +2,8 @@
|
|||
{
|
||||
public interface IConverting
|
||||
{
|
||||
bool ConvertingEnabled { get; set; }
|
||||
string APEConvertCommand { get; set; }
|
||||
bool ConvertingEnabled { get; set; }
|
||||
bool DoDeleteAfter { get; set; }
|
||||
string M4AConvertCommand { get; set; }
|
||||
string OGGConvertCommand { get; set; }
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace Roadie.Library.Configuration
|
|||
public interface IRoadieSettings
|
||||
{
|
||||
Dictionary<string, List<string>> ArtistNameReplace { get; set; }
|
||||
string BehindProxyHost { get; set; }
|
||||
string ConnectionString { get; set; }
|
||||
string ContentPath { get; set; }
|
||||
Converting Converting { get; set; }
|
||||
|
@ -14,11 +15,12 @@ namespace Roadie.Library.Configuration
|
|||
IEnumerable<string> FileExtensionsToDelete { get; set; }
|
||||
FilePlugins FilePlugins { get; set; }
|
||||
string InboundFolder { get; set; }
|
||||
Inspector Inspector { get; set; }
|
||||
Integrations Integrations { get; set; }
|
||||
ImageSize LargeImageSize { get; set; }
|
||||
ImageSize MaximumImageSize { get; set; }
|
||||
string LibraryFolder { get; set; }
|
||||
string ListenAddress { get; set; }
|
||||
ImageSize MaximumImageSize { get; set; }
|
||||
ImageSize MediumImageSize { get; set; }
|
||||
Processing Processing { get; set; }
|
||||
bool RecordNoResultSearches { get; set; }
|
||||
|
@ -35,8 +37,6 @@ namespace Roadie.Library.Configuration
|
|||
ImageSize ThumbnailImageSize { get; set; }
|
||||
Dictionary<string, string> TrackPathReplace { get; set; }
|
||||
bool UseSSLBehindProxy { get; set; }
|
||||
string BehindProxyHost { get; set; }
|
||||
string WebsocketAddress { get; set; }
|
||||
Inspector Inspector { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,19 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Configuration
|
||||
namespace Roadie.Library.Configuration
|
||||
{
|
||||
public class Inspector : IInspector
|
||||
{
|
||||
/// <summary>
|
||||
/// When true then make a copy of files to new destination versus moving files to destination.
|
||||
/// When true then make a copy of files to new destination versus moving files to destination.
|
||||
/// </summary>
|
||||
public bool DoCopyFiles { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When true then don't modify any files only report what would be done.
|
||||
/// When true then don't modify any files only report what would be done.
|
||||
/// </summary>
|
||||
public bool IsInReadOnlyMode { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,20 +15,15 @@ namespace Roadie.Library.Configuration
|
|||
|
||||
public List<ApiKey> ApiKeys { get; set; } = new List<ApiKey>();
|
||||
|
||||
|
||||
public string DiscogsConsumerKey
|
||||
{
|
||||
get
|
||||
{
|
||||
var keySetting = this.ApiKeys.FirstOrDefault(x => x.ApiName == "DiscogsConsumerKey");
|
||||
var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "DiscogsConsumerKey");
|
||||
if (keySetting != null)
|
||||
{
|
||||
return keySetting.Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace.WriteLine("Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled");
|
||||
}
|
||||
Trace.WriteLine(
|
||||
"Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -37,15 +32,11 @@ namespace Roadie.Library.Configuration
|
|||
{
|
||||
get
|
||||
{
|
||||
var keySetting = this.ApiKeys.FirstOrDefault(x => x.ApiName == "DiscogsConsumerKey");
|
||||
var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "DiscogsConsumerKey");
|
||||
if (keySetting != null)
|
||||
{
|
||||
return keySetting.KeySecret;
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace.WriteLine("Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled");
|
||||
}
|
||||
Trace.WriteLine(
|
||||
"Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -54,16 +45,11 @@ namespace Roadie.Library.Configuration
|
|||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.DiscogsConsumerKey) || string.IsNullOrEmpty(this.DiscogsConsumerSecret))
|
||||
{
|
||||
if (string.IsNullOrEmpty(DiscogsConsumerKey) || string.IsNullOrEmpty(DiscogsConsumerSecret))
|
||||
return false;
|
||||
}
|
||||
return this._discogsEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
this._discogsEnabled = value;
|
||||
return _discogsEnabled;
|
||||
}
|
||||
set => _discogsEnabled = value;
|
||||
}
|
||||
|
||||
public short? DiscogsReadWriteTimeout { get; set; }
|
||||
|
@ -76,15 +62,10 @@ namespace Roadie.Library.Configuration
|
|||
{
|
||||
get
|
||||
{
|
||||
var keySetting = this.ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey");
|
||||
var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey");
|
||||
if (keySetting != null)
|
||||
{
|
||||
return keySetting.Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled");
|
||||
}
|
||||
Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -93,15 +74,10 @@ namespace Roadie.Library.Configuration
|
|||
{
|
||||
get
|
||||
{
|
||||
var keySetting = this.ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey");
|
||||
var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey");
|
||||
if (keySetting != null)
|
||||
{
|
||||
return keySetting.KeySecret;
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled");
|
||||
}
|
||||
Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -110,16 +86,10 @@ namespace Roadie.Library.Configuration
|
|||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.LastFMApiKey) || string.IsNullOrEmpty(this.LastFmApiSecret))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this._lastFmEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
this._lastFmEnabled = value;
|
||||
if (string.IsNullOrEmpty(LastFMApiKey) || string.IsNullOrEmpty(LastFmApiSecret)) return false;
|
||||
return _lastFmEnabled;
|
||||
}
|
||||
set => _lastFmEnabled = value;
|
||||
}
|
||||
|
||||
public bool MusicBrainzProviderEnabled { get; set; }
|
||||
|
|
|
@ -6,34 +6,55 @@ namespace Roadie.Library.Configuration
|
|||
[Serializable]
|
||||
public class Processing : IProcessing
|
||||
{
|
||||
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 int MaxImageWidth { get; set; }
|
||||
public int MaximumArtistImagesToAdd { get; set; }
|
||||
public int MaximumReleaseImagesToAdd { get; set; }
|
||||
public string RemoveStringsRegex { get; set; }
|
||||
public string ArtistRemoveStringsRegex { get; set; }
|
||||
public string ReleaseRemoveStringsRegex { get; set; }
|
||||
public string TrackRemoveStringsRegex { get; set; }
|
||||
public string PreInspectScript { get; set; }
|
||||
|
||||
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 int MaxImageWidth { get; set; }
|
||||
|
||||
public int MaximumArtistImagesToAdd { get; set; }
|
||||
|
||||
public int MaximumReleaseImagesToAdd { get; set; }
|
||||
|
||||
public string PostInspectScript { get; set; }
|
||||
|
||||
public string PreInspectScript { get; set; }
|
||||
|
||||
public string ReleaseRemoveStringsRegex { get; set; }
|
||||
|
||||
public string RemoveStringsRegex { get; set; }
|
||||
|
||||
public List<ReplacementString> ReplaceStrings { get; set; }
|
||||
|
||||
public string TrackRemoveStringsRegex { get; set; }
|
||||
|
||||
public string UnknownFolder { get; set; }
|
||||
|
||||
public Processing()
|
||||
{
|
||||
this.ReplaceStrings = new List<ReplacementString>();
|
||||
this.DoAudioCleanup = true;
|
||||
this.DoClearComments = true;
|
||||
ReplaceStrings = new List<ReplacementString>();
|
||||
DoAudioCleanup = true;
|
||||
DoClearComments = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Configuration
|
||||
{
|
||||
[Serializable]
|
||||
public class ReplacementString : IReplacementString
|
||||
{
|
||||
public int Order { get; set; }
|
||||
public string Key { get; set; }
|
||||
public int Order { get; set; }
|
||||
public string ReplaceWith { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,53 +7,83 @@ namespace Roadie.Library.Configuration
|
|||
public sealed class RoadieSettings : IRoadieSettings
|
||||
{
|
||||
/// <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>
|
||||
/// 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 string BehindProxyHost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set to the Roadie Database for DbDataReader operations
|
||||
/// Set to the Roadie Database for DbDataReader operations
|
||||
/// </summary>
|
||||
public string ConnectionString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is the phsycial path to the content folder (which holds among other things place-holder images)
|
||||
/// This is the phsycial path to the content folder (which holds among other things place-holder images)
|
||||
/// </summary>
|
||||
public string ContentPath { get; set; }
|
||||
|
||||
public Converting Converting { get; set; }
|
||||
|
||||
public string DefaultTimeZone { get; set; }
|
||||
|
||||
public string DiagnosticsPassword { get; set; }
|
||||
|
||||
public IEnumerable<string> DontDoMetaDataProvidersSearchArtists { get; set; }
|
||||
|
||||
public IEnumerable<string> FileExtensionsToDelete { get; set; }
|
||||
|
||||
public FilePlugins FilePlugins { get; set; }
|
||||
|
||||
public string InboundFolder { get; set; }
|
||||
public Integrations Integrations { get; set; }
|
||||
public ImageSize LargeImageSize { get; set; }
|
||||
public ImageSize MaximumImageSize { get; set; }
|
||||
public string LibraryFolder { get; set; }
|
||||
public string ListenAddress { get; set; }
|
||||
public ImageSize MediumImageSize { get; set; }
|
||||
public Processing Processing { get; set; }
|
||||
public bool RecordNoResultSearches { get; set; }
|
||||
public RedisCache Redis { get; set; }
|
||||
public ImageSize SmallImageSize { get; set; }
|
||||
public string SecretKey { get; set; }
|
||||
public string SiteName { get; set; }
|
||||
public string SmtpFromAddress { get; set; }
|
||||
public string SmtpHost { get; set; }
|
||||
public string SmtpPassword { get; set; }
|
||||
public int SmtpPort { get; set; }
|
||||
public string SmtpUsername { get; set; }
|
||||
public bool SmtpUseSSl { get; set; }
|
||||
public ImageSize ThumbnailImageSize { get; set; }
|
||||
public Dictionary<string, string> TrackPathReplace { get; set; }
|
||||
public bool UseSSLBehindProxy { get; set; }
|
||||
public string BehindProxyHost { get; set; }
|
||||
public string WebsocketAddress { get; set; }
|
||||
|
||||
public Inspector Inspector { get; set; }
|
||||
|
||||
public Integrations Integrations { get; set; }
|
||||
|
||||
public ImageSize LargeImageSize { get; set; }
|
||||
|
||||
public string LibraryFolder { get; set; }
|
||||
|
||||
public string ListenAddress { get; set; }
|
||||
|
||||
public ImageSize MaximumImageSize { get; set; }
|
||||
|
||||
public ImageSize MediumImageSize { get; set; }
|
||||
|
||||
public Processing Processing { get; set; }
|
||||
|
||||
public bool RecordNoResultSearches { get; set; }
|
||||
|
||||
public RedisCache Redis { get; set; }
|
||||
|
||||
public string SecretKey { get; set; }
|
||||
|
||||
public string SiteName { get; set; }
|
||||
|
||||
public ImageSize SmallImageSize { get; set; }
|
||||
|
||||
public string SmtpFromAddress { get; set; }
|
||||
|
||||
public string SmtpHost { get; set; }
|
||||
|
||||
public string SmtpPassword { get; set; }
|
||||
|
||||
public int SmtpPort { get; set; }
|
||||
|
||||
public string SmtpUsername { get; set; }
|
||||
|
||||
public bool SmtpUseSSl { get; set; }
|
||||
|
||||
public ImageSize ThumbnailImageSize { get; set; }
|
||||
|
||||
public Dictionary<string, string> TrackPathReplace { get; set; }
|
||||
|
||||
public bool UseSSLBehindProxy { get; set; }
|
||||
|
||||
public string WebsocketAddress { get; set; }
|
||||
|
||||
public RoadieSettings()
|
||||
{
|
||||
ThumbnailImageSize = new ImageSize { Width = 80, Height = 80 };
|
||||
|
|
|
@ -6,12 +6,13 @@ namespace Roadie.Library.Configuration
|
|||
public class ImageSize : IImageSize
|
||||
{
|
||||
public short Height { get; set; }
|
||||
|
||||
public short Width { get; set; }
|
||||
|
||||
public ImageSize()
|
||||
{
|
||||
this.Height = 80;
|
||||
this.Width = 80;
|
||||
Height = 80;
|
||||
Width = 80;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,18 +9,12 @@ namespace Roadie.Library.Data
|
|||
[Table("artist")]
|
||||
public partial class Artist : BeginAndEndNamedEntityBase
|
||||
{
|
||||
[Column("amgId")]
|
||||
[MaxLength(100)]
|
||||
public string AmgId { get; set; }
|
||||
[Column("amgId")] [MaxLength(100)] public string AmgId { get; set; }
|
||||
|
||||
[Column("artistType", TypeName = "enum")]
|
||||
public string ArtistType { get; set; }
|
||||
|
||||
[InverseProperty("Artist")]
|
||||
public ICollection<ArtistAssociation> AssociatedArtists { get; set; }
|
||||
|
||||
[InverseProperty("Artist")]
|
||||
public ICollection<ArtistSimilar> SimilarArtists { get; set; }
|
||||
[InverseProperty("Artist")] public ICollection<ArtistAssociation> AssociatedArtists { get; set; }
|
||||
|
||||
[Column("bandStatus", TypeName = "enum")]
|
||||
public BandStatus? BandStatus { get; set; }
|
||||
|
@ -32,9 +26,9 @@ namespace Roadie.Library.Data
|
|||
[Column("birthDate", TypeName = "date")]
|
||||
public DateTime? BirthDate { get; set; }
|
||||
|
||||
[Column("discogsId")]
|
||||
[MaxLength(50)]
|
||||
public string DiscogsId { get; set; }
|
||||
public ICollection<Comment> Comments { get; set; }
|
||||
|
||||
[Column("discogsId")] [MaxLength(50)] public string DiscogsId { get; set; }
|
||||
|
||||
public ICollection<ArtistGenre> Genres { get; set; }
|
||||
|
||||
|
@ -44,59 +38,46 @@ namespace Roadie.Library.Data
|
|||
[MaxLength(65535)]
|
||||
public string ISNI { get; set; }
|
||||
|
||||
[Column("iTunesId")]
|
||||
[MaxLength(100)]
|
||||
public string ITunesId { get; set; }
|
||||
[Column("iTunesId")] [MaxLength(100)] public string ITunesId { get; set; }
|
||||
|
||||
[Column("lastPlayed")]
|
||||
public DateTime? LastPlayed { get; set; }
|
||||
[Column("lastPlayed")] public DateTime? LastPlayed { get; set; }
|
||||
|
||||
[Column("musicBrainzId")]
|
||||
[MaxLength(100)]
|
||||
public string MusicBrainzId { get; set; }
|
||||
|
||||
[Column("playedCount")] public int? PlayedCount { get; set; }
|
||||
|
||||
[Column("profile", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string Profile { get; set; }
|
||||
|
||||
[Column("playedCount")]
|
||||
public int? PlayedCount { get; set; }
|
||||
[Column("rank")] public decimal? Rank { get; set; }
|
||||
|
||||
[Column("rating")]
|
||||
public short? Rating { get; set; }
|
||||
[Column("rating")] public short? Rating { get; set; }
|
||||
|
||||
[Column("rank")]
|
||||
public decimal? Rank { get; set; }
|
||||
[Column("realName")] [MaxLength(500)] public string RealName { get; set; }
|
||||
|
||||
[Column("realName")]
|
||||
[MaxLength(500)]
|
||||
public string RealName { get; set; }
|
||||
[Column("releaseCount")] public int? ReleaseCount { get; set; }
|
||||
|
||||
//public List<Release> Releases { get; set; }
|
||||
public ICollection<Release> Releases { get; set; }
|
||||
|
||||
[Column("spotifyId")]
|
||||
[MaxLength(100)]
|
||||
public string SpotifyId { get; set; }
|
||||
[InverseProperty("Artist")] public ICollection<ArtistSimilar> SimilarArtists { get; set; }
|
||||
|
||||
[Column("releaseCount")]
|
||||
public int? ReleaseCount { get; set; }
|
||||
[Column("spotifyId")] [MaxLength(100)] public string SpotifyId { get; set; }
|
||||
|
||||
[Column("trackCount")]
|
||||
public int? TrackCount { get; set; }
|
||||
|
||||
public ICollection<Comment> Comments { get; set; }
|
||||
[Column("trackCount")] public int? TrackCount { get; set; }
|
||||
|
||||
public Artist()
|
||||
{
|
||||
this.Releases = new HashSet<Release>();
|
||||
this.Genres = new HashSet<ArtistGenre>();
|
||||
this.AssociatedArtists = new HashSet<ArtistAssociation>();
|
||||
this.SimilarArtists = new HashSet<ArtistSimilar>();
|
||||
this.Comments = new HashSet<Comment>();
|
||||
this.Rating = 0;
|
||||
this.Status = Statuses.Ok;
|
||||
Releases = new HashSet<Release>();
|
||||
Genres = new HashSet<ArtistGenre>();
|
||||
AssociatedArtists = new HashSet<ArtistAssociation>();
|
||||
SimilarArtists = new HashSet<ArtistSimilar>();
|
||||
Comments = new HashSet<Comment>();
|
||||
Rating = 0;
|
||||
Status = Statuses.Ok;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -4,20 +4,17 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("artistAssociation")]
|
||||
public partial class ArtistAssociation
|
||||
public class ArtistAssociation
|
||||
{
|
||||
//[ForeignKey("artistId")]
|
||||
public Artist Artist { get; set; }
|
||||
|
||||
[Column("artistId")]
|
||||
[Required]
|
||||
public int ArtistId { get; set; }
|
||||
[Column("artistId")] [Required] public int ArtistId { get; set; }
|
||||
|
||||
//[ForeignKey("associatedArtistId")]
|
||||
public Artist AssociatedArtist { get; set; }
|
||||
|
||||
[Column("associatedArtistId")]
|
||||
public int AssociatedArtistId { get; set; }
|
||||
[Column("associatedArtistId")] public int AssociatedArtistId { get; set; }
|
||||
|
||||
[Key]
|
||||
[Column("id")]
|
||||
|
|
|
@ -4,19 +4,15 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("artistGenreTable")]
|
||||
public partial class ArtistGenre
|
||||
public class ArtistGenre
|
||||
{
|
||||
public Artist Artist { get; set; }
|
||||
|
||||
[Column("artistId")]
|
||||
[Required]
|
||||
public int ArtistId { get; set; }
|
||||
[Column("artistId")] [Required] public int ArtistId { get; set; }
|
||||
|
||||
public Genre Genre { get; set; }
|
||||
|
||||
[Column("genreId")]
|
||||
[Required]
|
||||
public int? GenreId { get; set; }
|
||||
[Column("genreId")] [Required] public int? GenreId { get; set; }
|
||||
|
||||
[Column("id")]
|
||||
[Key]
|
||||
|
|
|
@ -2,85 +2,60 @@
|
|||
using Roadie.Library.Utility;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public partial class Artist
|
||||
{
|
||||
public static string CacheRegionUrn(Guid Id)
|
||||
{
|
||||
return $"urn:artist:{ Id}";
|
||||
}
|
||||
public string CacheKey => CacheUrn(RoadieId);
|
||||
|
||||
public static string CacheUrnByName(string name)
|
||||
{
|
||||
return $"urn:artist_by_name:{ name }";
|
||||
}
|
||||
|
||||
public static string CacheUrn(Guid Id)
|
||||
{
|
||||
return $"urn:artist_by_id:{ Id }";
|
||||
}
|
||||
|
||||
public string CacheKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return Artist.CacheUrn(this.RoadieId);
|
||||
}
|
||||
}
|
||||
|
||||
public string CacheRegion
|
||||
{
|
||||
get
|
||||
{
|
||||
return Artist.CacheRegionUrn(this.RoadieId);
|
||||
}
|
||||
}
|
||||
public string CacheRegion => CacheRegionUrn(RoadieId);
|
||||
|
||||
public string Etag
|
||||
{
|
||||
get
|
||||
{
|
||||
using (var md5 = System.Security.Cryptography.MD5.Create())
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
return String.Concat(md5.ComputeHash(System.Text.Encoding.Default.GetBytes(string.Format("{0}{1}", this.RoadieId, this.LastUpdated))).Select(x => x.ToString("D2")));
|
||||
return string.Concat(md5
|
||||
.ComputeHash(
|
||||
System.Text.Encoding.Default.GetBytes(string.Format("{0}{1}", RoadieId, LastUpdated)))
|
||||
.Select(x => x.ToString("D2")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNew
|
||||
public bool IsNew => Id < 1;
|
||||
|
||||
public bool IsValid => !string.IsNullOrEmpty(Name);
|
||||
|
||||
public string SortNameValue => string.IsNullOrEmpty(SortName) ? Name : SortName;
|
||||
|
||||
public static string CacheRegionUrn(Guid Id)
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Id < 1;
|
||||
}
|
||||
return $"urn:artist:{Id}";
|
||||
}
|
||||
|
||||
public bool IsValid
|
||||
public static string CacheUrn(Guid Id)
|
||||
{
|
||||
get
|
||||
{
|
||||
return !string.IsNullOrEmpty(this.Name);
|
||||
}
|
||||
return $"urn:artist_by_id:{Id}";
|
||||
}
|
||||
|
||||
public string SortNameValue
|
||||
public static string CacheUrnByName(string name)
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.IsNullOrEmpty(this.SortName) ? this.Name : this.SortName;
|
||||
}
|
||||
return $"urn:artist_by_name:{name}";
|
||||
}
|
||||
|
||||
public string ArtistFileFolder(IRoadieSettings configuration, string destinationRoot)
|
||||
{
|
||||
return FolderPathHelper.ArtistPath(configuration, this.SortNameValue, destinationRoot);
|
||||
return FolderPathHelper.ArtistPath(configuration, SortNameValue, destinationRoot);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("Id [{0}], Name [{1}], SortName [{2}], RoadieId [{3}]", this.Id, this.Name, this.SortNameValue, this.RoadieId);
|
||||
return string.Format("Id [{0}], Name [{1}], SortName [{2}], RoadieId [{3}]", Id, Name, SortNameValue,
|
||||
RoadieId);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,24 +4,21 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("artistSimilar")]
|
||||
public partial class ArtistSimilar
|
||||
public class ArtistSimilar
|
||||
{
|
||||
//[ForeignKey("artistId")]
|
||||
public Artist Artist { get; set; }
|
||||
|
||||
[Column("artistId")]
|
||||
[Required]
|
||||
public int ArtistId { get; set; }
|
||||
|
||||
//[ForeignKey("associatedArtistId")]
|
||||
public Artist SimilarArtist { get; set; }
|
||||
|
||||
[Column("similarArtistId")]
|
||||
public int SimilarArtistId { get; set; }
|
||||
[Column("artistId")] [Required] public int ArtistId { get; set; }
|
||||
|
||||
[Key]
|
||||
[Column("id")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
|
||||
//[ForeignKey("associatedArtistId")]
|
||||
public Artist SimilarArtist { get; set; }
|
||||
|
||||
[Column("similarArtistId")] public int SimilarArtistId { get; set; }
|
||||
}
|
||||
}
|
|
@ -8,7 +8,6 @@ namespace Roadie.Library.Data
|
|||
[Column("beginDate", TypeName = "date")]
|
||||
public DateTime? BeginDate { get; set; }
|
||||
|
||||
[Column("endDate", TypeName = "date")]
|
||||
public DateTime? EndDate { get; set; }
|
||||
[Column("endDate", TypeName = "date")] public DateTime? EndDate { get; set; }
|
||||
}
|
||||
}
|
|
@ -5,10 +5,8 @@ namespace Roadie.Library.Data
|
|||
{
|
||||
public abstract class BeginAndEndNamedEntityBase : NamedEntityBase
|
||||
{
|
||||
[Column("beginDate")]
|
||||
public DateTime? BeginDate { get; set; }
|
||||
[Column("beginDate")] public DateTime? BeginDate { get; set; }
|
||||
|
||||
[Column("endDate")]
|
||||
public DateTime? EndDate { get; set; }
|
||||
[Column("endDate")] public DateTime? EndDate { get; set; }
|
||||
}
|
||||
}
|
|
@ -8,26 +8,16 @@ namespace Roadie.Library.Data
|
|||
[Table("bookmark")]
|
||||
public partial class Bookmark : EntityBase
|
||||
{
|
||||
[Column("bookmarkTargetId")]
|
||||
public int BookmarkTargetId { get; set; }
|
||||
[Column("bookmarkTargetId")] public int BookmarkTargetId { get; set; }
|
||||
|
||||
// public short? Type { get; set; }
|
||||
|
||||
// public short? Type { get; set; }
|
||||
|
||||
[Column("bookmarkType")]
|
||||
public BookmarkType? BookmarkType { get; set; }
|
||||
[Column("bookmarkType")] public BookmarkType? BookmarkType { get; set; }
|
||||
|
||||
[Column("Comment")] [MaxLength(4000)] public string Comment { get; set; }
|
||||
[Column("position")] public int? Position { get; set; }
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
[Column("userId")]
|
||||
[Required]
|
||||
public int UserId { get; set; }
|
||||
|
||||
[Column("position")]
|
||||
public int? Position { get; set; }
|
||||
|
||||
[Column("Comment")]
|
||||
[MaxLength(4000)]
|
||||
public string Comment { get; set; }
|
||||
[Column("userId")] [Required] public int UserId { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,14 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public partial class Bookmark
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Id [{ this.Id }], BookmarkType [{ this.BookmarkType }], BookmarkTargetId [{ this.BookmarkTargetId }]";
|
||||
return $"Id [{Id}], BookmarkType [{BookmarkType}], BookmarkTargetId [{BookmarkTargetId}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +1,19 @@
|
|||
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("chatMessage")]
|
||||
public class ChatMessage : EntityBase
|
||||
{
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
[Column("userId")]
|
||||
[Required]
|
||||
public int UserId { get; set; }
|
||||
|
||||
[Column("message")]
|
||||
[Required]
|
||||
[MaxLength(5000)]
|
||||
public string Message { get; set; }
|
||||
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
[Column("userId")] [Required] public int UserId { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using Roadie.Library.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
@ -9,19 +8,17 @@ namespace Roadie.Library.Data
|
|||
[Table("collection")]
|
||||
public partial class Collection : NamedEntityBase
|
||||
{
|
||||
[Column("collectionCount")]
|
||||
public int CollectionCount { get; set; }
|
||||
[Column("collectionCount")] public int CollectionCount { get; set; }
|
||||
|
||||
[Column("collectionType")]
|
||||
public CollectionType? CollectionType { get; set; }
|
||||
[Column("collectionType")] public CollectionType? CollectionType { get; set; }
|
||||
|
||||
public ICollection<Comment> Comments { get; set; }
|
||||
|
||||
[Column("description")]
|
||||
[MaxLength(4000)]
|
||||
public string Description { get; set; }
|
||||
|
||||
[Column("edition")]
|
||||
[MaxLength(200)]
|
||||
public string Edition { get; set; }
|
||||
[Column("edition")] [MaxLength(200)] public string Edition { get; set; }
|
||||
|
||||
[Column("listInCSV", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
|
@ -31,12 +28,8 @@ namespace Roadie.Library.Data
|
|||
[MaxLength(200)]
|
||||
public string ListInCSVFormat { get; set; }
|
||||
|
||||
[Column("maintainerId")]
|
||||
public int MaintainerId { get; set; }
|
||||
[Column("maintainerId")] public int MaintainerId { get; set; }
|
||||
|
||||
public ICollection<CollectionRelease> Releases { get; set; }
|
||||
|
||||
public ICollection<Comment> Comments { get; set; }
|
||||
|
||||
}
|
||||
}
|
|
@ -1,28 +1,23 @@
|
|||
using Roadie.Library.Enums;
|
||||
using Roadie.Library.Identity;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("collectionMissing")]
|
||||
public partial class CollectionMissing
|
||||
public class CollectionMissing
|
||||
{
|
||||
[Column("artist")] [MaxLength(1000)] public string Artist { get; set; }
|
||||
|
||||
[Column("collectionId")] public int CollectionId { get; set; }
|
||||
|
||||
[Column("id")]
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
[Column("collectionId")]
|
||||
public int CollectionId { get; set; }
|
||||
[Column("isArtistFound")]
|
||||
public bool IsArtistFound { get; set; }
|
||||
[Column("position")]
|
||||
public int Position { get; set; }
|
||||
[Column("artist")]
|
||||
[MaxLength(1000)]
|
||||
public string Artist { get; set; }
|
||||
[Column("release")]
|
||||
[MaxLength(1000)]
|
||||
public string Release { get; set; }
|
||||
|
||||
[Column("isArtistFound")] public bool IsArtistFound { get; set; }
|
||||
|
||||
[Column("position")] public int Position { get; set; }
|
||||
[Column("release")] [MaxLength(1000)] public string Release { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,12 +6,83 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public partial class Collection
|
||||
{
|
||||
public int? _artistColumn;
|
||||
|
||||
public int? _positionColumn;
|
||||
public int? _releaseColumn;
|
||||
private IEnumerable<PositionArtistRelease> _positionArtistReleases;
|
||||
|
||||
public int ArtistColumn
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_artistColumn == null)
|
||||
{
|
||||
var looper = -1;
|
||||
foreach (var pos in ListInCSVFormat.Split(','))
|
||||
{
|
||||
looper++;
|
||||
if (pos.ToLower().Equals("artist")) _artistColumn = looper;
|
||||
}
|
||||
}
|
||||
|
||||
return _artistColumn.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public string CacheKey => CacheUrn(RoadieId);
|
||||
|
||||
public string CacheRegion => CacheRegionUrn(RoadieId);
|
||||
|
||||
public int PositionColumn
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_positionColumn == null)
|
||||
{
|
||||
var looper = -1;
|
||||
foreach (var pos in ListInCSVFormat.Split(','))
|
||||
{
|
||||
looper++;
|
||||
if (pos.ToLower().Equals("position")) _positionColumn = looper;
|
||||
}
|
||||
}
|
||||
|
||||
return _positionColumn.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public int ReleaseColumn
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_releaseColumn == null)
|
||||
{
|
||||
var looper = -1;
|
||||
foreach (var pos in ListInCSVFormat.Split(','))
|
||||
{
|
||||
looper++;
|
||||
if (pos.ToLower().Equals("release")) _releaseColumn = looper;
|
||||
}
|
||||
}
|
||||
|
||||
return _releaseColumn.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection()
|
||||
{
|
||||
Releases = new HashSet<CollectionRelease>();
|
||||
Comments = new HashSet<Comment>();
|
||||
ListInCSVFormat = "Position,Release,Artist";
|
||||
CollectionType = Enums.CollectionType.Rank;
|
||||
}
|
||||
|
||||
public static string CacheRegionUrn(Guid Id)
|
||||
{
|
||||
return string.Format("urn:collection:{0}", Id);
|
||||
|
@ -19,97 +90,15 @@ namespace Roadie.Library.Data
|
|||
|
||||
public static string CacheUrn(Guid Id)
|
||||
{
|
||||
return $"urn:collection_by_id:{ Id }";
|
||||
return $"urn:collection_by_id:{Id}";
|
||||
}
|
||||
|
||||
public string CacheKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return Collection.CacheUrn(this.RoadieId);
|
||||
}
|
||||
}
|
||||
|
||||
public string CacheRegion
|
||||
{
|
||||
get
|
||||
{
|
||||
return Collection.CacheRegionUrn(this.RoadieId);
|
||||
}
|
||||
}
|
||||
|
||||
public int? _positionColumn = null;
|
||||
public int PositionColumn
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this._positionColumn == null)
|
||||
{
|
||||
var looper = -1;
|
||||
foreach (var pos in this.ListInCSVFormat.Split(','))
|
||||
{
|
||||
looper++;
|
||||
if (pos.ToLower().Equals("position"))
|
||||
{
|
||||
this._positionColumn = looper;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this._positionColumn.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public int? _artistColumn = null;
|
||||
public int ArtistColumn
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this._artistColumn == null)
|
||||
{
|
||||
var looper = -1;
|
||||
foreach (var pos in this.ListInCSVFormat.Split(','))
|
||||
{
|
||||
looper++;
|
||||
if (pos.ToLower().Equals("artist"))
|
||||
{
|
||||
this._artistColumn = looper;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this._artistColumn.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public int? _releaseColumn = null;
|
||||
public int ReleaseColumn
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this._releaseColumn == null)
|
||||
{
|
||||
var looper = -1;
|
||||
foreach (var pos in this.ListInCSVFormat.Split(','))
|
||||
{
|
||||
looper++;
|
||||
if (pos.ToLower().Equals("release"))
|
||||
{
|
||||
this._releaseColumn = looper;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this._releaseColumn.Value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private IEnumerable<PositionArtistRelease> _positionArtistReleases = null;
|
||||
|
||||
public IEnumerable<PositionArtistRelease> PositionArtistReleases()
|
||||
{
|
||||
if (this._positionArtistReleases == null)
|
||||
if (_positionArtistReleases == null)
|
||||
{
|
||||
var rows = new List<PositionArtistRelease>();
|
||||
using (var sr = new StringReader(this.ListInCSV))
|
||||
using (var sr = new StringReader(ListInCSV))
|
||||
{
|
||||
var index = 0;
|
||||
var configuration = new CsvHelper.Configuration.Configuration
|
||||
|
@ -128,60 +117,49 @@ namespace Roadie.Library.Data
|
|||
rows.Add(new PositionArtistRelease
|
||||
{
|
||||
Index = index,
|
||||
Position = csv.GetField<int>(this.PositionColumn),
|
||||
Artist = SafeParser.ToString(csv.GetField<string>(this.ArtistColumn)),
|
||||
Release = SafeParser.ToString(csv.GetField<string>(this.ReleaseColumn)),
|
||||
Position = csv.GetField<int>(PositionColumn),
|
||||
Artist = SafeParser.ToString(csv.GetField<string>(ArtistColumn)),
|
||||
Release = SafeParser.ToString(csv.GetField<string>(ReleaseColumn))
|
||||
});
|
||||
}
|
||||
}
|
||||
this._positionArtistReleases = rows;
|
||||
}
|
||||
return this._positionArtistReleases;
|
||||
}
|
||||
|
||||
public Collection()
|
||||
{
|
||||
this.Releases = new HashSet<CollectionRelease>();
|
||||
this.Comments = new HashSet<Comment>();
|
||||
ListInCSVFormat = "Position,Release,Artist";
|
||||
CollectionType = Enums.CollectionType.Rank;
|
||||
_positionArtistReleases = rows;
|
||||
}
|
||||
|
||||
return _positionArtistReleases;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Id [{ this.Id }], Name [{ this.Name }]";
|
||||
return $"Id [{Id}], Name [{Name}]";
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class PositionArtistRelease
|
||||
{
|
||||
[JsonIgnore]
|
||||
public Statuses Status { get; set; }
|
||||
public string Artist { get; set; }
|
||||
|
||||
[JsonProperty("Status")]
|
||||
public string StatusVerbose
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Status.ToString();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// This is the index (position in the list regardless of the position number)
|
||||
/// This is the index (position in the list regardless of the position number)
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public int Index { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is the position number for the list (can be a year "1984" can be a number "14")
|
||||
/// This is the position number for the list (can be a year "1984" can be a number "14")
|
||||
/// </summary>
|
||||
public int Position { get; set; }
|
||||
public string Artist { get; set; }
|
||||
|
||||
public string Release { get; set; }
|
||||
[JsonIgnore] public Statuses Status { get; set; }
|
||||
|
||||
[JsonProperty("Status")] public string StatusVerbose => Status.ToString();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("Position [{0}], Artist [{1}], Release [{2}]", this.Position, this.Artist, this.Release);
|
||||
return string.Format("Position [{0}], Artist [{1}], Release [{2}]", Position, Artist, Release);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,21 +4,16 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("collectionrelease")]
|
||||
public partial class CollectionRelease : EntityBase
|
||||
public class CollectionRelease : EntityBase
|
||||
{
|
||||
public Collection Collection { get; set; }
|
||||
|
||||
[Column("collectionId")]
|
||||
[Required]
|
||||
public int CollectionId { get; set; }
|
||||
[Column("collectionId")] [Required] public int CollectionId { get; set; }
|
||||
|
||||
[Column("listNumber")]
|
||||
public int ListNumber { get; set; }
|
||||
[Column("listNumber")] public int ListNumber { get; set; }
|
||||
|
||||
public Release Release { get; set; }
|
||||
|
||||
[Column("releaseId")]
|
||||
[Required]
|
||||
public int ReleaseId { get; set; }
|
||||
[Column("releaseId")] [Required] public int ReleaseId { get; set; }
|
||||
}
|
||||
}
|
|
@ -9,50 +9,39 @@ namespace Roadie.Library.Data
|
|||
[Table("comment")]
|
||||
public partial class Comment : EntityBase
|
||||
{
|
||||
[Column("artistId")] public int? ArtistId { get; set; }
|
||||
|
||||
[Column("comment")]
|
||||
[MaxLength(25500)]
|
||||
[Required]
|
||||
public string Cmt { get; set; }
|
||||
|
||||
public ApplicationUser User { get; set; }
|
||||
[Column("collectionId")] public int? CollectionId { get; set; }
|
||||
|
||||
[Column("userId")]
|
||||
[Required]
|
||||
public int UserId { get; set; }
|
||||
[Column("genreId")] public int? GenreId { get; set; }
|
||||
|
||||
[Column("replyToCommentId")]
|
||||
public int? ReplyToCommentId { get; set; }
|
||||
[NotMapped] public new bool? IsLocked { get; set; }
|
||||
|
||||
[Column("artistId")]
|
||||
public int? ArtistId { get; set; }
|
||||
[Column("labelId")] public int? LabelId { get; set; }
|
||||
|
||||
[Column("collectionId")]
|
||||
public int? CollectionId { get; set; }
|
||||
|
||||
[Column("genreId")]
|
||||
public int? GenreId { get; set; }
|
||||
|
||||
[Column("labelId")]
|
||||
public int? LabelId { get; set; }
|
||||
|
||||
[Column("playlistId")]
|
||||
public int? PlaylistId { get; set; }
|
||||
|
||||
[Column("releaseId")]
|
||||
public int? ReleaseId { get; set; }
|
||||
|
||||
[Column("trackId")]
|
||||
public int? TrackId { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public new bool? IsLocked { get; set; }
|
||||
[Column("playlistId")] public int? PlaylistId { get; set; }
|
||||
|
||||
public ICollection<CommentReaction> Reactions { get; set; }
|
||||
|
||||
[Column("releaseId")] public int? ReleaseId { get; set; }
|
||||
|
||||
[Column("replyToCommentId")] public int? ReplyToCommentId { get; set; }
|
||||
|
||||
[Column("trackId")] public int? TrackId { get; set; }
|
||||
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
[Column("userId")] [Required] public int UserId { get; set; }
|
||||
|
||||
public Comment()
|
||||
{
|
||||
this.Reactions = new HashSet<CommentReaction>();
|
||||
this.Status = Statuses.Ok;
|
||||
Reactions = new HashSet<CommentReaction>();
|
||||
Status = Statuses.Ok;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
using Roadie.Library.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
|
@ -13,36 +10,15 @@ namespace Roadie.Library.Data
|
|||
{
|
||||
get
|
||||
{
|
||||
if(this.ArtistId.HasValue)
|
||||
{
|
||||
return CommentType.Artist;
|
||||
}
|
||||
if(this.CollectionId.HasValue)
|
||||
{
|
||||
return CommentType.Collection;
|
||||
}
|
||||
if(this.GenreId.HasValue)
|
||||
{
|
||||
return CommentType.Genre;
|
||||
}
|
||||
if(this.LabelId.HasValue)
|
||||
{
|
||||
return CommentType.Label;
|
||||
}
|
||||
if(this.PlaylistId.HasValue)
|
||||
{
|
||||
return CommentType.Playlist;
|
||||
}
|
||||
if(this.ReleaseId.HasValue)
|
||||
{
|
||||
return CommentType.Release;
|
||||
}
|
||||
if(this.TrackId.HasValue)
|
||||
{
|
||||
return CommentType.Track;
|
||||
}
|
||||
if (ArtistId.HasValue) return CommentType.Artist;
|
||||
if (CollectionId.HasValue) return CommentType.Collection;
|
||||
if (GenreId.HasValue) return CommentType.Genre;
|
||||
if (LabelId.HasValue) return CommentType.Label;
|
||||
if (PlaylistId.HasValue) return CommentType.Playlist;
|
||||
if (ReleaseId.HasValue) return CommentType.Release;
|
||||
if (TrackId.HasValue) return CommentType.Track;
|
||||
return CommentType.Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using Roadie.Library.Enums;
|
||||
using Roadie.Library.Identity;
|
||||
using Roadie.Library.Identity;
|
||||
using Roadie.Library.Utility;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
@ -7,33 +6,18 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("commentReaction")]
|
||||
public partial class CommentReaction : EntityBase
|
||||
public class CommentReaction : EntityBase
|
||||
{
|
||||
public Comment Comment { get; set; }
|
||||
|
||||
[Column("commentId")] [Required] public int CommentId { get; set; }
|
||||
[NotMapped] public new bool? IsLocked { get; set; }
|
||||
[Column("reaction")] public string Reaction { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public Enums.CommentReaction ReactionValue => SafeParser.ToEnum<Enums.CommentReaction>(Reaction ?? "Unknown");
|
||||
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
[Column("commentId")]
|
||||
[Required]
|
||||
public int CommentId { get; set; }
|
||||
|
||||
[Column("userId")]
|
||||
[Required]
|
||||
public int UserId { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public new bool? IsLocked { get; set; }
|
||||
|
||||
[Column("reaction")]
|
||||
public string Reaction { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public Enums.CommentReaction ReactionValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return SafeParser.ToEnum<Enums.CommentReaction>(this.Reaction ?? "Unknown");
|
||||
}
|
||||
}
|
||||
[Column("userId")] [Required] public int UserId { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using Mapster;
|
||||
using Roadie.Library.Enums;
|
||||
using Roadie.Library.Enums;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
@ -8,9 +7,7 @@ namespace Roadie.Library.Data
|
|||
{
|
||||
public abstract class EntityBase
|
||||
{
|
||||
[Column("createdDate")]
|
||||
[Required]
|
||||
public DateTime CreatedDate { get; set; }
|
||||
[Column("createdDate")] [Required] public DateTime CreatedDate { get; set; }
|
||||
|
||||
[Column("id")]
|
||||
[Key]
|
||||
|
@ -19,23 +16,18 @@ namespace Roadie.Library.Data
|
|||
|
||||
public bool? IsLocked { get; set; }
|
||||
|
||||
[Column("lastUpdated")]
|
||||
public DateTime? LastUpdated { get; set; }
|
||||
[Column("lastUpdated")] public DateTime? LastUpdated { get; set; }
|
||||
|
||||
[Column("RoadieId")]
|
||||
[Required]
|
||||
public Guid RoadieId { get; set; }
|
||||
[Column("RoadieId")] [Required] public Guid RoadieId { get; set; }
|
||||
|
||||
|
||||
[Column("status")]
|
||||
public Statuses? Status { get; set; }
|
||||
[Column("status")] public Statuses? Status { get; set; }
|
||||
|
||||
public EntityBase()
|
||||
{
|
||||
this.RoadieId = Guid.NewGuid();
|
||||
this.Status = Statuses.Incomplete;
|
||||
this.CreatedDate = DateTime.UtcNow;
|
||||
this.IsLocked = false;
|
||||
RoadieId = Guid.NewGuid();
|
||||
Status = Statuses.Incomplete;
|
||||
CreatedDate = DateTime.UtcNow;
|
||||
IsLocked = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,20 +7,19 @@ 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; }
|
||||
public ICollection<ArtistGenre> Artists { get; set; }
|
||||
|
||||
public ICollection<Comment> Comments { get; set; }
|
||||
|
||||
[Column("name")] [MaxLength(100)] public string Name { get; set; }
|
||||
|
||||
public ICollection<ReleaseGenre> Releases { get; set; }
|
||||
|
||||
public Genre()
|
||||
{
|
||||
this.Releases = new HashSet<ReleaseGenre>();
|
||||
this.Artists = new HashSet<ArtistGenre>();
|
||||
this.Comments = new HashSet<Comment>();
|
||||
Releases = new HashSet<ReleaseGenre>();
|
||||
Artists = new HashSet<ArtistGenre>();
|
||||
Comments = new HashSet<Comment>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public partial class Genre
|
||||
{
|
||||
public string CacheKey => CacheUrn(RoadieId);
|
||||
|
||||
public string CacheRegion => CacheRegionUrn(RoadieId);
|
||||
|
||||
public static string CacheRegionUrn(Guid Id)
|
||||
{
|
||||
return string.Format("urn:genre:{0}", Id);
|
||||
|
@ -13,23 +15,7 @@ namespace Roadie.Library.Data
|
|||
|
||||
public static string CacheUrn(Guid Id)
|
||||
{
|
||||
return $"urn:genre_by_id:{ Id }";
|
||||
}
|
||||
|
||||
public string CacheKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return Genre.CacheUrn(this.RoadieId);
|
||||
}
|
||||
}
|
||||
|
||||
public string CacheRegion
|
||||
{
|
||||
get
|
||||
{
|
||||
return Genre.CacheRegionUrn(this.RoadieId);
|
||||
}
|
||||
return $"urn:genre_by_id:{Id}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,20 +10,21 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public interface IRoadieDbContext : IDisposable, IInfrastructure<IServiceProvider>, IDbContextDependencies, IDbSetCache, IDbQueryCache, IDbContextPoolable
|
||||
public interface IRoadieDbContext : IDisposable, IInfrastructure<IServiceProvider>, IDbContextDependencies,
|
||||
IDbSetCache, IDbQueryCache, IDbContextPoolable
|
||||
{
|
||||
DbSet<ArtistAssociation> ArtistAssociations { get; set; }
|
||||
DbSet<ArtistSimilar> ArtistSimilar { get; set; }
|
||||
DbSet<ArtistGenre> ArtistGenres { get; set; }
|
||||
DbSet<Artist> Artists { get; set; }
|
||||
DbSet<ArtistSimilar> ArtistSimilar { get; set; }
|
||||
DbSet<Bookmark> Bookmarks { get; set; }
|
||||
ChangeTracker ChangeTracker { get; }
|
||||
DbSet<ChatMessage> ChatMessages { get; set; }
|
||||
DbSet<CollectionMissing> CollectionMissings { get; set; }
|
||||
DbSet<CollectionRelease> CollectionReleases { get; set; }
|
||||
DbSet<Collection> Collections { get; set; }
|
||||
DbSet<Comment> Comments { get; set; }
|
||||
DbSet<CommentReaction> CommentReactions { get; set; }
|
||||
DbSet<Comment> Comments { get; set; }
|
||||
DatabaseFacade Database { get; }
|
||||
DbSet<Genre> Genres { get; set; }
|
||||
DbSet<Image> Images { get; set; }
|
||||
|
@ -51,13 +52,15 @@ namespace Roadie.Library.Data
|
|||
|
||||
Task<EntityEntry> AddAsync(object entity, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
Task<EntityEntry<TEntity>> AddAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = default(CancellationToken)) where TEntity : class;
|
||||
Task<EntityEntry<TEntity>> AddAsync<TEntity>(TEntity entity,
|
||||
CancellationToken cancellationToken = default(CancellationToken)) where TEntity : class;
|
||||
|
||||
void AddRange(IEnumerable<object> entities);
|
||||
|
||||
void AddRange(params object[] entities);
|
||||
|
||||
Task AddRangeAsync(IEnumerable<object> entities, CancellationToken cancellationToken = default(CancellationToken));
|
||||
Task AddRangeAsync(IEnumerable<object> entities,
|
||||
CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
Task AddRangeAsync(params object[] entities);
|
||||
|
||||
|
@ -103,7 +106,8 @@ namespace Roadie.Library.Data
|
|||
|
||||
int SaveChanges();
|
||||
|
||||
Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken));
|
||||
Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess,
|
||||
CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
|
@ -118,7 +122,5 @@ namespace Roadie.Library.Data
|
|||
void UpdateRange(params object[] entities);
|
||||
|
||||
void UpdateRange(IEnumerable<object> entities);
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -6,28 +6,19 @@ namespace Roadie.Library.Data
|
|||
[Table("image")]
|
||||
public partial class Image : EntityBase
|
||||
{
|
||||
[Column("artistId")]
|
||||
public int? ArtistId { get; set; }
|
||||
public Artist Artist { get; set; }
|
||||
[Column("artistId")] public int? ArtistId { get; set; }
|
||||
|
||||
[Column("image", TypeName = "mediumblob")]
|
||||
public byte[] Bytes { get; set; }
|
||||
|
||||
[Column("caption")]
|
||||
[MaxLength(100)]
|
||||
public string Caption { get; set; }
|
||||
[Column("caption")] [MaxLength(100)] public string Caption { get; set; }
|
||||
|
||||
[Column("releaseId")]
|
||||
public int? ReleaseId { get; set; }
|
||||
|
||||
[Column("signature")]
|
||||
[MaxLength(50)]
|
||||
public string Signature { get; set; }
|
||||
|
||||
[Column("url")]
|
||||
[MaxLength(500)]
|
||||
public string Url { get; set; }
|
||||
|
||||
public Artist Artist { get; set; }
|
||||
public Release Release { get; set; }
|
||||
[Column("releaseId")] public int? ReleaseId { get; set; }
|
||||
|
||||
[Column("signature")] [MaxLength(50)] public string Signature { get; set; }
|
||||
|
||||
[Column("url")] [MaxLength(500)] public string Url { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
using Microsoft.Net.Http.Headers;
|
||||
using Roadie.Library.Imaging;
|
||||
using Roadie.Library.Utility;
|
||||
using Roadie.Library.Imaging;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
|
@ -8,6 +6,10 @@ namespace Roadie.Library.Data
|
|||
{
|
||||
public partial class Image
|
||||
{
|
||||
public string CacheKey => Artist.CacheUrn(RoadieId);
|
||||
|
||||
public string CacheRegion => CacheRegionUrn(RoadieId);
|
||||
|
||||
public static string CacheRegionUrn(Guid Id)
|
||||
{
|
||||
return string.Format("urn:image:{0}", Id);
|
||||
|
@ -15,34 +17,13 @@ namespace Roadie.Library.Data
|
|||
|
||||
public static string CacheUrn(Guid Id)
|
||||
{
|
||||
return $"urn:image_by_id:{ Id }";
|
||||
}
|
||||
|
||||
public string CacheKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return Artist.CacheUrn(this.RoadieId);
|
||||
}
|
||||
}
|
||||
|
||||
public string CacheRegion
|
||||
{
|
||||
get
|
||||
{
|
||||
return Image.CacheRegionUrn(this.RoadieId);
|
||||
}
|
||||
return $"urn:image_by_id:{Id}";
|
||||
}
|
||||
|
||||
public string GenerateSignature()
|
||||
{
|
||||
if (this.Bytes == null || !this.Bytes.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return ImageHasher.AverageHash(this.Bytes).ToString();
|
||||
if (Bytes == null || !Bytes.Any()) return null;
|
||||
return ImageHasher.AverageHash(Bytes).ToString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -8,13 +8,13 @@ namespace Roadie.Library.Data
|
|||
[Table("label")]
|
||||
public partial class Label : BeginAndEndNamedEntityBase
|
||||
{
|
||||
[Column("discogsId")]
|
||||
[MaxLength(50)]
|
||||
public string DiscogsId { get; set; }
|
||||
[Column("artistCount")] public int? ArtistCount { get; set; }
|
||||
|
||||
[Column("imageUrl")]
|
||||
[MaxLength(500)]
|
||||
public string ImageUrl { get; set; }
|
||||
public ICollection<Comment> Comments { get; set; }
|
||||
|
||||
[Column("discogsId")] [MaxLength(50)] public string DiscogsId { get; set; }
|
||||
|
||||
[Column("imageUrl")] [MaxLength(500)] public string ImageUrl { get; set; }
|
||||
|
||||
[Column("musicBrainzId")]
|
||||
[MaxLength(100)]
|
||||
|
@ -24,24 +24,17 @@ namespace Roadie.Library.Data
|
|||
[MaxLength(65535)]
|
||||
public string Profile { get; set; }
|
||||
|
||||
[Column("artistCount")]
|
||||
public int? ArtistCount { get; set; }
|
||||
|
||||
[Column("releaseCount")]
|
||||
public int? ReleaseCount { get; set; }
|
||||
|
||||
[Column("trackCount")]
|
||||
public int? TrackCount { get; set; }
|
||||
[Column("releaseCount")] public int? ReleaseCount { get; set; }
|
||||
|
||||
public ICollection<ReleaseLabel> ReleaseLabels { get; set; }
|
||||
|
||||
public ICollection<Comment> Comments { get; set; }
|
||||
[Column("trackCount")] public int? TrackCount { get; set; }
|
||||
|
||||
public Label()
|
||||
{
|
||||
this.ReleaseLabels = new HashSet<ReleaseLabel>();
|
||||
this.Comments = new HashSet<Comment>();
|
||||
this.Status = Statuses.Ok;
|
||||
ReleaseLabels = new HashSet<ReleaseLabel>();
|
||||
Comments = new HashSet<Comment>();
|
||||
Status = Statuses.Ok;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,31 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public partial class Label
|
||||
{
|
||||
public string CacheKey => CacheUrn(RoadieId);
|
||||
|
||||
public string CacheRegion => CacheRegionUrn(RoadieId);
|
||||
|
||||
public string Etag
|
||||
{
|
||||
get
|
||||
{
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
return string.Concat(md5
|
||||
.ComputeHash(
|
||||
System.Text.Encoding.Default.GetBytes(string.Format("{0}{1}", RoadieId, LastUpdated)))
|
||||
.Select(x => x.ToString("D2")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValid => !string.IsNullOrEmpty(Name);
|
||||
|
||||
public static string CacheRegionUrn(Guid Id)
|
||||
{
|
||||
return string.Format("urn:label:{0}", Id);
|
||||
|
@ -12,42 +33,7 @@ namespace Roadie.Library.Data
|
|||
|
||||
public static string CacheUrn(Guid Id)
|
||||
{
|
||||
return $"urn:label_by_id:{ Id }";
|
||||
}
|
||||
|
||||
public string CacheKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return Label.CacheUrn(this.RoadieId);
|
||||
}
|
||||
}
|
||||
|
||||
public string CacheRegion
|
||||
{
|
||||
get
|
||||
{
|
||||
return Label.CacheRegionUrn(this.RoadieId);
|
||||
}
|
||||
}
|
||||
|
||||
public string Etag
|
||||
{
|
||||
get
|
||||
{
|
||||
using (var md5 = System.Security.Cryptography.MD5.Create())
|
||||
{
|
||||
return String.Concat(md5.ComputeHash(System.Text.Encoding.Default.GetBytes(string.Format("{0}{1}", this.RoadieId, this.LastUpdated))).Select(x => x.ToString("D2")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValid
|
||||
{
|
||||
get
|
||||
{
|
||||
return !string.IsNullOrEmpty(this.Name);
|
||||
}
|
||||
return $"urn:label_by_id:{Id}";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,13 +9,9 @@ namespace Roadie.Library.Data
|
|||
[MaxLength(65535)]
|
||||
public string AlternateNames { get; set; }
|
||||
|
||||
[MaxLength(250)]
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
[MaxLength(250)] [Column("name")] public string Name { get; set; }
|
||||
|
||||
[Column("sortName")]
|
||||
[MaxLength(250)]
|
||||
public string SortName { get; set; }
|
||||
[Column("sortName")] [MaxLength(250)] public string SortName { get; set; }
|
||||
|
||||
[Column("tags", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
|
|
|
@ -8,37 +8,31 @@ namespace Roadie.Library.Data
|
|||
[Table("playlist")]
|
||||
public partial class Playlist : NamedEntityBase
|
||||
{
|
||||
[NotMapped]
|
||||
public new string SortName { get; set; }
|
||||
public ICollection<Comment> Comments { get; set; }
|
||||
|
||||
[Column("Description")]
|
||||
[MaxLength(1000)]
|
||||
public string Description { get; set; }
|
||||
|
||||
[Column("isPublic")]
|
||||
public bool IsPublic { get; set; }
|
||||
[Column("duration")] public int? Duration { get; set; }
|
||||
|
||||
[Column("isPublic")] public bool IsPublic { get; set; }
|
||||
|
||||
[Column("releaseCount")] public short ReleaseCount { get; set; }
|
||||
|
||||
[NotMapped] public new string SortName { get; set; }
|
||||
|
||||
[Column("trackCount")] public short TrackCount { get; set; }
|
||||
|
||||
public ICollection<PlaylistTrack> Tracks { get; set; }
|
||||
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
[Column("userId")]
|
||||
public int? UserId { get; set; }
|
||||
|
||||
[Column("duration")]
|
||||
public int? Duration { get; set; }
|
||||
|
||||
[Column("trackCount")]
|
||||
public short TrackCount { get; set; }
|
||||
|
||||
[Column("releaseCount")]
|
||||
public short ReleaseCount { get; set; }
|
||||
|
||||
public ICollection<Comment> Comments { get; set; }
|
||||
[Column("userId")] public int? UserId { get; set; }
|
||||
|
||||
public Playlist()
|
||||
{
|
||||
this.Comments = new HashSet<Comment>();
|
||||
Comments = new HashSet<Comment>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public partial class Playlist
|
||||
{
|
||||
public string CacheKey => CacheUrn(RoadieId);
|
||||
|
||||
public string CacheRegion => CacheRegionUrn(RoadieId);
|
||||
|
||||
public static string CacheRegionUrn(Guid Id)
|
||||
{
|
||||
return string.Format("urn:playlist:{0}", Id);
|
||||
|
@ -13,28 +15,12 @@ namespace Roadie.Library.Data
|
|||
|
||||
public static string CacheUrn(Guid Id)
|
||||
{
|
||||
return $"urn:playlist_by_id:{ Id }";
|
||||
}
|
||||
|
||||
public string CacheKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return Playlist.CacheUrn(this.RoadieId);
|
||||
}
|
||||
}
|
||||
|
||||
public string CacheRegion
|
||||
{
|
||||
get
|
||||
{
|
||||
return Playlist.CacheRegionUrn(this.RoadieId);
|
||||
}
|
||||
return $"urn:playlist_by_id:{Id}";
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Id [{this.Id}], Name [{this.Name}], RoadieId [{ this.RoadieId}]";
|
||||
return $"Id [{Id}], Name [{Name}], RoadieId [{RoadieId}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,20 +4,16 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("playlisttrack")]
|
||||
public partial class PlaylistTrack : EntityBase
|
||||
public class PlaylistTrack : EntityBase
|
||||
{
|
||||
[Column("listNumber")]
|
||||
[Required]
|
||||
public int ListNumber { get; set; }
|
||||
[Column("listNumber")] [Required] public int ListNumber { get; set; }
|
||||
|
||||
public Playlist Playlist { get; set; }
|
||||
|
||||
[Column("playListId")]
|
||||
public int PlayListId { get; set; }
|
||||
[Column("playListId")] public int PlayListId { get; set; }
|
||||
|
||||
public Track Track { get; set; }
|
||||
|
||||
[Column("trackId")]
|
||||
public int TrackId { get; set; }
|
||||
[Column("trackId")] public int TrackId { get; set; }
|
||||
}
|
||||
}
|
|
@ -13,54 +13,41 @@ namespace Roadie.Library.Data
|
|||
[MaxLength(65535)]
|
||||
public string AlternateNames { get; set; }
|
||||
|
||||
[Column("amgId")]
|
||||
[MaxLength(50)]
|
||||
public string AmgId { get; set; }
|
||||
[Column("amgId")] [MaxLength(50)] public string AmgId { get; set; }
|
||||
|
||||
public Artist Artist { get; set; }
|
||||
|
||||
[Column("artistId")]
|
||||
[Required]
|
||||
public int ArtistId { get; set; }
|
||||
[Column("artistId")] [Required] public int ArtistId { get; set; }
|
||||
|
||||
public ICollection<CollectionRelease> Collections { get; set; }
|
||||
|
||||
[Column("duration")]
|
||||
public int? Duration { get; set; }
|
||||
public ICollection<Comment> Comments { get; set; }
|
||||
|
||||
[Column("discogsId")]
|
||||
[MaxLength(50)]
|
||||
public string DiscogsId { get; set; }
|
||||
[Column("discogsId")] [MaxLength(50)] public string DiscogsId { get; set; }
|
||||
|
||||
[Column("duration")] public int? Duration { get; set; }
|
||||
|
||||
public ICollection<ReleaseGenre> Genres { get; set; }
|
||||
|
||||
public ICollection<Image> Images { get; set; }
|
||||
|
||||
[Column("isVirtual")]
|
||||
public bool? IsVirtual { get; set; }
|
||||
[Column("isVirtual")] public bool? IsVirtual { get; set; }
|
||||
|
||||
[Column("itunesId")]
|
||||
[MaxLength(100)]
|
||||
public string ITunesId { get; set; }
|
||||
[Column("itunesId")] [MaxLength(100)] public string ITunesId { get; set; }
|
||||
|
||||
public ICollection<ReleaseLabel> Labels { get; set; }
|
||||
|
||||
[Column("lastFMId")]
|
||||
[MaxLength(50)]
|
||||
public string LastFMId { get; set; }
|
||||
[Column("lastFMId")] [MaxLength(50)] public string LastFMId { get; set; }
|
||||
|
||||
[Column("lastFMSummary", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string LastFMSummary { get; set; }
|
||||
|
||||
[Column("lastPlayed")]
|
||||
public DateTime? LastPlayed { get; set; }
|
||||
[Column("lastPlayed")] public DateTime? LastPlayed { get; set; }
|
||||
|
||||
[Column("libraryStatus")]
|
||||
public LibraryStatus? LibraryStatus { get; set; }
|
||||
[Column("libraryStatus")] public LibraryStatus? LibraryStatus { get; set; }
|
||||
|
||||
[Column("mediaCount")]
|
||||
public short? MediaCount { get; set; }
|
||||
[Column("mediaCount")] public short? MediaCount { get; set; }
|
||||
|
||||
public ICollection<ReleaseMedia> Medias { get; set; }
|
||||
|
||||
|
@ -68,28 +55,23 @@ namespace Roadie.Library.Data
|
|||
[MaxLength(100)]
|
||||
public string MusicBrainzId { get; set; }
|
||||
|
||||
[Column("playedCount")]
|
||||
public int? PlayedCount { get; set; }
|
||||
[Column("playedCount")] public int? PlayedCount { get; set; }
|
||||
|
||||
[Column("profile", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string Profile { get; set; }
|
||||
|
||||
[Column("rating")]
|
||||
public short? Rating { get; set; }
|
||||
[Column("rank")] public decimal? Rank { get; set; }
|
||||
|
||||
[Column("releaseDate")]
|
||||
public DateTime? ReleaseDate { get; set; }
|
||||
[Column("rating")] public short? Rating { get; set; }
|
||||
|
||||
[Column("releaseType")]
|
||||
public ReleaseType? ReleaseType { get; set; }
|
||||
[Column("releaseDate")] public DateTime? ReleaseDate { get; set; }
|
||||
|
||||
[Column("spotifyId")]
|
||||
[MaxLength(100)]
|
||||
public string SpotifyId { get; set; }
|
||||
[Column("releaseType")] public ReleaseType? ReleaseType { get; set; }
|
||||
|
||||
[Column("submissionId")]
|
||||
public int? SubmissionId { get; set; }
|
||||
[Column("spotifyId")] [MaxLength(100)] public string SpotifyId { get; set; }
|
||||
|
||||
[Column("submissionId")] public int? SubmissionId { get; set; }
|
||||
|
||||
[Column("tags", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
|
@ -104,28 +86,22 @@ namespace Roadie.Library.Data
|
|||
[Required]
|
||||
public string Title { get; set; }
|
||||
|
||||
[Column("trackCount")]
|
||||
public short TrackCount { get; set; }
|
||||
[Column("trackCount")] public short TrackCount { get; set; }
|
||||
|
||||
[Column("urls", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
public string URLs { get; set; }
|
||||
|
||||
[Column("rank")]
|
||||
public decimal? Rank { get; set; }
|
||||
|
||||
public ICollection<Comment> Comments { get; set; }
|
||||
|
||||
public Release()
|
||||
{
|
||||
this.Rating = 0;
|
||||
this.ReleaseType = Enums.ReleaseType.Release;
|
||||
this.Images = new HashSet<Image>();
|
||||
this.Medias = new HashSet<ReleaseMedia>();
|
||||
this.Labels = new HashSet<ReleaseLabel>();
|
||||
this.Collections = new HashSet<CollectionRelease>();
|
||||
this.Genres = new HashSet<ReleaseGenre>();
|
||||
this.Comments = new HashSet<Comment>();
|
||||
Rating = 0;
|
||||
ReleaseType = Enums.ReleaseType.Release;
|
||||
Images = new HashSet<Image>();
|
||||
Medias = new HashSet<ReleaseMedia>();
|
||||
Labels = new HashSet<ReleaseLabel>();
|
||||
Collections = new HashSet<CollectionRelease>();
|
||||
Genres = new HashSet<ReleaseGenre>();
|
||||
Comments = new HashSet<Comment>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,13 +4,11 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("releaseGenreTable")]
|
||||
public partial class ReleaseGenre
|
||||
public class ReleaseGenre
|
||||
{
|
||||
public Genre Genre { get; set; }
|
||||
|
||||
[Column("genreId")]
|
||||
[Required]
|
||||
public int? GenreId { get; set; }
|
||||
[Column("genreId")] [Required] public int? GenreId { get; set; }
|
||||
|
||||
[Column("id")]
|
||||
[Key]
|
||||
|
@ -19,8 +17,6 @@ namespace Roadie.Library.Data
|
|||
|
||||
public Release Release { get; set; }
|
||||
|
||||
[Column("releaseId")]
|
||||
[Required]
|
||||
public int ReleaseId { get; set; }
|
||||
[Column("releaseId")] [Required] public int ReleaseId { get; set; }
|
||||
}
|
||||
}
|
|
@ -5,17 +5,14 @@ namespace Roadie.Library.Data
|
|||
[Table("releaselabel")]
|
||||
public class ReleaseLabel : BeginAndEndEntityBase
|
||||
{
|
||||
[Column("catalogNumber")]
|
||||
public string CatalogNumber { get; set; }
|
||||
[Column("catalogNumber")] public string CatalogNumber { get; set; }
|
||||
|
||||
public Label Label { get; set; }
|
||||
|
||||
[Column("labelId")]
|
||||
public int LabelId { get; set; }
|
||||
[Column("labelId")] public int LabelId { get; set; }
|
||||
|
||||
public Release Release { get; set; }
|
||||
|
||||
[Column("releaseId")]
|
||||
public int ReleaseId { get; set; }
|
||||
[Column("releaseId")] public int ReleaseId { get; set; }
|
||||
}
|
||||
}
|
|
@ -7,27 +7,23 @@ namespace Roadie.Library.Data
|
|||
[Table("releasemedia")]
|
||||
public class ReleaseMedia : EntityBase
|
||||
{
|
||||
[Column("releaseMediaNumber")]
|
||||
public short MediaNumber { get; set; }
|
||||
[Column("releaseMediaNumber")] public short MediaNumber { get; set; }
|
||||
|
||||
public Release Release { get; set; }
|
||||
|
||||
[Column("releaseId")]
|
||||
public int ReleaseId { get; set; }
|
||||
[Column("releaseId")] public int ReleaseId { get; set; }
|
||||
|
||||
[Column("releaseSubTitle")]
|
||||
[MaxLength(500)]
|
||||
public string SubTitle { get; set; }
|
||||
|
||||
[Column("trackCount")]
|
||||
[Required]
|
||||
public short TrackCount { get; set; }
|
||||
[Column("trackCount")] [Required] public short TrackCount { get; set; }
|
||||
|
||||
public ICollection<Track> Tracks { get; set; }
|
||||
|
||||
public ReleaseMedia()
|
||||
{
|
||||
this.Tracks = new HashSet<Track>();
|
||||
Tracks = new HashSet<Track>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,44 +3,26 @@ using Roadie.Library.Utility;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public partial class Release
|
||||
{
|
||||
public static string CacheRegionUrn(Guid Id)
|
||||
{
|
||||
return string.Format("urn:release:{0}", Id);
|
||||
}
|
||||
public string CacheKey => Artist.CacheUrn(RoadieId);
|
||||
|
||||
public static string CacheUrn(Guid Id)
|
||||
{
|
||||
return $"urn:release_by_id:{ Id }";
|
||||
}
|
||||
|
||||
public string CacheKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return Artist.CacheUrn(this.RoadieId);
|
||||
}
|
||||
}
|
||||
|
||||
public string CacheRegion
|
||||
{
|
||||
get
|
||||
{
|
||||
return Release.CacheRegionUrn(this.RoadieId);
|
||||
}
|
||||
}
|
||||
public string CacheRegion => CacheRegionUrn(RoadieId);
|
||||
|
||||
public string Etag
|
||||
{
|
||||
get
|
||||
{
|
||||
using (var md5 = System.Security.Cryptography.MD5.Create())
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
return String.Concat(md5.ComputeHash(System.Text.Encoding.Default.GetBytes(string.Format("{0}{1}", this.RoadieId, this.LastUpdated))).Select(x => x.ToString("D2")));
|
||||
return string.Concat(md5
|
||||
.ComputeHash(
|
||||
System.Text.Encoding.Default.GetBytes(string.Format("{0}{1}", RoadieId, LastUpdated)))
|
||||
.Select(x => x.ToString("D2")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,11 +31,8 @@ namespace Roadie.Library.Data
|
|||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.Title))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.IsReleaseTypeOf("Original Broadway Cast") || this.IsReleaseTypeOf("Original Cast");
|
||||
if (string.IsNullOrEmpty(Title)) return false;
|
||||
return IsReleaseTypeOf("Original Broadway Cast") || IsReleaseTypeOf("Original Cast");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,107 +40,80 @@ namespace Roadie.Library.Data
|
|||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.Title))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (string.IsNullOrEmpty(Title)) return false;
|
||||
foreach (var soundTrackTrigger in new List<string> { "soundtrack", " ost", "(ost)" })
|
||||
{
|
||||
if (this.IsReleaseTypeOf(soundTrackTrigger))
|
||||
{
|
||||
if (IsReleaseTypeOf(soundTrackTrigger))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValid
|
||||
{
|
||||
get
|
||||
{
|
||||
return !string.IsNullOrEmpty(this.Title) && this.ReleaseDate > DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReleaseTypeOf(string type, bool doCheckTitles = false)
|
||||
{
|
||||
if (string.IsNullOrEmpty(type))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (doCheckTitles)
|
||||
{
|
||||
if (this.Artist != null && !string.IsNullOrEmpty(this.Artist.Name))
|
||||
{
|
||||
if (this.Artist.Name.IndexOf(type, 0, StringComparison.OrdinalIgnoreCase) > -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(this.Title))
|
||||
{
|
||||
if (this.Title.IndexOf(type, 0, StringComparison.OrdinalIgnoreCase) > -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (this.AlternateNames != null)
|
||||
{
|
||||
if (this.AlternateNames.IsValueInDelimitedList(type))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.Tags != null)
|
||||
{
|
||||
if (this.Tags.IsValueInDelimitedList(type))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (this.Genres != null)
|
||||
{
|
||||
if (this.Genres.Any(x => x.Genre.Name.ToLower().Equals(type)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public bool IsValid => !string.IsNullOrEmpty(Title) && ReleaseDate > DateTime.MinValue;
|
||||
|
||||
public int? ReleaseYear
|
||||
{
|
||||
get
|
||||
{
|
||||
if(this.ReleaseDate.HasValue)
|
||||
{
|
||||
return this.ReleaseDate.Value.Year;
|
||||
}
|
||||
if (ReleaseDate.HasValue) return ReleaseDate.Value.Year;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static string CacheRegionUrn(Guid Id)
|
||||
{
|
||||
return string.Format("urn:release:{0}", Id);
|
||||
}
|
||||
|
||||
public static string CacheUrn(Guid Id)
|
||||
{
|
||||
return $"urn:release_by_id:{Id}";
|
||||
}
|
||||
|
||||
public bool IsReleaseTypeOf(string type, bool doCheckTitles = false)
|
||||
{
|
||||
if (string.IsNullOrEmpty(type)) return false;
|
||||
try
|
||||
{
|
||||
if (doCheckTitles)
|
||||
{
|
||||
if (Artist != null && !string.IsNullOrEmpty(Artist.Name))
|
||||
if (Artist.Name.IndexOf(type, 0, StringComparison.OrdinalIgnoreCase) > -1)
|
||||
return true;
|
||||
if (!string.IsNullOrEmpty(Title))
|
||||
if (Title.IndexOf(type, 0, StringComparison.OrdinalIgnoreCase) > -1)
|
||||
return true;
|
||||
if (AlternateNames != null)
|
||||
if (AlternateNames.IsValueInDelimitedList(type))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Tags != null)
|
||||
if (Tags.IsValueInDelimitedList(type))
|
||||
return true;
|
||||
if (Genres != null)
|
||||
if (Genres.Any(x => x.Genre.Name.ToLower().Equals(type)))
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return this releases file folder for the given artist folder
|
||||
/// Return this releases file folder for the given artist folder
|
||||
/// </summary>
|
||||
/// <param name="artistFolder"></param>
|
||||
/// <returns></returns>
|
||||
public string ReleaseFileFolder(string artistFolder)
|
||||
{
|
||||
return FolderPathHelper.ReleasePath(artistFolder, this.Title, this.ReleaseDate.Value);
|
||||
return FolderPathHelper.ReleasePath(artistFolder, Title, ReleaseDate.Value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Id [{ this.Id }], Title [{ this.Title }], Release Date [{this.ReleaseYear}]";
|
||||
return $"Id [{Id}], Title [{Title}], Release Date [{ReleaseYear}]";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,20 +5,16 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("request")]
|
||||
public partial class Request : EntityBase
|
||||
public class Request : EntityBase
|
||||
{
|
||||
[Column("description")]
|
||||
[MaxLength(500)]
|
||||
[Required]
|
||||
public string Description { get; set; }
|
||||
|
||||
[NotMapped] public new bool? IsLocked { get; set; }
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
[Column("userId")]
|
||||
public int? UserId { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public new bool? IsLocked { get; set; }
|
||||
|
||||
[Column("userId")] public int? UserId { get; set; }
|
||||
}
|
||||
}
|
|
@ -8,40 +8,68 @@ namespace Roadie.Library.Data
|
|||
public class RoadieDbContext : DbContext, IRoadieDbContext
|
||||
{
|
||||
public DbSet<ArtistAssociation> ArtistAssociations { get; set; }
|
||||
public DbSet<ArtistSimilar> ArtistSimilar { get; set; }
|
||||
|
||||
public DbSet<ArtistGenre> ArtistGenres { get; set; }
|
||||
|
||||
public DbSet<Artist> Artists { get; set; }
|
||||
|
||||
public DbSet<ArtistSimilar> ArtistSimilar { get; set; }
|
||||
|
||||
public DbSet<Bookmark> Bookmarks { get; set; }
|
||||
|
||||
public DbSet<ChatMessage> ChatMessages { get; set; }
|
||||
public DbSet<Comment> Comments { get; set; }
|
||||
|
||||
public DbSet<CollectionMissing> CollectionMissings { get; set; }
|
||||
public DbSet<CommentReaction> CommentReactions { get; set; }
|
||||
|
||||
public DbSet<CollectionRelease> CollectionReleases { get; set; }
|
||||
|
||||
public DbSet<Collection> Collections { get; set; }
|
||||
|
||||
public DbSet<CommentReaction> CommentReactions { get; set; }
|
||||
|
||||
public DbSet<Comment> Comments { get; set; }
|
||||
|
||||
public DbSet<Genre> Genres { get; set; }
|
||||
|
||||
public DbSet<Image> Images { get; set; }
|
||||
|
||||
public DbSet<Label> Labels { get; set; }
|
||||
|
||||
public DbSet<Playlist> Playlists { get; set; }
|
||||
|
||||
public DbSet<PlaylistTrack> PlaylistTracks { get; set; }
|
||||
|
||||
public DbSet<ReleaseGenre> ReleaseGenres { get; set; }
|
||||
|
||||
public DbSet<ReleaseLabel> ReleaseLabels { get; set; }
|
||||
|
||||
public DbSet<ReleaseMedia> ReleaseMedias { get; set; }
|
||||
|
||||
public DbSet<Release> Releases { get; set; }
|
||||
|
||||
public DbSet<Request> Requests { get; set; }
|
||||
|
||||
public DbSet<ScanHistory> ScanHistories { get; set; }
|
||||
|
||||
public DbSet<Submission> Submissions { get; set; }
|
||||
|
||||
public DbSet<Track> Tracks { get; set; }
|
||||
|
||||
public DbSet<UserArtist> UserArtists { get; set; }
|
||||
|
||||
public DbSet<UserQue> UserQues { get; set; }
|
||||
|
||||
public DbSet<UserRelease> UserReleases { get; set; }
|
||||
|
||||
public DbSet<ApplicationRole> UserRoles { get; set; }
|
||||
|
||||
public DbSet<ApplicationUser> Users { get; set; }
|
||||
|
||||
public DbSet<UserTrack> UserTracks { get; set; }
|
||||
|
||||
public RoadieDbContext(DbContextOptions<RoadieDbContext> options)
|
||||
: base(options)
|
||||
: base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
|
@ -56,7 +84,6 @@ namespace Roadie.Library.Data
|
|||
// v => string.IsNullOrEmpty(v) ? Statuses.Ok : (Statuses)Enum.Parse(typeof(Statuses), v))
|
||||
// .HasDefaultValue(Statuses.Ok);
|
||||
|
||||
|
||||
//builder
|
||||
// .Entity<Artist>()
|
||||
// .Property(e => e.Status)
|
||||
|
@ -70,7 +97,9 @@ namespace Roadie.Library.Data
|
|||
.Property(e => e.ReleaseType)
|
||||
.HasConversion(
|
||||
v => v.ToString(),
|
||||
v => string.IsNullOrEmpty(v) ? ReleaseType.Unknown : (ReleaseType)Enum.Parse(typeof(ReleaseType), v))
|
||||
v => string.IsNullOrEmpty(v)
|
||||
? ReleaseType.Unknown
|
||||
: (ReleaseType)Enum.Parse(typeof(ReleaseType), v))
|
||||
.HasDefaultValue(ReleaseType.Release);
|
||||
|
||||
builder
|
||||
|
@ -78,7 +107,9 @@ namespace Roadie.Library.Data
|
|||
.Property(e => e.LibraryStatus)
|
||||
.HasConversion(
|
||||
v => v.ToString(),
|
||||
v => string.IsNullOrEmpty(v) ? LibraryStatus.Incomplete : (LibraryStatus)Enum.Parse(typeof(LibraryStatus), v))
|
||||
v => string.IsNullOrEmpty(v)
|
||||
? LibraryStatus.Incomplete
|
||||
: (LibraryStatus)Enum.Parse(typeof(LibraryStatus), v))
|
||||
.HasDefaultValue(LibraryStatus.Incomplete);
|
||||
|
||||
builder
|
||||
|
@ -86,7 +117,9 @@ namespace Roadie.Library.Data
|
|||
.Property(e => e.CollectionType)
|
||||
.HasConversion(
|
||||
v => v.ToString(),
|
||||
v => string.IsNullOrEmpty(v) ? CollectionType.Unknown : (CollectionType)Enum.Parse(typeof(CollectionType), v))
|
||||
v => string.IsNullOrEmpty(v)
|
||||
? CollectionType.Unknown
|
||||
: (CollectionType)Enum.Parse(typeof(CollectionType), v))
|
||||
.HasDefaultValue(CollectionType.Unknown);
|
||||
|
||||
builder
|
||||
|
|
|
@ -1,35 +1,33 @@
|
|||
using Roadie.Library.Identity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Roadie.Library.Enums;
|
||||
using Roadie.Library.Identity;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("scanHistory")]
|
||||
public class ScanHistory : EntityBase
|
||||
{
|
||||
[Column("userId")]
|
||||
public int UserId { get; set; }
|
||||
[Column("forArtistId")] public int? ForArtistId { get; set; }
|
||||
|
||||
[Column("forReleaseId")] public int? ForReleaseId { get; set; }
|
||||
|
||||
[NotMapped] public new bool? IsLocked { get; set; }
|
||||
|
||||
[Column("newArtists")] public int? NewArtists { get; set; }
|
||||
|
||||
[Column("newReleases")] public int? NewReleases { get; set; }
|
||||
|
||||
[Column("newTracks")] public int? NewTracks { get; set; }
|
||||
|
||||
[Column("timeSpanInSeconds")] public int TimeSpanInSeconds { get; set; }
|
||||
|
||||
public ApplicationUser User { get; set; }
|
||||
[Column("forArtistId")]
|
||||
public int? ForArtistId { get; set; }
|
||||
[Column("forReleaseId")]
|
||||
public int? ForReleaseId { get; set; }
|
||||
[Column("newArtists")]
|
||||
public int? NewArtists { get; set; }
|
||||
[Column("newReleases")]
|
||||
public int? NewReleases { get; set; }
|
||||
[Column("newTracks")]
|
||||
public int? NewTracks { get; set; }
|
||||
[Column("timeSpanInSeconds")]
|
||||
public int TimeSpanInSeconds { get; set; }
|
||||
[NotMapped]
|
||||
public new bool? IsLocked { get; set; }
|
||||
|
||||
[Column("userId")] public int UserId { get; set; }
|
||||
|
||||
public ScanHistory()
|
||||
{
|
||||
this.Status = Enums.Statuses.Complete;
|
||||
Status = Statuses.Complete;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,11 +4,10 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("submission")]
|
||||
public partial class Submission : EntityBase
|
||||
public class Submission : EntityBase
|
||||
{
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
[Column("userId")]
|
||||
public int UserId { get; set; }
|
||||
[Column("userId")] public int UserId { get; set; }
|
||||
}
|
||||
}
|
|
@ -12,41 +12,27 @@ namespace Roadie.Library.Data
|
|||
[MaxLength(65535)]
|
||||
public string AlternateNames { get; set; }
|
||||
|
||||
[Column("amgId")]
|
||||
[MaxLength(50)]
|
||||
public string AmgId { get; set; }
|
||||
[Column("amgId")] [MaxLength(50)] public string AmgId { get; set; }
|
||||
|
||||
[Column("artistId")]
|
||||
public int? ArtistId { get; set; }
|
||||
[Column("artistId")] public int? ArtistId { get; set; }
|
||||
|
||||
[Column("duration")]
|
||||
public int? Duration { get; set; }
|
||||
public ICollection<Comment> Comments { get; set; }
|
||||
|
||||
[Column("fileName")]
|
||||
[MaxLength(500)]
|
||||
public string FileName { get; set; }
|
||||
[Column("duration")] public int? Duration { get; set; }
|
||||
|
||||
[Column("filePath")]
|
||||
[MaxLength(1000)]
|
||||
public string FilePath { get; set; }
|
||||
[Column("fileName")] [MaxLength(500)] public string FileName { get; set; }
|
||||
|
||||
[Column("fileSize")]
|
||||
public int? FileSize { get; set; }
|
||||
[Column("filePath")] [MaxLength(1000)] public string FilePath { get; set; }
|
||||
|
||||
[Column("hash")]
|
||||
[MaxLength(32)]
|
||||
public string Hash { get; set; }
|
||||
[Column("fileSize")] public int? FileSize { get; set; }
|
||||
|
||||
[Column("isrc")]
|
||||
[MaxLength(15)]
|
||||
public string ISRC { get; set; }
|
||||
[Column("hash")] [MaxLength(32)] public string Hash { get; set; }
|
||||
|
||||
[Column("lastFMId")]
|
||||
[MaxLength(50)]
|
||||
public string LastFMId { get; set; }
|
||||
[Column("isrc")] [MaxLength(15)] public string ISRC { get; set; }
|
||||
|
||||
[Column("lastPlayed")]
|
||||
public DateTime? LastPlayed { get; set; }
|
||||
[Column("lastFMId")] [MaxLength(50)] public string LastFMId { get; set; }
|
||||
|
||||
[Column("lastPlayed")] public DateTime? LastPlayed { get; set; }
|
||||
|
||||
[Column("musicBrainzId")]
|
||||
[MaxLength(100)]
|
||||
|
@ -56,20 +42,15 @@ namespace Roadie.Library.Data
|
|||
[MaxLength(65535)]
|
||||
public string PartTitles { get; set; }
|
||||
|
||||
[Column("playedCount")]
|
||||
public int? PlayedCount { get; set; }
|
||||
[Column("playedCount")] public int? PlayedCount { get; set; }
|
||||
|
||||
[Column("rating")]
|
||||
public short Rating { get; set; }
|
||||
[Column("rating")] public short Rating { get; set; }
|
||||
|
||||
public ReleaseMedia ReleaseMedia { get; set; }
|
||||
|
||||
[Column("releaseMediaId")]
|
||||
public int ReleaseMediaId { get; set; }
|
||||
[Column("releaseMediaId")] public int ReleaseMediaId { get; set; }
|
||||
|
||||
[Column("spotifyId")]
|
||||
[MaxLength(100)]
|
||||
public string SpotifyId { get; set; }
|
||||
[Column("spotifyId")] [MaxLength(100)] public string SpotifyId { get; set; }
|
||||
|
||||
[Column("tags", TypeName = "text")]
|
||||
[MaxLength(65535)]
|
||||
|
@ -83,16 +64,12 @@ namespace Roadie.Library.Data
|
|||
[Required]
|
||||
public string Title { get; set; }
|
||||
|
||||
[Column("trackNumber")]
|
||||
[Required]
|
||||
public short TrackNumber { get; set; }
|
||||
|
||||
public ICollection<Comment> Comments { get; set; }
|
||||
[Column("trackNumber")] [Required] public short TrackNumber { get; set; }
|
||||
|
||||
public Track()
|
||||
{
|
||||
this.Comments = new HashSet<Comment>();
|
||||
this.Rating = 0;
|
||||
Comments = new HashSet<Comment>();
|
||||
Rating = 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,11 +5,36 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
public partial class Track
|
||||
{
|
||||
public string CacheKey => CacheUrn(RoadieId);
|
||||
|
||||
public string CacheRegion => CacheRegionUrn(RoadieId);
|
||||
|
||||
public string Etag
|
||||
{
|
||||
get
|
||||
{
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
return string.Concat(md5
|
||||
.ComputeHash(
|
||||
System.Text.Encoding.Default.GetBytes(string.Format("{0}{1}", RoadieId, LastUpdated)))
|
||||
.Select(x => x.ToString("D2")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValid => !string.IsNullOrEmpty(Hash);
|
||||
|
||||
public Artist TrackArtist { get; set; }
|
||||
|
||||
[NotMapped] public IEnumerable<string> TrackArtists { get; set; }
|
||||
|
||||
public static string CacheRegionUrn(Guid Id)
|
||||
{
|
||||
return string.Format("urn:track:{0}", Id);
|
||||
|
@ -17,51 +42,11 @@ namespace Roadie.Library.Data
|
|||
|
||||
public static string CacheUrn(Guid Id)
|
||||
{
|
||||
return $"urn:track_by_id:{ Id }";
|
||||
return $"urn:track_by_id:{Id}";
|
||||
}
|
||||
|
||||
public string CacheKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return Track.CacheUrn(this.RoadieId);
|
||||
}
|
||||
}
|
||||
|
||||
public string CacheRegion
|
||||
{
|
||||
get
|
||||
{
|
||||
return Track.CacheRegionUrn(this.RoadieId);
|
||||
}
|
||||
}
|
||||
|
||||
public string Etag
|
||||
{
|
||||
get
|
||||
{
|
||||
using (var md5 = System.Security.Cryptography.MD5.Create())
|
||||
{
|
||||
return String.Concat(md5.ComputeHash(System.Text.Encoding.Default.GetBytes(string.Format("{0}{1}", this.RoadieId, this.LastUpdated))).Select(x => x.ToString("D2")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValid
|
||||
{
|
||||
get
|
||||
{
|
||||
return !string.IsNullOrEmpty(this.Hash);
|
||||
}
|
||||
}
|
||||
|
||||
public Artist TrackArtist { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public IEnumerable<string> TrackArtists { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a full file path to the current track
|
||||
/// Returns a full file path to the current track
|
||||
/// </summary>
|
||||
public string PathToTrack(IRoadieSettings configuration, string libraryFolder)
|
||||
{
|
||||
|
@ -69,31 +54,30 @@ namespace Roadie.Library.Data
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a full file path to the current track thumbnail (if any)
|
||||
/// Returns a full file path to the current track thumbnail (if any)
|
||||
/// </summary>
|
||||
public string PathToTrackThumbnail(IRoadieSettings configuration, string libraryFolder)
|
||||
{
|
||||
return FolderPathHelper.PathForTrackThumbnail(configuration, this, libraryFolder);
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("Id [{0}], TrackNumber [{1}], Title [{2}]", this.Id, this.TrackNumber, this.Title);
|
||||
return string.Format("Id [{0}], TrackNumber [{1}], Title [{2}]", Id, TrackNumber, Title);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update any file related columns to indicate this track file is missing
|
||||
/// Update any file related columns to indicate this track file is missing
|
||||
/// </summary>
|
||||
/// <param name="now">Optional datetime to mark for Updated, if missing defaults to UtcNow</param>
|
||||
public void UpdateTrackMissingFile(DateTime? now = null)
|
||||
{
|
||||
this.Hash = null;
|
||||
this.Status = Statuses.Missing;
|
||||
this.FileName = null;
|
||||
this.FileSize = null;
|
||||
this.FilePath = null;
|
||||
this.LastUpdated = now ?? DateTime.UtcNow;
|
||||
Hash = null;
|
||||
Status = Statuses.Missing;
|
||||
FileName = null;
|
||||
FileSize = null;
|
||||
FilePath = null;
|
||||
LastUpdated = now ?? DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,32 +5,25 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("userartist")]
|
||||
public partial class UserArtist : EntityBase
|
||||
public class UserArtist : EntityBase
|
||||
{
|
||||
public Artist Artist { get; set; }
|
||||
|
||||
[Column("artistId")]
|
||||
[Required]
|
||||
public int ArtistId { get; set; }
|
||||
[Column("artistId")] [Required] public int ArtistId { get; set; }
|
||||
|
||||
[Column("isDisliked")]
|
||||
public bool? IsDisliked { get; set; }
|
||||
[Column("isDisliked")] public bool? IsDisliked { get; set; }
|
||||
|
||||
[Column("isFavorite")]
|
||||
public bool? IsFavorite { get; set; }
|
||||
[Column("isFavorite")] public bool? IsFavorite { get; set; }
|
||||
|
||||
[Column("rating")]
|
||||
public short Rating { get; set; }
|
||||
[Column("rating")] public short Rating { get; set; }
|
||||
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
[Column("userId")]
|
||||
[Required]
|
||||
public int UserId { get; set; }
|
||||
[Column("userId")] [Required] public int UserId { get; set; }
|
||||
|
||||
public UserArtist()
|
||||
{
|
||||
this.Rating = 0;
|
||||
Rating = 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +1,19 @@
|
|||
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("userQue")]
|
||||
public class UserQue : EntityBase
|
||||
{
|
||||
[Column("isCurrent")] public bool? IsCurrent { get; set; }
|
||||
[Column("position")] public long? Position { get; set; }
|
||||
[Column("queSortOrder")] [Required] public short QueSortOrder { get; set; }
|
||||
public Track Track { get; set; }
|
||||
[Column("trackId")] [Required] public int TrackId { get; set; }
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
[Column("userId")]
|
||||
[Required]
|
||||
public int UserId { get; set; }
|
||||
|
||||
public Track Track { get; set; }
|
||||
|
||||
[Column("trackId")]
|
||||
[Required]
|
||||
public int TrackId { get; set; }
|
||||
|
||||
[Column("queSortOrder")]
|
||||
[Required]
|
||||
public short QueSortOrder { get; set; }
|
||||
|
||||
[Column("position")]
|
||||
public long? Position { get; set; }
|
||||
|
||||
[Column("isCurrent")]
|
||||
public bool? IsCurrent { get; set; }
|
||||
|
||||
[Column("userId")] [Required] public int UserId { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,32 +5,25 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("userrelease")]
|
||||
public partial class UserRelease : EntityBase
|
||||
public class UserRelease : EntityBase
|
||||
{
|
||||
[Column("isDisliked")]
|
||||
public bool? IsDisliked { get; set; }
|
||||
[Column("isDisliked")] public bool? IsDisliked { get; set; }
|
||||
|
||||
[Column("isFavorite")]
|
||||
public bool? IsFavorite { get; set; }
|
||||
[Column("isFavorite")] public bool? IsFavorite { get; set; }
|
||||
|
||||
[Column("rating")]
|
||||
public short Rating { get; set; }
|
||||
[Column("rating")] public short Rating { get; set; }
|
||||
|
||||
public Release Release { get; set; }
|
||||
|
||||
[Column("releaseId")]
|
||||
[Required]
|
||||
public int ReleaseId { get; set; }
|
||||
[Column("releaseId")] [Required] public int ReleaseId { get; set; }
|
||||
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
[Column("userId")]
|
||||
[Required]
|
||||
public int UserId { get; set; }
|
||||
[Column("userId")] [Required] public int UserId { get; set; }
|
||||
|
||||
public UserRelease()
|
||||
{
|
||||
this.Rating = 0;
|
||||
Rating = 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,37 +6,29 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("usertrack")]
|
||||
public partial class UserTrack : EntityBase
|
||||
public class UserTrack : EntityBase
|
||||
{
|
||||
[Column("isDisliked")]
|
||||
public bool? IsDisliked { get; set; }
|
||||
[Column("isDisliked")] public bool? IsDisliked { get; set; }
|
||||
|
||||
[Column("isFavorite")]
|
||||
public bool? IsFavorite { get; set; }
|
||||
[Column("isFavorite")] public bool? IsFavorite { get; set; }
|
||||
|
||||
[Column("lastPlayed")]
|
||||
public DateTime? LastPlayed { get; set; }
|
||||
[Column("lastPlayed")] public DateTime? LastPlayed { get; set; }
|
||||
|
||||
[Column("playedCount")]
|
||||
public int? PlayedCount { get; set; }
|
||||
[Column("playedCount")] public int? PlayedCount { get; set; }
|
||||
|
||||
[Column("rating")]
|
||||
public short Rating { get; set; }
|
||||
[Column("rating")] public short Rating { get; set; }
|
||||
|
||||
public Track Track { get; set; }
|
||||
|
||||
[Column("trackId")]
|
||||
[Required]
|
||||
public int TrackId { get; set; }
|
||||
[Column("trackId")] [Required] public int TrackId { get; set; }
|
||||
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
[Column("userId")]
|
||||
[Required]
|
||||
public int UserId { get; set; }
|
||||
[Column("userId")] [Required] public int UserId { get; set; }
|
||||
|
||||
public UserTrack()
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
public UserTrack(DateTime? now = null)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Encoding
|
||||
{
|
||||
|
@ -31,4 +29,4 @@ namespace Roadie.Library.Encoding
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,32 +29,34 @@ namespace Roadie.Library.Engines
|
|||
{
|
||||
public class ArtistLookupEngine : LookupEngineBase, IArtistLookupEngine
|
||||
{
|
||||
private List<int> _addedArtistIds = new List<int>();
|
||||
private readonly List<int> _addedArtistIds = new List<int>();
|
||||
|
||||
public IEnumerable<int> AddedArtistIds
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._addedArtistIds;
|
||||
}
|
||||
}
|
||||
public IEnumerable<int> AddedArtistIds => _addedArtistIds;
|
||||
|
||||
public IArtistSearchEngine DiscogsArtistSearchEngine { get; }
|
||||
|
||||
public IArtistSearchEngine ITunesArtistSearchEngine { get; }
|
||||
|
||||
public IArtistSearchEngine LastFmArtistSearchEngine { get; }
|
||||
|
||||
public IArtistSearchEngine MusicBrainzArtistSearchEngine { get; }
|
||||
|
||||
public IArtistSearchEngine SpotifyArtistSearchEngine { get; }
|
||||
|
||||
public IArtistSearchEngine WikipediaArtistSearchEngine { get; }
|
||||
|
||||
public ArtistLookupEngine(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context, ICacheManager cacheManager, ILogger logger)
|
||||
public ArtistLookupEngine(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context,
|
||||
ICacheManager cacheManager, ILogger logger)
|
||||
: base(configuration, httpEncoder, context, cacheManager, logger)
|
||||
{
|
||||
this.ITunesArtistSearchEngine = new ITunesSearchEngine(this.Configuration, this.CacheManager, this.Logger);
|
||||
this.MusicBrainzArtistSearchEngine = new musicbrainz.MusicBrainzProvider(this.Configuration, this.CacheManager, this.Logger);
|
||||
this.LastFmArtistSearchEngine = new lastfm.LastFmHelper(this.Configuration, this.CacheManager, this.Logger, context, httpEncoder);
|
||||
this.SpotifyArtistSearchEngine = new spotify.SpotifyHelper(this.Configuration, this.CacheManager, this.Logger);
|
||||
this.WikipediaArtistSearchEngine = new wikipedia.WikipediaHelper(this.Configuration, this.CacheManager, this.Logger, this.HttpEncoder);
|
||||
this.DiscogsArtistSearchEngine = new discogs.DiscogsHelper(this.Configuration, this.CacheManager, this.Logger);
|
||||
ITunesArtistSearchEngine = new ITunesSearchEngine(Configuration, CacheManager, Logger);
|
||||
MusicBrainzArtistSearchEngine = new musicbrainz.MusicBrainzProvider(Configuration, CacheManager, Logger);
|
||||
LastFmArtistSearchEngine =
|
||||
new lastfm.LastFmHelper(Configuration, CacheManager, Logger, context, httpEncoder);
|
||||
SpotifyArtistSearchEngine = new spotify.SpotifyHelper(Configuration, CacheManager, Logger);
|
||||
WikipediaArtistSearchEngine =
|
||||
new wikipedia.WikipediaHelper(Configuration, CacheManager, Logger, HttpEncoder);
|
||||
DiscogsArtistSearchEngine = new discogs.DiscogsHelper(Configuration, CacheManager, Logger);
|
||||
}
|
||||
|
||||
public async Task<OperationResult<Artist>> Add(Artist artist)
|
||||
|
@ -66,7 +68,8 @@ namespace Roadie.Library.Engines
|
|||
var ArtistGenreTables = artist.Genres;
|
||||
var ArtistImages = artist.Images;
|
||||
var now = DateTime.UtcNow;
|
||||
artist.AlternateNames = artist.AlternateNames.AddToDelimitedList(new string[] { artist.Name.ToAlphanumericName() });
|
||||
artist.AlternateNames =
|
||||
artist.AlternateNames.AddToDelimitedList(new[] { artist.Name.ToAlphanumericName() });
|
||||
artist.Genres = null;
|
||||
artist.Images = null;
|
||||
if (artist.Thumbnail == null && ArtistImages != null)
|
||||
|
@ -78,31 +81,29 @@ namespace Roadie.Library.Engines
|
|||
artist.Thumbnail = firstImageWithNotNullBytes.Bytes;
|
||||
if (artist.Thumbnail != null)
|
||||
{
|
||||
artist.Thumbnail = ImageHelper.ResizeImage(artist.Thumbnail, this.Configuration.ThumbnailImageSize.Width, this.Configuration.ThumbnailImageSize.Height);
|
||||
artist.Thumbnail = ImageHelper.ResizeImage(artist.Thumbnail,
|
||||
Configuration.ThumbnailImageSize.Width, Configuration.ThumbnailImageSize.Height);
|
||||
artist.Thumbnail = ImageHelper.ConvertToJpegFormat(artist.Thumbnail);
|
||||
if (artist.Thumbnail.Length >= ImageHelper.MaximumThumbnailByteSize)
|
||||
{
|
||||
Logger.LogWarning($"Artist Thumbnail larger than maximum size after resizing to [{ this.Configuration.ThumbnailImageSize.Width }x{ this.Configuration.ThumbnailImageSize.Height}] Thumbnail Size [{ artist.Thumbnail.Length }]");
|
||||
Logger.LogWarning(
|
||||
$"Artist Thumbnail larger than maximum size after resizing to [{Configuration.ThumbnailImageSize.Width}x{Configuration.ThumbnailImageSize.Height}] Thumbnail Size [{artist.Thumbnail.Length}]");
|
||||
artist.Thumbnail = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!artist.IsValid)
|
||||
{
|
||||
return new OperationResult<Artist>
|
||||
{
|
||||
Errors = new Exception[1] { new Exception("Artist is Invalid") }
|
||||
};
|
||||
}
|
||||
var addArtistResult = this.DbContext.Artists.Add(artist);
|
||||
int inserted = 0;
|
||||
inserted = await this.DbContext.SaveChangesAsync();
|
||||
this._addedArtistIds.Add(artist.Id);
|
||||
if (artist.Id < 1 && addArtistResult.Entity.Id > 0)
|
||||
{
|
||||
artist.Id = addArtistResult.Entity.Id;
|
||||
}
|
||||
var addArtistResult = DbContext.Artists.Add(artist);
|
||||
var inserted = 0;
|
||||
inserted = await DbContext.SaveChangesAsync();
|
||||
_addedArtistIds.Add(artist.Id);
|
||||
if (artist.Id < 1 && addArtistResult.Entity.Id > 0) artist.Id = addArtistResult.Entity.Id;
|
||||
if (inserted > 0 && artist.Id > 0)
|
||||
{
|
||||
if (ArtistGenreTables != null && ArtistGenreTables.Any(x => x.GenreId == null))
|
||||
|
@ -112,48 +113,51 @@ namespace Roadie.Library.Engines
|
|||
{
|
||||
foreach (var ArtistGenreTable in ArtistGenreTables)
|
||||
{
|
||||
var genre = this.DbContext.Genres.FirstOrDefault(x => x.Name.ToLower().Trim() == ArtistGenreTable.Genre.Name.ToLower().Trim());
|
||||
var genre = DbContext.Genres.FirstOrDefault(x =>
|
||||
x.Name.ToLower().Trim() == ArtistGenreTable.Genre.Name.ToLower().Trim());
|
||||
if (genre == null)
|
||||
{
|
||||
genre = new Genre
|
||||
{
|
||||
Name = ArtistGenreTable.Genre.Name
|
||||
};
|
||||
this.DbContext.Genres.Add(genre);
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
DbContext.Genres.Add(genre);
|
||||
await DbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (genre != null && genre.Id > 0)
|
||||
{
|
||||
await this.DbContext.Database.ExecuteSqlCommandAsync("INSERT INTO `artistGenreTable` (artistId, genreId) VALUES ({0}, {1});", artist.Id, genre.Id);
|
||||
}
|
||||
await DbContext.Database.ExecuteSqlCommandAsync(
|
||||
"INSERT INTO `artistGenreTable` (artistId, genreId) VALUES ({0}, {1});",
|
||||
artist.Id, genre.Id);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, "Sql [" + sql + "] Exception [" + ex.Serialize() + "]");
|
||||
Logger.LogError(ex, "Sql [" + sql + "] Exception [" + ex.Serialize() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
if (ArtistImages != null && ArtistImages.Any(x => x.Status == Statuses.New))
|
||||
{
|
||||
foreach (var ArtistImage in ArtistImages)
|
||||
{
|
||||
this.DbContext.Images.Add(new Image
|
||||
DbContext.Images.Add(new Image
|
||||
{
|
||||
ArtistId = artist.Id,
|
||||
Url = ArtistImage.Url,
|
||||
Signature = ArtistImage.Signature,
|
||||
Bytes = ArtistImage.Bytes
|
||||
});
|
||||
}
|
||||
inserted = await this.DbContext.SaveChangesAsync();
|
||||
inserted = await DbContext.SaveChangesAsync();
|
||||
}
|
||||
this.Logger.LogInformation("Added New Artist: [{0}]", artist.ToString());
|
||||
|
||||
Logger.LogInformation("Added New Artist: [{0}]", artist.ToString());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, ex.Serialize());
|
||||
Logger.LogError(ex, ex.Serialize());
|
||||
}
|
||||
|
||||
return new OperationResult<Artist>
|
||||
{
|
||||
IsSuccess = artist.Id > 0,
|
||||
|
@ -163,43 +167,41 @@ namespace Roadie.Library.Engines
|
|||
|
||||
public Artist DatabaseQueryForArtistName(string name, string sortName = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(name)) return null;
|
||||
try
|
||||
{
|
||||
var searchName = name.NormalizeName();
|
||||
var searchSortName = !string.IsNullOrEmpty(sortName) ? sortName.NormalizeName().ToLower() : searchName;
|
||||
var specialSearchName = name.ToAlphanumericName();
|
||||
|
||||
var searchNameStart = $"{ searchName }|";
|
||||
var searchNameIn = $"|{ searchName }|";
|
||||
var searchNameEnd = $"|{ searchName }";
|
||||
var searchNameStart = $"{searchName}|";
|
||||
var searchNameIn = $"|{searchName}|";
|
||||
var searchNameEnd = $"|{searchName}";
|
||||
|
||||
var specialSearchNameStart = $"{ specialSearchName }|";
|
||||
var specialSearchNameIn = $"|{ specialSearchName }|";
|
||||
var specialSearchNameEnd = $"|{ specialSearchName }";
|
||||
var specialSearchNameStart = $"{specialSearchName}|";
|
||||
var specialSearchNameIn = $"|{specialSearchName}|";
|
||||
var specialSearchNameEnd = $"|{specialSearchName}";
|
||||
|
||||
return (from a in this.DbContext.Artists
|
||||
where (a.Name == searchName ||
|
||||
a.Name == specialSearchName ||
|
||||
a.SortName == searchName ||
|
||||
a.SortName == searchSortName ||
|
||||
a.SortName == specialSearchName ||
|
||||
a.AlternateNames.StartsWith(searchNameStart) ||
|
||||
a.AlternateNames.Contains(searchNameIn) ||
|
||||
a.AlternateNames.EndsWith(searchNameEnd) ||
|
||||
a.AlternateNames.StartsWith(specialSearchNameStart) ||
|
||||
a.AlternateNames.Contains(specialSearchNameIn) ||
|
||||
a.AlternateNames.EndsWith(specialSearchNameEnd))
|
||||
return (from a in DbContext.Artists
|
||||
where a.Name == searchName ||
|
||||
a.Name == specialSearchName ||
|
||||
a.SortName == searchName ||
|
||||
a.SortName == searchSortName ||
|
||||
a.SortName == specialSearchName ||
|
||||
a.AlternateNames.StartsWith(searchNameStart) ||
|
||||
a.AlternateNames.Contains(searchNameIn) ||
|
||||
a.AlternateNames.EndsWith(searchNameEnd) ||
|
||||
a.AlternateNames.StartsWith(specialSearchNameStart) ||
|
||||
a.AlternateNames.Contains(specialSearchNameIn) ||
|
||||
a.AlternateNames.EndsWith(specialSearchNameEnd)
|
||||
select a
|
||||
).FirstOrDefault();
|
||||
).FirstOrDefault();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, ex.Serialize());
|
||||
Logger.LogError(ex, ex.Serialize());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -210,9 +212,9 @@ namespace Roadie.Library.Engines
|
|||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
var artistName = metaData.Artist ?? metaData.TrackArtist;
|
||||
var cacheRegion = (new Artist { Name = artistName }).CacheRegion;
|
||||
var cacheRegion = new Artist { Name = artistName }.CacheRegion;
|
||||
var cacheKey = string.Format("urn:artist_by_name:{0}", artistName);
|
||||
var resultInCache = this.CacheManager.Get<Artist>(cacheKey, cacheRegion);
|
||||
var resultInCache = CacheManager.Get<Artist>(cacheKey, cacheRegion);
|
||||
if (resultInCache != null)
|
||||
{
|
||||
sw.Stop();
|
||||
|
@ -223,56 +225,63 @@ namespace Roadie.Library.Engines
|
|||
Data = resultInCache
|
||||
};
|
||||
}
|
||||
var artist = this.DatabaseQueryForArtistName(artistName);
|
||||
|
||||
var artist = DatabaseQueryForArtistName(artistName);
|
||||
sw.Stop();
|
||||
if (artist == null || !artist.IsValid)
|
||||
{
|
||||
this.Logger.LogInformation("ArtistLookupEngine: Artist Not Found By Name [{0}]", artistName);
|
||||
Logger.LogInformation("ArtistLookupEngine: Artist Not Found By Name [{0}]", artistName);
|
||||
if (doFindIfNotInDatabase)
|
||||
{
|
||||
OperationResult<Artist> artistSearch = null;
|
||||
|
||||
// See if roadie.json file exists in the metadata files folder, if so then use artist data from that
|
||||
var releaseRoadieDataFilename = Path.Combine(Path.GetDirectoryName(metaData.Filename), "roadie.artist.json");
|
||||
var releaseRoadieDataFilename = Path.Combine(Path.GetDirectoryName(metaData.Filename),
|
||||
"roadie.artist.json");
|
||||
if (File.Exists(releaseRoadieDataFilename))
|
||||
{
|
||||
artist = JsonConvert.DeserializeObject<Artist>(File.ReadAllText(releaseRoadieDataFilename));
|
||||
var addResult = await this.Add(artist);
|
||||
var addResult = await Add(artist);
|
||||
if (!addResult.IsSuccess)
|
||||
{
|
||||
sw.Stop();
|
||||
this.Logger.LogWarning("Unable To Add Artist For Roadie Data File [{0}]", releaseRoadieDataFilename);
|
||||
Logger.LogWarning("Unable To Add Artist For Roadie Data File [{0}]",
|
||||
releaseRoadieDataFilename);
|
||||
return new OperationResult<Artist>
|
||||
{
|
||||
OperationTime = sw.ElapsedMilliseconds,
|
||||
Errors = addResult.Errors
|
||||
};
|
||||
}
|
||||
|
||||
artist = addResult.Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
artistSearch = await this.PerformMetaDataProvidersArtistSearch(metaData);
|
||||
artistSearch = await PerformMetaDataProvidersArtistSearch(metaData);
|
||||
if (artistSearch.IsSuccess)
|
||||
{
|
||||
artist = artistSearch.Data;
|
||||
// See if Artist already exist with either Name or Sort Name
|
||||
var alreadyExists = this.DatabaseQueryForArtistName(artistSearch.Data.Name, artistSearch.Data.SortNameValue);
|
||||
var alreadyExists = DatabaseQueryForArtistName(artistSearch.Data.Name,
|
||||
artistSearch.Data.SortNameValue);
|
||||
if (alreadyExists == null || !alreadyExists.IsValid)
|
||||
{
|
||||
var addResult = await this.Add(artist);
|
||||
var addResult = await Add(artist);
|
||||
if (!addResult.IsSuccess)
|
||||
{
|
||||
sw.Stop();
|
||||
this.Logger.LogWarning("Unable To Add Artist For MetaData [{0}]", metaData.ToString());
|
||||
Logger.LogWarning("Unable To Add Artist For MetaData [{0}]",
|
||||
metaData.ToString());
|
||||
return new OperationResult<Artist>
|
||||
{
|
||||
OperationTime = sw.ElapsedMilliseconds,
|
||||
Errors = addResult.Errors
|
||||
};
|
||||
}
|
||||
|
||||
artist = addResult.Data;
|
||||
}
|
||||
else
|
||||
|
@ -283,15 +292,13 @@ namespace Roadie.Library.Engines
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, ex.Serialize());
|
||||
Logger.LogError(ex, ex.Serialize());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (artist != null && artist.IsValid)
|
||||
{
|
||||
this.CacheManager.Add(cacheKey, artist);
|
||||
}
|
||||
|
||||
if (artist != null && artist.IsValid) CacheManager.Add(cacheKey, artist);
|
||||
return new OperationResult<Artist>
|
||||
{
|
||||
IsSuccess = artist != null,
|
||||
|
@ -301,15 +308,17 @@ namespace Roadie.Library.Engines
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, ex.Serialize());
|
||||
Logger.LogError(ex, ex.Serialize());
|
||||
}
|
||||
|
||||
return new OperationResult<Artist>();
|
||||
}
|
||||
|
||||
public async Task<OperationResult<Artist>> PerformMetaDataProvidersArtistSearch(AudioMetaData metaData)
|
||||
{
|
||||
SimpleContract.Requires<ArgumentNullException>(metaData != null, "Invalid MetaData");
|
||||
SimpleContract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(metaData.Artist), "Invalid MetaData, Missing Artist");
|
||||
SimpleContract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(metaData.Artist),
|
||||
"Invalid MetaData, Missing Artist");
|
||||
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
@ -324,36 +333,19 @@ namespace Roadie.Library.Engines
|
|||
|
||||
try
|
||||
{
|
||||
if (this.ITunesArtistSearchEngine.IsEnabled)
|
||||
if (ITunesArtistSearchEngine.IsEnabled)
|
||||
{
|
||||
var iTunesResult = await this.ITunesArtistSearchEngine.PerformArtistSearch(artistName, 1);
|
||||
var iTunesResult = await ITunesArtistSearchEngine.PerformArtistSearch(artistName, 1);
|
||||
if (iTunesResult.IsSuccess)
|
||||
{
|
||||
var i = iTunesResult.Data.First();
|
||||
if (i.AlternateNames != null)
|
||||
{
|
||||
result.AlternateNames = result.AlternateNames.AddToDelimitedList(i.AlternateNames);
|
||||
}
|
||||
if (i.Tags != null)
|
||||
{
|
||||
result.Tags = result.Tags.AddToDelimitedList(i.Tags);
|
||||
}
|
||||
if (i.Urls != null)
|
||||
{
|
||||
result.URLs = result.URLs.AddToDelimitedList(i.Urls);
|
||||
}
|
||||
if (i.ISNIs != null)
|
||||
{
|
||||
result.ISNI = result.ISNI.AddToDelimitedList(i.ISNIs);
|
||||
}
|
||||
if (i.ImageUrls != null)
|
||||
{
|
||||
artistImageUrls.AddRange(i.ImageUrls);
|
||||
}
|
||||
if (i.ArtistGenres != null)
|
||||
{
|
||||
artistGenres.AddRange(i.ArtistGenres);
|
||||
}
|
||||
if (i.Tags != null) result.Tags = result.Tags.AddToDelimitedList(i.Tags);
|
||||
if (i.Urls != null) result.URLs = result.URLs.AddToDelimitedList(i.Urls);
|
||||
if (i.ISNIs != null) result.ISNI = result.ISNI.AddToDelimitedList(i.ISNIs);
|
||||
if (i.ImageUrls != null) artistImageUrls.AddRange(i.ImageUrls);
|
||||
if (i.ArtistGenres != null) artistGenres.AddRange(i.ArtistGenres);
|
||||
result.CopyTo(new Artist
|
||||
{
|
||||
EndDate = i.EndDate,
|
||||
|
@ -363,56 +355,39 @@ namespace Roadie.Library.Engines
|
|||
BeginDate = i.BeginDate,
|
||||
Name = result.Name ?? i.ArtistName,
|
||||
SortName = result.SortName ?? i.ArtistSortName,
|
||||
Thumbnail = i.ArtistThumbnailUrl != null ? WebHelper.BytesForImageUrl(i.ArtistThumbnailUrl) : null,
|
||||
Thumbnail = i.ArtistThumbnailUrl != null
|
||||
? WebHelper.BytesForImageUrl(i.ArtistThumbnailUrl)
|
||||
: null,
|
||||
ArtistType = result.ArtistType ?? i.ArtistType
|
||||
});
|
||||
}
|
||||
if (iTunesResult.Errors != null)
|
||||
{
|
||||
resultsExceptions.AddRange(iTunesResult.Errors);
|
||||
}
|
||||
|
||||
if (iTunesResult.Errors != null) resultsExceptions.AddRange(iTunesResult.Errors);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, "iTunesArtistSearch: " + ex.Serialize());
|
||||
Logger.LogError(ex, "iTunesArtistSearch: " + ex.Serialize());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (this.MusicBrainzArtistSearchEngine.IsEnabled)
|
||||
if (MusicBrainzArtistSearchEngine.IsEnabled)
|
||||
{
|
||||
var mbResult = await this.MusicBrainzArtistSearchEngine.PerformArtistSearch(result.Name, 1);
|
||||
var mbResult = await MusicBrainzArtistSearchEngine.PerformArtistSearch(result.Name, 1);
|
||||
if (mbResult.IsSuccess)
|
||||
{
|
||||
var mb = mbResult.Data.First();
|
||||
if (mb.AlternateNames != null)
|
||||
{
|
||||
result.AlternateNames = result.AlternateNames.AddToDelimitedList(mb.AlternateNames);
|
||||
}
|
||||
if (mb.Tags != null)
|
||||
{
|
||||
result.Tags = result.Tags.AddToDelimitedList(mb.Tags);
|
||||
}
|
||||
if (mb.Urls != null)
|
||||
{
|
||||
result.URLs = result.URLs.AddToDelimitedList(mb.Urls);
|
||||
}
|
||||
if (mb.ISNIs != null)
|
||||
{
|
||||
result.ISNI = result.ISNI.AddToDelimitedList(mb.ISNIs);
|
||||
}
|
||||
if (mb.ImageUrls != null)
|
||||
{
|
||||
artistImageUrls.AddRange(mb.ImageUrls);
|
||||
}
|
||||
if (mb.ArtistGenres != null)
|
||||
{
|
||||
artistGenres.AddRange(mb.ArtistGenres);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(mb.ArtistName) && !mb.ArtistName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result.AlternateNames.AddToDelimitedList(new string[] { mb.ArtistName });
|
||||
}
|
||||
if (mb.Tags != null) result.Tags = result.Tags.AddToDelimitedList(mb.Tags);
|
||||
if (mb.Urls != null) result.URLs = result.URLs.AddToDelimitedList(mb.Urls);
|
||||
if (mb.ISNIs != null) result.ISNI = result.ISNI.AddToDelimitedList(mb.ISNIs);
|
||||
if (mb.ImageUrls != null) artistImageUrls.AddRange(mb.ImageUrls);
|
||||
if (mb.ArtistGenres != null) artistGenres.AddRange(mb.ArtistGenres);
|
||||
if (!string.IsNullOrEmpty(mb.ArtistName) &&
|
||||
!mb.ArtistName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
|
||||
result.AlternateNames.AddToDelimitedList(new[] { mb.ArtistName });
|
||||
result.CopyTo(new Artist
|
||||
{
|
||||
EndDate = mb.EndDate,
|
||||
|
@ -422,185 +397,147 @@ namespace Roadie.Library.Engines
|
|||
BeginDate = mb.BeginDate,
|
||||
Name = result.Name ?? mb.ArtistName,
|
||||
SortName = result.SortName ?? mb.ArtistSortName,
|
||||
Thumbnail = mb.ArtistThumbnailUrl != null ? WebHelper.BytesForImageUrl(mb.ArtistThumbnailUrl) : null,
|
||||
Thumbnail = mb.ArtistThumbnailUrl != null
|
||||
? WebHelper.BytesForImageUrl(mb.ArtistThumbnailUrl)
|
||||
: null,
|
||||
ArtistType = mb.ArtistType
|
||||
});
|
||||
}
|
||||
if (mbResult.Errors != null)
|
||||
{
|
||||
resultsExceptions.AddRange(mbResult.Errors);
|
||||
}
|
||||
|
||||
if (mbResult.Errors != null) resultsExceptions.AddRange(mbResult.Errors);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, "MusicBrainzArtistSearch: " + ex.Serialize());
|
||||
Logger.LogError(ex, "MusicBrainzArtistSearch: " + ex.Serialize());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (this.LastFmArtistSearchEngine.IsEnabled)
|
||||
if (LastFmArtistSearchEngine.IsEnabled)
|
||||
{
|
||||
var lastFmResult = await this.LastFmArtistSearchEngine.PerformArtistSearch(result.Name, 1);
|
||||
var lastFmResult = await LastFmArtistSearchEngine.PerformArtistSearch(result.Name, 1);
|
||||
if (lastFmResult.IsSuccess)
|
||||
{
|
||||
var l = lastFmResult.Data.First();
|
||||
if (l.AlternateNames != null)
|
||||
{
|
||||
result.AlternateNames = result.AlternateNames.AddToDelimitedList(l.AlternateNames);
|
||||
}
|
||||
if (l.Tags != null)
|
||||
{
|
||||
result.Tags = result.Tags.AddToDelimitedList(l.Tags);
|
||||
}
|
||||
if (l.Urls != null)
|
||||
{
|
||||
result.URLs = result.URLs.AddToDelimitedList(l.Urls);
|
||||
}
|
||||
if (l.ISNIs != null)
|
||||
{
|
||||
result.ISNI = result.ISNI.AddToDelimitedList(l.ISNIs);
|
||||
}
|
||||
if (l.ImageUrls != null)
|
||||
{
|
||||
artistImageUrls.AddRange(l.ImageUrls);
|
||||
}
|
||||
if (l.ArtistGenres != null)
|
||||
{
|
||||
artistGenres.AddRange(l.ArtistGenres);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(l.ArtistName) && !l.ArtistName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result.AlternateNames.AddToDelimitedList(new string[] { l.ArtistName });
|
||||
}
|
||||
if (l.Tags != null) result.Tags = result.Tags.AddToDelimitedList(l.Tags);
|
||||
if (l.Urls != null) result.URLs = result.URLs.AddToDelimitedList(l.Urls);
|
||||
if (l.ISNIs != null) result.ISNI = result.ISNI.AddToDelimitedList(l.ISNIs);
|
||||
if (l.ImageUrls != null) artistImageUrls.AddRange(l.ImageUrls);
|
||||
if (l.ArtistGenres != null) artistGenres.AddRange(l.ArtistGenres);
|
||||
if (!string.IsNullOrEmpty(l.ArtistName) &&
|
||||
!l.ArtistName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
|
||||
result.AlternateNames.AddToDelimitedList(new[] { l.ArtistName });
|
||||
result.CopyTo(new Artist
|
||||
{
|
||||
EndDate = l.EndDate,
|
||||
BioContext = this.HttpEncoder.HtmlEncode(l.Bio),
|
||||
Profile = this.HttpEncoder.HtmlEncode(l.Profile),
|
||||
BioContext = HttpEncoder.HtmlEncode(l.Bio),
|
||||
Profile = HttpEncoder.HtmlEncode(l.Profile),
|
||||
MusicBrainzId = l.MusicBrainzId,
|
||||
BeginDate = l.BeginDate,
|
||||
Name = result.Name ?? l.ArtistName,
|
||||
SortName = result.SortName ?? l.ArtistSortName,
|
||||
Thumbnail = l.ArtistThumbnailUrl != null ? WebHelper.BytesForImageUrl(l.ArtistThumbnailUrl) : null,
|
||||
Thumbnail = l.ArtistThumbnailUrl != null
|
||||
? WebHelper.BytesForImageUrl(l.ArtistThumbnailUrl)
|
||||
: null,
|
||||
ArtistType = result.ArtistType ?? l.ArtistType
|
||||
});
|
||||
}
|
||||
if (lastFmResult.Errors != null)
|
||||
{
|
||||
resultsExceptions.AddRange(lastFmResult.Errors);
|
||||
}
|
||||
|
||||
if (lastFmResult.Errors != null) resultsExceptions.AddRange(lastFmResult.Errors);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, "LastFMArtistSearch: " + ex.Serialize());
|
||||
Logger.LogError(ex, "LastFMArtistSearch: " + ex.Serialize());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (this.SpotifyArtistSearchEngine.IsEnabled)
|
||||
if (SpotifyArtistSearchEngine.IsEnabled)
|
||||
{
|
||||
var spotifyResult = await this.SpotifyArtistSearchEngine.PerformArtistSearch(result.Name, 1);
|
||||
var spotifyResult = await SpotifyArtistSearchEngine.PerformArtistSearch(result.Name, 1);
|
||||
if (spotifyResult.IsSuccess)
|
||||
{
|
||||
var s = spotifyResult.Data.First();
|
||||
if (s.Tags != null)
|
||||
{
|
||||
result.Tags = result.Tags.AddToDelimitedList(s.Tags);
|
||||
}
|
||||
if (s.Urls != null)
|
||||
{
|
||||
result.URLs = result.URLs.AddToDelimitedList(s.Urls);
|
||||
}
|
||||
if (s.ImageUrls != null)
|
||||
{
|
||||
artistImageUrls.AddRange(s.ImageUrls);
|
||||
}
|
||||
if (s.ArtistGenres != null)
|
||||
{
|
||||
artistGenres.AddRange(s.ArtistGenres);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(s.ArtistName) && !s.ArtistName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result.AlternateNames.AddToDelimitedList(new string[] { s.ArtistName });
|
||||
}
|
||||
if (s.Tags != null) result.Tags = result.Tags.AddToDelimitedList(s.Tags);
|
||||
if (s.Urls != null) result.URLs = result.URLs.AddToDelimitedList(s.Urls);
|
||||
if (s.ImageUrls != null) artistImageUrls.AddRange(s.ImageUrls);
|
||||
if (s.ArtistGenres != null) artistGenres.AddRange(s.ArtistGenres);
|
||||
if (!string.IsNullOrEmpty(s.ArtistName) &&
|
||||
!s.ArtistName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
|
||||
result.AlternateNames.AddToDelimitedList(new[] { s.ArtistName });
|
||||
result.CopyTo(new Artist
|
||||
{
|
||||
EndDate = s.EndDate,
|
||||
BioContext = s.Bio,
|
||||
Profile = this.HttpEncoder.HtmlEncode(s.Profile),
|
||||
Profile = HttpEncoder.HtmlEncode(s.Profile),
|
||||
MusicBrainzId = s.MusicBrainzId,
|
||||
BeginDate = s.BeginDate,
|
||||
Name = result.Name ?? s.ArtistName,
|
||||
SortName = result.SortName ?? s.ArtistSortName,
|
||||
Thumbnail = s.ArtistThumbnailUrl != null ? WebHelper.BytesForImageUrl(s.ArtistThumbnailUrl) : null,
|
||||
Thumbnail = s.ArtistThumbnailUrl != null
|
||||
? WebHelper.BytesForImageUrl(s.ArtistThumbnailUrl)
|
||||
: null,
|
||||
ArtistType = result.ArtistType ?? s.ArtistType
|
||||
});
|
||||
}
|
||||
if (spotifyResult.Errors != null)
|
||||
{
|
||||
resultsExceptions.AddRange(spotifyResult.Errors);
|
||||
}
|
||||
|
||||
if (spotifyResult.Errors != null) resultsExceptions.AddRange(spotifyResult.Errors);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, "SpotifyArtistSearch: " + ex.Serialize());
|
||||
Logger.LogError(ex, "SpotifyArtistSearch: " + ex.Serialize());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (this.DiscogsArtistSearchEngine.IsEnabled)
|
||||
if (DiscogsArtistSearchEngine.IsEnabled)
|
||||
{
|
||||
var discogsResult = await this.DiscogsArtistSearchEngine.PerformArtistSearch(result.Name, 1);
|
||||
var discogsResult = await DiscogsArtistSearchEngine.PerformArtistSearch(result.Name, 1);
|
||||
if (discogsResult.IsSuccess)
|
||||
{
|
||||
var d = discogsResult.Data.First();
|
||||
if (d.Urls != null)
|
||||
{
|
||||
result.URLs = result.URLs.AddToDelimitedList(d.Urls);
|
||||
}
|
||||
if (d.ImageUrls != null)
|
||||
{
|
||||
artistImageUrls.AddRange(d.ImageUrls);
|
||||
}
|
||||
if (d.Urls != null) result.URLs = result.URLs.AddToDelimitedList(d.Urls);
|
||||
if (d.ImageUrls != null) artistImageUrls.AddRange(d.ImageUrls);
|
||||
if (d.AlternateNames != null)
|
||||
{
|
||||
result.AlternateNames = result.AlternateNames.AddToDelimitedList(d.AlternateNames);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(d.ArtistName) && !d.ArtistName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result.AlternateNames.AddToDelimitedList(new string[] { d.ArtistName });
|
||||
}
|
||||
if (!string.IsNullOrEmpty(d.ArtistName) &&
|
||||
!d.ArtistName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
|
||||
result.AlternateNames.AddToDelimitedList(new[] { d.ArtistName });
|
||||
result.CopyTo(new Artist
|
||||
{
|
||||
Profile = this.HttpEncoder.HtmlEncode(d.Profile),
|
||||
Profile = HttpEncoder.HtmlEncode(d.Profile),
|
||||
DiscogsId = d.DiscogsId,
|
||||
Name = result.Name ?? d.ArtistName,
|
||||
RealName = result.RealName ?? d.ArtistRealName,
|
||||
Thumbnail = d.ArtistThumbnailUrl != null ? WebHelper.BytesForImageUrl(d.ArtistThumbnailUrl) : null,
|
||||
Thumbnail = d.ArtistThumbnailUrl != null
|
||||
? WebHelper.BytesForImageUrl(d.ArtistThumbnailUrl)
|
||||
: null,
|
||||
ArtistType = result.ArtistType ?? d.ArtistType
|
||||
});
|
||||
}
|
||||
if (discogsResult.Errors != null)
|
||||
{
|
||||
resultsExceptions.AddRange(discogsResult.Errors);
|
||||
}
|
||||
|
||||
if (discogsResult.Errors != null) resultsExceptions.AddRange(discogsResult.Errors);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, "DiscogsArtistSearch: " + ex.Serialize());
|
||||
Logger.LogError(ex, "DiscogsArtistSearch: " + ex.Serialize());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (this.WikipediaArtistSearchEngine.IsEnabled)
|
||||
if (WikipediaArtistSearchEngine.IsEnabled)
|
||||
{
|
||||
var wikiName = result.Name;
|
||||
// Help get better results for bands with proper nouns (e.g. "Poison")
|
||||
if (!result.ArtistType.Equals("Person", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
wikiName = wikiName + " band";
|
||||
}
|
||||
var wikipediaResult = await this.WikipediaArtistSearchEngine.PerformArtistSearch(wikiName, 1);
|
||||
var wikipediaResult = await WikipediaArtistSearchEngine.PerformArtistSearch(wikiName, 1);
|
||||
if (wikipediaResult != null)
|
||||
{
|
||||
if (wikipediaResult.IsSuccess)
|
||||
|
@ -608,56 +545,51 @@ namespace Roadie.Library.Engines
|
|||
var w = wikipediaResult.Data.First();
|
||||
result.CopyTo(new Artist
|
||||
{
|
||||
BioContext = this.HttpEncoder.HtmlEncode(w.Bio)
|
||||
BioContext = HttpEncoder.HtmlEncode(w.Bio)
|
||||
});
|
||||
}
|
||||
if (wikipediaResult.Errors != null)
|
||||
{
|
||||
resultsExceptions.AddRange(wikipediaResult.Errors);
|
||||
}
|
||||
|
||||
if (wikipediaResult.Errors != null) resultsExceptions.AddRange(wikipediaResult.Errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, "WikipediaArtistSearch: " + ex.Serialize());
|
||||
Logger.LogError(ex, "WikipediaArtistSearch: " + ex.Serialize());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (result.AlternateNames != null)
|
||||
{
|
||||
result.AlternateNames = string.Join("|", result.AlternateNames.ToListFromDelimited().Distinct().OrderBy(x => x));
|
||||
}
|
||||
result.AlternateNames = string.Join("|",
|
||||
result.AlternateNames.ToListFromDelimited().Distinct().OrderBy(x => x));
|
||||
if (result.URLs != null)
|
||||
{
|
||||
result.URLs = string.Join("|", result.URLs.ToListFromDelimited().Distinct().OrderBy(x => x));
|
||||
}
|
||||
if (result.Tags != null)
|
||||
{
|
||||
result.Tags = string.Join("|", result.Tags.ToListFromDelimited().Distinct().OrderBy(x => x));
|
||||
}
|
||||
if (artistGenres.Any())
|
||||
{
|
||||
var genreInfos = (from ag in artistGenres
|
||||
join g in this.DbContext.Genres on ag equals g.Name into gg
|
||||
from g in gg.DefaultIfEmpty()
|
||||
select new
|
||||
{
|
||||
newGenre = ag.ToTitleCase(),
|
||||
existingGenre = g
|
||||
});
|
||||
var genreInfos = from ag in artistGenres
|
||||
join g in DbContext.Genres on ag equals g.Name into gg
|
||||
from g in gg.DefaultIfEmpty()
|
||||
select new
|
||||
{
|
||||
newGenre = ag.ToTitleCase(),
|
||||
existingGenre = g
|
||||
};
|
||||
result.Genres = new List<ArtistGenre>();
|
||||
foreach (var genreInfo in genreInfos)
|
||||
{
|
||||
result.Genres.Add(new ArtistGenre
|
||||
{
|
||||
Genre = genreInfo.existingGenre != null ? genreInfo.existingGenre : new Genre
|
||||
{
|
||||
Name = genreInfo.newGenre
|
||||
}
|
||||
Genre = genreInfo.existingGenre != null
|
||||
? genreInfo.existingGenre
|
||||
: new Genre
|
||||
{
|
||||
Name = genreInfo.newGenre
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (artistImageUrls.Any())
|
||||
{
|
||||
var imageBag = new ConcurrentBag<Image>();
|
||||
|
@ -666,25 +598,26 @@ namespace Roadie.Library.Engines
|
|||
imageBag.Add(await WebHelper.GetImageFromUrlAsync(url));
|
||||
});
|
||||
await Task.WhenAll(i);
|
||||
result.Images = imageBag.Where(x => x != null && x.Bytes != null).GroupBy(x => x.Signature).Select(x => x.First()).Take(this.Configuration.Processing.MaximumArtistImagesToAdd).ToList();
|
||||
result.Images = imageBag.Where(x => x != null && x.Bytes != null).GroupBy(x => x.Signature)
|
||||
.Select(x => x.First()).Take(Configuration.Processing.MaximumArtistImagesToAdd).ToList();
|
||||
if (result.Thumbnail == null && result.Images != null)
|
||||
{
|
||||
result.Thumbnail = result.Images.First().Bytes;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.Thumbnail != null)
|
||||
{
|
||||
result.Thumbnail = ImageHelper.ResizeImage(result.Thumbnail, this.Configuration.ThumbnailImageSize.Width, this.Configuration.ThumbnailImageSize.Height);
|
||||
result.Thumbnail = ImageHelper.ResizeImage(result.Thumbnail, Configuration.ThumbnailImageSize.Width,
|
||||
Configuration.ThumbnailImageSize.Height);
|
||||
result.Thumbnail = ImageHelper.ConvertToJpegFormat(result.Thumbnail);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, "CombiningResults: " + ex.Serialize());
|
||||
Logger.LogError(ex, "CombiningResults: " + ex.Serialize());
|
||||
}
|
||||
|
||||
result.SortName = result.SortName.ToTitleCase();
|
||||
if (!string.IsNullOrEmpty(result.ArtistType))
|
||||
{
|
||||
switch (result.ArtistType.ToLower().Replace('-', ' '))
|
||||
{
|
||||
case "artist":
|
||||
|
@ -725,11 +658,11 @@ namespace Roadie.Library.Engines
|
|||
break;
|
||||
|
||||
default:
|
||||
this.Logger.LogWarning(string.Format("Unknown Artist Type [{0}]", result.ArtistType));
|
||||
Logger.LogWarning(string.Format("Unknown Artist Type [{0}]", result.ArtistType));
|
||||
result.ArtistType = "Other";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
return new OperationResult<Artist>
|
||||
{
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Roadie.Library.Data;
|
||||
using Roadie.Library.Data;
|
||||
using Roadie.Library.MetaData.Audio;
|
||||
using Roadie.Library.SearchEngines.Imaging;
|
||||
using Roadie.Library.SearchEngines.MetaData;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Engines
|
||||
{
|
||||
|
@ -18,8 +17,11 @@ namespace Roadie.Library.Engines
|
|||
IArtistSearchEngine WikipediaArtistSearchEngine { get; }
|
||||
|
||||
Task<OperationResult<Artist>> Add(Artist artist);
|
||||
Task<OperationResult<Artist>> GetByName(AudioMetaData metaData, bool doFindIfNotInDatabase = false);
|
||||
Task<OperationResult<Artist>> PerformMetaDataProvidersArtistSearch(AudioMetaData metaData);
|
||||
|
||||
Artist DatabaseQueryForArtistName(string name, string sortName = null);
|
||||
|
||||
Task<OperationResult<Artist>> GetByName(AudioMetaData metaData, bool doFindIfNotInDatabase = false);
|
||||
|
||||
Task<OperationResult<Artist>> PerformMetaDataProvidersArtistSearch(AudioMetaData metaData);
|
||||
}
|
||||
}
|
|
@ -1,12 +1,14 @@
|
|||
using System.Threading.Tasks;
|
||||
using Roadie.Library.Data;
|
||||
using Roadie.Library.Data;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Engines
|
||||
{
|
||||
public interface ILabelLookupEngine
|
||||
{
|
||||
Task<OperationResult<Label>> Add(Label label);
|
||||
|
||||
Task<OperationResult<Label>> GetByName(string LabelName, bool doFindIfNotInDatabase = false);
|
||||
|
||||
Task<OperationResult<Label>> PerformMetaDataProvidersLabelSearch(string LabelName);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using Roadie.Library.MetaData.Audio;
|
||||
using Roadie.Library.Data;
|
||||
using Roadie.Library.MetaData.Audio;
|
||||
using Roadie.Library.SearchEngines.MetaData;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -17,8 +18,12 @@ namespace Roadie.Library.Engines
|
|||
IReleaseSearchEngine SpotifyReleaseSearchEngine { get; }
|
||||
IReleaseSearchEngine WikipediaReleaseSearchEngine { get; }
|
||||
|
||||
Task<OperationResult<Data.Release>> GetByName(Data.Artist artist, AudioMetaData metaData, bool doFindIfNotInDatabase = false, bool doAddTracksInDatabase = false, int? submissionId = null);
|
||||
Task<OperationResult<Data.Release>> Add(Data.Release release, bool doAddTracksInDatabase = false);
|
||||
Task<OperationResult<Data.Release>> PerformMetaDataProvidersReleaseSearch(AudioMetaData metaData, string artistFolder = null, int? submissionId = null);
|
||||
Task<OperationResult<Release>> Add(Release release, bool doAddTracksInDatabase = false);
|
||||
|
||||
Task<OperationResult<Release>> GetByName(Artist artist, AudioMetaData metaData,
|
||||
bool doFindIfNotInDatabase = false, bool doAddTracksInDatabase = false, int? submissionId = null);
|
||||
|
||||
Task<OperationResult<Release>> PerformMetaDataProvidersReleaseSearch(AudioMetaData metaData,
|
||||
string artistFolder = null, int? submissionId = null);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MySql.Data.MySqlClient;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Roadie.Library.Caching;
|
||||
using Roadie.Library.Configuration;
|
||||
using Roadie.Library.Data;
|
||||
|
@ -21,10 +19,11 @@ namespace Roadie.Library.Engines
|
|||
{
|
||||
private ILabelSearchEngine DiscogsLabelSearchEngine { get; }
|
||||
|
||||
public LabelLookupEngine(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context, ICacheManager cacheManager, ILogger logger)
|
||||
public LabelLookupEngine(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context,
|
||||
ICacheManager cacheManager, ILogger logger)
|
||||
: base(configuration, httpEncoder, context, cacheManager, logger)
|
||||
{
|
||||
this.DiscogsLabelSearchEngine = new discogs.DiscogsHelper(this.Configuration, this.CacheManager, this.Logger);
|
||||
DiscogsLabelSearchEngine = new discogs.DiscogsHelper(Configuration, CacheManager, Logger);
|
||||
}
|
||||
|
||||
public async Task<OperationResult<Label>> Add(Label label)
|
||||
|
@ -34,29 +33,28 @@ namespace Roadie.Library.Engines
|
|||
try
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
label.AlternateNames = label.AlternateNames.AddToDelimitedList(new string[] { label.Name.ToAlphanumericName() });
|
||||
label.AlternateNames = label.AlternateNames.AddToDelimitedList(new[] { label.Name.ToAlphanumericName() });
|
||||
if (!label.IsValid)
|
||||
{
|
||||
return new OperationResult<Label>
|
||||
{
|
||||
Errors = new Exception[1] { new Exception("Label is Invalid") }
|
||||
};
|
||||
}
|
||||
this.DbContext.Labels.Add(label);
|
||||
int inserted = 0;
|
||||
DbContext.Labels.Add(label);
|
||||
var inserted = 0;
|
||||
try
|
||||
{
|
||||
inserted = await this.DbContext.SaveChangesAsync();
|
||||
inserted = await DbContext.SaveChangesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex);
|
||||
Logger.LogError(ex);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex);
|
||||
Logger.LogError(ex);
|
||||
}
|
||||
|
||||
return new OperationResult<Label>
|
||||
{
|
||||
IsSuccess = label.Id > 0,
|
||||
|
@ -70,9 +68,9 @@ namespace Roadie.Library.Engines
|
|||
{
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
var cacheRegion = (new Label { Name = labelName }).CacheRegion;
|
||||
var cacheRegion = new Label { Name = labelName }.CacheRegion;
|
||||
var cacheKey = string.Format("urn:Label_by_name:{0}", labelName);
|
||||
var resultInCache = this.CacheManager.Get<Label>(cacheKey, cacheRegion);
|
||||
var resultInCache = CacheManager.Get<Label>(cacheKey, cacheRegion);
|
||||
if (resultInCache != null)
|
||||
{
|
||||
sw.Stop();
|
||||
|
@ -83,34 +81,36 @@ namespace Roadie.Library.Engines
|
|||
Data = resultInCache
|
||||
};
|
||||
}
|
||||
|
||||
var searchName = labelName.NormalizeName();
|
||||
var specialSearchName = labelName.ToAlphanumericName();
|
||||
var label = (from l in this.DbContext.Labels
|
||||
where (l.Name.Contains(searchName) ||
|
||||
var label = (from l in DbContext.Labels
|
||||
where l.Name.Contains(searchName) ||
|
||||
l.SortName.Contains(searchName) ||
|
||||
l.AlternateNames.Contains(searchName) ||
|
||||
l.AlternateNames.Contains(specialSearchName))
|
||||
select l
|
||||
).FirstOrDefault();
|
||||
l.AlternateNames.Contains(specialSearchName)
|
||||
select l
|
||||
).FirstOrDefault();
|
||||
sw.Stop();
|
||||
if (label == null || !label.IsValid)
|
||||
{
|
||||
this.Logger.LogInformation("LabelFactory: Label Not Found By Name [{0}]", labelName);
|
||||
Logger.LogInformation("LabelFactory: Label Not Found By Name [{0}]", labelName);
|
||||
if (doFindIfNotInDatabase)
|
||||
{
|
||||
OperationResult<Label> LabelSearch = null;
|
||||
try
|
||||
{
|
||||
LabelSearch = await this.PerformMetaDataProvidersLabelSearch(labelName);
|
||||
LabelSearch = await PerformMetaDataProvidersLabelSearch(labelName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex);
|
||||
Logger.LogError(ex);
|
||||
}
|
||||
|
||||
if (LabelSearch.IsSuccess)
|
||||
{
|
||||
label = LabelSearch.Data;
|
||||
var addResult = await this.Add(label);
|
||||
var addResult = await Add(label);
|
||||
if (!addResult.IsSuccess)
|
||||
{
|
||||
sw.Stop();
|
||||
|
@ -125,8 +125,9 @@ namespace Roadie.Library.Engines
|
|||
}
|
||||
else
|
||||
{
|
||||
this.CacheManager.Add(cacheKey, label);
|
||||
CacheManager.Add(cacheKey, label);
|
||||
}
|
||||
|
||||
return new OperationResult<Label>
|
||||
{
|
||||
IsSuccess = label != null,
|
||||
|
@ -136,8 +137,9 @@ namespace Roadie.Library.Engines
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex);
|
||||
Logger.LogError(ex);
|
||||
}
|
||||
|
||||
return new OperationResult<Label>();
|
||||
}
|
||||
|
||||
|
@ -153,36 +155,28 @@ namespace Roadie.Library.Engines
|
|||
};
|
||||
var resultsExceptions = new List<Exception>();
|
||||
|
||||
if (this.DiscogsLabelSearchEngine.IsEnabled)
|
||||
if (DiscogsLabelSearchEngine.IsEnabled)
|
||||
{
|
||||
var discogsResult = await this.DiscogsLabelSearchEngine.PerformLabelSearch(result.Name, 1);
|
||||
var discogsResult = await DiscogsLabelSearchEngine.PerformLabelSearch(result.Name, 1);
|
||||
if (discogsResult.IsSuccess)
|
||||
{
|
||||
var d = discogsResult.Data.First();
|
||||
if (d.Urls != null)
|
||||
{
|
||||
result.URLs = result.URLs.AddToDelimitedList(d.Urls);
|
||||
}
|
||||
if (d.Urls != null) result.URLs = result.URLs.AddToDelimitedList(d.Urls);
|
||||
if (d.AlternateNames != null)
|
||||
{
|
||||
result.AlternateNames = result.AlternateNames.AddToDelimitedList(d.AlternateNames);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(d.LabelName) && !d.LabelName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result.AlternateNames.AddToDelimitedList(new string[] { d.LabelName });
|
||||
}
|
||||
if (!string.IsNullOrEmpty(d.LabelName) &&
|
||||
!d.LabelName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
|
||||
result.AlternateNames.AddToDelimitedList(new[] { d.LabelName });
|
||||
result.CopyTo(new Label
|
||||
{
|
||||
Profile = this.HttpEncoder.HtmlEncode(d.Profile),
|
||||
Profile = HttpEncoder.HtmlEncode(d.Profile),
|
||||
DiscogsId = d.DiscogsId,
|
||||
Name = result.Name ?? d.LabelName.ToTitleCase(),
|
||||
Thumbnail = d.LabelImageUrl != null ? WebHelper.BytesForImageUrl(d.LabelImageUrl) : null
|
||||
});
|
||||
}
|
||||
if (discogsResult.Errors != null)
|
||||
{
|
||||
resultsExceptions.AddRange(discogsResult.Errors);
|
||||
}
|
||||
|
||||
if (discogsResult.Errors != null) resultsExceptions.AddRange(discogsResult.Errors);
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
|
|
|
@ -3,27 +3,29 @@ using Roadie.Library.Caching;
|
|||
using Roadie.Library.Configuration;
|
||||
using Roadie.Library.Data;
|
||||
using Roadie.Library.Encoding;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Engines
|
||||
{
|
||||
public abstract class LookupEngineBase
|
||||
{
|
||||
protected ICacheManager CacheManager { get; }
|
||||
|
||||
protected IRoadieSettings Configuration { get; }
|
||||
|
||||
protected IRoadieDbContext DbContext { get; }
|
||||
|
||||
protected IHttpEncoder HttpEncoder { get; }
|
||||
|
||||
protected ILogger Logger { get; }
|
||||
|
||||
public LookupEngineBase(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context, ICacheManager cacheManager, ILogger logger)
|
||||
public LookupEngineBase(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context,
|
||||
ICacheManager cacheManager, ILogger logger)
|
||||
{
|
||||
this.Configuration = configuration;
|
||||
this.HttpEncoder = httpEncoder;
|
||||
this.DbContext = context;
|
||||
this.CacheManager = cacheManager;
|
||||
this.Logger = logger;
|
||||
Configuration = configuration;
|
||||
HttpEncoder = httpEncoder;
|
||||
DbContext = context;
|
||||
CacheManager = cacheManager;
|
||||
Logger = logger;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -6,6 +6,6 @@
|
|||
Active,
|
||||
OnHold,
|
||||
SplitUp,
|
||||
Deceased,
|
||||
Deceased
|
||||
}
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Enums
|
||||
namespace Roadie.Library.Enums
|
||||
{
|
||||
public enum CommentReaction
|
||||
{
|
||||
|
@ -10,4 +6,4 @@ namespace Roadie.Library.Enums
|
|||
Dislike,
|
||||
Like
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Enums
|
||||
namespace Roadie.Library.Enums
|
||||
{
|
||||
public enum CommentType
|
||||
{
|
||||
|
@ -15,4 +11,4 @@ namespace Roadie.Library.Enums
|
|||
Release,
|
||||
Track
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Enums
|
||||
namespace Roadie.Library.Enums
|
||||
{
|
||||
public enum ImageType : short
|
||||
{
|
||||
|
@ -14,4 +10,4 @@ namespace Roadie.Library.Enums
|
|||
Label,
|
||||
Track
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
|
||||
namespace Roadie.Library
|
||||
{
|
||||
[Serializable]
|
||||
public class EventMessage
|
||||
public class EventMessage
|
||||
{
|
||||
public Microsoft.Extensions.Logging.LogLevel Level { get; set; } = Microsoft.Extensions.Logging.LogLevel.Trace;
|
||||
public LogLevel Level { get; set; } = LogLevel.Trace;
|
||||
public string Message { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -4,19 +4,13 @@
|
|||
{
|
||||
public static int ComputeHash(this byte[] data)
|
||||
{
|
||||
if (data == null || data.Length == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (data == null || data.Length == 0) return 0;
|
||||
unchecked
|
||||
{
|
||||
const int p = 16777619;
|
||||
int hash = (int)2166136261;
|
||||
var hash = (int)2166136261;
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
hash = (hash ^ data[i]) * p;
|
||||
}
|
||||
for (var i = 0; i < data.Length; i++) hash = (hash ^ data[i]) * p;
|
||||
hash += hash << 13;
|
||||
hash ^= hash >> 7;
|
||||
hash += hash << 3;
|
||||
|
|
|
@ -6,14 +6,8 @@ namespace Roadie.Library.Extensions
|
|||
{
|
||||
public static DateTime? FormatDateTime(this DateTime? value)
|
||||
{
|
||||
if (!value.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (value.Value.Year == 0 || value.Value.Year == 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!value.HasValue) return null;
|
||||
if (value.Value.Year == 0 || value.Value.Year == 1) return null;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -31,10 +25,10 @@ namespace Roadie.Library.Extensions
|
|||
|
||||
public static int ToUnixTimeSinceEpoch(this DateTime dateTime)
|
||||
{
|
||||
DateTime utcDateTime = dateTime.ToUniversalTime();
|
||||
var utcDateTime = dateTime.ToUniversalTime();
|
||||
var jan1St1970 = new DateTime(1970, 1, 1, 0, 0, 0);
|
||||
|
||||
TimeSpan timeSinceJan1St1970 = utcDateTime.Subtract(jan1St1970);
|
||||
var timeSinceJan1St1970 = utcDateTime.Subtract(jan1St1970);
|
||||
return (int)timeSinceJan1St1970.TotalSeconds;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
using Roadie.Library.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Extensions
|
||||
{
|
||||
|
@ -9,20 +7,14 @@ namespace Roadie.Library.Extensions
|
|||
{
|
||||
public static int ToSecondsFromMilliseconds(this decimal? value)
|
||||
{
|
||||
if (value > 0)
|
||||
{
|
||||
return (int)new TimeInfo(value.Value).Seconds;
|
||||
}
|
||||
if (value > 0) return (int)new TimeInfo(value.Value).Seconds;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static TimeSpan? ToTimeSpan(this decimal? value)
|
||||
{
|
||||
if(!value.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!value.HasValue) return null;
|
||||
return TimeSpan.FromSeconds((double)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
namespace Roadie.Library.Extensions
|
||||
{
|
||||
|
@ -6,15 +7,12 @@ namespace Roadie.Library.Extensions
|
|||
{
|
||||
public static string Serialize(this Exception input)
|
||||
{
|
||||
if (input == null)
|
||||
if (input == null) return null;
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var settings = new Newtonsoft.Json.JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
return Newtonsoft.Json.JsonConvert.SerializeObject(input, Newtonsoft.Json.Formatting.Indented, settings);
|
||||
return JsonConvert.SerializeObject(input, Formatting.Indented, settings);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
|
@ -10,40 +9,19 @@ namespace Roadie.Library.Extensions
|
|||
{
|
||||
public static class GenericExt
|
||||
{
|
||||
public static TEntity CopyTo<TEntity>(this TEntity OriginalEntity, TEntity NewEntity)
|
||||
{
|
||||
PropertyInfo[] oProperties = OriginalEntity.GetType().GetProperties();
|
||||
|
||||
foreach (PropertyInfo CurrentProperty in oProperties.Where(p => p.CanWrite))
|
||||
{
|
||||
if (CurrentProperty.GetValue(NewEntity, null) != null)
|
||||
{
|
||||
CurrentProperty.SetValue(OriginalEntity, CurrentProperty.GetValue(NewEntity, null), null);
|
||||
}
|
||||
}
|
||||
|
||||
return OriginalEntity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform a deep Copy of the object using a BinaryFormatter.
|
||||
/// IMPORTANT: the object class must be marked as [Serializable] and have an parameterless constructor.
|
||||
/// Perform a deep Copy of the object using a BinaryFormatter.
|
||||
/// IMPORTANT: the object class must be marked as [Serializable] and have an parameterless constructor.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object being copied.</typeparam>
|
||||
/// <param name="source">The object instance to copy.</param>
|
||||
/// <returns>The copied object.</returns>
|
||||
public static T Clone<T>(this T source)
|
||||
{
|
||||
if (!typeof(T).IsSerializable)
|
||||
{
|
||||
throw new ArgumentException("The type must be serializable.", "source");
|
||||
}
|
||||
if (!typeof(T).IsSerializable) throw new ArgumentException("The type must be serializable.", "source");
|
||||
|
||||
// Don't serialize a null object, simply return the default for that object
|
||||
if (Object.ReferenceEquals(source, null))
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
if (ReferenceEquals(source, null)) return default(T);
|
||||
|
||||
IFormatter formatter = new BinaryFormatter();
|
||||
using (Stream stream = new MemoryStream())
|
||||
|
@ -54,12 +32,23 @@ namespace Roadie.Library.Extensions
|
|||
}
|
||||
}
|
||||
|
||||
public static TEntity CopyTo<TEntity>(this TEntity OriginalEntity, TEntity NewEntity)
|
||||
{
|
||||
var oProperties = OriginalEntity.GetType().GetProperties();
|
||||
|
||||
foreach (var CurrentProperty in oProperties.Where(p => p.CanWrite))
|
||||
if (CurrentProperty.GetValue(NewEntity, null) != null)
|
||||
CurrentProperty.SetValue(OriginalEntity, CurrentProperty.GetValue(NewEntity, null), null);
|
||||
|
||||
return OriginalEntity;
|
||||
}
|
||||
|
||||
public static string DescriptionAttr<T>(this T source)
|
||||
{
|
||||
FieldInfo fi = source.GetType().GetField(source.ToString());
|
||||
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||
var fi = source.GetType().GetField(source.ToString());
|
||||
var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||
if (attributes != null && attributes.Length > 0) return attributes[0].Description;
|
||||
else return source.ToString();
|
||||
return source.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,10 +6,7 @@ namespace Roadie.Library.Extensions
|
|||
{
|
||||
public static int? Or(this int? value, int? alternative)
|
||||
{
|
||||
if (!value.HasValue && !alternative.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!value.HasValue && !alternative.HasValue) return null;
|
||||
return value.HasValue ? value : alternative;
|
||||
}
|
||||
|
||||
|
@ -17,9 +14,10 @@ namespace Roadie.Library.Extensions
|
|||
{
|
||||
if (value > 0)
|
||||
{
|
||||
var contentDurationTimeSpan = TimeSpan.FromMilliseconds((double)(value ?? 0));
|
||||
var contentDurationTimeSpan = TimeSpan.FromMilliseconds(value ?? 0);
|
||||
return (int)contentDurationTimeSpan.TotalSeconds;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,19 +8,19 @@ namespace Roadie.Library.Extensions
|
|||
{
|
||||
public static IEnumerable<T> Randomize<T>(this IEnumerable<T> source)
|
||||
{
|
||||
Random rnd = new Random();
|
||||
return source.OrderBy<T, int>((item) => rnd.Next());
|
||||
var rnd = new Random();
|
||||
return source.OrderBy(item => rnd.Next());
|
||||
}
|
||||
|
||||
public static void Shuffle<T>(this IList<T> list)
|
||||
{
|
||||
int n = list.Count;
|
||||
Random rnd = new Random();
|
||||
var n = list.Count;
|
||||
var rnd = new Random();
|
||||
while (n > 1)
|
||||
{
|
||||
int k = (rnd.Next(0, n) % n);
|
||||
var k = rnd.Next(0, n) % n;
|
||||
n--;
|
||||
T value = list[k];
|
||||
var value = list[k];
|
||||
list[k] = list[n];
|
||||
list[n] = value;
|
||||
}
|
||||
|
@ -33,10 +33,7 @@ namespace Roadie.Library.Extensions
|
|||
|
||||
public static string ToDelimitedList<T>(this IEnumerable<T> list, char delimiter = '|')
|
||||
{
|
||||
if (list == null || !list.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (list == null || !list.Any()) return null;
|
||||
return string.Join(delimiter.ToString(), list);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.Extensions.Logging
|
||||
{
|
||||
|
@ -11,4 +9,4 @@ namespace Microsoft.Extensions.Logging
|
|||
logger.LogError(default(EventId), ex, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using Roadie.Library.Utility;
|
||||
using System;
|
||||
|
||||
namespace Roadie.Library.Extensions
|
||||
{
|
||||
|
@ -7,11 +6,8 @@ namespace Roadie.Library.Extensions
|
|||
{
|
||||
public static string ToFileSize(this long? l)
|
||||
{
|
||||
if (!l.HasValue)
|
||||
{
|
||||
return "0";
|
||||
}
|
||||
return String.Format(new FileSizeFormatProvider(), "{0:fs}", l);
|
||||
if (!l.HasValue) return "0";
|
||||
return string.Format(new FileSizeFormatProvider(), "{0:fs}", l);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,23 +4,14 @@
|
|||
{
|
||||
public static short? Or(this short? value, short? alternative)
|
||||
{
|
||||
if (!value.HasValue && !alternative.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!value.HasValue && !alternative.HasValue) return null;
|
||||
return value.HasValue ? value : alternative;
|
||||
}
|
||||
|
||||
public static short? TakeLarger(this short? value, short? alternative)
|
||||
{
|
||||
if (!value.HasValue && !alternative.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!value.HasValue && alternative.HasValue)
|
||||
{
|
||||
return alternative.Value;
|
||||
}
|
||||
if (!value.HasValue && !alternative.HasValue) return null;
|
||||
if (!value.HasValue && alternative.HasValue) return alternative.Value;
|
||||
return value.Value > alternative.Value ? value.Value : alternative.Value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using HtmlAgilityPack;
|
||||
using Roadie.Library.Configuration;
|
||||
using Roadie.Library.Configuration;
|
||||
using Roadie.Library.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
@ -13,7 +13,8 @@ namespace Roadie.Library.Extensions
|
|||
{
|
||||
public static class StringExt
|
||||
{
|
||||
private static readonly Dictionary<char, string> UnicodeAccents = new Dictionary<char, string>() {
|
||||
private static readonly Dictionary<char, string> UnicodeAccents = new Dictionary<char, string>
|
||||
{
|
||||
{'À', "A"}, {'Á', "A"}, {'Â', "A"}, {'Ã', "A"}, {'Ä', "Ae"}, {'Å', "A"}, {'Æ', "Ae"},
|
||||
{'Ç', "C"},
|
||||
{'È', "E"}, {'É', "E"}, {'Ê', "E"}, {'Ë', "E"},
|
||||
|
@ -35,60 +36,34 @@ namespace Roadie.Library.Extensions
|
|||
{'ý', "y"}, {'ÿ', "y"}
|
||||
};
|
||||
|
||||
|
||||
public static string AddToDelimitedList(this string input, IEnumerable<string> values, char delimiter = '|')
|
||||
{
|
||||
if (string.IsNullOrEmpty(input) && (values == null || !values.Any()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return string.Join(delimiter.ToString(), values);
|
||||
}
|
||||
if (values == null || !values.Any())
|
||||
{
|
||||
return input;
|
||||
}
|
||||
if (string.IsNullOrEmpty(input) && (values == null || !values.Any())) return null;
|
||||
if (string.IsNullOrEmpty(input)) return string.Join(delimiter.ToString(), values);
|
||||
if (values == null || !values.Any()) return input;
|
||||
foreach (var value in values)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (string.IsNullOrEmpty(value)) continue;
|
||||
if (!input.IsValueInDelimitedList(value, delimiter))
|
||||
{
|
||||
if (!input.EndsWith(delimiter.ToString()))
|
||||
{
|
||||
input = input + delimiter;
|
||||
}
|
||||
if (!input.EndsWith(delimiter.ToString())) input = input + delimiter;
|
||||
input = input + value;
|
||||
}
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
public static string CleanString(this string input, IRoadieSettings settings, string removeStringsRegex = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input) || settings == null)
|
||||
{
|
||||
return input;
|
||||
}
|
||||
if (string.IsNullOrEmpty(input) || settings == null) return input;
|
||||
var result = input;
|
||||
foreach (var kvp in settings.Processing.ReplaceStrings.OrderBy(x => x.Order).ThenBy(x => x.Key))
|
||||
{
|
||||
result = result.Replace(kvp.Key, kvp.ReplaceWith, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
result = result.Trim().ToTitleCase(false);
|
||||
if(string.IsNullOrEmpty(result))
|
||||
{
|
||||
return input;
|
||||
}
|
||||
if (string.IsNullOrEmpty(result)) return input;
|
||||
var rs = removeStringsRegex ?? settings.Processing.RemoveStringsRegex;
|
||||
if (!string.IsNullOrEmpty(rs))
|
||||
{
|
||||
result = Regex.Replace(result, rs, "", RegexOptions.IgnoreCase);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(rs)) result = Regex.Replace(result, rs, "", RegexOptions.IgnoreCase);
|
||||
if (result.Length > 5)
|
||||
{
|
||||
var extensionStart = result.Substring(result.Length - 5, 2);
|
||||
|
@ -100,16 +75,14 @@ namespace Roadie.Library.Extensions
|
|||
result = inputSb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
// Strip out any more than single space and remove any blanks before and after
|
||||
return Regex.Replace(result, @"\s+", " ").Trim();
|
||||
}
|
||||
|
||||
public static bool DoesStartWithNumber(this string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (string.IsNullOrEmpty(input)) return false;
|
||||
var firstPart = input.Split(' ').First().SafeReplace("[").SafeReplace("]");
|
||||
return SafeParser.ToNumber<long>(firstPart) > 0;
|
||||
}
|
||||
|
@ -117,47 +90,33 @@ namespace Roadie.Library.Extensions
|
|||
public static string FromHexString(this string hexString)
|
||||
{
|
||||
var bytes = new byte[hexString.Length / 2];
|
||||
for (var i = 0; i < bytes.Length; i++)
|
||||
{
|
||||
bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
|
||||
}
|
||||
for (var i = 0; i < bytes.Length; i++) bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
|
||||
|
||||
return System.Text.Encoding.UTF8.GetString(bytes); // returns: "Hello world" for "48656C6C6F20776F726C64"
|
||||
}
|
||||
|
||||
public static bool IsValidFilename(this string input)
|
||||
{
|
||||
Regex containsABadCharacter = new Regex("[" + Regex.Escape(new string(System.IO.Path.GetInvalidPathChars())) + "]");
|
||||
if (containsABadCharacter.IsMatch(input))
|
||||
{
|
||||
return false;
|
||||
};
|
||||
var containsABadCharacter = new Regex("[" + Regex.Escape(new string(Path.GetInvalidPathChars())) + "]");
|
||||
if (containsABadCharacter.IsMatch(input)) return false;
|
||||
;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsValueInDelimitedList(this string input, string value, char delimiter = '|')
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (string.IsNullOrEmpty(input)) return false;
|
||||
var p = input.Split(delimiter);
|
||||
return !p.Any() ? false : p.Any(x => x.Trim().Equals(value, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
public static string NormalizeName(this string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return input;
|
||||
}
|
||||
if (string.IsNullOrEmpty(input)) return input;
|
||||
input = input.ToLower();
|
||||
var removeParts = new List<string> { " ft. ", " ft ", " feat ", " feat. " };
|
||||
foreach (var removePart in removeParts)
|
||||
{
|
||||
input = input.Replace(removePart, "");
|
||||
}
|
||||
TextInfo cultInfo = new CultureInfo("en-US", false).TextInfo;
|
||||
foreach (var removePart in removeParts) input = input.Replace(removePart, "");
|
||||
var cultInfo = new CultureInfo("en-US", false).TextInfo;
|
||||
return cultInfo.ToTitleCase(input).Trim();
|
||||
}
|
||||
|
||||
|
@ -166,125 +125,67 @@ namespace Roadie.Library.Extensions
|
|||
return string.IsNullOrEmpty(input) ? alternative : input;
|
||||
}
|
||||
|
||||
public static string RemoveDiacritics(this string s)
|
||||
{
|
||||
var normalizedString = s.Normalize(NormalizationForm.FormD);
|
||||
var stringBuilder = new StringBuilder();
|
||||
for (var i = 0; i < normalizedString.Length; i++)
|
||||
{
|
||||
var c = normalizedString[i];
|
||||
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark) stringBuilder.Append(c);
|
||||
}
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
public static string RemoveFirst(this string input, string remove = "")
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return input;
|
||||
}
|
||||
int index = input.IndexOf(remove);
|
||||
return (index < 0)
|
||||
if (string.IsNullOrEmpty(input)) return input;
|
||||
var index = input.IndexOf(remove);
|
||||
return index < 0
|
||||
? input
|
||||
: input.Remove(index, remove.Length).Trim();
|
||||
}
|
||||
|
||||
public static string RemoveStartsWith(this string input, string remove = "")
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return input;
|
||||
}
|
||||
int index = input.IndexOf(remove);
|
||||
string result = input;
|
||||
if (string.IsNullOrEmpty(input)) return input;
|
||||
var index = input.IndexOf(remove);
|
||||
var result = input;
|
||||
while (index == 0)
|
||||
{
|
||||
result = result.Remove(index, remove.Length).Trim();
|
||||
index = result.IndexOf(remove);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string ReplaceLastOccurrence(this string input, string find, string replace = "")
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return input;
|
||||
}
|
||||
int Place = input.LastIndexOf(find);
|
||||
return input.Remove(Place, find.Length).Insert(Place, replace);
|
||||
}
|
||||
|
||||
public static string SafeReplace(this string input, string replace, string replaceWith = " ")
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return input.Replace(replace, replaceWith);
|
||||
}
|
||||
|
||||
public static string StripStartingNumber(this string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (input.DoesStartWithNumber())
|
||||
{
|
||||
return string.Join(" ", input.Split(' ').Skip(1));
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
public static string RemoveUnicodeAccents(this string text)
|
||||
{
|
||||
return text.Aggregate(
|
||||
new StringBuilder(),
|
||||
(sb, c) => {
|
||||
string r;
|
||||
if (UnicodeAccents.TryGetValue(c, out r))
|
||||
{
|
||||
return sb.Append(r);
|
||||
}
|
||||
return sb.Append(c);
|
||||
}).ToString();
|
||||
}
|
||||
|
||||
public static String RemoveDiacritics(this string s)
|
||||
{
|
||||
String normalizedString = s.Normalize(NormalizationForm.FormD);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < normalizedString.Length; i++)
|
||||
{
|
||||
Char c = normalizedString[i];
|
||||
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
|
||||
new StringBuilder(),
|
||||
(sb, c) =>
|
||||
{
|
||||
stringBuilder.Append(c);
|
||||
}
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
string r;
|
||||
if (UnicodeAccents.TryGetValue(c, out r)) return sb.Append(r);
|
||||
return sb.Append(c);
|
||||
}).ToString();
|
||||
}
|
||||
|
||||
public static string Translit(this string str)
|
||||
public static string ReplaceLastOccurrence(this string input, string find, string replace = "")
|
||||
{
|
||||
string[] lat_up = { "A", "B", "V", "G", "D", "E", "Yo", "Zh", "Z", "I", "Y", "K", "L", "M", "N", "O", "P", "R", "S", "T", "U", "F", "Kh", "Ts", "Ch", "Sh", "Shch", "\"", "Y", "'", "E", "Yu", "Ya" };
|
||||
string[] lat_low = { "a", "b", "v", "g", "d", "e", "yo", "zh", "z", "i", "y", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", "kh", "ts", "ch", "sh", "shch", "\"", "y", "'", "e", "yu", "ya" };
|
||||
string[] rus_up = { "А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж", "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ы", "Ь", "Э", "Ю", "Я" };
|
||||
string[] rus_low = { "а", "б", "в", "г", "д", "е", "ё", "ж", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ы", "ь", "э", "ю", "я" };
|
||||
for (int i = 0; i <= 32; i++)
|
||||
{
|
||||
str = str.Replace(rus_up[i], lat_up[i]);
|
||||
str = str.Replace(rus_low[i], lat_low[i]);
|
||||
}
|
||||
return str;
|
||||
if (string.IsNullOrEmpty(input)) return input;
|
||||
var Place = input.LastIndexOf(find);
|
||||
return input.Remove(Place, find.Length).Insert(Place, replace);
|
||||
}
|
||||
|
||||
public static string ToAlphanumericName(this string input)
|
||||
public static string SafeReplace(this string input, string replace, string replaceWith = " ")
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return input;
|
||||
}
|
||||
input = WebUtility.HtmlDecode(input);
|
||||
input = input.ScrubHtml().ToLower().Trim().Replace("&", "and");
|
||||
char[] arr = input.ToCharArray();
|
||||
arr = Array.FindAll<char>(arr, (c => (char.IsLetterOrDigit(c))));
|
||||
input = new string(arr).RemoveDiacritics().RemoveUnicodeAccents().Translit();
|
||||
input = Regex.Replace(input, @"[^A-Za-z0-9]+", "");
|
||||
return input;
|
||||
if (string.IsNullOrEmpty(input)) return null;
|
||||
return input.Replace(replace, replaceWith);
|
||||
}
|
||||
|
||||
|
||||
public static string ScrubHtml(this string value)
|
||||
{
|
||||
var step1 = Regex.Replace(value, @"<[^>]+>| ", "").Trim();
|
||||
|
@ -292,30 +193,40 @@ namespace Roadie.Library.Extensions
|
|||
return step2;
|
||||
}
|
||||
|
||||
public static string StripStartingNumber(this string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input)) return null;
|
||||
if (input.DoesStartWithNumber()) return string.Join(" ", input.Split(' ').Skip(1));
|
||||
return input;
|
||||
}
|
||||
|
||||
public static string ToAlphanumericName(this string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input)) return input;
|
||||
input = WebUtility.HtmlDecode(input);
|
||||
input = input.ScrubHtml().ToLower().Trim().Replace("&", "and");
|
||||
var arr = input.ToCharArray();
|
||||
arr = Array.FindAll(arr, c => char.IsLetterOrDigit(c));
|
||||
input = new string(arr).RemoveDiacritics().RemoveUnicodeAccents().Translit();
|
||||
input = Regex.Replace(input, @"[^A-Za-z0-9]+", "");
|
||||
return input;
|
||||
}
|
||||
|
||||
public static string ToContentDispositionFriendly(this string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(input)) return null;
|
||||
return input.Replace(',', ' ');
|
||||
}
|
||||
|
||||
public static string ToFileNameFriendly(this string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(input)) return null;
|
||||
return Regex.Replace(PathSanitizer.SanitizeFilename(input, ' '), @"\s+", " ").Trim();
|
||||
}
|
||||
|
||||
public static string ToFolderNameFriendly(this string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(input)) return null;
|
||||
return Regex.Replace(PathSanitizer.SanitizeFilename(input, ' '), @"\s+", " ").Trim().TrimEnd('.');
|
||||
}
|
||||
|
||||
|
@ -324,86 +235,90 @@ namespace Roadie.Library.Extensions
|
|||
var sb = new StringBuilder();
|
||||
|
||||
var bytes = System.Text.Encoding.UTF8.GetBytes(str);
|
||||
foreach (var t in bytes)
|
||||
{
|
||||
sb.Append(t.ToString("X2"));
|
||||
}
|
||||
foreach (var t in bytes) sb.Append(t.ToString("X2"));
|
||||
|
||||
return sb.ToString(); // returns: "48656C6C6F20776F726C64" for "Hello world"
|
||||
}
|
||||
|
||||
public static IEnumerable<string> ToListFromDelimited(this string input, char delimiter = '|')
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return new string[0];
|
||||
}
|
||||
if (string.IsNullOrEmpty(input)) return new string[0];
|
||||
return input.Split(delimiter);
|
||||
}
|
||||
|
||||
|
||||
public static string ToTitleCase(this string input, bool doPutTheAtEnd = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
|
||||
if (string.IsNullOrEmpty(input)) return null;
|
||||
var textInfo = new CultureInfo("en-US", false).TextInfo;
|
||||
var r = textInfo.ToTitleCase(input.Trim().ToLower());
|
||||
r = Regex.Replace(r, @"\s+", " ");
|
||||
if (doPutTheAtEnd)
|
||||
{
|
||||
if (r.StartsWith("The "))
|
||||
{
|
||||
return r.Replace("The ", "") + ", The";
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public static int? ToTrackDuration(this string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(input.Replace(":", "")))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(input.Replace(":", ""))) return null;
|
||||
try
|
||||
{
|
||||
var parts = input.Contains(":") ? input.Split(':').ToList() : new List<string> { input };
|
||||
while (parts.Count() < 3)
|
||||
{
|
||||
parts.Insert(0, "00:");
|
||||
}
|
||||
while (parts.Count() < 3) parts.Insert(0, "00:");
|
||||
var tsRaw = string.Empty;
|
||||
foreach (var part in parts)
|
||||
{
|
||||
if (tsRaw.Length > 0)
|
||||
{
|
||||
tsRaw += ":";
|
||||
}
|
||||
if (tsRaw.Length > 0) tsRaw += ":";
|
||||
tsRaw += part.PadLeft(2, '0').Substring(0, 2);
|
||||
}
|
||||
TimeSpan ts = TimeSpan.MinValue;
|
||||
|
||||
var ts = TimeSpan.MinValue;
|
||||
var success = TimeSpan.TryParse(tsRaw, out ts);
|
||||
if (success)
|
||||
{
|
||||
return (int?)ts.TotalMilliseconds;
|
||||
}
|
||||
if (success) return (int?)ts.TotalMilliseconds;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string Translit(this string str)
|
||||
{
|
||||
string[] lat_up =
|
||||
{
|
||||
"A", "B", "V", "G", "D", "E", "Yo", "Zh", "Z", "I", "Y", "K", "L", "M", "N", "O", "P", "R", "S", "T",
|
||||
"U", "F", "Kh", "Ts", "Ch", "Sh", "Shch", "\"", "Y", "'", "E", "Yu", "Ya"
|
||||
};
|
||||
string[] lat_low =
|
||||
{
|
||||
"a", "b", "v", "g", "d", "e", "yo", "zh", "z", "i", "y", "k", "l", "m", "n", "o", "p", "r", "s", "t",
|
||||
"u", "f", "kh", "ts", "ch", "sh", "shch", "\"", "y", "'", "e", "yu", "ya"
|
||||
};
|
||||
string[] rus_up =
|
||||
{
|
||||
"А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж", "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У",
|
||||
"Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ы", "Ь", "Э", "Ю", "Я"
|
||||
};
|
||||
string[] rus_low =
|
||||
{
|
||||
"а", "б", "в", "г", "д", "е", "ё", "ж", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у",
|
||||
"ф", "х", "ц", "ч", "ш", "щ", "ъ", "ы", "ь", "э", "ю", "я"
|
||||
};
|
||||
for (var i = 0; i <= 32; i++)
|
||||
{
|
||||
str = str.Replace(rus_up[i], lat_up[i]);
|
||||
str = str.Replace(rus_low[i], lat_low[i]);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
public static string TrimEnd(this string input, string suffixToRemove)
|
||||
{
|
||||
if (input != null && suffixToRemove != null && input.EndsWith(suffixToRemove))
|
||||
{
|
||||
return input.Substring(0, input.Length - suffixToRemove.Length);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Roadie.Library.Extensions
|
||||
{
|
||||
|
@ -8,11 +6,8 @@ namespace Roadie.Library.Extensions
|
|||
{
|
||||
public static string ToDuration(this TimeSpan input)
|
||||
{
|
||||
if(input == null || input.TotalMilliseconds == 0)
|
||||
{
|
||||
return "--/--/--";
|
||||
}
|
||||
if (input == null || input.TotalMilliseconds == 0) return "--/--/--";
|
||||
return input.ToString(@"ddd\.hh\:mm\:ss");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,6 @@ using Roadie.Library.Enums;
|
|||
using Roadie.Library.Extensions;
|
||||
using Roadie.Library.Imaging;
|
||||
using Roadie.Library.MetaData.Audio;
|
||||
using Roadie.Library.MetaData.ID3Tags;
|
||||
using Roadie.Library.Processors;
|
||||
using Roadie.Library.Utility;
|
||||
using System;
|
||||
|
@ -25,37 +24,30 @@ namespace Roadie.Library.Factories
|
|||
|
||||
public sealed class ArtistFactory : FactoryBase, IArtistFactory
|
||||
{
|
||||
private List<int> _addedArtistIds = new List<int>();
|
||||
private readonly List<int> _addedArtistIds = new List<int>();
|
||||
|
||||
public IEnumerable<int> AddedArtistIds
|
||||
public ArtistFactory(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context,
|
||||
ICacheManager cacheManager, ILogger logger, IArtistLookupEngine artistLookupEngine,
|
||||
IReleaseFactory releaseFactory, IImageFactory imageFactory, IReleaseLookupEngine releaseLookupEngine,
|
||||
IAudioMetaDataHelper audioMetaDataHelper)
|
||||
: base(configuration, context, cacheManager, logger, httpEncoder, artistLookupEngine, releaseLookupEngine)
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._addedArtistIds;
|
||||
}
|
||||
ReleaseFactory = releaseFactory;
|
||||
ImageFactory = imageFactory;
|
||||
AudioMetaDataHelper = audioMetaDataHelper;
|
||||
}
|
||||
|
||||
public IEnumerable<int> AddedArtistIds => _addedArtistIds;
|
||||
|
||||
private IReleaseFactory ReleaseFactory { get; }
|
||||
private IImageFactory ImageFactory { get; }
|
||||
private IAudioMetaDataHelper AudioMetaDataHelper { get; }
|
||||
|
||||
public ArtistFactory(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context,
|
||||
ICacheManager cacheManager, ILogger logger, IArtistLookupEngine artistLookupEngine, IReleaseFactory releaseFactory, IImageFactory imageFactory, IReleaseLookupEngine releaseLookupEngine, IAudioMetaDataHelper audioMetaDataHelper)
|
||||
: base(configuration, context, cacheManager, logger, httpEncoder, artistLookupEngine, releaseLookupEngine)
|
||||
{
|
||||
this.ReleaseFactory = releaseFactory;
|
||||
this.ImageFactory = imageFactory;
|
||||
this.AudioMetaDataHelper = audioMetaDataHelper;
|
||||
}
|
||||
|
||||
public async Task<OperationResult<bool>> Delete(Guid RoadieId)
|
||||
{
|
||||
var isSuccess = false;
|
||||
var Artist = this.DbContext.Artists.FirstOrDefault(x => x.RoadieId == RoadieId);
|
||||
if (Artist != null)
|
||||
{
|
||||
return await this.Delete(Artist);
|
||||
}
|
||||
var Artist = DbContext.Artists.FirstOrDefault(x => x.RoadieId == RoadieId);
|
||||
if (Artist != null) return await Delete(Artist);
|
||||
return new OperationResult<bool>
|
||||
{
|
||||
Data = isSuccess
|
||||
|
@ -69,21 +61,22 @@ namespace Roadie.Library.Factories
|
|||
{
|
||||
if (Artist != null)
|
||||
{
|
||||
this.DbContext.Artists.Remove(Artist);
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
this.CacheManager.ClearRegion(Artist.CacheRegion);
|
||||
this.Logger.LogInformation(string.Format("x DeleteArtist [{0}]", Artist.Id));
|
||||
DbContext.Artists.Remove(Artist);
|
||||
await DbContext.SaveChangesAsync();
|
||||
CacheManager.ClearRegion(Artist.CacheRegion);
|
||||
Logger.LogInformation(string.Format("x DeleteArtist [{0}]", Artist.Id));
|
||||
isSuccess = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, ex.Serialize());
|
||||
Logger.LogError(ex, ex.Serialize());
|
||||
return new OperationResult<bool>
|
||||
{
|
||||
Errors = new Exception[1] { ex }
|
||||
};
|
||||
}
|
||||
|
||||
return new OperationResult<bool>
|
||||
{
|
||||
IsSuccess = isSuccess,
|
||||
|
@ -91,21 +84,22 @@ namespace Roadie.Library.Factories
|
|||
};
|
||||
}
|
||||
|
||||
public OperationResult<Artist> GetByExternalIds(string musicBrainzId = null, string iTunesId = null, string amgId = null, string spotifyId = null)
|
||||
public OperationResult<Artist> GetByExternalIds(string musicBrainzId = null, string iTunesId = null,
|
||||
string amgId = null, string spotifyId = null)
|
||||
{
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
var Artist = (from a in this.DbContext.Artists
|
||||
where ((a.MusicBrainzId != null && (musicBrainzId != null && a.MusicBrainzId == musicBrainzId)) ||
|
||||
(a.ITunesId != null || (iTunesId != null && a.ITunesId == iTunesId)) ||
|
||||
(a.AmgId != null || (amgId != null && a.AmgId == amgId)) ||
|
||||
(a.SpotifyId != null || (spotifyId != null && a.SpotifyId == spotifyId)))
|
||||
var Artist = (from a in DbContext.Artists
|
||||
where a.MusicBrainzId != null && musicBrainzId != null && a.MusicBrainzId == musicBrainzId ||
|
||||
a.ITunesId != null || iTunesId != null && a.ITunesId == iTunesId || a.AmgId != null ||
|
||||
amgId != null && a.AmgId == amgId || a.SpotifyId != null ||
|
||||
spotifyId != null && a.SpotifyId == spotifyId
|
||||
select a).FirstOrDefault();
|
||||
sw.Stop();
|
||||
if (Artist == null || !Artist.IsValid)
|
||||
{
|
||||
this.Logger.LogTrace("ArtistFactory: Artist Not Found By External Ids: MusicbrainzId [{0}], iTunesIs [{1}], AmgId [{2}], SpotifyId [{3}]", musicBrainzId, iTunesId, amgId, spotifyId);
|
||||
}
|
||||
Logger.LogTrace(
|
||||
"ArtistFactory: Artist Not Found By External Ids: MusicbrainzId [{0}], iTunesIs [{1}], AmgId [{2}], SpotifyId [{3}]",
|
||||
musicBrainzId, iTunesId, amgId, spotifyId);
|
||||
return new OperationResult<Artist>
|
||||
{
|
||||
IsSuccess = Artist != null,
|
||||
|
@ -115,12 +109,13 @@ namespace Roadie.Library.Factories
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merge one Artist into another one
|
||||
/// Merge one Artist into another one
|
||||
/// </summary>
|
||||
/// <param name="ArtistToMerge">The Artist to be merged</param>
|
||||
/// <param name="artistToMergeInto">The Artist to merge into</param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperationResult<Artist>> MergeArtists(Artist ArtistToMerge, Artist artistToMergeInto, bool doDbUpdates = false)
|
||||
public async Task<OperationResult<Artist>> MergeArtists(Artist ArtistToMerge, Artist artistToMergeInto,
|
||||
bool doDbUpdates = false)
|
||||
{
|
||||
SimpleContract.Requires<ArgumentNullException>(ArtistToMerge != null, "Invalid Artist");
|
||||
SimpleContract.Requires<ArgumentNullException>(artistToMergeInto != null, "Invalid Artist");
|
||||
|
@ -141,52 +136,61 @@ namespace Roadie.Library.Factories
|
|||
artistToMergeInto.BirthDate = ArtistToMerge.BirthDate ?? artistToMergeInto.BirthDate;
|
||||
artistToMergeInto.BeginDate = ArtistToMerge.BeginDate ?? artistToMergeInto.BeginDate;
|
||||
artistToMergeInto.EndDate = ArtistToMerge.EndDate ?? artistToMergeInto.EndDate;
|
||||
if (!string.IsNullOrEmpty(ArtistToMerge.ArtistType) && !ArtistToMerge.ArtistType.Equals("Other", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ArtistToMerge.ArtistType) &&
|
||||
!ArtistToMerge.ArtistType.Equals("Other", StringComparison.OrdinalIgnoreCase))
|
||||
artistToMergeInto.ArtistType = ArtistToMerge.ArtistType;
|
||||
}
|
||||
artistToMergeInto.BioContext = ArtistToMerge.BioContext ?? artistToMergeInto.BioContext;
|
||||
artistToMergeInto.DiscogsId = ArtistToMerge.DiscogsId ?? artistToMergeInto.DiscogsId;
|
||||
|
||||
artistToMergeInto.Tags = artistToMergeInto.Tags.AddToDelimitedList(ArtistToMerge.Tags.ToListFromDelimited());
|
||||
artistToMergeInto.Tags =
|
||||
artistToMergeInto.Tags.AddToDelimitedList(ArtistToMerge.Tags.ToListFromDelimited());
|
||||
var altNames = ArtistToMerge.AlternateNames.ToListFromDelimited().ToList();
|
||||
altNames.Add(ArtistToMerge.Name);
|
||||
altNames.Add(ArtistToMerge.SortName);
|
||||
artistToMergeInto.AlternateNames = artistToMergeInto.AlternateNames.AddToDelimitedList(altNames);
|
||||
artistToMergeInto.URLs = artistToMergeInto.URLs.AddToDelimitedList(ArtistToMerge.URLs.ToListFromDelimited());
|
||||
artistToMergeInto.ISNI = artistToMergeInto.ISNI.AddToDelimitedList(ArtistToMerge.ISNI.ToListFromDelimited());
|
||||
artistToMergeInto.URLs =
|
||||
artistToMergeInto.URLs.AddToDelimitedList(ArtistToMerge.URLs.ToListFromDelimited());
|
||||
artistToMergeInto.ISNI =
|
||||
artistToMergeInto.ISNI.AddToDelimitedList(ArtistToMerge.ISNI.ToListFromDelimited());
|
||||
artistToMergeInto.LastUpdated = now;
|
||||
|
||||
if (doDbUpdates)
|
||||
{
|
||||
string sql = null;
|
||||
|
||||
sql = "UPDATE `artistGenreTable` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + ArtistToMerge.Id + ";";
|
||||
await this.DbContext.Database.ExecuteSqlCommandAsync(sql);
|
||||
sql = "UPDATE `image` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + ArtistToMerge.Id + ";";
|
||||
await this.DbContext.Database.ExecuteSqlCommandAsync(sql);
|
||||
sql = "UPDATE `userartist` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + ArtistToMerge.Id + ";";
|
||||
await this.DbContext.Database.ExecuteSqlCommandAsync(sql);
|
||||
sql = "UPDATE `track` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + ArtistToMerge.Id + ";";
|
||||
await this.DbContext.Database.ExecuteSqlCommandAsync(sql);
|
||||
sql = "UPDATE `artistGenreTable` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " +
|
||||
ArtistToMerge.Id + ";";
|
||||
await DbContext.Database.ExecuteSqlCommandAsync(sql);
|
||||
sql = "UPDATE `image` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " +
|
||||
ArtistToMerge.Id + ";";
|
||||
await DbContext.Database.ExecuteSqlCommandAsync(sql);
|
||||
sql = "UPDATE `userartist` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " +
|
||||
ArtistToMerge.Id + ";";
|
||||
await DbContext.Database.ExecuteSqlCommandAsync(sql);
|
||||
sql = "UPDATE `track` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " +
|
||||
ArtistToMerge.Id + ";";
|
||||
await DbContext.Database.ExecuteSqlCommandAsync(sql);
|
||||
|
||||
try
|
||||
{
|
||||
sql = "UPDATE `release` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + ArtistToMerge.Id + ";";
|
||||
await this.DbContext.Database.ExecuteSqlCommandAsync(sql);
|
||||
sql = "UPDATE `release` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " +
|
||||
ArtistToMerge.Id + ";";
|
||||
await DbContext.Database.ExecuteSqlCommandAsync(sql);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogWarning(ex.ToString());
|
||||
}
|
||||
var artistFolder = ArtistToMerge.ArtistFileFolder(this.Configuration, this.Configuration.LibraryFolder);
|
||||
foreach (var release in this.DbContext.Releases.Include("Artist").Where(x => x.ArtistId == ArtistToMerge.Id).ToArray())
|
||||
{
|
||||
var originalReleaseFolder = release.ReleaseFileFolder(artistFolder);
|
||||
await this.ReleaseFactory.Update(release, null, originalReleaseFolder);
|
||||
Logger.LogWarning(ex.ToString());
|
||||
}
|
||||
|
||||
await this.Delete(ArtistToMerge);
|
||||
var artistFolder = ArtistToMerge.ArtistFileFolder(Configuration, Configuration.LibraryFolder);
|
||||
foreach (var release in DbContext.Releases.Include("Artist").Where(x => x.ArtistId == ArtistToMerge.Id)
|
||||
.ToArray())
|
||||
{
|
||||
var originalReleaseFolder = release.ReleaseFileFolder(artistFolder);
|
||||
await ReleaseFactory.Update(release, null, originalReleaseFolder);
|
||||
}
|
||||
|
||||
await Delete(ArtistToMerge);
|
||||
}
|
||||
|
||||
result = true;
|
||||
|
@ -201,7 +205,7 @@ namespace Roadie.Library.Factories
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform a Metadata Provider search and then merge the results into the given Artist
|
||||
/// Perform a Metadata Provider search and then merge the results into the given Artist
|
||||
/// </summary>
|
||||
/// <param name="ArtistId">Given Artist RoadieId</param>
|
||||
/// <returns>Operation Result</returns>
|
||||
|
@ -215,36 +219,38 @@ namespace Roadie.Library.Factories
|
|||
sw.Start();
|
||||
try
|
||||
{
|
||||
var Artist = this.DbContext.Artists.FirstOrDefault(x => x.RoadieId == ArtistId);
|
||||
var Artist = DbContext.Artists.FirstOrDefault(x => x.RoadieId == ArtistId);
|
||||
if (Artist == null)
|
||||
{
|
||||
this.Logger.LogWarning("Unable To Find Artist [{0}]", ArtistId);
|
||||
Logger.LogWarning("Unable To Find Artist [{0}]", ArtistId);
|
||||
return new OperationResult<bool>();
|
||||
}
|
||||
|
||||
OperationResult<Artist> ArtistSearch = null;
|
||||
try
|
||||
{
|
||||
ArtistSearch = await this.ArtistLookupEngine.PerformMetaDataProvidersArtistSearch(new AudioMetaData
|
||||
ArtistSearch = await ArtistLookupEngine.PerformMetaDataProvidersArtistSearch(new AudioMetaData
|
||||
{
|
||||
Artist = Artist.Name
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, ex.Serialize());
|
||||
Logger.LogError(ex, ex.Serialize());
|
||||
}
|
||||
|
||||
if (ArtistSearch.IsSuccess)
|
||||
{
|
||||
// Do metadata search for Artist like if new Artist then set some overides and merge
|
||||
var mergeResult = await this.MergeArtists(ArtistSearch.Data, Artist);
|
||||
var mergeResult = await MergeArtists(ArtistSearch.Data, Artist);
|
||||
if (mergeResult.IsSuccess)
|
||||
{
|
||||
Artist = mergeResult.Data;
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
await DbContext.SaveChangesAsync();
|
||||
sw.Stop();
|
||||
this.CacheManager.ClearRegion(Artist.CacheRegion);
|
||||
this.Logger.LogInformation("Scanned RefreshArtistMetadata [{0}], OperationTime [{1}]", Artist.ToString(), sw.ElapsedMilliseconds);
|
||||
CacheManager.ClearRegion(Artist.CacheRegion);
|
||||
Logger.LogInformation("Scanned RefreshArtistMetadata [{0}], OperationTime [{1}]",
|
||||
Artist.ToString(), sw.ElapsedMilliseconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -254,9 +260,10 @@ namespace Roadie.Library.Factories
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, ex.Serialize());
|
||||
Logger.LogError(ex, ex.Serialize());
|
||||
resultErrors.Add(ex);
|
||||
}
|
||||
|
||||
return new OperationResult<bool>
|
||||
{
|
||||
Data = result,
|
||||
|
@ -267,7 +274,8 @@ namespace Roadie.Library.Factories
|
|||
}
|
||||
|
||||
[Obsolete]
|
||||
public async Task<OperationResult<bool>> ScanArtistReleasesFolders(Guid artistId, string destinationFolder, bool doJustInfo)
|
||||
public async Task<OperationResult<bool>> ScanArtistReleasesFolders(Guid artistId, string destinationFolder,
|
||||
bool doJustInfo)
|
||||
{
|
||||
SimpleContract.Requires<ArgumentOutOfRangeException>(artistId != Guid.Empty, "Invalid ArtistId");
|
||||
|
||||
|
@ -277,49 +285,45 @@ namespace Roadie.Library.Factories
|
|||
sw.Start();
|
||||
try
|
||||
{
|
||||
var artist = this.DbContext.Artists
|
||||
.Include("Releases")
|
||||
.Include("Releases.Labels")
|
||||
.FirstOrDefault(x => x.RoadieId == artistId);
|
||||
var artist = DbContext.Artists
|
||||
.Include("Releases")
|
||||
.Include("Releases.Labels")
|
||||
.FirstOrDefault(x => x.RoadieId == artistId);
|
||||
if (artist == null)
|
||||
{
|
||||
this.Logger.LogWarning("Unable To Find Artist [{0}]", artistId);
|
||||
Logger.LogWarning("Unable To Find Artist [{0}]", artistId);
|
||||
return new OperationResult<bool>();
|
||||
}
|
||||
|
||||
var releaseScannedCount = 0;
|
||||
var artistFolder = artist.ArtistFileFolder(this.Configuration, destinationFolder);
|
||||
var artistFolder = artist.ArtistFileFolder(Configuration, destinationFolder);
|
||||
var scannedArtistFolders = new List<string>();
|
||||
// Scan known releases for changes
|
||||
if (artist.Releases != null)
|
||||
{
|
||||
foreach (var release in artist.Releases)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = result && (await this.ReleaseFactory.ScanReleaseFolder(Guid.Empty, destinationFolder, doJustInfo, release)).Data;
|
||||
result = result && (await ReleaseFactory.ScanReleaseFolder(Guid.Empty, destinationFolder,
|
||||
doJustInfo, release)).Data;
|
||||
releaseScannedCount++;
|
||||
scannedArtistFolders.Add(release.ReleaseFileFolder(artistFolder));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, ex.Serialize());
|
||||
Logger.LogError(ex, ex.Serialize());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Any folder found in Artist folder not already scanned scan
|
||||
var folderProcessor = new FolderProcessor(this.Configuration, this.HttpEncoder, destinationFolder, this.DbContext, this.CacheManager, this.Logger, this.ArtistLookupEngine, this, this.ReleaseFactory, this.ImageFactory, this.ReleaseLookupEngine, this.AudioMetaDataHelper);
|
||||
var nonReleaseFolders = (from d in Directory.EnumerateDirectories(artistFolder)
|
||||
where !(from r in scannedArtistFolders select r).Contains(d)
|
||||
orderby d
|
||||
select d);
|
||||
var folderProcessor = new FolderProcessor(Configuration, HttpEncoder, destinationFolder, DbContext,
|
||||
CacheManager, Logger, ArtistLookupEngine, this, ReleaseFactory, ImageFactory, ReleaseLookupEngine,
|
||||
AudioMetaDataHelper);
|
||||
var nonReleaseFolders = from d in Directory.EnumerateDirectories(artistFolder)
|
||||
where !(from r in scannedArtistFolders select r).Contains(d)
|
||||
orderby d
|
||||
select d;
|
||||
foreach (var folder in nonReleaseFolders)
|
||||
{
|
||||
await folderProcessor.Process(new DirectoryInfo(folder), doJustInfo);
|
||||
}
|
||||
if (!doJustInfo)
|
||||
{
|
||||
FolderProcessor.DeleteEmptyFolders(new DirectoryInfo(artistFolder), this.Logger);
|
||||
}
|
||||
if (!doJustInfo) FolderProcessor.DeleteEmptyFolders(new DirectoryInfo(artistFolder), Logger);
|
||||
|
||||
// Always update artist image if artist image is found on an artist rescan
|
||||
var imageFiles = ImageHelper.ImageFilesInFolder(artistFolder, SearchOption.AllDirectories);
|
||||
|
@ -333,29 +337,34 @@ namespace Roadie.Library.Factories
|
|||
{
|
||||
// Read image and convert to jpeg
|
||||
artist.Thumbnail = File.ReadAllBytes(i.FullName);
|
||||
artist.Thumbnail = ImageHelper.ResizeImage(artist.Thumbnail, this.Configuration.MediumImageSize.Width, this.Configuration.MediumImageSize.Height);
|
||||
artist.Thumbnail = ImageHelper.ResizeImage(artist.Thumbnail,
|
||||
Configuration.MediumImageSize.Width, Configuration.MediumImageSize.Height);
|
||||
artist.Thumbnail = ImageHelper.ConvertToJpegFormat(artist.Thumbnail);
|
||||
if (artist.Thumbnail.Length >= ImageHelper.MaximumThumbnailByteSize)
|
||||
{
|
||||
Logger.LogWarning($"Artist Thumbnail larger than maximum size after resizing to [{ this.Configuration.ThumbnailImageSize.Width }x{ this.Configuration.ThumbnailImageSize.Height}] Thumbnail Size [{ artist.Thumbnail.Length }]");
|
||||
Logger.LogWarning(
|
||||
$"Artist Thumbnail larger than maximum size after resizing to [{Configuration.ThumbnailImageSize.Width}x{Configuration.ThumbnailImageSize.Height}] Thumbnail Size [{artist.Thumbnail.Length}]");
|
||||
artist.Thumbnail = null;
|
||||
}
|
||||
|
||||
artist.LastUpdated = DateTime.UtcNow;
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
this.CacheManager.ClearRegion(artist.CacheRegion);
|
||||
this.Logger.LogInformation("Update Thumbnail using Artist File [{0}]", iName);
|
||||
await DbContext.SaveChangesAsync();
|
||||
CacheManager.ClearRegion(artist.CacheRegion);
|
||||
Logger.LogInformation("Update Thumbnail using Artist File [{0}]", iName);
|
||||
}
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
this.CacheManager.ClearRegion(artist.CacheRegion);
|
||||
this.Logger.LogInformation("Scanned Artist [{0}], Releases Scanned [{1}], OperationTime [{2}]", artist.ToString(), releaseScannedCount, sw.ElapsedMilliseconds);
|
||||
CacheManager.ClearRegion(artist.CacheRegion);
|
||||
Logger.LogInformation("Scanned Artist [{0}], Releases Scanned [{1}], OperationTime [{2}]",
|
||||
artist.ToString(), releaseScannedCount, sw.ElapsedMilliseconds);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, ex.Serialize());
|
||||
Logger.LogError(ex, ex.Serialize());
|
||||
resultErrors.Add(ex);
|
||||
}
|
||||
|
||||
return new OperationResult<bool>
|
||||
{
|
||||
Data = result,
|
||||
|
@ -366,69 +375,71 @@ namespace Roadie.Library.Factories
|
|||
}
|
||||
|
||||
[Obsolete]
|
||||
public async Task<OperationResult<Artist>> Update(Artist Artist, IEnumerable<Image> ArtistImages, string destinationFolder = null)
|
||||
public async Task<OperationResult<Artist>> Update(Artist Artist, IEnumerable<Image> ArtistImages,
|
||||
string destinationFolder = null)
|
||||
{
|
||||
SimpleContract.Requires<ArgumentNullException>(Artist != null, "Invalid Artist");
|
||||
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
var artistGenreTables = Artist.Genres.Select(x => new ArtistGenre { ArtistId = Artist.Id, GenreId = x.GenreId }).ToList();
|
||||
var artistAssociatedWith = Artist.AssociatedArtists.Select(x => new ArtistAssociation { ArtistId = Artist.Id, AssociatedArtistId = x.AssociatedArtistId }).ToList();
|
||||
var similarArtists = Artist.SimilarArtists.Select(x => new ArtistSimilar { ArtistId = Artist.Id, SimilarArtistId = x.SimilarArtistId }).ToList();
|
||||
var artistGenreTables = Artist.Genres
|
||||
.Select(x => new ArtistGenre { ArtistId = Artist.Id, GenreId = x.GenreId }).ToList();
|
||||
var artistAssociatedWith = Artist.AssociatedArtists.Select(x => new ArtistAssociation
|
||||
{ ArtistId = Artist.Id, AssociatedArtistId = x.AssociatedArtistId }).ToList();
|
||||
var similarArtists = Artist.SimilarArtists.Select(x => new ArtistSimilar
|
||||
{ ArtistId = Artist.Id, SimilarArtistId = x.SimilarArtistId }).ToList();
|
||||
var result = true;
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
var originalArtistFolder = Artist.ArtistFileFolder(this.Configuration, destinationFolder ?? this.Configuration.LibraryFolder);
|
||||
var originalArtistFolder =
|
||||
Artist.ArtistFileFolder(Configuration, destinationFolder ?? Configuration.LibraryFolder);
|
||||
var originalName = Artist.Name;
|
||||
var originalSortName = Artist.SortName;
|
||||
|
||||
Artist.LastUpdated = now;
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
await DbContext.SaveChangesAsync();
|
||||
|
||||
this.DbContext.ArtistGenres.RemoveRange((from at in this.DbContext.ArtistGenres
|
||||
where at.ArtistId == Artist.Id
|
||||
select at));
|
||||
DbContext.ArtistGenres.RemoveRange(from at in DbContext.ArtistGenres
|
||||
where at.ArtistId == Artist.Id
|
||||
select at);
|
||||
Artist.Genres = artistGenreTables;
|
||||
this.DbContext.ArtistAssociations.RemoveRange((from at in this.DbContext.ArtistAssociations
|
||||
where at.ArtistId == Artist.Id
|
||||
select at));
|
||||
DbContext.ArtistAssociations.RemoveRange(from at in DbContext.ArtistAssociations
|
||||
where at.ArtistId == Artist.Id
|
||||
select at);
|
||||
Artist.AssociatedArtists = artistAssociatedWith;
|
||||
Artist.SimilarArtists = similarArtists;
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
await DbContext.SaveChangesAsync();
|
||||
|
||||
var existingImageIds = (from ai in ArtistImages
|
||||
where ai.Status != Statuses.New
|
||||
select ai.RoadieId).ToArray();
|
||||
this.DbContext.Images.RemoveRange((from i in this.DbContext.Images
|
||||
where i.ArtistId == Artist.Id
|
||||
where !(from x in existingImageIds select x).Contains(i.RoadieId)
|
||||
select i));
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
DbContext.Images.RemoveRange(from i in DbContext.Images
|
||||
where i.ArtistId == Artist.Id
|
||||
where !(from x in existingImageIds select x).Contains(i.RoadieId)
|
||||
select i);
|
||||
await DbContext.SaveChangesAsync();
|
||||
if (ArtistImages != null && ArtistImages.Any(x => x.Status == Statuses.New))
|
||||
{
|
||||
foreach (var ArtistImage in ArtistImages.Where(x => x.Status == Statuses.New))
|
||||
{
|
||||
this.DbContext.Images.Add(ArtistImage);
|
||||
}
|
||||
DbContext.Images.Add(ArtistImage);
|
||||
try
|
||||
{
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
await DbContext.SaveChangesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, ex.Serialize());
|
||||
Logger.LogError(ex, ex.Serialize());
|
||||
}
|
||||
}
|
||||
|
||||
var newArtistFolder = Artist.ArtistFileFolder(this.Configuration, destinationFolder ?? this.Configuration.LibraryFolder);
|
||||
var newArtistFolder =
|
||||
Artist.ArtistFileFolder(Configuration, destinationFolder ?? Configuration.LibraryFolder);
|
||||
if (!originalArtistFolder.Equals(newArtistFolder, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
this.Logger.LogTrace("Moving Artist From Folder [{0}] To [{1}]", originalArtistFolder, newArtistFolder);
|
||||
// Directory.Move(originalArtistFolder, Artist.ArtistFileFolder(destinationFolder ?? SettingsHelper.Instance.LibraryFolder));
|
||||
// TODO if name changed then update Artist track files to have new Artist name
|
||||
}
|
||||
this.CacheManager.ClearRegion(Artist.CacheRegion);
|
||||
Logger.LogTrace("Moving Artist From Folder [{0}] To [{1}]", originalArtistFolder, newArtistFolder);
|
||||
// Directory.Move(originalArtistFolder, Artist.ArtistFileFolder(destinationFolder ?? SettingsHelper.Instance.LibraryFolder));
|
||||
// TODO if name changed then update Artist track files to have new Artist name
|
||||
CacheManager.ClearRegion(Artist.CacheRegion);
|
||||
sw.Stop();
|
||||
|
||||
return new OperationResult<Artist>
|
||||
|
|
|
@ -15,107 +15,113 @@ namespace Roadie.Library.Factories
|
|||
public abstract class FactoryBase
|
||||
{
|
||||
protected IArtistLookupEngine ArtistLookupEngine { get; }
|
||||
|
||||
protected ICacheManager CacheManager { get; }
|
||||
|
||||
protected IRoadieSettings Configuration { get; }
|
||||
|
||||
protected IRoadieDbContext DbContext { get; }
|
||||
|
||||
protected ILabelSearchEngine DiscogsLabelSearchEngine { get; }
|
||||
|
||||
protected IHttpEncoder HttpEncoder { get; }
|
||||
|
||||
protected ILogger Logger { get; }
|
||||
|
||||
protected IReleaseLookupEngine ReleaseLookupEngine { get; }
|
||||
|
||||
|
||||
public FactoryBase(IRoadieSettings configuration, IRoadieDbContext context, ICacheManager cacheManager, ILogger logger, IHttpEncoder httpEncoder, IArtistLookupEngine artistLookupEngine, IReleaseLookupEngine releaseLookupEngine)
|
||||
public FactoryBase(IRoadieSettings configuration, IRoadieDbContext context, ICacheManager cacheManager,
|
||||
ILogger logger, IHttpEncoder httpEncoder, IArtistLookupEngine artistLookupEngine,
|
||||
IReleaseLookupEngine releaseLookupEngine)
|
||||
{
|
||||
this.Configuration = configuration;
|
||||
this.DbContext = context;
|
||||
this.CacheManager = cacheManager;
|
||||
this.Logger = logger;
|
||||
this.HttpEncoder = httpEncoder;
|
||||
Configuration = configuration;
|
||||
DbContext = context;
|
||||
CacheManager = cacheManager;
|
||||
Logger = logger;
|
||||
HttpEncoder = httpEncoder;
|
||||
|
||||
this.ArtistLookupEngine = artistLookupEngine;
|
||||
this.ReleaseLookupEngine = releaseLookupEngine;
|
||||
ArtistLookupEngine = artistLookupEngine;
|
||||
ReleaseLookupEngine = releaseLookupEngine;
|
||||
}
|
||||
|
||||
[Obsolete("Use Service Methods")]
|
||||
protected IEnumerable<int> ArtistIdsForRelease(int releaseId)
|
||||
{
|
||||
var trackArtistIds = (from r in this.DbContext.Releases
|
||||
join rm in this.DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
|
||||
join tr in this.DbContext.Tracks on rm.Id equals tr.ReleaseMediaId
|
||||
where r.Id == releaseId
|
||||
where tr.ArtistId != null
|
||||
select tr.ArtistId.Value).ToList();
|
||||
trackArtistIds.Add(this.DbContext.Releases.FirstOrDefault(x => x.Id == releaseId).ArtistId);
|
||||
var trackArtistIds = (from r in DbContext.Releases
|
||||
join rm in DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
|
||||
join tr in DbContext.Tracks on rm.Id equals tr.ReleaseMediaId
|
||||
where r.Id == releaseId
|
||||
where tr.ArtistId != null
|
||||
select tr.ArtistId.Value).ToList();
|
||||
trackArtistIds.Add(DbContext.Releases.FirstOrDefault(x => x.Id == releaseId).ArtistId);
|
||||
return trackArtistIds.Distinct().ToArray();
|
||||
}
|
||||
|
||||
[Obsolete("Use Service Methods")]
|
||||
protected async Task UpdateArtistCounts(int artistId, DateTime now)
|
||||
{
|
||||
var artist = DbContext.Artists.FirstOrDefault(x => x.Id == artistId);
|
||||
if (artist != null)
|
||||
{
|
||||
artist.ReleaseCount = DbContext.Releases.Where(x => x.ArtistId == artistId).Count();
|
||||
artist.TrackCount = (from r in DbContext.Releases
|
||||
join rm in DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
|
||||
join tr in DbContext.Tracks on rm.Id equals tr.ReleaseMediaId
|
||||
where tr.ArtistId == artistId || r.ArtistId == artistId
|
||||
select tr).Count();
|
||||
|
||||
artist.LastUpdated = now;
|
||||
await DbContext.SaveChangesAsync();
|
||||
CacheManager.ClearRegion(artist.CacheRegion);
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use Service Methods")]
|
||||
/// <summary>
|
||||
/// Update the counts for all artists on a release (both track and release artists)
|
||||
/// </summary>
|
||||
protected async Task UpdateArtistCountsForRelease(int releaseId, DateTime now)
|
||||
{
|
||||
foreach(var artistId in this.ArtistIdsForRelease(releaseId))
|
||||
{
|
||||
await this.UpdateArtistCounts(artistId, now);
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use Service Methods")]
|
||||
protected async Task UpdateArtistCounts(int artistId, DateTime now)
|
||||
{
|
||||
var artist = this.DbContext.Artists.FirstOrDefault(x => x.Id == artistId);
|
||||
if (artist != null)
|
||||
{
|
||||
artist.ReleaseCount = this.DbContext.Releases.Where(x => x.ArtistId == artistId).Count();
|
||||
artist.TrackCount = (from r in this.DbContext.Releases
|
||||
join rm in this.DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
|
||||
join tr in this.DbContext.Tracks on rm.Id equals tr.ReleaseMediaId
|
||||
where (tr.ArtistId == artistId || r.ArtistId == artistId)
|
||||
select tr).Count();
|
||||
|
||||
artist.LastUpdated = now;
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
this.CacheManager.ClearRegion(artist.CacheRegion);
|
||||
}
|
||||
foreach (var artistId in ArtistIdsForRelease(releaseId)) await UpdateArtistCounts(artistId, now);
|
||||
}
|
||||
|
||||
[Obsolete("Use Service Methods")]
|
||||
protected async Task UpdateLabelCounts(int labelId, DateTime now)
|
||||
{
|
||||
var label = this.DbContext.Labels.FirstOrDefault(x => x.Id == labelId);
|
||||
var label = DbContext.Labels.FirstOrDefault(x => x.Id == labelId);
|
||||
if (label != null)
|
||||
{
|
||||
label.ReleaseCount = this.DbContext.ReleaseLabels.Where(x => x.LabelId == label.Id).Count();
|
||||
label.ArtistCount = (from r in this.DbContext.Releases
|
||||
join rl in this.DbContext.ReleaseLabels on r.Id equals rl.ReleaseId
|
||||
join a in this.DbContext.Artists on r.ArtistId equals a.Id
|
||||
label.ReleaseCount = DbContext.ReleaseLabels.Where(x => x.LabelId == label.Id).Count();
|
||||
label.ArtistCount = (from r in DbContext.Releases
|
||||
join rl in DbContext.ReleaseLabels on r.Id equals rl.ReleaseId
|
||||
join a in DbContext.Artists on r.ArtistId equals a.Id
|
||||
where rl.LabelId == label.Id
|
||||
group a by a.Id into artists
|
||||
group a by a.Id
|
||||
into artists
|
||||
select artists).Select(x => x.Key).Count();
|
||||
label.TrackCount = (from r in this.DbContext.Releases
|
||||
join rl in this.DbContext.ReleaseLabels on r.Id equals rl.ReleaseId
|
||||
join rm in this.DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
|
||||
join t in this.DbContext.Tracks on rm.Id equals t.ReleaseMediaId
|
||||
label.TrackCount = (from r in DbContext.Releases
|
||||
join rl in DbContext.ReleaseLabels on r.Id equals rl.ReleaseId
|
||||
join rm in DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
|
||||
join t in DbContext.Tracks on rm.Id equals t.ReleaseMediaId
|
||||
where rl.LabelId == label.Id
|
||||
select t).Count();
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
this.CacheManager.ClearRegion(label.CacheRegion);
|
||||
await DbContext.SaveChangesAsync();
|
||||
CacheManager.ClearRegion(label.CacheRegion);
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use Service Methods")]
|
||||
protected async Task UpdateReleaseCounts(int releaseId, DateTime now)
|
||||
{
|
||||
var release = this.DbContext.Releases.FirstOrDefault(x => x.Id == releaseId);
|
||||
var release = DbContext.Releases.FirstOrDefault(x => x.Id == releaseId);
|
||||
if (release != null)
|
||||
{
|
||||
release.Duration = (from t in this.DbContext.Tracks
|
||||
join rm in this.DbContext.ReleaseMedias on t.ReleaseMediaId equals rm.Id
|
||||
release.Duration = (from t in DbContext.Tracks
|
||||
join rm in DbContext.ReleaseMedias on t.ReleaseMediaId equals rm.Id
|
||||
where rm.ReleaseId == releaseId
|
||||
select t).Sum(x => x.Duration);
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
this.CacheManager.ClearRegion(release.CacheRegion);
|
||||
await DbContext.SaveChangesAsync();
|
||||
CacheManager.ClearRegion(release.CacheRegion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,14 +11,17 @@ namespace Roadie.Library.Factories
|
|||
|
||||
Task<OperationResult<bool>> Delete(Guid RoadieId);
|
||||
|
||||
OperationResult<Artist> GetByExternalIds(string musicBrainzId = null, string iTunesId = null, string amgId = null, string spotifyId = null);
|
||||
OperationResult<Artist> GetByExternalIds(string musicBrainzId = null, string iTunesId = null,
|
||||
string amgId = null, string spotifyId = null);
|
||||
|
||||
Task<OperationResult<Artist>> MergeArtists(Artist ArtistToMerge, Artist artistToMergeInto, bool doDbUpdates = false);
|
||||
Task<OperationResult<Artist>> MergeArtists(Artist ArtistToMerge, Artist artistToMergeInto,
|
||||
bool doDbUpdates = false);
|
||||
|
||||
Task<OperationResult<bool>> RefreshArtistMetadata(Guid ArtistId);
|
||||
|
||||
Task<OperationResult<bool>> ScanArtistReleasesFolders(Guid artistId, string destinationFolder, bool doJustInfo);
|
||||
|
||||
Task<OperationResult<Artist>> Update(Artist Artist, IEnumerable<Image> ArtistImages, string destinationFolder = null);
|
||||
Task<OperationResult<Artist>> Update(Artist Artist, IEnumerable<Image> ArtistImages,
|
||||
string destinationFolder = null);
|
||||
}
|
||||
}
|
|
@ -1,10 +1,6 @@
|
|||
using Roadie.Library.Data;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Factories
|
||||
namespace Roadie.Library.Factories
|
||||
{
|
||||
public interface ILabelFactory
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using Roadie.Library.Data;
|
||||
using Roadie.Library.MetaData.Audio;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -10,18 +9,22 @@ namespace Roadie.Library.Factories
|
|||
{
|
||||
IEnumerable<int> AddedTrackIds { get; }
|
||||
|
||||
Task<OperationResult<bool>> CheckAndChangeReleaseTitle(Release release, string oldReleaseFolder, string destinationFolder = null);
|
||||
Task<OperationResult<bool>> CheckAndChangeReleaseTitle(Release release, string oldReleaseFolder,
|
||||
string destinationFolder = null);
|
||||
|
||||
Task<OperationResult<bool>> Delete(Release release, bool doDeleteFiles = false, bool doUpdateArtistCounts = true);
|
||||
Task<OperationResult<bool>> Delete(Release release, bool doDeleteFiles = false,
|
||||
bool doUpdateArtistCounts = true);
|
||||
|
||||
Task<OperationResult<bool>> DeleteReleases(IEnumerable<Guid> releaseIds, bool doDeleteFiles = false);
|
||||
|
||||
OperationResult<Release> GetAllForArtist(Artist artist, bool forceRefresh = false);
|
||||
|
||||
Task<OperationResult<bool>> MergeReleases(Release releaseToMerge, Release releaseToMergeInto, bool addAsMedia);
|
||||
Task<OperationResult<bool>> MergeReleases(Release releaseToMerge, Release releaseToMergeInto, bool addAsMedia);
|
||||
|
||||
Task<OperationResult<bool>> ScanReleaseFolder(Guid releaseId, string destinationFolder, bool doJustInfo, Release releaseToScan = null);
|
||||
Task<OperationResult<bool>> ScanReleaseFolder(Guid releaseId, string destinationFolder, bool doJustInfo,
|
||||
Release releaseToScan = null);
|
||||
|
||||
Task<OperationResult<Release>> Update(Release release, IEnumerable<Image> releaseImages, string originalReleaseFolder, string destinationFolder = null);
|
||||
Task<OperationResult<Release>> Update(Release release, IEnumerable<Image> releaseImages,
|
||||
string originalReleaseFolder, string destinationFolder = null);
|
||||
}
|
||||
}
|
|
@ -18,13 +18,15 @@ namespace Roadie.Library.Factories
|
|||
{
|
||||
public sealed class ImageFactory : FactoryBase, IImageFactory
|
||||
{
|
||||
public ImageFactory(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context, ICacheManager cacheManager, ILogger logger, IArtistLookupEngine artistLookupEngine, IReleaseLookupEngine releaseLookupEngine)
|
||||
public ImageFactory(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context,
|
||||
ICacheManager cacheManager, ILogger logger, IArtistLookupEngine artistLookupEngine,
|
||||
IReleaseLookupEngine releaseLookupEngine)
|
||||
: base(configuration, context, cacheManager, logger, httpEncoder, artistLookupEngine, releaseLookupEngine)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get image data from all sources for either fileanme or MetaData
|
||||
/// Get image data from all sources for either fileanme or MetaData
|
||||
/// </summary>
|
||||
/// <param name="filename">Name of the File (ie a CUE file)</param>
|
||||
/// <param name="metaData">Populated MetaData</param>
|
||||
|
@ -34,11 +36,11 @@ namespace Roadie.Library.Factories
|
|||
SimpleContract.Requires<ArgumentException>(!string.IsNullOrEmpty(filename), "Invalid Filename");
|
||||
SimpleContract.Requires<ArgumentException>(metaData != null, "Invalid MetaData");
|
||||
|
||||
return this.ImageForFilename(filename);
|
||||
return ImageForFilename(filename);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does image exist with the same filename
|
||||
/// Does image exist with the same filename
|
||||
/// </summary>
|
||||
/// <param name="filename">Name of the File (ie a CUE file)</param>
|
||||
/// <returns>Null if not found else populated image</returns>
|
||||
|
@ -46,17 +48,14 @@ namespace Roadie.Library.Factories
|
|||
{
|
||||
AudioMetaDataImage imageMetaData = null;
|
||||
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
{
|
||||
return imageMetaData;
|
||||
}
|
||||
if (string.IsNullOrEmpty(filename)) return imageMetaData;
|
||||
try
|
||||
{
|
||||
var fileInfo = new FileInfo(filename);
|
||||
var ReleaseCover = Path.ChangeExtension(filename, "jpg");
|
||||
if (File.Exists(ReleaseCover))
|
||||
{
|
||||
using (var processor = new ImageProcessor(this.Configuration))
|
||||
using (var processor = new ImageProcessor(Configuration))
|
||||
{
|
||||
imageMetaData = new AudioMetaDataImage
|
||||
{
|
||||
|
@ -75,18 +74,14 @@ namespace Roadie.Library.Factories
|
|||
{
|
||||
FileInfo picture = null;
|
||||
// See if there is a "cover" or "front" jpg file if so use it
|
||||
picture = pictures.FirstOrDefault(x => x.Name.Equals("cover", StringComparison.OrdinalIgnoreCase));
|
||||
picture = pictures.FirstOrDefault(x =>
|
||||
x.Name.Equals("cover", StringComparison.OrdinalIgnoreCase));
|
||||
if (picture == null)
|
||||
{
|
||||
picture = pictures.FirstOrDefault(x => x.Name.Equals("front", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
if (picture == null)
|
||||
{
|
||||
picture = pictures.First();
|
||||
}
|
||||
picture = pictures.FirstOrDefault(x =>
|
||||
x.Name.Equals("front", StringComparison.OrdinalIgnoreCase));
|
||||
if (picture == null) picture = pictures.First();
|
||||
if (picture != null)
|
||||
{
|
||||
using (var processor = new ImageProcessor(this.Configuration))
|
||||
using (var processor = new ImageProcessor(Configuration))
|
||||
{
|
||||
imageMetaData = new AudioMetaDataImage
|
||||
{
|
||||
|
@ -95,17 +90,17 @@ namespace Roadie.Library.Factories
|
|||
MimeType = FileProcessor.DetermineFileType(picture)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.IO.FileNotFoundException)
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, ex.Serialize());
|
||||
Logger.LogError(ex, ex.Serialize());
|
||||
}
|
||||
|
||||
return imageMetaData;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,31 +1,21 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MySql.Data.MySqlClient;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Roadie.Library.Caching;
|
||||
using Roadie.Library.Configuration;
|
||||
using Roadie.Library.Data;
|
||||
using Roadie.Library.Encoding;
|
||||
using Roadie.Library.Engines;
|
||||
using Roadie.Library.Extensions;
|
||||
using Roadie.Library.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Factories
|
||||
{
|
||||
public sealed class LabelFactory : FactoryBase, ILabelFactory
|
||||
{
|
||||
public LabelFactory(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context, ICacheManager cacheManager, ILogger logger, IArtistLookupEngine artistLookupEngine, IReleaseLookupEngine releaseLookupEngine)
|
||||
public LabelFactory(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context,
|
||||
ICacheManager cacheManager, ILogger logger, IArtistLookupEngine artistLookupEngine,
|
||||
IReleaseLookupEngine releaseLookupEngine)
|
||||
: base(configuration, context, cacheManager, logger, httpEncoder, artistLookupEngine, releaseLookupEngine)
|
||||
{
|
||||
}
|
||||
|
||||
// TODO Merge
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -14,7 +14,9 @@ namespace Roadie.Library.Factories
|
|||
{
|
||||
public class PlaylistFactory : FactoryBase, IPlaylistFactory
|
||||
{
|
||||
public PlaylistFactory(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context, ICacheManager cacheManager, ILogger logger, IArtistLookupEngine artistLookupEngine, IReleaseLookupEngine releaseLookupEngine)
|
||||
public PlaylistFactory(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context,
|
||||
ICacheManager cacheManager, ILogger logger, IArtistLookupEngine artistLookupEngine,
|
||||
IReleaseLookupEngine releaseLookupEngine)
|
||||
: base(configuration, context, cacheManager, logger, httpEncoder, artistLookupEngine, releaseLookupEngine)
|
||||
{
|
||||
}
|
||||
|
@ -28,28 +30,26 @@ namespace Roadie.Library.Factories
|
|||
var result = false;
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
var existingTracksForPlaylist = (from plt in this.DbContext.PlaylistTracks
|
||||
join t in this.DbContext.Tracks on plt.TrackId equals t.Id
|
||||
where plt.PlayListId == playlist.Id
|
||||
select t);
|
||||
var newTracksForPlaylist = (from t in this.DbContext.Tracks
|
||||
var existingTracksForPlaylist = from plt in DbContext.PlaylistTracks
|
||||
join t in DbContext.Tracks on plt.TrackId equals t.Id
|
||||
where plt.PlayListId == playlist.Id
|
||||
select t;
|
||||
var newTracksForPlaylist = (from t in DbContext.Tracks
|
||||
where (from x in trackIds select x).Contains(t.RoadieId)
|
||||
where !(from x in existingTracksForPlaylist select x.RoadieId).Contains(t.RoadieId)
|
||||
select t).ToArray();
|
||||
foreach (var newTrackForPlaylist in newTracksForPlaylist)
|
||||
{
|
||||
this.DbContext.PlaylistTracks.Add(new PlaylistTrack
|
||||
DbContext.PlaylistTracks.Add(new PlaylistTrack
|
||||
{
|
||||
TrackId = newTrackForPlaylist.Id,
|
||||
PlayListId = playlist.Id,
|
||||
CreatedDate = now
|
||||
});
|
||||
}
|
||||
playlist.LastUpdated = now;
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
await DbContext.SaveChangesAsync();
|
||||
result = true;
|
||||
|
||||
var r = await this.ReorderPlaylist(playlist);
|
||||
var r = await ReorderPlaylist(playlist);
|
||||
result = result && r.IsSuccess;
|
||||
|
||||
return new OperationResult<bool>
|
||||
|
@ -70,13 +70,15 @@ namespace Roadie.Library.Factories
|
|||
if (playlist != null)
|
||||
{
|
||||
var looper = 0;
|
||||
foreach (var playlistTrack in this.DbContext.PlaylistTracks.Where(x => x.PlayListId == playlist.Id).OrderBy(x => x.CreatedDate))
|
||||
foreach (var playlistTrack in DbContext.PlaylistTracks.Where(x => x.PlayListId == playlist.Id)
|
||||
.OrderBy(x => x.CreatedDate))
|
||||
{
|
||||
looper++;
|
||||
playlistTrack.ListNumber = looper;
|
||||
playlistTrack.LastUpdated = now;
|
||||
}
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
|
||||
await DbContext.SaveChangesAsync();
|
||||
result = true;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,50 +1,52 @@
|
|||
using System;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Roadie.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// A OperationResult specific to a File type request.
|
||||
/// A OperationResult specific to a File type request.
|
||||
/// </summary>
|
||||
public class FileOperationResult<T> : OperationResult<T>
|
||||
{
|
||||
public EntityTagHeaderValue ETag { get; set; }
|
||||
public DateTimeOffset? LastModified { get; set; }
|
||||
public string ContentType { get; set; }
|
||||
|
||||
public EntityTagHeaderValue ETag { get; set; }
|
||||
|
||||
public DateTimeOffset? LastModified { get; set; }
|
||||
|
||||
public FileOperationResult()
|
||||
{
|
||||
}
|
||||
|
||||
public FileOperationResult(string message)
|
||||
{
|
||||
this.AddMessage(message);
|
||||
AddMessage(message);
|
||||
}
|
||||
|
||||
public FileOperationResult(bool isNotFoundResult, string message)
|
||||
{
|
||||
this.IsNotFoundResult = isNotFoundResult;
|
||||
this.AddMessage(message);
|
||||
IsNotFoundResult = isNotFoundResult;
|
||||
AddMessage(message);
|
||||
}
|
||||
|
||||
public FileOperationResult(IEnumerable<string> messages = null)
|
||||
{
|
||||
if (messages != null && messages.Any())
|
||||
{
|
||||
this.AdditionalData = new Dictionary<string, object>();
|
||||
messages.ToList().ForEach(x => this.AddMessage(x));
|
||||
AdditionalData = new Dictionary<string, object>();
|
||||
messages.ToList().ForEach(x => AddMessage(x));
|
||||
}
|
||||
}
|
||||
|
||||
public FileOperationResult(bool isNotFoundResult, IEnumerable<string> messages = null)
|
||||
{
|
||||
this.IsNotFoundResult = isNotFoundResult;
|
||||
IsNotFoundResult = isNotFoundResult;
|
||||
if (messages != null && messages.Any())
|
||||
{
|
||||
this.AdditionalData = new Dictionary<string, object>();
|
||||
messages.ToList().ForEach(x => this.AddMessage(x));
|
||||
AdditionalData = new Dictionary<string, object>();
|
||||
messages.ToList().ForEach(x => AddMessage(x));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ using Roadie.Library.Caching;
|
|||
using Roadie.Library.Configuration;
|
||||
using Roadie.Library.Encoding;
|
||||
using Roadie.Library.Engines;
|
||||
using Roadie.Library.Enums;
|
||||
using Roadie.Library.Extensions;
|
||||
using Roadie.Library.Factories;
|
||||
using Roadie.Library.Imaging;
|
||||
|
@ -28,7 +29,7 @@ namespace Roadie.Library.FilePlugins
|
|||
public override string[] HandlesTypes => new string[1] { "audio/mpeg" };
|
||||
|
||||
public Audio(IRoadieSettings configuration,
|
||||
IHttpEncoder httpEncoder,
|
||||
IHttpEncoder httpEncoder,
|
||||
IArtistFactory artistFactory,
|
||||
IReleaseFactory releaseFactory,
|
||||
IImageFactory imageFactory,
|
||||
|
@ -37,14 +38,18 @@ namespace Roadie.Library.FilePlugins
|
|||
IArtistLookupEngine artistLookupEngine,
|
||||
IReleaseLookupEngine releaseLookupEngine,
|
||||
IAudioMetaDataHelper audioMetaDataHelper)
|
||||
: base(configuration, httpEncoder, artistFactory, releaseFactory, imageFactory, cacheManager, logger, artistLookupEngine, releaseLookupEngine)
|
||||
: base(configuration, httpEncoder, artistFactory, releaseFactory, imageFactory, cacheManager, logger,
|
||||
artistLookupEngine, releaseLookupEngine)
|
||||
{
|
||||
this.AudioMetaDataHelper = audioMetaDataHelper;
|
||||
AudioMetaDataHelper = audioMetaDataHelper;
|
||||
}
|
||||
|
||||
public override async Task<OperationResult<bool>> Process(string destinationRoot, FileInfo fileInfo, bool doJustInfo, int? submissionId)
|
||||
public override async Task<OperationResult<bool>> Process(string destinationRoot, FileInfo fileInfo,
|
||||
bool doJustInfo, int? submissionId)
|
||||
{
|
||||
this.Logger.LogTrace(">> Audio: Process destinationRoot [{0}], FileInfo [{1}], doJustInfo [{2}], submissionId [{3}]", destinationRoot, fileInfo, doJustInfo, submissionId);
|
||||
Logger.LogTrace(
|
||||
">> Audio: Process destinationRoot [{0}], FileInfo [{1}], doJustInfo [{2}], submissionId [{3}]",
|
||||
destinationRoot, fileInfo, doJustInfo, submissionId);
|
||||
var sw = Stopwatch.StartNew();
|
||||
var result = new OperationResult<bool>();
|
||||
|
||||
|
@ -54,24 +59,25 @@ namespace Roadie.Library.FilePlugins
|
|||
|
||||
string destinationName = null;
|
||||
|
||||
var metaData = await this.AudioMetaDataHelper.GetInfo(fileInfo, doJustInfo);
|
||||
var metaData = await AudioMetaDataHelper.GetInfo(fileInfo, doJustInfo);
|
||||
if (!metaData.IsValid)
|
||||
{
|
||||
var minWeight = this.MinWeightToDelete;
|
||||
var minWeight = MinWeightToDelete;
|
||||
if (metaData.ValidWeight < minWeight && minWeight > 0)
|
||||
{
|
||||
this.Logger.LogTrace("Invalid File{3}: ValidWeight [{0}], Under MinWeightToDelete [{1}]. Deleting File [{2}]", metaData.ValidWeight, minWeight, fileInfo.FullName, doJustInfo ? " [Read Only Mode] " : string.Empty);
|
||||
if (!doJustInfo)
|
||||
{
|
||||
fileInfo.Delete();
|
||||
}
|
||||
Logger.LogTrace(
|
||||
"Invalid File{3}: ValidWeight [{0}], Under MinWeightToDelete [{1}]. Deleting File [{2}]",
|
||||
metaData.ValidWeight, minWeight, fileInfo.FullName,
|
||||
doJustInfo ? " [Read Only Mode] " : string.Empty);
|
||||
if (!doJustInfo) fileInfo.Delete();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
var artist = metaData.Artist.CleanString(this.Configuration);
|
||||
var album = metaData.Release.CleanString(this.Configuration);
|
||||
var title = metaData.Title.CleanString(this.Configuration).ToTitleCase(false);
|
||||
var artist = metaData.Artist.CleanString(Configuration);
|
||||
var album = metaData.Release.CleanString(Configuration);
|
||||
var title = metaData.Title.CleanString(Configuration).ToTitleCase(false);
|
||||
var year = metaData.Year;
|
||||
var trackNumber = metaData.TrackNumber ?? 0;
|
||||
var discNumber = metaData.Disc ?? 0;
|
||||
|
@ -83,20 +89,26 @@ namespace Roadie.Library.FilePlugins
|
|||
SimpleContract.Requires<ArgumentException>(year > 0, string.Format("Invalid Track Year [{0}]", year));
|
||||
SimpleContract.Requires<ArgumentException>(trackNumber > 0, "Missing Track Number");
|
||||
|
||||
var artistFolder = await this.DetermineArtistFolder(dr, metaData, doJustInfo);
|
||||
var artistFolder = await DetermineArtistFolder(dr, metaData, doJustInfo);
|
||||
if (string.IsNullOrEmpty(artistFolder))
|
||||
{
|
||||
this.Logger.LogWarning("Unable To Find ArtistFolder [{0}] For MetaData [{1}]", artistFolder, metaData.ToString());
|
||||
Logger.LogWarning("Unable To Find ArtistFolder [{0}] For MetaData [{1}]", artistFolder,
|
||||
metaData.ToString());
|
||||
return new OperationResult<bool>("Unable To Find Artist Folder");
|
||||
}
|
||||
var releaseFolder = await this.DetermineReleaseFolder(artistFolder, metaData, doJustInfo, submissionId);
|
||||
|
||||
var releaseFolder = await DetermineReleaseFolder(artistFolder, metaData, doJustInfo, submissionId);
|
||||
if (string.IsNullOrEmpty(releaseFolder))
|
||||
{
|
||||
this.Logger.LogWarning("Unable To Find ReleaseFolder For MetaData [{0}]", metaData.ToString());
|
||||
Logger.LogWarning("Unable To Find ReleaseFolder For MetaData [{0}]", metaData.ToString());
|
||||
return new OperationResult<bool>("Unable To Find Release Folder");
|
||||
}
|
||||
destinationName = FolderPathHelper.TrackFullPath(this.Configuration, metaData, dr, artistFolder, releaseFolder);
|
||||
this.Logger.LogTrace("Info: FileInfo [{0}], Artist Folder [{1}], Release Folder [{1}], Destination Name [{3}]", fileInfo.FullName, artistFolder, releaseFolder, destinationName);
|
||||
|
||||
destinationName =
|
||||
FolderPathHelper.TrackFullPath(Configuration, metaData, dr, artistFolder, releaseFolder);
|
||||
Logger.LogTrace(
|
||||
"Info: FileInfo [{0}], Artist Folder [{1}], Release Folder [{1}], Destination Name [{3}]",
|
||||
fileInfo.FullName, artistFolder, releaseFolder, destinationName);
|
||||
|
||||
if (doJustInfo)
|
||||
{
|
||||
|
@ -104,21 +116,16 @@ namespace Roadie.Library.FilePlugins
|
|||
return result;
|
||||
}
|
||||
|
||||
if(PluginBase.CheckMakeFolder(artistFolder))
|
||||
{
|
||||
this.Logger.LogTrace("Created ArtistFolder [{0}]", artistFolder);
|
||||
}
|
||||
if(PluginBase.CheckMakeFolder(releaseFolder))
|
||||
{
|
||||
this.Logger.LogTrace("Created ReleaseFolder [{0}]", releaseFolder);
|
||||
}
|
||||
if (CheckMakeFolder(artistFolder)) Logger.LogTrace("Created ArtistFolder [{0}]", artistFolder);
|
||||
if (CheckMakeFolder(releaseFolder)) Logger.LogTrace("Created ReleaseFolder [{0}]", releaseFolder);
|
||||
|
||||
try
|
||||
{
|
||||
// See if file folder parent folder (likely file is in release folder) has primary artist image if so then move to artist folder
|
||||
var artistImages = new List<FileInfo>();
|
||||
artistImages.AddRange(ImageHelper.FindImageTypeInDirectory(fileInfo.Directory, Enums.ImageType.Artist));
|
||||
artistImages.AddRange(ImageHelper.FindImageTypeInDirectory(fileInfo.Directory.Parent, Enums.ImageType.Artist));
|
||||
artistImages.AddRange(ImageHelper.FindImageTypeInDirectory(fileInfo.Directory, ImageType.Artist));
|
||||
artistImages.AddRange(
|
||||
ImageHelper.FindImageTypeInDirectory(fileInfo.Directory.Parent, ImageType.Artist));
|
||||
if (artistImages.Any())
|
||||
{
|
||||
var artistImage = artistImages.First();
|
||||
|
@ -135,21 +142,25 @@ namespace Roadie.Library.FilePlugins
|
|||
File.WriteAllBytes(artistImageFilename, imageBytes);
|
||||
artistImage.Delete();
|
||||
}
|
||||
this.Logger.LogDebug("Found Artist Image File [{0}], Moved to artist folder.", artistImage.Name);
|
||||
|
||||
Logger.LogDebug("Found Artist Image File [{0}], Moved to artist folder.", artistImage.Name);
|
||||
}
|
||||
}
|
||||
|
||||
// See if any secondary artist images if so then move to artist folder
|
||||
artistImages.Clear();
|
||||
artistImages.AddRange(ImageHelper.FindImageTypeInDirectory(fileInfo.Directory, Enums.ImageType.ArtistSecondary));
|
||||
artistImages.AddRange(ImageHelper.FindImageTypeInDirectory(fileInfo.Directory.Parent, Enums.ImageType.Artist));
|
||||
artistImages.AddRange(
|
||||
ImageHelper.FindImageTypeInDirectory(fileInfo.Directory, ImageType.ArtistSecondary));
|
||||
artistImages.AddRange(
|
||||
ImageHelper.FindImageTypeInDirectory(fileInfo.Directory.Parent, ImageType.Artist));
|
||||
if (artistImages.Any())
|
||||
{
|
||||
var looper = 0;
|
||||
foreach (var artistImage in artistImages)
|
||||
{
|
||||
looper++;
|
||||
var artistImageFilename = Path.Combine(artistFolder, string.Format(ImageHelper.ArtistSecondaryImageFilename, looper.ToString("00")));
|
||||
var artistImageFilename = Path.Combine(artistFolder,
|
||||
string.Format(ImageHelper.ArtistSecondaryImageFilename, looper.ToString("00")));
|
||||
if (artistImageFilename != artistImage.FullName)
|
||||
{
|
||||
// Read image and convert to jpeg
|
||||
|
@ -162,18 +173,24 @@ namespace Roadie.Library.FilePlugins
|
|||
while (File.Exists(artistImageFilename))
|
||||
{
|
||||
looper++;
|
||||
artistImageFilename = Path.Combine(artistFolder, string.Format(ImageHelper.ArtistSecondaryImageFilename, looper.ToString("00")));
|
||||
artistImageFilename = Path.Combine(artistFolder,
|
||||
string.Format(ImageHelper.ArtistSecondaryImageFilename,
|
||||
looper.ToString("00")));
|
||||
}
|
||||
|
||||
File.WriteAllBytes(artistImageFilename, imageBytes);
|
||||
artistImage.Delete();
|
||||
}
|
||||
this.Logger.LogDebug("Found Artist Secondary Image File [{0}], Moved to artist folder [{1}].", artistImage.Name, artistImageFilename);
|
||||
|
||||
Logger.LogDebug(
|
||||
"Found Artist Secondary Image File [{0}], Moved to artist folder [{1}].",
|
||||
artistImage.Name, artistImageFilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See if file folder has release image if so then move to release folder
|
||||
var releaseImages = ImageHelper.FindImageTypeInDirectory(fileInfo.Directory, Enums.ImageType.Release);
|
||||
var releaseImages = ImageHelper.FindImageTypeInDirectory(fileInfo.Directory, ImageType.Release);
|
||||
if (releaseImages.Any())
|
||||
{
|
||||
var releaseImage = releaseImages.First();
|
||||
|
@ -190,19 +207,23 @@ namespace Roadie.Library.FilePlugins
|
|||
File.WriteAllBytes(coverFileName, imageBytes);
|
||||
releaseImage.Delete();
|
||||
}
|
||||
this.Logger.LogDebug("Found Release Image File [{0}], Moved to release folder", releaseImage.Name);
|
||||
|
||||
Logger.LogDebug("Found Release Image File [{0}], Moved to release folder",
|
||||
releaseImage.Name);
|
||||
}
|
||||
}
|
||||
|
||||
// See if folder has secondary release image if so then move to release folder
|
||||
releaseImages = ImageHelper.FindImageTypeInDirectory(fileInfo.Directory, Enums.ImageType.ReleaseSecondary);
|
||||
releaseImages =
|
||||
ImageHelper.FindImageTypeInDirectory(fileInfo.Directory, ImageType.ReleaseSecondary);
|
||||
if (releaseImages.Any())
|
||||
{
|
||||
var looper = 0;
|
||||
foreach (var releaseImage in releaseImages)
|
||||
{
|
||||
looper++;
|
||||
var releaseImageFilename = Path.Combine(releaseFolder, string.Format(ImageHelper.ReleaseSecondaryImageFilename, looper.ToString("00")));
|
||||
var releaseImageFilename = Path.Combine(releaseFolder,
|
||||
string.Format(ImageHelper.ReleaseSecondaryImageFilename, looper.ToString("00")));
|
||||
if (releaseImageFilename != releaseImage.FullName)
|
||||
{
|
||||
// Read image and convert to jpeg
|
||||
|
@ -215,15 +236,16 @@ namespace Roadie.Library.FilePlugins
|
|||
File.WriteAllBytes(releaseImageFilename, imageBytes);
|
||||
releaseImage.Delete();
|
||||
}
|
||||
this.Logger.LogDebug("Found Release Image File [{0}], Moved to release folder [{1}]", releaseImage.Name, releaseImageFilename);
|
||||
|
||||
Logger.LogDebug("Found Release Image File [{0}], Moved to release folder [{1}]",
|
||||
releaseImage.Name, releaseImageFilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, "Error with Managing Images For [{0}]", fileInfo.FullName);
|
||||
Logger.LogError(ex, "Error with Managing Images For [{0}]", fileInfo.FullName);
|
||||
}
|
||||
|
||||
var doesFileExistsForTrack = File.Exists(destinationName);
|
||||
|
@ -232,17 +254,19 @@ namespace Roadie.Library.FilePlugins
|
|||
var existing = new FileInfo(destinationName);
|
||||
|
||||
// If Exists determine which is better - if same do nothing
|
||||
var existingMetaData = await this.AudioMetaDataHelper.GetInfo(existing, doJustInfo);
|
||||
var existingMetaData = await AudioMetaDataHelper.GetInfo(existing, doJustInfo);
|
||||
|
||||
var areSameFile = existing.FullName.Replace("\\", "").Replace("/", "").Equals(fileInfo.FullName.Replace("\\", "").Replace("/", ""), StringComparison.OrdinalIgnoreCase);
|
||||
var areSameFile = existing.FullName.Replace("\\", "").Replace("/", "")
|
||||
.Equals(fileInfo.FullName.Replace("\\", "").Replace("/", ""),
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
var currentBitRate = metaData.AudioBitrate;
|
||||
var existingBitRate = existingMetaData.AudioBitrate;
|
||||
|
||||
if (!areSameFile)
|
||||
{
|
||||
if (!existingMetaData.IsValid || (currentBitRate > existingBitRate))
|
||||
if (!existingMetaData.IsValid || currentBitRate > existingBitRate)
|
||||
{
|
||||
this.Logger.LogTrace("Newer Is Better: Deleting Existing File [{0}]", existing);
|
||||
Logger.LogTrace("Newer Is Better: Deleting Existing File [{0}]", existing);
|
||||
if (!doJustInfo)
|
||||
{
|
||||
existing.Delete();
|
||||
|
@ -251,36 +275,32 @@ namespace Roadie.Library.FilePlugins
|
|||
}
|
||||
else
|
||||
{
|
||||
this.Logger.LogTrace("Existing [{0}] Is Better or Equal: Deleting Found File [{1}]", existing, fileInfo.FullName);
|
||||
if (!doJustInfo)
|
||||
{
|
||||
fileInfo.Delete();
|
||||
}
|
||||
Logger.LogTrace("Existing [{0}] Is Better or Equal: Deleting Found File [{1}]", existing,
|
||||
fileInfo.FullName);
|
||||
if (!doJustInfo) fileInfo.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Logger.LogTrace("Moving File To [{0}]", destinationName);
|
||||
Logger.LogTrace("Moving File To [{0}]", destinationName);
|
||||
if (!doJustInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
fileInfo.MoveTo(destinationName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, "Error Moving File [{0}}", destinationName);
|
||||
Logger.LogError(ex, "Error Moving File [{0}}", destinationName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.AdditionalData.Add(PluginResultInfo.AdditionalDataKeyPluginResultInfo, new PluginResultInfo
|
||||
{
|
||||
ArtistFolder = artistFolder,
|
||||
ArtistId = this._artistId,
|
||||
ArtistId = _artistId,
|
||||
ReleaseFolder = releaseFolder,
|
||||
ReleaseId = this._releaseId,
|
||||
ReleaseId = _releaseId,
|
||||
Filename = fileInfo.FullName,
|
||||
TrackNumber = metaData.TrackNumber,
|
||||
TrackTitle = metaData.Title
|
||||
|
@ -289,51 +309,46 @@ namespace Roadie.Library.FilePlugins
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, "Error Processing File [{0}}", fileInfo);
|
||||
Logger.LogError(ex, "Error Processing File [{0}}", fileInfo);
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
this.Logger.LogTrace("<< Audio: Process Complete. Result `{0}`, ElapsedTime [{1}]", JsonConvert.SerializeObject(result), sw.ElapsedMilliseconds);
|
||||
Logger.LogTrace("<< Audio: Process Complete. Result `{0}`, ElapsedTime [{1}]",
|
||||
JsonConvert.SerializeObject(result), sw.ElapsedMilliseconds);
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<string> DetermineArtistFolder(string destinationRoot, AudioMetaData metaData, bool doJustInfo)
|
||||
private async Task<string> DetermineArtistFolder(string destinationRoot, AudioMetaData metaData,
|
||||
bool doJustInfo)
|
||||
{
|
||||
var artist = await this.ArtistLookupEngine.GetByName(metaData, !doJustInfo);
|
||||
if (!artist.IsSuccess)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var artist = await ArtistLookupEngine.GetByName(metaData, !doJustInfo);
|
||||
if (!artist.IsSuccess) return null;
|
||||
try
|
||||
{
|
||||
return artist.Data.ArtistFileFolder(this.Configuration, destinationRoot);
|
||||
return artist.Data.ArtistFileFolder(Configuration, destinationRoot);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, ex.Serialize());
|
||||
Logger.LogError(ex, ex.Serialize());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task<string> DetermineReleaseFolder(string artistFolder, AudioMetaData metaData, bool doJustInfo, int? submissionId)
|
||||
private async Task<string> DetermineReleaseFolder(string artistFolder, AudioMetaData metaData, bool doJustInfo,
|
||||
int? submissionId)
|
||||
{
|
||||
var artist = await this.ArtistLookupEngine.GetByName(metaData, !doJustInfo);
|
||||
if (!artist.IsSuccess)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
this._artistId = artist.Data.RoadieId;
|
||||
var release = await this.ReleaseLookupEngine.GetByName(artist.Data, metaData, !doJustInfo, submissionId: submissionId);
|
||||
if (!release.IsSuccess)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
this._releaseId = release.Data.RoadieId;
|
||||
var artist = await ArtistLookupEngine.GetByName(metaData, !doJustInfo);
|
||||
if (!artist.IsSuccess) return null;
|
||||
_artistId = artist.Data.RoadieId;
|
||||
var release =
|
||||
await ReleaseLookupEngine.GetByName(artist.Data, metaData, !doJustInfo, submissionId: submissionId);
|
||||
if (!release.IsSuccess) return null;
|
||||
_releaseId = release.Data.RoadieId;
|
||||
release.Data.ReleaseDate = SafeParser.ToDateTime(release.Data.ReleaseYear ?? metaData.Year);
|
||||
if(release.Data.ReleaseYear.HasValue && release.Data.ReleaseYear != metaData.Year)
|
||||
{
|
||||
this.Logger.LogWarning($"Found Release `{ release.Data }` has different Release Year than MetaData Year `{ metaData }`");
|
||||
}
|
||||
if (release.Data.ReleaseYear.HasValue && release.Data.ReleaseYear != metaData.Year)
|
||||
Logger.LogWarning(
|
||||
$"Found Release `{release.Data}` has different Release Year than MetaData Year `{metaData}`");
|
||||
return release.Data.ReleaseFileFolder(artistFolder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,13 +4,9 @@ using Roadie.Library.Configuration;
|
|||
using Roadie.Library.Encoding;
|
||||
using Roadie.Library.Engines;
|
||||
using Roadie.Library.Factories;
|
||||
using Roadie.Library.MetaData.ID3Tags;
|
||||
using Roadie.Library.Utility;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.FilePlugins
|
||||
|
@ -19,16 +15,11 @@ namespace Roadie.Library.FilePlugins
|
|||
{
|
||||
public abstract string[] HandlesTypes { get; }
|
||||
|
||||
public int MinWeightToDelete
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Configuration.FilePlugins.MinWeightToDelete;
|
||||
}
|
||||
}
|
||||
public int MinWeightToDelete => Configuration.FilePlugins.MinWeightToDelete;
|
||||
|
||||
protected IArtistFactory ArtistFactory { get; }
|
||||
|
||||
protected IArtistLookupEngine ArtistLookupEngine { get; }
|
||||
|
||||
protected ICacheManager CacheManager { get; }
|
||||
|
||||
|
@ -42,25 +33,25 @@ namespace Roadie.Library.FilePlugins
|
|||
|
||||
protected IReleaseFactory ReleaseFactory { get; }
|
||||
|
||||
protected IArtistLookupEngine ArtistLookupEngine { get; }
|
||||
protected IReleaseLookupEngine ReleaseLookupEngine { get; }
|
||||
|
||||
public PluginBase(IRoadieSettings configuration, IHttpEncoder httpEncoder, IArtistFactory artistFactory, IReleaseFactory releaseFactory, IImageFactory imageFactory, ICacheManager cacheManager, ILogger logger, IArtistLookupEngine artistLookupEngine, IReleaseLookupEngine releaseLookupEngine)
|
||||
public PluginBase(IRoadieSettings configuration, IHttpEncoder httpEncoder, IArtistFactory artistFactory,
|
||||
IReleaseFactory releaseFactory, IImageFactory imageFactory, ICacheManager cacheManager, ILogger logger,
|
||||
IArtistLookupEngine artistLookupEngine, IReleaseLookupEngine releaseLookupEngine)
|
||||
{
|
||||
this.Configuration = configuration;
|
||||
this.HttpEncoder = httpEncoder;
|
||||
this.ArtistFactory = artistFactory;
|
||||
this.ReleaseFactory = releaseFactory;
|
||||
this.ImageFactory = imageFactory;
|
||||
this.CacheManager = cacheManager;
|
||||
this.Logger = logger;
|
||||
this.ArtistLookupEngine = artistLookupEngine;
|
||||
this.ReleaseLookupEngine = releaseLookupEngine;
|
||||
|
||||
Configuration = configuration;
|
||||
HttpEncoder = httpEncoder;
|
||||
ArtistFactory = artistFactory;
|
||||
ReleaseFactory = releaseFactory;
|
||||
ImageFactory = imageFactory;
|
||||
CacheManager = cacheManager;
|
||||
Logger = logger;
|
||||
ArtistLookupEngine = artistLookupEngine;
|
||||
ReleaseLookupEngine = releaseLookupEngine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if exists if not make given folder
|
||||
/// Check if exists if not make given folder
|
||||
/// </summary>
|
||||
/// <param name="folder">Folder To Check</param>
|
||||
/// <returns>False if Exists, True if Made</returns>
|
||||
|
@ -73,11 +64,12 @@ namespace Roadie.Library.FilePlugins
|
|||
Directory.CreateDirectory(folder);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract Task<OperationResult<bool>> Process(string destinationRoot, FileInfo fileInfo, bool doJustInfo, int? submissionId);
|
||||
public abstract Task<OperationResult<bool>> Process(string destinationRoot, FileInfo fileInfo, bool doJustInfo,
|
||||
int? submissionId);
|
||||
|
||||
protected virtual bool IsFileLocked(FileInfo file)
|
||||
{
|
||||
|
@ -93,10 +85,7 @@ namespace Roadie.Library.FilePlugins
|
|||
}
|
||||
finally
|
||||
{
|
||||
if (stream != null)
|
||||
{
|
||||
stream.Close();
|
||||
}
|
||||
if (stream != null) stream.Close();
|
||||
}
|
||||
|
||||
//file is not locked
|
||||
|
|
|
@ -10,18 +10,26 @@ namespace Roadie.Library.FilePlugins
|
|||
public const string AdditionalDataKeyPluginResultInfo = "PluginResultInfo";
|
||||
|
||||
public string ArtistFolder { get; set; }
|
||||
|
||||
public Guid ArtistId { get; set; }
|
||||
|
||||
public IEnumerable<string> ArtistNames { get; set; }
|
||||
|
||||
public string Filename { get; set; }
|
||||
|
||||
public string ReleaseFolder { get; set; }
|
||||
|
||||
public Guid ReleaseId { get; set; }
|
||||
|
||||
public Statuses Status { get; set; }
|
||||
|
||||
public short? TrackNumber { get; set; }
|
||||
|
||||
public string TrackTitle { get; set; }
|
||||
|
||||
public PluginResultInfo()
|
||||
{
|
||||
this.Status = Statuses.Incomplete;
|
||||
Status = Statuses.Incomplete;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,10 +7,9 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Roadie.Library.Identity
|
||||
{
|
||||
[Table("userrole")]
|
||||
public partial class ApplicationRole : IdentityRole<int>
|
||||
public class ApplicationRole : IdentityRole<int>
|
||||
{
|
||||
[Column("createdDate")]
|
||||
public DateTime? CreatedDate { get; set; }
|
||||
[Column("createdDate")] public DateTime? CreatedDate { get; set; }
|
||||
|
||||
[Column("description")]
|
||||
[StringLength(200)]
|
||||
|
@ -20,11 +19,9 @@ namespace Roadie.Library.Identity
|
|||
//[Key]
|
||||
//public override int Id { get; set; }
|
||||
|
||||
[Column("isLocked")]
|
||||
public bool? IsLocked { get; set; }
|
||||
[Column("isLocked")] public bool? IsLocked { get; set; }
|
||||
|
||||
[Column("lastUpdated")]
|
||||
public DateTime? LastUpdated { get; set; }
|
||||
[Column("lastUpdated")] public DateTime? LastUpdated { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
[Required]
|
||||
|
@ -37,8 +34,7 @@ namespace Roadie.Library.Identity
|
|||
|
||||
public virtual ICollection<ApplicationRoleClaim> RoleClaims { get; set; }
|
||||
|
||||
[Column("status")]
|
||||
public short? Status { get; set; }
|
||||
[Column("status")] public short? Status { get; set; }
|
||||
|
||||
public virtual ICollection<ApplicationUserRole> UserRoles { get; set; }
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ namespace Roadie.Library.Identity
|
|||
{
|
||||
public virtual ApplicationRole Role { get; set; }
|
||||
|
||||
[Column("userRoleId")]
|
||||
public override int RoleId { get; set; }
|
||||
[Column("userRoleId")] public override int RoleId { get; set; }
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue