/// <summary>
        /// Returns the albums located at the specified URLs.
        /// </summary>
        /// <param name="urls">The URLs.</param>
        private async Task <List <Album> > GetAlbumsAsync(List <string> urls)
        {
            var albums = new List <Album>();

            foreach (string url in urls)
            {
                LogAdded(this, new LogArgs($"Retrieving album data for {url}", LogType.Info));

                // Retrieve URL HTML source code
                string htmlCode = "";
                using (var webClient = new WebClient()
                {
                    Encoding = Encoding.UTF8
                }) {
                    ProxyHelper.SetProxy(webClient);

                    if (_cancelDownloads)
                    {
                        // Abort
                        return(new List <Album>());
                    }

                    try {
                        htmlCode = await webClient.DownloadStringTaskAsync(url);
                    } catch {
                        LogAdded(this, new LogArgs($"Could not retrieve data for {url}", LogType.Error));
                        continue;
                    }
                }

                // Get info on album
                try {
                    Album album = BandcampHelper.GetAlbum(htmlCode);

                    if (album.Tracks.Count > 0)
                    {
                        albums.Add(album);
                    }
                    else
                    {
                        LogAdded(this, new LogArgs($"No tracks found for {url}, album will not be downloaded", LogType.Warning));
                    }
                } catch {
                    LogAdded(this, new LogArgs($"Could not retrieve album info for {url}", LogType.Error));
                    continue;
                }
            }

            return(albums);
        }
        /// <summary>
        /// Downloads the changelog file and returns its content.
        /// </summary>
        private async Task <string> DownloadChangelogAsync()
        {
            string changelog;

            using (var webClient = new WebClient()
            {
                Encoding = Encoding.UTF8
            }) {
                ProxyHelper.SetProxy(webClient);
                changelog = await webClient.DownloadStringTaskAsync(Constants.UrlChangelog);
            }

            return(changelog);
        }
Beispiel #3
0
        private async void ButtonDownloadUpdate_Click(object sender, RoutedEventArgs e)
        {
            string[] parts           = Constants.UrlReleaseZip.Split(new char[] { '/' });
            string   defaultFileName = parts[parts.Length - 1];

            var dialog = new SaveFileDialog {
                FileName = defaultFileName,
                Filter   = "Archive|*.zip",
                Title    = Properties.Resources.saveFileDialogTitle,
            };

            if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }

            string path   = dialog.FileName;
            string zipUrl = string.Format(Constants.UrlReleaseZip, _latestVersion.ToString());

            using (var webClient = new WebClient()) {
                ProxyHelper.SetProxy(webClient);
                await webClient.DownloadFileTaskAsync(zipUrl, path);
            }
        }
        /// <summary>
        /// Returns the artists discography from any URL (artist, album, track).
        /// </summary>
        /// <param name="urls">The URLs.</param>
        private async Task <List <string> > GetArtistDiscographyAsync(List <string> urls)
        {
            var albumsUrls = new List <string>();

            foreach (string url in urls)
            {
                LogAdded(this, new LogArgs($"Retrieving artist discography from {url}", LogType.Info));

                // Retrieve URL HTML source code
                string htmlCode = "";
                using (var webClient = new WebClient()
                {
                    Encoding = Encoding.UTF8
                }) {
                    ProxyHelper.SetProxy(webClient);

                    if (_cancelDownloads)
                    {
                        // Abort
                        return(new List <string>());
                    }

                    try {
                        htmlCode = await webClient.DownloadStringTaskAsync(url);
                    } catch {
                        LogAdded(this, new LogArgs($"Could not retrieve data for {url}", LogType.Error));
                        continue;
                    }
                }

                // Get artist "music" bandcamp page (http://artist.bandcamp.com/music)
                var regex = new Regex("band_url = \"(?<url>.*)\"");
                if (!regex.IsMatch(htmlCode))
                {
                    LogAdded(this, new LogArgs($"No discography could be found on {url}. Try to uncheck the \"Download artist discography\" option", LogType.Error));
                    continue;
                }
                string artistMusicPage = regex.Match(htmlCode).Groups["url"].Value + "/music";

                // Retrieve artist "music" page HTML source code
                using (var webClient = new WebClient()
                {
                    Encoding = Encoding.UTF8
                }) {
                    ProxyHelper.SetProxy(webClient);

                    if (_cancelDownloads)
                    {
                        // Abort
                        return(new List <string>());
                    }

                    try {
                        htmlCode = await webClient.DownloadStringTaskAsync(artistMusicPage);
                    } catch {
                        LogAdded(this, new LogArgs($"Could not retrieve data for {artistMusicPage}", LogType.Error));
                        continue;
                    }
                }

                // Get albums referred on the page
                regex = new Regex("TralbumData.*\n.*url:.*'/music'\n");
                if (!regex.IsMatch(htmlCode))
                {
                    // This seem to be a one-album artist with no "music" page => URL redirects to the unique album URL
                    albumsUrls.Add(url);
                }
                else
                {
                    // We are on a real "music" page
                    try {
                        albumsUrls.AddRange(BandcampHelper.GetAlbumsUrl(htmlCode));
                    } catch (NoAlbumFoundException) {
                        LogAdded(this, new LogArgs($"No referred album could be found on {artistMusicPage}. Try to uncheck the \"Download artist discography\" option", LogType.Error));
                        continue;
                    }
                }
            }

            return(albumsUrls.Distinct().ToList());
        }
        /// <summary>
        /// Downloads and returns the cover art of the specified album. Depending on UserSettings, save the cover art in
        /// the album folder.
        /// </summary>
        /// <param name="album">The album.</param>
        private async Task <TagLib.Picture> DownloadCoverArtAsync(Album album)
        {
            TagLib.Picture artworkInTags = null;

            int       tries             = 0;
            bool      artworkDownloaded = false;
            TrackFile currentFile       = DownloadingFiles.Where(f => f.Url == album.ArtworkUrl).First();

            do
            {
                if (_cancelDownloads)
                {
                    // Abort
                    return(null);
                }

                using (var webClient = new WebClient()) {
                    ProxyHelper.SetProxy(webClient);

                    // Update progress bar when downloading
                    webClient.DownloadProgressChanged += (s, e) => {
                        currentFile.BytesReceived = e.BytesReceived;
                    };

                    // Register current download
                    _cancellationTokenSource.Token.Register(webClient.CancelAsync);

                    // Start download
                    try {
                        await webClient.DownloadFileTaskAsync(album.ArtworkUrl, album.ArtworkTempPath);

                        artworkDownloaded = true;
                    } catch (WebException ex) when(ex.Status == WebExceptionStatus.RequestCanceled)
                    {
                        // Downloads cancelled by the user
                        return(null);
                    } catch (TaskCanceledException) {
                        // Downloads cancelled by the user
                        return(null);
                    } catch (WebException) {
                        // Connection closed probably because no response from Bandcamp
                        if (tries < App.UserSettings.DownloadMaxTries)
                        {
                            LogAdded(this, new LogArgs($"Unable to download artwork for album \"{album.Title}\". Try {tries + 1} of {App.UserSettings.DownloadMaxTries}", LogType.Warning));
                        }
                        else
                        {
                            LogAdded(this, new LogArgs($"Unable to download artwork for album \"{album.Title}\". Hit max retries of {App.UserSettings.DownloadMaxTries}", LogType.Error));
                        }
                    }

                    if (artworkDownloaded)
                    {
                        // Convert/resize artwork to be saved in album folder
                        if (App.UserSettings.SaveCoverArtInFolder && (App.UserSettings.CoverArtInFolderConvertToJpg || App.UserSettings.CoverArtInFolderResize))
                        {
                            var settings = new ResizeSettings();
                            if (App.UserSettings.CoverArtInFolderConvertToJpg)
                            {
                                settings.Format  = "jpg";
                                settings.Quality = 90;
                            }
                            if (App.UserSettings.CoverArtInFolderResize)
                            {
                                settings.MaxHeight = App.UserSettings.CoverArtInFolderMaxSize;
                                settings.MaxWidth  = App.UserSettings.CoverArtInFolderMaxSize;
                            }

                            await Task.Run(() => {
                                ImageBuilder.Current.Build(album.ArtworkTempPath, album.ArtworkPath, settings); // Save it to the album folder
                            });
                        }
                        else if (App.UserSettings.SaveCoverArtInFolder)
                        {
                            await FileHelper.CopyFileAsync(album.ArtworkTempPath, album.ArtworkPath);
                        }

                        // Convert/resize artwork to be saved in tags
                        if (App.UserSettings.SaveCoverArtInTags && (App.UserSettings.CoverArtInTagsConvertToJpg || App.UserSettings.CoverArtInTagsResize))
                        {
                            var settings = new ResizeSettings();
                            if (App.UserSettings.CoverArtInTagsConvertToJpg)
                            {
                                settings.Format  = "jpg";
                                settings.Quality = 90;
                            }
                            if (App.UserSettings.CoverArtInTagsResize)
                            {
                                settings.MaxHeight = App.UserSettings.CoverArtInTagsMaxSize;
                                settings.MaxWidth  = App.UserSettings.CoverArtInTagsMaxSize;
                            }

                            await Task.Run(() => {
                                ImageBuilder.Current.Build(album.ArtworkTempPath, album.ArtworkTempPath, settings); // Save it to %Temp%
                            });
                        }
                        artworkInTags = new TagLib.Picture(album.ArtworkTempPath)
                        {
                            Description = "Picture"
                        };

                        try {
                            File.Delete(album.ArtworkTempPath);
                        } catch {
                            // Could not delete the file. Nevermind, it's in %Temp% folder...
                        }

                        // Note the file as downloaded
                        currentFile.Downloaded = true;
                        LogAdded(this, new LogArgs($"Downloaded artwork for album \"{album.Title}\"", LogType.IntermediateSuccess));
                    }

                    tries++;
                    if (!artworkDownloaded && tries < App.UserSettings.DownloadMaxTries)
                    {
                        await WaitForCooldownAsync(tries);
                    }
                }
            } while (!artworkDownloaded && tries < App.UserSettings.DownloadMaxTries);

            return(artworkInTags);
        }
        /// <summary>
        /// Downloads and tags a track. Returns true if the track has been correctly downloaded; false otherwise.
        /// </summary>
        /// <param name="album">The album of the track to download.</param>
        /// <param name="track">The track to download.</param>
        /// <param name="artwork">The cover art.</param>
        private async Task <bool> DownloadAndTagTrackAsync(Album album, Track track, TagLib.Picture artwork)
        {
            LogAdded(this, new LogArgs($"Downloading track \"{track.Title}\" from url: {track.Mp3Url}", LogType.VerboseInfo));

            int       tries           = 0;
            bool      trackDownloaded = false;
            TrackFile currentFile     = DownloadingFiles.Where(f => f.Url == track.Mp3Url).First();

            if (File.Exists(track.Path))
            {
                long length = new FileInfo(track.Path).Length;
                if (currentFile.Size > length - (currentFile.Size * App.UserSettings.AllowedFileSizeDifference) &&
                    currentFile.Size < length + (currentFile.Size * App.UserSettings.AllowedFileSizeDifference))
                {
                    LogAdded(this, new LogArgs($"Track already exists within allowed file size range: track \"{Path.GetFileName(track.Path)}\" from album \"{album.Title}\" - Skipping download!", LogType.IntermediateSuccess));
                    return(false);
                }
            }

            do
            {
                if (_cancelDownloads)
                {
                    // Abort
                    return(false);
                }

                using (var webClient = new WebClient()) {
                    ProxyHelper.SetProxy(webClient);

                    // Update progress bar when downloading
                    webClient.DownloadProgressChanged += (s, e) => {
                        currentFile.BytesReceived = e.BytesReceived;
                    };

                    // Register current download
                    _cancellationTokenSource.Token.Register(webClient.CancelAsync);

                    // Start download
                    try {
                        await webClient.DownloadFileTaskAsync(track.Mp3Url, track.Path);

                        trackDownloaded = true;
                        LogAdded(this, new LogArgs($"Downloaded track \"{track.Title}\" from url: {track.Mp3Url}", LogType.VerboseInfo));
                    } catch (WebException ex) when(ex.Status == WebExceptionStatus.RequestCanceled)
                    {
                        // Downloads cancelled by the user
                        return(false);
                    } catch (TaskCanceledException) {
                        // Downloads cancelled by the user
                        return(false);
                    } catch (WebException) {
                        // Connection closed probably because no response from Bandcamp
                        if (tries + 1 < App.UserSettings.DownloadMaxTries)
                        {
                            LogAdded(this, new LogArgs($"Unable to download track \"{Path.GetFileName(track.Path)}\" from album \"{album.Title}\". Try {tries + 1} of {App.UserSettings.DownloadMaxTries}", LogType.Warning));
                        }
                        else
                        {
                            LogAdded(this, new LogArgs($"Unable to download track \"{Path.GetFileName(track.Path)}\" from album \"{album.Title}\". Hit max retries of {App.UserSettings.DownloadMaxTries}", LogType.Error));
                        }
                    }

                    if (trackDownloaded)
                    {
                        if (App.UserSettings.ModifyTags)
                        {
                            // Tag (ID3) the file when downloaded
                            var tagFile = TagLib.File.Create(track.Path);
                            tagFile = TagHelper.UpdateArtist(tagFile, album.Artist, App.UserSettings.TagArtist);
                            tagFile = TagHelper.UpdateAlbumArtist(tagFile, album.Artist, App.UserSettings.TagAlbumArtist);
                            tagFile = TagHelper.UpdateAlbumTitle(tagFile, album.Title, App.UserSettings.TagAlbumTitle);
                            tagFile = TagHelper.UpdateAlbumYear(tagFile, (uint)album.ReleaseDate.Year, App.UserSettings.TagYear);
                            tagFile = TagHelper.UpdateTrackNumber(tagFile, (uint)track.Number, App.UserSettings.TagTrackNumber);
                            tagFile = TagHelper.UpdateTrackTitle(tagFile, track.Title, App.UserSettings.TagTrackTitle);
                            tagFile = TagHelper.UpdateTrackLyrics(tagFile, track.Lyrics, App.UserSettings.TagLyrics);
                            tagFile = TagHelper.UpdateComments(tagFile, App.UserSettings.TagComments);
                            tagFile.Save();
                            LogAdded(this, new LogArgs($"Tags saved for track \"{Path.GetFileName(track.Path)}\" from album \"{album.Title}\"", LogType.VerboseInfo));
                        }

                        if (App.UserSettings.SaveCoverArtInTags && artwork != null)
                        {
                            // Save cover in tags when downloaded
                            var tagFile = TagLib.File.Create(track.Path);
                            tagFile.Tag.Pictures = new TagLib.IPicture[1] {
                                artwork
                            };
                            tagFile.Save();
                            LogAdded(this, new LogArgs($"Cover art saved in tags for track \"{Path.GetFileName(track.Path)}\" from album \"{album.Title}\"", LogType.VerboseInfo));
                        }

                        // Note the file as downloaded
                        currentFile.Downloaded = true;
                        LogAdded(this, new LogArgs($"Downloaded track \"{Path.GetFileName(track.Path)}\" from album \"{album.Title}\"", LogType.IntermediateSuccess));
                    }

                    tries++;
                    if (!trackDownloaded && tries < App.UserSettings.DownloadMaxTries)
                    {
                        await WaitForCooldownAsync(tries);
                    }
                }
            } while (!trackDownloaded && tries < App.UserSettings.DownloadMaxTries);

            return(trackDownloaded);
        }
        /// <summary>
        /// Returns the artists discography from any URL (artist, album, track).
        /// </summary>
        /// <param name="urls">The URLs.</param>
        private async Task <List <string> > GetArtistDiscographyAsync(List <string> urls)
        {
            var albumsUrls = new List <string>();

            foreach (string url in urls)
            {
                LogAdded(this, new LogArgs($"Retrieving artist discography from {url}", LogType.Info));

                // Retrieve URL HTML source code
                string htmlCode = "";
                using (var webClient = new WebClient()
                {
                    Encoding = Encoding.UTF8
                }) {
                    ProxyHelper.SetProxy(webClient);

                    if (_cancelDownloads)
                    {
                        // Abort
                        return(new List <string>());
                    }

                    try {
                        htmlCode = await webClient.DownloadStringTaskAsync(url);
                    } catch {
                        LogAdded(this, new LogArgs($"Could not retrieve data for {url}", LogType.Error));
                        continue;
                    }
                }

                // Get artist "music" bandcamp page (http://artist.bandcamp.com/music)

                var    regex           = new Regex("https?://[^/]*");
                string artistPage      = regex.Match(url).ToString();
                string artistMusicPage = artistPage + "/music";

                // Retrieve artist "music" page HTML source code
                using (var webClient = new WebClient()
                {
                    Encoding = Encoding.UTF8
                }) {
                    ProxyHelper.SetProxy(webClient);

                    if (_cancelDownloads)
                    {
                        // Abort
                        return(new List <string>());
                    }

                    try {
                        htmlCode = await webClient.DownloadStringTaskAsync(artistMusicPage);
                    } catch {
                        LogAdded(this, new LogArgs($"Could not retrieve data for {artistMusicPage}", LogType.Error));
                        continue;
                    }
                }

                int count = albumsUrls.Count;
                try {
                    albumsUrls.AddRange(BandcampHelper.GetAlbumsUrl(htmlCode, artistPage));
                } catch (NoAlbumFoundException) {
                    LogAdded(this, new LogArgs($"No referred album could be found on {artistMusicPage}. Try to uncheck the \"Download artist discography\" option", LogType.Error));
                }
                if (albumsUrls.Count - count == 0)
                {
                    // This seem to be a one-album artist with no "music" page => URL redirects to the unique album URL
                    albumsUrls.Add(url);
                }
            }

            return(albumsUrls.Distinct().ToList());
        }