summaryrefslogtreecommitdiffstats
path: root/repogenfromonlinerepo
diff options
context:
space:
mode:
authorTim Jenssen <tim.jenssen@nokia.com>2011-02-21 16:30:31 +0100
committerTim Jenssen <tim.jenssen@nokia.com>2011-02-21 16:41:32 +0100
commit8457830abdca9d5769e2ec1bdbfb793a05e6c5dd (patch)
tree4c9e87efd34104ec59ae31efd0394e998a2434f7 /repogenfromonlinerepo
init commit
Diffstat (limited to 'repogenfromonlinerepo')
-rw-r--r--repogenfromonlinerepo/downloadmanager.cpp172
-rw-r--r--repogenfromonlinerepo/downloadmanager.h84
-rw-r--r--repogenfromonlinerepo/main.cpp306
-rw-r--r--repogenfromonlinerepo/repogenfromonlinerepo.pro16
-rw-r--r--repogenfromonlinerepo/textprogressbar.cpp98
-rw-r--r--repogenfromonlinerepo/textprogressbar.h63
6 files changed, 739 insertions, 0 deletions
diff --git a/repogenfromonlinerepo/downloadmanager.cpp b/repogenfromonlinerepo/downloadmanager.cpp
new file mode 100644
index 000000000..61bf7ea88
--- /dev/null
+++ b/repogenfromonlinerepo/downloadmanager.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "downloadmanager.h"
+
+#include <QFileInfo>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QString>
+#include <QStringList>
+#include <QTimer>
+#include <stdio.h>
+
+DownloadManager::DownloadManager(QObject *parent)
+ : QObject(parent), downloadedCount(0), totalCount(0)
+{
+}
+
+void DownloadManager::append(const QStringList &urlList)
+{
+ foreach (QString url, urlList)
+ append(QUrl::fromEncoded(url.toLocal8Bit()));
+
+ if (downloadQueue.isEmpty())
+ QTimer::singleShot(0, this, SIGNAL(finished()));
+}
+
+void DownloadManager::append(const QUrl &url)
+{
+ if (downloadQueue.isEmpty())
+ QTimer::singleShot(0, this, SLOT(startNextDownload()));
+
+ downloadQueue.enqueue(url);
+ ++totalCount;
+}
+
+QString DownloadManager::saveFileName(const QUrl &url)
+{
+ QString path = url.path();
+ QString basename = QFileInfo(path).fileName();
+
+ if (basename.isEmpty())
+ basename = "download";
+
+ if (QFile::exists(basename)) {
+ // already exists, rename the old one
+ int i = 0;
+ while (QFile::exists(basename + ".old_" + QString::number(i)))
+ ++i;
+
+ QFile::rename(basename, basename + ".old_" + QString::number(i));
+ //basename += QString::number(i);
+ }
+
+ return basename;
+}
+
+void DownloadManager::startNextDownload()
+{
+ if (downloadQueue.isEmpty()) {
+ printf("%d/%d files downloaded successfully\n", downloadedCount, totalCount);
+ emit finished();
+ return;
+ }
+
+ QUrl url = downloadQueue.dequeue();
+
+ QString filename = saveFileName(url);
+ output.setFileName(filename);
+ if (!output.open(QIODevice::WriteOnly)) {
+ fprintf(stderr, "Problem opening save file '%s' for download '%s': %s\n",
+ qPrintable(filename), url.toEncoded().constData(),
+ qPrintable(output.errorString()));
+
+ startNextDownload();
+ return; // skip this download
+ }
+
+ QNetworkRequest request(url);
+ currentDownload = manager.get(request);
+ connect(currentDownload, SIGNAL(downloadProgress(qint64,qint64)),
+ SLOT(downloadProgress(qint64,qint64)));
+ connect(currentDownload, SIGNAL(finished()),
+ SLOT(downloadFinished()));
+ connect(currentDownload, SIGNAL(readyRead()),
+ SLOT(downloadReadyRead()));
+
+ // prepare the output
+ printf("Downloading %s...\n", url.toEncoded().constData());
+ downloadTime.start();
+}
+
+void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
+{
+ progressBar.setStatus(bytesReceived, bytesTotal);
+
+ // calculate the download speed
+ double speed = bytesReceived * 1000.0 / downloadTime.elapsed();
+ QString unit;
+ if (speed < 1024) {
+ unit = "bytes/sec";
+ } else if (speed < 1024*1024) {
+ speed /= 1024;
+ unit = "kB/s";
+ } else {
+ speed /= 1024*1024;
+ unit = "MB/s";
+ }
+
+ progressBar.setMessage(QString::fromLatin1("%1 %2")
+ .arg(speed, 3, 'f', 1).arg(unit));
+ progressBar.update();
+}
+
+void DownloadManager::downloadFinished()
+{
+ progressBar.clear();
+ output.close();
+
+ if (currentDownload->error()) {
+ // download failed
+ fprintf(stderr, "Failed: %s\n", qPrintable(currentDownload->errorString()));
+ } else {
+ printf("Succeeded.\n");
+ ++downloadedCount;
+ }
+
+ currentDownload->deleteLater();
+ startNextDownload();
+}
+
+void DownloadManager::downloadReadyRead()
+{
+ output.write(currentDownload->readAll());
+}
diff --git a/repogenfromonlinerepo/downloadmanager.h b/repogenfromonlinerepo/downloadmanager.h
new file mode 100644
index 000000000..d6d1abd70
--- /dev/null
+++ b/repogenfromonlinerepo/downloadmanager.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DOWNLOADMANAGER_H
+#define DOWNLOADMANAGER_H
+
+#include <QFile>
+#include <QObject>
+#include <QQueue>
+#include <QTime>
+#include <QUrl>
+#include <QNetworkAccessManager>
+
+#include "textprogressbar.h"
+
+class DownloadManager: public QObject
+{
+ Q_OBJECT
+public:
+ DownloadManager(QObject *parent = 0);
+
+ void append(const QUrl &url);
+ void append(const QStringList &urlList);
+ QString saveFileName(const QUrl &url);
+
+signals:
+ void finished();
+
+private slots:
+ void startNextDownload();
+ void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
+ void downloadFinished();
+ void downloadReadyRead();
+
+private:
+ QNetworkAccessManager manager;
+ QQueue<QUrl> downloadQueue;
+ QNetworkReply *currentDownload;
+ QFile output;
+ QTime downloadTime;
+ TextProgressBar progressBar;
+
+ int downloadedCount;
+ int totalCount;
+};
+
+#endif
diff --git a/repogenfromonlinerepo/main.cpp b/repogenfromonlinerepo/main.cpp
new file mode 100644
index 000000000..b6a0db0c7
--- /dev/null
+++ b/repogenfromonlinerepo/main.cpp
@@ -0,0 +1,306 @@
+/**************************************************************************
+**
+** 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 "downloadmanager.h"
+
+#include <QtCore/QCoreApplication>
+#include <QFile>
+#include <QString>
+#include <QDomDocument>
+#include <QDomElement>
+#include <QDomNodeList>
+#include <QStringList>
+#include <QDebug>
+#include <QFileInfo>
+#include <QDir>
+#include <iostream>
+
+static void printUsage()
+{
+ const QString appName = QFileInfo( QCoreApplication::applicationFilePath() ).fileName();
+ std::cout << "Usage: " << qPrintable(appName) << "--url <repository_url>" << std::endl;
+ std::cout << std::endl;
+ std::cout << "Example:" << std::endl;
+ std::cout << " " << qPrintable(appName) << " someDirectory foobar.7z" << std::endl;
+}
+
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+ QString repoUrl = "http://www.forum.nokia.com/nokiaqtsdkrepository/oppdatering/windows/online_ndk_repo";
+
+ QStringList args = app.arguments();
+ for( QStringList::const_iterator it = args.constBegin(); it != args.constEnd(); ++it )
+ {
+ if( *it == QString::fromLatin1( "-h" ) || *it == QString::fromLatin1( "--help" ) )
+ {
+ printUsage();
+ return 0;
+ }
+ else if( *it == QString::fromLatin1( "-u" ) || *it == QString::fromLatin1( "--url" ) )
+ {
+ ++it;
+ if( it == args.end() ) {
+// printUsage();
+// return -1;
+ } else {
+ repoUrl = *it;
+ }
+ }
+ }
+
+ QEventLoop downloadEventLoop;
+
+ DownloadManager downloadManager;
+
+// get Updates.xml to get to know what we can download
+ downloadManager.append(QUrl(repoUrl + "/Updates.xml"));
+ QObject::connect( &downloadManager, SIGNAL( finished() ), &downloadEventLoop, SLOT( quit() ) );
+ downloadEventLoop.exec();
+// END - get Updates.xml to get to know what we can download
+
+ QFile batchFile("download.bat");
+ if (!batchFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ qDebug() << "can not open " << QFileInfo(batchFile).absoluteFilePath();
+ return app.exec();
+ }
+
+ QTextStream batchFileOut(&batchFile);
+
+ const QString updatesXmlPath = "Updates.xml";
+
+ Q_ASSERT( !updatesXmlPath.isEmpty() );
+ Q_ASSERT( QFile::exists( updatesXmlPath ) );
+
+ QFile updatesFile( updatesXmlPath );
+ if ( !updatesFile.open( QIODevice::ReadOnly ) ) {
+ //qDebug() << QString( "Could not open Updates.xml for reading: %1").arg( updatesFile.errorString() ) ;
+ return app.exec();
+ }
+
+ QDomDocument doc;
+ QString err;
+ int line = 0;
+ int col = 0;
+ if ( !doc.setContent( &updatesFile, &err, &line, &col ) ) {
+ //qDebug() << QString( "Could not parse component index: %1:%2: %3").arg( QString::number( line ), QString::number( col ), err );
+ return app.exec();
+ }
+
+ const QDomElement root = doc.documentElement();
+ const QDomNodeList children = root.childNodes();
+ for ( int i = 0; i < children.count(); ++i ) {
+ //qDebug() << children.count();
+ QString packageName;
+ QString packageDisplayName;
+ QString packageDescription;
+ QString packageUpdateText;
+ QString packageVersion;
+ QString packageReleaseDate;
+ QString packageHash;
+ QString packageUserinterfacesAsString;
+ QString packageInstallPriority;
+ QString packageScript;
+ QString packageDependencies;
+ QString packageForcedInstallation;
+ bool packageIsVirtual = false;
+ QString sevenZString;
+ const QDomElement el = children.at( i ).toElement();
+ if ( el.isNull() )
+ continue;
+ if ( el.tagName() == QString("PackageUpdate") ) {
+ const QDomNodeList c2 = el.childNodes();
+
+ for ( int j = 0; j < c2.count(); ++j ) {
+ if ( c2.at( j ).toElement().tagName() == QString("Name") )
+ packageName = c2.at( j ).toElement().text();
+ else if ( c2.at( j ).toElement().tagName() == QString("DisplayName") )
+ packageDisplayName = c2.at( j ).toElement().text();
+ else if ( c2.at( j ).toElement().tagName() == QString("Description") )
+ packageDescription = c2.at( j ).toElement().text();
+ else if ( c2.at( j ).toElement().tagName() == QString("UpdateText") )
+ packageUpdateText = c2.at( j ).toElement().text();
+ else if ( c2.at( j ).toElement().tagName() == QString("Version") )
+ packageVersion = c2.at( j ).toElement().text();
+ else if ( c2.at( j ).toElement().tagName() == QString("ReleaseDate") )
+ packageReleaseDate = c2.at( j ).toElement().text();
+ else if ( c2.at( j ).toElement().tagName() == QString("SHA1") )
+ packageHash = c2.at( j ).toElement().text();
+ else if ( c2.at( j ).toElement().tagName() == QString("UserInterfaces") )
+ packageUserinterfacesAsString = c2.at( j ).toElement().text();
+ else if ( c2.at( j ).toElement().tagName() == QString("Script") )
+ packageScript = c2.at( j ).toElement().text();
+ else if ( c2.at( j ).toElement().tagName() == QString("Dependencies") )
+ packageDependencies = c2.at( j ).toElement().text();
+ else if ( c2.at( j ).toElement().tagName() == QString("ForcedInstallation") )
+ packageForcedInstallation = c2.at( j ).toElement().text();
+ else if ( c2.at( j ).toElement().tagName() == QString("InstallPriority") )
+ packageInstallPriority = c2.at( j ).toElement().text();
+ else if ( c2.at( j ).toElement().tagName() == QString("Virtual") && c2.at( j ).toElement().text() == "true")
+ packageIsVirtual = true;
+ }
+ }
+ if (packageName.isEmpty()) {
+ continue;
+ }
+
+ if ( !packageScript.isEmpty() ) {
+ // get Updates.xml to get to know what we can download
+ downloadManager.append(QUrl(repoUrl + "/" + packageName + "/" + packageScript));
+ QObject::connect( &downloadManager, SIGNAL( finished() ), &downloadEventLoop, SLOT( quit() ) );
+ downloadEventLoop.exec();
+ // END - get Updates.xml to get to know what we can download
+
+ QString localScriptFileName = packageScript;
+ Q_ASSERT( QFile::exists( localScriptFileName ) );
+
+ QFile file(localScriptFileName);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ //qDebug() << localScriptFileName << " was not readable";
+ continue;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ if(line.contains(".7z")) {
+ int firstPosition = line.indexOf("\"");
+ QString subString = line.right(line.count() - firstPosition - 1); //-1 means "
+ //qDebug() << subString;
+ int secondPosition = subString.indexOf("\"");
+ sevenZString = subString.left(secondPosition);
+ //qDebug() << sevenZString;
+ break;
+ }
+ }
+ file.remove();
+ }
+ QStringList packageUserinterfaces = packageUserinterfacesAsString.split(",");
+ packageUserinterfaces.removeAll(QString());
+ packageUserinterfaces.removeAll("");
+
+ QStringList fileList;
+
+ //fileList << packageVersion + sevenZString;
+ foreach(const QString file, packageUserinterfaces) {
+ if(!file.isEmpty()) {
+ fileList << file;
+ }/* else {
+ qDebug() << "There is something wrong with the userinterface string list.";
+ return a.exec();
+ }*/
+ }
+ if(!packageScript.isEmpty()) {
+ fileList << packageScript;
+ }
+
+ QFile packagesXml( QString( QCoreApplication::applicationDirPath() + "/" + packageName + ".xml" ));
+ packagesXml.open( QIODevice::WriteOnly );
+ QTextStream packageAsXmlStream( &packagesXml );
+ packageAsXmlStream << QString( "<?xml version=\"1.0\"?>" ) << endl;
+ packageAsXmlStream << QString( "<Package>" ) << endl;
+ packageAsXmlStream << QString( " <DisplayName>%1</DisplayName>" ).arg(packageDisplayName) << endl;
+
+ if (!packageDescription.isEmpty()) {
+ packageAsXmlStream << QString( " <Description>%1</Description>" ).arg(packageDescription) << endl;
+ }
+
+ if (!packageUpdateText.isEmpty()) {
+ packageAsXmlStream << QString( " <UpdateText>%1</UpdateText>" ).arg(packageUpdateText) << endl;
+ }
+
+ if (!packageVersion.isEmpty()) {
+ packageAsXmlStream << QString( " <Version>%1</Version>" ).arg(packageVersion) << endl;
+ }
+
+ if (!packageReleaseDate.isEmpty()) {
+ packageAsXmlStream << QString( " <ReleaseDate>%1</ReleaseDate>" ).arg(packageReleaseDate) << endl;
+ }
+ packageAsXmlStream << QString( " <Name>%1</Name>" ).arg(packageName) << endl;
+
+ if (!packageScript.isEmpty()) {
+ packageAsXmlStream << QString( " <Script>%1</Script>" ).arg(packageScript) << endl;
+ }
+
+ if (packageIsVirtual) {
+ packageAsXmlStream << QString( " <Virtual>true</Virtual>" ) << endl;
+ }
+
+ if (!packageInstallPriority.isEmpty())
+ packageAsXmlStream << QString( " <InstallPriority>%1</InstallPriority>" ).arg(packageInstallPriority) << endl;
+
+ if (!packageDependencies.isEmpty())
+ packageAsXmlStream << QString( " <Dependencies>%1</Dependencies>" ).arg(packageDependencies) << endl;
+
+ if (!packageForcedInstallation.isEmpty())
+ packageAsXmlStream << QString( " <ForcedInstallation>%1</ForcedInstallation>" ).arg(packageForcedInstallation) << endl;
+
+ if (!packageUserinterfaces.isEmpty()) {
+ packageAsXmlStream << QString( " <UserInterfaces>" ) << endl;
+ foreach(const QString userInterfaceFile, packageUserinterfaces) {
+ packageAsXmlStream << QString( " <UserInterface>%1</UserInterface>" ).arg(userInterfaceFile) << endl;
+ }
+ packageAsXmlStream << QString( " </UserInterfaces>" ) << endl;
+ }
+ packageAsXmlStream << QString( "</Package>" ) << endl;
+
+ batchFileOut << "rem download line BEGIN =============================================\n";
+
+ batchFileOut << "mkdir " << packageName << "\\meta\n";
+ batchFileOut << "move " << QDir::toNativeSeparators(QFileInfo(packagesXml).absoluteFilePath()) << " " << packageName << "\\meta\\package.xml\n";
+ if (!sevenZString.isEmpty()) {
+ batchFileOut << "mkdir " << packageName << "\\data\n";
+ batchFileOut << "cd " << packageName << "\\data\n";
+ batchFileOut << "wget " << repoUrl << "/" << packageName << "/" << QString(packageVersion + sevenZString) << " -O " << sevenZString << "\n";
+ batchFileOut << "cd ..\\..\n";
+ }
+ batchFileOut << "cd " << packageName << "\\meta\n";
+ foreach(const QString file, fileList) {
+ batchFileOut << "wget " << repoUrl << "/" << packageName << "/" << file << "\n";
+ }
+ batchFileOut << "cd ..\\..\n";
+
+ batchFileOut << "rem download line END =============================================\n";
+ } //for ( int i = 0; i < children.count(); ++i ) {
+
+ if ( children.count() == 0 ) {
+ qDebug() << "no packages found";
+ return app.exec();
+ } else {
+ qDebug() << "found packages and wrote batch file";
+ }
+
+
+ return 0;
+}
diff --git a/repogenfromonlinerepo/repogenfromonlinerepo.pro b/repogenfromonlinerepo/repogenfromonlinerepo.pro
new file mode 100644
index 000000000..63bb503a4
--- /dev/null
+++ b/repogenfromonlinerepo/repogenfromonlinerepo.pro
@@ -0,0 +1,16 @@
+QT += core network xml
+
+QT -= gui
+
+TARGET = repogenfromonlinerepo
+CONFIG += console
+CONFIG -= app_bundle
+
+TEMPLATE = app
+
+
+SOURCES += main.cpp
+HEADERS += downloadmanager.h
+SOURCES += downloadmanager.cpp
+HEADERS += textprogressbar.h
+SOURCES += textprogressbar.cpp
diff --git a/repogenfromonlinerepo/textprogressbar.cpp b/repogenfromonlinerepo/textprogressbar.cpp
new file mode 100644
index 000000000..ceba0922b
--- /dev/null
+++ b/repogenfromonlinerepo/textprogressbar.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "textprogressbar.h"
+#include <QByteArray>
+#include <stdio.h>
+
+TextProgressBar::TextProgressBar()
+ : value(0), maximum(-1), iteration(0)
+{
+}
+
+void TextProgressBar::clear()
+{
+ printf("\n");
+ fflush(stdout);
+
+ iteration = 0;
+ value = 0;
+ maximum = -1;
+}
+
+void TextProgressBar::update()
+{
+ ++iteration;
+
+ if (maximum > 0) {
+ // we know the maximum
+ // draw a progress bar
+ int percent = value * 100 / maximum;
+ int hashes = percent / 2;
+
+ QByteArray progressbar(hashes, '#');
+ if (percent % 2)
+ progressbar += '>';
+
+ printf("\r[%-50s] %3d%% %s ",
+ progressbar.constData(),
+ percent,
+ qPrintable(message));
+ } else {
+ // we don't know the maximum, so we can't draw a progress bar
+ int center = (iteration % 48) + 1; // 50 spaces, minus 2
+ QByteArray before(qMax(center - 2, 0), ' ');
+ QByteArray after(qMin(center + 2, 50), ' ');
+
+ printf("\r[%s###%s] %s ",
+ before.constData(), after.constData(), qPrintable(message));
+ }
+}
+
+void TextProgressBar::setMessage(const QString &m)
+{
+ message = m;
+}
+
+void TextProgressBar::setStatus(qint64 val, qint64 max)
+{
+ value = val;
+ maximum = max;
+}
diff --git a/repogenfromonlinerepo/textprogressbar.h b/repogenfromonlinerepo/textprogressbar.h
new file mode 100644
index 000000000..91ea04dd1
--- /dev/null
+++ b/repogenfromonlinerepo/textprogressbar.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TEXTPROGRESSBAR_H
+#define TEXTPROGRESSBAR_H
+
+#include <QString>
+
+class TextProgressBar
+{
+public:
+ TextProgressBar();
+
+ void clear();
+ void update();
+ void setMessage(const QString &message);
+ void setStatus(qint64 value, qint64 maximum);
+
+private:
+ QString message;
+ qint64 value;
+ qint64 maximum;
+ int iteration;
+};
+
+#endif