diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h index 36906341b925fc49e60e130d5d2ae33dc3081f6a..19871ce70ae87c87dad20f743c19c838673954c9 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h @@ -97,7 +97,8 @@ namespace Mantid * @param newvalue :: new value of property * @param prevvalue :: previous value of property */ - ValueChanged(const std::string name, const std::string newvalue, const std::string prevvalue) : ConfigServiceNotification(), m_name(name), m_value(newvalue), m_prev(prevvalue) {} + ValueChanged(const std::string &name, const std::string &newvalue, const std::string &prevvalue) + : ConfigServiceNotification(), m_name(name), m_value(newvalue), m_prev(prevvalue) {} /// The name of the user property that has changed, as it appears in the user.properties file const std::string & key() const { return this->m_name; } ///< @return The name of the changed the property /// The new value for the property @@ -146,12 +147,22 @@ namespace Mantid std::string getPropertiesDir() const; /// Returns a directory to use to write out Mantid information. Needs to be writable std::string getUserPropertiesDir() const; + + /** @name Search paths handling */ + //@{ /// Get the list of search paths const std::vector<std::string>& getDataSearchDirs() const; + /// Set a list of search paths via a vector + void setDataSearchDirs(const std::vector<std::string> &searchDirs); + /// Set a list of search paths via a string + void setDataSearchDirs(const std::string &searchDirs); + /// Adds the passed path to the end of the list of data search paths + void appendDataSearchDir(const std::string & path); /// Get the list of user search paths const std::vector<std::string>& getUserSearchDirs() const; /// Get instrument search directory const std::string getInstrumentDirectory() const; + //@} /// Load facility information from instrumentDir/Facilities.xml file void updateFacilities(const std::string& fName = ""); @@ -188,8 +199,6 @@ namespace Mantid std::string defaultConfig() const; /// Writes out a fresh user properties file void createUserPropertiesFile() const; - /// Adds the passed path to the end of the list of data search paths - void appendDataSearchDir(const std::string & path); /// Convert any relative paths to absolute ones and store them locally so that /// if the working directory is altered the paths will not be affected void convertRelativeToAbsolute(); diff --git a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp index ad026eae7be2fc837ec2da6887ad63130b2a4f02..bed591766212a52f12f1dea7bddd440e436e08b8 100644 --- a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp +++ b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp @@ -25,6 +25,7 @@ #include <Poco/Environment.h> #include <boost/algorithm/string/replace.hpp> +#include <boost/algorithm/string/join.hpp> #include <fstream> #include <sstream> @@ -464,27 +465,6 @@ bool ConfigServiceImpl::isInDataSearchList(const std::string & path) const return (it != m_DataSearchDirs.end()); } -/** - * Adds the passed path to the end of the list of data search paths - * the path name must be absolute - * @param path :: the absolute path to add - */ -void ConfigServiceImpl::appendDataSearchDir(const std::string & path) -{ - if ( ! isInDataSearchList(path) ) - { - std::string newSearchString; - std::vector<std::string>::const_iterator it = m_DataSearchDirs.begin(); - for( ; it != m_DataSearchDirs.end(); ++it) - { - newSearchString.append(*it); - newSearchString.append(";"); - } - newSearchString.append(path); - setString("datasearch.directories", newSearchString); - } -} - /** * writes a basic placeholder user.properties file to disk * any errors are caught and logged, but not propagated @@ -897,6 +877,47 @@ const std::vector<std::string>& ConfigServiceImpl::getDataSearchDirs() const return m_DataSearchDirs; } +/** + * Set a list of search paths via a vector + * @param searchDirs :: A list of search directories + */ +void ConfigServiceImpl::setDataSearchDirs(const std::vector<std::string> &searchDirs) +{ + std::string searchPaths = boost::join(searchDirs, ";"); + setDataSearchDirs(searchPaths); +} + +/** + * Set a list of search paths via a string + * @param searchDirs :: A string containing a list of search directories separated by a semi colon (;). + */ +void ConfigServiceImpl::setDataSearchDirs(const std::string &searchDirs) +{ + setString("datasearch.directories", searchDirs); +} + +/** + * Adds the passed path to the end of the list of data search paths + * the path name must be absolute + * @param path :: the absolute path to add + */ +void ConfigServiceImpl::appendDataSearchDir(const std::string & path) +{ + if ( ! isInDataSearchList(path) ) + { + std::string newSearchString; + std::vector<std::string>::const_iterator it = m_DataSearchDirs.begin(); + for( ; it != m_DataSearchDirs.end(); ++it) + { + newSearchString.append(*it); + newSearchString.append(";"); + } + newSearchString.append(path); + setString("datasearch.directories", newSearchString); + } +} + + /** * Return the list of user search paths * @returns A vector of strings containing the defined search directories diff --git a/Code/Mantid/Framework/PythonAPI/CMakeLists.txt b/Code/Mantid/Framework/PythonAPI/CMakeLists.txt index 4f7ce359c947edef988f2670d104960851875647..4b5fc29042381c89a3657a1656bc15a53d785204 100644 --- a/Code/Mantid/Framework/PythonAPI/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonAPI/CMakeLists.txt @@ -39,6 +39,7 @@ set ( TEST_PY_FILES test/ImportTest.py test/PythonAlgorithmTest.py test/NumpyTest.py test/WorkspaceTests.py + test/SettingsTest.py ) ########################################################################### diff --git a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/PyAlgorithmWrapper.h b/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/PyAlgorithmWrapper.h index dca05975d7ddbf6828c139f60ef25bc084531985..0d6d5bb476f232d4d2c34b3b2825f8d8819f6dda 100644 --- a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/PyAlgorithmWrapper.h +++ b/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/PyAlgorithmWrapper.h @@ -120,7 +120,7 @@ public: // FIXME validator is not passed in - but I'm not sure this would ever reasonably be called. (void)validator; //Extract the values from the python list into a std vector - this->IAlgorithm::declareProperty(prop_name, Conversions::convertToStdVector<TYPE>(values), doc, direction); + this->IAlgorithm::declareProperty(prop_name, Conversions::toStdVector<TYPE>(values), doc, direction); } /** @@ -137,7 +137,7 @@ public: { (void)validator; //Extract the values from the python list into a std vector - this->IAlgorithm::declareProperty(prop_name, Conversions::convertToStdVector<TYPE>(values), validator.clone(), doc, direction); + this->IAlgorithm::declareProperty(prop_name, Conversions::toStdVector<TYPE>(values), validator.clone(), doc, direction); } /** @@ -152,7 +152,7 @@ public: const unsigned int direction) { //Extract the values from the python list into a std vector - this->IAlgorithm::declareProperty(prop_name, Conversions::convertToStdVector<TYPE>(values), doc, direction); + this->IAlgorithm::declareProperty(prop_name, Conversions::toStdVector<TYPE>(values), doc, direction); } /** @@ -208,7 +208,7 @@ public: void _declareFileProperty(const std::string & prop_name, const std::string & default_value, const unsigned int type, boost::python::list exts, const std::string & description, const unsigned int direction) { - this->Algorithm::declareProperty(new API::FileProperty(prop_name, default_value, type, Conversions::convertToStdVector<std::string>(exts), direction), description); + this->Algorithm::declareProperty(new API::FileProperty(prop_name, default_value, type, Conversions::toStdVector<std::string>(exts), direction), description); } /** diff --git a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/PythonInterfaceFunctions.h b/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/PythonInterfaceFunctions.h index fee88a76c9e47394ac5180ada799b50f9550b16e..8ccbaad756c5d34da5bf9fd7e0ebab7c83a1a2a4 100644 --- a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/PythonInterfaceFunctions.h +++ b/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/PythonInterfaceFunctions.h @@ -245,9 +245,10 @@ namespace Mantid /** * Convert a Boost Python list to a std::vector of the requested type * @param pylist :: The Python list + * @returns A std::vector from the given list */ template<typename TYPE> - std::vector<TYPE> convertToStdVector(const boost::python::list & pylist) + std::vector<TYPE> toStdVector(const boost::python::list & pylist) { int length = boost::python::extract<int>(pylist.attr("__len__")()); std::vector<TYPE> seq_std(length, TYPE()); @@ -266,6 +267,19 @@ namespace Mantid } return seq_std; } + + //@{ + /** + * Convert a std::vector of the given type to boost python list + * @param stdvec :: An input vector + * @returns A boost::python list converted from the given vector + */ + template<typename TYPE> + boost::python::list toPyList(const std::vector<TYPE> & stdvec) + { + return boost::python::list(stdvec); + } + } //@} //@endcond diff --git a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/kernel_exports.h b/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/kernel_exports.h index 79c6e6b37e3ce5e59318a0ef67544b55d12f05e6..ffd73590cd3a7363d6a5e2843061c1e471fffa6e 100755 --- a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/kernel_exports.h +++ b/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/kernel_exports.h @@ -1,9 +1,12 @@ #ifndef MANTIDPYTHONAPI_KERNEL_EXPORTS_H_ #define MANTIDPYTHONAPI_KERNEL_EXPORTS_H_ -#include <MantidKernel/Exception.h> -#include <MantidKernel/ConfigService.h> -#include <MantidKernel/FacilityInfo.h> +#include "MantidPythonAPI/PythonInterfaceFunctions.h" + +#include "MantidKernel/Exception.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" + namespace Mantid { @@ -25,31 +28,11 @@ namespace Mantid { return Mantid::welcomeMessage(); } - - /** - * Retrieve a setting from the ConfigService - * @param name :: The name of the property - * @returns The current value of the property - */ - std::string getProperty(const std::string & name) const - { - return Mantid::Kernel::ConfigService::Instance().getString(name); - } - - /** - * Update a setting in the ConfigService - * @param name :: The name of the property - * @param value :: The new value of the property - */ - void setProperty(const std::string & name, const std::string & value) - { - Mantid::Kernel::ConfigService::Instance().setString(name, value); - } - + /** * Access the facilities information * @param name :: The name of a facility. If empty the default facility is returned. (default = "") - * @return the facility information object + * @returns The facility information object */ Kernel::FacilityInfo facility(const std::string & name = "") { @@ -70,6 +53,92 @@ namespace Mantid } } } + + /** + * Retrieve a setting from the ConfigService + * @param name :: The name of the property + * @returns The current value of the property + */ + std::string getString(const std::string & name) const + { + return Mantid::Kernel::ConfigService::Instance().getString(name); + } + + /** + * Update a setting in the ConfigService + * @param name :: The name of the property + * @param value :: The new value of the property + */ + void setString(const std::string & name, const std::string & value) + { + Mantid::Kernel::ConfigService::Instance().setString(name, value); + } + + /** @name Special handling for search path manipulation. */ + //@{ + + /** + * Get the list of data search directories + * @returns A list of the data search paths + */ + boost::python::list getDataSearchDirs() const + { + const std::vector<std::string> & paths = Mantid::Kernel::ConfigService::Instance().getDataSearchDirs(); + return Conversions::toPyList(paths); + } + + /** + * Replace the current list of data search paths with the given ones + * @param value :: A semi-colon separated list of paths + */ + void setDataSearchDirs(const std::string &value) + { + Mantid::Kernel::ConfigService::Instance().setDataSearchDirs(value); + } + + /** + * Replace the current list of data search paths with the given ones + * @param value :: A semi-colon separated list of paths + */ + void setDataSearchDirs(const boost::python::list &values) + { + Mantid::Kernel::ConfigService::Instance().setDataSearchDirs(Conversions::toStdVector<std::string>(values)); + } + + /** + * Adds the passed path to the end of the list of data search paths + * @param path :: A path to append + */ + void appendDataSearchDir(const std::string & path) + { + Mantid::Kernel::ConfigService::Instance().appendDataSearchDir(path); + } + + /// Get instrument search directory + const std::string getInstrumentDirectory() const + { + return Mantid::Kernel::ConfigService::Instance().getInstrumentDirectory(); + } + //@} + + /** + * Return the user properties filename + * @returns A string containing the filename of the user properties file + */ + std::string getUserFilename() const + { + return Mantid::Kernel::ConfigService::Instance().getUserFilename(); + } + + /** + * Saves and properties changed from the default to the given file + * @param A filename to write the settings to + */ + void saveConfig(const std::string &filename) const + { + Mantid::Kernel::ConfigService::Instance().saveConfig(filename); + } + }; } diff --git a/Code/Mantid/Framework/PythonAPI/src/kernel_exports.cpp b/Code/Mantid/Framework/PythonAPI/src/kernel_exports.cpp index 9a3021b67b6d04d295f038296e9a5c25c6cf0260..fd86f95e11c57e06ec1a26393e21bfdd6fd1e4fd 100644 --- a/Code/Mantid/Framework/PythonAPI/src/kernel_exports.cpp +++ b/Code/Mantid/Framework/PythonAPI/src/kernel_exports.cpp @@ -209,11 +209,18 @@ namespace PythonAPI { class_<ConfigServiceWrapper>("ConfigService") // Special methods - .def("__getitem__", &ConfigServiceWrapper::getProperty) - .def("__setitem__", &ConfigServiceWrapper::setProperty) + .def("__getitem__", &ConfigServiceWrapper::getString) + .def("__setitem__", &ConfigServiceWrapper::setString) // Standard methods .def("facility", &ConfigServiceWrapper::facility, ConfigService_facilityOverloads()) .def("welcomeMessage", &ConfigServiceWrapper::welcomeMessage) + .def("getDataSearchDirs",&ConfigServiceWrapper::getDataSearchDirs) + .def("setDataSearchDirs", (void (ConfigServiceWrapper::*)(const std::string &))&ConfigServiceWrapper::setDataSearchDirs) + .def("setDataSearchDirs", (void (ConfigServiceWrapper::*)(const boost::python::list &))&ConfigServiceWrapper::setDataSearchDirs) + .def("appendDataSearchDir", &ConfigServiceWrapper::appendDataSearchDir) + .def("getInstrumentDirectory", &ConfigServiceWrapper::getInstrumentDirectory) + .def("getUserFilename", &ConfigServiceWrapper::getUserFilename) + .def("saveConfig", &ConfigServiceWrapper::saveConfig) ; } diff --git a/Code/Mantid/Framework/PythonAPI/test/SettingsTest.py b/Code/Mantid/Framework/PythonAPI/test/SettingsTest.py new file mode 100644 index 0000000000000000000000000000000000000000..9e23660cf0081a51eaa4a2fd048b3e64fbb7ce1e --- /dev/null +++ b/Code/Mantid/Framework/PythonAPI/test/SettingsTest.py @@ -0,0 +1,82 @@ +import unittest +import os + +from MantidFramework import * +mtd.initialise() + +class SettingsTest(unittest.TestCase): + + __dirs_to_rm = [] + __init_dir_list = '' + + def test_welcome(self): + self.assertEquals(mtd.settings.welcomeMessage(), + 'Welcome to Mantid - Manipulation and Analysis Toolkit for Instrument Data') + + def test_getting_search_paths(self): + """Retrieve the search paths + """ + paths = mtd.settings.getDataSearchDirs() + self.assertEquals(type(paths), list) + self.assert_(len(paths) > 0) + + def test_setting_data_search_paths_via_string(self): + """Set data search paths via a string + """ + updated = self._setup_test_areas() + mtd.settings.setDataSearchDirs(updated) + # Have they been updated - The stored values come back with trailing slashes + self.assertEquals(mtd.settings['datasearch.directories'], updated) + + self._clean_up_test_areas() + + def test_setting_data_search_paths_via_string(self): + """Set data search paths via a string + """ + updated = self._setup_test_areas() + updated_list = updated.split(';') + + self.assertEquals(len(updated_list), 2) + self.assertEquals(type(updated_list), list) + mtd.settings.setDataSearchDirs(updated_list) + + # Have they been updated - The stored values come back with trailing slashes + self.assertEquals(mtd.settings['datasearch.directories'], updated) + + self._clean_up_test_areas() + + def _setup_test_areas(self): + """Set data search paths via a list + """ + self.__init_dir_list = mtd.settings['datasearch.directories'] + # Set new paths - Make a temporary directory so that I know where it is + test_path = os.path.join(os.getcwd(), "tmp") + try: + os.mkdir(test_path) + self.__dirs_to_rm.append(test_path) + except OSError: + pass + + test_path_two = os.path.join(os.getcwd(), "tmp_2") + try: + os.mkdir(test_path_two) + self.__dirs_to_rm.append(test_path_two) + except OSError: + pass + + updated = test_path + '/;' + test_path_two + '/' + return updated + + def _clean_up_test_areas(self): + mtd.settings['datasearch.directories'] = self.__init_dir_list + + # Remove temp directories + for p in self.__dirs_to_rm: + try: + os.rmdir(p) + except OSError: + pass +# ----------------------------------- + +if __name__ == '__main__': + unittest.main()