aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Utilities/Tango.BugReporter/Program.cs
blob: 39d50c4a8fededc2e203ee8114480926b1f9f8c8 (plain)
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;
        }
    }
}