示例#1
0
        private async Task LoadPlaylistsAsync(IProgress <double> progress)
        {
            await progress.SafeReportAsync(0.0d);

            this.logger.Debug("LoadPlaylistsAsync: loading playlists.");
            var playlists = await this.playlistsWebService.GetAllAsync();

            await progress.SafeReportAsync(0.6d);

            this.logger.Debug("LoadPlaylistsAsync: inserting playlists into database.");
            if (playlists.Playlists != null)
            {
                var entries = new List <UserPlaylistEntry>();

                foreach (var googleUserPlaylist in playlists.Playlists)
                {
                    var userPlaylist = new UserPlaylist
                    {
                        ProviderPlaylistId = googleUserPlaylist.PlaylistId,
                        Title     = googleUserPlaylist.Title,
                        TitleNorm = googleUserPlaylist.Title.Normalize()
                    };

                    await this.userPlaylistsRepository.InsertAsync(userPlaylist);

                    if (googleUserPlaylist.Playlist != null)
                    {
                        for (int index = 0; index < googleUserPlaylist.Playlist.Count; index++)
                        {
                            GoogleMusicSong googleSong = googleUserPlaylist.Playlist[index];

                            Song song;
                            if (!this.songEntities.TryGetValue(googleSong.Id, out song))
                            {
                                song           = googleSong.ToSong();
                                song.IsLibrary = false;
                                await this.songsRepository.InsertAsync(new[] { song });

                                this.songEntities.Add(googleSong.Id, song);
                            }

                            var entry = new UserPlaylistEntry
                            {
                                ProviderEntryId = googleSong.PlaylistEntryId,
                                PlaylistOrder   = index,
                                SongId          = song.SongId,
                                PlaylistId      = userPlaylist.PlaylistId
                            };

                            entries.Add(entry);
                        }
                    }
                }

                await this.userPlaylistsRepository.InsertEntriesAsync(entries);
            }

            await progress.SafeReportAsync(1.0d);
        }
        public static UserPlaylistEntry ToUserPlaylistEntry(this GoogleMusicPlaylistEntry googleMusicPlaylistEntry)
        {
            var entry = new UserPlaylistEntry();

            Mapper(googleMusicPlaylistEntry, entry);

            return(entry);
        }
 public static void Mapper(GoogleMusicPlaylistEntry googleMusicPlaylistEntry, UserPlaylistEntry entry)
 {
     entry.Id            = googleMusicPlaylistEntry.Id;
     entry.PlaylistOrder = googleMusicPlaylistEntry.AbsolutePosition;
     entry.SongId        = googleMusicPlaylistEntry.TrackId;
     entry.PlaylistId    = googleMusicPlaylistEntry.PlaylistId;
     entry.CreationDate  = DateTimeExtensions.FromUnixFileTime(googleMusicPlaylistEntry.CreationTimestamp / 1000);
     entry.LastModified  =
         DateTimeExtensions.FromUnixFileTime(googleMusicPlaylistEntry.LastModifiedTimestamp / 1000);
     entry.CliendId = googleMusicPlaylistEntry.ClientId;
     entry.Source   = googleMusicPlaylistEntry.Source;
 }
示例#4
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);
        }
示例#5
0
        private async Task <UserPlaylistsUpdateStatus> UpdateUserPlaylistsInternalAsync(IEnumerable <UserPlaylist> userPlaylists, IEnumerable <GoogleMusicPlaylist> googleMusicPlaylists)
        {
            var existingPlaylists = userPlaylists.ToList();

            int updatedPlaylists = 0;
            int newPlaylists     = 0;

            foreach (var googlePlaylist in googleMusicPlaylists)
            {
                bool playlistUpdated = false;

                var providerPlaylistId = googlePlaylist.PlaylistId;

                var userPlaylist = existingPlaylists.FirstOrDefault(x => string.Equals(x.ProviderPlaylistId, providerPlaylistId, StringComparison.OrdinalIgnoreCase));
                if (userPlaylist != null)
                {
                    if (!string.Equals(userPlaylist.Title, googlePlaylist.Title, StringComparison.CurrentCulture))
                    {
                        if (this.logger.IsDebugEnabled)
                        {
                            this.logger.Debug(
                                "UpdateUserPlaylistsAsync: title was changed from {0} to {1} (id - {2}).",
                                userPlaylist.Title,
                                googlePlaylist.Title,
                                providerPlaylistId);
                        }

                        userPlaylist.Title     = googlePlaylist.Title;
                        userPlaylist.TitleNorm = googlePlaylist.Title.Normalize();
                        playlistUpdated        = true;

                        await this.userPlaylistsRepository.UpdateAsync(userPlaylist);
                    }

                    existingPlaylists.Remove(userPlaylist);
                }
                else
                {
                    if (this.logger.IsDebugEnabled)
                    {
                        this.logger.Debug(
                            "UpdateUserPlaylistsAsync: new playlist {0} (id - {1}).",
                            googlePlaylist.Title,
                            providerPlaylistId);
                    }

                    userPlaylist = new UserPlaylist
                    {
                        ProviderPlaylistId = providerPlaylistId,
                        Title     = googlePlaylist.Title,
                        TitleNorm = googlePlaylist.Title.Normalize()
                    };

                    await this.userPlaylistsRepository.InsertAsync(userPlaylist);

                    newPlaylists++;
                }

                var userPlaylistSongs = await this.userPlaylistsRepository.GetSongsAsync(userPlaylist.Id, includeAll : true);

                List <UserPlaylistEntry> newEntries     = new List <UserPlaylistEntry>();
                List <UserPlaylistEntry> updatedEntries = new List <UserPlaylistEntry>();

                if (googlePlaylist.Playlist != null)
                {
                    for (int songIndex = 0; songIndex < googlePlaylist.Playlist.Count; songIndex++)
                    {
                        var song       = googlePlaylist.Playlist[songIndex];
                        var storedSong = userPlaylistSongs.FirstOrDefault(s =>
                                                                          string.Equals(s.ProviderSongId, song.Id, StringComparison.OrdinalIgnoreCase) &&
                                                                          string.Equals(s.UserPlaylistEntry.ProviderEntryId, song.PlaylistEntryId, StringComparison.OrdinalIgnoreCase));

                        if (storedSong != null)
                        {
                            if (storedSong.UserPlaylistEntry.PlaylistOrder != songIndex)
                            {
                                if (this.logger.IsDebugEnabled)
                                {
                                    this.logger.Debug(
                                        "UpdateUserPlaylistsAsync: order was changed for entry id {0} (playlist id - {1}).",
                                        storedSong.UserPlaylistEntry.ProviderEntryId,
                                        providerPlaylistId);
                                }

                                storedSong.UserPlaylistEntry.PlaylistOrder = songIndex;
                                updatedEntries.Add(storedSong.UserPlaylistEntry);
                                playlistUpdated = true;
                            }

                            userPlaylistSongs.Remove(storedSong);
                        }
                        else
                        {
                            storedSong = await this.Connection.FindAsync <Song>(x => x.ProviderSongId == song.Id);

                            if (storedSong == null)
                            {
                                storedSong           = song.ToSong();
                                storedSong.IsLibrary = false;
                                await this.Connection.InsertAsync(storedSong);
                            }

                            playlistUpdated = true;
                            var entry = new UserPlaylistEntry
                            {
                                PlaylistOrder   = songIndex,
                                SongId          = storedSong.SongId,
                                ProviderEntryId = song.PlaylistEntryId,
                                PlaylistId      = userPlaylist.PlaylistId
                            };

                            newEntries.Add(entry);
                        }
                    }
                }

                if (playlistUpdated)
                {
                    updatedPlaylists++;
                }

                if (newEntries.Count > 0)
                {
                    await this.userPlaylistsRepository.InsertEntriesAsync(newEntries);
                }

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

                if (userPlaylistSongs.Count > 0)
                {
                    await this.userPlaylistsRepository.DeleteEntriesAsync(userPlaylistSongs.Select(entry => entry.UserPlaylistEntry));
                }
            }

            foreach (var existingPlaylist in existingPlaylists)
            {
                await this.userPlaylistsRepository.DeleteAsync(existingPlaylist);
            }

            return(new UserPlaylistsUpdateStatus(newPlaylists, updatedPlaylists, existingPlaylists.Count));
        }