Last active
June 10, 2021 18:56
-
-
Save Tempest1000/bcfe53eda7c0b6dadda95acb39cf46e7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Query Kind="Program"> | |
<Reference Relative="bin\Newtonsoft.Json.dll">D:\Data\LINQ\bin\Newtonsoft.Json.dll</Reference> | |
</Query> | |
void Main() | |
{ | |
// ------------------------- | |
// To use this application you must download a copy of Newtonsoft.Json.dll, which by default is not bundled with LINQPad. | |
// This DLL can be sourced from the NuGet package manager here: https://www.nuget.org/packages/Newtonsoft.Json | |
// Note the hardcoded path above, this can be changed to the location of the DLL on your hard drive. | |
// To do this: F4 > browse > choose Newtonsoft.Json.dll | |
// The password for JIRA shouldn't be stored in plaintext in the script, so add this value to the LINQPad password manager. | |
// In the password manager give the password the name "Jira Password". | |
// ------------------------- | |
// credit to fyllepo | |
// for creating this fantastic app in PHP | |
// https://github.com/fyllepo/jira-report-time-logged-by-user/blob/master/index.php | |
string pathWithEnv = @"%USERPROFILE%\AppData\Local\LINQPad\report.html"; | |
int maxResults = 100; | |
string jiraUrl = "jira.genco.local"; | |
string jiraProjectKey = "RED5"; | |
string username = "user"; | |
string credentials = string.Format("{0}:{1}", username, Util.GetPassword("Jira Password")); | |
List<string> filterUsers = new List<string> | |
{ | |
"John Smith", | |
"Jane Smith" | |
}; | |
string responseData = null; | |
string responseHeaders = null; | |
int responseStatusCode = 0; | |
// credit to dhlavaty | |
// https://gist.github.com/dhlavaty/4433398 | |
using (BetterWebClient webClient = new BetterWebClient()) | |
{ | |
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(credentials); | |
string key = System.Convert.ToBase64String(plainTextBytes); | |
string method = System.Net.WebRequestMethods.Http.Get; | |
webClient.Proxy = null; | |
webClient.Headers.Add(System.Net.HttpRequestHeader.ContentType, "application/json; charset=utf-8"); | |
webClient.Headers.Add(System.Net.HttpRequestHeader.Authorization, "Basic " + key); | |
var webRequest = webClient.GetWebRequestX(new Uri(string.Format("http://{0}/rest/api/2/search?jql=project={1}&maxResults={2}", jiraUrl, jiraProjectKey, maxResults))); | |
webRequest.Method = method; | |
using (System.Net.WebResponse response = webRequest.GetResponse()) | |
{ | |
ProcessResponse(response, out responseData, out responseHeaders, out responseStatusCode); | |
} | |
} | |
// requires a download of Newtonsoft JSON from https://www.newtonsoft.com/json | |
// or the NuGet package manager here: https://www.nuget.org/packages/Newtonsoft.Json | |
// then F4 > browse > choose Newtonsoft.Json.dll | |
Newtonsoft.Json.Linq.JObject jo = Newtonsoft.Json.Linq.JObject.Parse(responseData); | |
var list = new List<JiraInfo>(); | |
foreach (var data in jo["issues"]) | |
{ | |
var field = data["fields"]; | |
var info = new JiraInfo(); | |
info.Key = data["key"].ToString(); | |
if (field["assignee"] != null) { | |
if (!field["assignee"].Any()) { | |
info.Assignee = "Unassigned"; | |
} | |
else | |
{ | |
info.Assignee = field["assignee"]["displayName"].ToString(); | |
} | |
} | |
info.Status = field["status"]["name"].ToString(); | |
info.Priority = field["priority"]["name"].ToString(); | |
info.Summary = field["summary"].ToString(); | |
var timeEstimate = field["timeestimate"].ToString(); | |
var totalTimeSpent = field["aggregatetimespent"].ToString(); | |
var timeEstimateHours = 0m; | |
var totalTimeSpentHours = 0m; | |
if (decimal.TryParse(timeEstimate, out decimal timeEstimateHoursParsed)) | |
{ | |
timeEstimateHours = timeEstimateHoursParsed / 3600; | |
} | |
if (decimal.TryParse(totalTimeSpent, out decimal totalTimeSpentHoursParsed)) | |
{ | |
totalTimeSpentHours = totalTimeSpentHoursParsed / 3600; | |
} | |
info.TimeEstimate = timeEstimateHours.ToString(); | |
info.TotalTimeSpent = totalTimeSpentHours.ToString(); | |
list.Add(info); | |
} | |
var html = GenerateHtml(list, filterUsers); | |
var filePath = Environment.ExpandEnvironmentVariables(pathWithEnv); | |
File.WriteAllText(filePath, html); | |
} | |
// classes | |
class JiraInfo | |
{ | |
public string Key { get; set; } | |
public string Assignee { get; set; } | |
public string Status { get; set; } | |
public string Priority { get; set; } | |
public string Summary { get; set; } | |
public string TimeEstimate { get; set; } | |
public string TotalTimeSpent { get; set; } | |
} | |
// credit to dhlavaty | |
// https://gist.github.com/dhlavaty/4433398 | |
class BetterWebClient : System.Net.WebClient | |
{ | |
public virtual System.Net.WebRequest GetWebRequestX(Uri address) | |
{ | |
return this.GetWebRequest(address); | |
} | |
} | |
// methods | |
void ProcessResponse(System.Net.WebResponse response, out string recurlyResponse, out string responseHeaders, out int responseStatusCode) | |
{ | |
recurlyResponse = responseHeaders = String.Empty; | |
responseStatusCode = 0; | |
using (var responseStream = response.GetResponseStream()) | |
{ | |
using (System.IO.StreamReader sr = new System.IO.StreamReader(responseStream, Encoding.UTF8)) | |
{ | |
recurlyResponse = sr.ReadToEnd(); | |
} | |
} | |
responseHeaders = response.Headers.ToString(); | |
var httpWebResponse = response as System.Net.HttpWebResponse; | |
if (httpWebResponse != null) | |
{ | |
responseStatusCode = (int)httpWebResponse.StatusCode; | |
} | |
} | |
string GenerateHtml(List<JiraInfo> list, List<string> filterUsers) | |
{ | |
StringBuilder sb = new StringBuilder(); | |
sb.Append(@" | |
<!DOCTYPE html> | |
<html lang=""en""> | |
<head> | |
<meta charset=""UTF-8""> | |
<title>JIRA Export</title> | |
<link rel=""stylesheet"" href=""https://unpkg.com/purecss@0.6.2/build/pure-min.css"" integrity=""sha384-UQiGfs9ICog+LwheBSRCt1o5cbyKIHbwjWscjemyBMT9YCUMZffs6UqUTd0hObXD"" crossorigin=""anonymous""> | |
<style>body{font-family:Arial;padding:30px}label{margin-top:50px;width:360px;font-size:22px;font-weight:700;padding-bottom: 10px;}input{margin-top:5px;height:40px;width:400px;font-size:20px;padding-left:15px;text-transform:uppercase;vertical-align:bottom;}button{color:#fff;vertical-align:bottom;height:46px;}.button-success{background:#1cb841;color:#fff;}.button-secondary{background:#42b8dd}.button-small{font-size:85%}.button-xlarge{font-size:125%}</style> | |
</head> | |
<body> | |
<h3>Results</h3> | |
<table class=""pure-table pure-table-bordered""> | |
<thead> | |
<tr> | |
<th width=""100"">Key</th> | |
<th>Assignee</th> | |
<th>Status</th> | |
<th>Priority</th> | |
<th>Summary</th> | |
<th>Time Estimated</th> | |
<th>Total Time Spent (hrs)</th> | |
</tr> | |
</thead> | |
<tbody> | |
"); | |
var rows = filterUsers.Any() ? list.Where(x => filterUsers.Contains(x.Assignee)) : list; | |
foreach(var info in rows) | |
{ | |
sb.Append(string.Format(@" | |
<tr> | |
<td>{0}</td> | |
<td>{1}</td> | |
<td>{2}</td> | |
<td>{3}</td> | |
<td>{4}</td> | |
<td>{5}</td> | |
<td>{6}</td> | |
</tr> | |
", info.Key, info.Assignee, info.Status, info.Priority, info.Summary, info.TimeEstimate, info.TotalTimeSpent)); | |
} | |
sb.Append(@" | |
</tbody> | |
</table> | |
</body> | |
</html> | |
"); | |
return sb.ToString(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment