Beispiel #1
0
        /// <summary>
        /// Updates the progress messages and the progressbar.
        /// </summary>
        /// <param name="fileUrl">The URL of the file that just progressed.</param>
        /// <param name="bytesReceived">The received bytes for the specified file.</param>
        private void UpdateProgress(String fileUrl, long bytesReceived)
        {
            DateTime now = DateTime.Now;

            lock (this.filesDownload) {
                // Compute new progress values
                TrackFile currentFile = this.filesDownload.Where(f => f.Url == fileUrl).First();
                currentFile.BytesReceived = bytesReceived;
                long totalReceivedBytes = this.filesDownload.Sum(f => f.BytesReceived);
                long bytesToDownload    = this.filesDownload.Sum(f => f.Size);

                Double bytesPerSecond;
                if (this.lastTotalReceivedBytes == 0)
                {
                    // First time we update the progress
                    bytesPerSecond = 0;
                    this.lastTotalReceivedBytes  = totalReceivedBytes;
                    this.lastDownloadSpeedUpdate = now;
                }
                else if ((now - this.lastDownloadSpeedUpdate).TotalMilliseconds > 500)
                {
                    // Last update of progress happened more than 500 milliseconds ago
                    // We only update the download speed every 500+ milliseconds
                    bytesPerSecond =
                        ((Double)(totalReceivedBytes - this.lastTotalReceivedBytes)) /
                        (now - this.lastDownloadSpeedUpdate).TotalSeconds;
                    this.lastTotalReceivedBytes  = totalReceivedBytes;
                    this.lastDownloadSpeedUpdate = now;

                    // Update UI
                    this.Dispatcher.Invoke(new Action(() => {
                        // Update download speed
                        labelDownloadSpeed.Content = (bytesPerSecond / 1024).ToString("0.0") + " kB/s";
                    }));
                }

                // Update UI
                this.Dispatcher.Invoke(new Action(() => {
                    if (!this.userCancelled)
                    {
                        // Update progress label
                        labelProgress.Content =
                            ((Double)totalReceivedBytes / (1024 * 1024)).ToString("0.00") + " MB / " +
                            ((Double)bytesToDownload / (1024 * 1024)).ToString("0.00") + " MB";
                        // Update progress bar
                        progressBar.Value = totalReceivedBytes;
                        // Taskbar progress is between 0 and 1
                        TaskbarItemInfo.ProgressValue = totalReceivedBytes / progressBar.Maximum;
                    }
                }));
            }
        }
        /// <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);
        }
Beispiel #4
0
        /// <summary>
        /// Downloads the cover art.
        /// </summary>
        /// <param name="album">The album to download.</param>
        /// <param name="downloadsFolder">The downloads folder.</param>
        /// <param name="saveCovertArtInFolder">True to save cover art in the downloads folder; false otherwise.</param>
        /// <param name="convertCoverArtToJpg">True to convert the cover art to jpg; false otherwise.</param>
        /// <param name="resizeCoverArt">True to resize the covert art; false otherwise.</param>
        /// <param name="coverArtMaxSize">The maximum width/height of the cover art when resizing.</param>
        /// <returns></returns>
        private TagLib.Picture DownloadCoverArt(Album album, String downloadsFolder, Boolean saveCovertArtInFolder, Boolean convertCoverArtToJpg, Boolean resizeCoverArt, int coverArtMaxSize)
        {
            // Compute path where to save artwork
            String artworkPath = (saveCovertArtInFolder ? downloadsFolder : Path.GetTempPath()) + "\\" + album.Title.ToAllowedFileName() + Path.GetExtension(album.ArtworkUrl);

            if (artworkPath.Length > 256)
            {
                // Shorten the path (Windows doesn't support a path > 256 characters)
                artworkPath = (saveCovertArtInFolder ? downloadsFolder : Path.GetTempPath()) + "\\" + album.Title.ToAllowedFileName().Substring(0, 3) + Path.GetExtension(album.ArtworkUrl);
            }

            TagLib.Picture artwork = null;

            int     tries             = 0;
            Boolean artworkDownloaded = false;

            do
            {
                var doneEvent = new AutoResetEvent(false);

                using (var webClient = new WebClient()) {
                    if (webClient.Proxy != null)
                    {
                        webClient.Proxy.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
                    }

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

                    // Warn when downloaded
                    webClient.DownloadFileCompleted += (s, e) => {
                        if (!e.Cancelled && e.Error == null)
                        {
                            artworkDownloaded = true;

                            // Convert/resize artwork
                            if (userSettings.ConvertCoverArtToJpg || userSettings.ResizeCoverArt)
                            {
                                var settings = new ResizeSettings();
                                if (convertCoverArtToJpg)
                                {
                                    settings.Format  = "jpg";
                                    settings.Quality = 90;
                                }
                                if (resizeCoverArt)
                                {
                                    settings.MaxHeight = userSettings.CoverArtMaxSize;
                                    settings.MaxWidth  = userSettings.CoverArtMaxSize;
                                }
                                ImageBuilder.Current.Build(artworkPath, artworkPath, settings);
                            }

                            artwork = new TagLib.Picture(artworkPath)
                            {
                                Description = "Picture"
                            };

                            // Delete the cover art file if it was saved in Temp
                            if (!saveCovertArtInFolder)
                            {
                                try {
                                    System.IO.File.Delete(artworkPath);
                                } catch {
                                    // Could not delete the file. Nevermind, it's in Temp/ folder...
                                }
                            }

                            // Note the file as downloaded
                            TrackFile currentFile = this.filesDownload.Where(f => f.Url == album.ArtworkUrl).First();
                            currentFile.Downloaded = true;
                            Log($"Downloaded artwork for album \"{album.Title}\"", LogType.IntermediateSuccess);
                        }
                        else if (!e.Cancelled && e.Error != null)
                        {
                            if (tries < userSettings.DownloadMaxTries)
                            {
                                Log($"Unable to download artwork for album \"{album.Title}\". Try {tries} of {userSettings.DownloadMaxTries}", LogType.Warning);
                            }
                            else
                            {
                                Log($"Unable to download artwork for album \"{album.Title}\". Hit max retries of {userSettings.DownloadMaxTries}", LogType.Error);
                            }
                        } // Else the download has been cancelled (by the user)

                        doneEvent.Set();
                    };

                    lock (this.pendingDownloads) {
                        if (this.userCancelled)
                        {
                            // Abort
                            return(null);
                        }
                        // Register current download
                        this.pendingDownloads.Add(webClient);
                        // Start download
                        webClient.DownloadFileAsync(new Uri(album.ArtworkUrl), artworkPath);
                    }

                    // Wait for download to be finished
                    doneEvent.WaitOne();
                    lock (this.pendingDownloads) {
                        this.pendingDownloads.Remove(webClient);
                    }
                }
            } while (!artworkDownloaded && tries < userSettings.DownloadMaxTries);

            return(artwork);
        }
Beispiel #5
0
        /// <summary>
        /// Downloads and tags a track. Returns true if the track has been correctly downloaded; false otherwise.
        /// </summary>
        /// <param name="albumDirectoryPath">The path where to save the tracks.</param>
        /// <param name="album">The album of the track to download.</param>
        /// <param name="track">The track to download.</param>
        /// <param name="tagTrack">True to tag the track; false otherwise.</param>
        /// <param name="saveCoverArtInTags">True to save the cover art in the tag tracks; false otherwise.</param>
        /// <param name="artwork">The cover art.</param>
        private Boolean DownloadAndTagTrack(String albumDirectoryPath, Album album, Track track, Boolean tagTrack, Boolean saveCoverArtInTags, TagLib.Picture artwork)
        {
            Log($"Downloading track \"{track.Title}\" from url: {track.Mp3Url}", LogType.VerboseInfo);

            // Set location to save the file
            String trackPath = albumDirectoryPath + "\\" + GetFileName(album, track);

            if (trackPath.Length > 256)
            {
                // Shorten the path (Windows doesn't support a path > 256 characters)
                trackPath = albumDirectoryPath + "\\" + GetFileName(album, track).Substring(0, 3) + Path.GetExtension(trackPath);
            }
            int     tries           = 0;
            Boolean trackDownloaded = false;

            if (File.Exists(trackPath))
            {
                long length = new FileInfo(trackPath).Length;
                foreach (TrackFile trackFile in filesDownload)
                {
                    if (track.Mp3Url == trackFile.Url &&
                        trackFile.Size > length - (trackFile.Size * userSettings.AllowableFileSizeDifference) &&
                        trackFile.Size < length + (trackFile.Size * userSettings.AllowableFileSizeDifference))
                    {
                        Log($"Track already exists within allowed filesize range: track \"{GetFileName(album, track)}\" from album \"{album.Title}\" - Skipping download!", LogType.IntermediateSuccess);
                        return(false);
                    }
                }
            }

            do
            {
                var doneEvent = new AutoResetEvent(false);

                using (var webClient = new WebClient()) {
                    if (webClient.Proxy != null)
                    {
                        webClient.Proxy.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
                    }

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

                    // Warn & tag when downloaded
                    webClient.DownloadFileCompleted += (s, e) => {
                        WaitForCooldown(tries);
                        tries++;

                        if (!e.Cancelled && e.Error == null)
                        {
                            trackDownloaded = true;

                            if (tagTrack)
                            {
                                // Tag (ID3) the file when downloaded
                                TagLib.File tagFile = TagLib.File.Create(trackPath);
                                tagFile.Tag.Album        = album.Title;
                                tagFile.Tag.AlbumArtists = new String[1] {
                                    album.Artist
                                };
                                tagFile.Tag.Performers = new String[1] {
                                    album.Artist
                                };
                                tagFile.Tag.Title  = track.Title;
                                tagFile.Tag.Track  = (uint)track.Number;
                                tagFile.Tag.Year   = (uint)album.ReleaseDate.Year;
                                tagFile.Tag.Lyrics = track.Lyrics;
                                tagFile.Save();
                            }

                            if (saveCoverArtInTags && artwork != null)
                            {
                                // Save cover in tags when downloaded
                                TagLib.File tagFile = TagLib.File.Create(trackPath);
                                tagFile.Tag.Pictures = new TagLib.IPicture[1] {
                                    artwork
                                };
                                tagFile.Save();
                            }

                            // Note the file as downloaded
                            TrackFile currentFile = this.filesDownload.Where(f => f.Url == track.Mp3Url).First();
                            currentFile.Downloaded = true;
                            Log($"Downloaded track \"{GetFileName(album, track)}\" from album \"{album.Title}\"", LogType.IntermediateSuccess);
                        }
                        else if (!e.Cancelled && e.Error != null)
                        {
                            if (tries < userSettings.DownloadMaxTries)
                            {
                                Log($"Unable to download track \"{GetFileName(album, track)}\" from album \"{album.Title}\". Try {tries} of {userSettings.DownloadMaxTries}", LogType.Warning);
                            }
                            else
                            {
                                Log($"Unable to download track \"{GetFileName(album, track)}\" from album \"{album.Title}\". Hit max retries of {userSettings.DownloadMaxTries}", LogType.Error);
                            }
                        } // Else the download has been cancelled (by the user)

                        doneEvent.Set();
                    };

                    lock (this.pendingDownloads) {
                        if (this.userCancelled)
                        {
                            // Abort
                            return(false);
                        }
                        // Register current download
                        this.pendingDownloads.Add(webClient);
                        // Start download
                        webClient.DownloadFileAsync(new Uri(track.Mp3Url), trackPath);
                    }
                    // Wait for download to be finished
                    doneEvent.WaitOne();
                    lock (this.pendingDownloads) {
                        this.pendingDownloads.Remove(webClient);
                    }
                }
            } while (!trackDownloaded && tries < userSettings.DownloadMaxTries);

            return(trackDownloaded);
        }