예제 #1
0
        public async Task <UpdateStatus> Update(IProgress <double> progress = null)
        {
            UpdateStatus updateStatus = new UpdateStatus();

            DateTime?libraryFreshnessDate = this.settingsService.GetLibraryFreshnessDate();
            DateTime currentTime          = DateTime.UtcNow;

            IProgress <int> subProgress = null;

            // Get status if we need to report progress

            if (!libraryFreshnessDate.HasValue && progress != null)
            {
                var status = await this.songsWebService.GetStatusAsync();

                subProgress = new Progress <int>(async songsCount => await progress.SafeReportAsync((((double)songsCount / status.AvailableTracks) * 0.75d) + 0.05d));
            }

            await progress.SafeReportAsync(0.03d);

            var allAccess = await this.configWebService.IsAllAccessAvailableAsync();

            if (this.settingsService.GetIsAllAccessAvailable() != allAccess)
            {
                updateStatus.SetBreakingChange();
                this.settingsService.SetIsAllAccessAvailable(allAccess);
            }

            await progress.SafeReportAsync(0.05d);

            // If this is not an initial load - let's send statistics first
            if (libraryFreshnessDate.HasValue)
            {
                var songsForStat = await this.songsRepository.GetSongsForStatUpdateAsync();

                if (songsForStat.Count > 0)
                {
                    var result = await this.songsWebService.SendStatsAsync(songsForStat);

                    foreach (var response in result.Responses)
                    {
                        if (string.Equals(response.ResponseCode, "OK", StringComparison.OrdinalIgnoreCase))
                        {
                            var song =
                                songsForStat.FirstOrDefault(
                                    x => string.Equals(x.SongId, response.Id, StringComparison.OrdinalIgnoreCase));

                            await this.songsRepository.ResetStatsAsync(song);
                        }
                    }
                }
            }

            await this.songsWebService.GetAllAsync(
                libraryFreshnessDate,
                subProgress,
                async (gSongs) =>
            {
                IList <Song> toBeDeleted  = new List <Song>();
                IList <Song> toBeUpdated  = new List <Song>();
                IList <Song> toBeInserted = new List <Song>();

                foreach (var googleMusicSong in gSongs)
                {
                    if (googleMusicSong.Deleted)
                    {
                        toBeDeleted.Add(googleMusicSong.ToSong());
                    }
                    else
                    {
                        Song song = null;
                        if (libraryFreshnessDate.HasValue)
                        {
                            song = await this.songsRepository.FindSongAsync(googleMusicSong.Id);
                        }

                        if (song != null)
                        {
                            GoogleMusicSongEx.Mapper(googleMusicSong, song);
                            toBeUpdated.Add(song);

                            if (!GoogleMusicSongEx.IsVisualMatch(googleMusicSong, song))
                            {
                                updateStatus.SetBreakingChange();
                            }
                            else
                            {
                                updateStatus.SetUpdated();
                            }
                        }
                        else
                        {
                            toBeInserted.Add(googleMusicSong.ToSong());
                        }
                    }
                }

                if (toBeDeleted.Count > 0)
                {
                    if (await this.songsRepository.DeleteAsync(toBeDeleted) > 0)
                    {
                        updateStatus.SetBreakingChange();
                    }
                }

                if (toBeInserted.Count > 0)
                {
                    if (await this.songsRepository.InsertAsync(toBeInserted) > 0)
                    {
                        updateStatus.SetBreakingChange();
                    }
                }

                if (toBeUpdated.Count > 0)
                {
                    await this.songsRepository.UpdateAsync(toBeUpdated);
                }
            });

            await progress.SafeReportAsync(0.8d);

            this.logger.Debug("LoadPlaylistsAsync: loading playlists.");
            await this.playlistsWebService.GetAllAsync(libraryFreshnessDate, chunkHandler : async(chunk) =>
            {
                IList <UserPlaylist> toBeDeleted  = new List <UserPlaylist>();
                IList <UserPlaylist> toBeUpdated  = new List <UserPlaylist>();
                IList <UserPlaylist> toBeInserted = new List <UserPlaylist>();

                foreach (var googleMusicPlaylist in chunk)
                {
                    if (googleMusicPlaylist.Deleted)
                    {
                        toBeDeleted.Add(googleMusicPlaylist.ToUserPlaylist());
                    }
                    else
                    {
                        UserPlaylist currentPlaylist = null;
                        if (libraryFreshnessDate.HasValue)
                        {
                            currentPlaylist = await this.userPlaylistsRepository.GetAsync(googleMusicPlaylist.Id);
                        }

                        if (currentPlaylist != null)
                        {
                            GoogleMusicPlaylistEx.Mapper(googleMusicPlaylist, currentPlaylist);
                            toBeUpdated.Add(currentPlaylist);
                        }
                        else
                        {
                            toBeInserted.Add(googleMusicPlaylist.ToUserPlaylist());
                        }
                    }
                }

                if (toBeDeleted.Count > 0)
                {
                    if (await this.userPlaylistsRepository.DeleteAsync(toBeDeleted) > 0)
                    {
                        updateStatus.SetBreakingChange();
                    }
                }

                if (toBeInserted.Count > 0)
                {
                    if (await this.userPlaylistsRepository.InsertAsync(toBeInserted) > 0)
                    {
                        updateStatus.SetBreakingChange();
                    }
                }

                if (toBeUpdated.Count > 0)
                {
                    await this.userPlaylistsRepository.UpdateAsync(toBeUpdated);
                }
            });

            await progress.SafeReportAsync(0.85d);

            this.logger.Debug("LoadPlaylistsAsync: loading playlist entries.");
            await this.playlistsWebService.GetAllPlaylistEntriesAsync(libraryFreshnessDate, chunkHandler : async(chunk) =>
            {
                IList <UserPlaylistEntry> toBeDeleted  = new List <UserPlaylistEntry>();
                IList <UserPlaylistEntry> toBeUpdated  = new List <UserPlaylistEntry>();
                IList <UserPlaylistEntry> toBeInserted = new List <UserPlaylistEntry>();

                IDictionary <string, Song> songsToInsert = new Dictionary <string, Song>();
                IDictionary <string, Song> songsToUpdate = new Dictionary <string, Song>();

                foreach (var entry in chunk)
                {
                    if (entry.Deleted)
                    {
                        toBeDeleted.Add(entry.ToUserPlaylistEntry());
                    }
                    else
                    {
                        UserPlaylistEntry currentEntry = null;
                        if (libraryFreshnessDate.HasValue)
                        {
                            currentEntry = await this.userPlaylistsRepository.GetEntryAsync(entry.Id);
                        }

                        if (currentEntry != null)
                        {
                            GoogleMusicPlaylistEntryEx.Mapper(entry, currentEntry);
                            toBeUpdated.Add(currentEntry);
                        }
                        else
                        {
                            toBeInserted.Add(entry.ToUserPlaylistEntry());
                        }

                        if (entry.Track != null)
                        {
                            var serverSong   = entry.Track.ToSong();
                            Song currentSong = await this.songsRepository.FindSongAsync(serverSong.SongId);

                            if (currentSong != null)
                            {
                                if (!songsToUpdate.ContainsKey(currentSong.SongId) && libraryFreshnessDate.HasValue)
                                {
                                    GoogleMusicSongEx.Mapper(entry.Track, currentSong);
                                    songsToUpdate.Add(currentSong.SongId, currentSong);
                                }
                            }
                            else
                            {
                                currentSong = serverSong;
                                if (!songsToInsert.ContainsKey(currentSong.SongId))
                                {
                                    currentSong.IsLibrary = false;
                                    songsToInsert.Add(currentSong.SongId, currentSong);
                                }
                            }
                        }
                    }
                }

                if (songsToInsert.Count > 0)
                {
                    await this.songsRepository.InsertAsync(songsToInsert.Values);
                }

                if (songsToUpdate.Count > 0)
                {
                    await this.songsRepository.UpdateAsync(songsToUpdate.Values);
                }

                if (toBeDeleted.Count > 0)
                {
                    if (await this.userPlaylistsRepository.DeleteEntriesAsync(toBeDeleted) > 0)
                    {
                        updateStatus.SetBreakingChange();
                    }
                }

                if (toBeInserted.Count > 0)
                {
                    if (await this.userPlaylistsRepository.InsertEntriesAsync(toBeInserted) > 0)
                    {
                        updateStatus.SetBreakingChange();
                    }
                }

                if (toBeUpdated.Count > 0)
                {
                    await this.userPlaylistsRepository.UpdateEntriesAsync(toBeUpdated);
                }
            });

            await progress.SafeReportAsync(0.95d);

            await this.radioWebService.GetAllAsync(
                libraryFreshnessDate,
                null,
                async (gRadios) =>
            {
                IList <Radio> toBeDeleted  = new List <Radio>();
                IList <Radio> toBeUpdated  = new List <Radio>();
                IList <Radio> toBeInserted = new List <Radio>();

                foreach (var radio in gRadios)
                {
                    if (radio.Deleted)
                    {
                        toBeDeleted.Add(radio.ToRadio());
                    }
                    else
                    {
                        Radio storedRadio = null;
                        if (libraryFreshnessDate.HasValue)
                        {
                            storedRadio = await this.radioStationsRepository.GetAsync(radio.Id);
                        }

                        if (storedRadio != null)
                        {
                            GoogleMusicRadioEx.Mapper(radio, storedRadio);
                            toBeUpdated.Add(storedRadio);
                        }
                        else
                        {
                            toBeInserted.Add(radio.ToRadio());
                        }
                    }
                }

                if (toBeDeleted.Count > 0)
                {
                    if (await this.radioStationsRepository.DeleteAsync(toBeDeleted) > 0)
                    {
                        updateStatus.SetBreakingChange();
                    }
                }

                if (toBeInserted.Count > 0)
                {
                    if (await this.radioStationsRepository.InsertAsync(toBeInserted) > 0)
                    {
                        updateStatus.SetBreakingChange();
                    }
                }

                if (toBeUpdated.Count > 0)
                {
                    await this.radioStationsRepository.UpdateAsync(toBeUpdated);
                }
            });


            await progress.SafeReportAsync(1d);

            this.settingsService.SetLibraryFreshnessDate(currentTime);

            return(updateStatus);
        }
예제 #2
0
        public async Task <SongsUpdateStatus> UpdateSongsAsync()
        {
            int songsUpdated  = 0;
            int songsDeleted  = 0;
            int songsInstered = 0;

            DateTime?libraryFreshnessDate = this.settingsService.GetLibraryFreshnessDate();
            DateTime currentTime          = DateTime.UtcNow;

            if (this.logger.IsDebugEnabled)
            {
                this.logger.Debug("UpdateSongsAsync: streaming load all tracks. Library freshness date {0}.", libraryFreshnessDate);
            }

            var updatedSongs = await this.songsWebService.StreamingLoadAllTracksAsync(libraryFreshnessDate, null);

            if (updatedSongs != null && updatedSongs.Count > 0)
            {
                if (this.logger.IsDebugEnabled)
                {
                    this.logger.Debug("UpdateSongsAsync: got {0} updates.", updatedSongs.Count);
                }

                await this.Connection.RunInTransactionAsync(connection =>
                {
                    foreach (var googleSong in updatedSongs)
                    {
                        var songId     = googleSong.Id;
                        var storedSong = connection.Find <Song>(x => x.ProviderSongId == songId);

                        if (googleSong.Deleted)
                        {
                            if (storedSong != null)
                            {
                                connection.Delete <Song>(storedSong.SongId);
                            }

                            songsDeleted++;
                        }
                        else
                        {
                            if (storedSong != null)
                            {
                                if (!GoogleMusicSongEx.IsVisualMatch(googleSong, storedSong))
                                {
                                    songsUpdated++;
                                }

                                GoogleMusicSongEx.Mapper(googleSong, storedSong);
                                connection.Update(storedSong);
                            }
                            else
                            {
                                connection.Insert(googleSong.ToSong());
                                songsInstered++;
                            }
                        }
                    }
                });
            }
            else
            {
                if (this.logger.IsDebugEnabled)
                {
                    this.logger.Debug("UpdateSongsAsync: no updates.");
                }
            }

            this.settingsService.SetLibraryFreshnessDate(currentTime);

            return(new SongsUpdateStatus(songsInstered, songsUpdated, songsDeleted));
        }