mirror of
https://github.com/sphildreth/roadie
synced 2024-11-21 19:53:11 +00:00
Updated NuGet packages, fixed LastFM integration, formatting and performance tweaks, bumped to v1.1.4
This commit is contained in:
parent
7fc99893e3
commit
5768316587
24 changed files with 257 additions and 196 deletions
|
@ -1,9 +1,6 @@
|
|||
using System.Threading.Tasks;
|
||||
using Roadie.Library.Models.Users;
|
||||
|
||||
namespace Roadie.Library.Scrobble
|
||||
namespace Roadie.Library.Scrobble
|
||||
{
|
||||
public interface ILastFMScrobbler : IScrobblerIntegration
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
using System.Threading.Tasks;
|
||||
using Roadie.Library.Models.Users;
|
||||
|
||||
namespace Roadie.Library.Scrobble
|
||||
namespace Roadie.Library.Scrobble
|
||||
{
|
||||
public interface IRoadieScrobbler : IScrobblerIntegration
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,4 +15,4 @@ namespace Roadie.Library.Scrobble
|
|||
/// </summary>
|
||||
Task<OperationResult<bool>> Scrobble(User user, ScrobbleInfo scrobble);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,10 @@ namespace Roadie.Library.Scrobble
|
|||
{
|
||||
public interface IScrobblerIntegration
|
||||
{
|
||||
int SortOrder { get; }
|
||||
|
||||
Task<OperationResult<bool>> NowPlaying(User roadieUser, ScrobbleInfo scrobble);
|
||||
|
||||
Task<OperationResult<bool>> Scrobble(User roadieUser, ScrobbleInfo scrobble);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ using Roadie.Library.MetaData.LastFm;
|
|||
using Roadie.Library.Models.Users;
|
||||
using Roadie.Library.Utility;
|
||||
using System.Threading.Tasks;
|
||||
using data = Roadie.Library.Data;
|
||||
|
||||
namespace Roadie.Library.Scrobble
|
||||
{
|
||||
|
@ -16,10 +15,17 @@ namespace Roadie.Library.Scrobble
|
|||
/// </summary>
|
||||
public class LastFMScrobbler : ScrobblerIntegrationBase, ILastFMScrobbler
|
||||
{
|
||||
public override int SortOrder => 0;
|
||||
|
||||
private ILastFmHelper LastFmHelper { get; }
|
||||
|
||||
public LastFMScrobbler(IRoadieSettings configuration, ILogger<LastFMScrobbler> logger, IRoadieDbContext dbContext,
|
||||
ICacheManager cacheManager, ILastFmHelper lastFmHelper, IHttpContext httpContext)
|
||||
public LastFMScrobbler(
|
||||
IRoadieSettings configuration,
|
||||
ILogger<LastFMScrobbler> logger,
|
||||
IRoadieDbContext dbContext,
|
||||
ICacheManager cacheManager,
|
||||
ILastFmHelper lastFmHelper,
|
||||
IHttpContext httpContext)
|
||||
: base(configuration, logger, dbContext, cacheManager, httpContext)
|
||||
{
|
||||
LastFmHelper = lastFmHelper;
|
||||
|
@ -43,6 +49,5 @@ namespace Roadie.Library.Scrobble
|
|||
/// </remark>
|
||||
/// </summary>
|
||||
public override async Task<OperationResult<bool>> Scrobble(User roadieUser, ScrobbleInfo scrobble) => await LastFmHelper.Scrobble(roadieUser, scrobble).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ using Roadie.Library.Models.Users;
|
|||
using Roadie.Library.Utility;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using data = Roadie.Library.Data;
|
||||
|
||||
|
@ -15,19 +14,27 @@ namespace Roadie.Library.Scrobble
|
|||
{
|
||||
public class RoadieScrobbler : ScrobblerIntegrationBase, IRoadieScrobbler
|
||||
{
|
||||
public override int SortOrder => 99; // Ensure that the Roadie Scrobbler is last due to heavy database and cache manipulation
|
||||
|
||||
public RoadieScrobbler(IRoadieSettings configuration, ILogger logger, IRoadieDbContext dbContext, ICacheManager cacheManager)
|
||||
public RoadieScrobbler(
|
||||
IRoadieSettings configuration,
|
||||
ILogger logger,
|
||||
IRoadieDbContext dbContext,
|
||||
ICacheManager cacheManager)
|
||||
: base(configuration, logger, dbContext, cacheManager, null)
|
||||
{
|
||||
}
|
||||
|
||||
public RoadieScrobbler(IRoadieSettings configuration, ILogger<RoadieScrobbler> logger, IRoadieDbContext dbContext,
|
||||
ICacheManager cacheManager, IHttpContext httpContext)
|
||||
public RoadieScrobbler(
|
||||
IRoadieSettings configuration,
|
||||
ILogger<RoadieScrobbler> logger,
|
||||
IRoadieDbContext dbContext,
|
||||
ICacheManager cacheManager,
|
||||
IHttpContext httpContext)
|
||||
: base(configuration, logger, dbContext, cacheManager, httpContext)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// For Roadie we only add a user play on the full scrobble event, otherwise we get double track play numbers.
|
||||
/// </summary>
|
||||
|
@ -48,7 +55,7 @@ namespace Roadie.Library.Scrobble
|
|||
try
|
||||
{
|
||||
// If a user and If less than half of duration then do nothing
|
||||
if (roadieUser != null &&
|
||||
if (roadieUser != null &&
|
||||
scrobble.ElapsedTimeOfTrackPlayed.TotalSeconds < scrobble.TrackDuration.TotalSeconds / 2)
|
||||
{
|
||||
Logger.LogTrace("Skipping Scrobble, Playback did not exceed minimum elapsed time");
|
||||
|
@ -81,22 +88,25 @@ namespace Roadie.Library.Scrobble
|
|||
{
|
||||
if (roadieUser != null)
|
||||
{
|
||||
var user = await DbContext.Users.FirstOrDefaultAsync(x => x.RoadieId == roadieUser.UserId).ConfigureAwait(false);
|
||||
userTrack = await DbContext.UserTracks.FirstOrDefaultAsync(x => x.UserId == user.Id && x.TrackId == track.Id).ConfigureAwait(false);
|
||||
if (userTrack == null)
|
||||
// User should be cached if not then skip as probably a bad user
|
||||
var user = CacheManager.Get<Identity.User>(Identity.User.CacheUrn(roadieUser.UserId));
|
||||
if (user != null)
|
||||
{
|
||||
userTrack = new data.UserTrack(now)
|
||||
userTrack = await DbContext.UserTracks.FirstOrDefaultAsync(x => x.UserId == user.Id && x.TrackId == track.Id).ConfigureAwait(false);
|
||||
if (userTrack == null)
|
||||
{
|
||||
UserId = user.Id,
|
||||
TrackId = track.Id
|
||||
};
|
||||
await DbContext.UserTracks.AddAsync(userTrack).ConfigureAwait(false);
|
||||
userTrack = new data.UserTrack(now)
|
||||
{
|
||||
UserId = user.Id,
|
||||
TrackId = track.Id
|
||||
};
|
||||
await DbContext.UserTracks.AddAsync(userTrack).ConfigureAwait(false);
|
||||
}
|
||||
userTrack.LastPlayed = now;
|
||||
userTrack.PlayedCount = (userTrack.PlayedCount ?? 0) + 1;
|
||||
|
||||
CacheManager.ClearRegion(user.CacheRegion);
|
||||
}
|
||||
|
||||
userTrack.LastPlayed = now;
|
||||
userTrack.PlayedCount = (userTrack.PlayedCount ?? 0) + 1;
|
||||
|
||||
CacheManager.ClearRegion(user.CacheRegion);
|
||||
}
|
||||
|
||||
track.PlayedCount = (track.PlayedCount ?? 0) + 1;
|
||||
|
@ -139,7 +149,7 @@ namespace Roadie.Library.Scrobble
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex,$"Error in Scrobble, Creating UserTrack: User `{roadieUser}` TrackId [{track.Id}");
|
||||
Logger.LogError(ex, $"Error in Scrobble, Creating UserTrack: User `{roadieUser}` TrackId [{track.Id}");
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
|
@ -159,4 +169,4 @@ namespace Roadie.Library.Scrobble
|
|||
return new OperationResult<bool>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,12 @@ namespace Roadie.Library.Scrobble
|
|||
|
||||
private IEnumerable<IScrobblerIntegration> Scrobblers { get; }
|
||||
|
||||
public ScrobbleHandler(IRoadieSettings configuration, ILogger logger, IRoadieDbContext dbContext, ICacheManager cacheManager, RoadieScrobbler roadieScrobbler)
|
||||
public ScrobbleHandler(
|
||||
IRoadieSettings configuration,
|
||||
ILogger logger,
|
||||
IRoadieDbContext dbContext,
|
||||
ICacheManager cacheManager,
|
||||
IRoadieScrobbler roadieScrobbler)
|
||||
{
|
||||
Logger = logger;
|
||||
Configuration = configuration;
|
||||
|
@ -43,9 +48,16 @@ namespace Roadie.Library.Scrobble
|
|||
Scrobblers = scrobblers;
|
||||
}
|
||||
|
||||
public ScrobbleHandler(IRoadieSettings configuration, ILogger<ScrobbleHandler> logger, IRoadieDbContext dbContext,
|
||||
ICacheManager cacheManager, IHttpEncoder httpEncoder, IHttpContext httpContext,
|
||||
ILastFmHelper lastFmHelper, IRoadieScrobbler roadieScrobbler, ILastFMScrobbler lastFMScrobbler)
|
||||
public ScrobbleHandler(
|
||||
IRoadieSettings configuration,
|
||||
ILogger<ScrobbleHandler> logger,
|
||||
IRoadieDbContext dbContext,
|
||||
ICacheManager cacheManager,
|
||||
IHttpEncoder httpEncoder,
|
||||
IHttpContext httpContext,
|
||||
ILastFmHelper lastFmHelper,
|
||||
IRoadieScrobbler roadieScrobbler,
|
||||
ILastFMScrobbler lastFMScrobbler)
|
||||
{
|
||||
Logger = logger;
|
||||
Configuration = configuration;
|
||||
|
@ -110,7 +122,7 @@ namespace Roadie.Library.Scrobble
|
|||
public async Task<OperationResult<bool>> Scrobble(User user, ScrobbleInfo scrobble)
|
||||
{
|
||||
var s = await GetScrobbleInfoDetailsAsync(scrobble).ConfigureAwait(false);
|
||||
foreach (var scrobbler in Scrobblers)
|
||||
foreach (var scrobbler in Scrobblers.OrderBy(x => x.SortOrder))
|
||||
{
|
||||
await scrobbler.Scrobble(user, s).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -121,4 +133,4 @@ namespace Roadie.Library.Scrobble
|
|||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,14 +6,21 @@ namespace Roadie.Library.Scrobble
|
|||
public class ScrobbleInfo
|
||||
{
|
||||
public string ArtistName { get; set; }
|
||||
|
||||
public TimeSpan ElapsedTimeOfTrackPlayed => DateTime.UtcNow.Subtract(TimePlayed);
|
||||
|
||||
public bool IsRandomizedScrobble { get; set; }
|
||||
|
||||
public string ReleaseTitle { get; set; }
|
||||
|
||||
public DateTime TimePlayed { get; set; }
|
||||
|
||||
public TimeSpan TrackDuration { get; set; }
|
||||
|
||||
public Guid TrackId { get; set; }
|
||||
|
||||
public string TrackNumber { get; set; }
|
||||
|
||||
public string TrackTitle { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
|
@ -21,4 +28,4 @@ namespace Roadie.Library.Scrobble
|
|||
return $"Artist: [{ArtistName}], Release: [{ReleaseTitle}], Track# [{TrackNumber}], Track [{TrackTitle}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ using Roadie.Library.Data.Context;
|
|||
using Roadie.Library.Models.Users;
|
||||
using Roadie.Library.Utility;
|
||||
using System.Threading.Tasks;
|
||||
using data = Roadie.Library.Data;
|
||||
|
||||
namespace Roadie.Library.Scrobble
|
||||
{
|
||||
|
@ -21,8 +20,14 @@ namespace Roadie.Library.Scrobble
|
|||
|
||||
protected ILogger Logger { get; }
|
||||
|
||||
public ScrobblerIntegrationBase(IRoadieSettings configuration, ILogger logger, IRoadieDbContext dbContext,
|
||||
ICacheManager cacheManager, IHttpContext httpContext)
|
||||
public abstract int SortOrder { get; }
|
||||
|
||||
public ScrobblerIntegrationBase(
|
||||
IRoadieSettings configuration,
|
||||
ILogger logger,
|
||||
IRoadieDbContext dbContext,
|
||||
ICacheManager cacheManager,
|
||||
IHttpContext httpContext)
|
||||
{
|
||||
Logger = logger;
|
||||
Configuration = configuration;
|
||||
|
@ -35,4 +40,4 @@ namespace Roadie.Library.Scrobble
|
|||
|
||||
public abstract Task<OperationResult<bool>> Scrobble(User roadieUser, ScrobbleInfo scrobble);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using IF.Lastfm.Core.Api;
|
||||
using IF.Lastfm.Core.Objects;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Roadie.Library.Caching;
|
||||
using Roadie.Library.Configuration;
|
||||
|
@ -14,14 +15,12 @@ using Roadie.Library.SearchEngines.MetaData.LastFm;
|
|||
using Roadie.Library.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using System.Xml.XPath;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
|
@ -46,6 +45,14 @@ namespace Roadie.Library.MetaData.LastFm
|
|||
|
||||
private IHttpEncoder HttpEncoder { get; }
|
||||
|
||||
private LastAuth LastFmTrackApiAuth { get; }
|
||||
|
||||
private IF.Lastfm.Core.Api.TrackApi LastFmTrackApi { get; }
|
||||
|
||||
private IF.Lastfm.Core.Scrobblers.MemoryScrobbler LastFmScrobbler { get; }
|
||||
|
||||
public int SortOrder => 0;
|
||||
|
||||
public LastFmHelper(
|
||||
IRoadieSettings configuration,
|
||||
ICacheManager cacheManager,
|
||||
|
@ -55,10 +62,13 @@ namespace Roadie.Library.MetaData.LastFm
|
|||
IHttpClientFactory httpClientFactory)
|
||||
: base(configuration, cacheManager, logger, httpClientFactory)
|
||||
{
|
||||
_apiKey = configuration.Integrations.ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey") ??
|
||||
new ApiKey();
|
||||
_apiKey = configuration.Integrations.ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey") ?? new ApiKey();
|
||||
DbContext = dbContext;
|
||||
HttpEncoder = httpEncoder;
|
||||
|
||||
LastFmTrackApiAuth = new LastAuth(ApiKey.Key, ApiKey.KeySecret);
|
||||
LastFmTrackApi = new IF.Lastfm.Core.Api.TrackApi(LastFmTrackApiAuth, HttpClient);
|
||||
LastFmScrobbler = new IF.Lastfm.Core.Scrobblers.MemoryScrobbler(LastFmTrackApiAuth, HttpClient);
|
||||
}
|
||||
|
||||
public static void CheckLastFmStatus(XPathNavigator navigator)
|
||||
|
@ -89,70 +99,70 @@ namespace Roadie.Library.MetaData.LastFm
|
|||
|
||||
public async Task<OperationResult<string>> GetSessionKeyForUserToken(string token)
|
||||
{
|
||||
var parameters = new Dictionary<string, string>
|
||||
var result = false;
|
||||
string sessionKey = null;
|
||||
try
|
||||
{
|
||||
{"token", token}
|
||||
};
|
||||
string responseXML = null;
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, BuildUrl("auth.getSession", parameters));
|
||||
request.Headers.Add("User-Agent", WebHelper.UserAgent);
|
||||
var response = await HttpClient.SendAsync(request).ConfigureAwait(false);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
responseXML = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
var parameters = new Dictionary<string, string>
|
||||
{
|
||||
{"token", token}
|
||||
};
|
||||
string responseXML = null;
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, BuildUrl("auth.getSession", parameters));
|
||||
request.Headers.Add("User-Agent", WebHelper.UserAgent);
|
||||
var response = await HttpClient.SendAsync(request).ConfigureAwait(false);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
responseXML = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
}
|
||||
var doc = new XmlDocument();
|
||||
doc.LoadXml(responseXML);
|
||||
sessionKey = doc.GetElementsByTagName("key")[0].InnerText;
|
||||
result = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, $"Error in LastFmHelper GetSessionKeyForUserToken: token [{token}]");
|
||||
}
|
||||
var doc = new XmlDocument();
|
||||
doc.LoadXml(responseXML);
|
||||
var sessionKey = doc.GetElementsByTagName("key")[0].InnerText;
|
||||
return new OperationResult<string>
|
||||
{
|
||||
Data = sessionKey,
|
||||
IsSuccess = true
|
||||
IsSuccess = result
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<OperationResult<bool>> NowPlaying(User roadieUser, ScrobbleInfo scrobble)
|
||||
{
|
||||
var result = false;
|
||||
string msg = null;
|
||||
try
|
||||
{
|
||||
if (!IsEnabled) return new OperationResult<bool>("LastFM Integation Disabled");
|
||||
|
||||
var user = DbContext.Users.FirstOrDefault(x => x.RoadieId == roadieUser.UserId);
|
||||
|
||||
if (user == null || string.IsNullOrEmpty(user.LastFMSessionKey))
|
||||
if (!IsEnabled)
|
||||
{
|
||||
return new OperationResult<bool>("LastFM Integation Disabled");
|
||||
}
|
||||
// User should be cached if not then skip as probably a bad user
|
||||
var user = CacheManager.Get<Identity.User>(Identity.User.CacheUrn(roadieUser.UserId));
|
||||
if (string.IsNullOrEmpty(user?.LastFMSessionKey))
|
||||
{
|
||||
return new OperationResult<bool>("User does not have LastFM Integration setup");
|
||||
}
|
||||
var method = "track.updateNowPlaying";
|
||||
var parameters = new RequestParameters
|
||||
LastFmTrackApiAuth.LoadSession(new LastUserSession { Token = user.LastFMSessionKey });
|
||||
var lastFmScrobble = new IF.Lastfm.Core.Objects.Scrobble(
|
||||
scrobble.ArtistName,
|
||||
scrobble.ReleaseTitle,
|
||||
scrobble.TrackTitle,
|
||||
DateTimeOffset.UtcNow)
|
||||
{
|
||||
{"artist", scrobble.ArtistName},
|
||||
{"track", scrobble.TrackTitle},
|
||||
{"album", scrobble.ReleaseTitle},
|
||||
{"duration", ((int) scrobble.TrackDuration.TotalSeconds).ToString()}
|
||||
Duration = scrobble.TrackDuration
|
||||
};
|
||||
var url = "http://ws.audioscrobbler.com/2.0/";
|
||||
var signature = GenerateMethodSignature(method, parameters, user.LastFMSessionKey);
|
||||
parameters.Add("api_sig", signature);
|
||||
|
||||
ServicePointManager.Expect100Continue = false;
|
||||
XPathNavigator xp = null;
|
||||
var parametersJson = new StringContent(CacheManager.CacheSerializer.Serialize(parameters), System.Text.Encoding.UTF8, Application.Json);
|
||||
using (var httpResponseMessage = await HttpClient.PostAsync(url, parametersJson).ConfigureAwait(false))
|
||||
{
|
||||
if (httpResponseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
xp = await GetResponseAsXml(httpResponseMessage).ConfigureAwait(false);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
Logger.LogTrace($"LastFmHelper: Success [{ result }] RoadieUser `{roadieUser}` NowPlaying `{scrobble}` LastFmResult [{xp.InnerXml}]");
|
||||
var nowPlayingResponse = await LastFmTrackApi.UpdateNowPlayingAsync(lastFmScrobble).ConfigureAwait(false);
|
||||
result = nowPlayingResponse?.Success ?? false;
|
||||
Logger.LogTrace($"LastFmHelper: NowPlaying : Success [{ result }] RoadieUser `{roadieUser}` NowPlaying `{scrobble}` LastFMResponse `{ CacheManager.CacheSerializer.Serialize(nowPlayingResponse) }`");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex,
|
||||
$"Error in LastFmHelper NowPlaying: RoadieUser `{roadieUser}` Scrobble `{scrobble}`");
|
||||
Logger.LogError(ex, $"Error in LastFmHelper NowPlaying: RoadieUser `{roadieUser}` Scrobble `{scrobble}` Http Msg [{ msg }]");
|
||||
}
|
||||
return new OperationResult<bool>
|
||||
{
|
||||
|
@ -188,7 +198,7 @@ namespace Roadie.Library.MetaData.LastFm
|
|||
{
|
||||
result.Tags = lastFmArtist.Tags.Select(x => x.Name).ToList();
|
||||
}
|
||||
if(lastFmArtist.MainImage != null)
|
||||
if (lastFmArtist.MainImage != null)
|
||||
{
|
||||
result.ImageUrls = new string[1] { lastFmArtist.MainImage.Largest?.AbsoluteUri };
|
||||
}
|
||||
|
@ -219,7 +229,7 @@ namespace Roadie.Library.MetaData.LastFm
|
|||
var data = await CacheManager.GetAsync<ReleaseSearchResult>(cacheKey, async () =>
|
||||
{
|
||||
var auth = new LastAuth(ApiKey.Key, ApiKey.KeySecret);
|
||||
var releaseApi =new IF.Lastfm.Core.Api.AlbumApi(auth, HttpClient);
|
||||
var releaseApi = new IF.Lastfm.Core.Api.AlbumApi(auth, HttpClient);
|
||||
var sendResponse = await releaseApi.GetInfoAsync(artistName, query).ConfigureAwait(false);
|
||||
if (!sendResponse.Success)
|
||||
{
|
||||
|
@ -237,9 +247,8 @@ namespace Roadie.Library.MetaData.LastFm
|
|||
MusicBrainzId = lastFmAlbum.Mbid
|
||||
};
|
||||
|
||||
if(lastFmAlbum.Images != null)
|
||||
if (lastFmAlbum.Images != null)
|
||||
{
|
||||
|
||||
result.ImageUrls = new string[1] { lastFmAlbum.Images.Largest.AbsoluteUri };
|
||||
}
|
||||
|
||||
|
@ -250,7 +259,7 @@ namespace Roadie.Library.MetaData.LastFm
|
|||
else
|
||||
{
|
||||
var tagResult = await releaseApi.GetTopTagsAsync(artistName, query).ConfigureAwait(false);
|
||||
if(tagResult != null)
|
||||
if (tagResult != null)
|
||||
{
|
||||
result.Tags = FilterTags(tagResult.Select(x => x.Name).Distinct().Take(25).ToArray());
|
||||
}
|
||||
|
@ -313,7 +322,7 @@ namespace Roadie.Library.MetaData.LastFm
|
|||
|
||||
private List<string> FilterTags(IEnumerable<string> tags)
|
||||
{
|
||||
if(tags.Any() == false)
|
||||
if (tags.Any() == false)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -326,51 +335,42 @@ namespace Roadie.Library.MetaData.LastFm
|
|||
var result = false;
|
||||
try
|
||||
{
|
||||
if (!IsEnabled) return new OperationResult<bool>("LastFM Integation Disabled");
|
||||
if (!IsEnabled)
|
||||
{
|
||||
return new OperationResult<bool>("LastFM Integation Disabled");
|
||||
}
|
||||
// LastFM Rules on scrobbling:
|
||||
// * The track must be longer than 30 seconds.
|
||||
// * And the track has been played for at least half its duration, or for 4 minutes(whichever occurs earlier.)
|
||||
if (scrobble.TrackDuration.TotalSeconds < 30)
|
||||
return new OperationResult<bool>(
|
||||
"Track duration or elapsed time does not qualify for LastFM Scrobbling");
|
||||
{
|
||||
return new OperationResult<bool>("Track duration or elapsed time does not qualify for LastFM Scrobbling");
|
||||
}
|
||||
// If less than half of duration then create a NowPlaying
|
||||
if (scrobble.ElapsedTimeOfTrackPlayed.TotalMinutes < 4 ||
|
||||
scrobble.ElapsedTimeOfTrackPlayed.TotalSeconds < scrobble.TrackDuration.TotalSeconds / 2)
|
||||
{
|
||||
return await NowPlaying(roadieUser, scrobble).ConfigureAwait(false);
|
||||
|
||||
var user = DbContext.Users.FirstOrDefault(x => x.RoadieId == roadieUser.UserId);
|
||||
|
||||
if (user == null || string.IsNullOrEmpty(user.LastFMSessionKey))
|
||||
}
|
||||
// User should be cached if not then skip as probably a bad user
|
||||
var user = CacheManager.Get<Identity.User>(Identity.User.CacheUrn(roadieUser.UserId));
|
||||
if (string.IsNullOrEmpty(user?.LastFMSessionKey))
|
||||
{
|
||||
return new OperationResult<bool>("User does not have LastFM Integration setup");
|
||||
}
|
||||
var parameters = new RequestParameters
|
||||
LastFmTrackApiAuth.LoadSession(new LastUserSession { Token = user.LastFMSessionKey });
|
||||
var lastFmScrobble = new IF.Lastfm.Core.Objects.Scrobble(
|
||||
scrobble.ArtistName,
|
||||
scrobble.ReleaseTitle,
|
||||
scrobble.TrackTitle,
|
||||
scrobble.TimePlayed)
|
||||
{
|
||||
{"artist", scrobble.ArtistName},
|
||||
{"track", scrobble.TrackTitle},
|
||||
{"timestamp", scrobble.TimePlayed.ToUnixTime().ToString()},
|
||||
{"album", scrobble.ReleaseTitle},
|
||||
{"chosenByUser", scrobble.IsRandomizedScrobble ? "1" : "0"},
|
||||
{"duration", ((int) scrobble.TrackDuration.TotalSeconds).ToString()}
|
||||
Duration = scrobble.TrackDuration,
|
||||
ChosenByUser = !scrobble.IsRandomizedScrobble
|
||||
};
|
||||
|
||||
var method = "track.scrobble";
|
||||
var url = "http://ws.audioscrobbler.com/2.0/";
|
||||
var signature = GenerateMethodSignature(method, parameters, user.LastFMSessionKey);
|
||||
parameters.Add("api_sig", signature);
|
||||
|
||||
ServicePointManager.Expect100Continue = false;
|
||||
XPathNavigator xp = null;
|
||||
var parametersJson = new StringContent(CacheManager.CacheSerializer.Serialize(parameters), System.Text.Encoding.UTF8, Application.Json);
|
||||
using (var httpResponseMessage = await HttpClient.PostAsync(url, parametersJson).ConfigureAwait(false))
|
||||
{
|
||||
if (httpResponseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
xp = await GetResponseAsXml(httpResponseMessage).ConfigureAwait(false);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
Logger.LogTrace($"LastFmHelper: RoadieUser `{roadieUser}` Scrobble `{scrobble}` LastFmResult [{xp.InnerXml}]");
|
||||
var scrobbleResponse = await LastFmScrobbler.ScrobbleAsync(lastFmScrobble);
|
||||
result = scrobbleResponse?.Success ?? false;
|
||||
Logger.LogTrace($"LastFmHelper: Scrobble : Success [{ result }] RoadieUser `{roadieUser}` Scrobble `{scrobble}`");
|
||||
result = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -566,10 +566,22 @@ namespace Roadie.Library.MetaData.LastFm
|
|||
|
||||
private string GenerateMethodSignature(string method, IDictionary<string, string> parameters = null, string sk = null)
|
||||
{
|
||||
if (parameters == null) parameters = new Dictionary<string, string>();
|
||||
if (!parameters.ContainsKey("method")) parameters.Add("method", method);
|
||||
if (!parameters.ContainsKey("api_key")) parameters.Add("api_key", _apiKey.Key);
|
||||
if (!string.IsNullOrEmpty(sk) && !parameters.ContainsKey("sk")) parameters.Add("sk", sk);
|
||||
if (parameters == null)
|
||||
{
|
||||
parameters = new Dictionary<string, string>();
|
||||
}
|
||||
if (!parameters.ContainsKey("method"))
|
||||
{
|
||||
parameters.Add("method", method);
|
||||
}
|
||||
if (!parameters.ContainsKey("api_key"))
|
||||
{
|
||||
parameters.Add("api_key", _apiKey.Key);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(sk) && !parameters.ContainsKey("sk"))
|
||||
{
|
||||
parameters.Add("sk", sk);
|
||||
}
|
||||
var builder = new StringBuilder();
|
||||
foreach (var kv in parameters.OrderBy(kv => kv.Key, StringComparer.Ordinal))
|
||||
{
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace Roadie.Api.Services
|
|||
var rowCount = result.Count();
|
||||
var rows = result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
|
||||
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
|
||||
foreach (var row in rows)
|
||||
{
|
||||
|
|
|
@ -10,6 +10,8 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
public interface ITrackService
|
||||
{
|
||||
Task<Roadie.Library.Identity.User> GetUserByUserNameAsync(string username);
|
||||
|
||||
Task<OperationResult<Track>> ByIdAsyncAsync(User roadieUser, Guid id, IEnumerable<string> includes);
|
||||
|
||||
Task<PagedResult<TrackList>> ListAsync(PagedRequest request, User roadieUser, bool? doRandomize = false, Guid? releaseId = null);
|
||||
|
|
|
@ -564,7 +564,7 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
try
|
||||
{
|
||||
var user = await GetUser(id).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(id).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new FileOperationResult<IImage>(true, $"User Not Found [{id}]");
|
||||
|
|
|
@ -28,16 +28,26 @@ namespace Roadie.Api.Services
|
|||
|
||||
protected IScrobbleHandler ScrobblerHandler { get; }
|
||||
|
||||
public PlayActivityService(IRoadieSettings configuration, IRoadieDbContext dbContext, ICacheManager cacheManager,
|
||||
ILogger logger, ScrobbleHandler scrobbleHandler)
|
||||
public PlayActivityService(
|
||||
IRoadieSettings configuration,
|
||||
IRoadieDbContext dbContext,
|
||||
ICacheManager cacheManager,
|
||||
ILogger logger,
|
||||
ScrobbleHandler scrobbleHandler)
|
||||
: base(configuration, null, dbContext, cacheManager, logger, null)
|
||||
{
|
||||
ScrobblerHandler = scrobbleHandler;
|
||||
}
|
||||
|
||||
public PlayActivityService(IRoadieSettings configuration, IHttpEncoder httpEncoder, IHttpContext httpContext,
|
||||
IRoadieDbContext dbContext, ICacheManager cacheManager, ILogger<PlayActivityService> logger,
|
||||
IScrobbleHandler scrobbleHandler, IHubContext<PlayActivityHub> playActivityHub)
|
||||
public PlayActivityService(
|
||||
IRoadieSettings configuration,
|
||||
IHttpEncoder httpEncoder,
|
||||
IHttpContext httpContext,
|
||||
IRoadieDbContext dbContext,
|
||||
ICacheManager cacheManager,
|
||||
ILogger<PlayActivityService> logger,
|
||||
IScrobbleHandler scrobbleHandler,
|
||||
IHubContext<PlayActivityHub> playActivityHub)
|
||||
: base(configuration, httpEncoder, dbContext, cacheManager, logger, httpContext)
|
||||
{
|
||||
PlayActivityHub = playActivityHub;
|
||||
|
@ -195,7 +205,7 @@ namespace Roadie.Api.Services
|
|||
? request.OrderValue(new Dictionary<string, string> { { "PlayedDateDateTime", "DESC" } })
|
||||
: request.OrderValue();
|
||||
var rowCount = result.Count();
|
||||
var rows = await result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArrayAsync().ConfigureAwait(false);
|
||||
var rows = await result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArrayAsync().ConfigureAwait(false);
|
||||
sw.Stop();
|
||||
return new Library.Models.Pagination.PagedResult<PlayActivityList>
|
||||
{
|
||||
|
@ -237,4 +247,4 @@ namespace Roadie.Api.Services
|
|||
return scrobbleResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -336,7 +336,7 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
if (result?.Data?.Tracks != null)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
foreach (var track in result.Data.Tracks)
|
||||
{
|
||||
track.Track.TrackPlayUrl = MakeTrackPlayUrl(user, HttpContext.BaseUrl, track.Track.Id);
|
||||
|
|
|
@ -487,7 +487,7 @@ namespace Roadie.Api.Services
|
|||
if (result.Data.Medias != null)
|
||||
{
|
||||
tsw.Restart();
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
tsw.Stop();
|
||||
timings.Add("getUser", tsw.ElapsedMilliseconds);
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ namespace Roadie.Api.Services
|
|||
}, data.Track.CacheRegionUrn(id));
|
||||
}
|
||||
|
||||
protected async Task<User> GetUser(string username)
|
||||
public async Task<User> GetUserByUserNameAsync(string username)
|
||||
{
|
||||
if (string.IsNullOrEmpty(username))
|
||||
{
|
||||
|
@ -205,10 +205,10 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
return DbContext.Users.FirstOrDefaultAsync(x => x.UserName == username);
|
||||
}, null).ConfigureAwait(false);
|
||||
return await GetUser(userByUsername?.RoadieId).ConfigureAwait(false);
|
||||
return await GetUserAsync(userByUsername?.RoadieId).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
protected Task<User> GetUser(Guid? id)
|
||||
public Task<User> GetUserAsync(Guid? id)
|
||||
{
|
||||
return CacheManager.GetAsync(User.CacheUrn(id.Value), async () =>
|
||||
{
|
||||
|
|
|
@ -110,13 +110,12 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
if (request == null || string.IsNullOrEmpty(request?.u))
|
||||
{
|
||||
return new subsonic.SubsonicOperationResult<subsonic.SubsonicAuthenticateResponse>(
|
||||
subsonic.ErrorCodes.WrongUsernameOrPassword, "Unknown Username");
|
||||
return new subsonic.SubsonicOperationResult<subsonic.SubsonicAuthenticateResponse>(subsonic.ErrorCodes.WrongUsernameOrPassword, "Unknown Username");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var user = DbContext.Users.FirstOrDefault(x => x.UserName == request.u);
|
||||
var user = await GetUserByUserNameAsync(request.u).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
Logger.LogTrace($"Unknown User [{request.u}]");
|
||||
|
@ -144,8 +143,7 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
try
|
||||
{
|
||||
var hashCheck =
|
||||
UserManger.PasswordHasher.VerifyHashedPassword(user, user.PasswordHash, password);
|
||||
var hashCheck = UserManger.PasswordHasher.VerifyHashedPassword(user, user.PasswordHash, password);
|
||||
if (hashCheck == PasswordVerificationResult.Failed)
|
||||
{
|
||||
user = null;
|
||||
|
@ -235,7 +233,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
CacheManager.ClearRegion(user.CacheRegion);
|
||||
|
||||
Logger.LogTrace(
|
||||
|
@ -371,7 +369,7 @@ namespace Roadie.Api.Services
|
|||
DbContext.Bookmarks.Remove(userBookmark);
|
||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
CacheManager.ClearRegion(user.CacheRegion);
|
||||
|
||||
Logger.LogTrace($"Subsonic: Deleted Bookmark `{userBookmark}` for User `{roadieUser}`");
|
||||
|
@ -847,7 +845,7 @@ namespace Roadie.Api.Services
|
|||
}
|
||||
else if (!string.IsNullOrEmpty(request.u))
|
||||
{
|
||||
var user = await GetUser(request.u).ConfigureAwait(false);
|
||||
var user = await GetUserByUserNameAsync(request.u).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new subsonic.SubsonicFileOperationResult<Library.Models.Image>(
|
||||
|
@ -990,7 +988,7 @@ namespace Roadie.Api.Services
|
|||
public async Task<subsonic.SubsonicOperationResult<subsonic.Response>> GetMusicDirectoryAsync(subsonic.Request request, Library.Models.Users.User roadieUser)
|
||||
{
|
||||
var directory = new subsonic.Directory();
|
||||
var user = await GetUser(roadieUser?.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser?.UserId).ConfigureAwait(false);
|
||||
|
||||
// Request to get albums for an Artist
|
||||
if (request.ArtistId != null)
|
||||
|
@ -1232,7 +1230,7 @@ namespace Roadie.Api.Services
|
|||
public async Task<subsonic.SubsonicOperationResult<subsonic.Response>> GetPlayQueueAsync(subsonic.Request request,
|
||||
Library.Models.Users.User roadieUser)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
|
||||
subsonic.PlayQueue playQue = null;
|
||||
|
||||
|
@ -1546,7 +1544,7 @@ namespace Roadie.Api.Services
|
|||
public async Task<subsonic.SubsonicOperationResult<subsonic.Response>> GetUserAsync(subsonic.Request request,
|
||||
string username)
|
||||
{
|
||||
var user = await GetUser(username).ConfigureAwait(false);
|
||||
var user = await GetUserByUserNameAsync(username).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new subsonic.SubsonicOperationResult<subsonic.Response>(
|
||||
|
@ -1612,7 +1610,7 @@ namespace Roadie.Api.Services
|
|||
Library.Models.Users.User roadieUser, string current, long? position)
|
||||
{
|
||||
// Remove any existing Que for User
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user.UserQues?.Any() == true)
|
||||
{
|
||||
DbContext.UserQues.RemoveRange(user.UserQues);
|
||||
|
@ -1744,7 +1742,7 @@ namespace Roadie.Api.Services
|
|||
public async Task<subsonic.SubsonicOperationResult<subsonic.Response>> SetRatingAsync(subsonic.Request request,
|
||||
Library.Models.Users.User roadieUser, short rating)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new subsonic.SubsonicOperationResult<subsonic.Response>(
|
||||
|
@ -1800,7 +1798,7 @@ namespace Roadie.Api.Services
|
|||
public async Task<subsonic.SubsonicOperationResult<subsonic.Response>> ToggleStarAsync(subsonic.Request request,
|
||||
Library.Models.Users.User roadieUser, bool star, string[] albumIds = null, string[] artistIds = null)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new subsonic.SubsonicOperationResult<subsonic.Response>(
|
||||
|
@ -1954,7 +1952,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
CacheManager.ClearRegion(user.CacheRegion);
|
||||
|
||||
return new subsonic.SubsonicOperationResult<subsonic.Response>
|
||||
|
|
|
@ -229,7 +229,7 @@ namespace Roadie.Api.Services
|
|||
if (result?.Data != null && roadieUser != null)
|
||||
{
|
||||
tsw.Restart();
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
tsw.Stop();
|
||||
timings.Add("getUser", tsw.ElapsedMilliseconds);
|
||||
|
||||
|
@ -620,7 +620,7 @@ namespace Roadie.Api.Services
|
|||
resultQuery = resultQuery.Where(x => x.ti.Tags != null && x.ti.Tags.Contains(tagValue));
|
||||
}
|
||||
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
var result = resultQuery.Select(x =>
|
||||
new TrackList
|
||||
{
|
||||
|
|
|
@ -128,7 +128,7 @@ namespace Roadie.Api.Services
|
|||
var tsw = new Stopwatch();
|
||||
|
||||
tsw.Restart();
|
||||
var user = await GetUser(id).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(id).ConfigureAwait(false);
|
||||
tsw.Stop();
|
||||
timings.Add("getUser", tsw.ElapsedMilliseconds);
|
||||
|
||||
|
@ -257,7 +257,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<bool>> DeleteAllBookmarksAsync(User roadieUser)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<bool>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -356,7 +356,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<bool>> SetArtistBookmarkAsync(Guid artistId, User roadieUser, bool isBookmarked)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<bool>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -380,7 +380,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<bool>> SetArtistDislikedAsync(Guid artistId, User roadieUser, bool isDisliked)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<bool>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -390,7 +390,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<bool>> SetArtistFavoriteAsync(Guid artistId, User roadieUser, bool isFavorite)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<bool>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -400,7 +400,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<short>> SetArtistRatingAsync(Guid artistId, User roadieUser, short rating)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<short>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -410,7 +410,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<bool>> SetCollectionBookmarkAsync(Guid collectionId, User roadieUser, bool isBookmarked)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<bool>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -433,7 +433,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<bool>> SetLabelBookmarkAsync(Guid labelId, User roadieUser, bool isBookmarked)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<bool>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -457,7 +457,7 @@ namespace Roadie.Api.Services
|
|||
public async Task<OperationResult<bool>> SetPlaylistBookmarkAsync(Guid playlistId, User roadieUser,
|
||||
bool isBookmarked)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<bool>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -480,7 +480,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<bool>> SetReleaseBookmarkAsync(Guid releaseid, User roadieUser, bool isBookmarked)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<bool>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -503,7 +503,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<bool>> SetReleaseDislikedAsync(Guid releaseId, User roadieUser, bool isDisliked)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<bool>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -513,7 +513,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<bool>> SetReleaseFavoriteAsync(Guid releaseId, User roadieUser, bool isFavorite)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<bool>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -523,7 +523,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<short>> SetReleaseRatingAsync(Guid releaseId, User roadieUser, short rating)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<short>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -533,7 +533,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<bool>> SetTrackBookmarkAsync(Guid trackId, User roadieUser, bool isBookmarked)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<bool>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -556,7 +556,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<bool>> SetTrackDislikedAsync(Guid trackId, User roadieUser, bool isDisliked)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<bool>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -566,7 +566,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
public async Task<OperationResult<bool>> SetTrackFavoriteAsync(Guid trackId, User roadieUser, bool isFavorite)
|
||||
{
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
if (user == null)
|
||||
{
|
||||
return new OperationResult<bool>(true, $"Invalid User [{roadieUser}]");
|
||||
|
@ -578,9 +578,9 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
var timings = new Dictionary<string, long>();
|
||||
var sw = Stopwatch.StartNew();
|
||||
var user = await GetUser(roadieUser.UserId).ConfigureAwait(false);
|
||||
var user = await GetUserAsync(roadieUser.UserId).ConfigureAwait(false);
|
||||
sw.Stop();
|
||||
timings.Add(nameof(GetUser), sw.ElapsedMilliseconds);
|
||||
timings.Add(nameof(GetUserByUserNameAsync), sw.ElapsedMilliseconds);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
|
|
|
@ -155,7 +155,6 @@ namespace Roadie.Api.Controllers
|
|||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var result = user.Adapt<models.User>();
|
||||
result.IsAdmin = User.IsInRole("Admin");
|
||||
result.IsEditor = User.IsInRole("Editor") || result.IsAdmin;
|
||||
|
|
|
@ -88,7 +88,12 @@ namespace Roadie.Api.Controllers
|
|||
[ProducesResponseType(404)]
|
||||
public async Task<IActionResult> Scrobble(Guid id, string startedPlaying, bool isRandom)
|
||||
{
|
||||
var result = await PlayActivityService.ScrobbleAsync(await CurrentUserModel().ConfigureAwait(false), new ScrobbleInfo
|
||||
var user = await CurrentUserModel().ConfigureAwait(false);
|
||||
|
||||
// Put user in cache (if not already) for future track related API operations.
|
||||
await TrackService.GetUserByUserNameAsync(user.UserName).ConfigureAwait(false);
|
||||
|
||||
var result = await PlayActivityService.ScrobbleAsync(user, new ScrobbleInfo
|
||||
{
|
||||
TrackId = id,
|
||||
TimePlayed = SafeParser.ToDateTime(startedPlaying) ?? DateTime.UtcNow,
|
||||
|
@ -119,7 +124,8 @@ namespace Roadie.Api.Controllers
|
|||
{
|
||||
return StatusCode((int)HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
// Put user in cache (if not already) for future track related API operations.
|
||||
await System.Threading.Tasks.Task.Run(async () => await TrackService.GetUserByUserNameAsync(user.UserName).ConfigureAwait(false));
|
||||
if (!ServiceBase.ConfirmTrackPlayToken(user, id, trackPlayToken))
|
||||
{
|
||||
return StatusCode((int)HttpStatusCode.Unauthorized);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.1.3</VersionPrefix>
|
||||
<VersionPrefix>1.1.4</VersionPrefix>
|
||||
<VersionSuffix></VersionSuffix>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
|||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<UserSecretsId>3f484b72-52aa-42ae-938d-4635f9511319</UserSecretsId>
|
||||
<Version>1.1.3</Version>
|
||||
<Version>1.1.4</Version>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -265,10 +265,10 @@ namespace Roadie.Api
|
|||
services.AddSingleton<IWikipediaHelper, WikipediaHelper>();
|
||||
services.AddSingleton<IFileNameHelper, FileNameHelper>();
|
||||
services.AddSingleton<IID3TagsHelper, ID3TagsHelper>();
|
||||
services.AddSingleton<ILastFmHelper, LastFmHelper>();
|
||||
services.AddSingleton<IRoadieScrobbler, RoadieScrobbler>();
|
||||
services.AddSingleton<ILastFMScrobbler, LastFMScrobbler>();
|
||||
|
||||
services.AddScoped<ILastFmHelper, LastFmHelper>();
|
||||
services.AddScoped<IRoadieScrobbler, RoadieScrobbler>();
|
||||
services.AddScoped<ILastFMScrobbler, LastFMScrobbler>();
|
||||
services.AddScoped<IStatisticsService, StatisticsService>();
|
||||
services.AddScoped<ICollectionService, CollectionService>();
|
||||
services.AddScoped<IPlaylistService, PlaylistService>();
|
||||
|
@ -361,7 +361,6 @@ namespace Roadie.Api
|
|||
}
|
||||
return new HttpContext(factory.GetService<IRoadieSettings>(), new UrlHelper(actionContext));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static string _roadieApiVersion = null;
|
||||
|
|
Loading…
Reference in a new issue