From 2d5a61e78f5e25d17d036d73092e211b9848287f Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Tue, 3 Sep 2024 09:41:44 -0700 Subject: [PATCH] Download only --- .vscode/launch.json | 21 ++--- .vscode/settings.json | 3 +- Day/HelperDay.cs | 2 + Day/Q32024/Helper-2024-08-30.cs | 133 ++++++++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 11 deletions(-) create mode 100644 Day/Q32024/Helper-2024-08-30.cs diff --git a/.vscode/launch.json b/.vscode/launch.json index 176350f..97f39a7 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,16 +13,17 @@ "args": [ "s", "X", - "D:/5-Other-Small/Kanban-mestsa003/ART-SPS/113724/.vscode/LogFiles/WaferCounter", - "Day-Helper-2024-08-28", - "*Wafer Counter Verify Log.csv", - "yyyy-MM-dd", - "D:/5-Other-Small/Kanban-mestsa003/ART-SPS/113724/.vscode/WaferCounter", - "*.wc", - "D:/5-Other-Small/Kanban-mestsa003/ART-SPS/113724/.vscode/Archive", - "777", - "888", - "999" + "L:/DevOps/Mesa_FI/File-Folder-Helper/.vscode/helper/tfs", + "Day-Helper-2024-08-30", + "MES", + "https://tfs.intra.infineon.com", + "/tfs/FactoryIntegration", + "ART SPS", + "/0d06e969-e1f5-4835-a359-620d557c7595/_apis/wit", + "/wiql/28112411-4edf-44bb-adf3-ffbc4b402681", + "4n7d2jcql6bkq32f66tohddonfxajkypq66lm5y3zqemtlohawsa", + "https://tfs.intra.infineon.com/tfs/FactoryIntegration/0d06e969-e1f5-4835-a359-620d557c7595/_backlogs/backlog/LEO%20Team/Features/", + "https://tfs.intra.infineon.com/tfs/FactoryIntegration/0d06e969-e1f5-4835-a359-620d557c7595/_backlogs/backlog/MES%20Team/Features/" ], "cwd": "${workspaceFolder}", "console": "integratedTerminal", diff --git a/.vscode/settings.json b/.vscode/settings.json index 4b87e1d..0861f9e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -36,6 +36,7 @@ "Serilog", "SUBM", "SURN", - "SYSLIB" + "SYSLIB", + "WIQL" ] } \ No newline at end of file diff --git a/Day/HelperDay.cs b/Day/HelperDay.cs index 43fdaac..37ab8ee 100644 --- a/Day/HelperDay.cs +++ b/Day/HelperDay.cs @@ -97,6 +97,8 @@ internal static class HelperDay Day.Q32024.Helper20240822.ParseKanbn(logger, args); else if (args[1] == "Day-Helper-2024-08-28") Day.Q32024.Helper20240828.MoveWaferCounterToArchive(logger, args); + else if (args[1] == "Day-Helper-2024-08-30") + Day.Q32024.Helper20240830.CompareWorkItems(logger, args); else throw new Exception(appSettings.Company); } diff --git a/Day/Q32024/Helper-2024-08-30.cs b/Day/Q32024/Helper-2024-08-30.cs new file mode 100644 index 0000000..f889214 --- /dev/null +++ b/Day/Q32024/Helper-2024-08-30.cs @@ -0,0 +1,133 @@ +using File_Folder_Helper.Day.Q32024.WorkItems; +using Microsoft.Extensions.Logging; +using Microsoft.TeamFoundation.WorkItemTracking.WebApi; +using Microsoft.VisualStudio.Services.Common; +using Microsoft.VisualStudio.Services.WebApi; +using System.Collections.ObjectModel; +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; +using System.Web; + +namespace File_Folder_Helper.Day.Q32024; + +internal static partial class Helper20240830 +{ + + private static string GetIds(HttpClient httpClient, string basePage, string api, string query) + { + StringBuilder result = new(); + Task httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, query)); + httpResponseMessageTask.Wait(); + if (!httpResponseMessageTask.Result.IsSuccessStatusCode) + throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString()); + Task streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync(); + streamTask.Wait(); + if (!streamTask.Result.CanRead) + throw new NullReferenceException(nameof(streamTask)); + WIQL.Root? root = JsonSerializer.Deserialize(streamTask.Result, WIQL.WIQLRootSourceGenerationContext.Default.Root); + streamTask.Result.Dispose(); + if (root is null || root.WorkItems is null) + throw new NullReferenceException(nameof(root)); + foreach (WIQL.WorkItem workItem in root.WorkItems) + _ = result.Append(workItem.Id).Append(','); + if (result.Length > 0) + _ = result.Remove(result.Length - 1, 1); + return result.ToString(); + } + + private static ReadOnlyCollection GetWorkItems(HttpClient httpClient, string basePage, string api, string sourceDirectory, string ids) + { + List results = []; + string json; + string file; + Value? value; + JsonElement[] jsonElements; + Task httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, $"/workitems?ids={ids}")); + httpResponseMessageTask.Wait(); + if (!httpResponseMessageTask.Result.IsSuccessStatusCode) + throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString()); + Task streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync(); + streamTask.Wait(); + if (!streamTask.Result.CanRead) + throw new NullReferenceException(nameof(streamTask)); + JsonElement? result = JsonSerializer.Deserialize(streamTask.Result); + if (result is null || result.Value.ValueKind != JsonValueKind.Object) + throw new NullReferenceException(nameof(result)); + JsonProperty[] jsonProperties = result.Value.EnumerateObject().ToArray(); + foreach (JsonProperty jsonProperty in jsonProperties) + { + if (jsonProperty.Value.ValueKind != JsonValueKind.Array) + continue; + jsonElements = jsonProperty.Value.EnumerateArray().ToArray(); + foreach (JsonElement jsonElement in jsonElements) + { + json = jsonElement.GetRawText(); + value = JsonSerializer.Deserialize(json, ValueSourceGenerationContext.Default.Value); + if (value is null) + continue; + file = Path.Combine(sourceDirectory, $"{-1}-{value.Id}.json"); + File.WriteAllText(file, json); + results.Add(new(value, -1, json)); + } + } + return new(results); + } + + private static void CompareWorkItems(WorkItemTrackingHttpClient workItemTrackingHttpClient, + string project, + string site, + ReadOnlyCollection valueWithReqCollection) + { + ArgumentNullException.ThrowIfNull(workItemTrackingHttpClient); + if (string.IsNullOrEmpty(project)) + throw new ArgumentException($"'{nameof(project)}' cannot be null or empty.", nameof(project)); + if (string.IsNullOrEmpty(site)) + throw new ArgumentException($"'{nameof(site)}' cannot be null or empty.", nameof(site)); + ArgumentNullException.ThrowIfNull(valueWithReqCollection); + // https://stackoverflow.com/questions/18153998/how-do-i-remove-all-html-tags-from-a-string-without-knowing-which-tags-are-in-it + } + + private static void CompareWorkItems(HttpClient httpClient, + string sourceDirectory, + string basePage, + string api, + string query, + WorkItemTrackingHttpClient workItemTrackingHttpClient, + string project, + string site) + { + string ids = GetIds(httpClient, basePage, api, query); + ReadOnlyCollection valueWithReqCollection = string.IsNullOrEmpty(ids) ? new([]) : GetWorkItems(httpClient, basePage, api, sourceDirectory, ids); + CompareWorkItems(workItemTrackingHttpClient, project, site, valueWithReqCollection); + } + + private static void CreateWorkItems(ILogger logger, string sourceDirectory, string api, string site, string query, string project, string basePage, string baseAddress, byte[] bytes, MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeaderValue, WorkItemTrackingHttpClient workItemTrackingHttpClient, HttpClient httpClient) + { + string base64 = Convert.ToBase64String(bytes); + httpClient.DefaultRequestHeaders.Authorization = new("Basic", base64); + httpClient.DefaultRequestHeaders.Accept.Add(mediaTypeWithQualityHeaderValue); + logger.LogInformation("{baseAddress}{basePage}/{project}{api}{query}", baseAddress, basePage, HttpUtility.HtmlEncode(project), api, query); + CompareWorkItems(httpClient, sourceDirectory, basePage, api, query, workItemTrackingHttpClient, project, site); + } + + internal static void CompareWorkItems(ILogger logger, List args) + { + string api = args[6]; + string pat = args[8]; + string site = args[2]; + string query = args[7]; + string project = args[5]; + string basePage = args[4]; + string baseAddress = args[3]; + string sourceDirectory = args[0]; + VssBasicCredential credential = new("", pat); + byte[] bytes = Encoding.ASCII.GetBytes($":{pat}"); + VssConnection connection = new(new(string.Concat(baseAddress, basePage)), credential); + MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeaderValue = new("application/json"); + WorkItemTrackingHttpClient workItemTrackingHttpClient = connection.GetClient(); + HttpClient httpClient = new(new HttpClientHandler() { UseDefaultCredentials = true }) { BaseAddress = new(baseAddress) }; + CreateWorkItems(logger, sourceDirectory, api, site, query, project, basePage, baseAddress, bytes, mediaTypeWithQualityHeaderValue, workItemTrackingHttpClient, httpClient); + } + +} \ No newline at end of file