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

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

sync with github

File size: 6.5 KB
Line 
1/* === This file is part of Calamares - <https://github.com/calamares> ===
2 *
3 *   Copyright 2016, Teo Mrnjavac <teo@kde.org>
4 *
5 *   Calamares is free software: you can redistribute it and/or modify
6 *   it under the terms of the GNU General Public License as published by
7 *   the Free Software Foundation, either version 3 of the License, or
8 *   (at your option) any later version.
9 *
10 *   Calamares is distributed in the hope that it will be useful,
11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 *   GNU General Public License for more details.
14 *
15 *   You should have received a copy of the GNU General Public License
16 *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "PythonQtViewModule.h"
20
21#include "utils/Logger.h"
22#include "viewpages/ViewStep.h"
23#include "viewpages/PythonQtViewStep.h"
24#include "ViewManager.h"
25#include "CalamaresConfig.h"
26#include "viewpages/PythonQtGlobalStorageWrapper.h"
27#include "viewpages/PythonQtUtilsWrapper.h"
28#include "GlobalStorage.h"
29#include "JobQueue.h"
30
31#include <PythonQt.h>
32#include <extensions/PythonQt_QtAll/PythonQt_QtAll.h>
33
34#include <QDir>
35#include <QPointer>
36
37
38static QPointer< GlobalStorage > s_gs = nullptr;
39static QPointer< Utils > s_utils = nullptr;
40
41namespace Calamares {
42
43Module::Type
44PythonQtViewModule::type() const
45{
46    return View;
47}
48
49
50Module::Interface
51PythonQtViewModule::interface() const
52{
53    return PythonQtInterface;
54}
55
56
57void
58PythonQtViewModule::loadSelf()
59{
60    if ( !m_scriptFileName.isEmpty() )
61    {
62        if ( PythonQt::self() == nullptr )
63        {
64            if ( Py_IsInitialized() )
65                PythonQt::init( PythonQt::IgnoreSiteModule |
66                                PythonQt::RedirectStdOut |
67                                PythonQt::PythonAlreadyInitialized );
68            else
69                PythonQt::init();
70
71            PythonQt_QtAll::init();
72            cDebug() << "Initializing PythonQt bindings."
73                     << "This should only happen once.";
74
75            //TODO: register classes here into the PythonQt environment, like this:
76            //PythonQt::self()->registerClass( &PythonQtViewStep::staticMetaObject,
77            //                                 "calamares" );
78
79            // We only do the following to force PythonQt to create a submodule
80            // "calamares" for us to put our static objects in
81            PythonQt::self()->registerClass( &::GlobalStorage::staticMetaObject,
82                                             "calamares" );
83
84            // Get a PythonQtObjectPtr to the PythonQt.calamares submodule
85            PythonQtObjectPtr pqtm = PythonQt::priv()->pythonQtModule();
86            PythonQtObjectPtr cala = PythonQt::self()->lookupObject( pqtm, "calamares" );
87
88            // Prepare GlobalStorage object, in module PythonQt.calamares
89            if ( !s_gs )
90                s_gs = new ::GlobalStorage( Calamares::JobQueue::instance()->globalStorage() );
91            cala.addObject( "global_storage", s_gs );
92
93            // Prepare Utils object, in module PythonQt.calamares
94            if ( !s_utils )
95                s_utils = new ::Utils( Calamares::JobQueue::instance()->globalStorage() );
96            cala.addObject( "utils", s_utils );
97
98            // Append configuration object, in module PythonQt.calamares
99            cala.addVariable("configuration", m_configurationMap);
100
101            // Basic stdout/stderr handling
102            QObject::connect( PythonQt::self(), &PythonQt::pythonStdOut,
103                     []( const QString& message )
104            {
105                cDebug() << "PythonQt OUT>" << message;
106            } );
107            QObject::connect( PythonQt::self(), &PythonQt::pythonStdErr,
108                     []( const QString& message )
109            {
110                cDebug() << "PythonQt ERR>" << message;
111            } );
112
113        }
114
115        QDir workingDir( m_workingPath );
116        if ( !workingDir.exists() )
117        {
118            cDebug() << "Invalid working directory"
119                     << m_workingPath
120                     << "for module"
121                     << name();
122            return;
123        }
124
125        QString fullPath = workingDir.absoluteFilePath( m_scriptFileName );
126        QFileInfo scriptFileInfo( fullPath );
127        if ( !scriptFileInfo.isReadable() )
128        {
129            cDebug() << "Invalid main script file path"
130                     << fullPath
131                     << "for module"
132                     << name();
133            return;
134        }
135
136        // Construct empty Python module with the given name
137        PythonQtObjectPtr cxt =
138                PythonQt::self()->
139                createModuleFromScript( name() );
140        if ( cxt.isNull() )
141        {
142            cDebug() << "Cannot load PythonQt context from file"
143                     << fullPath
144                     << "for module"
145                     << name();
146            return;
147        }
148
149        static const QLatin1Literal calamares_module_annotation(
150                "_calamares_module_typename = ''\n"
151                "def calamares_module(viewmodule_type):\n"
152                "    global _calamares_module_typename\n"
153                "    _calamares_module_typename = viewmodule_type.__name__\n"
154                "    return viewmodule_type\n");
155
156        // Load in the decorator
157        PythonQt::self()->evalScript( cxt, calamares_module_annotation );
158
159        // Load the module
160        PythonQt::self()->evalFile( cxt, fullPath );
161
162        m_viewStep = new PythonQtViewStep( cxt );
163
164        cDebug() << "PythonQtViewModule loading self for instance" << instanceKey()
165                 << "\nPythonQtViewModule at address" << this
166                 << "\nViewStep at address" << m_viewStep;
167
168        m_viewStep->setModuleInstanceKey( instanceKey() );
169        m_viewStep->setConfigurationMap( m_configurationMap );
170        ViewManager::instance()->addViewStep( m_viewStep );
171        m_loaded = true;
172        cDebug() << "PythonQtViewModule" << instanceKey() << "loading complete.";
173    }
174}
175
176
177JobList
178PythonQtViewModule::jobs() const
179{
180    return m_viewStep->jobs();
181}
182
183
184void
185PythonQtViewModule::initFrom( const QVariantMap& moduleDescriptor )
186{
187    Module::initFrom( moduleDescriptor );
188    QDir directory( location() );
189    m_workingPath = directory.absolutePath();
190
191    if ( !moduleDescriptor.value( "script" ).toString().isEmpty() )
192    {
193        m_scriptFileName = moduleDescriptor.value( "script" ).toString();
194    }
195}
196
197PythonQtViewModule::PythonQtViewModule()
198    : Module()
199{
200}
201
202PythonQtViewModule::~PythonQtViewModule()
203{
204}
205
206} // namespace Calamares
Note: See TracBrowser for help on using the repository browser.