|
|
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.Globalization;
- using System.IO;
- using System.Linq;
- using System.Management.Automation.Runspaces;
- using System.Net;
- using System.Net.Http;
- using System.Net.Http.Headers;
- using System.Security.Policy;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using System.Xml.Linq;
- using System.Xml.Serialization;
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- using MessageBox = System.Windows.MessageBox;
-
- namespace TrustedUninstaller.Shared
- {
- public class Playbook
- {
- public string Name { get; set; }
- public string ShortDescription { get; set; }
- public string Description { get; set; }
-
- public string Title { get; set; }
- public string Username { get; set; }
- public string Details { get; set; }
- public string Version { get; set; }
-
- [XmlArray]
- [XmlArrayItem(ElementName = "CheckboxPage", Type = typeof(CheckboxPage))]
- [XmlArrayItem(ElementName = "RadioPage", Type = typeof(RadioPage))]
- [XmlArrayItem(ElementName = "RadioImagePage", Type = typeof(RadioImagePage))]
- public FeaturePage[] FeaturePages { get; set; }
-
- public string ProgressText { get; set; } = "Deploying the selected Playbook configuration onto the system.";
- public int EstimatedMinutes { get; set; } = 25;
-
- #nullable enable
- public string[]? SupportedBuilds { get; set; }
- public Requirements.Requirement[] Requirements { get; set; } = new Requirements.Requirement[] {};
- public string? Git { get; set; }
- public string? DonateLink { get; set; }
- public string? Website { get; set; }
- public string? ProductCode { get; set; }
- public string? PasswordReplace { get; set; }
- #nullable disable
- public bool Overhaul { get; set; } = false;
-
- public string Path { get; set; }
-
- public List<string> Options { get; set; } = null;
-
- public string Validate()
- {
- if (FeaturePages == null)
- return null;
-
- foreach (var rawPage in FeaturePages)
- {
- if (rawPage.GetType() == typeof(CheckboxPage))
- {
- var page = (CheckboxPage)rawPage;
-
- if (page.Options.Length > 2 && page.TopLine != null && page.BottomLine != null)
- return @$"CheckboxPage with a TopLine and BottomLine must not have more than 2 options.";
- if (page.Options.Length > 3 && (page.TopLine != null || page.BottomLine != null))
- return @$"CheckboxPage with a TopLine or BottomLine must not have more than 3 options.";
- if (page.Options.Length > 4)
- return @$"CheckboxPage must not have more than 4 options.";
- }
- else if (rawPage.GetType() == typeof(RadioPage))
- {
- var page = (RadioPage)rawPage;
-
- if (page.Options.Length > 2 && page.TopLine != null && page.BottomLine != null)
- return @$"RadioPage with a TopLine and BottomLine must not have more than 2 options.";
- if (page.Options.Length > 3 && (page.TopLine != null || page.BottomLine != null))
- return @$"RadioPage with a TopLine or BottomLine must not have more than 3 options.";
- if (page.Options.Length > 4)
- return @$"RadioPage must not have more than 4 options.";
-
- if (page.DefaultOption != null && !page.Options.Any(x => x.Name == page.DefaultOption))
- return @$"No option matching DefaultOption {page.DefaultOption} in RadioPage.";
- }
- else if (rawPage.GetType() == typeof(RadioImagePage))
- {
- var page = (RadioImagePage)rawPage;
-
- if (page.Options.Length > 4)
- return @$"RadioImagePage must not have more than 4 options.";
- if (page.DefaultOption != null && !page.Options.Any(x => x.Name == page.DefaultOption))
- return @$"No option matching DefaultOption {page.DefaultOption} in RadioImagePage.";
- }
- }
- return null;
- }
-
- public static double GetVersionNumber(string toBeParsed)
- {
- // Examples:
- // 0.4
- // 0.4 Alpha
- // 1.0.5
- // 1.0.5 Beta
-
-
- // Remove characters after first space (and the space itself)
- if (toBeParsed.IndexOf(' ') >= 0)
- toBeParsed = toBeParsed.Substring(0, toBeParsed.IndexOf(' '));
-
- if (toBeParsed.LastIndexOf('.') != toBeParsed.IndexOf('.'))
- {
- // Example: 1.0.5
- toBeParsed = toBeParsed.Remove(toBeParsed.LastIndexOf('.'), 1);
- // Result: 1.05
- }
-
- return double.Parse(toBeParsed, CultureInfo.InvariantCulture);
- }
-
- public double GetVersionNumber()
- {
- return GetVersionNumber(Version);
- }
-
- public async Task<string> LatestPlaybookVersion()
- {
-
- if (!IsValidGit())
- {
- throw new ArgumentException("Link provided is not a proper Git link.");
- }
-
- string gitPlatform = GetPlaybookGitPlatform();
-
- string repo = GetRepository();
-
- using var httpClient = new HttpClient();
- httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("curl/7.55.1"); //Required for GitHub
-
- string url = gitPlatform switch
- {
- "github.com" => $"https://api.github.com/repos/{repo}/releases",
- "gitlab.com" => $"https://gitlab.com/api/v4/projects/{Uri.EscapeDataString(repo)}/releases",
- _ => $"https://{gitPlatform}/api/v1/repos/{repo}/releases"
- };
-
- var response = await httpClient.GetAsync(url);
-
- response.EnsureSuccessStatusCode();
-
- var json = await response.Content.ReadAsStringAsync();
- var array = JArray.Parse(json);
-
- return (string) array.FirstOrDefault()?["tag_name"];
- }
- public async Task<List<string>> GetPlaybookVersions()
- {
-
- if (!IsValidGit())
- {
- throw new ArgumentException("Link provided is not a proper Git link.");
- }
-
- string gitPlatform = GetPlaybookGitPlatform();
-
- string repo = GetRepository();
-
- using var httpClient = new HttpClient();
- httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("curl/7.55.1"); //Required for GitHub
-
- string url = gitPlatform switch
- {
- "github.com" => $"https://api.github.com/repos/{repo}/releases",
- "gitlab.com" => $"https://gitlab.com/api/v4/projects/{Uri.EscapeDataString(repo)}/releases",
- _ => $"https://{gitPlatform}/api/v1/repos/{repo}/releases"
- };
-
- var response = await httpClient.GetAsync(url);
-
- response.EnsureSuccessStatusCode();
-
- var json = await response.Content.ReadAsStringAsync();
- var array = JArray.Parse(json);
-
- var result = new List<string>();
- foreach (var releaseToken in array)
- result.Add((string)releaseToken["tag_name"]);
-
- return result;
- }
-
- public async Task DownloadLatestPlaybook(BackgroundWorker worker = null)
- {
- string repo = GetRepository();
- string gitPlatform = GetPlaybookGitPlatform();
-
- var httpClient = new WinUtil.HttpProgressClient();
- httpClient.Client.DefaultRequestHeaders.UserAgent.ParseAdd("curl/7.55.1"); //Required for GitHub
-
- var downloadUrl = string.Empty;
- var downloadDir = System.IO.Path.Combine(Environment.GetEnvironmentVariable("TEMP"), "AME");
- var downloadPath = System.IO.Path.Combine(downloadDir, "playbook.apbx");
-
- string baseUrl;
- string releasesUrl;
- string assetsKey;
- string browserDownloadUrlKey;
-
- switch (gitPlatform)
- {
- case "github.com":
- baseUrl = "https://api.github.com";
- releasesUrl = $"{baseUrl}/repos/{repo}/releases";
- assetsKey = "assets";
- browserDownloadUrlKey = "browser_download_url";
- break;
-
- case "gitlab.com":
- baseUrl = "https://gitlab.com/api/v4";
- releasesUrl = $"{baseUrl}/projects/{Uri.EscapeDataString(repo)}/releases";
- assetsKey = "assets.links";
- browserDownloadUrlKey = "direct_asset_url";
- break;
-
- default:
- baseUrl = $"https://{gitPlatform}/api/v1";
- releasesUrl = $"{baseUrl}/repos/{repo}/releases";
- assetsKey = "assets";
- browserDownloadUrlKey = "browser_download_url";
- break;
- }
-
- var releasesResponse = await httpClient.GetAsync(releasesUrl);
- releasesResponse.EnsureSuccessStatusCode();
-
- var releasesContent = await releasesResponse.Content.ReadAsStringAsync();
- var releases = JArray.Parse(releasesContent);
- var release = releases.FirstOrDefault();
-
- long size = 3000000;
-
- if (release?.SelectToken(assetsKey) is JArray assets)
- {
- var asset = assets.FirstOrDefault(a => a["name"].ToString().EndsWith(".apbx"));
- if (asset != null)
- {
- downloadUrl = asset[browserDownloadUrlKey]?.ToString();
-
- if (asset["size"] != null)
- long.TryParse(asset["size"].ToString(), out size);
- }
- }
-
- if (worker != null)
- worker.ReportProgress(10);
-
- // Download the release asset
- if (!string.IsNullOrEmpty(downloadUrl))
- {
- httpClient.Client.DefaultRequestHeaders.Clear();
-
- httpClient.ProgressChanged += (totalFileSize, totalBytesDownloaded, progressPercentage) => {
- if (progressPercentage.HasValue && worker != null)
- worker.ReportProgress((int)Math.Ceiling(10 + (progressPercentage.Value * 0.7)));
- };
-
- await httpClient.StartDownload(downloadUrl, downloadPath, size);
- }
- httpClient.Dispose();
- }
-
- public string GetRepository()
- {
- if (Git == null)
- {
- return null;
- }
-
- var urlSegments = Git.Replace("https://", "").Replace("http://", "").Split('/');
- return urlSegments[1] +"/"+ urlSegments[2];
- }
-
- public string GetPlaybookGitPlatform()
- {
- if (this.Git == null)
- {
- throw new NullReferenceException("No Git link available.");
- }
-
- return new Uri(Git).Host;
- }
-
- public bool IsValidGit()
- {
- if (Git == null)
- {
- throw new NullReferenceException("No Git link available.");
- }
-
- return Regex.IsMatch(Git, "((git|ssh|http(s)?)|(git@[\\w\\.]+))(:(//)?)([\\w\\.@\\:/\\-~]+)(/)?");;
- }
- public override string ToString()
- {
- return $"Name: {Name}\nDescription: {Description}\nUsername: {Username}\nDetails: {Details}\nRequirements: {Requirements}.";
- }
- [XmlType("CheckboxPage")]
- public class CheckboxPage : FeaturePage
- {
- public class CheckboxOption : Option
- {
- [XmlAttribute]
- public bool IsChecked { get; set; } = true;
- }
-
- [XmlArray]
- [XmlArrayItem(ElementName = "CheckboxOption", Type = typeof(CheckboxOption))]
- public Option[] Options { get; set; }
- }
- public class RadioPage : FeaturePage
- {
- [XmlAttribute]
- public string DefaultOption { get; set; } = null;
- public class RadioOption : Option
- {
- }
-
- [XmlArray]
- [XmlArrayItem(ElementName = "RadioOption", Type = typeof(RadioOption))]
- public Option[] Options { get; set; }
- }
- public class RadioImagePage : FeaturePage
- {
- [XmlAttribute]
- public string DefaultOption { get; set; } = null;
- public class RadioImageOption : Option
- {
- public string FileName { get; set; } = null;
-
- public bool Fill { get; set; } = false;
- [XmlAttribute]
- public bool None { get; set; } = false;
-
- public string GradientTopColor { get; set; } = null;
- public string GradientBottomColor { get; set; } = null;
- }
-
- [XmlArray]
- [XmlArrayItem(ElementName = "RadioImageOption", Type = typeof(RadioImageOption))]
- public Option[] Options { get; set; }
-
- [XmlAttribute]
- public bool CheckDefaultBrowser { get; set; } = false;
- }
-
- public class FeaturePage
- {
- [XmlAttribute]
- public string DependsOn { get; set; } = null;
- [XmlAttribute]
- public bool IsRequired { get; set; } = false;
- public Line TopLine { get; set; } = null;
- public Line BottomLine { get; set; } = null;
-
- public class Option
- {
- public string Name { get; set; } = null;
- public virtual string Text { get; set; }
-
- [XmlAttribute]
- public string DependsOn { get; set; } = null;
- }
- public class Line
- {
- [XmlAttribute("Text")]
- public string Text { get; set; }
- [XmlAttribute("Link")]
- public string Link { get; set; } = null;
- }
- [XmlAttribute]
- public string Description { get; set; }
- }
- }
- }
|