diff options
author | kh1 <karsten.heimrich@nokia.com> | 2012-01-20 15:08:13 +0100 |
---|---|---|
committer | Karsten Heimrich <karsten.heimrich@nokia.com> | 2012-01-20 16:39:49 +0100 |
commit | e5557f134e78cf4673b29b5ab124e3f403f0b3c7 (patch) | |
tree | 1291b7d21abf9e946abc0335e6ae8178e21253f8 | |
parent | 6d50d407c0047d75a7c746e1147a107ee3c75bad (diff) |
Initial part to update repositories.
Change-Id: I247cca06386eee0f1af084ac4c15a813e38c3f02
Reviewed-by: Alexander Lenhardt <alexander.lenhardt@nokia.com>
8 files changed, 144 insertions, 51 deletions
diff --git a/installerbuilder/libinstaller/getrepositoriesmetainfojob.cpp b/installerbuilder/libinstaller/getrepositoriesmetainfojob.cpp index ada5bcabe..c5df1d993 100644 --- a/installerbuilder/libinstaller/getrepositoriesmetainfojob.cpp +++ b/installerbuilder/libinstaller/getrepositoriesmetainfojob.cpp @@ -58,11 +58,6 @@ QSet<Repository> GetRepositoriesMetaInfoJob::repositories() const return m_repositories; } -QHash<Repository, Repository> GetRepositoriesMetaInfoJob::redirects() const -{ - return m_redirects; -} - void GetRepositoriesMetaInfoJob::setRepositories(const QSet<Repository> &repos) { m_repositories = repos; @@ -72,6 +67,11 @@ void GetRepositoriesMetaInfoJob::setRepositories(const QSet<Repository> &repos) } } +QHash<QString, QPair<Repository, Repository> > GetRepositoriesMetaInfoJob::repositoryUpdates() const +{ + return m_repositoryUpdates; +} + QStringList GetRepositoriesMetaInfoJob::temporaryDirectories() const { return m_repositoryByTemporaryDirectory.keys(); @@ -125,6 +125,8 @@ bool GetRepositoriesMetaInfoJob::isCanceled() const return m_canceled; } +// -- private Q_SLOTS + void GetRepositoriesMetaInfoJob::doStart() { fetchNextRepo(); @@ -162,7 +164,7 @@ void GetRepositoriesMetaInfoJob::fetchNextRepo() connect(m_job, SIGNAL(infoMessage(KDJob*, QString)), this, SIGNAL(infoMessage(KDJob*, QString))); m_job->setSilentRetries(silentRetries()); - m_job->setRepository(m_currentRepository = m_tmpRepositories.takeLast()); + m_job->setRepository(m_tmpRepositories.takeLast()); m_job->start(); } @@ -186,6 +188,13 @@ void GetRepositoriesMetaInfoJob::jobFinished(KDJob *j) return; } + if (job->error() == QInstaller::RepositoryUpdatesReceived) { + qDebug() << job->errorString(); + m_repositoryUpdates = job->repositoryUpdates(); + emitFinishedWithError(job->error(), job->errorString()); + return; + } + if (job->error() == QInstaller::UserIgnoreError) { m_haveIgnoredError = true; m_errorString = job->errorString(); @@ -193,8 +202,6 @@ void GetRepositoriesMetaInfoJob::jobFinished(KDJob *j) const QString &tmpdir = job->releaseTemporaryDirectory(); job->m_tempDirDeleter.passAndRelease(m_tempDirDeleter, tmpdir); m_repositoryByTemporaryDirectory.insert(tmpdir, job->repository()); - if (m_currentRepository != job->repository()) - m_redirects.insert(m_currentRepository, job->repository()); } QMetaObject::invokeMethod(this, "fetchNextRepo", Qt::QueuedConnection); } diff --git a/installerbuilder/libinstaller/getrepositoriesmetainfojob.h b/installerbuilder/libinstaller/getrepositoriesmetainfojob.h index 3ef832fae..cf6a3b645 100644 --- a/installerbuilder/libinstaller/getrepositoriesmetainfojob.h +++ b/installerbuilder/libinstaller/getrepositoriesmetainfojob.h @@ -54,8 +54,8 @@ public: explicit GetRepositoriesMetaInfoJob(const QByteArray &publicKey, QObject *parent = 0); QSet<Repository> repositories() const; - QHash<Repository, Repository> redirects() const; void setRepositories(const QSet<Repository> &repositories); + QHash<QString, QPair<Repository, Repository> > repositoryUpdates() const; QStringList temporaryDirectories() const; QStringList releaseTemporaryDirectories() const; @@ -88,8 +88,7 @@ private: QString m_errorString; mutable TempDirDeleter m_tempDirDeleter; - Repository m_currentRepository; - QHash<Repository, Repository> m_redirects; + QHash<QString, QPair<Repository, Repository> > m_repositoryUpdates; }; } // namespace QInstaller diff --git a/installerbuilder/libinstaller/getrepositorymetainfojob.cpp b/installerbuilder/libinstaller/getrepositorymetainfojob.cpp index 41171fa87..7ccf9eaf7 100644 --- a/installerbuilder/libinstaller/getrepositorymetainfojob.cpp +++ b/installerbuilder/libinstaller/getrepositorymetainfojob.cpp @@ -151,6 +151,11 @@ void GetRepositoryMetaInfoJob::setSilentRetries(int retries) m_silentRetries = retries; } +QHash<QString, QPair<Repository, Repository> > GetRepositoryMetaInfoJob::repositoryUpdates() const +{ + return m_repositoryUpdates; +} + void GetRepositoryMetaInfoJob::doStart() { m_retriesLeft = m_silentRetries; @@ -279,6 +284,54 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished() emit infoMessage(this, tr("Parsing component meta information...")); const QDomElement root = doc.documentElement(); + + m_repositoryUpdates.clear(); + // search for additional repositories that we might need to check + const QDomNode repositoryUpdate = root.firstChildElement(QLatin1String("RepositoryUpdate")); + if (!repositoryUpdate.isNull()) { + const QDomNodeList children = repositoryUpdate.toElement().childNodes(); + for (int i = 0; i < children.count(); ++i) { + const QDomElement el = children.at(i).toElement(); + if (!el.isNull() && el.tagName() == QLatin1String("Repository")) { + const QString action = el.attribute(QLatin1String("action")); + if (action == QLatin1String("add")) { + // add a new repository to the defaults list + Repository repository(el.attribute(QLatin1String("url")), true); + repository.setUsername(el.attribute(QLatin1String("username"))); + repository.setPassword(el.attribute(QLatin1String("password"))); + m_repositoryUpdates.insertMulti(action, qMakePair(repository, Repository())); + + qDebug() << "Added new repository:" << repository.url().toString(); + } else if (action == QLatin1String("remove")) { + // remove possible default repositories using the given server url + Repository repository(el.attribute(QLatin1String("url")), true); + m_repositoryUpdates.insertMulti(action, qMakePair(repository, Repository())); + + qDebug() << "Repository to remove:" << repository.url().toString(); + } else if (action == QLatin1String("replace")) { + // replace possible default repositories using the given server url + Repository oldRepository(el.attribute(QLatin1String("oldUrl")), true); + Repository newRepository(el.attribute(QLatin1String("newUrl")), true); + newRepository.setUsername(el.attribute(QLatin1String("username"))); + newRepository.setPassword(el.attribute(QLatin1String("password"))); + + // store the new repository and the one old it replaces + m_repositoryUpdates.insertMulti(action, qMakePair(newRepository, oldRepository)); + qDebug() << "Replace repository:" << oldRepository.url().toString() << "with:" + << newRepository.url().toString(); + } else { + qDebug() << "Invalid additional repositories action set in updates.xml fetched from:" + << m_repository.url().toString() << "Line:" << el.lineNumber(); + } + } + } + + if (!m_repositoryUpdates.isEmpty()) { + finished(QInstaller::RepositoryUpdatesReceived, tr("Repository updates received.")); + return; + } + } + const QDomNodeList children = root.childNodes(); for (int i = 0; i < children.count(); ++i) { const QDomElement el = children.at(i).toElement(); @@ -293,10 +346,6 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished() m_packageVersions << c2.at(j).toElement().text(); else if (c2.at(j).toElement().tagName() == QLatin1String("SHA1")) m_packageHash << c2.at(j).toElement().text(); - } else if (el.tagName() == QLatin1String("RedirectUpdateUrl")) { // received a new URL for package download - m_repository.setUrl(QUrl(el.text())); // update the internal repo container - startUpdatesXmlDownload(); // ... and start over - return; } } diff --git a/installerbuilder/libinstaller/getrepositorymetainfojob.h b/installerbuilder/libinstaller/getrepositorymetainfojob.h index fe257ac03..75f8794fd 100644 --- a/installerbuilder/libinstaller/getrepositorymetainfojob.h +++ b/installerbuilder/libinstaller/getrepositorymetainfojob.h @@ -28,6 +28,7 @@ #include <kdjob.h> +#include <QtCore/QHash> #include <QtCore/QPointer> #include <QtCore/QString> #include <QtCore/QStringList> @@ -65,6 +66,8 @@ public: QString temporaryDirectory() const; QString releaseTemporaryDirectory() const; + QHash<QString, QPair<Repository, Repository> > repositoryUpdates() const; + private: /* reimp */ void doStart(); /* reimp */ void doCancel(); @@ -100,6 +103,8 @@ private: bool m_waitForDone; QThreadPool m_threadPool; + + QHash<QString, QPair<Repository, Repository> > m_repositoryUpdates; }; } // namespace QInstaller diff --git a/installerbuilder/libinstaller/packagemanagercore_p.cpp b/installerbuilder/libinstaller/packagemanagercore_p.cpp index 3af6db817..11a4d38a3 100644 --- a/installerbuilder/libinstaller/packagemanagercore_p.cpp +++ b/installerbuilder/libinstaller/packagemanagercore_p.cpp @@ -2035,15 +2035,25 @@ bool PackageManagerCorePrivate::fetchMetaInformationFromRepositories() } if (m_repoMetaInfoJob->isCanceled() || m_repoMetaInfoJob->error() != KDJob::NoError) { - if (m_repoMetaInfoJob->error() != QInstaller::UserIgnoreError) { - setStatus(PackageManagerCore::Failure, m_repoMetaInfoJob->errorString()); - return m_repoFetched; + switch (m_repoMetaInfoJob->error()) { + case QInstaller::UserIgnoreError: + break; // we can simply ignore this error, the user knows about it + + case QInstaller::RepositoryUpdatesReceived: + if (m_settings.updateDefaultRepositories(m_repoMetaInfoJob->repositoryUpdates()) + == Settings::UpdatesApplied) { + fetchMetaInformationFromRepositories(); // start over, we might have complete new repos + return m_repoFetched; + } + break; + + default: + setStatus(PackageManagerCore::Failure, m_repoMetaInfoJob->errorString()); + return m_repoFetched; } } m_repoFetched = true; - m_settings.updateRepositories(m_repoMetaInfoJob->redirects()); - return m_repoFetched; } diff --git a/installerbuilder/libinstaller/qinstallerglobal.h b/installerbuilder/libinstaller/qinstallerglobal.h index 1b4d79221..e1cde0de0 100644 --- a/installerbuilder/libinstaller/qinstallerglobal.h +++ b/installerbuilder/libinstaller/qinstallerglobal.h @@ -55,7 +55,8 @@ enum INSTALLER_EXPORT JobError InvalidUpdatesXml, InvalidMetaInfo, ExtractionError, - UserIgnoreError + UserIgnoreError, + RepositoryUpdatesReceived }; typedef KDUpdater::UpdateOperation Operation; diff --git a/installerbuilder/libinstaller/settings.cpp b/installerbuilder/libinstaller/settings.cpp index aaa175ae9..5003c97af 100644 --- a/installerbuilder/libinstaller/settings.cpp +++ b/installerbuilder/libinstaller/settings.cpp @@ -163,25 +163,6 @@ public: return path; return m_data.value(scPrefix).toString() + QLatin1String("/") + path; } - - void updateRepositories(const QHash<Repository, Repository> &updates, const QString &repoType) - { - bool update = false; - QSet<Repository> repositories = variantListToSet<Repository>(m_data.values(repoType)); - foreach (const Repository &repo, updates.keys()) { - if (repositories.contains(repo)) { - update = true; - repositories.remove(repo); - repositories.insert(updates.value(repo)); - } - } - - if (update) { - m_data.remove(repoType); - foreach (const Repository &repository, repositories) - m_data.insertMulti(repoType, QVariant().fromValue(repository)); - } - } }; @@ -409,16 +390,6 @@ QSet<Repository> Settings::repositories() const + d->m_data.values(scUserRepositories) + d->m_data.values(scTmpRepositories)); } -void Settings::updateRepositories(const QHash<Repository, Repository> &updates) -{ - if (updates.isEmpty()) - return; - - d->updateRepositories(updates, scRepositories); - d->updateRepositories(updates, scTmpRepositories); - d->updateRepositories(updates, scUserRepositories); -} - QSet<Repository> Settings::defaultRepositories() const { return variantListToSet<Repository>(d->m_data.values(scRepositories)); @@ -436,6 +407,52 @@ void Settings::addDefaultRepositories(const QSet<Repository> &repositories) d->m_data.insertMulti(scRepositories, QVariant().fromValue(repository)); } +Settings::Update +Settings::updateDefaultRepositories(const QHash<QString, QPair<Repository, Repository> > &updates) +{ + if (updates.isEmpty()) + return Settings::NoUpdatesApplied; + + QHash <QUrl, Repository> defaultRepos; + foreach (const QVariant &variant, d->m_data.values(scRepositories)) { + const Repository repository = variant.value<Repository>(); + defaultRepos.insert(repository.url(), repository); + } + + bool update = false; + QList<QPair<Repository, Repository> > values = updates.values(QLatin1String("replace")); + for (int a = 0; a < values.count(); ++a) { + const QPair<Repository, Repository> data = values.at(a); + if (defaultRepos.contains(data.second.url())) { + update = true; + defaultRepos.remove(data.second.url()); + defaultRepos.insert(data.first.url(), data.first); + } + } + + values = updates.values(QLatin1String("remove")); + for (int a = 0; a < values.count(); ++a) { + const QPair<Repository, Repository> data = values.at(a); + if (defaultRepos.contains(data.first.url())) { + update = true; + defaultRepos.remove(data.first.url()); + } + } + + values = updates.values(QLatin1String("add")); + for (int a = 0; a < values.count(); ++a) { + const QPair<Repository, Repository> data = values.at(a); + if (!defaultRepos.contains(data.first.url())) { + update = true; + defaultRepos.insert(data.first.url(), data.first); + } + } + + if (update) + setDefaultRepositories(defaultRepos.values().toSet()); + return update ? Settings::UpdatesApplied : Settings::NoUpdatesApplied; +} + QSet<Repository> Settings::temporaryRepositories() const { return variantListToSet<Repository>(d->m_data.values(scTmpRepositories)); diff --git a/installerbuilder/libinstaller/settings.h b/installerbuilder/libinstaller/settings.h index 15469fadb..6f15b4b7a 100644 --- a/installerbuilder/libinstaller/settings.h +++ b/installerbuilder/libinstaller/settings.h @@ -45,6 +45,11 @@ class INSTALLER_EXPORT Settings Q_DECLARE_TR_FUNCTIONS(Settings) public: + enum Update { + UpdatesApplied, + NoUpdatesApplied + }; + enum ProxyType { NoProxy, SystemProxy, @@ -89,11 +94,11 @@ public: bool hasReplacementRepos() const; QSet<Repository> repositories() const; - void updateRepositories(const QHash<Repository, Repository> &updates); QSet<Repository> defaultRepositories() const; void setDefaultRepositories(const QSet<Repository> &repositories); void addDefaultRepositories(const QSet<Repository> &repositories); + Settings::Update updateDefaultRepositories(const QHash<QString, QPair<Repository, Repository> > &updates); QSet<Repository> temporaryRepositories() const; void setTemporaryRepositories(const QSet<Repository> &repositories, bool replace); |