From 74be2fd098c673ab5f8c2226af54889ee41e279d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 15 Aug 2017 22:50:26 +0200 Subject: [PATCH] Python-i18n: implement gettext functions in libcalamares.utils - remove Job.gettextPath - add libcalamares.utils.gettext_path() - add libcalamares.utils.gettext_lang() - modify examples in main.py - add some gettext debug-output from dummypython - correct namespace mis-labeling - provide two forms of GlobalStorage - regular use, has a JobQueue with storage - testing use, creates GlobalStorage separately, provide independent access to that for Python. --- src/libcalamares/GlobalStorage.cpp | 12 +++++++-- src/libcalamares/GlobalStorage.h | 6 +++++ src/libcalamares/PythonHelper.cpp | 2 +- src/libcalamares/PythonJob.cpp | 7 +++++- src/libcalamares/PythonJobApi.cpp | 39 +++++++++++++++++++----------- src/libcalamares/PythonJobApi.h | 3 +-- src/modules/dummypython/main.py | 7 +++++- 7 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/libcalamares/GlobalStorage.cpp b/src/libcalamares/GlobalStorage.cpp index e56a241e9..36405ce87 100644 --- a/src/libcalamares/GlobalStorage.cpp +++ b/src/libcalamares/GlobalStorage.cpp @@ -101,14 +101,22 @@ GlobalStorage::debugDump() const namespace CalamaresPython { +Calamares::GlobalStorage* GlobalStoragePythonWrapper::s_gs_instance = nullptr; + // The special handling for nullptr is only for the testing // script for the python bindings, which passes in None; // normal use will have a GlobalStorage from JobQueue::instance() // passed in. Testing use will leak the allocated GlobalStorage // object, but that's OK for testing. GlobalStoragePythonWrapper::GlobalStoragePythonWrapper( Calamares::GlobalStorage* gs ) - : m_gs( gs ? gs : new Calamares::GlobalStorage ) -{} + : m_gs( gs ? gs : s_gs_instance ) +{ + if (!m_gs) + { + s_gs_instance = new Calamares::GlobalStorage; + m_gs = s_gs_instance; + } +} bool GlobalStoragePythonWrapper::contains( const std::string& key ) const diff --git a/src/libcalamares/GlobalStorage.h b/src/libcalamares/GlobalStorage.h index ff8d32682..0ff56ac62 100644 --- a/src/libcalamares/GlobalStorage.h +++ b/src/libcalamares/GlobalStorage.h @@ -87,8 +87,14 @@ public: int remove( const std::string& key ); boost::python::api::object value( const std::string& key ) const; + // This is a helper for scripts that do not go through + // the JobQueue (i.e. the module testpython script), + // which allocate their own (singleton) GlobalStorage. + static Calamares::GlobalStorage* globalStorageInstance() { return s_gs_instance; } + private: Calamares::GlobalStorage* m_gs; + static Calamares::GlobalStorage* s_gs_instance; // See globalStorageInstance() }; } // namespace CalamaresPython diff --git a/src/libcalamares/PythonHelper.cpp b/src/libcalamares/PythonHelper.cpp index b252f90b2..14a63f4d3 100644 --- a/src/libcalamares/PythonHelper.cpp +++ b/src/libcalamares/PythonHelper.cpp @@ -316,4 +316,4 @@ Helper::handleLastError() } -} // namespace Calamares +} // namespace CalamaresPython diff --git a/src/libcalamares/PythonJob.cpp b/src/libcalamares/PythonJob.cpp index 7cd4ae556..3d16e946b 100644 --- a/src/libcalamares/PythonJob.cpp +++ b/src/libcalamares/PythonJob.cpp @@ -70,7 +70,6 @@ BOOST_PYTHON_MODULE( libcalamares ) .def_readonly( "module_name", &CalamaresPython::PythonJobInterface::moduleName ) .def_readonly( "pretty_name", &CalamaresPython::PythonJobInterface::prettyName ) .def_readonly( "working_path", &CalamaresPython::PythonJobInterface::workingPath ) - .def_readonly( "gettext_path", &CalamaresPython::PythonJobInterface::gettextPath ) .def_readonly( "configuration", &CalamaresPython::PythonJobInterface::configuration ) .def( "setprogress", @@ -223,6 +222,12 @@ BOOST_PYTHON_MODULE( libcalamares ) &CalamaresPython::gettext_languages, "Returns list of languages (most to least-specific) for gettext." ); + + bp::def( + "gettext_path", + &CalamaresPython::gettext_path, + "Returns path for gettext search." + ); } diff --git a/src/libcalamares/PythonJobApi.cpp b/src/libcalamares/PythonJobApi.cpp index 15c14ab51..705467f25 100644 --- a/src/libcalamares/PythonJobApi.cpp +++ b/src/libcalamares/PythonJobApi.cpp @@ -186,14 +186,6 @@ PythonJobInterface::PythonJobInterface( Calamares::PythonJob* parent ) prettyName = m_parent->prettyName().toStdString(); workingPath = m_parent->m_workingPath.toStdString(); configuration = CalamaresPython::variantMapToPyDict( m_parent->m_configurationMap ); - - if (moduleDir.cd("../_lang/python")) - gettextPath = moduleDir.absolutePath().toStdString(); - else - { - debug( "No _lang/ directory for translations." ); - gettextPath = std::string(); - } } @@ -211,31 +203,50 @@ obscure( const std::string& string ) return CalamaresUtils::obscure( QString::fromStdString( string ) ).toStdString(); } -std::list< std::string > +bp::list gettext_languages() { - std::list< std::string > pyList; - QVariant localeConf_ = Calamares::JobQueue::instance()->globalStorage()->value( "localeConf" ); + bp::list pyList; + + // There are two ways that Python jobs can be initialised: + // - through JobQueue, in which case that has an instance which holds + // a GlobalStorage object, or + // - through the Python test-script, which initialises its + // own GlobalStoragePythonWrapper, which then holds a + // GlobalStorage object for all of Python. + Calamares::JobQueue* jq = Calamares::JobQueue::instance(); + Calamares::GlobalStorage* gs = jq ? jq->globalStorage() : CalamaresPython::GlobalStoragePythonWrapper::globalStorageInstance(); + + QVariant localeConf_ = gs->value( "localeConf" ); if ( localeConf_.canConvert< QVariantMap >() ) { QVariant lang_ = localeConf_.value< QVariantMap >()[ "LANG" ]; if ( lang_.canConvert< QString >() ) { QString lang = lang_.value< QString >(); - pyList.push_back( lang.toStdString() ); + pyList.append( lang.toStdString() ); if ( lang.indexOf( '.' ) > 0) { lang.truncate( lang.indexOf( '.' ) ); - pyList.push_back( lang.toStdString() ); + pyList.append( lang.toStdString() ); } if ( lang.indexOf( '_' ) > 0) { lang.truncate( lang.indexOf( '_' ) ); - pyList.push_back( lang.toStdString() ); + pyList.append( lang.toStdString() ); } } } return pyList; } +std::string +gettext_path() +{ + // TODO: distinguish between -d runs and normal runs + // TODO: can we detect DESTDIR-installs? + return std::string(); +} + + } diff --git a/src/libcalamares/PythonJobApi.h b/src/libcalamares/PythonJobApi.h index 09835b2ed..a732e005b 100644 --- a/src/libcalamares/PythonJobApi.h +++ b/src/libcalamares/PythonJobApi.h @@ -63,7 +63,7 @@ std::string obscure( const std::string& string ); std::string gettext_path(); -std::list< std::string > gettext_languages(); +boost::python::list gettext_languages(); void debug( const std::string& s ); @@ -77,7 +77,6 @@ public: std::string moduleName; std::string prettyName; std::string workingPath; - std::string gettextPath; boost::python::dict configuration; diff --git a/src/modules/dummypython/main.py b/src/modules/dummypython/main.py index bcbe3f537..ec6b02bfd 100644 --- a/src/modules/dummypython/main.py +++ b/src/modules/dummypython/main.py @@ -35,7 +35,7 @@ from time import gmtime, strftime, sleep import gettext _ = gettext.translation("calamares-python", - localedir=libcalamares.utils.gettext_path, + localedir=libcalamares.utils.gettext_path(), languages=libcalamares.utils.gettext_languages(), fallback=True).gettext @@ -46,6 +46,11 @@ def pretty_name(): def run(): """Dummy python job.""" + libcalamares.utils.debug("LocaleDir=" + + str(libcalamares.utils.gettext_path())) + libcalamares.utils.debug("Languages=" + + str(libcalamares.utils.gettext_languages())) + os.system("/bin/sh -c \"touch ~/calamares-dummypython\"") accumulator = strftime("%Y-%m-%d %H:%M:%S", gmtime()) + "\n" accumulator += "Calamares version: " + libcalamares.VERSION_SHORT + "\n"