private static (bool, string) DownloadFile(string url, string destFile, FileUpdaterOptions opts) { Uri uri = new Uri(url); bool result = true; string errorMsg = null; Stopwatch watch = Stopwatch.StartNew(); using (WebClient client = new WebClient()) { client.Headers.Add("User-Agent", opts.UserAgent ?? Engine.DefaultUserAgent); if (opts.Model != null) { client.DownloadProgressChanged += (object sender, DownloadProgressChangedEventArgs e) => { opts.Model.BuildCommandProgressValue = e.ProgressPercentage; TimeSpan t = watch.Elapsed; double totalSec = t.TotalSeconds; string downloaded = NumberHelper.ByteSizeToSIUnit(e.BytesReceived, 1); string total = NumberHelper.ByteSizeToSIUnit(e.TotalBytesToReceive, 1); if (Math.Abs(totalSec) < double.Epsilon) { opts.Model.BuildCommandProgressText = $"{url}\r\nTotal : {total}\r\nReceived : {downloaded}"; } else { long bytePerSec = (long)(e.BytesReceived / totalSec); // Byte per sec string speedStr = NumberHelper.ByteSizeToSIUnit((long)(e.BytesReceived / totalSec), 1) + "/s"; // KB/s, MB/s, ... // ReSharper disable once PossibleLossOfFraction TimeSpan r = TimeSpan.FromSeconds((e.TotalBytesToReceive - e.BytesReceived) / bytePerSec); int hour = (int)r.TotalHours; int min = r.Minutes; int sec = r.Seconds; opts.Model.BuildCommandProgressText = $"{url}\r\nTotal : {total}\r\nReceived : {downloaded}\r\nSpeed : {speedStr}\r\nRemaining Time : {hour}h {min}m {sec}s"; } }; } AutoResetEvent resetEvent = new AutoResetEvent(false); client.DownloadFileCompleted += (object sender, AsyncCompletedEventArgs e) => { // Check if error occured if (e.Cancelled || e.Error != null) { result = false; if (e.Error is WebException webEx) { errorMsg = $"[{webEx.Status}] {webEx.Message}"; } if (File.Exists(destFile)) { File.Delete(destFile); } } resetEvent.Set(); }; client.DownloadFileAsync(uri, destFile); resetEvent.WaitOne(); } watch.Stop(); return(result, errorMsg); }
public static (Script newScript, string msg) UpdateScript(Project p, Script sc, FileUpdaterOptions opts) { if (!sc.Sections.ContainsKey(UpdateSection)) { return(null, "Unable to find script update information"); } Dictionary <string, string> scUpdateDict = sc.Sections[UpdateSection].IniDict; // Parse ScriptUpdateType if (!scUpdateDict.ContainsKey(ScriptTypeKey)) { return(null, "Unable to find script update type"); } ScriptUpdateType scType = ParseScriptUpdateType(scUpdateDict[ScriptTypeKey]); if (scType == ScriptUpdateType.None) { return(null, "Invalid script update type"); } // Get ScriptUrl if (!scUpdateDict.ContainsKey(ScriptUrlKey)) { return(null, "Unable to find script server url"); } string url = scUpdateDict[ScriptUrlKey].TrimStart('/'); if (scType == ScriptUpdateType.Project) { // Get BaseUrl if (!p.MainScript.Sections.ContainsKey(UpdateSection)) { return(null, "Unable to find project update information"); } Dictionary <string, string> pUpdateDict = p.MainScript.Sections[UpdateSection].IniDict; if (!pUpdateDict.ContainsKey(BaseUrlKey)) { return(null, "Unable to find project update base url"); } string pBaseUrl = pUpdateDict[BaseUrlKey].TrimEnd('/'); url = $"{url}\\{pBaseUrl}"; } string tempFile = FileHelper.GetTempFileNameEx(); opts.Model?.SetBuildCommandProgress("Download Progress"); try { (bool result, string errorMsg) = DownloadFile(url, tempFile, opts); if (result) { // Success File.Copy(tempFile, sc.DirectRealPath, true); Script newScript = p.RefreshScript(sc); return(newScript != null ? (newScript, $"Updated script [{sc.Title}] to [v{sc.Version}] from [v{newScript.Version}]") : (null, @"Downloaded script is corrupted")); } else { // Failure return(null, errorMsg); } } finally { opts.Model?.ResetBuildCommandProgress(); if (File.Exists(tempFile)) { File.Delete(tempFile); } } }
public static List <LogInfo> UpdateProject(Project p, FileUpdaterOptions opts) { List <LogInfo> logs = new List <LogInfo>(); return(logs); // Work in Progress /* * List<(Script, string)> newScripts = new List<(Script, string)>(p.AllScripts.Count); * * // Get BaseUrl * if (!p.MainScript.Sections.ContainsKey(UpdateSection)) * return LogInfo.LogErrorMessage(logs, "Unable to find project update information"); * Dictionary<string, string> pUpdateDict = IniUtil.ParseIniLinesIniStyle(p.MainScript.Sections[UpdateSection].GetLines()); * if (!pUpdateDict.ContainsKey(BaseUrlKey)) * return LogInfo.LogErrorMessage(logs, "Unable to find project update base url"); * string pBaseUrl = pUpdateDict[BaseUrlKey].TrimEnd('\\'); * * foreach (Script sc in p.AllScripts) * { * if (!sc.Sections.ContainsKey(UpdateSection)) * continue; * Dictionary<string, string> scUpdateDict = IniUtil.ParseIniLinesIniStyle(sc.Sections[UpdateSection].GetLines()); * * // Parse ScriptUpdateType * if (!scUpdateDict.ContainsKey(ScriptTypeKey)) * continue; * ScriptUpdateType scType = ParseScriptUpdateType(scUpdateDict[ScriptTypeKey]); * if (scType == ScriptUpdateType.None) * { * logs.Add(new LogInfo(LogState.Error, "Invalid script update type")); * continue; * } * * // Get ScriptUrl * if (!scUpdateDict.ContainsKey(ScriptUrlKey)) * { * logs.Add(new LogInfo(LogState.Error, "Unable to find script server url")); * continue; * } * string url = scUpdateDict[ScriptUrlKey].TrimStart('\\'); * * // Final Url * if (scType == ScriptUpdateType.Project) * url = $"{url}\\{pBaseUrl}"; * * string tempFile = FileHelper.GetTempFileNameEx(); * opts.Model?.SetBuildCommandProgress("Download Progress"); * try * { * (bool result, string errorMsg) = DownloadFile(url, tempFile, opts); * if (result) * { // Success * File.Copy(tempFile, sc.DirectRealPath, true); * Script newScript = p.RefreshScript(sc); * if (newScript != null) * newScripts.Add((newScript, $"Updated script [{sc.Title}] to [{sc.Version}] from [{newScript.Version}]")); * else * newScripts.Add((null, @"Downloaded script is corrupted")); * } * else * { // Failure * newScripts.Add((null, errorMsg)); * } * } * finally * { * opts.Model?.ResetBuildCommandProgress(); * * if (File.Exists(tempFile)) * File.Delete(tempFile); * } * } * * return logs; */ }