BibleTime
btinstallthread.cpp
Go to the documentation of this file.
1/*********
2*
3* In the name of the Father, and of the Son, and of the Holy Spirit.
4*
5* This file is part of BibleTime's source code, https://bibletime.info/
6*
7* Copyright 1999-2025 by the BibleTime developers.
8* The BibleTime source code is licensed under the GNU General Public License
9* version 2.0.
10*
11**********/
12
13#include "btinstallthread.h"
14
15#include <memory>
16#include <QDebug>
17#include <QByteArray>
18#include <QDir>
19#include <QString>
20#include <QVariant>
21#include "btinstallbackend.h"
24
25// Sword includes:
26#include <installmgr.h>
27#include <swbuf.h>
28#include <swmgr.h>
29
30
31namespace {
32
33inline bool runMkdir(QDir & dir, const QString & dirName) {
34 if (!dir.exists(dirName)) {
35 if (!dir.mkpath(dirName)) {
36 qDebug() << "failed to make directory" << dirName;
37 return false;
38 }
39 qDebug() << "made directory" << dirName;
40 }
41 return true;
42}
43
44}
45
47 // Make sure target/mods.d and target/modules exist
48 /// \todo move this to some common precondition
49 QDir dir(m_destination);
50 if (!runMkdir(dir, m_destination)
51 || !runMkdir(dir, "modules")
52 || !runMkdir(dir, "mods.d"))
53 {
54 return;
55 }
56
57 for (m_currentModuleIndex = 0;
60 {
62 if (m_stopRequested.load(std::memory_order_relaxed))
63 break;
64 }
65}
66
69
70 const CSwordModuleInfo * const module = m_modules.at(m_currentModuleIndex);
71
72 QVariant vModuleName = module->property("installSourceName");
73 QString moduleName = vModuleName.toString();
74 sword::InstallSource installSource = BtInstallBackend::source(moduleName);
75
76 // Check whether it's an update. If yes, remove existing module first:
77 /// \todo silently removing without undo if the user cancels the update is WRONG!!!
78 if (!removeModule() && m_stopRequested.load(std::memory_order_relaxed))
79 return;
80
81 // manager for the destination path
82 sword::SWMgr lMgr(m_destination.toLatin1());
83 if (BtInstallBackend::isRemote(installSource)) {
84 int status = m_iMgr.installModule(&lMgr,
85 nullptr,
86 module->name().toLatin1(),
87 &installSource);
88 if (status == 0) {
90 } else {
91 qWarning() << "Error with install: " << status
92 << "module:" << module->name();
93 }
94 Q_EMIT installCompleted(m_currentModuleIndex, status == 0);
95 } else { // Local source
96 int status = m_iMgr.installModule(&lMgr,
97 installSource.directory.c_str(),
98 module->name().toLatin1());
99 if (status == 0) {
101 } else if (status != -1) {
102 qWarning() << "Error with install: " << status
103 << "module:" << module->name();
104 }
105 Q_EMIT installCompleted(m_currentModuleIndex, status == 0);
106 }
107}
108
109void BtInstallThread::slotManagerStatusUpdated(int totalProgress, int /*fileProgress*/) {
110 Q_EMIT statusUpdated(m_currentModuleIndex, totalProgress);
111}
112
116
118 CSwordModuleInfo * const installedModule = m_modules.at(m_currentModuleIndex);
119 CSwordModuleInfo const * m =
120 CSwordBackend::instance().findModuleByName(installedModule->name());
121 std::unique_ptr<CSwordBackend const> backend;
122 if (!m) {
125 m = backend->findModuleByName(installedModule->name());
126 }
127
128 if (!m)
129 return false;
130
131 qDebug() << "Removing module" << installedModule->name();
132 QString prefixPath = m->config(CSwordModuleInfo::AbsoluteDataPath) + '/';
133 QString dataPath = m->config(CSwordModuleInfo::DataPath);
134 auto const moduleName(m->name());
135 backend.reset();
136
137 if (dataPath.left(2) == QStringLiteral("./"))
138 dataPath = dataPath.mid(2);
139
140 if (prefixPath.contains(dataPath)) {
141 prefixPath.remove(prefixPath.indexOf(dataPath), dataPath.length());
142 } else {
143 prefixPath = CSwordBackend::instance().prefixPath();
144 }
145
146 sword::SWMgr mgr(prefixPath.toLatin1());
147 BtInstallMgr().removeModule(&mgr, moduleName.toLatin1());
148 return true;
149}
void downloadStarted(int moduleIndex)
void preparingInstall(int moduleIndex)
void installCompleted(int moduleIndex, bool success)
std::atomic< bool > m_stopRequested
void statusUpdated(int moduleIndex, int progressPercent)
void slotManagerStatusUpdated(int totalProgress, int fileProgress)
void run() override
const QString m_destination
const QList< CSwordModuleInfo * > & m_modules
BtInstallMgr m_iMgr
CSwordModuleInfo * findModuleByName(const QString &name) const
Searches for a module with the given name.
QString prefixPath() const
static CSwordBackend & instance() noexcept
QString config(const CSwordModuleInfo::ConfigEntry entry) const
QString const & name() const
bool isRemote(const sword::InstallSource &source)
sword::InstallSource source(const QString &name)
std::unique_ptr< CSwordBackend > backend(sword::InstallSource const &is)
bool runMkdir(QDir &dir, const QString &dirName)