summaryrefslogtreecommitdiff
path: root/src/frontend/bookshelfmanager/installpage/btinstallthread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/bookshelfmanager/installpage/btinstallthread.cpp')
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallthread.cpp199
1 files changed, 199 insertions, 0 deletions
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallthread.cpp b/src/frontend/bookshelfmanager/installpage/btinstallthread.cpp
new file mode 100644
index 0000000..adab4fa
--- /dev/null
+++ b/src/frontend/bookshelfmanager/installpage/btinstallthread.cpp
@@ -0,0 +1,199 @@
+/*********
+*
+* This file is part of BibleTime's source code, http://www.bibletime.info/.
+*
+* Copyright 1999-2008 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License version 2.0.
+*
+**********/
+
+#include "btinstallthread.h"
+
+#include "frontend/bookshelfmanager/btinstallmgr.h"
+#include "frontend/bookshelfmanager/instbackend.h"
+#include "util/cpointers.h"
+#include "backend/managers/cswordbackend.h"
+
+#include <QApplication>
+#include <QString>
+#include <QThread>
+#include <QDir>
+
+#include <QDebug>
+
+// sword
+#include <filemgr.h>
+
+BtInstallThread::BtInstallThread(QObject* parent, QString moduleName, QString sourceName, QString destinationName)
+ : QThread(parent),
+ done(false),
+ m_module(moduleName),
+ m_destination(destinationName),
+ m_source(sourceName),
+ m_cancelled(false),
+ m_installSource(instbackend::source(sourceName)),
+ m_backendForSource(instbackend::backend(m_installSource))
+{
+ m_iMgr = new BtInstallMgr();
+}
+
+
+BtInstallThread::~BtInstallThread()
+{
+ delete m_iMgr;
+}
+
+void BtInstallThread::run()
+{
+ qDebug() << "****************************************\nBtInstallThread::run, mod:" << m_module << "\n************************************";
+
+
+ emit preparingInstall(m_module, m_source);
+
+ //make sure target/mods.d and target/modules exist
+ //TODO: move this to some common precondition
+ QDir dir(m_destination);
+ if (!dir.exists()) {
+ dir.mkdir(m_destination);
+ qDebug() << "made directory" << m_destination;
+ }
+ if (!dir.exists("modules")) {
+ dir.mkdir("modules");
+ qDebug() << "made directory" << m_destination << "/modules";
+ }
+ if (!dir.exists("mods.d")) {
+ dir.mkdir("mods.d");
+ qDebug() << "made directory" << m_destination << "/mods.d";
+ }
+
+ QObject::connect(m_iMgr, SIGNAL(percentCompleted(int, int)), this, SLOT(slotManagerStatusUpdated(int, int)), Qt::QueuedConnection);
+ QObject::connect(m_iMgr, SIGNAL(downloadStarted()), this, SLOT(slotDownloadStarted()), Qt::QueuedConnection);
+
+ //check whether it's an update. If yes, remove existing module first
+ //TODO: silently removing without undo if the user cancels the update is WRONG!!!
+ removeModule();
+
+ // manager for the destination path
+ sword::SWMgr lMgr( m_destination.toLatin1() );
+
+ if (instbackend::isRemote(m_installSource)) {
+ qDebug() << "calling install";
+ int status = m_iMgr->installModule(&lMgr, 0, m_module.toLatin1(), &m_installSource);
+ if (status != 0) {
+ qWarning() << "Error with install: " << status << "module:" << m_module;
+ }
+ else {
+ done = true;
+ emit installCompleted(m_module, m_source, status);
+ }
+ }
+ else { //local source
+ emit statusUpdated(m_module, 0);
+ int status = m_iMgr->installModule(&lMgr, m_installSource.directory.c_str(), m_module.toLatin1());
+ if (status > 0) {
+ qWarning() << "Error with install: " << status << "module:" << m_module;
+ }
+ else if (status == -1) {
+ // it was terminated, do nothing
+ }
+ else {
+ emit statusUpdated(m_module, 100);
+ done = true;
+ emit installCompleted(m_module, m_source, status);
+ }
+ }
+}
+
+void BtInstallThread::slotStopInstall()
+{
+ qDebug() << "*************************************\nBtInstallThread::slotStopInstall" << m_module << "\n********************************";
+ if (!done) {
+ done = true;
+ qDebug() << "*********************************\nBtInstallThread::slotStopInstall, installing" << m_module << "was cancelled\n**************************************";
+ m_iMgr->terminate();
+ //this->terminate(); // It's dangerous to forcibly stop, but we will clean up the files
+ qDebug() << "BtInstallThread::slotStopInstall 2";
+ //qApp->processEvents();
+ // wait to terminate for some secs. We rather let the execution go on and cleaning up to fail than the app to freeze
+ int notRun = this->wait(200);
+ if (notRun) {
+ this->terminate();
+ this->wait(2);
+ qDebug() << "installthread ("<< m_module << ") terminated, delete m_iMgr";
+ delete m_iMgr; // this makes sure the ftp library will be cleaned up in the destroyer
+ m_iMgr = 0;
+ }
+ qDebug() << "BtInstallThread::slotStopInstall 3";
+ // cleanup: remove the module, remove the temp files
+ if (true) {
+ qDebug() << "BtInstallThread::slotStopInstall 4";
+ // remove the installed module, just to be sure because mgr may
+ // have been terminated when copying files
+ removeModule();
+ removeTempFiles();
+ qDebug() << "BtInstallThread::slotStopInstall will emit installStopped...";
+ emit installStopped(m_module, m_source);
+ }
+ }
+}
+
+void BtInstallThread::slotManagerStatusUpdated(int totalProgress, int /*fileProgress*/)
+{
+ //qDebug("BtInstallThread::slotManagerStatusUpdated");
+ emit statusUpdated(m_module, totalProgress);
+}
+
+void BtInstallThread::slotDownloadStarted()
+{
+ qDebug("BtInstallThread::slotDownloadStarted");
+ emit downloadStarted(m_module);
+}
+
+void BtInstallThread::removeModule()
+{
+ qDebug() << "BtInstallThread::removeModule start";
+ CSwordModuleInfo* m;
+ m = CPointers::backend()->findModuleByName(m_module);
+ if (!m) {
+ m = instbackend::backend(instbackend::source(m_destination.toLatin1()))->findModuleByName(m_module);
+ }
+ if (m) { //module found?
+ qDebug() << "BtInstallThread::removeModule, module" << m_module << "found";
+ QString prefixPath = m->config(CSwordModuleInfo::AbsoluteDataPath) + "/";
+ QString dataPath = m->config(CSwordModuleInfo::DataPath);
+ if (dataPath.left(2) == "./") {
+ dataPath = dataPath.mid(2);
+ }
+
+ if (prefixPath.contains(dataPath)) {
+ prefixPath.remove( prefixPath.indexOf(dataPath), dataPath.length() );
+ }
+ else {
+ prefixPath = QString::fromLatin1(CPointers::backend()->prefixPath);
+ }
+
+ sword::SWMgr mgr(prefixPath.toLatin1());
+ BtInstallMgr iMgr;
+ iMgr.removeModule(&mgr, m->name().toLatin1());
+ } else {
+ qDebug() << "BtInstallThread::removeModule, module" << m_module << "not found";
+ }
+}
+
+void BtInstallThread::removeTempFiles()
+{
+ qDebug("BtInstallThread::removeTempFiles start");
+
+ // (take the remote conf file for this module, take DataPath,
+ // take the absolute path of the InstallMgr)
+
+ //sword::InstallSource is = instbackend::source(m_source);
+ if (instbackend::isRemote(m_installSource)) {
+ // get the path for the module temp files
+ CSwordModuleInfo* mInfo = m_backendForSource->findModuleByName(m_module);
+ QString dataPath = mInfo->config(CSwordModuleInfo::AbsoluteDataPath);
+ qDebug() << "Delete path:" << dataPath;
+ // it's easier to use sword than qt
+ sword::FileMgr::removeDir(dataPath.toLatin1().data());
+ }
+}