From 64391c88c7e1421dd146b528c4395c68049c4adb Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Tue, 8 Mar 2011 20:46:27 +0100 Subject: moved some directories and adjusted the README - also removed some unused projects under examples(updater, updaterplugin) - adjusted pro files to the new structure --- tools/maddehelper/maddehelper.pro | 12 + tools/maddehelper/main.cpp | 306 +++++++++++++++++++++ tools/operationrunner/operationrunner.cpp | 92 +++++++ tools/operationrunner/operationrunner.pro | 18 ++ tools/repogenfromonlinerepo/downloadmanager.cpp | 172 ++++++++++++ tools/repogenfromonlinerepo/downloadmanager.h | 84 ++++++ tools/repogenfromonlinerepo/main.cpp | 306 +++++++++++++++++++++ .../repogenfromonlinerepo.pro | 16 ++ tools/repogenfromonlinerepo/textprogressbar.cpp | 98 +++++++ tools/repogenfromonlinerepo/textprogressbar.h | 63 +++++ 10 files changed, 1167 insertions(+) create mode 100644 tools/maddehelper/maddehelper.pro create mode 100644 tools/maddehelper/main.cpp create mode 100644 tools/operationrunner/operationrunner.cpp create mode 100644 tools/operationrunner/operationrunner.pro create mode 100644 tools/repogenfromonlinerepo/downloadmanager.cpp create mode 100644 tools/repogenfromonlinerepo/downloadmanager.h create mode 100644 tools/repogenfromonlinerepo/main.cpp create mode 100644 tools/repogenfromonlinerepo/repogenfromonlinerepo.pro create mode 100644 tools/repogenfromonlinerepo/textprogressbar.cpp create mode 100644 tools/repogenfromonlinerepo/textprogressbar.h (limited to 'tools') diff --git a/tools/maddehelper/maddehelper.pro b/tools/maddehelper/maddehelper.pro new file mode 100644 index 000000000..df9954eba --- /dev/null +++ b/tools/maddehelper/maddehelper.pro @@ -0,0 +1,12 @@ +QT += core + +QT -= gui + +TARGET = maddehelper +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + + +SOURCES += main.cpp diff --git a/tools/maddehelper/main.cpp b/tools/maddehelper/main.cpp new file mode 100644 index 000000000..1f4ed555b --- /dev/null +++ b/tools/maddehelper/main.cpp @@ -0,0 +1,306 @@ +#include +#include +#include +#include +#include +#include + +//rebase to adress 0x20000000 results in crashing tools like perl on win7/64bit +//which I used for testing +bool rebaseDlls(const QString &maddeBinLocation, + const QString &rebaseBinaryLocation, + const QString &adressValue = "0x50000000", + const QString &dllFilter = "msys*.dll") +{ + QStringList dllStringList = QDir(maddeBinLocation).entryList(QStringList(dllFilter), QDir::Files, QDir::Size | QDir::Reversed); + QString dlls; + QString dllsEnd; //of an unknown issue msys-1.0.dll should be the last on my system + foreach (QString dll, dllStringList) { + dll.prepend(maddeBinLocation + "/"); + if (dll.contains("msys-1")) { + dllsEnd.append(dll + " "); + } else { + dlls.append(dll + " "); + } + } + dlls = dlls.append(dllsEnd); + + QProcess process; + process.setEnvironment(QStringList("EMPTY_ENVIRONMENT=true")); + QProcess::ProcessError initError(process.error()); + process.setProcessChannelMode(QProcess::MergedChannels); + process.setNativeArguments(QString("-b %1 -o 0x10000 -v %2").arg(adressValue, dlls)); + process.start(rebaseBinaryLocation); + process.waitForFinished(); + if (process.exitCode() != 0 || + initError != process.error() || + process.exitStatus() == QProcess::CrashExit) + { + qWarning() << rebaseBinaryLocation + " " + process.nativeArguments(); + qWarning() << QString("\t Adress rebasing failed! Maybe a process(bash.exe, ssh, ...) is using some of the dlls(%1).").arg(dllStringList.join(", ")); + qWarning() << "\t Output: \n" << process.readAll(); + if (initError != process.error()) { + qDebug() << QString("\tError(%1): ").arg(process.error()) << process.errorString(); + } + + if (process.exitStatus() == QProcess::CrashExit) { + qDebug() << "\tcrashed!!!"; + } + return false; + } + qWarning() << rebaseBinaryLocation + " " + process.nativeArguments(); + //qWarning() << "\t Output: \n" << process.readAll(); + return true; +} + +bool checkTools(const QString &maddeBinLocation, const QStringList &binaryCheckList) +{ + QDirIterator it( maddeBinLocation, binaryCheckList, QDir::Files ); + while (it.hasNext()) { + QString processPath(it.next()); + if (!QFileInfo(processPath).exists()) { + qDebug() << processPath << " is missing - so we don't need to check it"; + continue; + } + bool testedToolState = true; + QProcess process; + process.setEnvironment(QStringList("EMPTY_ENVIRONMENT=true")); + QProcess::ProcessError initError(process.error()); + process.setProcessChannelMode(QProcess::MergedChannels); + process.start(processPath, QStringList("--version")); + process.waitForFinished(1000); + QString processOutput = process.readAll(); + + //check for the unpossible load dll error + if (processOutput.contains("VirtualAlloc pointer is null") || + processOutput.contains("Couldn't reserve space for") || + process.exitStatus() == QProcess::CrashExit) + { + qWarning() << QString("found dll loading problem with(ExitCode: %1): ").arg(QString::number(process.exitCode())) << processPath; + qWarning() << processOutput; + testedToolState = false; + if (initError != process.error()) { + qWarning() << QString("\tError(%1): ").arg(process.error()) << process.errorString(); + } + + if (process.exitStatus() == QProcess::CrashExit) { + qWarning() << "\tcrashed!!!"; + } + } + if ( process.state() == QProcess::Running ) + process.terminate(); + //again wait some time + if ( !process.waitForFinished( 1000 ) ) { + process.kill(); + process.waitForFinished( 1000 ); //some more waittime + } + if (testedToolState == false) { + return false; + } + } + return true; +} + +bool removeDirectory( const QString& path ) +{ + if ( !QFileInfo(path).exists() ) + return true; + if ( path.isEmpty() ) // QDir( "" ) points to the working directory! We never want to remove that one. + return true; + + QDirIterator it(path, QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden | QDir::System); + while ( it.hasNext() ) + { + it.next(); + const QFileInfo currentFileInfo = it.fileInfo(); + + if ( currentFileInfo.isDir() && !currentFileInfo.isSymLink() ) + { + removeDirectory( currentFileInfo.filePath() ); + } + else + { + QFile f( currentFileInfo.filePath() ); + if( !f.remove() ) + qWarning() << "Can't remove: " << currentFileInfo.absoluteFilePath(); + } + } + + if ( !QDir().rmdir(path)) + return QDir().rename(path, path + "_" + QDateTime::currentDateTime().toString()); + return true; +} + +bool cleanUpSubDirectories(const QString &maddeLocation, const QStringList &subDirectoryList, const QStringList &extraFiles) +{ + if (maddeLocation.isEmpty()) { + qWarning() << "Remove nothing could be result in a broken system ;)"; + return false; + } + if (!QFileInfo(maddeLocation).exists()) { + qWarning() << QString("Ups, location '%1' is not existing.").arg(maddeLocation); + return false; + } + + foreach (const QString &subDirectory, subDirectoryList) { + bool removed = removeDirectory(maddeLocation + "/" + subDirectory); + if (!removed) { + qWarning() << "Can't remove " << subDirectory <<" for a clean up step"; + return false; + } + } + foreach (const QString &fileName, extraFiles) { + QFile file(fileName); + if (file.exists()) { + bool removed = QFile(fileName).remove(); + if (!removed) { + qWarning() << "Can't remove " << extraFiles <<" for a clean up step"; + } + } + } + + return true; +} + +bool runInstall(const QString &postinstallCommand, const QString &checkFileForAnOkInstallation) +{ + QProcess process; + process.setEnvironment(QStringList("EMPTY_ENVIRONMENT=true")); + QProcess::ProcessError initError(process.error()); + process.setProcessChannelMode(QProcess::ForwardedChannels); + process.setNativeArguments(postinstallCommand); + process.start(QString(), QStringList()); + + process.waitForFinished(-1); + if (process.exitCode() != 0 || + initError != process.error() || + process.exitStatus() == QProcess::CrashExit) + { + qWarning() << QString("runInstall(ExitCode: %1) went wrong \n'%2'").arg(QString::number(process.exitCode()), postinstallCommand); + if (initError != process.error()) { + qDebug() << QString("\tError(%1): ").arg(process.error()) << process.errorString(); + } + + if (process.exitStatus() == QProcess::CrashExit) { + qDebug() << "\tcrashed!!!"; + } + } + if ( process.state() == QProcess::Running ) + process.terminate(); + //again wait some time + if ( !process.waitForFinished( 1000 ) ) + process.kill(); + + return QFileInfo(checkFileForAnOkInstallation).exists(); +} + + +static void printUsage() +{ + const QString appName = QFileInfo( QCoreApplication::applicationFilePath() ).fileName(); + std::cout << "Usage: " << qPrintable(appName) << " -r -m " << std::endl; + std::cout << "Example:" << std::endl; + std::cout << " " << qPrintable(appName) << " -r D:/msysgit_rebase.exe -m D:/Maemo/4.6.2" << std::endl; +} + + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + if ( app.arguments().count() != 5 ) //5. is app name + { + printUsage(); + return 6; + } + + QString rebaseBinaryLocation; + QString maddeLocation; + for ( int i = 1; i < app.arguments().size(); ++i ) { + if ( app.arguments().at( i ) == QLatin1String( "" ) ) + continue; + if (app.arguments().at(i) == "-r") { + i++; + rebaseBinaryLocation = app.arguments().at(i); + } + if (app.arguments().at(i) == "-m") { + i++; + maddeLocation = app.arguments().at(i); + } + } + if (!QFileInfo(maddeLocation).isDir()) { + qDebug() << "MADDE location is not existing."; + return 4; + } + if (!QFileInfo(maddeLocation + "/bin").isDir()) { + qDebug() << "It seems that the madde location don't have a 'bin'' directory."; + return 5; + } + QString maddeBinLocation = maddeLocation + "/bin"; + + //from qs +// var envExecutable = installer.value("TargetDir") + "/" + winMaddeSubPath + "/bin/env.exe"; +// var postShell = installer.value("TargetDir") + "/" + winMaddeSubPath + "/postinstall/postinstall.sh"; +// component.addOperation("Execute", "{0,1}", envExecutable, "-i" , "/bin/sh", "--login", postShell, "--nosleepontrap", "showStandardError"); + + QString postinstallShell = maddeLocation + "/postinstall/postinstall.sh"; + //"--nosleepontrap" is not used in our Madde, but later maybe it is there again + QString postinstallCommand = maddeBinLocation + QString("/env.exe -i /bin/sh --login %1").arg(postinstallShell + " --nosleepontrap"); + QString successFileCheck = maddeLocation + "/madbin/mad.cmd"; + QString directoriesForCleanUpArgument = "sysroots, toolchains, targets, runtimes, wbin"; + directoriesForCleanUpArgument.remove(" "); + QStringList directoriesForCleanUp(directoriesForCleanUpArgument.split(",")); + + //this was used for testings + //cleanUpSubDirectories(maddeLocation, directoriesForCleanUp, QStringList(successFileCheck)); + + bool installationWentFine = runInstall(postinstallCommand, successFileCheck); + + if (installationWentFine) + return 0; + + + QString binaryCheckArgument = ("a2p.exe, basename.exe, bash.exe, bzip2.exe, cat.exe, chmod.exe, cmp.exe, comm.exe, cp.exe, cut.exe, " \ + "date.exe, diff.exe, diff3.exe, dirname.exe, du.exe, env.exe, expr.exe, find.exe, fold.exe, gawk.exe, " \ + "grep.exe, gzip.exe, head.exe, id.exe, install.exe, join.exe, less.exe, ln.exe, ls.exe, lzma.exe, m4.exe, " \ + "make.exe, md5sum.exe, mkdir.exe, mv.exe, od.exe, paste.exe, patch.exe, perl.exe, perl5.6.1.exe, ps.exe, " \ + "rm.exe, rmdir.exe, sed.exe, sh.exe, sleep.exe, sort.exe, split.exe, ssh-agent.exe, ssh-keygen.exe, " \ + "stty.exe, tail.exe, tar.exe, tee.exe, touch.exe, tr.exe, true.exe, uname.exe, uniq.exe, vim.exe, wc.exe, xargs.exe"); + binaryCheckArgument.remove(" "); + QStringList binaryCheckList(binaryCheckArgument.split(",")); + + QStringList possibleRebaseAdresses; + possibleRebaseAdresses << "0x5200000"; //this uses perl + possibleRebaseAdresses << "0x30000000"; + possibleRebaseAdresses << "0x35000000"; + possibleRebaseAdresses << "0x40000000"; + possibleRebaseAdresses << "0x60000000"; + possibleRebaseAdresses << "0x60800000"; + possibleRebaseAdresses << "0x68000000"; //this uses git + + foreach (const QString &newAdress, possibleRebaseAdresses) { + bool rebased = rebaseDlls(maddeBinLocation, rebaseBinaryLocation, newAdress); + if (!rebased) { + //rebasing is not working + return 2; + } + bool reseted = cleanUpSubDirectories(maddeLocation, directoriesForCleanUp, QStringList(successFileCheck)); + if (!reseted) { + //Madde couldn't reseted to the starting position + return 3; + } + if (!checkTools(maddeBinLocation, binaryCheckList)) { + //we need another adress + continue; + } + bool installationWentFine = runInstall(postinstallCommand, successFileCheck); + + if (installationWentFine) { + qDebug() << "Rebasing dlls to " << newAdress <<" helped to install MADDE"; + return 0; + } + } + + //means rebasing was not helping + return 1; +} diff --git a/tools/operationrunner/operationrunner.cpp b/tools/operationrunner/operationrunner.cpp new file mode 100644 index 000000000..242aa9866 --- /dev/null +++ b/tools/operationrunner/operationrunner.cpp @@ -0,0 +1,92 @@ +/************************************************************************** +** +** 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 +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +static void printUsage() +{ + std::cout << "Usage: " << std::endl; + std::cout << std::endl; + std::cout << "operationrunner \"Execute\" \"{0,1}\" \"C:\\Windows\\System32\\cmd.exe\" \"/A\" \"/Q\" \"/C\" \"magicmaemoscript.bat\" \"showStandardError\"" << std::endl; +} + +int main(int argc, char **argv) +{ + try { + QCoreApplication app(argc, argv); + + QStringList argumentList = app.arguments(); + + if( argumentList.count() < 2 || argumentList.contains("--help") ) + { + printUsage(); + return 1; + } + argumentList.removeFirst(); // we don't need the application name + + QInstaller::init(); + + QInstaller::setVerbose( true ); + + QString operationName = argumentList.takeFirst(); + KDUpdater::UpdateOperation* const operation = KDUpdater::UpdateOperationFactory::instance().create( operationName ); + if (!operation) { + std::cerr << "Can not find the operation: " << qPrintable(operationName) << std::endl; + return 1; + } + operation->setArguments(argumentList); + bool readyPerformed = operation->performOperation(); + if (readyPerformed) { + std::cout << "Operation was succesfully performed." << std::endl; + } else { + std::cerr << "There was a problem while performing the operation: " << qPrintable(operation->errorString()) << std::endl; + } + return 0; + } catch ( const QInstaller::Error& e ) { + std::cerr << qPrintable(e.message()) << std::endl; + } + return 1; +} diff --git a/tools/operationrunner/operationrunner.pro b/tools/operationrunner/operationrunner.pro new file mode 100644 index 000000000..d2f1b05cc --- /dev/null +++ b/tools/operationrunner/operationrunner.pro @@ -0,0 +1,18 @@ +TEMPLATE = app +TARGET = operationrunner +DEPENDPATH += . .. ../../installerbuilder/common +INCLUDEPATH += . .. + +DESTDIR = ../../installerbuilder/bin + +CONFIG += console +CONFIG -= app_bundle + +QT += xml + +include(../../installerbuilder/libinstaller/libinstaller.pri) + +# Input +SOURCES += operationrunner.cpp + +LIBS = -L../../installerbuilder/lib -linstaller $$LIBS diff --git a/tools/repogenfromonlinerepo/downloadmanager.cpp b/tools/repogenfromonlinerepo/downloadmanager.cpp new file mode 100644 index 000000000..61bf7ea88 --- /dev/null +++ b/tools/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 +#include +#include +#include +#include +#include +#include + +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/tools/repogenfromonlinerepo/downloadmanager.h b/tools/repogenfromonlinerepo/downloadmanager.h new file mode 100644 index 000000000..d6d1abd70 --- /dev/null +++ b/tools/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 +#include +#include +#include +#include +#include + +#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 downloadQueue; + QNetworkReply *currentDownload; + QFile output; + QTime downloadTime; + TextProgressBar progressBar; + + int downloadedCount; + int totalCount; +}; + +#endif diff --git a/tools/repogenfromonlinerepo/main.cpp b/tools/repogenfromonlinerepo/main.cpp new file mode 100644 index 000000000..b6a0db0c7 --- /dev/null +++ b/tools/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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void printUsage() +{ + const QString appName = QFileInfo( QCoreApplication::applicationFilePath() ).fileName(); + std::cout << "Usage: " << qPrintable(appName) << "--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( "" ) << endl; + packageAsXmlStream << QString( "" ) << endl; + packageAsXmlStream << QString( " %1" ).arg(packageDisplayName) << endl; + + if (!packageDescription.isEmpty()) { + packageAsXmlStream << QString( " %1" ).arg(packageDescription) << endl; + } + + if (!packageUpdateText.isEmpty()) { + packageAsXmlStream << QString( " %1" ).arg(packageUpdateText) << endl; + } + + if (!packageVersion.isEmpty()) { + packageAsXmlStream << QString( " %1" ).arg(packageVersion) << endl; + } + + if (!packageReleaseDate.isEmpty()) { + packageAsXmlStream << QString( " %1" ).arg(packageReleaseDate) << endl; + } + packageAsXmlStream << QString( " %1" ).arg(packageName) << endl; + + if (!packageScript.isEmpty()) { + packageAsXmlStream << QString( " " ).arg(packageScript) << endl; + } + + if (packageIsVirtual) { + packageAsXmlStream << QString( " true" ) << endl; + } + + if (!packageInstallPriority.isEmpty()) + packageAsXmlStream << QString( " %1" ).arg(packageInstallPriority) << endl; + + if (!packageDependencies.isEmpty()) + packageAsXmlStream << QString( " %1" ).arg(packageDependencies) << endl; + + if (!packageForcedInstallation.isEmpty()) + packageAsXmlStream << QString( " %1" ).arg(packageForcedInstallation) << endl; + + if (!packageUserinterfaces.isEmpty()) { + packageAsXmlStream << QString( " " ) << endl; + foreach(const QString userInterfaceFile, packageUserinterfaces) { + packageAsXmlStream << QString( " %1" ).arg(userInterfaceFile) << endl; + } + packageAsXmlStream << QString( " " ) << endl; + } + packageAsXmlStream << QString( "" ) << 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/tools/repogenfromonlinerepo/repogenfromonlinerepo.pro b/tools/repogenfromonlinerepo/repogenfromonlinerepo.pro new file mode 100644 index 000000000..63bb503a4 --- /dev/null +++ b/tools/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/tools/repogenfromonlinerepo/textprogressbar.cpp b/tools/repogenfromonlinerepo/textprogressbar.cpp new file mode 100644 index 000000000..ceba0922b --- /dev/null +++ b/tools/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 +#include + +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/tools/repogenfromonlinerepo/textprogressbar.h b/tools/repogenfromonlinerepo/textprogressbar.h new file mode 100644 index 000000000..91ea04dd1 --- /dev/null +++ b/tools/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 + +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 -- cgit v1.2.3