resolves #24, also most Info log writes are now Trace.

This commit is contained in:
Steven Hildreth 2019-08-03 17:59:20 -05:00
parent 872350763a
commit 891f57d89a
43 changed files with 776 additions and 291 deletions

1
.gitignore vendored
View file

@ -259,3 +259,4 @@ paket-files/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
/Roadie.Api/logs/logs.db

View file

@ -97,11 +97,11 @@ namespace Roadie.Library.Caching
{
r = await getItem();
Add(key, r, region);
Logger.LogInformation($"-+> Cache Miss for Key [{key}], Region [{region}]");
Logger.LogTrace($"-+> Cache Miss for Key [{key}], Region [{region}]");
}
else
{
Logger.LogInformation($"-!> Cache Hit for Key [{key}], Region [{region}]");
Logger.LogTrace($"-!> Cache Hit for Key [{key}], Region [{region}]");
}
return r;

View file

@ -48,8 +48,7 @@ namespace Roadie.Library.Data
public override string ToString()
{
return string.Format("Id [{0}], Name [{1}], SortName [{2}], RoadieId [{3}]", Id, Name, SortNameValue,
RoadieId);
return $"Id [{ Id }], Status [{ Status }], Name [{ Name }], SortName [{ SortNameValue}], RoadieId [{ RoadieId}]";
}
}
}

View file

@ -25,5 +25,10 @@ namespace Roadie.Library.Data
if (Bytes == null || !Bytes.Any()) return null;
return ImageHasher.AverageHash(Bytes).ToString();
}
public override string ToString()
{
return $"Id [{Id}], RoadieId [{RoadieId}]";
}
}
}

View file

@ -107,7 +107,7 @@ namespace Roadie.Library.Data
public override string ToString()
{
return $"Id [{Id}], Title [{Title}], Release Date [{ReleaseYear}]";
return $"Id [{Id}], Status [{ Status }], LibraryStatus [{ LibraryStatus }], Title [{Title}], Release Date [{ReleaseYear}]";
}
}
}

View file

@ -69,7 +69,7 @@ namespace Roadie.Library.Data
public override string ToString()
{
return string.Format("Id [{0}], TrackNumber [{1}], Title [{2}]", Id, TrackNumber, Title);
return $"Id [{ Id }], Status [{ Status }], TrackNumber [{ TrackNumber }], Title [{ Title}]";
}
/// <summary>

View file

@ -152,7 +152,7 @@ namespace Roadie.Library.Engines
inserted = await DbContext.SaveChangesAsync();
}
sw.Stop();
Logger.LogInformation($"Added New Artist: Elapsed Time [{ sw.ElapsedMilliseconds }], Artist `{ artist }`");
Logger.LogTrace($"Added New Artist: Elapsed Time [{ sw.ElapsedMilliseconds }], Artist `{ artist }`");
}
}
catch (Exception ex)
@ -232,7 +232,7 @@ namespace Roadie.Library.Engines
sw.Stop();
if (artist == null || !artist.IsValid)
{
Logger.LogInformation("ArtistLookupEngine: Artist Not Found By Name [{0}]", artistName);
Logger.LogTrace("ArtistLookupEngine: Artist Not Found By Name [{0}]", artistName);
if (doFindIfNotInDatabase)
{
OperationResult<Artist> artistSearch = null;

View file

@ -101,7 +101,7 @@ namespace Roadie.Library.Engines
sw.Stop();
if (label == null || !label.IsValid)
{
Logger.LogInformation("LabelFactory: Label Not Found By Name [{0}]", labelName);
Logger.LogTrace("LabelFactory: Label Not Found By Name [{0}]", labelName);
if (doFindIfNotInDatabase)
{
OperationResult<Label> LabelSearch = null;

View file

@ -274,7 +274,7 @@ namespace Roadie.Library.Engines
}
}
sw.Stop();
Logger.LogInformation($"Added New Release: Elapsed Time [{ sw.ElapsedMilliseconds }], Release `{ release }`");
Logger.LogTrace($"Added New Release: Elapsed Time [{ sw.ElapsedMilliseconds }], Release `{ release }`");
}
}
catch (Exception ex)
@ -342,7 +342,7 @@ namespace Roadie.Library.Engines
sw.Stop();
if (release == null || !release.IsValid)
{
Logger.LogInformation("ReleaseFactory: Release Not Found For Artist `{0}` MetaData [{1}]",
Logger.LogTrace("ReleaseFactory: Release Not Found For Artist `{0}` MetaData [{1}]",
artist.ToString(), metaData.ToString());
if (doFindIfNotInDatabase)
{

View file

@ -25,8 +25,7 @@ namespace Roadie.Library.Models.Collections
public DataToken Release { get; set; }
public Image Thumbnail { get; set; }
public static CollectionList FromDataCollection(Data.Collection collection, int foundCount,
Image collectionThumbnail)
public static CollectionList FromDataCollection(Data.Collection collection, int foundCount, Image collectionThumbnail)
{
return new CollectionList
{

View file

@ -28,18 +28,10 @@ namespace Roadie.Library.Models
public DateTime? LastUpdated { get; set; }
/// <summary>
/// Random int to sort when Random Request
/// </summary>
[AdaptIgnore]
[JsonIgnore]
public int RandomSortId { get; set; }
[MaxLength(250)] public string SortName { get; set; }
public EntityInfoModelBase()
{
RandomSortId = StaticRandom.Instance.Next();
}
}
}

View file

@ -41,7 +41,11 @@ namespace Roadie.Library.Models
public DateTime? EndDate { get; set; }
[AdaptMember("RoadieId")] public virtual Guid? Id { get; set; }
/// <summary>
/// This is the exposed Id for API consumers, not the Database Id.
/// </summary>
[AdaptMember("RoadieId")]
public virtual Guid? Id { get; set; }
public bool? IsLocked { get; set; }

View file

@ -1,4 +1,5 @@
using System;
using Newtonsoft.Json;
using System;
namespace Roadie.Library.Models
{

View file

@ -26,8 +26,7 @@ namespace Roadie.Library.Models.Playlists
public DataToken User { get; set; }
public Image UserThumbnail { get; set; }
public static PlaylistList FromDataPlaylist(Data.Playlist playlist, ApplicationUser user,
Image playlistThumbnail, Image userThumbnail)
public static PlaylistList FromDataPlaylist(Data.Playlist playlist, ApplicationUser user, Image playlistThumbnail, Image userThumbnail)
{
return new PlaylistList
{

View file

@ -35,7 +35,7 @@ namespace Roadie.Library.Models.Users
[MaxLength(250)] public string FtpUrl { get; set; }
[MaxLength(50)] public string FtpUsername { get; set; }
public int? Id { get; set; }
public new int? Id { get; set; }
public bool IsAdmin { get; set; }
public bool IsEditor { get; set; }
public bool IsPrivate { get; set; }
@ -73,9 +73,6 @@ namespace Roadie.Library.Models.Users
public DateTime LastApiAccess { get; set; }
public short? DefaultRowsPerPage { get; set; }
public override string ToString()
{
return $"Id [{Id}], RoadieId [{UserId}], UserName [{UserName}]";
}
public override string ToString() => $"Id [{Id}], RoadieId [{UserId}], UserName [{UserName}]";
}
}

View file

@ -11,7 +11,7 @@
<PackageReference Include="AutoCompare.Core" Version="1.0.0" />
<PackageReference Include="CsvHelper" Version="12.1.2" />
<PackageReference Include="EFCore.BulkExtensions" Version="2.5.2" />
<PackageReference Include="FluentFTP" Version="27.0.0" />
<PackageReference Include="FluentFTP" Version="27.0.1" />
<PackageReference Include="Hashids.net" Version="1.2.2" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.12" />
<PackageReference Include="IdSharp.Common" Version="1.0.1" />

View file

@ -65,8 +65,7 @@ namespace Roadie.Library.Scrobble
try
{
var user = DbContext.Users.FirstOrDefault(x => x.RoadieId == roadieUser.UserId);
userTrack = DbContext.UserTracks.FirstOrDefault(x =>
x.UserId == roadieUser.Id && x.TrackId == track.Id);
userTrack = DbContext.UserTracks.FirstOrDefault(x => x.UserId == user.Id && x.TrackId == track.Id);
if (userTrack == null)
{
userTrack = new data.UserTrack(now)

View file

@ -141,7 +141,7 @@ namespace Roadie.Library.MetaData.Audio
result.SetArtistName(artistNameReplaceKp.Key);
}
Logger.LogInformation("File [{0}], TagSources [{1}] MetaData [{2}]", fileInfo.Name,
Logger.LogTrace("File [{0}], TagSources [{1}] MetaData [{2}]", fileInfo.Name,
string.Join(",", tagSources), result.ToString());
return result;
}

View file

@ -136,7 +136,7 @@ namespace Roadie.Library.MetaData.LastFm
dataStream.Close();
}
var xp = GetResponseAsXml(request);
Logger.LogInformation($"LastFmHelper: RoadieUser `{roadieUser}` NowPlaying `{scrobble}` LastFmResult [{xp.InnerXml}]");
Logger.LogTrace($"LastFmHelper: RoadieUser `{roadieUser}` NowPlaying `{scrobble}` LastFmResult [{xp.InnerXml}]");
result = true;
});
}
@ -303,8 +303,7 @@ namespace Roadie.Library.MetaData.LastFm
}
var xp = GetResponseAsXml(request);
Logger.LogInformation(
$"LastFmHelper: RoadieUser `{roadieUser}` Scrobble `{scrobble}` LastFmResult [{xp.InnerXml}]");
Logger.LogTrace($"LastFmHelper: RoadieUser `{roadieUser}` Scrobble `{scrobble}` LastFmResult [{xp.InnerXml}]");
result = true;
}
catch (Exception ex)

View file

@ -0,0 +1,332 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Roadie.Library.SearchEngines.MetaData.LastFm
{
// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class scrobbles
{
private scrobblesScrobble scrobbleField;
private byte ignoredField;
private byte acceptedField;
/// <remarks/>
public scrobblesScrobble scrobble
{
get
{
return this.scrobbleField;
}
set
{
this.scrobbleField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public byte ignored
{
get
{
return this.ignoredField;
}
set
{
this.ignoredField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public byte accepted
{
get
{
return this.acceptedField;
}
set
{
this.acceptedField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class scrobblesScrobble
{
private scrobblesScrobbleTrack trackField;
private scrobblesScrobbleArtist artistField;
private scrobblesScrobbleAlbum albumField;
private scrobblesScrobbleAlbumArtist albumArtistField;
private uint timestampField;
private scrobblesScrobbleIgnoredMessage ignoredMessageField;
/// <remarks/>
public scrobblesScrobbleTrack track
{
get
{
return this.trackField;
}
set
{
this.trackField = value;
}
}
/// <remarks/>
public scrobblesScrobbleArtist artist
{
get
{
return this.artistField;
}
set
{
this.artistField = value;
}
}
/// <remarks/>
public scrobblesScrobbleAlbum album
{
get
{
return this.albumField;
}
set
{
this.albumField = value;
}
}
/// <remarks/>
public scrobblesScrobbleAlbumArtist albumArtist
{
get
{
return this.albumArtistField;
}
set
{
this.albumArtistField = value;
}
}
/// <remarks/>
public uint timestamp
{
get
{
return this.timestampField;
}
set
{
this.timestampField = value;
}
}
/// <remarks/>
public scrobblesScrobbleIgnoredMessage ignoredMessage
{
get
{
return this.ignoredMessageField;
}
set
{
this.ignoredMessageField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class scrobblesScrobbleTrack
{
private byte correctedField;
private string valueField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public byte corrected
{
get
{
return this.correctedField;
}
set
{
this.correctedField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string Value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class scrobblesScrobbleArtist
{
private byte correctedField;
private string valueField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public byte corrected
{
get
{
return this.correctedField;
}
set
{
this.correctedField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string Value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class scrobblesScrobbleAlbum
{
private byte correctedField;
private string valueField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public byte corrected
{
get
{
return this.correctedField;
}
set
{
this.correctedField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string Value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class scrobblesScrobbleAlbumArtist
{
private byte correctedField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public byte corrected
{
get
{
return this.correctedField;
}
set
{
this.correctedField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class scrobblesScrobbleIgnoredMessage
{
private byte codeField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public byte code
{
get
{
return this.codeField;
}
set
{
this.codeField = value;
}
}
}
}

View file

@ -160,7 +160,7 @@ namespace Roadie.Library.MetaData.MusicBrainz
}
else
{
Logger.LogWarning("MusicBrainzArtist: ArtistName [{0}], No MusicBrainz Artist Found", query);
Logger.LogTrace("MusicBrainzArtist: ArtistName [{0}], No MusicBrainz Artist Found", query);
}
return new OperationResult<IEnumerable<ArtistSearchResult>>
{
@ -283,7 +283,7 @@ namespace Roadie.Library.MetaData.MusicBrainz
if (result == null)
{
Logger.LogWarning("MusicBrainzArtist: ArtistName [{0}], ReleaseTitle [{0}], No MusicBrainz Release Found", artistName, query);
Logger.LogTrace("MusicBrainzArtist: ArtistName [{0}], ReleaseTitle [{0}], No MusicBrainz Release Found", artistName, query);
}
else
{

View file

@ -35,8 +35,6 @@ namespace Roadie.Api.Services
private IFileDirectoryProcessorService FileDirectoryProcessorService { get; }
private ILogger MessageLogger => EventMessageLogger as ILogger;
private IReleaseLookupEngine ReleaseLookupEngine { get; }
private IReleaseService ReleaseService { get; }
@ -501,7 +499,7 @@ namespace Roadie.Api.Services
}
sw.Stop();
await LogAndPublish($"DeleteTracks `{track}`, By User `{user}`", LogLevel.Information);
await LogAndPublish($"DeleteTracks `{track}`, By User `{user}`", LogLevel.Warning);
}
CacheManager.Clear();
return new OperationResult<bool>
@ -553,7 +551,7 @@ namespace Roadie.Api.Services
}
sw.Stop();
await LogAndPublish($"DeleteUser `{user}`, By User `{user}`", LogLevel.Information);
await LogAndPublish($"DeleteUser `{user}`, By User `{user}`", LogLevel.Warning);
CacheManager.Clear();
return new OperationResult<bool>
{
@ -565,11 +563,9 @@ namespace Roadie.Api.Services
}
/// <summary>
/// This is a very simple way to seed the database or setup configuration when the first (who becomes "Admin") user
/// registers
/// This is a very simple way to seed the database or setup configuration when the first (who becomes "Admin") user registers
/// </summary>
public async Task<OperationResult<bool>> DoInitialSetup(ApplicationUser user,
UserManager<ApplicationUser> userManager)
public async Task<OperationResult<bool>> DoInitialSetup(ApplicationUser user, UserManager<ApplicationUser> userManager)
{
var sw = new Stopwatch();
sw.Start();
@ -700,7 +696,7 @@ namespace Roadie.Api.Services
sw.Stop();
await LogAndPublish(
$"ScanAllCollections, By User `{user}`, Updated Release Count [{updatedReleaseIds.Distinct().Count()}], ElapsedTime [{sw.ElapsedMilliseconds}]",
LogLevel.Information);
LogLevel.Warning);
return new OperationResult<bool>
{
IsSuccess = !errors.Any(),
@ -769,7 +765,6 @@ namespace Roadie.Api.Services
});
await DbContext.SaveChangesAsync();
await UpdateArtistRank(artist.Id, true);
await LogAndPublish($"ScanArtist `{artist}`, By User `{user}`", LogLevel.Information);
return new OperationResult<bool>
{
IsSuccess = !errors.Any(),
@ -950,7 +945,7 @@ namespace Roadie.Api.Services
}
sw.Stop();
Logger.LogInformation(string.Format("RescanCollection `{0}`, By User `{1}`, ElapsedTime [{2}]", collection,
Logger.LogWarning(string.Format("RescanCollection `{0}`, By User `{1}`, ElapsedTime [{2}]", collection,
user, sw.ElapsedMilliseconds));
return new OperationResult<bool>
@ -966,15 +961,13 @@ namespace Roadie.Api.Services
public async Task<OperationResult<bool>> ScanInboundFolder(ApplicationUser user, bool isReadOnly = false)
{
var d = new DirectoryInfo(Configuration.InboundFolder);
var dest = new DirectoryInfo(Configuration.LibraryFolder);
return await ScanFolder(user, d, dest, isReadOnly);
return await ScanFolder(user, d, isReadOnly);
}
public async Task<OperationResult<bool>> ScanLibraryFolder(ApplicationUser user, bool isReadOnly = false)
{
var d = new DirectoryInfo(Configuration.LibraryFolder);
var dest = new DirectoryInfo(Configuration.LibraryFolder);
return await ScanFolder(user, d, dest, isReadOnly);
return await ScanFolder(user, d, isReadOnly);
}
public async Task<OperationResult<bool>> ScanRelease(ApplicationUser user, Guid releaseId, bool isReadOnly = false, bool wasDoneForInvalidTrackPlay = false)
@ -1013,9 +1006,6 @@ namespace Roadie.Api.Services
TimeSpanInSeconds = (int)sw.Elapsed.TotalSeconds
});
await DbContext.SaveChangesAsync();
await LogAndPublish(
$"ScanRelease `{release}`, By User `{user}`, WasDoneForInvalidTrackPlay [{wasDoneForInvalidTrackPlay}]",
LogLevel.Information);
return new OperationResult<bool>
{
IsSuccess = !errors.Any(),
@ -1025,10 +1015,7 @@ namespace Roadie.Api.Services
};
}
private void EventMessageLogger_Messages(object sender, EventMessage e)
{
Task.WaitAll(LogAndPublish(e.Message, e.Level));
}
private void EventMessageLogger_Messages(object sender, EventMessage e) => Task.WaitAll(LogAndPublish(e.Message, e.Level));
private async Task LogAndPublish(string message, LogLevel level = LogLevel.Trace)
{
@ -1058,7 +1045,7 @@ namespace Roadie.Api.Services
await ScanActivityHub.Clients.All.SendAsync("SendSystemActivity", message);
}
private async Task<OperationResult<bool>> ScanFolder(ApplicationUser user, DirectoryInfo d, DirectoryInfo dest, bool isReadOnly)
private async Task<OperationResult<bool>> ScanFolder(ApplicationUser user, DirectoryInfo d, bool isReadOnly)
{
var sw = new Stopwatch();
sw.Start();

View file

@ -192,7 +192,7 @@ namespace Roadie.Api.Services
await DbContext.SaveChangesAsync();
// TODO delete artist folder if empty?
CacheManager.ClearRegion(artist.CacheRegion);
Logger.LogInformation(string.Format("x DeleteArtist [{0}]", artist.Id));
Logger.LogWarning("User `{0}` deleted Artist `{1}]`", user, artist);
isSuccess = true;
}
}
@ -217,6 +217,8 @@ namespace Roadie.Api.Services
var sw = new Stopwatch();
sw.Start();
int? rowCount = null;
IQueryable<int> favoriteArtistIds = null;
if (request.FilterFavoriteOnly)
{
@ -273,8 +275,29 @@ namespace Roadie.Api.Services
var normalizedFilterValue = !string.IsNullOrEmpty(request.FilterValue)
? request.FilterValue.ToAlphanumericName()
: null;
int[] randomArtistIds = null;
if (doRandomize ??false)
{
var randomLimit = request.Limit ?? roadieUser?.RandomReleaseLimit ?? request.LimitValue;
var userId = roadieUser?.Id ?? -1;
//// This is MySQL specific but I can't figure out how else to get random without throwing EF local evaluate warnings.
var sql = @"select a.id
FROM `artist` a
WHERE(a.id NOT IN(select artistId FROM `userartist` where userId = {1} and isDisliked = 1))
OR(a.id IN(select artistId FROM `userartist` where userId = {1} and isFavorite = 1)
AND {2} = 0)
order BY RIGHT(HEX((1 << 24) * (1 + RAND())), 6)
LIMIT 0, {0}";
randomArtistIds = (from a in DbContext.Artists.FromSql(sql, randomLimit, userId, request.FilterFavoriteOnly ? "1" : "0")
select a.Id).ToArray();
rowCount = DbContext.Artists.Count();
}
var result = (from a in DbContext.Artists
where !onlyWithReleases || a.ReleaseCount > 0
where randomArtistIds == null || randomArtistIds.Contains(a.Id)
where request.FilterToArtistId == null || a.RoadieId == request.FilterToArtistId
where request.FilterMinimumRating == null || a.Rating >= request.FilterMinimumRating.Value
where request.FilterValue == "" ||
@ -311,17 +334,14 @@ namespace Roadie.Api.Services
ReleaseCount = a.ReleaseCount,
TrackCount = a.TrackCount,
SortName = a.SortName
}).Distinct();
});
ArtistList[] rows;
var rowCount = result.Count();
rowCount = rowCount ?? result.Count();
if (doRandomize ?? false)
{
var randomLimit = roadieUser?.RandomReleaseLimit ?? request.Limit;
request.Limit = request.LimitValue > randomLimit ? randomLimit : request.LimitValue;
rows = result.OrderBy(x => x.RandomSortId)
.Take(request.LimitValue)
.ToArray();
rows = result.ToArray();
}
else
{
@ -379,7 +399,7 @@ namespace Roadie.Api.Services
sw.Stop();
return new Library.Models.Pagination.PagedResult<ArtistList>
{
TotalCount = rowCount,
TotalCount = rowCount.Value,
CurrentPage = request.PageValue,
TotalPages = (int)Math.Ceiling((double)rowCount / request.LimitValue),
OperationTime = sw.ElapsedMilliseconds,
@ -426,7 +446,7 @@ namespace Roadie.Api.Services
{
CacheManager.ClearRegion(artistToMerge.CacheRegion);
CacheManager.ClearRegion(mergeIntoArtist.CacheRegion);
Logger.LogInformation("MergeArtists `{0}` => `{1}`, By User `{2}`", artistToMerge, mergeIntoArtist,
Logger.LogWarning("MergeArtists `{0}` => `{1}`, By User `{2}`", artistToMerge, mergeIntoArtist,
user);
}
}
@ -487,7 +507,7 @@ namespace Roadie.Api.Services
await DbContext.SaveChangesAsync();
sw.Stop();
CacheManager.ClearRegion(artist.CacheRegion);
Logger.LogInformation("Scanned RefreshArtistMetadata [{0}], OperationTime [{1}]",
Logger.LogTrace("Scanned RefreshArtistMetadata [{0}], OperationTime [{1}]",
artist.ToString(), sw.ElapsedMilliseconds);
}
else
@ -579,7 +599,7 @@ namespace Roadie.Api.Services
artist.LastUpdated = DateTime.UtcNow;
await DbContext.SaveChangesAsync();
CacheManager.ClearRegion(artist.CacheRegion);
Logger.LogInformation("Update Thumbnail using Artist File [{0}]", iName);
Logger.LogTrace("Update Thumbnail using Artist File [{0}]", iName);
}
}
@ -675,7 +695,7 @@ namespace Roadie.Api.Services
didRenameArtist = true;
if (Directory.Exists(originalArtistFolder))
{
Logger.LogInformation("Moving Artist From Folder [{0}] -> [{1}]", originalArtistFolder, newArtistFolder);
Logger.LogTrace("Moving Artist From Folder [{0}] -> [{1}]", originalArtistFolder, newArtistFolder);
Directory.Move(originalArtistFolder, newArtistFolder);
}
}
@ -1460,7 +1480,7 @@ namespace Roadie.Api.Services
if (!Directory.Exists(artistFolder))
{
Directory.CreateDirectory(artistFolder);
Logger.LogInformation("Created Artist Folder [0] for `artist`", artistFolder, artist);
Logger.LogTrace("Created Artist Folder [0] for `artist`", artistFolder, artist);
}
// Save unaltered image to artist file

View file

@ -154,7 +154,7 @@ namespace Roadie.Api.Services
}
sw.Stop();
Logger.LogInformation($"DeleteCollection `{collection}`, By User `{user}`");
Logger.LogWarning($"DeleteCollection `{collection}`, By User `{user}`");
return new OperationResult<bool>
{
IsSuccess = !errors.Any(),
@ -194,19 +194,43 @@ namespace Roadie.Api.Services
}
var result = from c in collections
let collectionCount = (from crc in DbContext.CollectionReleases
where crc.CollectionId == c.Id
select crc.Id).Count()
where request.FilterValue.Length == 0 ||
request.FilterValue.Length > 0 && c.Name.Contains(request.Filter)
where request.FilterToStatusValue == Statuses.Ok || c.Status == request.FilterToStatusValue
select CollectionList.FromDataCollection(c, (from crc in DbContext.CollectionReleases
where crc.CollectionId == c.Id
select crc.Id).Count(), MakeCollectionThumbnailImage(c.RoadieId));
select new CollectionList
{
DatabaseId = c.Id,
Collection = new DataToken
{
Text = c.Name,
Value = c.RoadieId.ToString()
},
Id = c.RoadieId,
CollectionCount = c.CollectionCount,
CollectionType = (c.CollectionType ?? CollectionType.Unknown).ToString(),
CollectionFoundCount = collectionCount,
CreatedDate = c.CreatedDate,
IsLocked = c.IsLocked,
LastUpdated = c.LastUpdated,
Thumbnail = MakeCollectionThumbnailImage(c.RoadieId)
};
var sortBy = string.IsNullOrEmpty(request.Sort)
? request.OrderValue(new Dictionary<string, string> { { "Collection.Text", "ASC" } })
: request.OrderValue();
var rowCount = result.Count();
var rows = result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
var rows = result
.OrderBy(sortBy)
.Skip(request.SkipValue)
.Take(request.LimitValue)
.ToArray();
if (request.FilterToStatusValue == Statuses.Incomplete)
{
rows = rows.OrderByDescending(x => x.PercentComplete).ThenBy(x => x.SortName).ToArray();
}
sw.Stop();
return Task.FromResult(new Library.Models.Pagination.PagedResult<CollectionList>
{

View file

@ -109,7 +109,7 @@ namespace Roadie.Api.Services
_addedArtistIds.AddRange(ArtistLookupEngine.AddedArtistIds);
_addedReleaseIds.AddRange(ReleaseLookupEngine.AddedReleaseIds);
_addedTrackIds.AddRange(ReleaseLookupEngine.AddedTrackIds);
Logger.LogInformation("** Completed! Processed Folder [{0}]: Processed Files [{1}] : Elapsed Time [{2}]", folder.FullName, processedFiles, sw.Elapsed);
Logger.LogInformation("Completed! Processed Folder [{0}]: Processed Files [{1}] : Elapsed Time [{2}]", folder.FullName, processedFiles, sw.Elapsed);
return new OperationResult<bool>
{
IsSuccess = !errors.Any(),
@ -143,7 +143,7 @@ namespace Roadie.Api.Services
if (!doJustInfo)
{
fileInFolder.Delete();
Logger.LogInformation("x Deleted File [{0}], Was found in in FileExtensionsToDelete",
Logger.LogTrace("Deleted File [{0}], Was found in in FileExtensionsToDelete",
fileInFolder.Name);
}
}

View file

@ -1,5 +1,6 @@
using Mapster;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Roadie.Library;
using Roadie.Library.Caching;
@ -69,7 +70,7 @@ namespace Roadie.Api.Services
File.Delete(genreImageFilename);
}
Logger.LogInformation("User `{0}` deleted Genre `{1}]`", user, genre);
Logger.LogWarning("User `{0}` deleted Genre `{1}]`", user, genre);
CacheManager.ClearRegion(genre.CacheRegion);
sw.Stop();
return new OperationResult<bool>
@ -187,13 +188,31 @@ namespace Roadie.Api.Services
var sw = new Stopwatch();
sw.Start();
int? rowCount = null;
if (!string.IsNullOrEmpty(request.Sort))
{
request.Sort = request.Sort.Replace("createdDate", "createdDateTime");
request.Sort = request.Sort.Replace("lastUpdated", "lastUpdatedDateTime");
}
int[] randomGenreIds = null;
if (doRandomize ?? false)
{
var randomLimit = request.Limit ?? roadieUser?.RandomReleaseLimit ?? request.LimitValue;
// This is MySQL specific but I can't figure out how else to get random without throwing EF local evaluate warnings.
var sql = @"select g.id
FROM `genre` g
order BY RIGHT( HEX( (1<<24) * (1+RAND()) ), 6)
LIMIT 0, {0}";
randomGenreIds = (from l in DbContext.Genres.FromSql(sql, randomLimit)
select l.Id).ToArray();
rowCount = DbContext.Genres.Count();
}
var result = from g in DbContext.Genres
where randomGenreIds == null || randomGenreIds.Contains(g.Id)
let releaseCount = (from rg in DbContext.ReleaseGenres
where rg.GenreId == g.Id
select rg.Id).Count()
@ -218,12 +237,10 @@ namespace Roadie.Api.Services
};
GenreList[] rows;
var rowCount = result.Count();
rowCount = rowCount ?? result.Count();
if (doRandomize ?? false)
{
var randomLimit = roadieUser?.RandomReleaseLimit ?? 100;
request.Limit = request.LimitValue > randomLimit ? randomLimit : request.LimitValue;
rows = result.OrderBy(x => x.RandomSortId).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
rows = result.ToArray();
}
else
{
@ -236,7 +253,7 @@ namespace Roadie.Api.Services
sw.Stop();
return Task.FromResult(new Library.Models.Pagination.PagedResult<GenreList>
{
TotalCount = rowCount,
TotalCount = rowCount.Value,
CurrentPage = request.PageValue,
TotalPages = (int)Math.Ceiling((double)rowCount / request.LimitValue),
OperationTime = sw.ElapsedMilliseconds,

View file

@ -106,7 +106,7 @@ namespace Roadie.Api.Services
if (image.ArtistId.HasValue) CacheManager.ClearRegion(data.Artist.CacheRegionUrn(image.Artist.RoadieId));
if (image.ReleaseId.HasValue) CacheManager.ClearRegion(data.Release.CacheRegionUrn(image.Release.RoadieId));
CacheManager.ClearRegion(data.Image.CacheRegionUrn(id));
Logger.LogInformation($"Deleted Image [{id}], By User [{user}]");
Logger.LogWarning("User `{0}` deleted Image `{1}]`", user, image);
sw.Stop();
return new OperationResult<bool>
{
@ -241,7 +241,7 @@ namespace Roadie.Api.Services
artistFolder = artist.ArtistFileFolder(Configuration);
if (!Directory.Exists(artistFolder))
{
Logger.LogWarning($"Artist Folder [{artistFolder}], Not Found For Artist `{artist}`");
Logger.LogTrace($"Artist Folder [{artistFolder}], Not Found For Artist `{artist}`");
}
else
{
@ -294,7 +294,7 @@ namespace Roadie.Api.Services
artistFolder = artist.ArtistFileFolder(Configuration);
if (!Directory.Exists(artistFolder))
{
Logger.LogWarning($"Artist Folder [{artistFolder}], Not Found For Artist `{artist}`");
Logger.LogTrace($"Artist Folder [{artistFolder}], Not Found For Artist `{artist}`");
}
else
{
@ -593,7 +593,7 @@ namespace Roadie.Api.Services
artistFolder = release.Artist.ArtistFileFolder(Configuration);
if (!Directory.Exists(artistFolder))
{
Logger.LogWarning($"Artist Folder [{artistFolder}], Not Found For Artist `{release.Artist}`");
Logger.LogTrace($"Artist Folder [{artistFolder}], Not Found For Artist `{release.Artist}`");
}
else
{
@ -656,7 +656,7 @@ namespace Roadie.Api.Services
artistFolder = release.Artist.ArtistFileFolder(Configuration);
if (!Directory.Exists(artistFolder))
{
Logger.LogWarning($"Artist Folder [{artistFolder}], Not Found For Artist `{release.Artist}`");
Logger.LogTrace($"Artist Folder [{artistFolder}], Not Found For Artist `{release.Artist}`");
}
else
{

View file

@ -59,7 +59,7 @@ namespace Roadie.Api.Services
File.Delete(labelImageFilename);
}
Logger.LogInformation("User `{0}` deleted Label `{1}]`", user, label);
Logger.LogWarning("User `{0}` deleted Label `{1}]`", user, label);
CacheManager.ClearRegion(label.CacheRegion);
sw.Stop();
return new OperationResult<bool>
@ -120,6 +120,8 @@ namespace Roadie.Api.Services
var sw = new Stopwatch();
sw.Start();
int? rowCount = null;
if (!string.IsNullOrEmpty(request.Sort))
{
request.Sort = request.Sort.Replace("createdDate", "createdDateTime");
@ -129,7 +131,24 @@ namespace Roadie.Api.Services
var normalizedFilterValue = !string.IsNullOrEmpty(request.FilterValue)
? request.FilterValue.ToAlphanumericName()
: null;
int[] randomLabelIds = null;
if (doRandomize ?? false)
{
var randomLimit = request.Limit ?? roadieUser?.RandomReleaseLimit ?? request.LimitValue;
// This is MySQL specific but I can't figure out how else to get random without throwing EF local evaluate warnings.
var sql = @"select l.id
FROM `label` l
order BY RIGHT( HEX( (1<<24) * (1+RAND()) ), 6)
LIMIT 0, {0}";
randomLabelIds = (from l in DbContext.Labels.FromSql(sql, randomLimit)
select l.Id).ToArray();
rowCount = DbContext.Labels.Count();
}
var result = from l in DbContext.Labels
where randomLabelIds == null || randomLabelIds.Contains(l.Id)
where request.FilterValue == "" || (
l.Name.Contains(request.FilterValue) ||
l.SortName.Contains(request.FilterValue) ||
@ -154,27 +173,27 @@ namespace Roadie.Api.Services
Thumbnail = MakeLabelThumbnailImage(l.RoadieId)
};
LabelList[] rows = null;
var rowCount = result.Count();
rowCount = rowCount ?? result.Count();
if (doRandomize ?? false)
{
var randomLimit = roadieUser?.RandomReleaseLimit ?? request.Limit;
request.Limit = request.LimitValue > randomLimit ? randomLimit : request.LimitValue;
rows = result.OrderBy(x => x.RandomSortId)
.Take(request.LimitValue)
.ToArray();
rows = result.ToArray();
}
else
{
var sortBy = string.IsNullOrEmpty(request.Sort)
? request.OrderValue(new Dictionary<string, string> { { "SortName", "ASC" }, { "Label.Text", "ASC" } })
: request.OrderValue();
rows = result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
rows = result
.OrderBy(sortBy)
.Skip(request.SkipValue)
.Take(request.LimitValue)
.ToArray();
}
sw.Stop();
return Task.FromResult(new Library.Models.Pagination.PagedResult<LabelList>
{
TotalCount = rowCount,
TotalCount = rowCount.Value,
CurrentPage = request.PageValue,
TotalPages = (int)Math.Ceiling((double)rowCount / request.LimitValue),
OperationTime = sw.ElapsedMilliseconds,

View file

@ -188,7 +188,7 @@ namespace Roadie.Api.Services
File.Delete(playlistImageFilename);
}
Logger.LogInformation("User `{0}` deleted Playlist `{1}]`", user, playlist);
Logger.LogWarning("User `{0}` deleted Playlist `{1}]`", user, playlist);
CacheManager.ClearRegion(playlist.CacheRegion);
sw.Stop();
return new OperationResult<bool>
@ -199,14 +199,14 @@ namespace Roadie.Api.Services
};
}
public Task<Library.Models.Pagination.PagedResult<PlaylistList>> List(PagedRequest request,
User roadieUser = null)
public Task<Library.Models.Pagination.PagedResult<PlaylistList>> List(PagedRequest request, User roadieUser = null)
{
var sw = new Stopwatch();
sw.Start();
var playlistWithArtistTrackIds = new int[0];
if (request.FilterToArtistId.HasValue)
{
playlistWithArtistTrackIds = (from pl in DbContext.Playlists
join pltr in DbContext.PlaylistTracks on pl.Id equals pltr.PlayListId
join t in DbContext.Tracks on pltr.TrackId equals t.Id
@ -216,8 +216,10 @@ namespace Roadie.Api.Services
where a.RoadieId == request.FilterToArtistId
select pl.Id
).ToArray();
}
var playlistReleaseTrackIds = new int[0];
if (request.FilterToReleaseId.HasValue)
{
playlistReleaseTrackIds = (from pl in DbContext.Playlists
join pltr in DbContext.PlaylistTracks on pl.Id equals pltr.PlayListId
join t in DbContext.Tracks on pltr.TrackId equals t.Id
@ -226,23 +228,45 @@ namespace Roadie.Api.Services
where r.RoadieId == request.FilterToReleaseId
select pl.Id
).ToArray();
}
var result = from pl in DbContext.Playlists
join u in DbContext.Users on pl.UserId equals u.Id
where request.FilterToPlaylistId == null || pl.RoadieId == request.FilterToPlaylistId
where request.FilterToArtistId == null || playlistWithArtistTrackIds.Contains(pl.Id)
where request.FilterToReleaseId == null || playlistReleaseTrackIds.Contains(pl.Id)
where roadieUser == null && pl.IsPublic || roadieUser != null && u.RoadieId == roadieUser.UserId ||
pl.IsPublic
where request.FilterValue.Length == 0 || request.FilterValue.Length > 0 && pl.Name != null &&
pl.Name.Contains(request.FilterValue)
select PlaylistList.FromDataPlaylist(pl, u, MakePlaylistThumbnailImage(pl.RoadieId),
MakeUserThumbnailImage(u.RoadieId));
where roadieUser == null && pl.IsPublic || roadieUser != null && u.RoadieId == roadieUser.UserId || pl.IsPublic
where request.FilterValue.Length == 0 || request.FilterValue.Length > 0 && pl.Name != null && pl.Name.Contains(request.FilterValue)
select new PlaylistList
{
Playlist = new DataToken
{
Text = pl.Name,
Value = pl.RoadieId.ToString()
},
User = new DataToken
{
Text = u.UserName,
Value = u.RoadieId.ToString()
},
PlaylistCount = pl.TrackCount,
IsPublic = pl.IsPublic,
Duration = pl.Duration,
TrackCount = pl.TrackCount,
CreatedDate = pl.CreatedDate,
LastUpdated = pl.LastUpdated,
UserThumbnail = MakeUserThumbnailImage(u.RoadieId),
Id = pl.RoadieId,
Thumbnail = MakePlaylistThumbnailImage(pl.RoadieId)
};
var sortBy = string.IsNullOrEmpty(request.Sort)
? request.OrderValue(new Dictionary<string, string> { { "Playlist.Text", "ASC" } })
: request.OrderValue();
var rowCount = result.Count();
var rows = result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
var rows = result
.OrderBy(sortBy)
.Skip(request.SkipValue)
.Take(request.LimitValue)
.ToArray();
sw.Stop();
return Task.FromResult(new Library.Models.Pagination.PagedResult<PlaylistList>
{

View file

@ -104,26 +104,26 @@ namespace Roadie.Api.Services
{
var sw = Stopwatch.StartNew();
sw.Start();
var cacheKey = string.Format("urn:release_by_id_operation:{0}:{1}", id,
includes == null ? "0" : string.Join("|", includes));
var result = await CacheManager.GetAsync(cacheKey,
async () => { return await ReleaseByIdAction(id, includes); }, data.Artist.CacheRegionUrn(id));
var cacheKey = string.Format("urn:release_by_id_operation:{0}:{1}", id, includes == null ? "0" : string.Join("|", includes));
var result = await CacheManager.GetAsync(cacheKey,async () => { return await ReleaseByIdAction(id, includes); }, data.Artist.CacheRegionUrn(id));
if (result?.Data != null && roadieUser != null)
{
var release = GetRelease(id);
var userBookmarkResult =
await BookmarkService.List(roadieUser, new PagedRequest(), false, BookmarkType.Release);
var userBookmarkResult = await BookmarkService.List(roadieUser, new PagedRequest(), false, BookmarkType.Release);
if (userBookmarkResult.IsSuccess)
result.Data.UserBookmarked =
userBookmarkResult?.Rows?.FirstOrDefault(x =>
x.Bookmark.Value == release.RoadieId.ToString()) != null;
{
result.Data.UserBookmarked = userBookmarkResult?.Rows?.FirstOrDefault(x => x.Bookmark.Value == release.RoadieId.ToString()) != null;
}
if (result.Data.Medias != null)
{
var user = GetUser(roadieUser.UserId);
foreach (var media in result.Data.Medias)
{
foreach (var track in media.Tracks)
{
track.TrackPlayUrl = MakeTrackPlayUrl(user, track.DatabaseId, track.Id);
}
}
var releaseTrackIds = result.Data.Medias.SelectMany(x => x.Tracks).Select(x => x.Id);
var releaseUserTracks = (from ut in DbContext.UserTracks
join t in DbContext.Tracks on ut.TrackId equals t.Id
@ -135,7 +135,9 @@ namespace Roadie.Api.Services
ut
}).ToArray();
if (releaseUserTracks != null && releaseUserTracks.Any())
{
foreach (var releaseUserTrack in releaseUserTracks)
{
foreach (var media in result.Data.Medias)
{
var releaseTrack = media.Tracks.FirstOrDefault(x => x.Id == releaseUserTrack.t.RoadieId);
@ -150,16 +152,19 @@ namespace Roadie.Api.Services
};
}
}
}
}
var userRelease =
DbContext.UserReleases.FirstOrDefault(x => x.ReleaseId == release.Id && x.UserId == roadieUser.Id);
var userRelease = DbContext.UserReleases.FirstOrDefault(x => x.ReleaseId == release.Id && x.UserId == roadieUser.Id);
if (userRelease != null)
{
result.Data.UserRating = new UserRelease
{
IsDisliked = userRelease.IsDisliked ?? false,
IsFavorite = userRelease.IsFavorite ?? false,
Rating = userRelease.Rating
};
}
if (result.Data.Comments.Any())
{
var commentIds = result.Data.Comments.Select(x => x.DatabaseId).ToArray();
@ -169,8 +174,7 @@ namespace Roadie.Api.Services
select cr).ToArray();
foreach (var comment in result.Data.Comments)
{
var userCommentReaction =
userCommentReactions.FirstOrDefault(x => x.CommentId == comment.DatabaseId);
var userCommentReaction = userCommentReactions.FirstOrDefault(x => x.CommentId == comment.DatabaseId);
comment.IsDisliked = userCommentReaction?.ReactionValue == CommentReaction.Dislike;
comment.IsLiked = userCommentReaction?.ReactionValue == CommentReaction.Like;
}
@ -193,22 +197,27 @@ namespace Roadie.Api.Services
{
var sw = new Stopwatch();
sw.Start();
int? rowCount = null;
IQueryable<int> collectionReleaseIds = null;
if (request.FilterToCollectionId.HasValue)
{
collectionReleaseIds = from cr in DbContext.CollectionReleases
join c in DbContext.Collections on cr.CollectionId equals c.Id
join r in DbContext.Releases on cr.ReleaseId equals r.Id
where c.RoadieId == request.FilterToCollectionId.Value
orderby cr.ListNumber
select r.Id;
}
IQueryable<int> favoriteReleaseIds = null;
if (request.FilterFavoriteOnly)
{
favoriteReleaseIds = from a in DbContext.Releases
join ur in DbContext.UserReleases on a.Id equals ur.ReleaseId
where ur.IsFavorite ?? false
where roadieUser == null || ur.UserId == roadieUser.Id
select a.Id;
}
IQueryable<int> genreReleaseIds = null;
var isFilteredToGenre = false;
if(request.FilterToGenreId.HasValue)
@ -269,8 +278,31 @@ namespace Roadie.Api.Services
var normalizedFilterValue = !string.IsNullOrEmpty(request.FilterValue)
? request.FilterValue.ToAlphanumericName()
: null;
int[] randomReleaseIds = null;
if (doRandomize ?? false)
{
var randomLimit = request.Limit ?? roadieUser?.RandomReleaseLimit ?? request.LimitValue;
var userId = roadieUser?.Id ?? -1;
// This is MySQL specific but I can't figure out how else to get random without throwing EF local evaluate warnings.
var sql = @"select r.id
FROM `release` r
WHERE (r.id NOT IN (select releaseId FROM `userrelease` where userId = {1} and isDisliked = 1))
OR (r.id IN (select releaseId FROM `userrelease` where userId = {1} and isFavorite = 1)
AND {2} = 0)
order BY RIGHT( HEX( (1<<24) * (1+RAND()) ), 6)
LIMIT 0, {0}";
randomReleaseIds = (from a in DbContext.Releases.FromSql(sql, randomLimit, userId, request.FilterFavoriteOnly ? "1" : "0")
select a.Id).ToArray();
rowCount = DbContext.Releases.Count();
}
var result = (from r in DbContext.Releases
join a in DbContext.Artists on r.ArtistId equals a.Id
where randomReleaseIds == null || randomReleaseIds.Contains(r.Id)
where request.FilterMinimumRating == null || r.Rating >= request.FilterMinimumRating.Value
where request.FilterToArtistId == null || r.Artist.RoadieId == request.FilterToArtistId
where request.FilterToCollectionId == null || collectionReleaseIds.Contains(r.Id)
@ -280,11 +312,14 @@ namespace Roadie.Api.Services
r.ReleaseDate != null && r.ReleaseDate.Value.Year <= request.FilterFromYear
where request.FilterToYear == null ||
r.ReleaseDate != null && r.ReleaseDate.Value.Year >= request.FilterToYear
where request.FilterValue == "" || r.Title.Contains(request.FilterValue) ||
where request.FilterValue == "" ||
r.Title.Contains(request.FilterValue) ||
r.AlternateNames.Contains(request.FilterValue) ||
r.AlternateNames.Contains(normalizedFilterValue)
where !isEqualFilter || r.Title.Equals(request.FilterValue) ||
r.AlternateNames.Equals(request.FilterValue) || r.AlternateNames.Equals(normalizedFilterValue)
where !isEqualFilter ||
r.Title.Equals(request.FilterValue) ||
r.AlternateNames.Equals(request.FilterValue) ||
r.AlternateNames.Equals(normalizedFilterValue)
select new ReleaseList
{
DatabaseId = r.Id,
@ -315,37 +350,53 @@ namespace Roadie.Api.Services
TrackCount = r.TrackCount,
TrackPlayedCount = r.PlayedCount
}
).Distinct();
);
ReleaseList[] rows = null;
var rowCount = result.Count();
rowCount = rowCount ?? result.Count();
if (doRandomize ?? false)
{
var randomLimit = roadieUser?.RandomReleaseLimit ?? request.Limit;
request.Limit = request.LimitValue > randomLimit ? randomLimit : request.LimitValue;
rows = result.OrderBy(x => x.RandomSortId)
.Take(request.LimitValue)
.ToArray();
rows = result.ToArray();
}
else
{
string sortBy = null;
if (request.ActionValue == User.ActionKeyUserRated)
{
sortBy = request.OrderValue(new Dictionary<string, string> { { "Rating", "DESC" } });
}
else if (request.FilterToArtistId.HasValue)
sortBy = request.OrderValue(new Dictionary<string, string>
{{"ReleaseDate", "ASC"}, {"Release.Text", "ASC"}});
{
sortBy = request.OrderValue(new Dictionary<string, string> { { "ReleaseDate", "ASC" }, { "Release.Text", "ASC" } });
}
else
{
sortBy = request.OrderValue(new Dictionary<string, string> { { "Release.Text", "ASC" } });
if (request.FilterRatedOnly) result = result.Where(x => x.Rating.HasValue);
}
if (request.FilterRatedOnly)
{
result = result.Where(x => x.Rating.HasValue);
}
if (request.FilterMinimumRating.HasValue)
result = result.Where(x =>
x.Rating.HasValue && x.Rating.Value >= request.FilterMinimumRating.Value);
{
result = result.Where(x => x.Rating.HasValue && x.Rating.Value >= request.FilterMinimumRating.Value);
}
if (request.FilterToCollectionId.HasValue)
{
rows = result.ToArray();
}
else
rows = result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
{
rows = result
.OrderBy(sortBy)
.Skip(request.SkipValue)
.Take(request.LimitValue)
.ToArray();
}
}
if (rows.Any())
@ -415,8 +466,13 @@ namespace Roadie.Api.Services
// Resort the list for the collection by listNumber
if (request.FilterToStatusValue != Statuses.Ok)
{
newRows = newRows.Where(x => x.Status == request.FilterToStatusValue).ToList();
rows = newRows.OrderBy(x => x.ListNumber).Skip(request.SkipValue).Take(request.LimitValue)
}
rows = newRows
.OrderBy(x => x.ListNumber)
.Skip(request.SkipValue)
.Take(request.LimitValue)
.ToArray();
rowCount = collection.CollectionCount;
}
@ -487,7 +543,7 @@ namespace Roadie.Api.Services
sw.Stop();
return Task.FromResult(new Library.Models.Pagination.PagedResult<ReleaseList>
{
TotalCount = rowCount,
TotalCount = rowCount.Value,
CurrentPage = request.PageValue,
TotalPages = (int)Math.Ceiling((double)rowCount / request.LimitValue),
OperationTime = sw.ElapsedMilliseconds,
@ -829,7 +885,7 @@ namespace Roadie.Api.Services
if (File.Exists(trackPath))
{
File.Delete(trackPath);
Logger.LogWarning("x For Release [{0}], Deleted File [{1}]", release.Id, trackPath);
Logger.LogWarning("For Release [{0}], Deleted File [{1}]", release.Id, trackPath);
}
}
catch (Exception ex)
@ -872,6 +928,7 @@ namespace Roadie.Api.Services
foreach (var releaseLabelId in releaseLabelIds)
await UpdateLabelCounts(releaseLabelId, now);
sw.Stop();
Logger.LogWarning("User `{0}` deleted Release `{1}]`", user, release);
return new OperationResult<bool>
{
Data = result,
@ -964,7 +1021,7 @@ namespace Roadie.Api.Services
}
zipFileName = $"{release.Artist.Name}_{release.Title}.zip".ToFileNameFriendly();
Logger.LogInformation(
Logger.LogTrace(
$"User `{roadieUser}` downloaded Release `{release}` ZipFileName [{zipFileName}], Zip Size [{zipBytes?.Length}]");
}
catch (Exception ex)
@ -1611,13 +1668,13 @@ namespace Roadie.Api.Services
var release = GetRelease(id);
if (release == null)
{
return new OperationResult<Release>(true, string.Format("Release Not Found [{0}]", id));
}
var result = release.Adapt<Release>();
result.Artist =
ArtistList.FromDataArtist(release.Artist, MakeArtistThumbnailImage(release.Artist.RoadieId));
result.Artist = ArtistList.FromDataArtist(release.Artist, MakeArtistThumbnailImage(release.Artist.RoadieId));
result.Thumbnail = MakeReleaseThumbnailImage(release.RoadieId);
result.MediumThumbnail = MakeThumbnailImage(id, "release", Configuration.MediumImageSize.Width,
Configuration.MediumImageSize.Height);
result.MediumThumbnail = MakeThumbnailImage(id, "release", Configuration.MediumImageSize.Width, Configuration.MediumImageSize.Height);
result.ReleasePlayUrl = $"{HttpContext.BaseUrl}/play/release/{release.RoadieId}";
result.Profile = release.Profile;
result.ReleaseDate = release.ReleaseDate.Value;
@ -1633,10 +1690,11 @@ namespace Roadie.Api.Services
: null;
if (release.SubmissionId.HasValue)
{
var submission = DbContext.Submissions.Include(x => x.User)
.FirstOrDefault(x => x.Id == release.SubmissionId);
var submission = DbContext.Submissions.Include(x => x.User).FirstOrDefault(x => x.Id == release.SubmissionId);
if (submission != null)
{
if (!submission.User.IsPrivate ?? false)
{
result.Submission = new ReleaseSubmission
{
User = new DataToken
@ -1648,15 +1706,19 @@ namespace Roadie.Api.Services
SubmittedDate = submission.CreatedDate
};
}
}
}
if (includes != null && includes.Any())
{
if (includes.Contains("genres"))
{
result.Genres = release.Genres.Select(x => new DataToken
{
Text = x.Genre.Name,
Value = x.Genre.RoadieId.ToString()
});
}
if (includes.Contains("stats"))
{
var releaseTracks = from r in DbContext.Releases
@ -1695,16 +1757,18 @@ namespace Roadie.Api.Services
if (includes.Contains("images"))
{
var releaseImages = DbContext.Images.Where(x => x.ReleaseId == release.Id)
.Select(x => MakeFullsizeImage(x.RoadieId, x.Caption)).ToArray();
if (releaseImages != null && releaseImages.Any()) result.Images = releaseImages;
var releaseImages = DbContext.Images.Where(x => x.ReleaseId == release.Id).Select(x => MakeFullsizeImage(x.RoadieId, x.Caption)).ToArray();
if (releaseImages != null && releaseImages.Any())
{
result.Images = releaseImages;
}
var artistFolder = release.Artist.ArtistFileFolder(Configuration);
var releaseFolder = release.ReleaseFileFolder(artistFolder);
var releaseImagesInFolder = ImageHelper.FindImageTypeInDirectory(new DirectoryInfo(releaseFolder),
ImageType.ReleaseSecondary, SearchOption.TopDirectoryOnly);
var releaseImagesInFolder = ImageHelper.FindImageTypeInDirectory(new DirectoryInfo(releaseFolder), ImageType.ReleaseSecondary, SearchOption.TopDirectoryOnly);
if (releaseImagesInFolder.Any())
result.Images = result.Images.Concat(releaseImagesInFolder.Select((x, i) =>
MakeFullsizeSecondaryImage(id, ImageType.ReleaseSecondary, i)));
{
result.Images = result.Images.Concat(releaseImagesInFolder.Select((x, i) => MakeFullsizeSecondaryImage(id, ImageType.ReleaseSecondary, i)));
}
}
if (includes.Contains("playlists"))
@ -1767,11 +1831,14 @@ namespace Roadie.Api.Services
if (includes.Contains("collections"))
{
var releaseCollections = DbContext.CollectionReleases.Include(x => x.Collection)
.Where(x => x.ReleaseId == release.Id).OrderBy(x => x.ListNumber).ToArray();
.Where(x => x.ReleaseId == release.Id)
.OrderBy(x => x.ListNumber)
.ToArray();
if (releaseCollections != null)
{
var collections = new List<ReleaseInCollection>();
foreach (var releaseCollection in releaseCollections)
{
collections.Add(new ReleaseInCollection
{
Collection = new CollectionList
@ -1797,14 +1864,17 @@ namespace Roadie.Api.Services
},
ListNumber = releaseCollection.ListNumber
});
}
result.Collections = collections;
}
}
if (includes.Contains("comments"))
{
var releaseComments = DbContext.Comments.Include(x => x.User).Where(x => x.ReleaseId == release.Id)
.OrderByDescending(x => x.CreatedDate).ToArray();
var releaseComments = DbContext.Comments.Include(x => x.User)
.Where(x => x.ReleaseId == release.Id)
.OrderByDescending(x => x.CreatedDate)
.ToArray();
if (releaseComments.Any())
{
var comments = new List<Comment>();
@ -1816,15 +1886,11 @@ namespace Roadie.Api.Services
{
var comment = releaseComment.Adapt<Comment>();
comment.DatabaseId = releaseComment.Id;
comment.User = UserList.FromDataUser(releaseComment.User,
MakeUserThumbnailImage(releaseComment.User.RoadieId));
comment.DislikedCount = userCommentReactions.Count(x =>
x.CommentId == releaseComment.Id && x.ReactionValue == CommentReaction.Dislike);
comment.LikedCount = userCommentReactions.Count(x =>
x.CommentId == releaseComment.Id && x.ReactionValue == CommentReaction.Like);
comment.User = UserList.FromDataUser(releaseComment.User, MakeUserThumbnailImage(releaseComment.User.RoadieId));
comment.DislikedCount = userCommentReactions.Count(x => x.CommentId == releaseComment.Id && x.ReactionValue == CommentReaction.Dislike);
comment.LikedCount = userCommentReactions.Count(x => x.CommentId == releaseComment.Id && x.ReactionValue == CommentReaction.Like);
comments.Add(comment);
}
result.Comments = comments;
}
}

View file

@ -763,7 +763,7 @@ namespace Roadie.Api.Services
await DbContext.SaveChangesAsync();
CacheManager.ClearRegion(artist.CacheRegion);
Logger.LogInformation("UpdatedArtistRank For Artist `{0}`", artist);
Logger.LogTrace("UpdatedArtistRank For Artist `{0}`", artist);
}
}
catch (Exception ex)
@ -899,7 +899,7 @@ namespace Roadie.Api.Services
await DbContext.SaveChangesAsync();
CacheManager.ClearRegion(release.CacheRegion);
Logger.LogInformation("UpdateReleaseRank For Release `{0}`", release);
Logger.LogTrace("UpdateReleaseRank For Release `{0}`", release);
if (updateArtistRank) await UpdateArtistsRankForRelease(release);
}
}

View file

@ -73,11 +73,13 @@ namespace Roadie.Api.Services
var result = new List<DateAndCount>();
var dateInfos = (from r in DbContext.Releases
orderby r.CreatedDate
group r by r.CreatedDate.ToString("yyyy-MM-dd") into g
select new
select r.CreatedDate)
.ToArray()
.GroupBy(x => x.ToString("yyyy-MM-dd"))
.Select(x => new
{
date = g.Key,
count = g.Count()
date = x.Key,
count = x.Count()
});
foreach (var dateInfo in dateInfos)
{

View file

@ -126,7 +126,7 @@ namespace Roadie.Api.Services
.FirstOrDefault(x => x.UserName == request.u);
if (user == null)
{
Logger.LogInformation($"Unknown User [{request.u}]");
Logger.LogTrace($"Unknown User [{request.u}]");
return new subsonic.SubsonicOperationResult<subsonic.SubsonicAuthenticateResponse>(
subsonic.ErrorCodes.WrongUsernameOrPassword, "Unknown Username");
}
@ -163,12 +163,12 @@ namespace Roadie.Api.Services
if (user == null)
{
Logger.LogInformation($"Invalid Credentials given for User [{request.u}]");
Logger.LogTrace($"Invalid Credentials given for User [{request.u}]");
return new subsonic.SubsonicOperationResult<subsonic.SubsonicAuthenticateResponse>(
subsonic.ErrorCodes.WrongUsernameOrPassword, "Unknown Username");
}
Logger.LogInformation(
Logger.LogTrace(
$"Subsonic: Successfully Authenticated User [{user}] via Application [{request.c}], Application Version [{request.v}]");
return new subsonic.SubsonicOperationResult<subsonic.SubsonicAuthenticateResponse>
{
@ -230,7 +230,7 @@ namespace Roadie.Api.Services
var user = GetUser(roadieUser.UserId);
CacheManager.ClearRegion(user.CacheRegion);
Logger.LogInformation(
Logger.LogTrace(
$"{(createdBookmark ? "Created" : "Updated")} Bookmark `{userBookmark}` for User `{roadieUser}`");
return new subsonic.SubsonicOperationResult<subsonic.Response>
{
@ -326,7 +326,7 @@ namespace Roadie.Api.Services
}
await DbContext.SaveChangesAsync();
Logger.LogInformation(
Logger.LogTrace(
$"Subsonic: User `{roadieUser}` {(didCreate ? "created" : "modified")} Playlist `{playlist}` added [{songRoadieIds.Count()}] Tracks.");
request.id = subsonic.Request.PlaylistdIdentifier + playlist.RoadieId;
return await GetPlaylist(request, roadieUser);
@ -355,7 +355,7 @@ namespace Roadie.Api.Services
var user = GetUser(roadieUser.UserId);
CacheManager.ClearRegion(user.CacheRegion);
Logger.LogInformation($"Subsonic: Deleted Bookmark `{userBookmark}` for User `{roadieUser}`");
Logger.LogTrace($"Subsonic: Deleted Bookmark `{userBookmark}` for User `{roadieUser}`");
}
return new subsonic.SubsonicOperationResult<subsonic.Response>
@ -372,28 +372,27 @@ namespace Roadie.Api.Services
/// <summary>
/// Deletes a saved playlist.
/// </summary>
public async Task<subsonic.SubsonicOperationResult<subsonic.Response>> DeletePlaylist(subsonic.Request request,
User roadieUser)
public async Task<subsonic.SubsonicOperationResult<subsonic.Response>> DeletePlaylist(subsonic.Request request,User roadieUser)
{
if (!request.PlaylistId.HasValue)
return new subsonic.SubsonicOperationResult<subsonic.Response>(
subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Playlist Id [{request.id}]");
var playlist = GetPlaylist(request.PlaylistId.Value);
if (playlist == null)
return new subsonic.SubsonicOperationResult<subsonic.Response>(
subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Playlist Id [{request.TrackId.Value}]");
if (playlist.UserId != roadieUser.Id && !roadieUser.IsAdmin)
return new subsonic.SubsonicOperationResult<subsonic.Response>(
subsonic.ErrorCodes.UserIsNotAuthorizedForGivenOperation,
"User is not allowed to delete playlist.");
DbContext.Playlists.Remove(playlist);
await DbContext.SaveChangesAsync();
var user = GetUser(roadieUser.UserId);
CacheManager.ClearRegion(user.CacheRegion);
Logger.LogInformation($"Subsonic: Deleted Playlist `{playlist}` for User `{roadieUser}`");
//request.PlaylistId.Value
var deleteResult = await PlaylistService.DeletePlaylist(roadieUser, request.PlaylistId.Value);
if (deleteResult == null || deleteResult.IsNotFoundResult)
{
return new subsonic.SubsonicOperationResult<subsonic.Response>(subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Playlist Id [{request.id}]");
}
if (!deleteResult.IsSuccess)
{
if (deleteResult.IsAccessDeniedResult)
{
return new subsonic.SubsonicOperationResult<subsonic.Response>(subsonic.ErrorCodes.UserIsNotAuthorizedForGivenOperation, "User is not allowed to delete playlist.");
}
if (deleteResult.Messages?.Any() ?? false)
{
return new subsonic.SubsonicOperationResult<subsonic.Response>(subsonic.ErrorCodes.Generic, deleteResult.Messages.First());
}
return new subsonic.SubsonicOperationResult<subsonic.Response>(subsonic.ErrorCodes.Generic, "An Error Occured");
}
return new subsonic.SubsonicOperationResult<subsonic.Response>
{
IsSuccess = true,

View file

@ -204,7 +204,9 @@ namespace Roadie.Api.Services
};
rowCount = playlistTrackInfos.Count();
playListTrackPositions = playlistTrackInfos.Skip(request.SkipValue).Take(request.LimitValue)
playListTrackPositions = playlistTrackInfos
.Skip(request.SkipValue)
.Take(request.LimitValue)
.ToDictionary(x => x.Id, x => x.ListNumber);
playlistTrackIds = playListTrackPositions.Select(x => x.Key).ToArray();
request.Sort = "TrackNumber";
@ -225,7 +227,10 @@ namespace Roadie.Api.Services
join t in DbContext.Tracks on rm.Id equals t.ReleaseMediaId
where c.RoadieId == request.FilterToCollectionId.Value
orderby cr.ListNumber, rm.MediaNumber, t.TrackNumber
select t.Id).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
select t.Id)
.Skip(request.SkipValue)
.Take(request.LimitValue)
.ToArray();
}
IQueryable<int> topTrackids = null;
@ -247,43 +252,28 @@ namespace Roadie.Api.Services
int[] randomTrackIds = null;
if (doRandomize ?? false)
{
var randomLimit = roadieUser?.RandomReleaseLimit ?? request.Limit ?? 50;
var randomLimit = request.Limit ?? roadieUser?.RandomReleaseLimit ?? request.LimitValue;
var userId = roadieUser?.Id ?? -1;
// Select random tracks that are not disliked Artist, Release or Track by user.
var dislikedArtistIds = (from ua in DbContext.UserArtists
where ua.UserId == userId
where ua.IsDisliked == true
select ua.ArtistId).ToArray();
var dislikedReleaseIds = (from ur in DbContext.UserReleases
where ur.UserId == userId
where ur.IsDisliked == true
select ur.ReleaseId).ToArray();
var dislikedTrackIds = (from ut in DbContext.UserTracks
where ut.UserId == userId
where ut.IsDisliked == true
select ut.TrackId).ToArray();
int[] favoritedTrackIds = null;
if (request.FilterFavoriteOnly)
{
favoritedTrackIds = (from ut in DbContext.UserTracks
where ut.UserId == userId
where ut.IsFavorite == true
select ut.TrackId).ToArray();
favoriteTrackIds = new int[0].AsQueryable();
request.FilterFavoriteOnly = false;
}
randomTrackIds = TrackList.Shuffle((from t in DbContext.Tracks
// This is MySQL specific but I can't figure out how else to get random without throwing EF local evaluate warnings.
var sql = @"select t.id
FROM `track` t
JOIN `releasemedia` rm on(t.releaseMediaId = rm.id)
JOIN `release` r on(rm.releaseId = r.id)
WHERE (t.id NOT IN(select trackId FROM `usertrack` where userId = {1} and isDisliked = 1)
AND r.id NOT IN(select releaseId FROM `userrelease` where userId = {1} and isDisliked = 1)
AND r.artistId NOT IN(select artistId FROM `userartist` where userId = {1} and isDisliked = 1)
AND t.artistId NOT IN(select artistId FROM `userartist` where userId = {1} and isDisliked = 1))
OR (t.id IN(select trackId FROM `usertrack` where userId = {1} and isFavorite = 1)
AND {2} = 1)
order BY RIGHT(HEX((1 << 24) * (1 + RAND())), 6)
LIMIT 0, {0}";
randomTrackIds = TrackList.Shuffle((from tr in DbContext.Tracks.FromSql(sql, randomLimit, userId, request.FilterFavoriteOnly ? "1" : "0")
join t in DbContext.Tracks on tr.Id equals t.Id
join rm in DbContext.ReleaseMedias on t.ReleaseMediaId equals rm.Id
join r in DbContext.Releases on rm.ReleaseId equals r.Id
join a in DbContext.Artists on r.ArtistId equals a.Id
where !request.FilterRatedOnly || request.FilterRatedOnly && t.Rating > 0
where !dislikedArtistIds.Contains(r.ArtistId)
where !dislikedArtistIds.Contains(t.ArtistId ?? 0)
where !dislikedReleaseIds.Contains(r.Id)
where !dislikedTrackIds.Contains(t.Id)
where favoritedTrackIds == null || favoritedTrackIds.Contains(t.Id)
where t.Hash != null
select new TrackList
{
DatabaseId = t.Id,
@ -293,13 +283,12 @@ namespace Roadie.Api.Services
},
Release = new ReleaseList
{
Release = new DataToken { Value = r.RoadieId.ToString(), Text = r.Title}
Release = new DataToken { Value = r.RoadieId.ToString(), Text = r.Title }
}
})
.OrderBy(x => x.RandomSortId)
.Take(randomLimit))
}).ToArray())
.Select(x => x.DatabaseId)
.ToArray();
rowCount = DbContext.Tracks.Count();
}
Guid?[] filterToTrackIds = null;
@ -516,19 +505,21 @@ namespace Roadie.Api.Services
}
}
if (doRandomize ?? false)
if(doRandomize ?? false)
{
var randomLimit = roadieUser?.RandomReleaseLimit ?? request.Limit;
request.Limit = request.LimitValue > randomLimit ? randomLimit : request.LimitValue;
//rows = result.OrderBy(x => x.Artist.RandomSortId)
// .ThenBy(x => x.RandomSortId)
// .ToArray();
rows = result.OrderBy(x => x.Artist.RandomSortId)
.ThenBy(x => x.RandomSortId)
.Take(request.LimitValue)
.ToArray();
rows = result.ToArray();
}
else
{
rows = result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
rows = result
.OrderBy(sortBy)
.Skip(request.SkipValue)
.Take(request.LimitValue)
.ToArray();
}
if (rows.Any() && roadieUser != null)

View file

@ -350,7 +350,7 @@ namespace Roadie.Api.Services
timings.Add("SetTrackRating", sw.ElapsedMilliseconds);
result.AdditionalData.Add("Timing", sw.ElapsedMilliseconds);
Logger.LogInformation(
Logger.LogTrace(
$"User `{roadieUser}` set rating [{rating}] on TrackId [{trackId}]. Result [{JsonConvert.SerializeObject(result)}]");
return result;
}
@ -546,7 +546,7 @@ namespace Roadie.Api.Services
CacheManager.ClearRegion(ApplicationUser.CacheRegionUrn(user.RoadieId));
Logger.LogInformation($"User `{user}` Updated LastFm SessionKey");
Logger.LogTrace($"User `{user}` Updated LastFm SessionKey");
return new OperationResult<bool>
{

View file

@ -87,7 +87,7 @@ namespace Roadie.Api.Controllers
var result = UserManager.ConfirmEmailAsync(user, code).Result;
if (result.Succeeded)
{
Logger.LogInformation("User [{0}] Confirmed Email Successfully", userid);
Logger.LogTrace("User [{0}] Confirmed Email Successfully", userid);
return Content($"Email for {RoadieSettings.SiteName} account confirmed successfully!");
}
@ -113,7 +113,7 @@ namespace Roadie.Api.Controllers
user.LastUpdated = now;
await UserManager.UpdateAsync(user);
var t = await TokenService.GenerateToken(user, UserManager);
Logger.LogInformation($"Successfully authenticated User [{model.Username}]");
Logger.LogTrace($"Successfully authenticated User [{model.Username}]");
if (!user.EmailConfirmed)
try
{
@ -194,7 +194,7 @@ namespace Roadie.Api.Controllers
var tokenValidation = await AdminService.ValidateInviteToken(registerModel.InviteToken);
if(!tokenValidation.IsSuccess)
{
Logger.LogInformation("Invalid Token");
Logger.LogTrace("Invalid Invite Token");
return StatusCode((int)HttpStatusCode.BadRequest, new { Title = "Invite Token Is Required" });
}
}
@ -217,7 +217,7 @@ namespace Roadie.Api.Controllers
await SignInManager.SignInAsync(user, false);
var t = await TokenService.GenerateToken(user, UserManager);
Logger.LogInformation($"Successfully created and authenticated User [{registerModel.Username}]");
Logger.LogTrace($"Successfully created and authenticated User [{registerModel.Username}]");
CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
var avatarUrl = $"{RoadieHttpContext.ImageBaseUrl}/user/{user.RoadieId}/{RoadieSettings.ThumbnailImageSize.Width}/{RoadieSettings.ThumbnailImageSize.Height}";
if (registerModel.InviteToken.HasValue)
@ -307,7 +307,7 @@ namespace Roadie.Api.Controllers
{
await EmailSender.SendEmailAsync(user.Email, $"Reset your {RoadieSettings.SiteName} password",
$"A request has been made to reset your password for your {RoadieSettings.SiteName} account. To proceed <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>click here</a>.");
Logger.LogInformation("User [{0}] Email [{1}] Requested Password Reset Callback [{2}]", username,
Logger.LogTrace("User [{0}] Email [{1}] Requested Password Reset Callback [{2}]", username,
user.Email, callbackUrl);
return Ok();
}

View file

@ -34,7 +34,7 @@ namespace Roadie.Api.Controllers
public IActionResult ClearCache()
{
CacheManager.Clear();
Logger.LogInformation("Cache Cleared");
Logger.LogWarning("Cache Cleared");
return Ok();
}

View file

@ -1,5 +1,4 @@
using Mapster;
using Microsoft.AspNet.OData;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
@ -15,11 +14,12 @@ using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web.Http;
using models = Roadie.Library.Models.Users;
namespace Roadie.Api.Controllers
{
public abstract class EntityControllerBase : ODataController
public abstract class EntityControllerBase : Controller
{
public const string ControllerCacheRegionUrn = "urn:controller_cache";
@ -132,8 +132,7 @@ namespace Roadie.Api.Controllers
};
await playActivityService.NowPlaying(user, scrobble);
sw.Stop();
Logger.LogInformation(
$"StreamTrack ElapsedTime [{sw.ElapsedMilliseconds}], Timings [{JsonConvert.SerializeObject(timings)}], StreamInfo `{info?.Data}`");
Logger.LogTrace($"StreamTrack ElapsedTime [{sw.ElapsedMilliseconds}], Timings [{JsonConvert.SerializeObject(timings)}], StreamInfo `{info?.Data}`");
return new EmptyResult();
}

View file

@ -39,10 +39,15 @@ namespace Roadie.Api.Controllers
[ProducesResponseType(404)]
public async Task<IActionResult> Get(Guid id, string inc = null)
{
var result = await ReleaseService.ById(await CurrentUserModel(), id,
(inc ?? Release.DefaultIncludes).ToLower().Split(","));
if (result == null || result.IsNotFoundResult) return NotFound();
if (!result.IsSuccess) return StatusCode((int)HttpStatusCode.InternalServerError);
var result = await ReleaseService.ById(await CurrentUserModel(), id, (inc ?? Release.DefaultIncludes).ToLower().Split(","));
if (result == null || result.IsNotFoundResult)
{
return NotFound();
}
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
return Ok(result);
}

View file

@ -15,9 +15,7 @@ namespace Roadie.Api
public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", false, true)
.AddJsonFile(
$"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json",
true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true)
.AddEnvironmentVariables()
.Build();
@ -25,7 +23,6 @@ namespace Roadie.Api
{
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.WriteTo.RollingFileAlternate("logs", "errors", LogEventLevel.Error)
.CreateLogger();
try
@ -36,13 +33,11 @@ namespace Roadie.Api
#if DEBUG
// Logging Output tests
Log.Verbose(
":: Log Test: Verbose (Trace,None)"); // Microsoft.Extensions.Logging.LogLevel.Trace and Microsoft.Extensions.Logging.LogLevel.None
Log.Verbose(":: Log Test: Verbose (Trace,None)"); // Microsoft.Extensions.Logging.LogLevel.Trace and Microsoft.Extensions.Logging.LogLevel.None
Log.Debug(":: Log Test: Debug"); // Microsoft.Extensions.Logging.LogLevel.Debug
Log.Information(":: Log Test: Information"); // Microsoft.Extensions.Logging.LogLevel.Information
Log.Warning(":: Log Test: Warning"); // Microsoft.Extensions.Logging.LogLevel.Warning
Log.Error(new Exception("Log Test Exception"),
"Log Test Error Message"); // Microsoft.Extensions.Logging.LogLevel.Error
Log.Error(new Exception("Log Test Exception"), "Log Test Error Message"); // Microsoft.Extensions.Logging.LogLevel.Error
Log.Fatal(":: Log Test: Fatal (Critial)"); // Microsoft.Extensions.Logging.LogLevel.Critical
Trace.WriteLine(":: Log Test: Trace WriteLine()");
#endif

View file

@ -18,7 +18,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\Images\" />
<Folder Include="wwwroot\images\" />
</ItemGroup>
<ItemGroup>
@ -27,16 +27,19 @@
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.10.0" />
<PackageReference Include="Microsoft.AspNet.SignalR" Version="2.4.1" />
<PackageReference Include="Microsoft.AspNetCore.All" />
<PackageReference Include="Microsoft.AspNetCore.OData" Version="7.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.2.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.2.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.3" />
<PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" />
<PackageReference Include="Serilog.Exceptions" Version="5.3.1" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.LiteDB.NetStandard" Version="1.0.14" />
<PackageReference Include="Serilog.Sinks.RollingFileAlternate" Version="2.0.9" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.5.0" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.18" />

View file

@ -7,7 +7,7 @@
}
},
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.RollingFileAlternate" ],
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.RollingFileAlternate", "Serilog.Sinks.LiteDB" ],
"MinimumLevel": {
"Default": "Verbose",
"Override": {
@ -21,16 +21,23 @@
"Name": "Console",
"Args": {
"theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
"restrictedToMinimumLevel": "Information"
}
},
{
"Name": "LiteDB",
"Args": {
"databaseUrl": "logs\\logs.db",
"restrictedToMinimumLevel": "Verbose"
}
},
{
"Name": "RollingFileAlternate",
"Args": {
"restrictedToMinimumLevel": "Warning",
"path": "{Date}.log",
"minimumLevel": "Verbose",
"logDirectory": "logs",
"fileSizeLimitBytes": 26214400,
"retainedFileCountLimit": 30,
"buffered": true
}
}

View file

@ -21,7 +21,7 @@
"Name": "Console",
"Args": {
"theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
"restrictedToMinimumLevel": "Verbose"
"restrictedToMinimumLevel": "Warning"
}
},
{