aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs
blob: b3e1212536e6ff6753ac4cacaf35ed85b9675629 (plain)
1
2
3
4
5
6
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tango.MachineStudio.Common.Automation
{
    public class UI
    {
        public static String LoginButton { get; set; } = nameof(LoginButton);
    }
}
30 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 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
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),
                    });
                }
            }

            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;
        }
    }
}