public void Submit(FBApi api, Mapping target)
        {
            Log.Verbose(LogCategory, "Submitting new or updated error information to server", null);

            // Start by looking for the fingerprint to decide whether we need
            // to create an new case or update an existing one.
            Dictionary<string, string> args = new Dictionary<string, string>
                           {
                               {"sScoutDescription", Error.Fingerprint},
                           };

            string results = api.Cmd("listScoutCase", args);
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(results);
            XmlNode caseNode = xml.SelectSingleNode("/response/case/ixBug");

            if (caseNode == null)
            {
                Log.Information(LogCategory, "Submitting as new issue because no existing Scout Case could be found with the fingerprint", "Fingerprint: {0}\r\n\r\nRaw Result:\r\n{1}", Error.Fingerprint, results);
                SubmitNew(api, target);
            }
            else
            {
                Log.Information(LogCategory, "Submitting as an update because an existing Scout Case matched the fingerprint", "Fingerprint: {0}\r\n\r\nRaw Result:\r\n{1}", Error.Fingerprint, results);
                SubmitUpdate(api, caseNode.InnerText);
            }
        }
示例#2
0
        public void Submit(FBApi api, Mapping target)
        {
            Log.Verbose(LogCategory, "Submitting new or updated error information to server", null);

            // Start by looking for the fingerprint to decide whether we need
            // to create an new case or update an existing one.
            Dictionary <string, string> args = new Dictionary <string, string>
            {
                { "sScoutDescription", Error.Fingerprint },
            };

            string      results = api.Cmd("listScoutCase", args);
            XmlDocument xml     = new XmlDocument();

            xml.LoadXml(results);
            XmlNode caseNode = xml.SelectSingleNode("/response/case/ixBug");

            if (caseNode == null)
            {
                Log.Information(LogCategory, "Submitting as new issue because no existing Scout Case could be found with the fingerprint", "Fingerprint: {0}\r\n\r\nRaw Result:\r\n{1}", Error.Fingerprint, results);
                SubmitNew(api, target);
            }
            else
            {
                Log.Information(LogCategory, "Submitting as an update because an existing Scout Case matched the fingerprint", "Fingerprint: {0}\r\n\r\nRaw Result:\r\n{1}", Error.Fingerprint, results);
                SubmitUpdate(api, caseNode.InnerText);
            }
        }
        /// <summary>
        /// Load a list of FogBugz cases matching the filter string
        /// </summary>
        /// <param name="api">api is created by FBApi</param>
        /// <param name="filter">The filter string is created by FogBugzFilter</param>
        public void Load(FBApi api, string filter)
        {
            string query = "tag:Gibraltar " + filter;

            Dictionary<string, string> queryArgs = new Dictionary<string, string>
                                {
                                    {"q", query},
                                    {"cols", "ixBug,sTitle,fOpen,sStatus,dtLastUpdated,events"}
                                };

            // Get the list of candidate FogBugz cases
            string queryResults = api.Cmd("search", queryArgs);
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(queryResults);
            XmlNodeList caseList = xml.SelectNodes("/response/cases/case");
            if (caseList == null)
                return;

            Cases = new List<FogBugzCaseInfo>();

            foreach (XmlNode caseNode in caseList)
            {
                // It shouldn't happen that no events exist, but, if so, ignore that case
                XmlNodeList eventList = caseNode.SelectNodes("./events/event/s");
                if (eventList == null)
                    continue;

                FogBugzCaseInfo caseInfo = new FogBugzCaseInfo(caseNode);

                // Search every event
                foreach (XmlNode eventNode in eventList)
                {
                    // Search every line of each event looking for session guids
                    string text = eventNode.InnerText;
                    string[] lines = text.Split('\n');
                    foreach (string line in lines)
                    {
                        if (line.StartsWith(LogMessageFormatter.SessionIdPrefix))
                        {
                            string sessionId = line.Substring(LogMessageFormatter.SessionIdPrefix.Length);
                            Guid guid = new Guid(sessionId);
                            if (!caseInfo.Sessions.Contains(guid))
                                caseInfo.Sessions.Add(guid);
                        }
                    }
                }

                if (caseInfo.Sessions.Count > 0)
                    Cases.Add(caseInfo);
            }

            // Sort in descending case id order with the default entry at the top of the list
            Cases.Sort((c1, c2) => c2.CaseId - c1.CaseId);
        }
        private string GetCaseId(FBApi api)
        {
            Dictionary <string, string> args = new Dictionary <string, string>
            {
                { "sScoutDescription", m_Fingerprint },
            };
            string      results = api.Cmd("listScoutCase", args);
            XmlDocument xml     = new XmlDocument();

            xml.LoadXml(results);

            XmlNode caseNode = xml.SelectSingleNode("/response/case/ixBug");

            string caseId = caseNode != null ? caseNode.InnerText : null;

            m_Context.Log.Verbose(LogCategory, "Completed Case Id Lookup", "Looking for fingerprint: {0}\r\nParsed Id: {1}\r\n\r\nRaw Return:\r\n{2}", m_Fingerprint, caseId ?? "(null)", results);
            return(caseId);
        }
        /// <summary>
        /// Create a new case with all available details about the error
        /// </summary>
        private void SubmitNew(FBApi api, Mapping target)
        {
            LogMessageFormatter formatter = new LogMessageFormatter(FirstMessage);
            Dictionary<string, string> args = new Dictionary<string, string>
                            {
                                {"sScoutDescription", Error.Fingerprint},
                                {"sProject", target.Project},
                                {"sArea", target.Area},
                                {"ixPriority", target.Priority.ToString()},
                                {"sTitle", formatter.GetTitle()},
                                {"sVersion", Session.Summary.ApplicationVersion.ToString()},
                                {"sEvent", formatter.GetNewEvent(Error)},
                                {"sTags", formatter.GetTags()},
                            };

            string results = api.Cmd("new", args);

            // TODO: Should check for errors here
            Log.Information(LogCategory, "Completed new issue submission", "Scout Description: {0}\r\nProject: {1}\r\nArea: {2}\r\nRaw result: {3}",Error.Fingerprint, target.Project, target.Area, results);
        }
示例#6
0
        /// <summary>
        /// Create a new case with all available details about the error
        /// </summary>
        private void SubmitNew(FBApi api, Mapping target)
        {
            LogMessageFormatter         formatter = new LogMessageFormatter(FirstMessage);
            Dictionary <string, string> args      = new Dictionary <string, string>
            {
                { "sScoutDescription", Error.Fingerprint },
                { "sProject", target.Project },
                { "sArea", target.Area },
                { "ixPriority", target.Priority.ToString() },
                { "sTitle", formatter.GetTitle() },
                { "sVersion", Session.Summary.ApplicationVersion.ToString() },
                { "sEvent", formatter.GetNewEvent(Error) },
                { "sTags", formatter.GetTags() },
            };

            string results = api.Cmd("new", args);

            // TODO: Should check for errors here
            Log.Information(LogCategory, "Completed new issue submission", "Scout Description: {0}\r\nProject: {1}\r\nArea: {2}\r\nRaw result: {3}", Error.Fingerprint, target.Project, target.Area, results);
        }
        /// <summary>
        /// Add or update a FogBugz case
        /// </summary>
        private void Submit(FBApi api)
        {
            // Whether we're adding or updating a case, we'll want to update the
            // title and add an event description that includes our session id.
            // Appending session id ensures that this session is associated
            // with this case.  We append it here after the user is done
            // editing to prevent the user from mangling our guid which would
            // break our ability to do session lookups.
            string text = string.Format("{0}\r\n{1}\r\n",
                                        DescriptionTextBox.Text,
                                        m_SessionIdMessage);

            Dictionary <string, string> args = new Dictionary <string, string>
            {
                { "sTitle", TitleTextBox.Text },
                { "sEvent", text }
            };

            m_Context.Log.Information(LogCategory, "User is submitting new / updated case", "Title: {0}\r\n\r\nEvent: {1}", TitleTextBox.Text, text);

            string results;

            // Create or update a case depending on whether we have a case id
            if (CaseLabel.Tag == null)
            {
                // We only provide project, tags and fingerprint when creating a new case
                args.Add("sProject", ProjectSelection.Text);
                args.Add("sTags", "Gibraltar");
                args.Add("sScoutDescription", m_Fingerprint);
                results = api.Cmd("new", args);
            }
            else
            {
                // When updating an existing case, we must provide the case id
                args.Add("ixBug", CaseLabel.Text);
                results = api.Cmd("edit", args);
            }

            m_Context.Log.Verbose(LogCategory, "Case submission completed", "Result from server:\r\n{0}", results);
        }
        /// <summary>
        /// Load the FB data asynchronously
        /// </summary>
        /// <param name="state"></param>
        private void AsyncInitializeData(object state)
        {
            try //we're on the thread pool so if we don't catch the exception, it's terminal to the application
            {
                //unbundle the state
                FBApi api = (FBApi)state;

                //make our FB calls
                m_ProjectsAndAreas = api.ListProjectsAndAreas();
                string caseId = GetCaseId(api);

                // If a case already exists, get info about it from FogBugz
                string projectName = null, areaName = null;
                if (string.IsNullOrEmpty(caseId) == false)
                {
                    Dictionary <string, string> queryArgs = new Dictionary <string, string>
                    {
                        { "q", caseId },
                        { "cols", "sProject,sArea,sStatus" }
                    };

                    string      queryResults = api.Cmd("search", queryArgs);
                    XmlDocument xml          = new XmlDocument();
                    xml.LoadXml(queryResults);
                    XmlNode projectNode = xml.SelectSingleNode("/response/cases/case/sProject");
                    projectName = projectNode.InnerText;

                    XmlNode areaNode = xml.SelectSingleNode("/response/cases/case/sArea");
                    areaName = areaNode.InnerText;
                }

                ThreadSafeDisplayDefect(caseId, projectName, areaName);
            }
            catch (Exception)
            {
            }
        }
        /// <summary>
        /// Process a user's Add Defect request
        /// </summary>
        public DialogResult AddDefect(IRepositoryContext context, IList<ILogMessage> messages, RepositoryController controller, FBApi api)
        {
            // It shouldn't happen that we get called with no messages selected,
            // but check for it anyway.
            if (messages.Count <= 0)
                return DialogResult.Cancel;

            UseWaitCursor = true;

            //store off our initial state
            m_Context = context;
            m_Controller = controller;
            m_LogMessages = messages;
            int lastMessageIndex = messages.Count - 1;
            m_PrimaryMessage = messages[lastMessageIndex];
            ErrorInfo errorInfo = new ErrorInfo(m_PrimaryMessage);
            m_Fingerprint = errorInfo.Fingerprint;

            //Blank our display
            ClearDisplay();

            //now go to the background to initialize it
            ThreadPool.QueueUserWorkItem(AsyncInitializeData, api);

            DialogResult result = ShowDialog();
            if (result == DialogResult.OK)
            {
                Submit(api);
            }
            else
            {
                m_Context.Log.Verbose(LogCategory, "User canceled dialog, no changes will be submitted", null);
            }

            return DialogResult;
        }
        internal FBApi GetApi()
        {
            string url = m_CommonConfig.Url;
            string userName, password;
            if (m_Context.Environment == LoupeEnvironment.Server)
            {
                m_Context.Configuration.GetServerCredentials(ServerCredentialsKey, out userName, out password);
            }
            else
            {
                m_Context.Configuration.GetUserCredentials(ServerCredentialsKey, out userName, out password);
            }

            if (string.IsNullOrEmpty(url))
            {
                throw new InvalidOperationException("No FogBugz server URL has been configured to connect to.");
            }

            if (string.IsNullOrEmpty(userName))
            {
                throw new InvalidOperationException(string.Format("No account has been provided to connect to FogBugz with.  Please configure a {0} account.",
                    (m_Context.Environment == LoupeEnvironment.Server) ? "server" : "personal"));
            }

            // Throw an exception if we can't connect with FogBugz
            FBApi api;
            try
            {
                m_Context.Log.Verbose(LogCategory, "Connecting to FogBugz Server", "Server URL: {0}\r\nUser Name: {1}", url, userName);
                api = new FBApi(url, userName, password);
            }
            catch (Exception ex)
            {
                m_Context.Log.Error(ex, LogCategory, "Failed to connect to FogBugz Server", "Server URL: {0}\r\nUser Name: {1}\r\nException: {2}", url, userName, ex.Message);
                throw new ApplicationException("Could not contact FogBugz Server", ex);
            }

            return api;
        }
示例#11
0
 public XmlDocument XUnsubscribe(int ixBug, int ixWikiPage)
 {
     return(FBApi.DocFromXml(Unsubscribe(ixBug, ixWikiPage)));
 }
示例#12
0
 public XmlDocument XView(int ixBug)
 {
     return(FBApi.DocFromXml(View(ixBug)));
 }
示例#13
0
 public XmlNodeList XListIntervals(DateTime dtStart, DateTime dtEnd)
 {
     return(FBApi.DocFromXml(ListIntervals(dtStart, dtEnd)).GetElementsByTagName("interval"));
 }
示例#14
0
 public XmlNodeList XListIntervals(DateTime dtStart, DateTime dtEnd, int ixBug)
 {
     return(FBApi.DocFromXml(ListIntervals(dtStart, dtEnd)).SelectNodes(String.Format("/response/intervals/interval[ixBug='{0}']", ixBug)));
 }
示例#15
0
        private string GetCaseId(FBApi api)
        {
            Dictionary<string, string> args = new Dictionary<string, string>
                           {
                               {"sScoutDescription", m_Fingerprint},

                           };
            string results = api.Cmd("listScoutCase", args);
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(results);

            XmlNode caseNode = xml.SelectSingleNode("/response/case/ixBug");

            string caseId = caseNode != null ? caseNode.InnerText : null;
            m_Context.Log.Verbose(LogCategory, "Completed Case Id Lookup", "Looking for fingerprint: {0}\r\nParsed Id: {1}\r\n\r\nRaw Return:\r\n{2}", m_Fingerprint, caseId ?? "(null)", results);
            return caseId;
        }
        /// <summary>
        /// Load a list of FogBugz cases matching the filter string
        /// </summary>
        /// <param name="api">api is created by FBApi</param>
        /// <param name="filter">The filter string is created by FogBugzFilter</param>
        public void Load(FBApi api, string filter)
        {
            string query = "tag:Gibraltar " + filter;

            Dictionary <string, string> queryArgs = new Dictionary <string, string>
            {
                { "q", query },
                { "cols", "ixBug,sTitle,fOpen,sStatus,dtLastUpdated,events" }
            };

            // Get the list of candidate FogBugz cases
            string      queryResults = api.Cmd("search", queryArgs);
            XmlDocument xml          = new XmlDocument();

            xml.LoadXml(queryResults);
            XmlNodeList caseList = xml.SelectNodes("/response/cases/case");

            if (caseList == null)
            {
                return;
            }

            Cases = new List <FogBugzCaseInfo>();

            foreach (XmlNode caseNode in caseList)
            {
                // It shouldn't happen that no events exist, but, if so, ignore that case
                XmlNodeList eventList = caseNode.SelectNodes("./events/event/s");
                if (eventList == null)
                {
                    continue;
                }

                FogBugzCaseInfo caseInfo = new FogBugzCaseInfo(caseNode);

                // Search every event
                foreach (XmlNode eventNode in eventList)
                {
                    // Search every line of each event looking for session guids
                    string   text  = eventNode.InnerText;
                    string[] lines = text.Split('\n');
                    foreach (string line in lines)
                    {
                        if (line.StartsWith(LogMessageFormatter.SessionIdPrefix))
                        {
                            string sessionId = line.Substring(LogMessageFormatter.SessionIdPrefix.Length);
                            Guid   guid      = new Guid(sessionId);
                            if (!caseInfo.Sessions.Contains(guid))
                            {
                                caseInfo.Sessions.Add(guid);
                            }
                        }
                    }
                }

                if (caseInfo.Sessions.Count > 0)
                {
                    Cases.Add(caseInfo);
                }
            }

            // Sort in descending case id order with the default entry at the top of the list
            Cases.Sort((c1, c2) => c2.CaseId - c1.CaseId);
        }
示例#17
0
 public XmlNodeList XListFixFors(int ixProject)
 {
     return(FBApi.DocFromXml(ListFixFors(ixProject)).SelectNodes("/response/fixfors/fixfor"));
 }
示例#18
0
 public XmlDocument XStartWork(int ixBug)
 {
     return(FBApi.DocFromXml(StartWork(ixBug)));
 }
示例#19
0
        /// <summary>
        /// Update an existing case
        /// </summary>
        private void SubmitUpdate(FBApi api, string caseId)
        {
            Dictionary <string, string> queryArgs = new Dictionary <string, string>
            {
                { "q", caseId },
                { "cols", "sVersion,tags,events" }
            };

            string queryResults = api.Cmd("search", queryArgs);

            Log.Verbose(LogCategory, "Retrieved existing issue information from server", "Query Results:\r\n{0}", queryResults);

            XmlDocument xml = new XmlDocument();

            xml.LoadXml(queryResults);
            XmlNodeList eventList        = xml.GetElementsByTagName("s");
            string      sessionIdMessage = new LogMessageFormatter(FirstMessage).GetSessionIdMessage();

            // If this case already references this session, we're done
            foreach (XmlNode node in eventList)
            {
                if (node.InnerText.Contains(sessionIdMessage))
                {
                    return;
                }
            }

            LogMessageFormatter         formatter  = new LogMessageFormatter(FirstMessage);
            Dictionary <string, string> updateArgs = new Dictionary <string, string>
            {
                { "sScoutDescription", Error.Fingerprint },
            };

            // Compare the version of the current session with the session associated with the case.
            // The version in FogBugz is the high watermark (highest version seen to-date).
            // If this session if for a
            XmlNode versionNode     = xml.SelectSingleNode("//sVersion");
            Version previousVersion = new Version(versionNode.InnerText);

            if (Session.Summary.ApplicationVersion > previousVersion)
            {
                // If this is a new version, update the high watermark and write
                // a detailed description.
                updateArgs.Add("sVersion", Session.Summary.ApplicationVersion.ToString());
                updateArgs.Add("sEvent", formatter.GetRecurrenceLaterVersionEvent(Error));
                Log.Verbose(LogCategory, "Updating latest version information on existing issue", "This new instance has a higher version number than any previous occurrence so we'll update the high water mark on the server.\r\nPrevious Version: {0}\r\nThis Version: {1}", previousVersion, Session.Summary.ApplicationVersion);
            }
            else if (Session.Summary.ApplicationVersion == previousVersion)
            {
                // If this is another instance of the same version, write a short update
                updateArgs.Add("sEvent", formatter.GetRecurrenceSameVersionEvent(Error));
            }
            else
            {
                // If the version of this session is earlier, ignore this session.
                Log.Information(LogCategory, "Skipping reporting new occurrence of issue because its from an old version", "This new instance has a lower version number than one or more previous occurrences, so we wont report it.\r\nPrevious Version: {0}\r\nThis Version: {1}", previousVersion, Session.Summary.ApplicationVersion);
                return;
            }

            // We use the "new" command rather than "edit" because FogBugz has the
            // smarts to reactivate closed cases with scout descriptions.
            string results = api.Cmd("new", updateArgs);

            // TODO: Should check for errors here
            Log.Information(LogCategory, "Completed issue update submission", "Scout Description: {0}\r\nRaw result: {1}", Error.Fingerprint, results);
        }
示例#20
0
 public XmlNodeList XListCategories()
 {
     return(FBApi.DocFromXml(ListCategories()).SelectNodes("/response/categories/category"));
 }
示例#21
0
 public XmlNodeList XSearch(string q, string cols, int max)
 {
     return(FBApi.DocFromXml(Search(q, cols, max)).SelectNodes("/response/cases/case"));
 }
        /// <summary>
        /// Update an existing case
        /// </summary>
        private void SubmitUpdate(FBApi api, string caseId)
        {
            Dictionary<string, string> queryArgs = new Dictionary<string, string>
                                    {
                                        {"q", caseId},
                                        {"cols", "sVersion,tags,events"}
                                    };

            string queryResults = api.Cmd("search", queryArgs);
            Log.Verbose(LogCategory, "Retrieved existing issue information from server", "Query Results:\r\n{0}", queryResults);

            XmlDocument xml = new XmlDocument();
            xml.LoadXml(queryResults);
            XmlNodeList eventList = xml.GetElementsByTagName("s");
            string sessionIdMessage = new LogMessageFormatter(FirstMessage).GetSessionIdMessage();

            // If this case already references this session, we're done
            foreach (XmlNode node in eventList)
            {
                if (node.InnerText.Contains(sessionIdMessage))
                    return;
            }

            LogMessageFormatter formatter = new LogMessageFormatter(FirstMessage);
            Dictionary<string, string> updateArgs = new Dictionary<string, string>
                                 {
                                     {"sScoutDescription", Error.Fingerprint},
                                 };

            // Compare the version of the current session with the session associated with the case.
            // The version in FogBugz is the high watermark (highest version seen to-date).
            // If this session if for a 
            XmlNode versionNode = xml.SelectSingleNode("//sVersion");
            Version previousVersion = new Version(versionNode.InnerText);
            if (Session.Summary.ApplicationVersion > previousVersion)
            {
                // If this is a new version, update the high watermark and write
                // a detailed description.
                updateArgs.Add("sVersion", Session.Summary.ApplicationVersion.ToString());
                updateArgs.Add("sEvent", formatter.GetRecurrenceLaterVersionEvent(Error));
                Log.Verbose(LogCategory, "Updating latest version information on existing issue", "This new instance has a higher version number than any previous occurrence so we'll update the high water mark on the server.\r\nPrevious Version: {0}\r\nThis Version: {1}", previousVersion, Session.Summary.ApplicationVersion);
            }
            else if (Session.Summary.ApplicationVersion == previousVersion)
            {
                // If this is another instance of the same version, write a short update
                updateArgs.Add("sEvent", formatter.GetRecurrenceSameVersionEvent(Error));
            }
            else
            {
                // If the version of this session is earlier, ignore this session.
                Log.Information(LogCategory, "Skipping reporting new occurrence of issue because its from an old version", "This new instance has a lower version number than one or more previous occurrences, so we wont report it.\r\nPrevious Version: {0}\r\nThis Version: {1}", previousVersion, Session.Summary.ApplicationVersion);
                return;
            }

            // We use the "new" command rather than "edit" because FogBugz has the
            // smarts to reactivate closed cases with scout descriptions.
            string results = api.Cmd("new", updateArgs);

            // TODO: Should check for errors here
            Log.Information(LogCategory, "Completed issue update submission", "Scout Description: {0}\r\nRaw result: {1}", Error.Fingerprint, results);
        }
        private void Load(FBApi api, int caseId)
        {
            Dictionary<string, string> queryArgs = new Dictionary<string, string>
                                {
                                    {"q", caseId.ToString()},
                                    {"cols", "ixBug,sTitle,sProject,sArea,sStatus,sPriority,events"}
                                };

            // Get the list of candidate FogBugz cases
            string queryResults = api.Cmd("search", queryArgs);
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(queryResults);
            XmlNodeList caseList = xml.SelectNodes("/response/cases/case");

            CaseId = caseId;
            Project = string.Empty;
            Area = string.Empty;
            Status = string.Empty;
            Priority = string.Empty;
            LastUpdated = DateTime.MinValue;
            SessionIds = new List<Guid>();

            if (caseList == null || caseList.Count <= 0)
                return;

            XmlNode caseNode = caseList[0];
            // It shouldn't happen that no events exist, but, if so, ignore that case
            XmlNodeList eventList = caseNode.SelectNodes("./events/event");
            if (eventList == null || eventList.Count <= 0)
                return;

            Project = caseNode.SelectSingleNode("./sProject").InnerText;
            Area = caseNode.SelectSingleNode("./sArea").InnerText;
            Title = caseNode.SelectSingleNode("./sTitle").InnerText;
            Status = caseNode.SelectSingleNode("./sStatus").InnerText;
            Priority = caseNode.SelectSingleNode("./sPriority").InnerText;

            XmlNode lastEvent = eventList[eventList.Count - 1];
            LastUpdated = DateTime.Parse(lastEvent.SelectSingleNode("./dt").InnerText);
            LastUpdatedBy = lastEvent.SelectSingleNode("./sVerb").InnerText;

            foreach (XmlNode eventNode in eventList)
            {
                string text = eventNode.SelectSingleNode("./s").InnerText;

                // Skip events with no text change
                if (string.IsNullOrEmpty(text))
                    continue;

                // Avoid showing SessionIdPrefix
                string rawText = eventNode.SelectSingleNode("./s").InnerText;
                int maxLength = rawText.LastIndexOf(LogMessageFormatter.SessionIdPrefix);
                LatestSummary = maxLength > 0 ? rawText.Substring(0, maxLength) : rawText;

                string[] lines = text.Split('\n');
                foreach (string line in lines)
                {
                    if (line.StartsWith(LogMessageFormatter.SessionIdPrefix))
                    {
                        string sessionId = line.Substring(LogMessageFormatter.SessionIdPrefix.Length);
                        Guid guid = new Guid(sessionId);
                        if (!SessionIds.Contains(guid))
                            SessionIds.Add(guid);
                    }
                }
            }
        }
        private void Load(FBApi api, int caseId)
        {
            Dictionary <string, string> queryArgs = new Dictionary <string, string>
            {
                { "q", caseId.ToString() },
                { "cols", "ixBug,sTitle,sProject,sArea,sStatus,sPriority,events" }
            };

            // Get the list of candidate FogBugz cases
            string      queryResults = api.Cmd("search", queryArgs);
            XmlDocument xml          = new XmlDocument();

            xml.LoadXml(queryResults);
            XmlNodeList caseList = xml.SelectNodes("/response/cases/case");

            CaseId      = caseId;
            Project     = string.Empty;
            Area        = string.Empty;
            Status      = string.Empty;
            Priority    = string.Empty;
            LastUpdated = DateTime.MinValue;
            SessionIds  = new List <Guid>();

            if (caseList == null || caseList.Count <= 0)
            {
                return;
            }

            XmlNode caseNode = caseList[0];
            // It shouldn't happen that no events exist, but, if so, ignore that case
            XmlNodeList eventList = caseNode.SelectNodes("./events/event");

            if (eventList == null || eventList.Count <= 0)
            {
                return;
            }

            Project  = caseNode.SelectSingleNode("./sProject").InnerText;
            Area     = caseNode.SelectSingleNode("./sArea").InnerText;
            Title    = caseNode.SelectSingleNode("./sTitle").InnerText;
            Status   = caseNode.SelectSingleNode("./sStatus").InnerText;
            Priority = caseNode.SelectSingleNode("./sPriority").InnerText;

            XmlNode lastEvent = eventList[eventList.Count - 1];

            LastUpdated   = DateTime.Parse(lastEvent.SelectSingleNode("./dt").InnerText);
            LastUpdatedBy = lastEvent.SelectSingleNode("./sVerb").InnerText;

            foreach (XmlNode eventNode in eventList)
            {
                string text = eventNode.SelectSingleNode("./s").InnerText;

                // Skip events with no text change
                if (string.IsNullOrEmpty(text))
                {
                    continue;
                }

                // Avoid showing SessionIdPrefix
                string rawText   = eventNode.SelectSingleNode("./s").InnerText;
                int    maxLength = rawText.LastIndexOf(LogMessageFormatter.SessionIdPrefix);
                LatestSummary = maxLength > 0 ? rawText.Substring(0, maxLength) : rawText;

                string[] lines = text.Split('\n');
                foreach (string line in lines)
                {
                    if (line.StartsWith(LogMessageFormatter.SessionIdPrefix))
                    {
                        string sessionId = line.Substring(LogMessageFormatter.SessionIdPrefix.Length);
                        Guid   guid      = new Guid(sessionId);
                        if (!SessionIds.Contains(guid))
                        {
                            SessionIds.Add(guid);
                        }
                    }
                }
            }
        }
示例#25
0
 public XmlDocument XStopWork()
 {
     return(FBApi.DocFromXml(StopWork()));
 }
示例#26
0
        /// <summary>
        /// Add or update a FogBugz case
        /// </summary>
        private void Submit(FBApi api)
        {
            // Whether we're adding or updating a case, we'll want to update the
            // title and add an event description that includes our session id.
            // Appending session id ensures that this session is associated
            // with this case.  We append it here after the user is done
            // editing to prevent the user from mangling our guid which would
            // break our ability to do session lookups.
            string text = string.Format("{0}\r\n{1}\r\n",
                                     DescriptionTextBox.Text,
                                     m_SessionIdMessage);

            Dictionary<string, string> args = new Dictionary<string, string>
                            {
                                {"sTitle", TitleTextBox.Text},
                                {"sEvent", text}
                            };

            m_Context.Log.Information(LogCategory, "User is submitting new / updated case", "Title: {0}\r\n\r\nEvent: {1}", TitleTextBox.Text, text);

            string results;

            // Create or update a case depending on whether we have a case id
            if (CaseLabel.Tag == null)
            {
                // We only provide project, tags and fingerprint when creating a new case
                args.Add("sProject", ProjectSelection.Text);
                args.Add("sTags", "Gibraltar");
                args.Add("sScoutDescription", m_Fingerprint);
                results = api.Cmd("new", args);
            }
            else
            {
                // When updating an existing case, we must provide the case id
                args.Add("ixBug", CaseLabel.Text);
                results = api.Cmd("edit", args);
            }

            m_Context.Log.Verbose(LogCategory, "Case submission completed", "Result from server:\r\n{0}", results);
        }
示例#27
0
 public XmlDocument XNewInterval(int ixBug, DateTime dtStart, DateTime dtEnd)
 {
     return(FBApi.DocFromXml(NewInterval(ixBug, dtStart, dtEnd)));
 }
示例#28
0
 public XmlNodeList XListProjects(bool onlyWritable)
 {
     return(FBApi.DocFromXml(ListProjects(onlyWritable)).SelectNodes("/response/projects/project"));
 }
        /// <summary>
        /// Process a user's Add Defect request
        /// </summary>
        public DialogResult AddDefect(IRepositoryContext context, IList <ILogMessage> messages, RepositoryController controller, FBApi api)
        {
            // It shouldn't happen that we get called with no messages selected,
            // but check for it anyway.
            if (messages.Count <= 0)
            {
                return(DialogResult.Cancel);
            }

            UseWaitCursor = true;

            //store off our initial state
            m_Context     = context;
            m_Controller  = controller;
            m_LogMessages = messages;
            int lastMessageIndex = messages.Count - 1;

            m_PrimaryMessage = messages[lastMessageIndex];
            ErrorInfo errorInfo = new ErrorInfo(m_PrimaryMessage);

            m_Fingerprint = errorInfo.Fingerprint;

            //Blank our display
            ClearDisplay();

            //now go to the background to initialize it
            ThreadPool.QueueUserWorkItem(AsyncInitializeData, api);

            DialogResult result = ShowDialog();

            if (result == DialogResult.OK)
            {
                Submit(api);
            }
            else
            {
                m_Context.Log.Verbose(LogCategory, "User canceled dialog, no changes will be submitted", null);
            }

            return(DialogResult);
        }