예제 #1
0
        // async due to await calls so can't be inside the above lambda expression without farmimg it out to a seperate function
        private async void UpdateHistoryInternal()
        {
            bool canRun = false;

            lock (historyLock)
            {
                if (!isUpdatingHistory)
                {
                    isUpdatingHistory = true;
                    canRun            = true;
                }
            }

            if (!canRun)
            {
                return;
            }

            Logger.Current.Log(new CallerInfo(), LogLevel.Info, "Updating history items");

            List <HistoryTable> historyItems = DatabaseManager.Current.FetchHistoryItems();

            // Process everything first so we don't have to wait for scrobbles to see those updates
            foreach (HistoryTable historyItem in historyItems)
            {
                SongModel song = LibraryModel.Current.LookupSongById(historyItem.SongId);

                if (song != null)
                {
                    if (!historyItem.Processed)
                    {
                        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                        {
                            song.PlayCount++;

                            if (song.LastPlayed < historyItem.DatePlayed)
                            {
                                song.LastPlayed = historyItem.DatePlayed;
                            }
                        });

                        historyItem.Processed = true;
                        DatabaseManager.Current.Update(historyItem);
                    }
                }
            }

            Logger.Current.Log(new CallerInfo(), LogLevel.Info, "Scrobbling history items");

            // TODO: #3 can batch scrobbles
            foreach (HistoryTable historyItem in historyItems)
            {
                if (!historyItem.Scrobbled)
                {
                    LastfmStatusCode scrobbleResult = await LastFMManager.Current.ScrobbleTrack(historyItem.SongName, historyItem.ArtistName, new DateTime(historyItem.DatePlayed));

                    Logger.Current.Log(new CallerInfo(), LogLevel.Info, "Scrobbling row {0} result {1}", historyItem.RowId, scrobbleResult);

                    // "Failure" is non-recoverable, so actually mark it as scrobbled so we don't retry later
                    if (scrobbleResult == LastfmStatusCode.Success ||
                        scrobbleResult == LastfmStatusCode.Failure)
                    {
                        historyItem.Scrobbled = true;
                    }
                }

                if (historyItem.Processed && historyItem.Scrobbled)
                {
                    DatabaseManager.Current.DeleteHistoryItem(historyItem.RowId);
                }
                else
                {
                    DatabaseManager.Current.Update(historyItem);
                }
            }

            Logger.Current.Log(new CallerInfo(), LogLevel.Info, "Done updating history items");

            lock (historyLock)
            {
                isUpdatingHistory = false;
            }
        }
예제 #2
0
        public async Task <LastfmStatusCode> ScrobbleTrack(string trackName, string artistName, DateTime time, bool retry = false)
        {
            bool isScrobblingOn = ApplicationSettings.GetSettingsValue <bool>(ApplicationSettings.SETTING_IS_LASTFM_SCROBBLING_ENABLED, false);

            if (!isScrobblingOn)
            {
                return(LastfmStatusCode.Success);
            }

            string sessionKey = ApplicationSettings.GetSettingsValue <string>(ApplicationSettings.SETTING_LASTFM_SESSION_TOKEN, string.Empty);

            if (sessionKey == string.Empty)
            {
                await UpdateScrobbleSession();

                sessionKey = ApplicationSettings.GetSettingsValue <string>(ApplicationSettings.SETTING_LASTFM_SESSION_TOKEN, string.Empty);

                if (sessionKey == string.Empty)
                {
                    return(LastfmStatusCode.Failure);
                }
            }

            int totalSeconds = (int)(time - UnixTimeZero).TotalSeconds;


            JObject result = await getInfo("track.scrobble",
                                           new Dictionary <string, string>() { { "track", trackName }, { "artist", artistName }, { "timestamp", totalSeconds.ToString() }, { "sk", sessionKey } },
                                           true);

            if (result["error"] != null)
            {
                int r = Int32.Parse(result["error"].ToString());

                // bad session key
                if (r == 9 && !retry)
                {
                    Logger.Current.Log(new CallerInfo(), LogLevel.Warning, "Got an invalid session response when scrobbling, retrying");

                    await UpdateScrobbleSession();

                    LastfmStatusCode secondSuccess = await ScrobbleTrack(trackName, artistName, time, true);

                    return(secondSuccess);
                }
                else if (r == 8 || r == 11 || r == 16 || r == 29)
                {
                    Logger.Current.Log(new CallerInfo(), LogLevel.Warning, "Got an retryable response {0} when scrobbling, retrying later", r);

                    return(LastfmStatusCode.RetryableFailure);
                }

                Logger.Current.Log(new CallerInfo(), LogLevel.Warning, "Got an failure response {0} when scrobbling, giving up", r);

                return(LastfmStatusCode.Failure);
            }
            else if (result["scrobbles"] != null)
            {
                return(LastfmStatusCode.Success);
            }
            else
            {
                return(LastfmStatusCode.Failure);
            }
        }