Exemplo n.º 1
0
        private void buttonStart_Click(object sender, RoutedEventArgs e)
        {
            if (textBoxUrls.Text == Constants.UrlsHint)
            {
                // No URL to look
                Log("Paste some albums URLs to be downloaded", LogType.Error);
                return;
            }
            int coverArtMaxSize = 0;

            if (checkBoxResizeCoverArt.IsChecked.Value && !Int32.TryParse(textBoxCoverArtMaxSize.Text, out coverArtMaxSize))
            {
                Log("Cover art max width/height must be an integer", LogType.Error);
                return;
            }

            this.userCancelled = false;

            this.pendingDownloads = new List <WebClient>();

            // Set controls to "downloading..." state
            this.activeDownloads = true;
            UpdateControlsState(true);

            Log("Starting download...", LogType.Info);

            // Get user inputs
            List <String> userUrls = textBoxUrls.Text.Split(new String[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).ToList();

            userUrls = userUrls.Distinct().ToList();

            var urls   = new List <String>();
            var albums = new List <Album>();

            Task.Factory.StartNew(() => {
                // Get URLs of albums to download
                if (userSettings.DownloadArtistDiscography)
                {
                    urls = GetArtistDiscography(userUrls);
                }
                else
                {
                    urls = userUrls;
                }
                urls = urls.Distinct().ToList();
            }).ContinueWith(x => {
                // Get info on albums
                albums = GetAlbums(urls);
            }).ContinueWith(x => {
                // Save files to download (we'll need the list to update the progressBar)
                this.filesDownload = GetFilesToDownload(albums, userSettings.SaveCoverArtInTags || userSettings.SaveCoverArtInFolder);
            }).ContinueWith(x => {
                // Set progressBar max value
                long maxProgressBarValue;
                if (userSettings.RetrieveFilesizes)
                {
                    maxProgressBarValue = this.filesDownload.Sum(f => f.Size); // Bytes to download
                }
                else
                {
                    maxProgressBarValue = this.filesDownload.Count; // Number of files to download
                }
                if (maxProgressBarValue > 0)
                {
                    this.Dispatcher.Invoke(new Action(() => {
                        progressBar.IsIndeterminate   = false;
                        progressBar.Maximum           = maxProgressBarValue;
                        TaskbarItemInfo.ProgressState = TaskbarItemProgressState.Normal;
                    }));
                }
            }).ContinueWith(x => {
                // Start downloading albums
                if (userSettings.DownloadOneAlbumAtATime)
                {
                    // Download one album at a time
                    foreach (Album album in albums)
                    {
                        DownloadAlbum(album, ParseDownloadLocation(userSettings.DownloadsLocation, album), userSettings.TagTracks, userSettings.SaveCoverArtInTags, userSettings.SaveCoverArtInFolder, userSettings.ConvertCoverArtToJpg, userSettings.ResizeCoverArt, userSettings.CoverArtMaxSize);
                    }
                }
                else
                {
                    // Parallel download
                    Task[] tasks = new Task[albums.Count];
                    for (int i = 0; i < albums.Count; i++)
                    {
                        Album album = albums[i]; // Mandatory or else => race condition
                        tasks[i]    = Task.Factory.StartNew(() =>
                                                            DownloadAlbum(album, ParseDownloadLocation(userSettings.DownloadsLocation, album), userSettings.TagTracks, userSettings.SaveCoverArtInTags, userSettings.SaveCoverArtInFolder, userSettings.ConvertCoverArtToJpg, userSettings.ResizeCoverArt, userSettings.CoverArtMaxSize));
                    }
                    // Wait for all albums to be downloaded
                    Task.WaitAll(tasks);
                }
            }).ContinueWith(x => {
                if (this.userCancelled)
                {
                    // Display message if user cancelled
                    Log("Downloads cancelled by user", LogType.Info);
                }
                // Set controls to "ready" state
                this.activeDownloads = false;
                UpdateControlsState(false);
                // Play a sound
                try {
                    (new SoundPlayer(@"C:\Windows\Media\Windows Ding.wav")).Play();
                } catch {
                }
            });
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
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);
        }
        /// <summary>
        /// Downloads an album.
        /// </summary>
        /// <param name="album">The album to download.</param>
        /// <param name="downloadsFolder">The downloads folder.</param>
        /// <param name="tagTracks">True to tag tracks; false otherwise.</param>
        /// <param name="saveCoverArtInTags">True to save cover art in tags; false otherwise.</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>
        private void DownloadAlbum(Album album, String downloadsFolder, Boolean tagTracks, Boolean saveCoverArtInTags,
            Boolean saveCovertArtInFolder, Boolean convertCoverArtToJpg, Boolean resizeCoverArt, int coverArtMaxSize) {
            if (this.userCancelled) {
                // Abort
                return;
            }

            // Create directory to place track files
            String directoryPath = downloadsFolder + "\\" + album.Title.ToAllowedFileName() + "\\";
            try {
                Directory.CreateDirectory(directoryPath);
            } catch {
                Log("An error occured when creating the album folder. Make sure you have the rights to write files in the folder you chose",
                    LogType.Error);
                return;
            }

            TagLib.Picture artwork = null;

            // Download artwork
            if (saveCoverArtInTags || saveCovertArtInFolder) {
                artwork = DownloadCoverArt(album, downloadsFolder, saveCovertArtInFolder, convertCoverArtToJpg, resizeCoverArt,
                    coverArtMaxSize);
            }

            // Download & tag tracks
            Task[] tasks = new Task[album.Tracks.Count];
            Boolean[] tracksDownloaded = new Boolean[album.Tracks.Count];
            for (int i = 0; i < album.Tracks.Count; i++) {
                // Temporarily save the index or we will have a race condition exception when i hits its maximum value
                int currentIndex = i;
                tasks[currentIndex] = Task.Factory.StartNew(() => tracksDownloaded[currentIndex] =
                    DownloadAndTagTrack(directoryPath, album, album.Tracks[currentIndex], tagTracks, saveCoverArtInTags, artwork));
            }

            // Wait for all tracks to be downloaded before saying the album is downloaded
            Task.WaitAll(tasks);

            if (!this.userCancelled) {
                // Tasks have not been aborted
                if (tracksDownloaded.All(x => x == true)) {
                    Log("Successfully downloaded album \"" + album.Title + "\"", LogType.Success);
                } else {
                    Log("Finished downloading album \"" + album.Title + "\". Some tracks could not be downloaded", LogType.Success);
                }
            }
        }
        /// <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 + "\\" + album.Title.ToAllowedFileName() :
                Path.GetTempPath() ) + "\\" + album.Title.ToAllowedFileName() + 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()) {
                    // 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 (convertCoverArtToJpg || resizeCoverArt) {
                                var settings = new ResizeSettings();
                                if (convertCoverArtToJpg) {
                                    settings.Format = "jpg";
                                    settings.Quality = 90;
                                }
                                if (resizeCoverArt) {
                                    settings.MaxHeight = coverArtMaxSize;
                                    settings.MaxWidth = 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...
                                }
                            }

                            Log("Downloaded artwork for album \"" + album.Title + "\"", LogType.IntermediateSuccess);
                        } else if (!e.Cancelled && e.Error != null) {
                            if (tries < Constants.DownloadMaxTries) {
                                Log("Unable to download artwork for album \"" + album.Title + "\". " + "Try " + tries + " of " +
                                    Constants.DownloadMaxTries, LogType.Warning);
                            } else {
                                Log("Unable to download artwork for album \"" + album.Title + "\". " + "Hit max retries of " +
                                    Constants.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 < Constants.DownloadMaxTries);

            return artwork;
        }
        /// <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 + track.GetFileName(album.Artist);

            int tries = 0;
            Boolean trackDownloaded = false;

            do {
                var doneEvent = new AutoResetEvent(false);

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

                    // Warn & tag when downloaded
                    webClient.DownloadFileCompleted += (s, e) => {
                        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.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();
                            }

                            Log("Downloaded track \"" + track.GetFileName(album.Artist) + "\" from album \"" + album.Title + "\"",
                                LogType.IntermediateSuccess);
                        } else if (!e.Cancelled && e.Error != null) {
                            if (tries < Constants.DownloadMaxTries) {
                                Log("Unable to download track \"" + track.GetFileName(album.Artist) + "\" from album \"" + album.Title +
                                    "\". " + "Try " + tries + " of " + Constants.DownloadMaxTries, LogType.Warning);
                            } else {
                                Log("Unable to download track \"" + track.GetFileName(album.Artist) + "\" from album \"" + album.Title +
                                    "\". " + "Hit max retries of " + Constants.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 < Constants.DownloadMaxTries);

            return trackDownloaded;
        }