Пример #1
0
        /// <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));
            }
        }
        /// <summary>
        /// Return a view model containing a sorted list of crashes based on the user input.
        /// </summary>
        /// <param name="FormData">The user input from the client.</param>
        /// <returns>A view model to use to display a list of crashes.</returns>
        /// <remarks>The filtering mechanism works by generating a fluent query to describe the set of crashes we wish to view. Basically, 'Select.Where().Where().Where().Where()' etc.
        /// The filtering is applied in the following order:
        /// 1. Get all crashes.
        /// 2. Filter between the start and end dates.
        /// 3. Apply the search query.
        /// 4. Filter by the branch.
        /// 5. Filter by the game name.
        /// 6. Filter by the type of reports to view.
        /// 7. Filter by the user group.
        /// 8. Sort the results by the sort term.
        /// 9. Take one page of results.</remarks>
        public CrashesViewModel GetResults(FormHelper FormData)
        {
            using (FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer(this.GetType().ToString()))
            {
                UsersMapping UniqueUser = null;

                IEnumerable <Crash> Results = null;
                int Skip = (FormData.Page - 1) * FormData.PageSize;
                int Take = FormData.PageSize;

                var ResultsAll = ConstructQueryForFiltering(FormData);

                // Filter by data and get as enumerable.
                Results = FilterByDate(ResultsAll, FormData.DateFrom, FormData.DateTo);

                // Filter by BuggId
                if (!string.IsNullOrEmpty(FormData.BuggId))
                {
                    int  BuggId = 0;
                    bool bValid = int.TryParse(FormData.BuggId, out BuggId);

                    if (bValid)
                    {
                        BuggRepository Buggs   = new BuggRepository();
                        Bugg           NewBugg = Buggs.GetBugg(BuggId);

                        if (NewBugg != null)
                        {
                            List <Crash> Crashes   = NewBugg.GetCrashes();
                            var          NewResult = Results.Intersect(Crashes, new CrashComparer());
                            Results = NewResult;
                        }
                    }
                }

                // Get UserGroup ResultCounts
                Dictionary <string, int> GroupCounts = GetCountsByGroupFromCrashes(Results);

                // Filter by user group if present
                int UserGroupId;
                if (!string.IsNullOrEmpty(FormData.UserGroup))
                {
                    UserGroupId = FRepository.Get(this).FindOrAddGroup(FormData.UserGroup);
                }
                else
                {
                    UserGroupId = 1;
                }

                HashSet <int> UserIdsForGroup = FRepository.Get(this).GetUserIdsFromUserGroupId(UserGroupId);

                using (FScopedLogTimer LogTimer3 = new FScopedLogTimer("CrashRepository.Results.Users"))
                {
                    List <Crash> NewResults = new List <Crash>();
                    foreach (Crash Crash in Results)
                    {
                        if (UserIdsForGroup.Contains(Crash.UserNameId.Value))
                        {
                            NewResults.Add(Crash);
                        }
                    }

                    Results = NewResults;
                }

                // Pass in the results and return them sorted properly
                Results = GetSortedResults(Results, FormData.SortTerm, (FormData.SortOrder == "Descending"));

                // Get the Count for pagination
                int ResultCount = 0;
                using (FScopedLogTimer LogTimer3 = new FScopedLogTimer("CrashRepository.Results.Users"))
                {
                    ResultCount = Results.Count();
                }


                // Grab just the results we want to display on this page
                Results = Results.Skip(Skip).Take(Take);

                using (FScopedLogTimer LogTimer3 = new FScopedLogTimer("CrashRepository.GetResults.GetCallstacks"))
                {
                    // Process call stack for display
                    foreach (Crash CrashInstance in Results)
                    {
                        // Put callstacks into an list so we can access them line by line in the view
                        CrashInstance.CallStackContainer = GetCallStack(CrashInstance);
                    }
                }

                return(new CrashesViewModel
                {
                    Results = Results,
                    PagingInfo = new PagingInfo {
                        CurrentPage = FormData.Page, PageSize = FormData.PageSize, TotalResults = ResultCount
                    },
                    SortOrder = FormData.SortOrder,
                    SortTerm = FormData.SortTerm,
                    UserGroup = FormData.UserGroup,
                    CrashType = FormData.CrashType,
                    SearchQuery = FormData.SearchQuery,
                    UsernameQuery = FormData.UsernameQuery,
                    EpicIdOrMachineQuery = FormData.EpicIdOrMachineQuery,
                    MessageQuery = FormData.MessageQuery,
                    BuiltFromCL = FormData.BuiltFromCL,
                    BuggId = FormData.BuggId,
                    JiraQuery = FormData.JiraQuery,
                    DateFrom = (long)(FormData.DateFrom - CrashesViewModel.Epoch).TotalMilliseconds,
                    DateTo = (long)(FormData.DateTo - CrashesViewModel.Epoch).TotalMilliseconds,
                    BranchName = FormData.BranchName,
                    VersionName = FormData.VersionName,
                    PlatformName = FormData.PlatformName,
                    GameName = FormData.GameName,
                    GroupCounts = GroupCounts,
                    RealUserName = UniqueUser != null?UniqueUser.ToString() : null,
                });
            }
        }
Пример #3
0
        /// <summary>
        /// Sort the container of Buggs by the requested criteria.
        /// </summary>
        /// <param name="Results">A container of unsorted Buggs.</param>
        /// <param name="SortTerm">The term to sort by.</param>
        /// <param name="bSortDescending">Whether to sort by descending or ascending.</param>
        /// <param name="DateFrom">The date of the earliest Bugg to examine.</param>
        /// <param name="DateTo">The date of the most recent Bugg to examine.</param>
        /// <param name="UserGroup">The user group name to filter by.</param>
        /// <returns>A sorted container of Buggs.</returns>
        public IEnumerable <Bugg> GetSortedResults(IEnumerable <Bugg> Results, string SortTerm, bool bSortDescending, DateTime DateFrom, DateTime DateTo, string UserGroup)
        {
            using (FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer(this.GetType().ToString()))
            {
                try
                {
                    // Get the group id and grab all buggs for the specified group.
                    int NumResults = Results.Count();
                    HashSet <string> UserNamesForUserGroup = GetUserNamesFromUserGroups(UserGroup);


                    // Simplified query.
                    var BuggIdToCountMapGroup = new Dictionary <int, int>();
                    var BuggIdToCountMapRest  = new Dictionary <int, int>();
                    var BuggIdToMachineSet    = new Dictionary <int, HashSet <string> >();
                    Dictionary <string, int> MachineIdToCountMap = new Dictionary <string, int>();
                    List <Buggs_Crash>       BuggsFromDate       = null;
                    Dictionary <int, string> CrashToUser         = null;
                    Dictionary <int, string> CrashToMachine      = null;


                    // Get all buggs from the date range.
                    using (FScopedLogTimer LogTimer1 = new FScopedLogTimer("BuggRepository.GetSortedResults.BuggsFromDate SQL"))
                    {
                        BuggsFromDate =
                            (
                                from BuggCrash in Context.Buggs_Crashes
                                where BuggCrash.Crash.TimeOfCrash >= DateFrom && BuggCrash.Crash.TimeOfCrash <= AddOneDayToDate(DateTo)
                                select BuggCrash
                            ).AsEnumerable().ToList();

                        var CrashesWithIdUserMachine =
                            (
                                from Crash in Context.Crashes
                                where Crash.TimeOfCrash >= DateFrom && Crash.TimeOfCrash <= AddOneDayToDate(DateTo)
                                select new { Id = Crash.Id, UserName = Crash.UserName, MachineId = Crash.ComputerName }
                            );

                        CrashToUser    = CrashesWithIdUserMachine.ToDictionary(x => x.Id, y => y.UserName);
                        CrashToMachine = CrashesWithIdUserMachine.ToDictionary(x => x.Id, y => y.MachineId);
                    }


                    using (FScopedLogTimer LogTimer0 = new FScopedLogTimer("BuggRepository.GetSortedResults.Filtering"))
                    {
                        // This calculates total crashes for selected group and all groups.
                        foreach (Buggs_Crash BuggCrash in BuggsFromDate)
                        {
                            string MachineId;
                            CrashToMachine.TryGetValue(BuggCrash.CrashId, out MachineId);

                            string UserName       = CrashToUser[BuggCrash.CrashId];
                            bool   bValidForGroup = UserNamesForUserGroup.Contains(UserName);
                            if (!bValidForGroup)
                            {
                                int  CountRest     = 0;
                                bool bFoundRestKey = BuggIdToCountMapRest.TryGetValue(BuggCrash.BuggId, out CountRest);
                                if (bFoundRestKey)
                                {
                                    BuggIdToCountMapRest[BuggCrash.BuggId]++;
                                }
                                else
                                {
                                    BuggIdToCountMapRest.Add(BuggCrash.BuggId, 1);
                                }

                                continue;
                            }

                            int  Count     = 0;
                            bool bFoundKey = BuggIdToCountMapGroup.TryGetValue(BuggCrash.BuggId, out Count);
                            if (bFoundKey)
                            {
                                BuggIdToCountMapGroup[BuggCrash.BuggId]++;
                            }
                            else
                            {
                                BuggIdToCountMapGroup.Add(BuggCrash.BuggId, 1);
                            }

                            if (MachineId != null && MachineId.Length > 0)
                            {
                                HashSet <string> MachineSet       = null;
                                bool             bFoundMachineKey = BuggIdToMachineSet.TryGetValue(BuggCrash.BuggId, out MachineSet);
                                if (!bFoundMachineKey)
                                {
                                    BuggIdToMachineSet.Add(BuggCrash.BuggId, new HashSet <string>());
                                }

                                BuggIdToMachineSet[BuggCrash.BuggId].Add(MachineId);
                            }
                        }
                    }

                    using (FScopedLogTimer LogTimer2 = new FScopedLogTimer("BuggRepository.GetSortedResults.CrashesInTimeFrame"))
                    {
                        foreach (var Result in Results)
                        {
                            int GroupCount = 0;
                            BuggIdToCountMapGroup.TryGetValue(Result.Id, out GroupCount);
                            Result.CrashesInTimeFrameGroup = GroupCount;

                            int GroupRest = 0;
                            BuggIdToCountMapRest.TryGetValue(Result.Id, out GroupRest);
                            Result.CrashesInTimeFrameAll = GroupCount + GroupRest;
                        }
                    }

                    using (FScopedLogTimer LogTimer2 = new FScopedLogTimer("BuggRepository.GetSortedResults.UniqueMachineCrashesInTimeFrame"))
                    {
                        foreach (var Result in Results)
                        {
                            HashSet <string> MachineSet = null;
                            bool             bFoundKey  = BuggIdToMachineSet.TryGetValue(Result.Id, out MachineSet);
                            if (bFoundKey)
                            {
                                Result.NumberOfUniqueMachines = MachineSet.Count;
                            }
                            else
                            {
                                Result.NumberOfUniqueMachines = 0;
                            }
                        }
                    }

                    var IntermediateQueryable = Results.AsQueryable();

                    switch (SortTerm)
                    {
                    case "CrashesInTimeFrameGroup":
                        Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.CrashesInTimeFrameGroup, bSortDescending);
                        break;

                    case "CrashesInTimeFrameAll":
                        Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.CrashesInTimeFrameAll, bSortDescending);
                        break;

                    case "Id":
                        Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.Id, bSortDescending);
                        break;

                    case "BuildVersion":
                        Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.BuildVersion, bSortDescending);
                        break;

                    case "LatestCrash":
                        Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.TimeOfLastCrash, bSortDescending);
                        break;

                    case "FirstCrash":
                        Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.TimeOfFirstCrash, bSortDescending);
                        break;

                    case "NumberOfCrashes":
                        Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.NumberOfCrashes, bSortDescending);
                        break;


                    case "NumberOfUsers":
                    {
                        Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.NumberOfUniqueMachines, bSortDescending);
                    }
                    break;

                    case "Pattern":
                        Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.Pattern, bSortDescending);
                        break;

                    case "CrashType":
                        Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.CrashType, bSortDescending);
                        break;

                    case "Status":
                        Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.Status, bSortDescending);
                        break;

                    case "FixedChangeList":
                        Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.FixedChangeList, bSortDescending);
                        break;

                    case "TTPID":
                        Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.TTPID, bSortDescending);
                        break;
                    }
                    return(Results);
                }
                catch (Exception Ex)
                {
                    Debug.WriteLine("Exception in GetSortedResults: " + Ex.ToString());
                }
                return(Results);
            }
        }
Пример #4
0
        /// <summary>
        /// Sort the container of Buggs by the requested criteria.
        /// </summary>
        /// <param name="Results">A container of unsorted Buggs.</param>
        /// <param name="SortTerm">The term to sort by.</param>
        /// <param name="bSortDescending">Whether to sort by descending or ascending.</param>
        /// <param name="DateFrom">The date of the earliest Bugg to examine.</param>
        /// <param name="DateTo">The date of the most recent Bugg to examine.</param>
        /// <returns>A sorted container of Buggs.</returns>
        public IQueryable<Bugg> GetSortedResults( IQueryable<Bugg> Results, string SortTerm, bool bSortDescending, DateTime DateFrom, DateTime DateTo )
        {
            using( FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer( this.GetType().ToString() ) )
            {
                try
                {

                    var IntermediateResults =
                    (
                        from BuggCrashDetail in BuggsDataContext.Buggs_Crashes
                        where BuggCrashDetail.Crash.TimeOfCrash >= DateFrom && BuggCrashDetail.Crash.TimeOfCrash <= AddOneDayToDate( DateTo )
                        group BuggCrashDetail by BuggCrashDetail.BuggId into CrashesGrouped
                        join BuggDetail in Results on CrashesGrouped.Key equals BuggDetail.Id
                        select new { Bugg = BuggDetail, Count = CrashesGrouped.Count() }
                    );

                    using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "BuggRepository.GetSortedResults.CrashesInTimeFrame" ) )
                    {
                        foreach( var Result in IntermediateResults )
                        {
                            Result.Bugg.CrashesInTimeFrame = Result.Count;
                        }
                    }

                    switch( SortTerm )
                    {
                        case "CrashesInTimeFrame":
                            IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Count, bSortDescending );
                            break;

                        case "Id":
                            IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.Id, bSortDescending );
                            break;

                        case "BuildVersion":
                            IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.BuildVersion, bSortDescending );
                            break;

                        case "LatestCrash":
                            IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.TimeOfLastCrash, bSortDescending );
                            break;

                        case "FirstCrash":
                            IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.TimeOfFirstCrash, bSortDescending );
                            break;

                        case "NumberOfCrashes":
                            IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.NumberOfCrashes, bSortDescending );
                            break;

                        case "NumberOfUsers":
                            IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.NumberOfUsers, bSortDescending );
                            break;

                        case "Pattern":
                            IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.Pattern, bSortDescending );
                            break;

                        case "Status":
                            IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.Status, bSortDescending );
                            break;

                        case "FixedChangeList":
                            IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.FixedChangeList, bSortDescending );
                            break;

                        case "TTPID":
                            IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.TTPID, bSortDescending );
                            break;

                    }
                    return IntermediateResults.Select( x => x.Bugg );
                }
                catch( Exception Ex )
                {
                    Debug.WriteLine( "Exception in GetSortedResults: " + Ex.ToString() );
                }
                return Results;
            }
        }
Пример #5
0
        /// <summary>
        /// Return a view model containing a sorted list of crashes based on the user input.
        /// </summary>
        /// <param name="FormData">The user input from the client.</param>
        /// <returns>A view model to use to display a list of crashes.</returns>
        /// <remarks>The filtering mechanism works by generating a fluent query to describe the set of crashes we wish to view. Basically, 'Select.Where().Where().Where().Where()' etc.
        /// The filtering is applied in the following order:
        /// 1. Get all crashes.
        /// 2. Filter between the start and end dates.
        /// 3. Apply the search query.
        /// 4. Filter by the branch.
        /// 5. Filter by the game name.
        /// 6. Filter by the type of reports to view.
        /// 7. Filter by the user group.
        /// 8. Sort the results by the sort term.
        /// 9. Take one page of results.</remarks>
        public CrashesViewModel GetResults(FormHelper FormData)
        {
            using (FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer(this.GetType().ToString()))
            {
                UsersMapping       UniqueUser = null;
                IQueryable <Crash> Results    = null;
                int Skip = (FormData.Page - 1) * FormData.PageSize;
                int Take = FormData.PageSize;

                Results = ListAll();
                Results = FilterByDate(Results, FormData.DateFrom, FormData.DateTo);

                // Grab Results
                if (!string.IsNullOrEmpty(FormData.SearchQuery))
                {
                    string DecodedQuery = HttpUtility.HtmlDecode(FormData.SearchQuery).ToLower();
                    using (FScopedLogTimer LogTimer2 = new FScopedLogTimer("CrashRepository.GetResults.FindUserFromQuery" + "(Query=" + DecodedQuery + ")"))
                    {
                        if (!string.IsNullOrEmpty(DecodedQuery))
                        {
                            // Check if we are looking for user name.
                            string[] Params = DecodedQuery.Split(new string[] { "user:"******"SELECT * FROM [analyticsdb-01.dmz.epicgames.net].[CrashReport].[dbo].[UsersMapping] WHERE lower(UserName) = {0} OR lower(UserEmail) = {0}", Params[1]);

                                foreach (UsersMapping TheUser in FoundUsers)
                                {
                                    UniqueUser = TheUser;
                                    break;
                                }
                                if (UniqueUser != null)
                                {
                                    Results = Results.Where(CrashInstance => CrashInstance.EpicAccountId == UniqueUser.EpicAccountId);
                                }
                                else
                                {
                                    Results = Results.Where(CrashInstance => CrashInstance.EpicAccountId == "SomeValueThatIsNotPresentInTheDatabase");
                                }
                            }
                            else
                            {
                                Results = Search(Results, DecodedQuery);
                            }
                        }
                    }
                }

                // Start Filtering the results

                // Filter by BranchName
                if (!string.IsNullOrEmpty(FormData.BranchName))
                {
                    if (FormData.BranchName.StartsWith("-"))
                    {
                        Results =
                            (
                                from CrashDetail in Results
                                where !CrashDetail.Branch.Contains(FormData.BranchName.Substring(1))
                                select CrashDetail
                            );
                    }
                    else
                    {
                        Results =
                            (
                                from CrashDetail in Results
                                where CrashDetail.Branch.Contains(FormData.BranchName)
                                select CrashDetail
                            );
                    }
                }

                // Filter by GameName
                if (!string.IsNullOrEmpty(FormData.GameName))
                {
                    if (FormData.GameName.StartsWith("-"))
                    {
                        Results =
                            (
                                from CrashDetail in Results
                                where !CrashDetail.GameName.Contains(FormData.GameName.Substring(1))
                                select CrashDetail
                            );
                    }
                    else
                    {
                        Results =
                            (
                                from CrashDetail in Results
                                where CrashDetail.GameName.Contains(FormData.GameName)
                                select CrashDetail
                            );
                    }
                }

                // Filter by Crash Type
                if (FormData.CrashType != "All")
                {
                    switch (FormData.CrashType)
                    {
                    case "Crashes":
                        Results = Results.Where(CrashInstance => CrashInstance.CrashType == 1);
                        break;

                    case "Assert":
                        Results = Results.Where(CrashInstance => CrashInstance.CrashType == 2);
                        break;

                    case "Ensure":
                        Results = Results.Where(CrashInstance => CrashInstance.CrashType == 3);
                        break;

                    case "CrashesAsserts":
                        Results = Results.Where(CrashInstance => CrashInstance.CrashType == 1 || CrashInstance.CrashType == 2);
                        break;
                    }
                }

                // Get UserGroup ResultCounts
                Dictionary <string, int> GroupCounts = GetCountsByGroupFromCrashes(Results);

                // Filter by user group if present
                int UserGroupId;
                if (!string.IsNullOrEmpty(FormData.UserGroup))
                {
                    UserGroupId = FindOrAddUserGroup(FormData.UserGroup);
                }
                else
                {
                    UserGroupId = 1;
                }
                Results =
                    (
                        from CrashDetail in Results
                        from UserDetail in CrashRepositoryDataContext.Users
                        where UserDetail.UserGroupId == UserGroupId &&
                        (CrashDetail.UserNameId == UserDetail.Id || CrashDetail.UserName == UserDetail.UserName)
                        select CrashDetail
                    );

                // Pass in the results and return them sorted properly
                Results = GetSortedResults(Results, FormData.SortTerm, (FormData.SortOrder == "Descending"));

                // Get the Count for pagination
                int ResultCount = Results.Count();

                // Grab just the results we want to display on this page
                Results = Results.Skip(Skip).Take(Take);

                using (FScopedLogTimer LogTimer3 = new FScopedLogTimer("CrashRepository.GetResults.GetCallstacks"))
                {
                    // Process call stack for display
                    foreach (Crash CrashInstance in Results)
                    {
                        // Put callstacks into an list so we can access them line by line in the view
                        CrashInstance.CallStackContainer = GetCallStack(CrashInstance);
                    }
                }

                return(new CrashesViewModel
                {
                    Results = Results,
                    PagingInfo = new PagingInfo {
                        CurrentPage = FormData.Page, PageSize = FormData.PageSize, TotalResults = ResultCount
                    },
                    SortOrder = FormData.SortOrder,
                    SortTerm = FormData.SortTerm,
                    UserGroup = FormData.UserGroup,
                    CrashType = FormData.CrashType,
                    SearchQuery = FormData.SearchQuery,
                    DateFrom = (long)(FormData.DateFrom - CrashesViewModel.Epoch).TotalMilliseconds,
                    DateTo = (long)(FormData.DateTo - CrashesViewModel.Epoch).TotalMilliseconds,
                    BranchName = FormData.BranchName,
                    GameName = FormData.GameName,
                    GroupCounts = GroupCounts,
                    RealUserName = UniqueUser != null?UniqueUser.ToString() : null,
                });
            }
        }
Пример #6
0
		/// <summary>
		/// Sort the container of Buggs by the requested criteria.
		/// </summary>
		/// <param name="Results">A container of unsorted Buggs.</param>
		/// <param name="SortTerm">The term to sort by.</param>
		/// <param name="bSortDescending">Whether to sort by descending or ascending.</param>
		/// <param name="DateFrom">The date of the earliest Bugg to examine.</param>
		/// <param name="DateTo">The date of the most recent Bugg to examine.</param>
		/// <param name="UserGroup">The user group name to filter by.</param>
		/// <returns>A sorted container of Buggs.</returns>
		public IEnumerable<Bugg> GetSortedResults( IEnumerable<Bugg> Results, string SortTerm, bool bSortDescending, DateTime DateFrom, DateTime DateTo, string UserGroup )
		{
			using( FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer( this.GetType().ToString() ) )
			{
				try
				{
					// Get the group id and grab all buggs for the specified group.
					int NumResults = Results.Count();
					HashSet<string> UserNamesForUserGroup = GetUserNamesFromUserGroups( UserGroup );


					// Simplified query.
					var BuggIdToCountMapGroup = new Dictionary<int, int>();
					var BuggIdToCountMapRest = new Dictionary<int, int>();
					var BuggIdToMachineSet = new Dictionary<int, HashSet<string>>();
					Dictionary<string, int> MachineIdToCountMap = new Dictionary<string, int>();
					List<Buggs_Crash> BuggsFromDate = null;
					Dictionary<int, string> CrashToUser = null;
					Dictionary<int, string> CrashToMachine = null;


					// Get all buggs from the date range.
					using( FScopedLogTimer LogTimer1 = new FScopedLogTimer( "BuggRepository.GetSortedResults.BuggsFromDate SQL" ) )
					{
						BuggsFromDate =
								(
									from BuggCrash in Context.Buggs_Crashes
									where BuggCrash.Crash.TimeOfCrash >= DateFrom && BuggCrash.Crash.TimeOfCrash <= AddOneDayToDate( DateTo )
									select BuggCrash
								).AsEnumerable().ToList();

						var CrashesWithIdUserMachine =
						(
							from Crash in Context.Crashes
							where Crash.TimeOfCrash >= DateFrom && Crash.TimeOfCrash <= AddOneDayToDate( DateTo )
							select new { Id = Crash.Id, UserName = Crash.UserName, MachineId = Crash.ComputerName }
						);

						CrashToUser = CrashesWithIdUserMachine.ToDictionary( x => x.Id, y => y.UserName );
						CrashToMachine = CrashesWithIdUserMachine.ToDictionary( x => x.Id, y => y.MachineId );
					}


					using( FScopedLogTimer LogTimer0 = new FScopedLogTimer( "BuggRepository.GetSortedResults.Filtering" ) )
					{
						// This calculates total crashes for selected group and all groups.
						foreach( Buggs_Crash BuggCrash in BuggsFromDate )
						{
							string MachineId;
							CrashToMachine.TryGetValue( BuggCrash.CrashId, out MachineId );

							string UserName = CrashToUser[BuggCrash.CrashId];
							bool bValidForGroup = UserNamesForUserGroup.Contains( UserName );
							if( !bValidForGroup )
							{
								int CountRest = 0;
								bool bFoundRestKey = BuggIdToCountMapRest.TryGetValue( BuggCrash.BuggId, out CountRest );
								if( bFoundRestKey )
								{
									BuggIdToCountMapRest[BuggCrash.BuggId]++;
								}
								else
								{
									BuggIdToCountMapRest.Add( BuggCrash.BuggId, 1 );
								}

								continue;
							}

							int Count = 0;
							bool bFoundKey = BuggIdToCountMapGroup.TryGetValue( BuggCrash.BuggId, out Count );
							if( bFoundKey )
							{
								BuggIdToCountMapGroup[BuggCrash.BuggId]++;
							}
							else
							{
								BuggIdToCountMapGroup.Add( BuggCrash.BuggId, 1 );
							}

							if( MachineId != null && MachineId.Length > 0 )
							{
								HashSet<string> MachineSet = null;
								bool bFoundMachineKey = BuggIdToMachineSet.TryGetValue( BuggCrash.BuggId, out MachineSet );
								if( !bFoundMachineKey )
								{
									BuggIdToMachineSet.Add( BuggCrash.BuggId, new HashSet<string>() );
								}

								BuggIdToMachineSet[BuggCrash.BuggId].Add( MachineId );
							}
						}
					}

					using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "BuggRepository.GetSortedResults.CrashesInTimeFrame" ) )
					{
						foreach( var Result in Results )
						{
							int GroupCount = 0;
							BuggIdToCountMapGroup.TryGetValue( Result.Id, out GroupCount );
							Result.CrashesInTimeFrameGroup = GroupCount;

							int GroupRest = 0;
							BuggIdToCountMapRest.TryGetValue( Result.Id, out GroupRest );
							Result.CrashesInTimeFrameAll = GroupCount + GroupRest;
						}
					}

					using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "BuggRepository.GetSortedResults.UniqueMachineCrashesInTimeFrame" ) )
					{
						foreach( var Result in Results )
						{
							HashSet<string> MachineSet = null;
							bool bFoundKey = BuggIdToMachineSet.TryGetValue( Result.Id, out MachineSet );
							if( bFoundKey )
							{
								Result.NumberOfUniqueMachines = MachineSet.Count;
							}
							else
							{
								Result.NumberOfUniqueMachines = 0;
							}
						}
					}

					var IntermediateQueryable = Results.AsQueryable();

					switch( SortTerm )
					{
						case "CrashesInTimeFrameGroup":
							Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.CrashesInTimeFrameGroup, bSortDescending );
							break;

						case "CrashesInTimeFrameAll":
							Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.CrashesInTimeFrameAll, bSortDescending );
							break;

						case "Id":
							Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.Id, bSortDescending );
							break;

						case "BuildVersion":
							Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.BuildVersion, bSortDescending );
							break;

						case "LatestCrash":
							Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.TimeOfLastCrash, bSortDescending );
							break;

						case "FirstCrash":
							Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.TimeOfFirstCrash, bSortDescending );
							break;

						case "NumberOfCrashes":
							Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.NumberOfCrashes, bSortDescending );
							break;


						case "NumberOfUsers":
							{
								Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.NumberOfUniqueMachines, bSortDescending );
							}
							break;

						case "Pattern":
							Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.Pattern, bSortDescending );
							break;

						case "CrashType":
							Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.CrashType, bSortDescending );
							break;

						case "Status":
							Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.Status, bSortDescending );
							break;

						case "FixedChangeList":
							Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.FixedChangeList, bSortDescending );
							break;

						case "TTPID":
							Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.TTPID, bSortDescending );
							break;

					}
					return Results;
				}
				catch( Exception Ex )
				{
					Debug.WriteLine( "Exception in GetSortedResults: " + Ex.ToString() );
				}
				return Results;
			}
		}
Пример #7
0
        /// <summary>
        /// Sort the container of Buggs by the requested criteria.
        /// </summary>
        /// <param name="Results">A container of unsorted Buggs.</param>
        /// <param name="SortTerm">The term to sort by.</param>
        /// <param name="bSortDescending">Whether to sort by descending or ascending.</param>
        /// <param name="DateFrom">The date of the earliest Bugg to examine.</param>
        /// <param name="DateTo">The date of the most recent Bugg to examine.</param>
        /// <returns>A sorted container of Buggs.</returns>
        public IQueryable <Bugg> GetSortedResults(IQueryable <Bugg> Results, string SortTerm, bool bSortDescending, DateTime DateFrom, DateTime DateTo)
        {
            using (FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer(this.GetType().ToString()))
            {
                try
                {
                    var IntermediateResults =
                        (
                            from BuggCrashDetail in BuggsDataContext.Buggs_Crashes
                            where BuggCrashDetail.Crash.TimeOfCrash >= DateFrom && BuggCrashDetail.Crash.TimeOfCrash <= AddOneDayToDate(DateTo)
                            group BuggCrashDetail by BuggCrashDetail.BuggId into CrashesGrouped
                            join BuggDetail in Results on CrashesGrouped.Key equals BuggDetail.Id
                            select new { Bugg = BuggDetail, Count = CrashesGrouped.Count() }
                        );

                    using (FScopedLogTimer LogTimer2 = new FScopedLogTimer("BuggRepository.GetSortedResults.CrashesInTimeFrame"))
                    {
                        foreach (var Result in IntermediateResults)
                        {
                            Result.Bugg.CrashesInTimeFrame = Result.Count;
                        }
                    }


                    switch (SortTerm)
                    {
                    case "CrashesInTimeFrame":
                        IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Count, bSortDescending);
                        break;

                    case "Id":
                        IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.Id, bSortDescending);
                        break;

                    case "BuildVersion":
                        IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.BuildVersion, bSortDescending);
                        break;

                    case "LatestCrash":
                        IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.TimeOfLastCrash, bSortDescending);
                        break;

                    case "FirstCrash":
                        IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.TimeOfFirstCrash, bSortDescending);
                        break;

                    case "NumberOfCrashes":
                        IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.NumberOfCrashes, bSortDescending);
                        break;

                    case "NumberOfUsers":
                        IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.NumberOfUsers, bSortDescending);
                        break;

                    case "Pattern":
                        IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.Pattern, bSortDescending);
                        break;

                    case "Status":
                        IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.Status, bSortDescending);
                        break;

                    case "FixedChangeList":
                        IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.FixedChangeList, bSortDescending);
                        break;

                    case "TTPID":
                        IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.TTPID, bSortDescending);
                        break;
                    }
                    return(IntermediateResults.Select(x => x.Bugg));
                }
                catch (Exception Ex)
                {
                    Debug.WriteLine("Exception in GetSortedResults: " + Ex.ToString());
                }
                return(Results);
            }
        }
Пример #8
0
        /// <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(""));
                }

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

                    // <STATUS>
                }

                // 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();
                }

                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));
            }
        }
Пример #9
0
		/// <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 );
			}
		}
Пример #10
0
        private IQueryable <Crash> ConstructQuery(FormHelper FormData)
        {
            var results = ListAll();

            // Grab Results
            if (!string.IsNullOrEmpty(FormData.SearchQuery))
            {
                if (!string.IsNullOrEmpty(FormData.UsernameQuery))
                {
                    //We only use SearchQuery now for CallStack searching - if there's a searchquery value and a Username value, we need to get rid of the
                    //Username so that we can create a broader search range
                    FormData.UsernameQuery = "";
                }
                string DecodedQuery = HttpUtility.HtmlDecode(FormData.SearchQuery).ToLower();
                using (FScopedLogTimer LogTimer2 = new FScopedLogTimer("CrashRepository.GetResults.FindUserFromQuery" + "(Query=" + DecodedQuery + ")"))
                {
                    results = results.Where(item => item.RawCallStack.Contains(FormData.SearchQuery));
                }
            }

            // Filter by Crash Type
            if (FormData.CrashType != "All")
            {
                switch (FormData.CrashType)
                {
                case "Crashes":
                    results = results.Where(CrashInstance => CrashInstance.CrashType == 1);
                    break;

                case "Assert":
                    results = results.Where(CrashInstance => CrashInstance.CrashType == 2);
                    break;

                case "Ensure":
                    results = results.Where(CrashInstance => CrashInstance.CrashType == 3);
                    break;

                case "CrashesAsserts":
                    results = results.Where(CrashInstance => CrashInstance.CrashType == 1 || CrashInstance.CrashType == 2);
                    break;
                }
            }

            if (!string.IsNullOrEmpty(FormData.UsernameQuery))
            {
                results =
                    (
                        from CrashDetail in results
                        where CrashDetail.UserName.Equals(FormData.UsernameQuery)
                        select CrashDetail
                    );
            }

            // Start Filtering the results
            if (!string.IsNullOrEmpty(FormData.EpicIdQuery))
            {
                var DecodedQuery = HttpUtility.HtmlDecode(FormData.EpicIdQuery).ToLower();
                results =
                    (
                        from CrashDetail in results
                        where CrashDetail.EpicAccountId.Equals(FormData.EpicIdQuery)
                        select CrashDetail
                    );
            }

            if (!string.IsNullOrEmpty(FormData.MachineIdQuery))
            {
                var DecodedQuery = HttpUtility.HtmlDecode(FormData.MachineIdQuery).ToLower();
                results =
                    (
                        from CrashDetail in results
                        where CrashDetail.ComputerName.Equals(FormData.MachineIdQuery)
                        select CrashDetail
                    );
            }

            if (!string.IsNullOrEmpty(FormData.JiraQuery))
            {
                var DecodedQuery = HttpUtility.HtmlDecode(FormData.JiraQuery).ToLower();
                results =
                    (
                        from CrashDetail in results
                        where CrashDetail.TTPID.Equals(FormData.JiraQuery)
                        select CrashDetail
                    );
            }
            // Filter by BranchName
            if (!string.IsNullOrEmpty(FormData.BranchName))
            {
                if (FormData.BranchName.StartsWith("-"))
                {
                    results =
                        (
                            from CrashDetail in results
                            where !CrashDetail.Branch.Contains(FormData.BranchName.Substring(1))
                            select CrashDetail
                        );
                }
                else
                {
                    results =
                        (
                            from CrashDetail in results
                            where CrashDetail.Branch.Equals(FormData.BranchName)
                            select CrashDetail
                        );
                }
            }
            else
            {
                results =
                    (
                        from CrashDetail in results
                        where !CrashDetail.Branch.Equals("UE4-UT-Releases") && !CrashDetail.Branch.Equals("UE4-UT")
                        select CrashDetail
                    );
            }

            // Filter by GameName
            if (!string.IsNullOrEmpty(FormData.GameName))
            {
                if (FormData.GameName.StartsWith("-"))
                {
                    results =
                        (
                            from CrashDetail in results
                            where !CrashDetail.GameName.Contains(FormData.GameName.Substring(1))
                            select CrashDetail
                        );
                }
                else
                {
                    results =
                        (
                            from CrashDetail in results
                            where CrashDetail.GameName.Contains(FormData.GameName)
                            select CrashDetail
                        );
                }
            }

            if (!string.IsNullOrEmpty(FormData.MessageQuery))
            {
                results =
                    (
                        from CrashDetail in results
                        where SqlMethods.Like(CrashDetail.Summary, "%" + FormData.MessageQuery + "%")
                        select CrashDetail
                    );
            }

            if (!string.IsNullOrEmpty(FormData.DescriptionQuery))
            {
                results =
                    (
                        from CrashDetail in results
                        where SqlMethods.Like(CrashDetail.Description, "%" + FormData.DescriptionQuery + "%")
                        select CrashDetail
                    );
            }

            if (!string.IsNullOrEmpty(FormData.SearchQuery))
            {
                results =
                    (
                        from CrashDetail in results
                        where SqlMethods.Like(CrashDetail.RawCallStack, "%" + FormData.SearchQuery + "%")
                        select CrashDetail
                    );
            }

            return(results);
        }
Пример #11
0
        /// <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( "" );
                }

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

                    // <STATUS>
                }

                // 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();
                }

                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 );
            }
        }
Пример #12
0
        /// <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));
            }
        }
Пример #13
0
        /// <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 );
            }
        }