diff --git a/Lastfm-Scrobbler/Api/LastfmApiClient.cs b/Lastfm-Scrobbler/Api/LastfmApiClient.cs index c1e3f67..8089309 100644 --- a/Lastfm-Scrobbler/Api/LastfmApiClient.cs +++ b/Lastfm-Scrobbler/Api/LastfmApiClient.cs @@ -15,21 +15,20 @@ public class LastfmApiClient : BaseLastfmApiClient { public LastfmApiClient(IHttpClient httpClient, IJsonSerializer jsonSerializer) : base(httpClient, jsonSerializer) { } - public async Task RequestSession(string username, string password) + public async Task GetSession(string token) { //Build request object - var request = new MobileSessionRequest + var request = new SessionRequest { - Username = username, - Password = password, + Token = token, Secure = true }; - var response = await Post(request); + var response = await Post(request).ConfigureAwait(false); //Log the key for debugging - if (response != null) - Plugin.Logger.Info("{0} successfully logged into Last.fm", username); + if (response == null) + Plugin.Logger.Info("{0} failed to login into Last.fm"); return response; } @@ -147,4 +146,4 @@ public Task UnloveTrack(Audio item, LastfmUser user) return LoveTrack(item, user, false); } } -} +} \ No newline at end of file diff --git a/Lastfm-Scrobbler/Configuration/PluginConfiguration.cs b/Lastfm-Scrobbler/Configuration/PluginConfiguration.cs index 20e427a..ab677a0 100644 --- a/Lastfm-Scrobbler/Configuration/PluginConfiguration.cs +++ b/Lastfm-Scrobbler/Configuration/PluginConfiguration.cs @@ -1,5 +1,6 @@ namespace LastfmScrobbler.Configuration { + using System.Collections.Generic; using Models; using MediaBrowser.Model.Plugins; @@ -8,14 +9,14 @@ /// public class PluginConfiguration : BasePluginConfiguration { - public LastfmUser[] LastfmUsers { get; set; } + public List LastfmUsers { get; set; } /// /// Initializes a new instance of the class. /// public PluginConfiguration() { - LastfmUsers = new LastfmUser[] { }; + LastfmUsers = new List(); } } } diff --git a/Lastfm-Scrobbler/Configuration/configPage.html b/Lastfm-Scrobbler/Configuration/configPage.html index abe1bad..60d23f5 100644 --- a/Lastfm-Scrobbler/Configuration/configPage.html +++ b/Lastfm-Scrobbler/Configuration/configPage.html @@ -15,12 +15,9 @@
  • - - -
  • -
  • - - +
    + +
  • @@ -42,6 +39,7 @@ var LastfmScrobblerConfigurationPage = { _pluginUniqueId: "1f5e1261-1e09-4bed-8839-dc07afe096c2", + _apiKey: "e85c2d4e649f4a01dbfec778d758ab2e", _users: [], _config: [], @@ -68,6 +66,7 @@ this.$el.find('#LastfmScrobblerConfigurationForm').on('submit', this, this.onSubmit); this.$el.find('#user').on('change', this, $.proxy(this.onUserChange, this)); this.$el.find("#removeUser").on('click', $.proxy(this.removeUser, this)); + this.$el.find("#connect").on('click', $.proxy(this.redirectToLastfm, this)); var loadConfig = this.loadConfiguration(); var loadUsers = this.loadUsers().then($.proxy(this.buildUserList, this)); @@ -110,6 +109,14 @@ .selectmenu("refresh"); }, + redirectToLastfm: function() { + var userId = this.getCurrentSelectedUserId(); + + var callbackUrl = "LastFm/Callback?UserId=" + userId + "&retUrl=" + window.location; + + window.location = "http://www.last.fm/api/auth/?api_key=" + this._apiKey + "&cb=" + ApiClient.getUrl(encodeURIComponent(callbackUrl)); + }, + populateInputs: function (userData) { var data = $.extend({}, this.configDefaults, userData); diff --git a/Lastfm-Scrobbler/Lastfm-Scrobbler.csproj b/Lastfm-Scrobbler/Lastfm-Scrobbler.csproj index 1825083..ae2159e 100644 --- a/Lastfm-Scrobbler/Lastfm-Scrobbler.csproj +++ b/Lastfm-Scrobbler/Lastfm-Scrobbler.csproj @@ -1,96 +1,97 @@ - - - - - Debug - AnyCPU - {30B2A395-5E43-454F-8093-DAF307D6D4FB} - Library - Properties - LastfmScrobbler - Lastfm-Scrobbler - v4.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\MediaBrowser.Common.3.0.701\lib\portable-net45+win8+wpa81\MediaBrowser.Common.dll - - - ..\packages\MediaBrowser.Server.Core.3.0.701\lib\net45\MediaBrowser.Controller.dll - - - ..\packages\MediaBrowser.Common.3.0.701\lib\portable-net45+win8+wpa81\MediaBrowser.Model.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - xcopy "$(TargetPath)" "%25AppData%25\MediaBrowser-Server\Plugins\" /y - - + --> \ No newline at end of file diff --git a/Lastfm-Scrobbler/Models/LastfmUser.cs b/Lastfm-Scrobbler/Models/LastfmUser.cs index 348ae2c..d4dac96 100644 --- a/Lastfm-Scrobbler/Models/LastfmUser.cs +++ b/Lastfm-Scrobbler/Models/LastfmUser.cs @@ -4,6 +4,9 @@ public class LastfmUser { + /// + /// Last.fm Username + /// public string Username { get; set; } //We wont store the password, but instead store the session key since its a lifetime key diff --git a/Lastfm-Scrobbler/Models/Requests/MobileSessionRequest.cs b/Lastfm-Scrobbler/Models/Requests/SessionRequest.cs similarity index 50% rename from Lastfm-Scrobbler/Models/Requests/MobileSessionRequest.cs rename to Lastfm-Scrobbler/Models/Requests/SessionRequest.cs index 5168caa..57c347c 100644 --- a/Lastfm-Scrobbler/Models/Requests/MobileSessionRequest.cs +++ b/Lastfm-Scrobbler/Models/Requests/SessionRequest.cs @@ -3,19 +3,17 @@ using System.Collections.Generic; using Resources; - public class MobileSessionRequest : BaseRequest + public class SessionRequest : BaseRequest { - public string Password { get; set; } - public string Username { get; set; } + public string Token { get; set; } - public override string Method => Strings.Methods.GetMobileSession; + public override string Method => Strings.Methods.GetSession; public override Dictionary ToDictionary() { return new Dictionary(base.ToDictionary()) { - { "password", Password }, - { "username", Username }, + { "token", Token } }; } } diff --git a/Lastfm-Scrobbler/Models/Responses/GetUserInfoResponse.cs b/Lastfm-Scrobbler/Models/Responses/GetUserInfoResponse.cs new file mode 100644 index 0000000..735a26f --- /dev/null +++ b/Lastfm-Scrobbler/Models/Responses/GetUserInfoResponse.cs @@ -0,0 +1,16 @@ +namespace LastfmScrobbler.Models.Responses +{ + using System.Runtime.Serialization; + + [DataContract] + public class GetUserInfoResponse : BaseResponse + { + public User User { get; set; } + } + + [DataContract] + public class User + { + + } +} \ No newline at end of file diff --git a/Lastfm-Scrobbler/Models/Responses/MobileSessionResponse.cs b/Lastfm-Scrobbler/Models/Responses/SessionResponse.cs similarity index 60% rename from Lastfm-Scrobbler/Models/Responses/MobileSessionResponse.cs rename to Lastfm-Scrobbler/Models/Responses/SessionResponse.cs index f8d2602..cf94817 100644 --- a/Lastfm-Scrobbler/Models/Responses/MobileSessionResponse.cs +++ b/Lastfm-Scrobbler/Models/Responses/SessionResponse.cs @@ -3,9 +3,9 @@ using System.Runtime.Serialization; [DataContract] - public class MobileSessionResponse : BaseResponse + public class SessionResponse : BaseResponse { [DataMember(Name="session")] - public MobileSession Session { get; set; } + public Session Session { get; set; } } } diff --git a/Lastfm-Scrobbler/Models/MobileSession.cs b/Lastfm-Scrobbler/Models/Session.cs similarity index 91% rename from Lastfm-Scrobbler/Models/MobileSession.cs rename to Lastfm-Scrobbler/Models/Session.cs index ce0985b..a75d956 100644 --- a/Lastfm-Scrobbler/Models/MobileSession.cs +++ b/Lastfm-Scrobbler/Models/Session.cs @@ -3,7 +3,7 @@ using System.Runtime.Serialization; [DataContract] - public class MobileSession + public class Session { [DataMember(Name = "name")] public string Name { get; set; } diff --git a/Lastfm-Scrobbler/Resources/Strings.cs b/Lastfm-Scrobbler/Resources/Strings.cs index 88c4eef..c40f45f 100644 --- a/Lastfm-Scrobbler/Resources/Strings.cs +++ b/Lastfm-Scrobbler/Resources/Strings.cs @@ -11,7 +11,7 @@ public static class Methods { public static string Scrobble = "track.scrobble"; public static string NowPlaying = "track.updateNowPlaying"; - public static string GetMobileSession = "auth.getMobileSession"; + public static string GetSession = "auth.getSession"; public static string TrackLove = "track.love"; public static string TrackUnlove = "track.unlove"; } diff --git a/Lastfm-Scrobbler/RestApi.cs b/Lastfm-Scrobbler/RestApi.cs index a1d10de..2a3ae9c 100644 --- a/Lastfm-Scrobbler/RestApi.cs +++ b/Lastfm-Scrobbler/RestApi.cs @@ -1,36 +1,103 @@ namespace LastfmScrobbler { using System; + using System.Linq; + using System.Threading.Tasks; using Api; using MediaBrowser.Common.Net; + using MediaBrowser.Controller.Library; + using MediaBrowser.Controller.Net; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Services; - using Models.Responses; + using Models; - [Route("/Lastfm/Login", "POST")] - public class Login : IReturn + [Route("/LastFm/callback")] + public class LastfmCallback { - public string Username { get; set; } - public string Password { get; set; } + public string Token { get; set; } + public Guid UserId { get; set; } } - public class RestApi : IService, IDisposable + public class RestApi : IService, IHasResultFactory, IDisposable { + private readonly IUserManager _userManager; private readonly LastfmApiClient _apiClient; - public RestApi(IJsonSerializer jsonSerializer, IHttpClient httpClient) + public RestApi(IJsonSerializer jsonSerializer, IHttpClient httpClient, IUserManager userManager) { + _userManager = userManager; _apiClient = new LastfmApiClient(httpClient, jsonSerializer); } - public object Post(Login request) + public async Task Get(LastfmCallback callback) { - return _apiClient.RequestSession(request.Username, request.Password); + if (string.IsNullOrWhiteSpace(callback.Token)) + return Redirect(AuthResult.MissingToken); + + //Check user is valid + var user = _userManager.GetUserById(callback.UserId); + if (user == null) + return Redirect(AuthResult.InvalidUser); + + var session = await _apiClient.GetSession(callback.Token); + if (session.IsError()) + return Redirect(AuthResult.BadSession); + + var userConfig = + Plugin.Instance.PluginConfiguration.LastfmUsers.FirstOrDefault( + u => u.MediaBrowserUserId.Equals(user.Id)); + + if (userConfig == null) + { + Plugin.Logger.Info("Creating config for user: {0}", user.Id); + + //create new config for user + Plugin.Instance.PluginConfiguration.LastfmUsers.Add(new LastfmUser + { + SessionKey = session.Session.Key, + MediaBrowserUserId = user.Id, + Options = new LastFmUserOptions + { + Scrobble = true + }, + Username = session.Session.Name + }); + } + else + { + Plugin.Logger.Info("Update config for user: {0}", user.Id); + + //update existing + userConfig.SessionKey = session.Session.Key; + userConfig.Username = session.Session.Name; + } + + Plugin.Instance.SaveConfiguration(); + + return await Redirect(AuthResult.Success); + } + + private enum AuthResult + { + Success = 200, + MissingToken = 10, + BadSession = 20, + InvalidUser = 30 + } + + private Task Redirect(AuthResult result) + { + //return ResultFactory.GetStaticFileResult(Request, ""); + + return Task.FromResult(result.ToString()); } public void Dispose() { _apiClient?.Dispose(); } + + public IRequest Request { get; set; } + public IHttpResultFactory ResultFactory { get; set; } } }