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-2021 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"
23 #include "managers/cswordbackend.h"
24 
25 // Sword includes:
26 #include <installmgr.h>
27 #include <swbuf.h>
28 #include <swmgr.h>
29 
30 
31 namespace {
32 
33 inline 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  {
61  installModule();
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) {
100  Q_EMIT statusUpdated(m_currentModuleIndex, 100);
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 
109 void BtInstallThread::slotManagerStatusUpdated(int totalProgress, int /*fileProgress*/) {
110  Q_EMIT statusUpdated(m_currentModuleIndex, totalProgress);
111 }
112 
115 }
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
Definition: cswordbackend.h:98
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)