private void DownloadModule(Net.DownloadTarget target) { if (shouldQueue(target)) { // Throttled host already downloading, we will get back to this later queuedDownloads.Add(target); } else { // We need a new variable for our closure/lambda, hence index = 1+prev max int index = downloads.Count; var dl = new NetAsyncDownloaderDownloadPart(target); downloads.Add(dl); // Encode spaces to avoid confusing URL parsers User.RaiseMessage("Downloading \"{0}\"", dl.target.url.ToString().Replace(" ", "%20")); // Schedule for us to get back progress reports. dl.Progress += (sender, args) => FileProgressReport(index, args.ProgressPercentage, args.BytesReceived, args.TotalBytesToReceive); // And schedule a notification if we're done (or if something goes wrong) dl.Done += (sender, args) => FileDownloadComplete(index, args.Error); // Start the download! dl.Download(dl.target.url, dl.path); } }
/// <summary> /// Generates a download progress report. /// </summary> /// <param name="index">Index of the file being downloaded</param> /// <param name="percent">The percent complete</param> /// <param name="bytesDownloaded">The bytes downloaded</param> /// <param name="bytesToDownload">The total amount of bytes we expect to download</param> private void FileProgressReport(int index, int percent, long bytesDownloaded, long bytesToDownload) { if (download_canceled) { return; } NetAsyncDownloaderDownloadPart download = downloads[index]; DateTime now = DateTime.Now; TimeSpan timeSpan = now - download.lastProgressUpdateTime; if (timeSpan.Seconds >= 3.0) { long bytesChange = bytesDownloaded - download.lastProgressUpdateSize; download.lastProgressUpdateSize = (int)bytesDownloaded; download.lastProgressUpdateTime = now; download.bytesPerSecond = (int)bytesChange / timeSpan.Seconds; } download.size = bytesToDownload; download.bytesLeft = download.size - bytesDownloaded; if (Progress != null) { Progress(download.target, download.bytesLeft, download.size); } int totalBytesPerSecond = 0; long totalBytesLeft = 0; long totalSize = 0; foreach (NetAsyncDownloaderDownloadPart t in downloads.ToList()) { if (t.bytesLeft > 0) { totalBytesPerSecond += t.bytesPerSecond; } totalBytesLeft += t.bytesLeft; totalSize += t.size; } foreach (Net.DownloadTarget t in queuedDownloads.ToList()) { totalBytesLeft += t.size; totalSize += t.size; } int totalPercentage = (int)(((totalSize - totalBytesLeft) * 100) / (totalSize)); if (!download_canceled) { // Math.Ceiling was added to avoid showing 0 MiB left when finishing User.RaiseProgress( String.Format("{0}/sec - downloading - {1} left", CkanModule.FmtSize(totalBytesPerSecond), CkanModule.FmtSize(totalBytesLeft)), totalPercentage); } }
/// <summary> /// Generates a download progress reports, and sends it to /// onProgressReport if it's set. /// </summary> private void FileProgressReport(int index, int percent, long bytesDownloaded, long bytesLeft) { if (downloadCanceled) { return; } NetAsyncDownloaderDownloadPart download = downloads[index]; DateTime now = DateTime.Now; TimeSpan timeSpan = now - download.lastProgressUpdateTime; if (timeSpan.Seconds >= 3.0) { long bytesChange = bytesDownloaded - download.lastProgressUpdateSize; download.lastProgressUpdateSize = (int)bytesDownloaded; download.lastProgressUpdateTime = now; download.bytesPerSecond = (int)bytesChange / timeSpan.Seconds; } download.bytesLeft = bytesLeft; download.bytesDownloaded = bytesDownloaded; downloads[index] = download; int totalPercentage = 0; int totalBytesPerSecond = 0; long totalBytesLeft = 0; long totalBytesDownloaded = 0; foreach (NetAsyncDownloaderDownloadPart t in downloads.ToList()) { if (t.bytesLeft > 0) { totalBytesPerSecond += t.bytesPerSecond; } totalBytesLeft += t.bytesLeft; totalBytesDownloaded += t.bytesDownloaded; totalBytesLeft += t.bytesLeft; } totalPercentage = (int)((totalBytesDownloaded * 100) / (totalBytesLeft + totalBytesDownloaded + 1)); if (!downloadCanceled) { User.RaiseProgress( String.Format("{0} kbps - downloading - {1} MiB left", totalBytesPerSecond / 1024, totalBytesLeft / 1024 / 1024), totalPercentage); } }
/// <summary> /// Generates a download progress reports, and sends it to /// onProgressReport if it's set. This takes the index of the file /// being downloaded, the percent complete, the bytes downloaded, /// and the total amount of bytes we expect to download. /// </summary> private void FileProgressReport(int index, int percent, long bytesDownloaded, long bytesToDownload) { if (download_canceled) { return; } NetAsyncDownloaderDownloadPart download = downloads[index]; DateTime now = DateTime.Now; TimeSpan timeSpan = now - download.lastProgressUpdateTime; if (timeSpan.Seconds >= 3.0) { long bytesChange = bytesDownloaded - download.lastProgressUpdateSize; download.lastProgressUpdateSize = (int)bytesDownloaded; download.lastProgressUpdateTime = now; download.bytesPerSecond = (int)bytesChange / timeSpan.Seconds; } download.size = bytesToDownload; download.bytesLeft = download.size - bytesDownloaded; downloads[index] = download; int totalBytesPerSecond = 0; long totalBytesLeft = 0; long totalSize = 0; foreach (NetAsyncDownloaderDownloadPart t in downloads.ToList()) { if (t.bytesLeft > 0) { totalBytesPerSecond += t.bytesPerSecond; } totalBytesLeft += t.bytesLeft; totalSize += t.size; } int totalPercentage = (int)(((totalSize - totalBytesLeft) * 100) / (totalSize)); if (!download_canceled) { // Math.Ceiling was added to avoid showing 0 MiB left when finishing User.RaiseProgress( String.Format("{0} kbps - downloading - {1:f0} MB left", totalBytesPerSecond / 1024, Math.Ceiling((double)totalBytesLeft / 1024 / 1024)), totalPercentage); } }
/// <summary> /// Generates a download progress reports, and sends it to /// onProgressReport if it's set. /// </summary> private void FileProgressReport(int index, int percent, long bytesDownloaded, long bytesLeft) { if (downloadCanceled) { return; } NetAsyncDownloaderDownloadPart download = downloads[index]; download.percentComplete = percent; DateTime now = DateTime.Now; TimeSpan timeSpan = now - download.lastProgressUpdateTime; if (timeSpan.Seconds >= 3.0) { long bytesChange = bytesDownloaded - download.lastProgressUpdateSize; download.lastProgressUpdateSize = (int)bytesDownloaded; download.lastProgressUpdateTime = now; download.bytesPerSecond = (int)bytesChange / timeSpan.Seconds; } download.bytesLeft = bytesLeft; download.bytesDownloaded = bytesDownloaded; downloads[index] = download; if (onProgressReport != null) { int totalPercentage = 0; int totalBytesPerSecond = 0; long totalBytesLeft = 0; long totalBytesDownloaded = 0; for (int i = 0; i < downloads.Count; i++) { totalBytesPerSecond += downloads[i].bytesPerSecond; totalBytesLeft += downloads[i].bytesLeft; totalBytesDownloaded += downloads[i].bytesDownloaded; totalBytesLeft += downloads[i].bytesLeft; } totalPercentage = (int)((totalBytesDownloaded * 100) / (totalBytesLeft + totalBytesDownloaded + 1)); if (!downloadCanceled) { onProgressReport(totalPercentage, totalBytesPerSecond, totalBytesLeft); } } }
/// <summary> /// Downloads our files, returning an array of filenames that we're writing to. /// The .onCompleted delegate will be called on completion. /// </summary> public string[] Download(ICollection <Uri> urls) { foreach (Uri url in urls) { var download = new NetAsyncDownloaderDownloadPart(url); this.downloads.Add(download); } var filePaths = new string[downloads.Count]; for (int i = 0; i < downloads.Count; i++) { User.WriteLine("Downloading \"{0}\"", downloads[i].url); // We need a new variable for our closure/lambda, hence index = i. int index = i; // Schedule for us to get back progress reports. downloads[i].agent.DownloadProgressChanged += (sender, args) => FileProgressReport(index, args.ProgressPercentage, args.BytesReceived, args.TotalBytesToReceive - args.BytesReceived); // And schedule a notification if we're done (or if something goes wrong) downloads[i].agent.DownloadFileCompleted += (sender, args) => FileDownloadComplete(index, args.Error); // Snapshot whatever was in that location, in case we need to roll-back. file_transaction.Snapshot(downloads[i].path); // Bytes ahoy! downloads[i].agent.DownloadFileAsync(downloads[i].url, downloads[i].path); } // The user hasn't cancelled us yet. :) downloadCanceled = false; return(filePaths); }