summaryrefslogtreecommitdiffstats
path: root/tools/repocompare
diff options
context:
space:
mode:
authorMaurice Kalinowski <maurice.kalinowski@nokia.com>2011-04-08 16:53:35 +0200
committerMaurice Kalinowski <maurice.kalinowski@nokia.com>2011-04-08 16:53:35 +0200
commit6431cc7a539973e756fbcb2a56cfe72f031b8b48 (patch)
tree86dd213d372a326a0d8a5c63f5146de08061756b /tools/repocompare
parentff837125c11be52dcfa11d2c070bced5d6728fac (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.cpp43
-rw-r--r--tools/repocompare/mainwindow.cpp235
-rw-r--r--tools/repocompare/mainwindow.h84
-rw-r--r--tools/repocompare/mainwindow.ui206
-rw-r--r--tools/repocompare/repocompare.pro18
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