source: calamares/trunk/fuentes/src/libcalamaresui/modulesystem/Module.cpp @ 7538

Last change on this file since 7538 was 7538, checked in by kbut, 13 months ago

sync with github

File size: 7.0 KB
Line 
1/* === This file is part of Calamares - <https://github.com/calamares> ===
2 *
3 *   Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
4 *   Copyright 2017, Adriaan de Groot <groot@kde.org>
5 *
6 *   Calamares is free software: you can redistribute it and/or modify
7 *   it under the terms of the GNU General Public License as published by
8 *   the Free Software Foundation, either version 3 of the License, or
9 *   (at your option) any later version.
10 *
11 *   Calamares is distributed in the hope that it will be useful,
12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *   GNU General Public License for more details.
15 *
16 *   You should have received a copy of the GNU General Public License
17 *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "Module.h"
21
22#include "ProcessJobModule.h"
23#include "CppJobModule.h"
24#include "ViewModule.h"
25#include "utils/CalamaresUtils.h"
26#include "utils/YamlUtils.h"
27#include "utils/Logger.h"
28#include "Settings.h"
29#include "CalamaresConfig.h"
30
31#ifdef WITH_PYTHON
32#include "PythonJobModule.h"
33#endif
34
35#ifdef WITH_PYTHONQT
36#include "PythonQtViewModule.h"
37#endif
38
39#include <yaml-cpp/yaml.h>
40
41#include <QDir>
42#include <QFile>
43#include <QFileInfo>
44#include <QString>
45
46
47// Example module.desc
48/*
49---
50type:      "view"      #job or view
51name:      "foo"      #the module name. must be unique and same as the parent directory
52interface: "qtplugin" #can be: qtplugin, python, process, ...
53*/
54
55namespace Calamares
56{
57
58Module::~Module()
59{}
60
61Module*
62Module::fromDescriptor( const QVariantMap& moduleDescriptor,
63                        const QString& instanceId,
64                        const QString& configFileName,
65                        const QString& moduleDirectory )
66{
67    Module* m = nullptr;
68
69    QString typeString = moduleDescriptor.value( "type" ).toString();
70    QString intfString = moduleDescriptor.value( "interface" ).toString();
71
72    if ( typeString.isEmpty() ||
73         intfString.isEmpty() )
74    {
75        cError() << "Bad module descriptor format" << instanceId;
76        return nullptr;
77    }
78    if ( ( typeString == "view" ) || ( typeString == "viewmodule" ) )
79    {
80        if ( intfString == "qtplugin" )
81        {
82            m = new ViewModule();
83        }
84        else if ( intfString == "pythonqt" )
85        {
86#ifdef WITH_PYTHONQT
87            m = new PythonQtViewModule();
88#else
89            cError() << "PythonQt view modules are not supported in this version of Calamares.";
90#endif
91        }
92        else
93            cError() << "Bad interface" << intfString << "for module type" << typeString;
94    }
95    else if ( typeString == "job" )
96    {
97        if ( intfString == "qtplugin" )
98        {
99            m = new CppJobModule();
100        }
101        else if ( intfString == "process" )
102        {
103            m = new ProcessJobModule();
104        }
105        else if ( intfString == "python" )
106        {
107#ifdef WITH_PYTHON
108            m = new PythonJobModule();
109#else
110            cError() << "Python modules are not supported in this version of Calamares.";
111#endif
112        }
113        else
114            cError() << "Bad interface" << intfString << "for module type" << typeString;
115    }
116    else
117        cError() << "Bad module type" << typeString;
118
119    if ( !m )
120    {
121        cError() << "Bad module type (" << typeString
122            << ") or interface string (" << intfString
123            << ") for module " << instanceId;
124        return nullptr;
125    }
126
127    QDir moduleDir( moduleDirectory );
128    if ( moduleDir.exists() && moduleDir.isReadable() )
129        m->m_directory = moduleDir.absolutePath();
130    else
131    {
132        cError() << "Bad module directory" << moduleDirectory << "for" << instanceId;
133        delete m;
134        return nullptr;
135    }
136
137    m->m_instanceId = instanceId;
138
139    m->initFrom( moduleDescriptor );
140    try
141    {
142        m->loadConfigurationFile( configFileName );
143    }
144    catch ( YAML::Exception& e )
145    {
146        cError() << "YAML parser error " << e.what();
147        delete m;
148        return nullptr;
149    }
150    return m;
151}
152
153
154void
155Module::loadConfigurationFile( const QString& configFileName ) //throws YAML::Exception
156{
157    QStringList configFilesByPriority;
158
159    if ( CalamaresUtils::isAppDataDirOverridden() )
160    {
161        configFilesByPriority.append(
162            CalamaresUtils::appDataDir().absoluteFilePath(
163                QString( "modules/%1" ).arg( configFileName ) ) );
164    }
165    else
166    {
167        if ( Settings::instance()->debugMode() )
168        {
169            configFilesByPriority.append(
170                QDir( QDir::currentPath() ).absoluteFilePath(
171                    QString( "src/modules/%1/%2" ).arg( m_name )
172                                                  .arg( configFileName ) ) );
173        }
174
175        configFilesByPriority.append(
176            QString( "/etc/calamares/modules/%1" ).arg( configFileName ) );
177        configFilesByPriority.append(
178            CalamaresUtils::appDataDir().absoluteFilePath(
179                QString( "modules/%2" ).arg( configFileName ) ) );
180    }
181
182    foreach ( const QString& path, configFilesByPriority )
183    {
184        QFile configFile( path );
185        if ( configFile.exists() && configFile.open( QFile::ReadOnly | QFile::Text ) )
186        {
187            QByteArray ba = configFile.readAll();
188
189            YAML::Node doc = YAML::Load( ba.constData() );
190            if ( doc.IsNull() )
191            {
192                // Special case: empty config files are valid,
193                // but aren't a map.
194                return;
195            }
196            if ( !doc.IsMap() )
197            {
198                cWarning() << "Bad module configuration format" << path;
199                return;
200            }
201
202            m_configurationMap = CalamaresUtils::yamlMapToVariant( doc ).toMap();
203            return;
204        }
205        else
206            continue;
207    }
208}
209
210
211QString
212Module::name() const
213{
214    return m_name;
215}
216
217
218QString
219Module::instanceId() const
220{
221    return m_instanceId;
222}
223
224
225QString
226Module::instanceKey() const
227{
228    return QString( "%1@%2" ).arg( m_name )
229                             .arg( m_instanceId );
230}
231
232
233QStringList
234Module::requiredModules() const
235{
236    return m_requiredModules;
237}
238
239
240QString
241Module::location() const
242{
243    return m_directory;
244}
245
246
247QString
248Module::typeString() const
249{
250    switch ( type() )
251    {
252    case Job:
253        return "Job Module";
254    case View:
255        return "View Module";
256    }
257    return QString();
258}
259
260
261QString
262Module::interfaceString() const
263{
264    switch ( interface() )
265    {
266    case ProcessInterface:
267        return "External process";
268    case PythonInterface:
269        return "Python (Boost.Python)";
270    case PythonQtInterface:
271        return "Python (experimental)";
272    case QtPluginInterface:
273        return "Qt Plugin";
274    }
275    return QString();
276}
277
278
279bool
280Module::isLoaded() const
281{
282    return m_loaded;
283}
284
285
286QVariantMap
287Module::configurationMap()
288{
289    return m_configurationMap;
290}
291
292
293Module::Module()
294    : m_loaded( false )
295{}
296
297
298void
299Module::initFrom( const QVariantMap& moduleDescriptor )
300{
301    m_name = moduleDescriptor.value( "name" ).toString();
302}
303
304} //ns
Note: See TracBrowser for help on using the repository browser.