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));
        }
        public async Task HandleResponseMultiple()
        {
            var command = new GetTracksCommand(MAuth.Object, "rj", "", "", DateTimeOffset.MinValue)
            {
                Count = 1
            }; 

            var expectedTrack = new LastTrack
            {
                ArtistName = "Stevie Wonder",
                Duration = new TimeSpan(0, 4, 8),
                PlayCount = 56,
                Mbid = "0161855d-0b98-4f2d-b2ab-446dbd8d6759",
                Name = "Superstition",
                ArtistMbid = "1ee18fb3-18a6-4c7f-8ba0-bc41cdd0462e",
                AlbumName = "Number Ones",
                Url = new Uri("http://www.last.fm/music/Stevie+Wonder/_/Superstition", UriKind.Absolute),
                Images = new LastImageSet(
                    "http://userserve-ak.last.fm/serve/34s/99695819.jpg",
                    "http://userserve-ak.last.fm/serve/64s/99695819.jpg",
                    "http://userserve-ak.last.fm/serve/126/99695819.jpg",
                    "http://userserve-ak.last.fm/serve/300x300/99695819.jpg")

            };

            var response = CreateResponseMessage(Encoding.UTF8.GetString(LibraryApiResponses.LibraryGetTracksMultiple));
            var actual = await command.HandleResponse(response);

            Assert.IsTrue(actual.Success);
            TestHelper.AssertSerialiseEqual(expectedTrack, actual.Content[1]); // Testing the second track returned
        }
        public async Task HandleResponseSingle()
        {
            var command = new GetTracksCommand(MAuth.Object, "rj", "", "", DateTimeOffset.MinValue)
            {
                Count = 1
            };

            var expectedTrack = new LastTrack
            {
                ArtistName = "Dire Straits",
                Duration = new TimeSpan(0, 5, 47),
                PlayCount = 81,
                Mbid = "0317e524-7f70-4910-bc12-95dd468a29fc",
                Name = "Sultans of Swing",
                ArtistMbid = "614e3804-7d34-41ba-857f-811bad7c2b7a",
                AlbumName = "Dire Straits (Remastered)",
                Url = new Uri("http://www.last.fm/music/Dire+Straits/_/Sultans+of+Swing", UriKind.Absolute),
                Images = new LastImageSet(
                    "http://userserve-ak.last.fm/serve/34s/56827829.jpg",
                    "http://userserve-ak.last.fm/serve/64s/56827829.jpg",
                    "http://userserve-ak.last.fm/serve/126/56827829.jpg",
                    "http://userserve-ak.last.fm/serve/300x300/56827829.jpg")
            };
            
            var response = CreateResponseMessage(Encoding.UTF8.GetString(LibraryApiResponses.LibraryGetTracksSingle));
            var actual = await command.HandleResponse(response);

            Assert.IsTrue(actual.Success);
            TestHelper.AssertSerialiseEqual(expectedTrack, actual.Single());
        }
        public async Task HandleResponseSingle()
        {
            var command = new GetRecentTracksCommand(MAuth.Object, "rj")
            {
                Count = 1
            };

            var expectedTrack = new LastTrack
            {
                ArtistName = "Rick James",
                Mbid = "",
                Name = "Super Freak (Part 1) - 1981 Single Version",
                ArtistMbid = "cba9cec2-be8d-41bd-91b4-a1cd7de39b0c",

                TimePlayed = new DateTime(2014,12,20,10,16,52, DateTimeKind.Utc),
                AlbumName = "The Definitive Collection",
                Url = new Uri("http://www.last.fm/music/Rick+James/_/Super+Freak+(Part+1)+-+1981+Single+Version", UriKind.Absolute),
                Images = new LastImageSet(
                    "http://userserve-ak.last.fm/serve/34s/90462319.jpg",
                    "http://userserve-ak.last.fm/serve/64s/90462319.jpg",
                    "http://userserve-ak.last.fm/serve/126/90462319.jpg",
                    "http://userserve-ak.last.fm/serve/300x300/90462319.jpg")
            };
            
            var response = CreateResponseMessage(Encoding.UTF8.GetString(UserApiResponses.UserGetRecentTracksSingle));
            var actual = await command.HandleResponse(response);

            Assert.IsTrue(actual.Success);
            TestHelper.AssertSerialiseEqual(expectedTrack, actual.Single());
        }
        public async Task HandleResponseMultiple()
        {
            var command = new GetRecentTracksCommand(MAuth.Object, "rj")
            {
                Count = 1
            };

            var expectedTrack = new LastTrack
            {
                ArtistName = "The Who",
                TimePlayed = new DateTime(2014, 12, 19, 16, 13, 55,DateTimeKind.Utc),
                Mbid = "79f3dc97-2297-47ee-8556-9a1bb4b48d53",
                Name = "Pinball Wizard",
                ArtistMbid = "9fdaa16b-a6c4-4831-b87c-bc9ca8ce7eaa",
                AlbumName = "Tommy (Remastered)",
                Url = new Uri("http://www.last.fm/music/The+Who/_/Pinball+Wizard", UriKind.Absolute),
                Images = new LastImageSet(
                    "http://userserve-ak.last.fm/serve/34s/35234991.jpg",
                    "http://userserve-ak.last.fm/serve/64s/35234991.jpg",
                    "http://userserve-ak.last.fm/serve/126/35234991.jpg",
                    "http://userserve-ak.last.fm/serve/300x300/35234991.jpg")
            };

            var response = CreateResponseMessage(Encoding.UTF8.GetString(UserApiResponses.UserGetRecentTracksMultiple));
            var actual = await command.HandleResponse(response);

            Assert.IsTrue(actual.Success);
            TestHelper.AssertSerialiseEqual(expectedTrack, actual.Content[2]);
        }
        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 testGuid = Guid.Empty;
            var expectedTrack = new LastTrack
            {
                Name = TRACK_NAME,
                ArtistName = ARTIST_NAME,
                AlbumName = ALBUM_NAME,
                Mbid = testGuid.ToString("D"),
                ArtistMbid = testGuid.ToString("D"),
                Url = new Uri("http://www.last.fm/music/Hot+Chip/_/Over+and+Over"),
                Images = new LastImageSet("http://userserve-ak.last.fm/serve/34s/50921593.png",
                    "http://userserve-ak.last.fm/serve/64s/50921593.png",
                    "http://userserve-ak.last.fm/serve/126/50921593.png",
                    "http://userserve-ak.last.fm/serve/300x300/50921593.png")
            };
            var expectedJson = expectedTrack.TestSerialise();

            var tracks = await Lastfm.User.GetRecentScrobbles(Lastfm.Auth.UserSession.Username, null, 0, 1);
            Assert.IsTrue(tracks.Any());

            var actual = tracks.Content.First();
            
            TestHelper.AssertSerialiseEqual(trackPlayed, actual.TimePlayed);
            actual.TimePlayed = null;

            // MBIDs returned by last.fm change from time to time, so let's just test that they're there.
            Assert.IsTrue(Guid.Parse(actual.Mbid) != Guid.Empty);
            Assert.IsTrue(Guid.Parse(actual.ArtistMbid) != Guid.Empty);
            actual.Mbid = testGuid.ToString("D");
            actual.ArtistMbid = testGuid.ToString("D");

            var actualJson = actual.TestSerialise();

            Assert.AreEqual(expectedJson, actualJson, expectedJson.DifferencesTo(actualJson));
        }
예제 #7
0
        public static async Task<SaveResults> SaveTrackAsync(LastTrack track)
        {
            try
            {
                Song preparedSong = null;
                var providerId = track.ToSong().ProviderId;
                if (providerId == "lastid.")
                {
                    preparedSong = await PrepareTrackForDownloadAsync(track);
                    providerId = preparedSong.ProviderId;
                }

                var exists = App.Locator.CollectionService.SongAlreadyExists(
                    providerId,
                    track.Name,
                    track.AlbumName,
                    track.ArtistName);
                if (exists != null)
                {
                    return new SaveResults() { Error = SavingError.AlreadyExists, Entry = exists };
                }

                if (preparedSong == null)
                {
                    preparedSong = await PrepareTrackForDownloadAsync(track);
                }

                await App.Locator.CollectionService.AddSongAsync(preparedSong).ConfigureAwait(false);

                CollectionHelper.MatchSong(preparedSong);
                return new SaveResults{Error = SavingError.None, Entry = preparedSong};
            }
            catch (NetworkException)
            {
                return new SaveResults { Error = SavingError.Network };
            }
            catch
            {
                return new SaveResults { Error = SavingError.Unknown };
            }
        }
예제 #8
0
        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));
        }
예제 #9
0
        internal static async Task<Song> PrepareTrackForDownloadAsync(LastTrack track)
        {
            var lastTrack =
                await
                App.Locator.ScrobblerService.GetDetailTrack(track.Name, track.ArtistName).ConfigureAwait(false);
            LastArtist artist;

            if (lastTrack != null) track = lastTrack;

            var preparedSong = track.ToSong();
            preparedSong.ArtistName = track.ArtistName;

            if (!string.IsNullOrEmpty(track.AlbumName + track.AlbumName))
            {
                var lastAlbum =
                    await
                    App.Locator.ScrobblerService.GetDetailAlbum(
                        track.AlbumName, 
                        track.ArtistName);

                artist = await App.Locator.ScrobblerService.GetDetailArtist(track.ArtistName).ConfigureAwait(false);

                if (lastAlbum != null)
                    preparedSong.Album = lastAlbum.ToAlbum();
                if (artist != null)
                    preparedSong.Album.PrimaryArtist = artist.ToArtist();
            }
            else
            {
                artist = await App.Locator.ScrobblerService.GetDetailArtist(track.ArtistName).ConfigureAwait(false);
            }

            if (artist != null)
                preparedSong.Artist = artist.ToArtist();

            return preparedSong;
        }
예제 #10
0
파일: LastTrack.cs 프로젝트: 0Delfo0/lastfm
        /// <summary>
        /// Parses the given JToken into a track
        /// </summary>
        /// <param name="token">A valid JToken</param>
        /// <returns>track equivalent to the JToken</returns>
        /// <remarks>If this method is used directly then the duration attribute will be parsed as MILLIseconds</remarks>
        internal static LastTrack ParseJToken(JToken token)
        {
            var t = new LastTrack();

            t.Id   = token.Value <string>("id");
            t.Name = token.Value <string>("name");
            t.Mbid = token.Value <string>("mbid");

            //some tracks do not contain the playcount prop, it will throw a FormatException
            var playCountStr = token.Value <string>("playcount");
            int playCount;

            if (int.TryParse(playCountStr, out playCount))
            {
                t.PlayCount = playCount;
            }

            var listenerCountStr = token.Value <string>("listeners");
            int listenerCount;

            if (int.TryParse(listenerCountStr, out listenerCount))
            {
                t.ListenerCount = listenerCount;
            }

            var userPlayCountStr = token.Value <string>("userplaycount");
            int userPlayCount;

            if (int.TryParse(userPlayCountStr, out userPlayCount))
            {
                t.UserPlayCount = userPlayCount;
            }

            t.Url = new Uri(token.Value <string>("url"), UriKind.Absolute);

            var artistToken = token.SelectToken("artist");

            if (artistToken.Type != JTokenType.String)
            {
                t.ArtistName = LastArtist.GetNameFromJToken(artistToken);
                t.ArtistMbid = artistToken.Value <string>("mbid");
            }
            else
            {
                t.ArtistName = artistToken.ToObject <string>();
            }

            var albumToken = token.SelectToken("album");

            if (albumToken != null)
            {
                t.AlbumName = LastAlbum.GetNameFromJToken(albumToken);
            }

            var tagsToken = token.SelectToken("toptags");

            if (tagsToken != null)
            {
                var tagToken = tagsToken.SelectToken("tag");
                if (tagToken != null)
                {
                    t.TopTags =
                        tagToken.Type == JTokenType.Array
                        ? tagToken.Children().Select(token1 => LastTag.ParseJToken(token1))
                        : new List <LastTag> {
                        LastTag.ParseJToken(tagToken)
                    };
                }
            }

            var date = token.SelectToken("date");

            if (date != null)
            {
                var stamp = date.Value <double>("uts");
                t.TimePlayed = stamp.FromUnixTime();
            }

            var images = token.SelectToken("image");

            if (images != null)
            {
                var imageCollection = LastImageSet.ParseJToken(images);
                t.Images = imageCollection;
            }

            var lovedToken = token.SelectToken("userloved");

            if (lovedToken != null)
            {
                t.IsLoved = Convert.ToBoolean(lovedToken.Value <int>());
            }
            var attrToken = token.SelectToken("@attr");

            if (attrToken != null && attrToken.HasValues)
            {
                t.IsNowPlaying = attrToken.Value <bool>("nowplaying");
                t.Rank         = attrToken.Value <int?>("rank");
            }

            // api returns milliseconds when track.getInfo is called directly
            var    secsStr = token.Value <string>("duration");
            double secs;

            if (double.TryParse(secsStr, out secs))
            {
                if (Math.Abs(secs - default(double)) > double.Epsilon)
                {
                    t.Duration = TimeSpan.FromMilliseconds(secs);
                }
            }

            return(t);
        }
예제 #11
0
        public static async Task<SaveResults> SaveTrackAsync(LastTrack track)
        {
            using (
                var handle = Insights.TrackTime(
                    "Save Song",
                    new Dictionary<string, string>
                    {
                        {"Type", "LastFM"},
                        {"ProviderId", track.Id},
                        {"Name", track.Name},
                        {"ArtistName", track.ArtistName}
                    }))
            {
                var result = await _SaveTrackAsync(track);
                ShowResults(result, track.Name);

                handle.Data.Add("SavingError", result.ToString());

                return result;
            }
        }
예제 #12
0
        private static async Task<SaveResults> _SaveTrackAsync(LastTrack track)
        {
            if (track == null)
            {
                return new SaveResults {Error = SavingError.Unknown};
            }

            var alreadySaving = LastfmSavingTracks.FirstOrDefault(p => p == track.Id) != null;

            if (alreadySaving)
            {
                return new SaveResults { Error = SavingError.AlreadySaving };
            }

            LastfmSavingTracks.Add(track.Id);

            while (!App.Locator.CollectionService.IsLibraryLoaded)
            {
            }

            var startTransaction = !App.Locator.SqlService.DbConnection.IsInTransaction;

            if (startTransaction)
            {
                App.Locator.SqlService.BeginTransaction();
            }

            var result = await ScrobblerHelper.SaveTrackAsync(track);

            if (startTransaction)
            {
                App.Locator.SqlService.Commit();
            }

            ShowErrorResults(result.Error, track.Name);

            LastfmSavingTracks.Remove(track.Id);

#pragma warning disable 4014
            if (result.Entry != null)
            {
                var song = (Song)result.Entry;
                if (!song.Album.HasArtwork && !song.Album.NoArtworkFound)
                {
                    if (track.Images != null && track.Images.Largest != null)
                    {
                        SaveAlbumImageAsync(song.Album, track.Images.Largest.AbsoluteUri);
                    }
                    else
                    {
                        DownloadAlbumsArtworkAsync();
                    }
                }
            }

            DownloadArtistsArtworkAsync();
#pragma warning restore 4014

            return result;
        }
예제 #13
0
파일: LastAlbum.cs 프로젝트: RomanGL/lastfm
        internal static LastAlbum ParseJToken(JToken token)
        {
            var a = new LastAlbum();

            a.Id = token.Value <string>("id");
            var artistToken = token["artist"];

            switch (artistToken.Type)
            {
            case JTokenType.String:
                a.ArtistName = token.Value <string>("artist");
                break;

            case JTokenType.Object:
                a.ArtistName = artistToken.Value <string>("name");
                break;
            }

            var tracksToken = token.SelectToken("tracks");

            if (tracksToken != null)
            {
                var trackToken = tracksToken.SelectToken("track");
                if (trackToken != null)
                {
                    a.Tracks = trackToken.Type == JTokenType.Array
                        ? trackToken.Children().Select(t => LastTrack.ParseJToken(t, a.Name))
                        : new List <LastTrack>()
                    {
                        LastTrack.ParseJToken(trackToken, a.Name)
                    }
                }
                ;
            }
            else
            {
                a.Tracks = Enumerable.Empty <LastTrack>();
            }

            var tagsToken = token.SelectToken("toptags");

            if (tagsToken != null)
            {
                var tagToken = tagsToken.SelectToken("tag");
                if (tagToken != null)
                {
                    a.TopTags =
                        tagToken.Type == JTokenType.Array
                        ? tagToken.Children().Select(token1 => LastTag.ParseJToken(token1))
                        : new List <LastTag> {
                        LastTag.ParseJToken(tagToken)
                    };
                }
            }
            else
            {
                a.TopTags = Enumerable.Empty <LastTag>();
            }

            a.ListenerCount = token.Value <int?>("listeners");
            a.Mbid          = token.Value <string>("mbid");
            a.Name          = token.Value <string>("name");

            var playCountStr = token.Value <string>("playcount");
            int playCount;

            if (int.TryParse(playCountStr, out playCount))
            {
                a.PlayCount = playCount;
            }

            var images = token.SelectToken("image");

            if (images != null)
            {
                var imageCollection = LastImageSet.ParseJToken(images);
                a.Images = imageCollection;
            }

            a.Url = new Uri(token.Value <string>("url"), UriKind.Absolute);

            var            dateString = token.Value <string>("releasedate");
            DateTimeOffset releaseDate;

            if (DateTimeOffset.TryParse(dateString, out releaseDate))
            {
                a.ReleaseDateUtc = releaseDate;
            }

            var wikiToken = token["wiki"];

            if (wikiToken != null)
            {
                a.Wiki = LastWiki.ParseJToken(wikiToken);
            }

            return(a);
        }
예제 #14
0
        /// <summary>
        /// Parses the given JToken into a track
        /// </summary>
        /// <param name="token">A valid JToken</param>
        /// <returns>track equivalent to the JToken</returns>
        /// <remarks>If this method is used directly then the duration attribute will be parsed as MILLIseconds</remarks>
        internal static LastTrack ParseJToken(JToken token)
        {
            var t = new LastTrack();

            t.Id = token.Value<string>("id");
            t.Name = token.Value<string>("name");
            t.Mbid = token.Value<string>("mbid");

            //some tracks do not contain the playcount prop, it will throw a FormatException
            var playCountStr = token.Value<string>("playcount");
            int playCount;
            if (int.TryParse(playCountStr, out playCount))
            {
                t.PlayCount = playCount;
            }

            t.Url = new Uri(token.Value<string>("url"), UriKind.Absolute);

            var artistToken = token.SelectToken("artist");
            if (artistToken.Type != JTokenType.String)
            {
                t.ArtistName = LastArtist.GetNameFromJToken(artistToken);
                t.ArtistMbid = artistToken.Value<string>("mbid");
            }
            else
                t.ArtistName = artistToken.ToObject<string>();

            var albumToken = token.SelectToken("album");
            if (albumToken != null)
            {
                t.AlbumName = LastAlbum.GetNameFromJToken(albumToken);
            }

            var tagsToken = token.SelectToken("toptags");
            if (tagsToken != null)
            {
                var tagToken = tagsToken.SelectToken("tag");
                if (tagToken != null)
                {
                    t.TopTags =
                        tagToken.Type == JTokenType.Array
                        ? tagToken.Children().Select(token1 => LastTag.ParseJToken(token1))
                        : new List<LastTag> { LastTag.ParseJToken(tagToken) };
                }
            }

            var date = token.SelectToken("date");
            if (date != null)
            {
                var stamp = date.Value<double>("uts");
                t.TimePlayed = stamp.FromUnixTime();
            }

            var images = token.SelectToken("image");
            if (images != null)
            {
                var imageCollection = LastImageSet.ParseJToken(images);
                t.Images = imageCollection;
            }

            var lovedToken = token.SelectToken("userloved");
            if (lovedToken != null)
            {
                t.IsLoved = Convert.ToBoolean(lovedToken.Value<int>());
            }
            var attrToken = token.SelectToken("@attr");
            if (attrToken != null && attrToken.HasValues)
            {
                t.IsNowPlaying = attrToken.Value<bool>("nowplaying");
                t.Rank = attrToken.Value<int?>("rank");
            }

            // api returns milliseconds when track.getInfo is called directly
            var secsStr = token.Value<string>("duration");
            double secs;

            if (double.TryParse(secsStr, out secs))
            {
                if (Math.Abs(secs - default(double)) > double.Epsilon)
                {
                    t.Duration = TimeSpan.FromMilliseconds(secs);
                }
            }

            return t;
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="scrobble">The scrobbled track.</param>
 public FetchedFriendTrackViewModel(LastTrack scrobble)
 {
   Track = scrobble;
 }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="fetchedTrack">The fetched track.</param>
 /// <param name="smallAlbumImage">The small image of the parent album.</param>
 public FetchedTrackViewModel(LastTrack fetchedTrack, Uri smallAlbumImage)
 {
   FetchedTrack = fetchedTrack;
   SmallAlbumImage = smallAlbumImage;
 }