/// <summary> /// Create the html required to generate a link for a line of callstack in a Bugg. /// </summary> /// <param name="Helper">The Url helper object.</param> /// <param name="CallStack">A line of callstack to make a link for.</param> /// <param name="Model">The view model for the current page.</param> /// <returns>A string suitable for MVC to render.</returns> public static MvcHtmlString CallStackSearchLink( this UrlHelper Helper, string CallStack, BuggViewModel Model ) { StringBuilder Result = new StringBuilder(); TagBuilder Tag = new TagBuilder( "a" ); Tag.MergeAttribute( "href", "/Buggs/Show/" + Model.Bugg.Id ); Tag.InnerHtml = CallStack; Result.AppendLine( Tag.ToString() ); return MvcHtmlString.Create( Result.ToString() ); }
/// <summary> /// Create the html required to create the links for table headers to control the sorting of a Bugg. /// </summary> /// <param name="Helper">The Url helper object.</param> /// <param name="HeaderName">The table column header name.</param> /// <param name="SortTerm">The sort term to use when sorting by this column.</param> /// <param name="Model">The view model for the current page.</param> /// <returns>A string suitable for MVC to render.</returns> public static MvcHtmlString TableHeader( this UrlHelper Helper, string HeaderName, string SortTerm, BuggViewModel Model ) { StringBuilder Result = new StringBuilder(); TagBuilder Tag = new TagBuilder( "a" ); Tag.MergeAttribute( "href", "/Buggs/Show/" + Model.Bugg.Id ); Tag.InnerHtml = "<span>" + HeaderName + "</span>"; Result.AppendLine( Tag.ToString() ); return MvcHtmlString.Create( Result.ToString() ); }
/// <summary> /// The Show action. /// </summary> /// <param name="BuggsForm">The form of user data passed up from the client.</param> /// <param name="id">The unique id of the Bugg.</param> /// <returns>The view to display a Bugg on the client.</returns> public ActionResult Show( FormCollection BuggsForm, int id ) { using( FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer( this.GetType().ToString() + "(BuggId=" + id + ")" ) ) { // Set the display properties based on the radio buttons bool DisplayModuleNames = false; if( BuggsForm["DisplayModuleNames"] == "true" ) { DisplayModuleNames = true; } bool DisplayFunctionNames = false; if( BuggsForm["DisplayFunctionNames"] == "true" ) { DisplayFunctionNames = true; } bool DisplayFileNames = false; if( BuggsForm["DisplayFileNames"] == "true" ) { DisplayFileNames = true; } bool DisplayFilePathNames = false; if( BuggsForm["DisplayFilePathNames"] == "true" ) { DisplayFilePathNames = true; DisplayFileNames = false; } bool DisplayUnformattedCallStack = false; if( BuggsForm["DisplayUnformattedCallStack"] == "true" ) { DisplayUnformattedCallStack = true; } // Create a new view and populate with crashes List<Crash> Crashes = null; Bugg Bugg = new Bugg(); BuggViewModel Model = new BuggViewModel(); Bugg = LocalBuggRepository.GetBugg( id ); if( Bugg == null ) { return RedirectToAction( "" ); } // @TODO yrx 2015-02-17 JIRA using( FAutoScopedLogTimer GetCrashesTimer = new FAutoScopedLogTimer( "Bugg.GetCrashes().ToList" ) ) { Crashes = Bugg.GetCrashes(); Bugg.AffectedVersions = new SortedSet<string>(); HashSet<string> MachineIds = new HashSet<string>(); foreach( Crash Crash in Crashes ) { MachineIds.Add( Crash.ComputerName ); // Ignore bad build versions. if( Crash.BuildVersion.StartsWith( "4." ) ) { Bugg.AffectedVersions.Add( Crash.BuildVersion ); } if( Crash.User == null ) { //?? } } Bugg.NumberOfUniqueMachines = MachineIds.Count; } // Apply any user settings if( BuggsForm.Count > 0 ) { if( !string.IsNullOrEmpty( BuggsForm["SetStatus"] ) ) { Bugg.Status = BuggsForm["SetStatus"]; LocalCrashRepository.SetBuggStatus( Bugg.Status, id ); } if( !string.IsNullOrEmpty( BuggsForm["SetFixedIn"] ) ) { Bugg.FixedChangeList = BuggsForm["SetFixedIn"]; LocalCrashRepository.SetBuggFixedChangeList( Bugg.FixedChangeList, id ); } if( !string.IsNullOrEmpty( BuggsForm["SetTTP"] ) ) { Bugg.TTPID = BuggsForm["SetTTP"]; BuggRepository.SetJIRAForBuggAndCrashes( Bugg.TTPID, id ); } if( !string.IsNullOrEmpty( BuggsForm["Description"] ) ) { Bugg.Description = BuggsForm["Description"]; } // <STATUS> } // Set up the view model with the crash data Model.Bugg = Bugg; Model.Crashes = Crashes; Crash NewCrash = Model.Crashes.FirstOrDefault(); if( NewCrash != null ) { using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "CallstackTrimming" ) ) { CallStackContainer CallStack = new CallStackContainer( NewCrash ); // Set callstack properties CallStack.bDisplayModuleNames = DisplayModuleNames; CallStack.bDisplayFunctionNames = DisplayFunctionNames; CallStack.bDisplayFileNames = DisplayFileNames; CallStack.bDisplayFilePathNames = DisplayFilePathNames; CallStack.bDisplayUnformattedCallStack = DisplayUnformattedCallStack; Model.CallStack = CallStack; // Shorten very long function names. foreach( CallStackEntry Entry in Model.CallStack.CallStackEntries ) { Entry.FunctionName = Entry.GetTrimmedFunctionName( 128 ); } Model.SourceContext = NewCrash.SourceContext; } } /*using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "BuggsController.Show.PopulateUserInfo" + "(id=" + id + ")" ) ) { // Add in the users for each crash in the Bugg foreach( Crash CrashInstance in Model.Crashes ) { LocalCrashRepository.PopulateUserInfo( CrashInstance ); } }*/ return View( "Show", Model ); } }
/// <summary> /// The Show action. /// </summary> /// <param name="BuggsForm">The form of user data passed up from the client.</param> /// <param name="id">The unique id of the Bugg.</param> /// <returns>The view to display a Bugg on the client.</returns> public ActionResult Show( FormCollection BuggsForm, int id ) { // Set the display properties based on the radio buttons bool DisplayModuleNames = false; if( BuggsForm["DisplayModuleNames"] == "true" ) { DisplayModuleNames = true; } bool DisplayFunctionNames = false; if( BuggsForm["DisplayFunctionNames"] == "true" ) { DisplayFunctionNames = true; } bool DisplayFileNames = false; if( BuggsForm["DisplayFileNames"] == "true" ) { DisplayFileNames = true; } bool DisplayFilePathNames = false; if( BuggsForm["DisplayFilePathNames"] == "true" ) { DisplayFilePathNames = true; DisplayFileNames = false; } bool DisplayUnformattedCallStack = false; if( BuggsForm["DisplayUnformattedCallStack"] == "true" ) { DisplayUnformattedCallStack = true; } // Create a new view and populate with crashes List<Crash> Crashes = null; Bugg Bugg = new Bugg(); BuggViewModel Model = new BuggViewModel(); Bugg = LocalBuggRepository.GetBugg( id ); if( Bugg == null ) { return RedirectToAction( "" ); } Crashes = Bugg.GetCrashes().ToList(); // Apply any user settings if( BuggsForm.Count > 0 ) { if( !string.IsNullOrEmpty( BuggsForm["SetStatus"] ) ) { Bugg.Status = BuggsForm["SetStatus"]; LocalCrashRepository.SetBuggStatus( Bugg.Status, id ); } if( !string.IsNullOrEmpty( BuggsForm["SetFixedIn"] ) ) { Bugg.FixedChangeList = BuggsForm["SetFixedIn"]; LocalCrashRepository.SetBuggFixedChangeList( Bugg.FixedChangeList, id ); } if( !string.IsNullOrEmpty( BuggsForm["SetTTP"] ) ) { Bugg.TTPID = BuggsForm["SetTTP"]; LocalCrashRepository.SetBuggTTPID( Bugg.TTPID, id ); } if( !string.IsNullOrEmpty( BuggsForm["Description"] ) ) { Bugg.Description = BuggsForm["Description"]; } } // Set up the view model with the crash data Model.Bugg = Bugg; Model.Crashes = Crashes; Crash NewCrash = Model.Crashes.FirstOrDefault(); if( NewCrash != null ) { CallStackContainer CallStack = new CallStackContainer( NewCrash ); // Set callstack properties CallStack.bDisplayModuleNames = DisplayModuleNames; CallStack.bDisplayFunctionNames = DisplayFunctionNames; CallStack.bDisplayFileNames = DisplayFileNames; CallStack.bDisplayFilePathNames = DisplayFilePathNames; CallStack.bDisplayUnformattedCallStack = DisplayUnformattedCallStack; Model.CallStack = CallStack; NewCrash.CallStackContainer = NewCrash.GetCallStack(); } // Add in the users for each crash in the Bugg foreach( Crash CrashInstance in Model.Crashes ) { LocalCrashRepository.PopulateUserInfo( CrashInstance ); } return View( "Show", Model ); }
/// <summary> /// The Show action. /// </summary> /// <param name="BuggsForm">The form of user data passed up from the client.</param> /// <param name="id">The unique id of the Bugg.</param> /// <returns>The view to display a Bugg on the client.</returns> public ActionResult Show( FormCollection BuggsForm, int id ) { using( FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer( this.GetType().ToString() + "(BuggId=" + id + ")", bCreateNewLog: true ) ) { // Handle 'CopyToJira' button int BuggIDToBeAddedToJira = 0; foreach( var Entry in BuggsForm ) { if( Entry.ToString().Contains( Bugg.JiraSubmitName ) ) { int.TryParse( Entry.ToString().Substring( Bugg.JiraSubmitName.Length ), out BuggIDToBeAddedToJira ); break; } } BuggRepository Buggs = new BuggRepository(); // Set the display properties based on the radio buttons bool DisplayModuleNames = false; if( BuggsForm["DisplayModuleNames"] == "true" ) { DisplayModuleNames = true; } bool DisplayFunctionNames = false; if( BuggsForm["DisplayFunctionNames"] == "true" ) { DisplayFunctionNames = true; } bool DisplayFileNames = false; if( BuggsForm["DisplayFileNames"] == "true" ) { DisplayFileNames = true; } bool DisplayFilePathNames = false; if( BuggsForm["DisplayFilePathNames"] == "true" ) { DisplayFilePathNames = true; DisplayFileNames = false; } bool DisplayUnformattedCallStack = false; if( BuggsForm["DisplayUnformattedCallStack"] == "true" ) { DisplayUnformattedCallStack = true; } // Create a new view and populate with crashes List<Crash> Crashes = null; BuggViewModel Model = new BuggViewModel(); Bugg NewBugg = Buggs.GetBugg( id ); if( NewBugg == null ) { return RedirectToAction( "" ); } Crashes = NewBugg.GetCrashes(); using (FAutoScopedLogTimer GetCrashesTimer = new FAutoScopedLogTimer( "Bugg.PrepareBuggForJira" )) { if (Crashes.Count > 0) { NewBugg.PrepareBuggForJira( Crashes ); if (BuggIDToBeAddedToJira != 0) { NewBugg.CopyToJira(); } } } using( FAutoScopedLogTimer JiraResultsTimer = new FAutoScopedLogTimer( "Bugg.GrabJira" ) ) { var JC = JiraConnection.Get(); bool bValidJira = false; // Verify valid JiraID, this may be still a TTP if( !string.IsNullOrEmpty( NewBugg.Jira ) ) { int TTPID = 0; int.TryParse( NewBugg.Jira, out TTPID ); if( TTPID == 0 ) { //AddBuggJiraMapping( NewBugg, ref FoundJiras, ref JiraIDtoBugg ); bValidJira = true; } } if( JC.CanBeUsed() && bValidJira ) { // Grab the data form JIRA. string JiraSearchQuery = "key = " + NewBugg.Jira; var JiraResults = JC.SearchJiraTickets( JiraSearchQuery, new string[] { "key", // string "summary", // string "components", // System.Collections.ArrayList, Dictionary<string,object>, name "resolution", // System.Collections.Generic.Dictionary`2[System.String,System.Object], name "fixVersions", // System.Collections.ArrayList, Dictionary<string,object>, name "customfield_11200" // string } ); // Jira Key, Summary, Components, Resolution, Fix version, Fix changelist foreach( var Jira in JiraResults ) { string JiraID = Jira.Key; string Summary = (string)Jira.Value["summary"]; string ComponentsText = ""; System.Collections.ArrayList Components = (System.Collections.ArrayList)Jira.Value["components"]; foreach( Dictionary<string, object> Component in Components ) { ComponentsText += (string)Component["name"]; ComponentsText += " "; } Dictionary<string, object> ResolutionFields = (Dictionary<string, object>)Jira.Value["resolution"]; string Resolution = ResolutionFields != null ? (string)ResolutionFields["name"] : ""; string FixVersionsText = ""; System.Collections.ArrayList FixVersions = (System.Collections.ArrayList)Jira.Value["fixVersions"]; foreach( Dictionary<string, object> FixVersion in FixVersions ) { FixVersionsText += (string)FixVersion["name"]; FixVersionsText += " "; } int FixCL = Jira.Value["customfield_11200"] != null ? (int)(decimal)Jira.Value["customfield_11200"] : 0; NewBugg.JiraSummary = Summary; NewBugg.JiraComponentsText = ComponentsText; NewBugg.JiraResolution = Resolution; NewBugg.JiraFixVersionsText = FixVersionsText; if( FixCL != 0 ) { NewBugg.JiraFixCL = FixCL.ToString(); } break; } } } // Apply any user settings if( BuggsForm.Count > 0 ) { if( !string.IsNullOrEmpty( BuggsForm["SetStatus"] ) ) { NewBugg.Status = BuggsForm["SetStatus"]; Buggs.SetBuggStatus( NewBugg.Status, id ); } if( !string.IsNullOrEmpty( BuggsForm["SetFixedIn"] ) ) { NewBugg.FixedChangeList = BuggsForm["SetFixedIn"]; Buggs.SetBuggFixedChangeList( NewBugg.FixedChangeList, id ); } if( !string.IsNullOrEmpty( BuggsForm["SetTTP"] ) ) { NewBugg.Jira = BuggsForm["SetTTP"]; Buggs.SetJIRAForBuggAndCrashes( NewBugg.Jira, id ); } // <STATUS> } // Set up the view model with the crash data Model.Bugg = NewBugg; Model.Crashes = Crashes; Crash NewCrash = Model.Crashes.FirstOrDefault(); if( NewCrash != null ) { using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "CallstackTrimming" ) ) { CallStackContainer CallStack = new CallStackContainer( NewCrash ); // Set callstack properties CallStack.bDisplayModuleNames = DisplayModuleNames; CallStack.bDisplayFunctionNames = DisplayFunctionNames; CallStack.bDisplayFileNames = DisplayFileNames; CallStack.bDisplayFilePathNames = DisplayFilePathNames; CallStack.bDisplayUnformattedCallStack = DisplayUnformattedCallStack; Model.CallStack = CallStack; // Shorten very long function names. foreach( CallStackEntry Entry in Model.CallStack.CallStackEntries ) { Entry.FunctionName = Entry.GetTrimmedFunctionName( 128 ); } Model.SourceContext = NewCrash.SourceContext; } Model.Bugg.LatestCrashSummary = NewCrash.Summary; } Model.GenerationTime = LogTimer.GetElapsedSeconds().ToString( "F2" ); return View( "Show", Model ); } }