1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Shapes.Charts;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
using PdfSharp.Drawing;
using PdfSharp.Pdf;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Tango.Core.Helpers;
using Tango.Core.IO;
using Tango.TFS;
namespace Tango.BugReporter
{
class Program
{
private static List<Color> _colors = new List<Color>()
{
Colors.Crimson,
Colors.Coral,
Colors.Khaki,
Colors.Wheat,
Colors.PaleGreen,
Colors.PaleTurquoise,
Colors.CadetBlue,
Colors.Lavender,
Colors.SlateBlue,
Colors.LightSteelBlue,
Colors.PowderBlue,
Colors.Silver,
Colors.SlateGray,
};
static void Main(string[] args)
{
String startPath = AssemblyHelper.GetCurrentAssemblyFolder();
ITeamFoundationServiceClient tfs = new TeamFoundationServiceClient("https://twinetfs.visualstudio.com/DefaultCollection", String.Empty, "szzfokrceo4rhd4eqi5qpmxn3pa5iwl3q7tlqd36l2m7smz2ynoa");
var project = tfs.GetProject("Tango").Result;
var allItems = tfs.GetAllWorkItems(project).Result.OrderByDescending(x => x.Type).OrderBy(x => x.Severity).ToList();
var activeItems = allItems.Where(x => x.State == State.Active || x.State == State.New).ToList();
var resolvedItems = allItems.Where(x => x.State == State.Resolved).ToList();
Document document = new Document();
document.Info.Title = "Tango Bug Report";
document.Info.Author = "Twine Solutions LTD";
document.DefaultPageSetup.TopMargin = 5;
document.DefaultPageSetup.RightMargin = 5;
document.DefaultPageSetup.LeftMargin = 5;
Style style = document.Styles["Normal"];
style.Font.Size = 7;
var section = document.AddSection();
section.PageSetup.PageFormat = PageFormat.A4;
var headParagraph = section.AddParagraph();
headParagraph.Format.Alignment = ParagraphAlignment.Left;
headParagraph.Format.Font.Size = 16;
headParagraph.Format.Font.Bold = true;
headParagraph.Format.SpaceBefore = "8mm";
headParagraph.Format.SpaceAfter = "5mm";
headParagraph.Format.RightIndent = "5mm";
headParagraph.Format.Font.Color = Colors.DimGray;
var img = headParagraph.AddImage(Path.Combine(startPath, "twine-logo.jpg"));
headParagraph.AddSpace(5);
var t = headParagraph.AddText(" Twine Solutions VSTS Report");
var pp = section.AddParagraph(String.Format("This report was generated on {0}. Below you can find a daily summery of the Tango project, work items state and urgency.", DateTime.Now.ToShortDateString()));
pp.Format.LeftIndent = "2cm";
AddTable(section, "All Active Items", activeItems);
section.AddPageBreak();
AddTable(section, "Created Today", activeItems.Where(x => x.CreatedDate.Date == DateTime.Now.Date));
section.AddPageBreak();
AddTable(section, "Resolved Today", resolvedItems.Where(x => x.ResolvedDate.Date == DateTime.Now.Date));
section.AddPageBreak();
AddChart(section, ChartType.Column2D, "Items Per Member", activeItems.GroupBy(x => x.AssignedTo), nameof(TeamMember.DisplayName));
section.AddPageBreak();
AddChart(section, ChartType.Bar2D, "Items Per Area", activeItems.GroupBy(x => x.Area.Name), null);
section.AddPageBreak();
foreach (var g in activeItems.GroupBy(x => x.Area.Name))
{
AddTable(section, g.Key + " Items", g);
section.AddPageBreak();
}
var group = activeItems.GroupBy(x => x.AssignedTo);
var file = TemporaryManager.Default.CreateFile();
PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer(false, PdfFontEmbedding.None);
pdfRenderer.Document = document;
pdfRenderer.RenderDocument();
pdfRenderer.PdfDocument.Save(file.Path);
ITeamFoundationEmailClient emailClient = new TeamFoundationEmailClient(new System.Net.NetworkCredential("roy@twine-s.com", "Maya2018"));
Email mail = new Email();
mail.Attachments.Add(new Attachment() { FilePath = file.Path, Name = "VSTS-REPORT.pdf" });
mail.From = project.Members.SingleOrDefault(x => x.DisplayName.Contains("Roy"));
mail.To.Add(mail.From);
mail.Subject = "VSTS Daily Report";
mail.Body = "Attached is a daily report containing Tango project work items.";
emailClient.Send(mail).Wait();
file.Delete();
}
private static Chart AddChart<T>(Section section, ChartType chartType, String header, IEnumerable<IGrouping<T, WorkItem>> workItemGroups, String propName)
{
var headParagraph = section.AddParagraph(header);
headParagraph.Format.Alignment = ParagraphAlignment.Left;
headParagraph.Format.Font.Size = 16;
headParagraph.Format.Font.Bold = true;
headParagraph.Format.SpaceBefore = "8mm";
headParagraph.Format.SpaceAfter = "5mm";
Chart chart = section.AddChart(chartType);
chart.Width = section.Document.DefaultPageSetup.PageWidth - 5;
chart.Height = "10cm";
workItemGroups = workItemGroups.OrderByDescending(x => x.Count());
Series series = chart.SeriesCollection.AddSeries();
series.Add(workItemGroups.Select(x => (double)x.Count()).ToArray());
XSeries xseries = chart.XValues.AddXSeries();
if (propName != null)
{
xseries.Add(workItemGroups.Select(x => x.Key.GetType().GetProperty(propName, BindingFlags.Public | BindingFlags.Instance).GetValue(x.Key).ToString()).ToArray());
}
else
{
xseries.Add(workItemGroups.Select(x => x.Key.ToString()).ToArray());
}
var elements = series.Elements.Cast<Point>().ToArray();
for (int i = 0; i < elements.Length; i++)
{
elements[i].FillFormat.Color = _colors[i];
}
chart.XAxis.MajorTickMark = TickMarkType.Outside;
chart.XAxis.Title.Caption = propName;
chart.YAxis.MajorTickMark = TickMarkType.Outside;
chart.YAxis.HasMajorGridlines = true;
chart.PlotArea.LineFormat.Color = Colors.White;
chart.PlotArea.LineFormat.Width = 1;
chart.PlotArea.LineFormat.Visible = true;
return chart;
}
private static Table AddTable(Section section, String header, IEnumerable<WorkItem> workItems)
{
String startPath = AssemblyHelper.GetCurrentAssemblyFolder();
var headParagraph = section.AddParagraph(header);
headParagraph.Format.Alignment = ParagraphAlignment.Left;
headParagraph.Format.Font.Size = 16;
headParagraph.Format.Font.Bold = true;
headParagraph.Format.SpaceBefore = "8mm";
headParagraph.Format.SpaceAfter = "5mm";
var table = section.AddTable();
table.Borders.Color = Colors.Black;
table.Borders.Width = 0.25;
table.Borders.Left.Width = 0.5;
table.Borders.Right.Width = 0.5;
table.Rows.LeftIndent = 0;
table.BottomPadding = "2mm";
table.TopPadding = "2mm";
table.LeftPadding = "2mm";
table.RightPadding = "2mm";
// Before you can add a row, you must define the columns
table.AddColumn("1cm");
table.AddColumn();
table.AddColumn("4cm");
table.AddColumn();
table.AddColumn();
table.AddColumn();
table.AddColumn("1.5cm");
table.AddColumn("1.5cm");
table.AddColumn("1.5cm");
// Create the header of the table
Row row = table.AddRow();
row.HeadingFormat = true;
row.Shading.Color = Colors.Gainsboro;
row.Cells[0].AddParagraph("Work Item");
row.Cells[1].AddParagraph("Created Date");
row.Cells[2].AddParagraph("Title");
row.Cells[3].AddParagraph("Area");
row.Cells[4].AddParagraph("Created By");
row.Cells[5].AddParagraph("Assigned To");
row.Cells[6].AddParagraph("Severity");
row.Cells[7].AddParagraph("Priority");
row.Cells[8].AddParagraph("State");
foreach (var item in workItems)
{
Row r = table.AddRow();
var image = r.Cells[0].AddImage(Path.Combine(startPath, item.Type == WorkItemType.Bug ? "bug.png" : "task.png"));
image.Width = 15;
image.Height = 15;
r.Cells[1].AddParagraph(item.CreatedDate.ToShortDateString());
var linkParagraph = r.Cells[2].AddParagraph();
var link = linkParagraph.AddHyperlink(String.Format("https://twinetfs.visualstudio.com/DefaultCollection/Tango/_queries?id={0}&_a=edit", item.ID), HyperlinkType.Web);
link.AddFormattedText(item.Title);
r.Cells[3].AddParagraph(item.Area.Name);
r.Cells[4].AddParagraph(item.CreatedBy.DisplayName);
r.Cells[5].AddParagraph(item.AssignedTo.DisplayName);
var p = r.Cells[6].AddParagraph(item.Severity.ToString());
if (item.Severity == Severity.Critical || item.Severity == Severity.High)
{
p.Format.Font.Color = Colors.Red;
}
r.Cells[7].AddParagraph(item.Priority.ToDescription());
r.Cells[8].AddParagraph(item.State.ToString());
}
return table;
}
}
}
|