diff options
author | Maurice Kalinowski <maurice.kalinowski@nokia.com> | 2011-10-04 13:37:49 +0200 |
---|---|---|
committer | Tim Jenssen <tim.jenssen@nokia.com> | 2011-10-05 17:50:34 +0200 |
commit | 4ee37dc4dc5c25796a29dd1f5d70f479eb8b713f (patch) | |
tree | 3878baf8b23c5d1861639458ed3224b38a3bf085 /tools/repocompare | |
parent | 80686f13e141850ed4ee4be57ea7e782f4c1328b (diff) |
create headless mode
some build scripts want to generate a update file without launching
any user interface. Introduce some refactoring to be able to use
the networking code from a non-gui application as well
Change-Id: I187b7287095c89e140fbb68d9fdffe42c481ed52
Reviewed-on: http://codereview.qt-project.org/6013
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Tim Jenssen <tim.jenssen@nokia.com>
Reviewed-by: Karsten Heimrich <karsten.heimrich@nokia.com>
Diffstat (limited to 'tools/repocompare')
-rw-r--r-- | tools/repocompare/main.cpp | 28 | ||||
-rw-r--r-- | tools/repocompare/mainwindow.cpp | 159 | ||||
-rw-r--r-- | tools/repocompare/mainwindow.h | 20 | ||||
-rw-r--r-- | tools/repocompare/repocompare.pro | 6 | ||||
-rw-r--r-- | tools/repocompare/repositorymanager.cpp | 195 | ||||
-rw-r--r-- | tools/repocompare/repositorymanager.h | 78 |
6 files changed, 326 insertions, 160 deletions
diff --git a/tools/repocompare/main.cpp b/tools/repocompare/main.cpp index 419e0bd21..cf1e3d19a 100644 --- a/tools/repocompare/main.cpp +++ b/tools/repocompare/main.cpp @@ -31,14 +31,36 @@ ** **************************************************************************/ #include <QtGui/QApplication> +#include <QTimer> +#include <QtCore> #include "mainwindow.h" +#include "repositorymanager.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QCoreApplication::setApplicationName(QLatin1String("IFW_repocompare")); - MainWindow w; - w.show(); + if (a.arguments().contains("-i")) { + if (a.arguments().count() != 5) { + qWarning() << "Usage: " << a.arguments().at(0) << " -i <production Repo> <update Repo> <outputFile>"; + return -1; + } + const QString productionRepo = a.arguments().at(2); + const QString updateRepo = a.arguments().at(3); + const QString outputFile = a.arguments().at(4); + RepositoryManager manager; + manager.setProductionRepository(productionRepo); + manager.setUpdateRepository(updateRepo); + a.connect(&manager, SIGNAL(repositoriesCompared()), &a, SLOT(quit())); + qDebug() << "Waiting for server reply..."; + a.exec(); + qDebug() << "Writing into " << outputFile; + manager.writeUpdateFile(outputFile); + return 0; + } else { + MainWindow w; + w.show(); - return a.exec(); + return a.exec(); + } } diff --git a/tools/repocompare/mainwindow.cpp b/tools/repocompare/mainwindow.cpp index 51a388c72..641cab7e9 100644 --- a/tools/repocompare/mainwindow.cpp +++ b/tools/repocompare/mainwindow.cpp @@ -80,9 +80,8 @@ MainWindow::MainWindow(QWidget *parent) : connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(close())); connect(ui->productionButton, SIGNAL(clicked()), this, SLOT(getProductionRepository())); connect(ui->updateButton, SIGNAL(clicked()), this, SLOT(getUpdateRepository())); - manager = new QNetworkAccessManager(this); - connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(receiveRepository(QNetworkReply*))); connect(ui->exportButton, SIGNAL(clicked()), this, SLOT(createExportFile())); + connect(&manager, SIGNAL(repositoriesCompared()), this, SLOT(displayRepositories())); } MainWindow::~MainWindow() @@ -95,121 +94,29 @@ MainWindow::~MainWindow() void MainWindow::getProductionRepository() { - QUrl url = this->ui->productionRepo->currentText(); - if (!url.isValid()) { - QMessageBox::critical(this, "Error", "Specified URL is not valid"); - return; - } - - if (productionFile.isOpen()) - productionFile.close(); - if (!productionFile.open()) { - QMessageBox::critical(this, "Error", "Could not open File"); - return; - } - - QNetworkRequest request(url); - productionReply = manager->get(request); + manager.setProductionRepository(ui->productionRepo->currentText()); } void MainWindow::getUpdateRepository() { - QUrl url = this->ui->updateRepo->currentText(); - if (!url.isValid()) { - QMessageBox::critical(this, "Error", "Specified URL is not valid"); - return; - } - - if (updateFile.isOpen()) - updateFile.close(); - if (!updateFile.open()) { - QMessageBox::critical(this, "Error", "Could not open File"); - return; - } - - QNetworkRequest request(url); - updateReply = manager->get(request); + manager.setUpdateRepository(ui->updateRepo->currentText()); } -void MainWindow::receiveRepository(QNetworkReply *reply) +void MainWindow::displayRepositories() { - QByteArray data = reply->readAll(); - reply->deleteLater(); - if (reply == productionReply) { - createRepositoryMap(data, productionMap); - uniqueAppend(ui->productionRepo, reply->url().toString()); - } else if (reply == updateReply) { - createRepositoryMap(data, updateMap); - uniqueAppend(ui->updateRepo, reply->url().toString()); - } - if (productionMap.size() && updateMap.size()) - compareRepositories(); -} + uniqueAppend(ui->productionRepo, ui->productionRepo->currentText()); + uniqueAppend(ui->updateRepo, ui->updateRepo->currentText()); -void MainWindow::createRepositoryMap(const QByteArray &data, QMap<QString, RepositoryDescription> &map) -{ - QXmlStreamReader reader(data); - QString currentItem; - RepositoryDescription currentDescription; - while (!reader.atEnd()) { - QXmlStreamReader::TokenType type = reader.readNext(); - if (type == QXmlStreamReader::StartElement) { - if (reader.name() == "PackageUpdate") { - // new package - if (!currentItem.isEmpty()) - map.insert(currentItem, currentDescription); - currentDescription.updateText.clear(); - currentDescription.version.clear(); - currentDescription.checksum.clear(); - } - if (reader.name() == "SHA1") - currentDescription.checksum = reader.readElementText(); - else if (reader.name() == "Version") - currentDescription.version = reader.readElementText(); - else if (reader.name() == "ReleaseDate") - currentDescription.releaseDate = QDate::fromString(reader.readElementText(), "yyyy-MM-dd"); - else if (reader.name() == "UpdateText") - currentDescription.updateText = reader.readElementText(); - else if (reader.name() == "Name") - currentItem = reader.readElementText(); - } - } - // Insert the last item - if (!currentItem.isEmpty()) - map.insert(currentItem, currentDescription); -} - -static qreal createVersionNumber(const QString &text) -{ - QStringList items = text.split(QLatin1Char('.')); - QString last = items.takeLast(); - items.append(last.split(QLatin1Char('-'))); - - qreal value = 0; - if (items.count() == 4) - value += qreal(0.01) * items.takeLast().toInt(); - - int multiplier = 10000; - do { - value += multiplier * items.takeFirst().toInt(); - multiplier /= 100; - } while (items.count()); - - return value; -} - -void MainWindow::compareRepositories() -{ // First we put everything into the treeview for (int i = 0; i < 2; ++i) { - QMap<QString, RepositoryDescription>* map; + QMap<QString, ComponentDescription>* map; if (i == 0) - map = &productionMap; + map = manager.productionComponents(); else - map = &updateMap; + map = manager.updateComponents(); int indexIncrement = 4*i; - for (QMap<QString, RepositoryDescription>::iterator it = map->begin(); it != map->end(); ++it) { + for (QMap<QString, ComponentDescription>::iterator it = map->begin(); it != map->end(); ++it) { QList<QTreeWidgetItem*> list = ui->treeWidget->findItems(it.key(), Qt::MatchExactly); QTreeWidgetItem* item; if (list.size()) @@ -222,29 +129,14 @@ void MainWindow::compareRepositories() item->setText(indexIncrement + 4, it.value().releaseDate.toString("yyyy-MM-dd")); item->setText(indexIncrement + 5, it.value().checksum); item->setText(indexIncrement + 6, it.value().updateText); - } - } - - // Now iterate over the items and check where an update is needed - for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) { - QTreeWidgetItem* item = ui->treeWidget->topLevelItem(i); - if (item->text(3).isEmpty() && !item->text(7).isEmpty()) { - item->setText(1, "Yes"); - item->setText(2, "New Component"); - } else if (item->text(7).isEmpty()) { - item->setText(2, "Caution: component removed"); - } else if (createVersionNumber(item->text(3)) < createVersionNumber(item->text(7))) { - // New Version - item->setText(1, "Yes"); - // Check update date - QDate productionDate = QDate::fromString(item->text(4), "yyyy-MM-dd"); - QDate updateDate = QDate::fromString(item->text(8), "yyyy-MM-dd"); - if (updateDate <= productionDate) - item->setText(2, "Error: Date not correct"); - else if (item->text(6) == item->text(10) || item->text(10).isEmpty()) - item->setText(2, "Error: Update text wrong"); - else - item->setText(2, "Ok"); + if (i != 0) { + QString errorText; + if (manager.updateRequired(it.key(), &errorText)) + item->setText(1, "Yes"); + else + item->setText(1, "No"); + item->setText(2, errorText); + } } } } @@ -252,18 +144,7 @@ void MainWindow::compareRepositories() void MainWindow::createExportFile() { QString fileName = QFileDialog::getSaveFileName(this, "Export File"); - QFile file(fileName); - if (!file.open(QIODevice::ReadWrite)) { - QMessageBox::critical(this, "Error", "Could not open File for saving"); + if (fileName.isEmpty()) return; - } - - QTextStream s(&file); - for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) { - QTreeWidgetItem* item = ui->treeWidget->topLevelItem(i); - if (item->text(1) == "Yes" && item->text(2) == "Ok") - s << item->text(0) << "\n"; - } - s.flush(); - file.close(); + manager.writeUpdateFile(fileName); } diff --git a/tools/repocompare/mainwindow.h b/tools/repocompare/mainwindow.h index 40b03cf2d..bc1e99f22 100644 --- a/tools/repocompare/mainwindow.h +++ b/tools/repocompare/mainwindow.h @@ -33,6 +33,7 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H +#include "repositorymanager.h" #include <QtCore/QTemporaryFile> #include <QtCore/QUrl> #include <QtCore/QDate> @@ -45,12 +46,6 @@ namespace Ui { class MainWindow; } -struct RepositoryDescription { - QString version; - QDate releaseDate; - QString checksum; - QString updateText; -}; class MainWindow : public QMainWindow { @@ -60,25 +55,18 @@ public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); - void compareRepositories(); public slots: - void receiveRepository(QNetworkReply* reply); + void displayRepositories(); void getProductionRepository(); void getUpdateRepository(); void createExportFile(); private: - void createRepositoryMap(const QByteArray &data, QMap<QString, RepositoryDescription> &map); + void createRepositoryMap(const QByteArray &data, QMap<QString, ComponentDescription> &map); Ui::MainWindow *ui; - QTemporaryFile productionFile; - QTemporaryFile updateFile; - QNetworkReply *productionReply; - QNetworkReply *updateReply; - QNetworkAccessManager *manager; - QMap<QString, RepositoryDescription> productionMap; - QMap<QString, RepositoryDescription> updateMap; + RepositoryManager manager; }; #endif // MAINWINDOW_H diff --git a/tools/repocompare/repocompare.pro b/tools/repocompare/repocompare.pro index 349ac01e9..3e576322a 100644 --- a/tools/repocompare/repocompare.pro +++ b/tools/repocompare/repocompare.pro @@ -11,8 +11,10 @@ TEMPLATE = app SOURCES += main.cpp\ - mainwindow.cpp + mainwindow.cpp \ + repositorymanager.cpp -HEADERS += mainwindow.h +HEADERS += mainwindow.h \ + repositorymanager.h FORMS += mainwindow.ui diff --git a/tools/repocompare/repositorymanager.cpp b/tools/repocompare/repositorymanager.cpp new file mode 100644 index 000000000..1e746b480 --- /dev/null +++ b/tools/repocompare/repositorymanager.cpp @@ -0,0 +1,195 @@ +/************************************************************************** +** +** This file is part of Qt SDK** +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** +** Contact: Nokia Corporation qt-info@nokia.com** +** +** No Commercial Usage +** +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception version +** 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you are unsure which license is appropriate for your use, please contact +** (qt-info@nokia.com). +** +**************************************************************************/ +#include "repositorymanager.h" + +#include <QtCore/QDebug> +#include <QtCore/QFile> +#include <QtCore/QStringList> +#include <QtCore/QUrl> +#include <QtNetwork/QNetworkRequest> +#include <QtNetwork/QNetworkReply> +#include <QtXml/QXmlStreamReader> +#include <QtGui/QMessageBox> + +namespace { +qreal createVersionNumber(const QString &text) +{ + QStringList items = text.split(QLatin1Char('.')); + QString last = items.takeLast(); + items.append(last.split(QLatin1Char('-'))); + + qreal value = 0; + if (items.count() == 4) + value += qreal(0.01) * items.takeLast().toInt(); + + int multiplier = 10000; + do { + value += multiplier * items.takeFirst().toInt(); + multiplier /= 100; + } while (items.count()); + + return value; +} +} + +RepositoryManager::RepositoryManager(QObject *parent) : + QObject(parent) +{ + manager = new QNetworkAccessManager(this); + connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(receiveRepository(QNetworkReply*))); + productionMap.clear(); + updateMap.clear(); +} + +void RepositoryManager::setProductionRepository(const QString &repo) +{ + QUrl url(repo); + if (!url.isValid()) { + QMessageBox::critical(0, "Error", "Specified URL is not valid"); + return; + } + + QNetworkRequest request(url); + productionReply = manager->get(request); +} + +void RepositoryManager::setUpdateRepository(const QString &repo) +{ + QUrl url(repo); + if (!url.isValid()) { + QMessageBox::critical(0, "Error", "Specified URL is not valid"); + return; + } + + QNetworkRequest request(url); + updateReply = manager->get(request); +} + +void RepositoryManager::receiveRepository(QNetworkReply *reply) +{ + QByteArray data = reply->readAll(); + if (reply == productionReply) { + createRepositoryMap(data, productionMap); + } else if (reply == updateReply) { + createRepositoryMap(data, updateMap); + } + reply->deleteLater(); + + if (productionMap.size() && updateMap.size()) + compareRepositories(); +} + +void RepositoryManager::createRepositoryMap(const QByteArray &data, QMap<QString, ComponentDescription> &map) +{ + QXmlStreamReader reader(data); + QString currentItem; + ComponentDescription currentDescription; + while (!reader.atEnd()) { + QXmlStreamReader::TokenType type = reader.readNext(); + if (type == QXmlStreamReader::StartElement) { + if (reader.name() == "PackageUpdate") { + // new package + if (!currentItem.isEmpty()) + map.insert(currentItem, currentDescription); + currentDescription.updateText.clear(); + currentDescription.version.clear(); + currentDescription.checksum.clear(); + } + if (reader.name() == "SHA1") + currentDescription.checksum = reader.readElementText(); + else if (reader.name() == "Version") + currentDescription.version = reader.readElementText(); + else if (reader.name() == "ReleaseDate") + currentDescription.releaseDate = QDate::fromString(reader.readElementText(), "yyyy-MM-dd"); + else if (reader.name() == "UpdateText") + currentDescription.updateText = reader.readElementText(); + else if (reader.name() == "Name") + currentItem = reader.readElementText(); + } + } + // Insert the last item + if (!currentItem.isEmpty()) + map.insert(currentItem, currentDescription); +} + +void RepositoryManager::compareRepositories() +{ + for (QMap<QString, ComponentDescription>::iterator it = updateMap.begin(); it != updateMap.end(); ++it) { + // New item in the update + if (!productionMap.contains(it.key())) { + it.value().update = true; + continue; + } + it.value().update = updateRequired(it.key()); + } + emit repositoriesCompared(); +} + +bool RepositoryManager::updateRequired(const QString &componentName, QString *message) +{ + if (!productionMap.contains(componentName) || !updateMap.contains(componentName)) + qFatal("Accessing non existing component"); + const ComponentDescription &productionDescription = productionMap.value(componentName); + const ComponentDescription &updateDescription = updateMap.value(componentName); + if (createVersionNumber(productionDescription.version) < createVersionNumber(updateDescription.version)) { + if (productionDescription.releaseDate >= updateDescription.releaseDate) { + if (message) + *message = QString::fromLatin1("Error: Component %1 has wrong release date %2").arg(componentName).arg(updateDescription.releaseDate.toString()); + return false; + } else if (productionDescription.updateText == updateDescription.updateText) + if (message) + *message = QString::fromLatin1("Warning: Component %1 has no new update text: %2").arg(componentName).arg(updateDescription.updateText); + if (message && message->isEmpty()) + *message = QLatin1String("Ok"); + return true; + } + return false; +} + +void RepositoryManager::writeUpdateFile(const QString &fileName) +{ + QFile file(fileName); + if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) { + QMessageBox::critical(0, "Error", "Could not open File for saving"); + return; + } + + QStringList items; + for (QMap<QString, ComponentDescription>::const_iterator it = updateMap.begin(); it != updateMap.end(); ++it) { + if (it.value().update) + items.append(it.key()); + } + + file.write(items.join(QLatin1String(",")).toLatin1()); + file.close(); +} diff --git a/tools/repocompare/repositorymanager.h b/tools/repocompare/repositorymanager.h new file mode 100644 index 000000000..1f5f3bb86 --- /dev/null +++ b/tools/repocompare/repositorymanager.h @@ -0,0 +1,78 @@ +/************************************************************************** +** +** This file is part of Qt SDK** +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).* +** +** Contact: Nokia Corporation qt-info@nokia.com** +** +** No Commercial Usage +** +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception version +** 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you are unsure which license is appropriate for your use, please contact +** (qt-info@nokia.com). +** +**************************************************************************/ +#ifndef REPOSITORYMANAGER_H +#define REPOSITORYMANAGER_H + +#include <QtCore/QObject> +#include <QtCore/QMap> +#include <QtCore/QDate> +#include <QtNetwork/QNetworkAccessManager> + +struct ComponentDescription { + QString version; + QDate releaseDate; + QString checksum; + QString updateText; + bool update; +}; + +class RepositoryManager : public QObject +{ + Q_OBJECT +public: + explicit RepositoryManager(QObject *parent = 0); + + bool updateRequired(const QString &componentName, QString *message = 0); + QMap<QString, ComponentDescription>* productionComponents() { return &productionMap; } + QMap<QString, ComponentDescription>* updateComponents() { return &updateMap; } +signals: + void repositoriesCompared(); + +public slots: + void setProductionRepository(const QString &repo); + void setUpdateRepository(const QString &repo); + void writeUpdateFile(const QString &fileName); + + void receiveRepository(QNetworkReply *reply); + + void compareRepositories(); +private: + void createRepositoryMap(const QByteArray &data, QMap<QString, ComponentDescription> &map); + QNetworkReply *productionReply; + QNetworkReply *updateReply; + QNetworkAccessManager *manager; + QMap<QString, ComponentDescription> productionMap; + QMap<QString, ComponentDescription> updateMap; +}; + +#endif // REPOSITORYMANAGER_H |