{"action":"created","comment":{"url":"https://api.github.com/repos/mantidproject/mantid/pulls/comments/79413902","id":79413902,"diff_hunk":"@@ -193,345 +207,475 @@ void EnggDiffFittingPresenter::fittingFinished() {\n // Fitting Tab Run Number & Bank handling here\n void EnggDiffFittingPresenter::fittingRunNoChanged() {\n \n-  try {\n-\n-    // receive the run number from the text-field\n-    auto strFocusedFile = m_view->getFittingRunNo();\n+  // receive the run number from the text-field\n+  const std::string userPathInput = m_view->getFittingRunNo();\n \n-    if (m_previousInput == strFocusedFile) {\n-      // Short circuit the checks and skip any warnings\n-      // or errors as the user has not changed anything\n-      // just clicked the box. Additionally this resolves an\n-      // issue where QT will return the cursor and produce a new\n-      // warning when the current warning is closed\n-      return;\n-    } else {\n-      m_previousInput = strFocusedFile;\n-    }\n-\n-    // file name\n-    Poco::Path selectedfPath(strFocusedFile);\n-    Poco::Path bankDir;\n+  if (m_previousInput == userPathInput || userPathInput.empty()) {\n+    // Short circuit the checks and skip any warnings\n+    // or errors as the user has not changed anything\n+    // just clicked the box. Additionally this resolves an\n+    // issue where QT will return the cursor and produce a new\n+    // warning when the current warning is closed\n+    return;\n+  } else {\n+    m_previousInput = userPathInput;\n+  }\n \n-    std::vector<std::string> runnoDirVector;\n+  // file name\n+  const Poco::Path pocoUserPathInput(userPathInput);\n \n-    std::string strFPath = selectedfPath.toString();\n-    // returns empty if no directory is found\n+  std::vector<std::string> foundFullFilePaths;\n \n-    // split directory if 'ENGINX_' found by '_.'\n-    std::vector<std::string> splitBaseName;\n-    if (strFPath.find(\"ENGINX_\") != std::string::npos) {\n-      boost::split(splitBaseName, strFPath, boost::is_any_of(\"_.\"));\n-    }\n+  // returns empty if no directory is found\n+  const std::string parsedUserInput = pocoUserPathInput.toString();\n \n-    // runNo when single focused file selected\n-    std::vector<std::string> runNoVec;\n+  // split directory if 'ENGINX_' found by '_.'\n+  std::vector<std::string> splitBaseName;\n+  if (parsedUserInput.find(\"ENGINX_\") != std::string::npos) {\n+    boost::split(splitBaseName, parsedUserInput, boost::is_any_of(\"_.\"));\n+  }\n \n+  try {\n     // if input file is a directory and successfully splitBaseName\n     // or when default bank is set or changed, the text-field is updated with\n     // selected bank directory which would trigger this function again\n-    if (selectedfPath.isFile() && !splitBaseName.empty()) {\n-\n-#ifdef __unix__\n-      bankDir = selectedfPath.parent();\n-#else\n-      bankDir = (bankDir).expand(selectedfPath.parent().toString());\n-#endif\n-      // if vector is not empty and correct focus format file is selected\n-      if (!splitBaseName.empty() && splitBaseName.size() > 3) {\n+    if (pocoUserPathInput.isFile() && !splitBaseName.empty()) {\n+      foundFullFilePaths =\n+          processFullPathInput(pocoUserPathInput, splitBaseName);\n+      // if given a multi-run\n+    } else if (userPathInput.find(\"-\") != std::string::npos) {\n+      foundFullFilePaths = processMultiRun(userPathInput);\n+      // try to process using single run\n+    } else {\n+      foundFullFilePaths = processSingleRun(userPathInput, splitBaseName);\n+    }\n+  } catch (std::invalid_argument &ia) {\n+    // If something went wrong stop and print error only\n+    g_log.error(\"Failed to process user input. Error was: \");\n+    g_log.error(ia.what());\n+    return;\n+  }\n \n-        std::string bankFileDir = bankDir.toString();\n+  // if single or multi run-number\n+  // set the text-field to directory here to the first in\n+  // the vector if its not empty\n+  if (foundFullFilePaths.empty()) {\n+    m_view->userWarning(\n+        \"Error finding file(s)\",\n+        \"Unable to find one or more files with a name matching the run\"\n+        \" number or range input. Please check the files are present in\"\n+        \" the focused output directory and the input is correct.\");\n+  } else if (!pocoUserPathInput.isFile()) {\n+    // foundFiles is not empty and this is a directory\n+    const std::string firstDir = foundFullFilePaths[0];\n+    m_view->setFittingRunNo(firstDir);\n+  }\n+}\n \n-        // browse the file\n-        browsedFile(strFocusedFile, runnoDirVector, splitBaseName, runNoVec,\n-                    bankFileDir);\n-      }\n-      // if given a multi-run OR single number\n-    } else if (strFocusedFile.size() > 4) {\n+/**\n+  * Verifies and uses the user input path (i.e. a browsed file)\n+  * to update drop down for available banks and various widgets on the GUI\n+  *\n+  * @param pocoFilePath The user entered file path as a Poco Path\n+  * @param splitBaseName The base file name split by the `_` delimiter\n+  *\n+  * @return The full file path as a vector of strings to make this\n+  * consistent with the other file processing methods\n+  */\n+std::vector<std::string> EnggDiffFittingPresenter::processFullPathInput(\n+    const Poco::Path &pocoFilePath,\n+    const std::vector<std::string> &splitBaseName) {\n \n-      // if multi-run number string finds '-' to define run number\n-      if (strFocusedFile.find(\"-\") != std::string::npos) {\n+  std::vector<std::string> foundRunNumbers;\n+  std::vector<std::string> foundFullFilePaths;\n \n-        // adds run number to list widget on right and changes text-field\n-        // to single run number and trigger FittingRunNo changed again\n-        processMultiRun(strFocusedFile, runnoDirVector);\n+  // Handle files the user browsed to separately\n+  try {\n+    foundRunNumbers =\n+        getAllBrowsedFilePaths(pocoFilePath.toString(), foundFullFilePaths);\n+  } catch (std::runtime_error &e) {\n+    const std::string eMsg(e.what());\n+    g_log.error(\"Error loading browsed file: \" + eMsg);\n \n-      } else {\n-        // true if string convertible to digit\n-        auto focusDir = m_view->focusingDir();\n-\n-        // if not valid parent dir and not valid single run number\n-        if (focusDir.empty()) {\n-          m_view->userWarning(\n-              \"Invalid Input\",\n-              \"Please check that a valid directory is \"\n-              \"set for Output Folder under Focusing Settings on the \"\n-              \"settings tab and the specified file is located within the \"\n-              \"folder. \");\n-\n-          m_view->enableFitAllButton(false);\n-        } else if (!isDigit(strFocusedFile)) {\n-\n-          m_view->userWarning(\"Invalid Run Number\",\n-                              \"Invalid format of run number has been entered. \"\n-                              \"Please try again\");\n-          m_view->enableFitAllButton(false);\n-        }\n+    m_view->userWarning(\n+        \"Run Number Not Found\",\n+        \"The run number specified could not be located \"\n+        \"in the focused output directory. Please check that the \"\n+        \"correct directory is set for Output Folder under Focusing Settings \"\n+        \"on the settings tab and that the input is correct\");\n+    // Bring it back to a known state of 0 found\n+    foundFullFilePaths.clear();\n+    return foundFullFilePaths;\n+  }\n \n-        // else - given or hard-coded to a single run number\n-        else {\n-          processSingleRun(focusDir, strFocusedFile, runnoDirVector,\n-                           splitBaseName);\n-        }\n-      }\n-    }\n+  // Update UI to reflect found files\n+  // Update the list of files found in the view\n+  m_view->setFittingRunNumVec(foundFullFilePaths);\n \n-    // if single or multi run-number\n-    // set the text-field to directory here to the first in\n-    // the vector if its not empty\n-    if (!runnoDirVector.empty() && !selectedfPath.isFile()) {\n+  const bool multiRunMode = m_view->getFittingMultiRunMode();\n+  const bool singleRunMode = m_view->getFittingSingleRunMode();\n+  // if not run mode or bank mode: to avoid recreating widgets\n+  if (!multiRunMode && !singleRunMode) {\n \n-      auto firstDir = runnoDirVector[0];\n-      m_view->setFittingRunNo(firstDir);\n+    // add bank to the combo-box\n+    setBankItems(foundFullFilePaths);\n+    // set the bank widget according to selected bank file\n+    setDefaultBank(splitBaseName, pocoFilePath.toString());\n \n-    } else if (m_view->getFittingRunNo().empty()) {\n-      m_view->userWarning(\"Invalid Input\",\n-                          \"Invalid directory or run number given. \"\n-                          \"Please try again\");\n-    }\n-\n-  } catch (std::runtime_error &re) {\n-    m_view->userWarning(\"Invalid file\",\n-                        \"Unable to select the file; \" +\n-                            static_cast<std::string>(re.what()));\n-    return;\n+    // Skips this step if it is multiple run because widget already\n+    // updated\n+    setRunNoItems(foundRunNumbers, false);\n   }\n+\n+  return foundFullFilePaths;\n }\n \n-void EnggDiffFittingPresenter::browsedFile(\n-    const std::string strFocusedFile, std::vector<std::string> &runnoDirVector,\n-    const std::vector<std::string> &splitBaseName,\n-    std::vector<std::string> &runNoVec, const std::string &bankFileDir) {\n+/**\n+  * Takes the full path of a file which has been selected through\n+  * browse, the run number the user has input and stores the\n+  * full file paths of all files (specifically all banks) associated\n+  * with that run number. Then updates the view to display all run\n+  * numbers for multi-runs\n+  *\n+  * @param inputFullPath The user inputted path in the view\n+  * @param foundFullFilePaths The full paths of all associated files found\n+  *\n+  * @return Vector of all run numbers for which a full file path was found\n+  */\n+std::vector<std::string> EnggDiffFittingPresenter::getAllBrowsedFilePaths(\n+    const std::string &inputFullPath,\n+    std::vector<std::string> &foundFullFilePaths) {\n   // to track the FittingRunnoChanged loop number\n   if (g_fitting_runno_counter == 0) {\n     g_multi_run_directories.clear();\n   }\n \n   g_fitting_runno_counter++;\n \n-  // regenerating the focus file name\n-  std::string foc_file = splitBaseName[0] + \"_\" + splitBaseName[1] + \"_\" +\n-                         splitBaseName[2] + \"_\" + splitBaseName[3];\n+  // Files take the form 'ENGINX_123456_focused_bank_1' so create\n+  // a string similar to 'ENGINX_123456_focused_bank' to allow us\n+  // to search for additional banks]\n+  const std::string baseName = getBaseNameFromStr(inputFullPath);\n+  const std::vector<std::string> splitBaseName =\n+      splitFittingDirectory(baseName);\n+\n+  // TODO look at removal of hard coded filename positions\n+  // Produced <INST>_<RunNumber>_focused for subsequent lookup\n+  const std::string baseFilenamePrefix =\n+      splitBaseName[0] + \"_\" + splitBaseName[1] + \"_\" + splitBaseName[2];\n+\n+  Poco::Path pocoFullFilePath;\n+  if (!pocoFullFilePath.tryParse(inputFullPath)) {\n+    // File path isn't valid\n+    m_view->userWarning(\"Bad file path entered\",\n+                        \"The entered file path could not \"\n+                        \" be opened. Please check the file and/or directory \"\n+                        \"exists.\");\n \n-  // if base directory of file is empty\n-  if (bankFileDir.empty()) {\n-    m_view->userWarning(\"Invalid Input\",\n-                        \"Please check that a valid directory is \"\n-                        \"set for Output Folder under Focusing Settings on the \"\n-                        \"settings tab. \"\n-                        \"Please try again\");\n-  } else {\n+    throw std::runtime_error(\n+        \"The file path entered could not be parsed\"\n+        \" this usually indicates a syntax error or bad path input\");\n+  }\n \n-    // foc_file - vector holding the file name split\n-    // runnoDirVector - giving empty vector here holding directory of\n-    // selected vector\n-    // dummy vector not being used in this case\n-    std::vector<std::string> dummy;\n-    updateFittingDirVec(bankFileDir, foc_file, runnoDirVector, dummy);\n-\n-    m_view->setFittingRunNumVec(runnoDirVector);\n-\n-    auto multiRunMode = m_view->getFittingMultiRunMode();\n-    auto singleRunMode = m_view->getFittingSingleRunMode();\n-    // if not run mode or bank mode: to avoid recreating widgets\n-    if (!multiRunMode && !singleRunMode) {\n-\n-      // add bank to the combo-box\n-      setBankItems();\n-      // set the bank widget according to selected bank file\n-      setDefaultBank(splitBaseName, strFocusedFile);\n-      runNoVec.clear();\n-      runNoVec.push_back(splitBaseName[1]);\n-\n-      // Skips this step if it is multiple run because widget already\n-      // updated\n-      setRunNoItems(runNoVec, false);\n-    }\n+  const std::string workingDirectory = pocoFullFilePath.parent().toString();\n+\n+  // Find all files which match this baseFilenamePrefix -\n+  // like a poor mans regular expression for files\n+  if (!findFilePathFromBaseName(workingDirectory, baseFilenamePrefix,\n+                                foundFullFilePaths)) {\n+    // I can't see this ever being thrown if the user is browsing to files but\n+    // better to be safe and give an informative message\n+    throw std::runtime_error(\"Could not find any files matching the generated\"\n+                             \" pattern: \" +\n+                             baseFilenamePrefix);\n   }\n+\n+  // Store the run number as found\n+  std::vector<std::string> runNoVec;\n+  runNoVec.push_back(splitBaseName[1]);\n+\n+  return runNoVec;\n }\n \n-void EnggDiffFittingPresenter::processMultiRun(\n-    const std::string strFocusedFile,\n-    std::vector<std::string> &runnoDirVector) {\n+/**\n+  * Processes a multi run input to the interface\n+  * such as '12345-12350' by splitting it into '12345' to '12350'\n+  * then calling enableMultiRun\n+  * @param userInput The user input from the view\n+  *\n+  * @return List of found full file paths for the files specified\n+  */\n+std::vector<std::string>\n+EnggDiffFittingPresenter::processMultiRun(const std::string userInput) {\n+\n+  // Split user input into the first and last run number\n   std::vector<std::string> firstLastRunNoVec;\n-  boost::split(firstLastRunNoVec, strFocusedFile, boost::is_any_of(\"-\"));\n+  boost::split(firstLastRunNoVec, userInput, boost::is_any_of(\"-\"));\n+\n+  // Then store them in their own strings\n   std::string firstRun;\n   std::string lastRun;\n   if (!firstLastRunNoVec.empty()) {\n     firstRun = firstLastRunNoVec[0];\n     lastRun = firstLastRunNoVec[1];\n \n     m_view->setFittingMultiRunMode(true);\n-    enableMultiRun(firstRun, lastRun, runnoDirVector);\n   }\n+  return enableMultiRun(firstRun, lastRun);\n }\n \n-void EnggDiffFittingPresenter::processSingleRun(\n-    const std::string &focusDir, const std::string &strFocusedFile,\n-    std::vector<std::string> &runnoDirVector,\n+std::vector<std::string> EnggDiffFittingPresenter::processSingleRun(\n+    const std::string &userInputBasename,\n     const std::vector<std::string> &splitBaseName) {\n \n+  std::string focusDir = m_view->focusingDir();\n+\n+  // Check there is a folder to search for this file\n+  // this will be changed to respect user directories as well later\n+  if (focusDir.empty()) {\n+    m_view->userWarning(\"Focus directory not set.\",\n+                        \"Please check that a valid directory is \"\n+                        \"set for Output Folder under Focusing Settings on the \"\n+                        \"settings tab. \"\n+                        \"Please try again\");\n+\n+    m_view->enableFitAllButton(false);\n+  }\n+\n+  // Next check input is a run number only as this is currently all\n+  // that we can handle\n+  if (userInputBasename.size() == 0 || !isDigit(userInputBasename)) {\n+\n+    m_view->userWarning(\"Invalid Run Number\",\n+                        \"Invalid format of run number has been entered. \"\n+                        \"Please try again\");","path":"MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffFittingPresenter.cpp","position":408,"original_position":408,"commit_id":"8b865ac1a1b15fdb4f4d086e0954b3fd19f7cf09","original_commit_id":"8b865ac1a1b15fdb4f4d086e0954b3fd19f7cf09","user":{"login":"FedeMPouzols","id":5257172,"avatar_url":"https://avatars.githubusercontent.com/u/5257172?v=3","gravatar_id":"","url":"https://api.github.com/users/FedeMPouzols","html_url":"https://github.com/FedeMPouzols","followers_url":"https://api.github.com/users/FedeMPouzols/followers","following_url":"https://api.github.com/users/FedeMPouzols/following{/other_user}","gists_url":"https://api.github.com/users/FedeMPouzols/gists{/gist_id}","starred_url":"https://api.github.com/users/FedeMPouzols/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/FedeMPouzols/subscriptions","organizations_url":"https://api.github.com/users/FedeMPouzols/orgs","repos_url":"https://api.github.com/users/FedeMPouzols/repos","events_url":"https://api.github.com/users/FedeMPouzols/events{/privacy}","received_events_url":"https://api.github.com/users/FedeMPouzols/received_events","type":"User","site_admin":false},"body":"And this message could be more explicit about the issue found, empty or non-numerical string?","created_at":"2016-09-19T15:12:33Z","updated_at":"2016-09-19T15:12:33Z","html_url":"https://github.com/mantidproject/mantid/pull/17432#discussion_r79413902","pull_request_url":"https://api.github.com/repos/mantidproject/mantid/pulls/17432","_links":{"self":{"href":"https://api.github.com/repos/mantidproject/mantid/pulls/comments/79413902"},"html":{"href":"https://github.com/mantidproject/mantid/pull/17432#discussion_r79413902"},"pull_request":{"href":"https://api.github.com/repos/mantidproject/mantid/pulls/17432"}}},"pull_request":{"url":"https://api.github.com/repos/mantidproject/mantid/pulls/17432","id":84481069,"html_url":"https://github.com/mantidproject/mantid/pull/17432","diff_url":"https://github.com/mantidproject/mantid/pull/17432.diff","patch_url":"https://github.com/mantidproject/mantid/pull/17432.patch","issue_url":"https://api.github.com/repos/mantidproject/mantid/issues/17432","number":17432,"state":"open","locked":false,"title":"Engg:: Fitting presenter fittingRunNoChanged refactor","user":{"login":"DavidFair","id":1817032,"avatar_url":"https://avatars.githubusercontent.com/u/1817032?v=3","gravatar_id":"","url":"https://api.github.com/users/DavidFair","html_url":"https://github.com/DavidFair","followers_url":"https://api.github.com/users/DavidFair/followers","following_url":"https://api.github.com/users/DavidFair/following{/other_user}","gists_url":"https://api.github.com/users/DavidFair/gists{/gist_id}","starred_url":"https://api.github.com/users/DavidFair/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DavidFair/subscriptions","organizations_url":"https://api.github.com/users/DavidFair/orgs","repos_url":"https://api.github.com/users/DavidFair/repos","events_url":"https://api.github.com/users/DavidFair/events{/privacy}","received_events_url":"https://api.github.com/users/DavidFair/received_events","type":"User","site_admin":false},"body":"Description of work.\r\nThis PR refactors the logic which is run when the run number is changed in the `Fitting` tab under the Engineering Diffraction interface.\r\n\r\nChanges include:\r\n- Variables have been renamed to reflect their purpose.\r\n- Several if blocks have been condensed or removed\r\n- Some common logic has been split out into methods\r\n- Additional code comments added or clarified and Doxygen added where missing\r\n- Prep for additional refactoring - these ideas can be found in ~~#17301~~ #17433 \r\n\r\n**To test:**\r\nUsing the files to test located at  `\\\\olympic\\Babylon5\\Public\\David Fairbrother\\z_test`:\r\n\r\nOpen Mantid - Interfaces - Engineering Diffraction\r\nGo to `Settings` and set the focus output directory to the folder where the files are located\r\nGo to `Fitting` and in the input box do the following\r\n\r\nThe following should work correctly and update the display to reflect the found file:\r\n- Attempt to locate a file using the browse button\r\n- Enter a single run number such as `256663`\r\n- Enter a multi run input: `256663-256664`\r\n\r\nUnder the Plot Bank drop down the available options should match the available banks - for this test data this will be `256663: 1, 2, Cropped` and `256664: 1, 2, 1, 2, 3` (This is a separate bug as it currently doesn't distinguish textured and normal banks)\r\n\r\nThe following should fail and produce a clear and descriptive error:\r\n- Use a large range `250-500` (It is capped at 200 for the moment)\r\n- Use a descending range `256664-256663` or `150-100` for example\r\n- Use a run number which does not exist\r\n- Use a multi run number which partially exist (such as `256663-256665`)\r\n\r\nIf there are any ambiguous or unclear error messages please let me know so I can tweak them to be more user friendly or specific. \r\n\r\nFixes #17301 and #17299 .\r\n\r\nDoes not need to be in release notes as it should be invisible to users. \r\n\r\n---\r\n\r\n#### Reviewer ####\r\n\r\nPlease comment on the following ([full description](http://www.mantidproject.org/Individual_Ticket_Testing)):\r\n\r\n##### Code Review #####\r\n\r\n- [ ] Is the code of an acceptable quality?\r\n- [ ] Does the code conform to the [coding standards](http://www.mantidproject.org/Coding_Standards)? Is it well structured with small focussed classes/methods/functions?\r\n- [ ] Are there unit/system tests in place? Are the unit tests small and test the a class in isolation?\r\n- [ ] If there are changes in the release notes then do they describe the changes appropriately?\r\n\r\n##### Functional Tests #####\r\n\r\n- [ ] Do changes function as described? Add comments below that describe the tests performed?\r\n- [ ] How do the changes handle unexpected situations, e.g. bad input?\r\n- [ ] Has the relevant documentation been added/updated?\r\n- [ ] Is user-facing documentation written in a user-friendly manner?\r\n- [ ] Has developer documentation been updated if required?\r\n\r\n- Does everything look good? Comment with the ship it emoji but don't merge. A member of `@mantidproject/gatekeepers` will take care of it.\r\n","created_at":"2016-09-08T13:49:55Z","updated_at":"2016-09-19T15:22:17Z","closed_at":null,"merged_at":null,"merge_commit_sha":"df1fa15f2dab923afd2dc470b9348ee2a6b894f7","assignee":{"login":"FedeMPouzols","id":5257172,"avatar_url":"https://avatars.githubusercontent.com/u/5257172?v=3","gravatar_id":"","url":"https://api.github.com/users/FedeMPouzols","html_url":"https://github.com/FedeMPouzols","followers_url":"https://api.github.com/users/FedeMPouzols/followers","following_url":"https://api.github.com/users/FedeMPouzols/following{/other_user}","gists_url":"https://api.github.com/users/FedeMPouzols/gists{/gist_id}","starred_url":"https://api.github.com/users/FedeMPouzols/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/FedeMPouzols/subscriptions","organizations_url":"https://api.github.com/users/FedeMPouzols/orgs","repos_url":"https://api.github.com/users/FedeMPouzols/repos","events_url":"https://api.github.com/users/FedeMPouzols/events{/privacy}","received_events_url":"https://api.github.com/users/FedeMPouzols/received_events","type":"User","site_admin":false},"assignees":[{"login":"FedeMPouzols","id":5257172,"avatar_url":"https://avatars.githubusercontent.com/u/5257172?v=3","gravatar_id":"","url":"https://api.github.com/users/FedeMPouzols","html_url":"https://github.com/FedeMPouzols","followers_url":"https://api.github.com/users/FedeMPouzols/followers","following_url":"https://api.github.com/users/FedeMPouzols/following{/other_user}","gists_url":"https://api.github.com/users/FedeMPouzols/gists{/gist_id}","starred_url":"https://api.github.com/users/FedeMPouzols/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/FedeMPouzols/subscriptions","organizations_url":"https://api.github.com/users/FedeMPouzols/orgs","repos_url":"https://api.github.com/users/FedeMPouzols/repos","events_url":"https://api.github.com/users/FedeMPouzols/events{/privacy}","received_events_url":"https://api.github.com/users/FedeMPouzols/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/mantidproject/mantid/milestones/58","html_url":"https://github.com/mantidproject/mantid/milestones/Release%203.8","labels_url":"https://api.github.com/repos/mantidproject/mantid/milestones/58/labels","id":1505614,"number":58,"title":"Release 3.8","description":"Code Freeze: 16-Sep-2016\r\nDeveloper & Unscripted Testing: 16-Sep-2016 to 20-Sep-2016\r\nBeta test: 20-Sep-2016 to 04-Oct-2016\r\nRelease Date: 10-Oct-2016","creator":{"login":"granrothge","id":5910574,"avatar_url":"https://avatars.githubusercontent.com/u/5910574?v=3","gravatar_id":"","url":"https://api.github.com/users/granrothge","html_url":"https://github.com/granrothge","followers_url":"https://api.github.com/users/granrothge/followers","following_url":"https://api.github.com/users/granrothge/following{/other_user}","gists_url":"https://api.github.com/users/granrothge/gists{/gist_id}","starred_url":"https://api.github.com/users/granrothge/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/granrothge/subscriptions","organizations_url":"https://api.github.com/users/granrothge/orgs","repos_url":"https://api.github.com/users/granrothge/repos","events_url":"https://api.github.com/users/granrothge/events{/privacy}","received_events_url":"https://api.github.com/users/granrothge/received_events","type":"User","site_admin":false},"open_issues":513,"closed_issues":913,"state":"open","created_at":"2016-01-13T20:00:53Z","updated_at":"2016-09-19T15:16:40Z","due_on":"2016-10-10T00:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/mantidproject/mantid/pulls/17432/commits","review_comments_url":"https://api.github.com/repos/mantidproject/mantid/pulls/17432/comments","review_comment_url":"https://api.github.com/repos/mantidproject/mantid/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mantidproject/mantid/issues/17432/comments","statuses_url":"https://api.github.com/repos/mantidproject/mantid/statuses/8b865ac1a1b15fdb4f4d086e0954b3fd19f7cf09","head":{"label":"mantidproject:17301_Engg_fitting_presenter_refactor","ref":"17301_Engg_fitting_presenter_refactor","sha":"8b865ac1a1b15fdb4f4d086e0954b3fd19f7cf09","user":{"login":"mantidproject","id":671496,"avatar_url":"https://avatars.githubusercontent.com/u/671496?v=3","gravatar_id":"","url":"https://api.github.com/users/mantidproject","html_url":"https://github.com/mantidproject","followers_url":"https://api.github.com/users/mantidproject/followers","following_url":"https://api.github.com/users/mantidproject/following{/other_user}","gists_url":"https://api.github.com/users/mantidproject/gists{/gist_id}","starred_url":"https://api.github.com/users/mantidproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mantidproject/subscriptions","organizations_url":"https://api.github.com/users/mantidproject/orgs","repos_url":"https://api.github.com/users/mantidproject/repos","events_url":"https://api.github.com/users/mantidproject/events{/privacy}","received_events_url":"https://api.github.com/users/mantidproject/received_events","type":"Organization","site_admin":false},"repo":{"id":2594116,"name":"mantid","full_name":"mantidproject/mantid","owner":{"login":"mantidproject","id":671496,"avatar_url":"https://avatars.githubusercontent.com/u/671496?v=3","gravatar_id":"","url":"https://api.github.com/users/mantidproject","html_url":"https://github.com/mantidproject","followers_url":"https://api.github.com/users/mantidproject/followers","following_url":"https://api.github.com/users/mantidproject/following{/other_user}","gists_url":"https://api.github.com/users/mantidproject/gists{/gist_id}","starred_url":"https://api.github.com/users/mantidproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mantidproject/subscriptions","organizations_url":"https://api.github.com/users/mantidproject/orgs","repos_url":"https://api.github.com/users/mantidproject/repos","events_url":"https://api.github.com/users/mantidproject/events{/privacy}","received_events_url":"https://api.github.com/users/mantidproject/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mantidproject/mantid","description":"Main repository for Mantid code","fork":false,"url":"https://api.github.com/repos/mantidproject/mantid","forks_url":"https://api.github.com/repos/mantidproject/mantid/forks","keys_url":"https://api.github.com/repos/mantidproject/mantid/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mantidproject/mantid/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mantidproject/mantid/teams","hooks_url":"https://api.github.com/repos/mantidproject/mantid/hooks","issue_events_url":"https://api.github.com/repos/mantidproject/mantid/issues/events{/number}","events_url":"https://api.github.com/repos/mantidproject/mantid/events","assignees_url":"https://api.github.com/repos/mantidproject/mantid/assignees{/user}","branches_url":"https://api.github.com/repos/mantidproject/mantid/branches{/branch}","tags_url":"https://api.github.com/repos/mantidproject/mantid/tags","blobs_url":"https://api.github.com/repos/mantidproject/mantid/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mantidproject/mantid/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mantidproject/mantid/git/refs{/sha}","trees_url":"https://api.github.com/repos/mantidproject/mantid/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mantidproject/mantid/statuses/{sha}","languages_url":"https://api.github.com/repos/mantidproject/mantid/languages","stargazers_url":"https://api.github.com/repos/mantidproject/mantid/stargazers","contributors_url":"https://api.github.com/repos/mantidproject/mantid/contributors","subscribers_url":"https://api.github.com/repos/mantidproject/mantid/subscribers","subscription_url":"https://api.github.com/repos/mantidproject/mantid/subscription","commits_url":"https://api.github.com/repos/mantidproject/mantid/commits{/sha}","git_commits_url":"https://api.github.com/repos/mantidproject/mantid/git/commits{/sha}","comments_url":"https://api.github.com/repos/mantidproject/mantid/comments{/number}","issue_comment_url":"https://api.github.com/repos/mantidproject/mantid/issues/comments{/number}","contents_url":"https://api.github.com/repos/mantidproject/mantid/contents/{+path}","compare_url":"https://api.github.com/repos/mantidproject/mantid/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mantidproject/mantid/merges","archive_url":"https://api.github.com/repos/mantidproject/mantid/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mantidproject/mantid/downloads","issues_url":"https://api.github.com/repos/mantidproject/mantid/issues{/number}","pulls_url":"https://api.github.com/repos/mantidproject/mantid/pulls{/number}","milestones_url":"https://api.github.com/repos/mantidproject/mantid/milestones{/number}","notifications_url":"https://api.github.com/repos/mantidproject/mantid/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mantidproject/mantid/labels{/name}","releases_url":"https://api.github.com/repos/mantidproject/mantid/releases{/id}","deployments_url":"https://api.github.com/repos/mantidproject/mantid/deployments","created_at":"2011-10-17T19:07:38Z","updated_at":"2016-08-22T07:35:41Z","pushed_at":"2016-09-19T15:16:42Z","git_url":"git://github.com/mantidproject/mantid.git","ssh_url":"git@github.com:mantidproject/mantid.git","clone_url":"https://github.com/mantidproject/mantid.git","svn_url":"https://github.com/mantidproject/mantid","homepage":"www.mantidproject.org","size":439528,"stargazers_count":47,"watchers_count":47,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":36,"mirror_url":null,"open_issues_count":1632,"forks":36,"open_issues":1632,"watchers":47,"default_branch":"master"}},"base":{"label":"mantidproject:master","ref":"master","sha":"07a98d2c33bb1a96297e0541443acf2358a502dd","user":{"login":"mantidproject","id":671496,"avatar_url":"https://avatars.githubusercontent.com/u/671496?v=3","gravatar_id":"","url":"https://api.github.com/users/mantidproject","html_url":"https://github.com/mantidproject","followers_url":"https://api.github.com/users/mantidproject/followers","following_url":"https://api.github.com/users/mantidproject/following{/other_user}","gists_url":"https://api.github.com/users/mantidproject/gists{/gist_id}","starred_url":"https://api.github.com/users/mantidproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mantidproject/subscriptions","organizations_url":"https://api.github.com/users/mantidproject/orgs","repos_url":"https://api.github.com/users/mantidproject/repos","events_url":"https://api.github.com/users/mantidproject/events{/privacy}","received_events_url":"https://api.github.com/users/mantidproject/received_events","type":"Organization","site_admin":false},"repo":{"id":2594116,"name":"mantid","full_name":"mantidproject/mantid","owner":{"login":"mantidproject","id":671496,"avatar_url":"https://avatars.githubusercontent.com/u/671496?v=3","gravatar_id":"","url":"https://api.github.com/users/mantidproject","html_url":"https://github.com/mantidproject","followers_url":"https://api.github.com/users/mantidproject/followers","following_url":"https://api.github.com/users/mantidproject/following{/other_user}","gists_url":"https://api.github.com/users/mantidproject/gists{/gist_id}","starred_url":"https://api.github.com/users/mantidproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mantidproject/subscriptions","organizations_url":"https://api.github.com/users/mantidproject/orgs","repos_url":"https://api.github.com/users/mantidproject/repos","events_url":"https://api.github.com/users/mantidproject/events{/privacy}","received_events_url":"https://api.github.com/users/mantidproject/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mantidproject/mantid","description":"Main repository for Mantid code","fork":false,"url":"https://api.github.com/repos/mantidproject/mantid","forks_url":"https://api.github.com/repos/mantidproject/mantid/forks","keys_url":"https://api.github.com/repos/mantidproject/mantid/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mantidproject/mantid/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mantidproject/mantid/teams","hooks_url":"https://api.github.com/repos/mantidproject/mantid/hooks","issue_events_url":"https://api.github.com/repos/mantidproject/mantid/issues/events{/number}","events_url":"https://api.github.com/repos/mantidproject/mantid/events","assignees_url":"https://api.github.com/repos/mantidproject/mantid/assignees{/user}","branches_url":"https://api.github.com/repos/mantidproject/mantid/branches{/branch}","tags_url":"https://api.github.com/repos/mantidproject/mantid/tags","blobs_url":"https://api.github.com/repos/mantidproject/mantid/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mantidproject/mantid/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mantidproject/mantid/git/refs{/sha}","trees_url":"https://api.github.com/repos/mantidproject/mantid/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mantidproject/mantid/statuses/{sha}","languages_url":"https://api.github.com/repos/mantidproject/mantid/languages","stargazers_url":"https://api.github.com/repos/mantidproject/mantid/stargazers","contributors_url":"https://api.github.com/repos/mantidproject/mantid/contributors","subscribers_url":"https://api.github.com/repos/mantidproject/mantid/subscribers","subscription_url":"https://api.github.com/repos/mantidproject/mantid/subscription","commits_url":"https://api.github.com/repos/mantidproject/mantid/commits{/sha}","git_commits_url":"https://api.github.com/repos/mantidproject/mantid/git/commits{/sha}","comments_url":"https://api.github.com/repos/mantidproject/mantid/comments{/number}","issue_comment_url":"https://api.github.com/repos/mantidproject/mantid/issues/comments{/number}","contents_url":"https://api.github.com/repos/mantidproject/mantid/contents/{+path}","compare_url":"https://api.github.com/repos/mantidproject/mantid/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mantidproject/mantid/merges","archive_url":"https://api.github.com/repos/mantidproject/mantid/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mantidproject/mantid/downloads","issues_url":"https://api.github.com/repos/mantidproject/mantid/issues{/number}","pulls_url":"https://api.github.com/repos/mantidproject/mantid/pulls{/number}","milestones_url":"https://api.github.com/repos/mantidproject/mantid/milestones{/number}","notifications_url":"https://api.github.com/repos/mantidproject/mantid/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mantidproject/mantid/labels{/name}","releases_url":"https://api.github.com/repos/mantidproject/mantid/releases{/id}","deployments_url":"https://api.github.com/repos/mantidproject/mantid/deployments","created_at":"2011-10-17T19:07:38Z","updated_at":"2016-08-22T07:35:41Z","pushed_at":"2016-09-19T15:16:42Z","git_url":"git://github.com/mantidproject/mantid.git","ssh_url":"git@github.com:mantidproject/mantid.git","clone_url":"https://github.com/mantidproject/mantid.git","svn_url":"https://github.com/mantidproject/mantid","homepage":"www.mantidproject.org","size":439528,"stargazers_count":47,"watchers_count":47,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":36,"mirror_url":null,"open_issues_count":1632,"forks":36,"open_issues":1632,"watchers":47,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mantidproject/mantid/pulls/17432"},"html":{"href":"https://github.com/mantidproject/mantid/pull/17432"},"issue":{"href":"https://api.github.com/repos/mantidproject/mantid/issues/17432"},"comments":{"href":"https://api.github.com/repos/mantidproject/mantid/issues/17432/comments"},"review_comments":{"href":"https://api.github.com/repos/mantidproject/mantid/pulls/17432/comments"},"review_comment":{"href":"https://api.github.com/repos/mantidproject/mantid/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mantidproject/mantid/pulls/17432/commits"},"statuses":{"href":"https://api.github.com/repos/mantidproject/mantid/statuses/8b865ac1a1b15fdb4f4d086e0954b3fd19f7cf09"}}}}
{"actor":{"display_login":"FedeMPouzols"}}