aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs
blob: 7b1727ec303e9e462c88eab78b0c389e61253d1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tango.MachineStudio.Logging.Helpers
{
    public static class TimelineHelper
    {
        public static double ConvertTimeToPixels(TimeSpan time, double scaleFactor)
        {
            return ((double)(0.05f * ((double)(time.TotalSeconds) * 20))) * scaleFactor;
        }
    }
}
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Security.Authentication;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Tango.BL.Entities;
using Tango.Core.DI;
using Tango.Core.ExtensionMethods;
using Tango.Core.Helpers;
using Tango.Core.IO;
using Tango.Integration.Operation;
using Tango.Logging;
using Tango.MachineStudio.Common.Authentication;
using Tango.MachineStudio.Common.StudioApplication;
using Tango.SharedUI.Helpers;
using Tango.TFS;

namespace Tango.MachineStudio.UI.TFS
{
    public class TeamFoundationServiceExtendedClient : TeamFoundationServiceClient
    {
        private TemporaryFolder _tempFolder;
        private String user_email;

        public Project Project { get; private set; }

        private ObservableCollection<WorkItem> _resolvedWorkItems;
        public ObservableCollection<WorkItem> ResolvedWorkItems
        {
            get { return _resolvedWorkItems; }
            set { _resolvedWorkItems = value; RaisePropertyChangedAuto(); }
        }

        private bool _isInitialized;
        public bool IsInitialized
        {
            get { return _isInitialized; }
            private set { _isInitialized = value; RaisePropertyChangedAuto(); }
        }

        public TeamFoundationServiceExtendedClient(string collectionURL, string userName, string personalToken) : base(collectionURL, userName, personalToken)
        {
            _tempFolder = TemporaryManager.CreateFolder();

            ResolvedWorkItems = new ObservableCollection<WorkItem>();
            TangoIOC.Default.GetInstance<IAuthenticationProvider>().CurrentUserChanged += TeamFoundationServiceExtendedClient_CurrentUserChanged;
        }

        private void TeamFoundationServiceExtendedClient_CurrentUserChanged(object sender, User user)
        {
            if (user != null)
            {
                user_email = user.Email;

                Task.Factory.StartNew(async () =>
                {
                    Thread.Sleep(5000);
                    await UpdateCurrentUserResolvedWorkItems();
                });
            }
        }

        public Task<WorkItem> UploadWorkItem(WorkItem workItem)
        {
            return UploadWorkItem(Project, workItem);
        }

        public async Task UpdateCurrentUserResolvedWorkItems()
        {
            try
            {
                if (Project != null)
                {
                    IStudioApplicationManager app = TangoIOC.Default.GetInstance<IStudioApplicationManager>();
                    var member = GetUserTeamMember();

                    if (member != null)
                    {
                        var items = await GetWorkItemsCreatedBy(Project, member);
                        items.Where(x => x.StepsToReproduce != null).ToList().ForEach(x => x.StepsToReproduce = x.StepsToReproduce.Replace("<div style=\"white-space:pre;\">", "").Replace("</div>", ""));
                        ResolvedWorkItems = items.Where(x => x.State == State.Resolved && x.ResolvedReason == ResolvedReason.Fixed && x.IsBuildVersionValid && x.FoundInBuildVersion < app.Version).ToObservableCollection();
                    }
                    else
                    {
                        LogManager.Default.Log($"User '{user_email}' is not part of the VSTS team.", LogCategory.Warning);
                    }
                }
            }
            catch (Exception ex)
            {
                LogManager.Log(ex, "Error getting the current user resolved work items.");
            }
        }

        public async Task<WorkItem> CloseWorkItem(WorkItem workItem)
        {
            await SetWorkItemState(Project, workItem, State.Closed);
            var updated = await AddWorkItemComment(Project, workItem, GetUserTeamMember(), "Bug has been verified and closed by " + GetUserTeamMember().DisplayName + " (via Machine Studio).");
            ResolvedWorkItems.Remove(workItem);
            return updated;
        }

        public async Task<WorkItem> ReactivateWorkItem(WorkItem workItem)
        {
            await SetWorkItemState(Project, workItem, State.New);
            var updated = await AddWorkItemComment(Project, workItem, GetUserTeamMember(), "Bug has been reactivated by " + GetUserTeamMember().DisplayName + " (via Machine Studio).");
            updated = await SetWorkItemAssignment(Project, updated, workItem.ResolvedBy);
            ResolvedWorkItems.Remove(workItem);
            return updated;
        }

        public void Initialize()
        {
            Task.Factory.StartNew(() =>
            {
                if (!IsInitialized)
                {
                    try
                    {
                        Project = GetProject("Tango").Result;
                        IsInitialized = true;
                    }
                    catch (Exception ex)
                    {
                        LogManager.Log(ex, "Error initializing the Team Foundation Service client.");
                    }
                }
            });
        }

        public WorkItem CreateBug()
        {
            WorkItem item = new WorkItem();

            IAuthenticationProvider auth = TangoIOC.Default.GetInstance<IAuthenticationProvider>();
            IStudioApplicationManager app = TangoIOC.Default.GetInstance<IStudioApplicationManager>();

            item.Area = Project.Areas.FirstOrDefault();
            item.Iteration = Project.Iterations.FirstOrDefault();

            TeamMember currentUser = GetUserTeamMember();

            if (currentUser == null)
            {
                throw LogManager.Default.Log(new AuthenticationException($"User '{user_email}' is not part of the Tango VSTS team. Please contact your administrator."));
            }

            item.CreatedBy = currentUser;
            item.ChangedBy = currentUser;
            item.AuthorizedAs = currentUser;

            item.FoundInBuild = app.Version.ToString();
            item.Priority = Priority.Priority3;
            item.Severity = Severity.Medium;
            item.State = State.New;
            item.Type = WorkItemType.Bug;

            foreach (var window in Application.Current.Windows.OfType<Window>().Where(x => !String.IsNullOrWhiteSpace(x.Title)))
            {
                var bitmap = UIHelper.TakeSnapshot(window);

                if (!_tempFolder.Exists())
                {
                    _tempFolder = TemporaryManager.CreateFolder();
                }

                var tempFile = _tempFolder.CreateFile();
                bitmap.SaveJpeg(tempFile.Path, 30);

                String title = window.Title;

                item.Attachments.Add(new Attachment()
                {
                    Description = title + " Screen Capture",
                    FilePath = tempFile.Path,
                    Name = $"{title}.jpg",
                });
            }

            return item;
        }

        private string[] GetLogFiles(FileLogger logger)
        {
            string[] fileEntries = new string[1];
            fileEntries[0] = logger.LogFile;
            string fileName = Path.GetFileNameWithoutExtension(logger.LogFile);
            int indexPos = fileName.IndexOf(FileLogger.FILE_SET_EXTENSION);
            if (indexPos > 0)
            {
                string extension = Path.GetExtension(logger.LogFile);
                fileName = fileName.Substring(0, indexPos);
                fileEntries = Directory.GetFiles(logger.Folder, $"{fileName}*{extension}").Where(x => Path.GetFileName(x).StartsWith(logger.Tag)).OrderBy(x => x.Length).ThenBy(x => x).ToArray();
            }

            return fileEntries;
        }

        public void FinalizeBug(WorkItem item)
        {
            IAuthenticationProvider auth = TangoIOC.Default.GetInstance<IAuthenticationProvider>();
            IStudioApplicationManager app = TangoIOC.Default.GetInstance<IStudioApplicationManager>();

            FileLogger appFileLogger = LogManager.Default.RegisteredLoggers.FirstOrDefault(x => x.GetType() == typeof(FileLogger)) as FileLogger;
            FileLogger embeddedFileLogger = MachineOperator.EmbeddedLogManager.RegisteredLoggers.FirstOrDefault(x => x.GetType() == typeof(FileLogger)) as FileLogger;
            
            if (appFileLogger != null)
            {
                string[] logFiles = GetLogFiles(appFileLogger);
                foreach( string file  in logFiles)
                {
                    var appLogFile = _tempFolder.CreateImaginaryFile();
                    File.Copy(file, appLogFile.Path);
                    item.Attachments.Add(new Attachment()
                    {
                        Description = "Application Log File",
                        FilePath = appLogFile.Path,
                        Name = Path.GetFileName(file),
                    });
                }
            }

            if (embeddedFileLogger != null && File.Exists(embeddedFileLogger.LogFile))
            {
                string[] logFiles = GetLogFiles(embeddedFileLogger);
                foreach (string file in logFiles)
                {
                    var embeddedLogFile = _tempFolder.CreateImaginaryFile();
                    File.Copy(file, embeddedLogFile.Path);
                    item.Attachments.Add(new Attachment()
                    {
                        Description = "Embedded Log File",
                        FilePath = embeddedLogFile.Path,
                        Name = Path.GetFileName(file),
                    });
                }
            }

            //Add session log file..
            if (MachineOperator.EnableSessionLogFile)
            {
                var file = MachineOperator.SessionLogger.LogFile;

                if (file != null && File.Exists(file))
                {
                    var sessionLogFile = _tempFolder.CreateImaginaryFile();
                    File.Copy(file, sessionLogFile.Path);
                    item.Attachments.Add(new Attachment()
                    {
                        Description = "Session Log File",
                        FilePath = sessionLogFile.Path,
                        Name = Path.GetFileName(file),
                    });
                }
            }

            SystemInformationModel sysModel = new SystemInformationModel();
            sysModel.ApplicationVersion = app.Version.ToString();
            sysModel.EmbeddedVersion = "N/A";
            sysModel.HostName = Environment.MachineName;
            sysModel.UserName = auth.CurrentUser.Contact.FullName;

            if (app.ConnectedMachine != null)
            {
                Machine machine = app.Machine;

                sysModel.Machine = machine;
                sysModel.EmbeddedVersion = app.ConnectedMachine.DeviceInformation.Version;

                sysModel.ConfigurationString = machine.Configuration.Clone().ToJsonString();

                if (app.ConnectedMachine.CurrentProcessParameters != null)
                {
                    sysModel.LoadedProcessParametersString = app.ConnectedMachine.CurrentProcessParameters.ToJsonString(nameof(ProcessParametersTable.ProcessParametersTablesGroup));
                }

                if (app.ConnectedMachine.CurrentHardwareConfiguration != null)
                {
                    sysModel.LoadedHardwareConfigurationString = app.ConnectedMachine.CurrentHardwareConfiguration.ToJsonString();
                }
            }

            if (app.Machine != null && app.ConnectedMachine != null && app.ConnectedMachine.DeviceInformation != null)
            {
                item.EmbeddedVersion = app.ConnectedMachine.DeviceInformation.Version;
                item.MachineSerialNumber = app.Machine.SerialNumber;
            }

            String html = String.Empty;

            using (var stream = EmbeddedResourceHelper.GetEmbeddedResourceStream("Tango.MachineStudio.UI.TFS.SystemInformationTemplate.cshtml"))
            {
                StreamReader reader = new StreamReader(stream);
                html = reader.ReadToEnd();
            }

            item.SystemInformation = CodeGeneration.Helper.Parse(html, sysModel);

            item.StepsToReproduce = String.Format("<div style=\"white-space:pre\">{0}</div>", item.StepsToReproduce);
        }

        private TeamMember GetUserTeamMember()
        {
            IAuthenticationProvider auth = TangoIOC.Default.GetInstance<IAuthenticationProvider>();
            TeamMember currentUser = Project.Members.SingleOrDefault(x => x.UniqueName.ToLower().Contains(auth.CurrentUser.Email.ToLower()));
            return currentUser;
        }
    }
}