diff options
author | Maurice Kalinowski <maurice.kalinowski@nokia.com> | 2011-04-08 16:53:35 +0200 |
---|---|---|
committer | Maurice Kalinowski <maurice.kalinowski@nokia.com> | 2011-04-08 16:53:35 +0200 |
commit | 6431cc7a539973e756fbcb2a56cfe72f031b8b48 (patch) | |
tree | 86dd213d372a326a0d8a5c63f5146de08061756b /tools/repocompare | |
parent | ff837125c11be52dcfa11d2c070bced5d6728fac (diff) |
add repocompare
this is a little helper tool comparing to different repositories
and checks for updates. It nominates components which can be
updated and warns about potential errors.
Diffstat (limited to 'tools/repocompare')
-rw-r--r-- | tools/repocompare/main.cpp | 43 | ||||
-rw-r--r-- | tools/repocompare/mainwindow.cpp | 235 | ||||
-rw-r--r-- | tools/repocompare/mainwindow.h | 84 | ||||
-rw-r--r-- | tools/repocompare/mainwindow.ui | 206 | ||||
-rw-r--r-- | tools/repocompare/repocompare.pro | 18 |
5 files changed, 586 insertions, 0 deletions
diff --git a/tools/repocompare/main.cpp b/tools/repocompare/main.cpp new file mode 100644 index 000000000..1914cade3 --- /dev/null +++ b/tools/repocompare/main.cpp @@ -0,0 +1,43 @@ +/************************************************************************** +** +** 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 <QtGui/QApplication> +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/tools/repocompare/mainwindow.cpp b/tools/repocompare/mainwindow.cpp new file mode 100644 index 000000000..b53a39650 --- /dev/null +++ b/tools/repocompare/mainwindow.cpp @@ -0,0 +1,235 @@ +/************************************************************************** +** +** 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 "mainwindow.h" +#include "ui_mainwindow.h" +#include <QtCore/QFile> +#include <QtCore/QTemporaryFile> +#include <QtCore/QMapIterator> +#include <QtCore/QTextStream> +#include <QtCore/QUrl> +#include <QtCore/QXmlStreamReader> +#include <QtGui/QMessageBox> +#include <QtGui/QFileDialog> +#include <QtNetwork/QNetworkReply> +#include <QtNetwork/QNetworkRequest> + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + 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())); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +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); +} + +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); +} + +void MainWindow::receiveRepository(QNetworkReply *reply) +{ + QByteArray data = reply->readAll(); + reply->deleteLater(); + if(reply == productionReply) + createRepositoryMap(data, productionMap); + else if (reply == updateReply) + createRepositoryMap(data, updateMap); + + if (productionMap.size() && updateMap.size()) + compareRepositories(); +} + +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; + if (i == 0) + map = &productionMap; + else + map = &updateMap; + int indexIncrement = 4*i; + for (QMap<QString, RepositoryDescription>::iterator it = map->begin(); it != map->end(); ++it) { + QList<QTreeWidgetItem*> list = ui->treeWidget->findItems(it.key(), Qt::MatchExactly); + QTreeWidgetItem* item; + if (list.size()) + item = list.at(0); + else + item = new QTreeWidgetItem(ui->treeWidget); + + item->setText(0, it.key()); + item->setText(indexIncrement + 3, it.value().version); + 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"); + } + } +} + +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"); + 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(); +} diff --git a/tools/repocompare/mainwindow.h b/tools/repocompare/mainwindow.h new file mode 100644 index 000000000..40b03cf2d --- /dev/null +++ b/tools/repocompare/mainwindow.h @@ -0,0 +1,84 @@ +/************************************************************************** +** +** 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 MAINWINDOW_H +#define MAINWINDOW_H + +#include <QtCore/QTemporaryFile> +#include <QtCore/QUrl> +#include <QtCore/QDate> +#include <QtCore/QString> +#include <QtCore/QMap> +#include <QtGui/QMainWindow> +#include <QtNetwork/QNetworkAccessManager> + +namespace Ui { + class MainWindow; +} + +struct RepositoryDescription { + QString version; + QDate releaseDate; + QString checksum; + QString updateText; +}; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + + void compareRepositories(); + +public slots: + void receiveRepository(QNetworkReply* reply); + void getProductionRepository(); + void getUpdateRepository(); + void createExportFile(); + +private: + void createRepositoryMap(const QByteArray &data, QMap<QString, RepositoryDescription> &map); + + Ui::MainWindow *ui; + QTemporaryFile productionFile; + QTemporaryFile updateFile; + QNetworkReply *productionReply; + QNetworkReply *updateReply; + QNetworkAccessManager *manager; + QMap<QString, RepositoryDescription> productionMap; + QMap<QString, RepositoryDescription> updateMap; +}; + +#endif // MAINWINDOW_H diff --git a/tools/repocompare/mainwindow.ui b/tools/repocompare/mainwindow.ui new file mode 100644 index 000000000..c768b840a --- /dev/null +++ b/tools/repocompare/mainwindow.ui @@ -0,0 +1,206 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>877</width> + <height>613</height> + </rect> + </property> + <property name="windowTitle"> + <string>RepoCompare</string> + </property> + <widget class="QWidget" name="centralWidget"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Production Repository:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="productionRepo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="productionButton"> + <property name="text"> + <string>Receive</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Update Repository:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="updateRepo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="updateButton"> + <property name="text"> + <string>Receive</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QTreeWidget" name="treeWidget"> + <column> + <property name="text"> + <string>Component Name</string> + </property> + </column> + <column> + <property name="text"> + <string>Update required</string> + </property> + </column> + <column> + <property name="text"> + <string>Status</string> + </property> + </column> + <column> + <property name="text"> + <string>Old Version</string> + </property> + </column> + <column> + <property name="text"> + <string>Old Date</string> + </property> + </column> + <column> + <property name="text"> + <string>Old Checksum</string> + </property> + </column> + <column> + <property name="text"> + <string>Old Update Text</string> + </property> + </column> + <column> + <property name="text"> + <string>New Version</string> + </property> + </column> + <column> + <property name="text"> + <string>New Date</string> + </property> + </column> + <column> + <property name="text"> + <string>New Checksum</string> + </property> + </column> + <column> + <property name="text"> + <string>New Update Text</string> + </property> + </column> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="exportButton"> + <property name="text"> + <string>Export Update File</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menuBar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>877</width> + <height>21</height> + </rect> + </property> + <widget class="QMenu" name="menuFile"> + <property name="title"> + <string>File</string> + </property> + <addaction name="actionExit"/> + </widget> + <addaction name="menuFile"/> + </widget> + <widget class="QToolBar" name="mainToolBar"> + <attribute name="toolBarArea"> + <enum>TopToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + </widget> + <widget class="QStatusBar" name="statusBar"/> + <action name="actionExit"> + <property name="text"> + <string>Exit</string> + </property> + </action> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections/> +</ui> diff --git a/tools/repocompare/repocompare.pro b/tools/repocompare/repocompare.pro new file mode 100644 index 000000000..349ac01e9 --- /dev/null +++ b/tools/repocompare/repocompare.pro @@ -0,0 +1,18 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2011-04-04T09:43:46 +# +#------------------------------------------------- + +QT += core gui network + +TARGET = repocompare +TEMPLATE = app + + +SOURCES += main.cpp\ + mainwindow.cpp + +HEADERS += mainwindow.h + +FORMS += mainwindow.ui |