public void Debug() { return; var tokenResult = Auth.GetToken().Result; var url = Auth.GetAuthorizeTokenUrl(tokenResult.Result); Process.Start(url); Console.WriteLine("Press enter once the token is authorized in the browser."); Console.ReadLine(); var sessionResult = Auth.GetSession(tokenResult.Result).Result; var scrobble = new Scrobble("Russ Chimes", "Targa (Original Mix)", DateTimeOffset.Now.AddMinutes(-4)) { Album = "Midnight Club EP", TrackNumber = "1/3", Duration = new TimeSpan(0, 5, 16) }; var sessionKey = ""; var updateNowPlayingResult = Track.UpdateNowPlaying(sessionKey, scrobble).Result; var scrobbleResult = Track.Scrobble(sessionKey, scrobble).Result; }
public async Task Scrobble() { InProgress = true; var appsettings = new ApplicationSettingsService(); var apikey = appsettings.Get <string>("apikey"); var apisecret = appsettings.Get <string>("apisecret"); var username = appsettings.Get <string>("username"); var pass = appsettings.Get <string>("pass"); var auth = new LastAuth(apikey, apisecret); await auth.GetSessionTokenAsync(username, pass); var trackApi = new Core.Api.TrackApi(auth); var scrobble = new Scrobble(Artist, Album, Track, DateTime.UtcNow) { AlbumArtist = AlbumArtist }; var response = await trackApi.ScrobbleAsync(scrobble); Successful = response.Success; InProgress = false; }
/// <summary> /// Scrobbles the track with the given info. /// </summary> public override async Task Scrobble() { try { EnableControls = false; OnStatusUpdated("Trying to scrobble..."); Scrobble s = new Scrobble(Artist, Album, Track, Time) { AlbumArtist = AlbumArtist, Duration = Duration }; var response = await Scrobbler.ScrobbleAsync(s); if (response.Success && response.Status == LastResponseStatus.Successful) { OnStatusUpdated(string.Format("Successfully scrobbled '{0}'", s.Track)); } else { OnStatusUpdated(string.Format("Error while scrobbling '{0}': {1}", s.Track, response.Status)); } } catch (Exception ex) { OnStatusUpdated("Fatal error while trying to scrobble: " + ex.Message); } finally { EnableControls = true; } }
public async Task UpdatesNowPlaying() { var trackPlayed = DateTime.UtcNow.AddMinutes(-1); var testScrobble = new Scrobble(ARTIST_NAME, ALBUM_NAME, TRACK_NAME, trackPlayed) { Duration = new TimeSpan(0, 0, 3, 49, 200), AlbumArtist = ARTIST_NAME }; var response = await Lastfm.Track.UpdateNowPlayingAsync(testScrobble); Assert.IsTrue(response.Success); var tracks = await Lastfm.User.GetRecentScrobbles(Lastfm.Auth.UserSession.Username, null, 1, 1); var expectedTrack = new LastTrack { Name = TRACK_NAME, ArtistName = ARTIST_NAME, AlbumName = ALBUM_NAME, Mbid = "1b9ee1d8-c5a7-44d9-813e-85beb0d59f1b", ArtistMbid = "b1570544-93ab-4b2b-8398-131735394202", Url = new Uri("http://www.last.fm/music/Crystal+Castles/_/Not+in+Love"), Images = new LastImageSet("http://userserve-ak.last.fm/serve/34s/61473043.png", "http://userserve-ak.last.fm/serve/64s/61473043.png", "http://userserve-ak.last.fm/serve/126/61473043.png", "http://userserve-ak.last.fm/serve/300x300/61473043.png"), IsNowPlaying = true }; var expectedJson = expectedTrack.TestSerialise(); var actualJson = tracks.Content.FirstOrDefault().TestSerialise(); Assert.AreEqual(expectedJson, actualJson, expectedJson.DifferencesTo(actualJson)); }
/// <summary> /// Asynchronously stores a scrobble in the underlying cache file. /// Will throw an exception if the cache file cannot be accessed. /// This method is thread safe. /// </summary> public async Task StoreAsync(Scrobble scrobble) { EnsureFileLockIsAcquired(); using (await _fileOperationAsyncLock.LockAsync()) { // Note about the file content: // The file is line separated. // Instead of writing the data followed by a new line, we do the opposite: // We always start by writing a new line, followed by the data. // This way, we don't risk continuing a corrupted line without a proper line ending. // Unreadable lines can then be discarded, and we lose only one record instead of two. await EnsureCorrectHeaderAndGetFileVersionAsync(_fileStream); // Skip to the end of the file to append a new scrobble. _fileStream.Seek(0, SeekOrigin.End); var serializedScrobble = ScrobbleSerializer.Serialize(scrobble); byte[] buffer = Encoding.UTF8.GetBytes(serializedScrobble); byte[] newLineBuffer = Encoding.UTF8.GetBytes("\n"); await _fileStream.WriteAsync(newLineBuffer, 0, newLineBuffer.Length); await _fileStream.WriteAsync(buffer, 0, buffer.Length); } }
/// <summary> /// Scrobbles the track with the given info. /// </summary> public override async Task Scrobble() { EnableControls = false; try { OnStatusUpdated("Trying to scrobble..."); Scrobble s = new Scrobble(Artist, Album, Track, Time) { AlbumArtist = AlbumArtist, Duration = Duration }; var response = await Scrobbler.ScrobbleAsync(s); if (response.Success) { OnStatusUpdated("Successfully scrobbled!"); } else { OnStatusUpdated("Error while scrobbling!"); } } catch (Exception ex) { OnStatusUpdated("Fatal error while trying to scrobble: " + ex.Message); } finally { EnableControls = true; } }
public async Task ScrobbleTest() { Scrobble expected = new Scrobble("TestArtist", "TestAlbum", "TestTrack", DateTime.Now) { AlbumArtist = "TestAlbumArtist", Duration = TimeSpan.FromSeconds(30) }; Mock <IAuthScrobbler> scrobblerMock = new Mock <IAuthScrobbler>(); Scrobble actual = null; scrobblerMock.Setup(i => i.ScrobbleAsync(It.IsAny <Scrobble>())).Callback <Scrobble>(s => actual = s); ManualScrobbleViewModel vm = new ManualScrobbleViewModel(null) { Scrobbler = scrobblerMock.Object, UseCurrentTime = false, Artist = expected.Artist, Album = expected.Album, Track = expected.Track, Time = expected.TimePlayed.DateTime, AlbumArtist = expected.AlbumArtist, Duration = expected.Duration.Value }; await vm.Scrobble(); Assert.That(actual.IsEqualScrobble(expected), Is.True); }
/// <summary> /// Clones the given <paramref name="scrobble"/> with an added /// second to the <see cref="Scrobble.TimePlayed"/>. This is used /// because some scrobblers add an extra second to be able /// to scrobble duplicates. /// </summary> /// <param name="scrobble">The scrobble to clone with an additional second.</param> /// <returns>Cloned scrobble.</returns> public static Scrobble CloneWithAddedTime(this Scrobble scrobble, TimeSpan timeToAdd) { return(new Scrobble(scrobble.Artist, scrobble.Album, scrobble.Track, scrobble.TimePlayed.Add(timeToAdd)) { AlbumArtist = scrobble.AlbumArtist, Duration = scrobble.Duration }); }
public static Scrobble Deserialize(string serializedScrobble) { if (serializedScrobble == null) { throw new ArgumentNullException(nameof(serializedScrobble)); } var encodedFields = serializedScrobble.Split(FieldSeparator); if (encodedFields.Length != 8) { throw new ArgumentException("Wrong number of fields.", nameof(serializedScrobble)); } DateTimeOffset timestamp = DateTimeOffset.FromUnixTimeSeconds(long.Parse(Decode(encodedFields[0]), CultureInfo.InvariantCulture)); TimeSpan?duration; string durationField = Decode(encodedFields[7]); duration = string.IsNullOrWhiteSpace(durationField) ? (TimeSpan?)null : TimeSpan.FromSeconds(int.Parse(durationField, CultureInfo.InvariantCulture)); var result = new Scrobble(artist: Decode(encodedFields[2]), track: Decode(encodedFields[1]), timestamp: timestamp) { Album = Decode(encodedFields[3]), AlbumArtist = Decode(encodedFields[4]), TrackNumber = Decode(encodedFields[5]), Mbid = Decode(encodedFields[6]), Duration = duration, }; return(result); }
public async Task ScrobbleTest() { Scrobble expected = new Scrobble("TestArtist", "TestAlbum", "TestTrack", DateTime.Now) { AlbumArtist = "TestAlbumArtist", Duration = TimeSpan.FromSeconds(30) }; Mock <IUserScrobbler> scrobblerMock = new Mock <IUserScrobbler>(); Scrobble actual = null; scrobblerMock.Setup(i => i.ScrobbleAsync(It.IsAny <Scrobble>(), false)).Callback <Scrobble, bool>((s, c) => actual = s) .Returns(Task.Run(() => new ScrobbleResponse(LastResponseStatus.Successful))); Mock <IExtendedWindowManager> windowManagerMock = new Mock <IExtendedWindowManager>(MockBehavior.Strict); ManualScrobbleViewModel vm = new ManualScrobbleViewModel(windowManagerMock.Object) { Scrobbler = scrobblerMock.Object, Artist = expected.Artist, Album = expected.Album, Track = expected.Track, AlbumArtist = expected.AlbumArtist, Duration = expected.Duration.Value }; vm.ScrobbleTimeVM.UseCurrentTime = false; vm.ScrobbleTimeVM.Time = expected.TimePlayed.DateTime; await vm.Scrobble(); Assert.That(actual.IsEqualScrobble(expected), Is.True); }
/// <summary> /// Clones the given <paramref name="scrobble"/> with an added /// second to the <see cref="Scrobble.TimePlayed"/>. This is used /// because some scrobblers add an extra second to be able /// to scrobble duplicates. /// </summary> /// <param name="scrobble">The scrobble to clone with an additional second.</param> /// <returns>Cloned scrobble.</returns> public static Scrobble CloneWithAddedSecond(this Scrobble scrobble) { return(new Scrobble(scrobble.Artist, scrobble.Album, scrobble.Track, scrobble.TimePlayed.AddSeconds(1)) { AlbumArtist = scrobble.AlbumArtist, Duration = scrobble.Duration }); }
public void UpdateRecentScrobblesTest() { // given: user with recent scrobbles User user = new User("TestUser", "TestToken", false); int numScrobbles = 10; DateTime timePlayed = DateTime.Now.Subtract(TimeSpan.FromHours(25)); Scrobble[] scrobbles = new Scrobble[numScrobbles]; for (int i = 0; i < numScrobbles; i++) { // half of the scrobbles get a "normal" date that should // not be cleared if (i >= numScrobbles / 2) { scrobbles[i] = new Scrobble("", "", "", DateTime.Now); } else { scrobbles[i] = new Scrobble("", "", "", timePlayed); } } user.AddScrobbles(scrobbles); // when: updating recent scrobbles user.UpdateRecentScrobbles(); // then: half of the scrobbles should be gone Assert.That(user.RecentScrobbles.Count, Is.EqualTo(numScrobbles / 2)); // all recent scrobbles are newer than 1 day Assert.That(user.RecentScrobbles.All(s => s.Item2 > DateTime.Now.Subtract(TimeSpan.FromDays(1)))); }
private void pageRoot_Loaded_1(object sender, RoutedEventArgs e) { if (MediaControl.IsPlaying) { BG1.Begin(); id3 = Playlist.NowPlaying[0]; SongTitle.Text = id3.Title; Artist.Text = id3.Artist; } else { SongTitle.Text = "Play a song now!"; Artist.Text = "Swipe up from bottom for more options!"; } if (Security._vault.RetrieveAll().Count != 0) { Scrobble.SetValue(AutomationProperties.NameProperty, "Last.fm Signout"); PasswordCredential rt = Security._vault.Retrieve("Session Key", "user"); rt.RetrievePassword(); Globalv.session_key = rt.Password; } /* * if (Globalv.session_key != null) * LoginBtn.Content = "Logoff"; * else * LoginBtn.Content = "Login"; */ }
/// <summary> /// Checks if this Scrobble has equal values as the <paramref name="expected"/> scrobble. /// </summary> /// <param name="actual">Actual scrobble values.</param> /// <param name="expected">Scrobble values to check.</param> /// <returns>True if scrobbles are equal, false if not.</returns> public static bool IsEqualScrobble(this Scrobble actual, Scrobble expected) { return(actual.Artist == expected.Artist && actual.Album == expected.Album && actual.Track == expected.Track && actual.TimePlayed.ToString() == expected.TimePlayed.ToString() && actual.AlbumArtist == expected.AlbumArtist && actual.Duration == expected.Duration); }
/// <summary> /// Scrobbles the current song. /// </summary> /// <returns>Task.</returns> public override async Task Scrobble() { if (EnableControls && CanScrobble) { EnableControls = false; Scrobble s = null; try { OnStatusUpdated(string.Format("Trying to scrobble '{0}'...", CurrentTrackName)); // lock while acquiring current data lock (_lockAnchor) { // try to get AlbumArtist string albumArtist = string.Empty; try { albumArtist = (ITunesApp.CurrentTrack as dynamic).AlbumArtist; } catch (RuntimeBinderException) { // swallow, AlbumArtist doesn't exist for some reason. } s = new Scrobble(CurrentArtistName, CurrentAlbumName, CurrentTrackName, DateTime.Now) { Duration = TimeSpan.FromSeconds(CurrentTrackLength), AlbumArtist = albumArtist }; } var response = await Scrobbler.ScrobbleAsync(s, true); if (response.Success && response.Status == LastResponseStatus.Successful) { OnStatusUpdated(string.Format("Successfully scrobbled '{0}'", s.Track)); } else if (response.Status == LastResponseStatus.Cached) { OnStatusUpdated(string.Format("Scrobbling '{0}' failed. Scrobble has been cached", s.Track)); } else { OnStatusUpdated(string.Format("Error while scrobbling '{0}': {1}", s.Track, response.Status)); } } catch (Exception ex) { OnStatusUpdated(string.Format("Fatal error while trying to scrobble '{0}': {1}", s?.Track, ex.Message)); } finally { EnableControls = true; } } }
public TrackScrobbleCommandTests() { _scrobblePlayed = DateTimeOffset.UtcNow; _testScrobble = new Scrobble("Kate Nash", "Made of Bricks", "Foundations", _scrobblePlayed) { AlbumArtist = "Kate Nash" }; _command = new ScrobbleCommand(MAuth.Object, _testScrobble); }
/// <summary> /// Creates generic scrobbles (without information). /// </summary> /// <param name="amount">Amount of scrobbles to create.</param> /// <returns>Newly created, generic scrobbles.</returns> public static Scrobble[] CreateGenericScrobbles(int amount) { Scrobble[] scrobbles = new Scrobble[amount]; for (int i = 0; i < scrobbles.Length; i++) { scrobbles[i] = new Scrobble(); } return(scrobbles); }
public async Task <string> UpdateNowPlaying(SongDetails song) { if (!client.Auth.Authenticated) { await Authenticate(client); } var scrobble = new Scrobble(song.Artist, song.Album, song.Song, DateTime.UtcNow); var response = await client.Track.UpdateNowPlayingAsync(scrobble); return(response.Status.ToString()); }
/// <summary> /// Scrobbles the current song. /// </summary> /// <returns>Task.</returns> public override async Task Scrobble() { if (EnableControls && CanScrobble) { EnableControls = false; try { OnStatusUpdated("Trying to scrobble currently playing track..."); // try to get AlbumArtist string albumArtist = string.Empty; try { albumArtist = (ITunesApp.CurrentTrack as dynamic).AlbumArtist; } catch (RuntimeBinderException) { // swallow, AlbumArtist doesn't exist for some reason. } Scrobble s = new Scrobble(CurrentArtistName, CurrentAlbumName, CurrentTrackName, DateTime.Now) { Duration = TimeSpan.FromSeconds(CurrentTrackLength), AlbumArtist = albumArtist }; var response = await Scrobbler.ScrobbleAsync(s); if (response.Success && response.Status == LastResponseStatus.Successful) { OnStatusUpdated(string.Format("Successfully scrobbled {0}!", CurrentTrackName)); } else if (response.Status == LastResponseStatus.Cached) { OnStatusUpdated(string.Format("Scrobbling of track {0} failed. Scrobble has been cached", CurrentTrackName)); } else { OnStatusUpdated("Error while scrobbling: " + response.Status); } } catch (Exception ex) { OnStatusUpdated("Fatal error while trying to scrobble currently playing track. Error: " + ex.Message); } finally { EnableControls = true; } } }
public static IEnumerable <object[]> SerializationTestData() { { var scrobble = new Scrobble("", "", DateTimeOffset.FromUnixTimeMilliseconds(0)); var serialized = "0&&&&&&&"; yield return(new object[] { scrobble, serialized }); } { var scrobble = new Scrobble("track", "artist", DateTimeOffset.FromUnixTimeMilliseconds(123_456)) { Album = "album", AlbumArtist = "albumArtist", Duration = TimeSpan.FromSeconds(789), Mbid = "mbid", TrackNumber = "trackNumber" }; var serialized = "123&track&artist&album&albumArtist&trackNumber&mbid&789"; yield return(new object[] { scrobble, serialized }); } { var scrobble = new Scrobble("♥", "♥", DateTimeOffset.FromUnixTimeMilliseconds(123_456)) { Album = "♥", AlbumArtist = "♥", Duration = TimeSpan.FromSeconds(789), Mbid = "♥", TrackNumber = "♥" }; var serialized = "123&%E2%99%A5&%E2%99%A5&%E2%99%A5&%E2%99%A5&%E2%99%A5&%E2%99%A5&789"; yield return(new object[] { scrobble, serialized }); } { var scrobble = new Scrobble("&♥", "&♥", DateTimeOffset.FromUnixTimeMilliseconds(123_456)) { Album = "&♥", AlbumArtist = "&♥", Duration = TimeSpan.FromSeconds(789), Mbid = "&♥", TrackNumber = "&♥" }; var serialized = "123&%26%E2%99%A5&%26%E2%99%A5&%26%E2%99%A5&%26%E2%99%A5&%26%E2%99%A5&%26%E2%99%A5&789"; yield return(new object[] { scrobble, serialized }); } { var scrobble = new Scrobble(default, default, default);
// Private method for converting an incorrectly formatted scrobble response into a correctly formatted response from this client private ScrobbleResponse GetScrobbleResponseFromScrobble(JObject scrobbleResponse) { // De-serializing the scrobble response seems to be hit and miss if you follow 'normal convention'. // JsonConvert.Deserialize fails to de-serialize the scrobble response with a 'Path scrobbles.scrobble.artist' error. // However, splitting out the JSON string from the root node, and converting the objects into the relevant types // seems to solve the problem nicely. From these response we can then build up the overall scrobble response, setting // the relevant flags. ScrobbleResponse response = new ScrobbleResponse(); List <Scrobble> scrobbleResults = new List <Scrobble>(); if (scrobbleResponse["scrobbles"]["scrobble"] is JArray) { // Convert the scrobble responses into an array Scrobble[] scrobbles = JsonConvert.DeserializeObject <Scrobble[]>(scrobbleResponse["scrobbles"]["scrobble"].ToString()); if (scrobbles != null) { scrobbleResults.AddRange(scrobbles.ToList()); } } else { Scrobble scrobble = JsonConvert.DeserializeObject <Scrobble>(scrobbleResponse["scrobbles"]["scrobble"].ToString()); if (scrobble != null) { scrobbleResults.Add(scrobble); } } // Parse the results, and set the relevant properties int ignored = scrobbleResults.Count(item => item.IgnoredMessage.Code != Enums.ReasonCodes.IgnoredReason.AllOk); int accepted = scrobbleResults.Count(item => item.IgnoredMessage.Code == Enums.ReasonCodes.IgnoredReason.AllOk); response.Scrobbles = new Scrobbles() { AcceptedResult = new Models.AcceptedResult() { Ignored = ignored, Accepted = accepted }, ScrobbleItems = scrobbleResults.ToArray() }; return(response); }
/// <summary> /// Scrobbles the track entered in the textBoxes. /// </summary> private async void btnScrobble_Click(object sender, EventArgs e) { UpdateTimes(sender, e); lblScrobbleStatusInfo.Text = "Trying to scrobble."; dateTimePicker1.Value = new DateTime(dateTimePicker1.Value.Year, dateTimePicker1.Value.Month, dateTimePicker1.Value.Day, dateTimePicker2.Value.Hour, dateTimePicker2.Value.Minute, dateTimePicker2.Value.Second); Scrobble s = new Scrobble(textBoxArtist.Text, textBoxAlbum.Text, textBoxTrack.Text, dateTimePicker1.Value); var response = await _scrobbler.ScrobbleAsync(s); if (response.Success) { lblScrobbleStatusInfo.Text = "Successfully scrobbled."; } else { lblScrobbleStatusInfo.Text = "Failed to scrobble."; } }
public async void ScrobbleTrack(string artist, string album, string track) { var trackApi = new TrackApi(_auth); var scrobble = new Scrobble(artist, album, track, DateTimeOffset.Now); IScrobbler _scrobbler; _scrobbler = new Scrobbler(_auth); var response = await _scrobbler.ScrobbleAsync(scrobble); if (response.Success) { Debug.WriteLine("Scrobble success!"); } else { Debug.WriteLine("Scrobble failed!"); } }
/// <summary> /// Scrobbles the currently playing track. /// </summary> /// <returns>Task.</returns> public override async Task Scrobble() { if (CanScrobble && !_currentResponse.Track.IsAd()) { EnableControls = false; Scrobble s = null; try { OnStatusUpdated($"Trying to scrobble '{CurrentTrackName}'..."); // lock while acquiring current data lock (_lockAnchor) { s = new Scrobble(CurrentArtistName, CurrentAlbumName, CurrentTrackName, DateTime.Now) { Duration = TimeSpan.FromSeconds(CurrentTrackLength), }; } var response = await Scrobbler.ScrobbleAsync(s, true); if (response.Success && response.Status == LastResponseStatus.Successful) { OnStatusUpdated($"Successfully scrobbled '{s.Track}'"); } else if (response.Status == LastResponseStatus.Cached) { OnStatusUpdated($"Scrobbling '{s.Track}' failed. Scrobble has been cached"); } else { OnStatusUpdated($"Error while scrobbling '{s.Track}': {response.Status}"); } } catch (Exception ex) { OnStatusUpdated($"Fatal error while trying to scrobble '{s.Track}: {ex.Message}"); } finally { EnableControls = true; } } }
public async Task ScrobblesSingle() { var trackPlayed = DateTimeOffset.UtcNow.AddMinutes(-1).RoundToNearestSecond(); var testScrobble = new Scrobble("Hot Chip", "The Warning", "Over and Over", trackPlayed) { AlbumArtist = ARTIST_NAME, ChosenByUser = false }; var response = await Lastfm.Scrobbler.ScrobbleAsync(testScrobble); Assert.IsTrue(response.Success); var expectedTrack = new LastTrack { Name = TRACK_NAME, ArtistName = ARTIST_NAME, AlbumName = ALBUM_NAME, }; var expectedJson = expectedTrack.TestSerialise(); var tracks = await Lastfm.User.GetRecentScrobbles(Lastfm.Auth.UserSession.Username, null, null, false, 1, 1); var scrobbledTrack = tracks.Single(x => !x.IsNowPlaying.GetValueOrDefault(false)); // This test fails here when it took too much time to test the whole solution // TestHelper.AssertSerialiseEqual(trackPlayed, scrobbledTrack.TimePlayed); scrobbledTrack.TimePlayed = null; // Some properties change from time to time; parsing is covered in unit tests scrobbledTrack.Mbid = null; scrobbledTrack.ArtistMbid = null; scrobbledTrack.Images = null; scrobbledTrack.Url = null; scrobbledTrack.ArtistImages = null; scrobbledTrack.ArtistUrl = null; scrobbledTrack.IsLoved = null; var actualJson = scrobbledTrack.TestSerialise(); Assert.AreEqual(expectedJson, actualJson, expectedJson.DifferencesTo(actualJson)); }
public static string Serialize(Scrobble scrobble) { if (scrobble == null) { throw new ArgumentNullException(nameof(scrobble)); } var sb = new StringBuilder(); sb.Append(Encode(scrobble.StringTimestamp)); sb.Append(FieldSeparator); sb.Append(Encode(scrobble.Track)); sb.Append(FieldSeparator); sb.Append(Encode(scrobble.Artist)); sb.Append(FieldSeparator); sb.Append(Encode(scrobble.Album)); sb.Append(FieldSeparator); sb.Append(Encode(scrobble.AlbumArtist)); sb.Append(FieldSeparator); sb.Append(Encode(scrobble.TrackNumber)); sb.Append(FieldSeparator); sb.Append(Encode(scrobble.Mbid)); sb.Append(FieldSeparator); sb.Append(Encode(scrobble.StringDuration)); return(sb.ToString()); }
public async Task UpdatesNowPlaying() { var trackPlayed = DateTime.UtcNow.AddMinutes(-1); var testScrobble = new Scrobble(ARTIST_NAME, ALBUM_NAME, TRACK_NAME, trackPlayed) { Duration = new TimeSpan(0, 0, 3, 49, 200), AlbumArtist = ARTIST_NAME }; var response = await Lastfm.Track.UpdateNowPlayingAsync(testScrobble); Assert.IsTrue(response.Success); await Task.Delay(1000); var tracks = await Lastfm.User.GetRecentScrobbles(Lastfm.Auth.UserSession.Username, null, null, false, 1, 1); var expectedTrack = new LastTrack { Name = TRACK_NAME, ArtistName = ARTIST_NAME, AlbumName = ALBUM_NAME, IsNowPlaying = true }; var actual = tracks.Content.Single(x => x.IsNowPlaying.GetValueOrDefault(false)); // Some properties change from time to time actual.Mbid = null; actual.ArtistMbid = null; actual.Images = null; actual.Url = null; actual.ArtistImages = null; actual.ArtistUrl = null; actual.IsLoved = null; var expectedJson = expectedTrack.TestSerialise(); var actualJson = actual.TestSerialise(); Assert.AreEqual(expectedJson, actualJson, expectedJson.DifferencesTo(actualJson)); }
public async void OnTrackCanScrobble(string title, string artist, string album, string trackNumber, int durationMs, long utcUnixTimestamp) { Scrobble scrobble = CreateScrobble(title, artist, album, trackNumber, null, durationMs, utcUnixTimestamp); Logger.Log(LogLevel.Info, $"Track played on {scrobble.Timestamp.ToLocalTime():s} ready to scrobble: '{title}', artist: '{artist}', album: '{album}'"); // Cache the scrobble and wait for the end of the track to actually send it. try { await _cache.StoreAsync(scrobble); } catch (Exception ex) { lock (_lastPotentialScrobbleInCaseOfCacheFailureLock) { _lastPotentialScrobbleInCaseOfCacheFailure = scrobble; } Logger.Log(LogLevel.Warn, $"An error occured while trying to store a scrobble into the cache file: {ex}"); ShowErrorBubble(ex); } }
public async Task ScrobblesSingle() { var trackPlayed = DateTimeOffset.UtcNow.AddMinutes(-1).RoundToNearestSecond(); var testScrobble = new Scrobble("Hot Chip", "The Warning", "Over and Over", trackPlayed) { AlbumArtist = ARTIST_NAME, ChosenByUser = false }; var response = await Lastfm.Scrobbler.ScrobbleAsync(testScrobble); Assert.IsTrue(response.Success); var expectedTrack = new LastTrack { Name = TRACK_NAME, ArtistName = ARTIST_NAME, AlbumName = ALBUM_NAME }; var expectedJson = expectedTrack.TestSerialise(); var tracks = await Lastfm.User.GetRecentScrobbles(Lastfm.Auth.UserSession.Username, null, 1, 1); Assert.IsTrue(tracks.Any()); var actual = tracks.Content.First(); TestHelper.AssertSerialiseEqual(trackPlayed, actual.TimePlayed); actual.TimePlayed = null; // Some properties change from time to time; parsing is covered in unit tests actual.Mbid = null; actual.ArtistMbid = null; actual.Images = null; actual.Url = null; var actualJson = actual.TestSerialise(); Assert.AreEqual(expectedJson, actualJson, expectedJson.DifferencesTo(actualJson)); }
/// <summary> /// Scrobbles the currently playing track. /// </summary> /// <returns>Task.</returns> public override async Task Scrobble() { if (CanScrobble && !_currentResponse.Track.IsAd()) { EnableControls = false; try { OnStatusUpdated("Trying to scrobble currently playing track..."); Scrobble s = new Scrobble(CurrentArtistName, CurrentAlbumName, CurrentTrackName, DateTime.Now) { Duration = TimeSpan.FromSeconds(CurrentTrackLength), }; var response = await Scrobbler.ScrobbleAsync(s); if (response.Success && response.Status == LastResponseStatus.Successful) { OnStatusUpdated(string.Format("Successfully scrobbled {0}!", CurrentTrackName)); } else if (response.Status == LastResponseStatus.Cached) { OnStatusUpdated(string.Format("Scrobbling of track {0} failed. Scrobble has been cached", CurrentTrackName)); } else { OnStatusUpdated("Error while scrobbling: " + response.Status); } } catch (Exception ex) { OnStatusUpdated("Fatal error while trying to scrobble currently playing track. Error: " + ex.Message); } finally { EnableControls = true; } } }