From 63f0078f679b104aff4e22ca7900d77cb5860228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=C3=B9ng=20Th=E1=BB=8Bnh?= Date: Thu, 9 Nov 2017 16:57:06 +0700 Subject: [PATCH] git commit update process UI --- Pluralsight_Download/Entity/Course.cs | 8 ++ Pluralsight_Download/PluralsightClient.cs | 69 ++++++++++-- .../Pluralsight_Download.csproj | 4 +- THttpWebRequest/THttpWebRequest.csproj | 1 + THttpWebRequest/Utility/ProgressBar.cs | 102 ++++++++++++++++++ 5 files changed, 172 insertions(+), 12 deletions(-) create mode 100644 THttpWebRequest/Utility/ProgressBar.cs diff --git a/Pluralsight_Download/Entity/Course.cs b/Pluralsight_Download/Entity/Course.cs index f833e2f..dcc5272 100644 --- a/Pluralsight_Download/Entity/Course.cs +++ b/Pluralsight_Download/Entity/Course.cs @@ -64,4 +64,12 @@ public enum Level Beginner, Advanced } + + public class LinkDownload + { + public string CDN { get; set; } + public string Source { get; set; } + public int Rank { get; set; } + public string Url { get; set; } + } } diff --git a/Pluralsight_Download/PluralsightClient.cs b/Pluralsight_Download/PluralsightClient.cs index 2f09021..73463a7 100644 --- a/Pluralsight_Download/PluralsightClient.cs +++ b/Pluralsight_Download/PluralsightClient.cs @@ -1,11 +1,16 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Web; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Pluralsight_Download.Entity; using THttpWebRequest; using THttpWebRequest.Utility; +using System.Threading; +using System.Threading.Tasks; namespace PluralSight_Download { @@ -32,31 +37,73 @@ public bool Login(string user, string pass) public string DownLoad(string urldownload) { var uri = new Uri(urldownload); - string url = "http://app.pluralsight.com/training/Player/ViewClip"; + string url = "https://app.pluralsight.com/video/clips/viewclip"; + var moduleName = HttpUtility.ParseQueryString(uri.Query).Get("name"); object data = new { - a = HttpUtility.ParseQueryString(uri.Query).Get("author"), - m = HttpUtility.ParseQueryString(uri.Query).Get("name"), - course = HttpUtility.ParseQueryString(uri.Query).Get("course"), - cn = HttpUtility.ParseQueryString(uri.Query).Get("clip"), - mt = ConfigValue.FileType, - q = ConfigValue.Quality, - cap = ConfigValue.Cap, - lc = ConfigValue.Localize + author = HttpUtility.ParseQueryString(uri.Query).Get("author"), + moduleName = moduleName, + courseName = HttpUtility.ParseQueryString(uri.Query).Get("course"), + clipIndex = int.Parse(HttpUtility.ParseQueryString(uri.Query).Get("clip") ?? "0"), + mediaType = ConfigValue.FileType, + quality = ConfigValue.Quality, + includeCaptions = ConfigValue.Cap, + locale = ConfigValue.Localize }; - return Post(url, data.ToJsonString(), TypeRequest.Json); + Referer = urldownload; + var downLoad = Post(url, data.ToJsonString(), TypeRequest.Json); + var jObject = JsonConvert.DeserializeObject(downLoad); + if(jObject!=null && jObject["urls"]!=null) + { + var urls = JsonConvert.DeserializeObject>(jObject["urls"].ToString()); + return urls.FirstOrDefault()?.Url; + } + throw new Exception($"Not find any url download for module {moduleName}"); } public void DownLoadFile(string url, string path, string fileName) { using (var webClient = new WebClient()) { + var fileSizeFromUrl = GetFileSizeFromUrl(webClient, url); + CreateIfNotExitDirectory(path); var combine = PathCombine(path, CleanFileName(fileName)); - webClient.DownloadFile(new Uri(url), combine); + + if (!CheckFileIsDonloaded(combine, fileSizeFromUrl, url)) + { + var progress = new ProgressBar(); + + webClient.DownloadProgressChanged += (sender, args) => + { + progress.Report((double)args.BytesReceived / args.TotalBytesToReceive); + }; + + webClient.DownloadFileCompleted += (sender, args) => + { + progress.Dispose(); + }; + + webClient.DownloadFileTaskAsync(new Uri(url), combine).Wait(); + } } } + public bool CheckFileIsDonloaded(string fileLocation, Int64 bytesTotal, string urlFile) + { + if (!File.Exists(fileLocation)) return false; + + if (new FileInfo(fileLocation).Length == bytesTotal) + return true; + return false; + } + + public Int64 GetFileSizeFromUrl(WebClient wc, string urlFile) + { + wc.OpenRead(urlFile); + return Convert.ToInt64(wc.ResponseHeaders["Content-Length"]); + } + public void DownloadAll(Course course, string path) { path = PathCombine(path, CleanFileName(course.Title)); diff --git a/Pluralsight_Download/Pluralsight_Download.csproj b/Pluralsight_Download/Pluralsight_Download.csproj index e9ca129..febe9ab 100644 --- a/Pluralsight_Download/Pluralsight_Download.csproj +++ b/Pluralsight_Download/Pluralsight_Download.csproj @@ -54,7 +54,9 @@ - + + Designer + diff --git a/THttpWebRequest/THttpWebRequest.csproj b/THttpWebRequest/THttpWebRequest.csproj index c454339..999ed7f 100644 --- a/THttpWebRequest/THttpWebRequest.csproj +++ b/THttpWebRequest/THttpWebRequest.csproj @@ -47,6 +47,7 @@ + diff --git a/THttpWebRequest/Utility/ProgressBar.cs b/THttpWebRequest/Utility/ProgressBar.cs new file mode 100644 index 0000000..72ec8ce --- /dev/null +++ b/THttpWebRequest/Utility/ProgressBar.cs @@ -0,0 +1,102 @@ +using System; +using System.Text; +using System.Threading; + +namespace THttpWebRequest.Utility +{ + public class ProgressBar : IDisposable, IProgress + { + private const int blockCount = 10; + private readonly TimeSpan animationInterval = TimeSpan.FromSeconds(1.0 / 8); + private const string animation = @"|/-\"; + + private readonly Timer timer; + + private double currentProgress = 0; + private string currentText = string.Empty; + private bool disposed = false; + private int animationIndex = 0; + + public ProgressBar() + { + timer = new Timer(TimerHandler); + + // A progress bar is only for temporary display in a console window. + // If the console output is redirected to a file, draw nothing. + // Otherwise, we'll end up with a lot of garbage in the target file. + if (!Console.IsOutputRedirected) + { + ResetTimer(); + } + } + + public void Report(double value) + { + // Make sure value is in [0..1] range + value = Math.Max(0, Math.Min(1, value)); + Interlocked.Exchange(ref currentProgress, value); + } + + private void TimerHandler(object state) + { + lock (timer) + { + if (disposed) return; + + int progressBlockCount = (int)(currentProgress * blockCount); + int percent = (int)(currentProgress * 100); + string text = string.Format("[{0}{1}] {2,3}% {3}", + new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount), + percent, + animation[animationIndex++ % animation.Length]); + UpdateText(text); + + ResetTimer(); + } + } + + private void UpdateText(string text) + { + // Get length of common portion + int commonPrefixLength = 0; + int commonLength = Math.Min(currentText.Length, text.Length); + while (commonPrefixLength < commonLength && text[commonPrefixLength] == currentText[commonPrefixLength]) + { + commonPrefixLength++; + } + + // Backtrack to the first differing character + StringBuilder outputBuilder = new StringBuilder(); + outputBuilder.Append('\b', currentText.Length - commonPrefixLength); + + // Output new suffix + outputBuilder.Append(text.Substring(commonPrefixLength)); + + // If the new text is shorter than the old one: delete overlapping characters + int overlapCount = currentText.Length - text.Length; + if (overlapCount > 0) + { + outputBuilder.Append(' ', overlapCount); + outputBuilder.Append('\b', overlapCount); + } + + Console.Write(outputBuilder); + currentText = text; + } + + private void ResetTimer() + { + timer.Change(animationInterval, TimeSpan.FromMilliseconds(-1)); + } + + public void Dispose() + { + lock (timer) + { + disposed = true; + UpdateText(string.Empty); + } + } + + } +}