create getrepositorycontent tool

It is a very useful tool to get repositories locally
for testing.

Change-Id: Ia83841c3e5c96ab369c35580dd98141cf22ed643
Reviewed-by: Karsten Heimrich <karsten.heimrich@digia.com>
This commit is contained in:
Tim Jenssen 2013-04-09 10:21:54 +02:00
parent 3ba4a78b39
commit ac2319b4f0
12 changed files with 708 additions and 548 deletions

View File

@ -0,0 +1,53 @@
/**************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Installer Framework.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
**************************************************************************/
#include "domnodedebugstreamoperator.h"
QDebug operator<<(QDebug dbg, const QDomNode &domNode)
{
if (domNode.isNull())
return dbg << "domNode is Null";
QString debugOutput;
QTextStream stream(&debugOutput);
domNode.save(stream, 4);
return dbg << debugOutput;
}

View File

@ -0,0 +1,51 @@
/**************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Installer Framework.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
**************************************************************************/
#ifndef DEBUGDOMNODE_H
#define DEBUGDOMNODE_H
#include <QDebug>
#include <QDomNode>
QDebug operator<<(QDebug dbg, const QDomNode &domNode);
#endif // DEBUGDOMNODE_H

View File

@ -0,0 +1,114 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** 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 Digia Plc 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 "downloader.h"
#include <fileutils.h>
#include <QtNetwork/QNetworkProxy>
class ProxyFactory : public KDUpdater::FileDownloaderProxyFactory
{
public:
ProxyFactory() {}
ProxyFactory *clone() const
{
return new ProxyFactory();
}
QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery())
{
return QNetworkProxyFactory::systemProxyForQuery(query);
}
};
Downloader::Downloader(const QUrl &source, const QString &target)
: QObject()
, m_source(source)
, m_target(target)
, m_fileDownloader(0)
{
m_fileDownloader = KDUpdater::FileDownloaderFactory::instance().create(m_source.scheme(), this);
m_fileDownloader->setDownloadedFileName(target);
if (m_fileDownloader) {
m_fileDownloader->setUrl(m_source);
m_fileDownloader->setProxyFactory(new ProxyFactory());
connect(m_fileDownloader, SIGNAL(downloadCanceled()), this, SLOT(downloadFinished()));
connect(m_fileDownloader, SIGNAL(downloadCompleted()), this, SLOT(downloadFinished()));
connect(m_fileDownloader, SIGNAL(downloadAborted(QString)), this, SLOT(downloadFinished(QString)));
connect(m_fileDownloader, SIGNAL(downloadSpeed(qint64)), this, SLOT(downloadSpeed(qint64)));
connect(m_fileDownloader, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64)));
m_fileDownloader->setAutoRemoveDownloadedFile(false);
}
}
void Downloader::downloadFinished(const QString &message)
{
if (!message.isEmpty())
qDebug() << "Error:" << message;
progressBar.setStatus(100, 100);
progressBar.update();
printf("\n");
emit finished();
}
void Downloader::downloadSpeed(qint64 speed)
{
progressBar.setMessage(QString::fromLatin1("%1 /sec").arg(QInstaller::humanReadableSize(speed)));
}
void Downloader::downloadProgress(qint64 bytesReceived, qint64 bytesToReceive)
{
if (bytesReceived == 0 || bytesToReceive == 0)
return;
progressBar.setStatus(bytesReceived, bytesToReceive);
progressBar.update();
}
void Downloader::run()
{
m_fileDownloader->download();
}

View File

@ -38,8 +38,13 @@
**
****************************************************************************/
#ifndef DOWNLOADMANAGER_H
#define DOWNLOADMANAGER_H
#ifndef DOWNLOADER_H
#define DOWNLOADER_H
#include "textprogressbar.h"
#include <kdupdaterfiledownloader.h>
#include <kdupdaterfiledownloaderfactory.h>
#include <QFile>
#include <QObject>
@ -48,37 +53,24 @@
#include <QUrl>
#include <QNetworkAccessManager>
#include "textprogressbar.h"
class DownloadManager: public QObject
class Downloader : public QObject
{
Q_OBJECT
public:
explicit DownloadManager(QObject *parent = 0);
void append(const QUrl &url);
void append(const QStringList &urlList);
QString saveFileName(const QUrl &url);
explicit Downloader(const QUrl &source, const QString &target);
void run();
signals:
void finished();
private slots:
void startNextDownload();
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void downloadFinished();
void downloadReadyRead();
void downloadFinished(const QString &message = QString());
void downloadSpeed(qint64 speed);
void downloadProgress(qint64 bytesReceived, qint64 bytesToReceive);
private:
QNetworkAccessManager manager;
QQueue<QUrl> downloadQueue;
QNetworkReply *currentDownload;
QFile output;
QTime downloadTime;
TextProgressBar progressBar;
int downloadedCount;
int totalCount;
QUrl m_source;
QString m_target;
KDUpdater::FileDownloader *m_fileDownloader;
};
#endif
#endif // DOWNLOADER_H

View File

@ -0,0 +1,22 @@
TEMPLATE = app
INCLUDEPATH += . ..
TARGET = getrepositorycontent
include(../../installerfw.pri)
QT -= gui
QT += network
CONFIG += console
DESTDIR = $$IFW_APP_PATH
SOURCES += main.cpp \
textprogressbar.cpp \
downloader.cpp \
domnodedebugstreamoperator.cpp
HEADERS += \
textprogressbar.h \
downloader.h \
domnodedebugstreamoperator.h

View File

@ -0,0 +1,450 @@
/**************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Installer Framework.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
**************************************************************************/
#include "downloader.h"
#include "domnodedebugstreamoperator.h"
#include <globals.h>
#include <init.h>
#include <fileutils.h>
#include <lib7z_facade.h>
#include <utils.h>
#include <QCoreApplication>
#include <QFile>
#include <QUrl>
#include <QString>
#include <QDomDocument>
#include <QDomElement>
#include <QDomNodeList>
#include <QStringList>
#include <QDebug>
#include <QFileInfo>
#include <QDir>
#include <QDirIterator>
#include <QDebug>
#include <iostream>
static void printUsage()
{
const QString appName = QFileInfo( QCoreApplication::applicationFilePath() ).fileName();
std::cout << "Usage: " << qPrintable(appName)
<< " --url <repository_url> --repository <empty_repository_dir> --packages <empty_packages_dir>" << std::endl;
std::cout << " --url URL to fetch all the content from." << std::endl;
std::cout << " --repository Target directory for the repository content." << std::endl;
std::cout << " --packages The packages target directory where it creates the needed content to create new installers or repositories." << std::endl;
std::cout << " --clean Removes all the content if there is an existing repository or packages dir" << std::endl;
std::cout << "Example:" << std::endl;
std::cout << " " << qPrintable(appName) << " --url http://www.example.com/repository/" <<
" --repository repository --packages packages" << std::endl;
}
// this should be a new class which uses XmlStreamReader instead of DomDocument
// should be implicit shared, see repository class
// maybe we can use some code from persistentdata in qtcreator
class ComponentData {
public:
ComponentData() {}
ComponentData(const QString &/*xmlData*/) {}
QVariant attributeValue(const QString &key, const QString &attribute, const QVariant &defaultValue = QVariant()) {
Q_UNUSED(key)
Q_UNUSED(attribute)
return defaultValue;
}
QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) {
Q_UNUSED(defaultValue)
// just use the quick dirty hack added members
if (key == QLatin1String("Script"))
return m_script;
if (key == QLatin1String("Version"))
return m_version;
return QVariant();
}
QString textValue(const QString &key, const QString &defaultValue = QString()) {
return value(key, defaultValue).toString();
}
// quick dirty hack added public members
public:
QDomDocument m_packageXml;
QStringList m_downloadDownloadableArchives;
QString m_script;
QString m_version;
};
static void downloadFile(const QUrl &source, const QString &target)
{
QEventLoop downloadEventLoop;
Downloader downloader(source, target);
QObject::connect(&downloader, SIGNAL(finished()), &downloadEventLoop, SLOT(quit()));
downloader.run();
downloadEventLoop.exec();
}
QHash<QString, ComponentData> downLoadRepository(const QString &repositoryUrl, const QString &repositoryTarget)
{
const QString updatesXmlFileName = QLatin1String("Updates.xml");
QHash<QString, ComponentData> componentDataHash;
const QUrl updatesXmlUrl(QString::fromLatin1("%1/%2").arg(repositoryUrl, updatesXmlFileName));
downloadFile(updatesXmlUrl, QDir(repositoryTarget).filePath(updatesXmlFileName));
QFile updatesFile(QDir(repositoryTarget).filePath(updatesXmlFileName));
if (!updatesFile.exists()) {
qDebug() << "could not download the file:" << updatesXmlUrl.toString();
return componentDataHash;
} else
qDebug() << "file downloaded to location:" << QDir(repositoryTarget).filePath(updatesXmlFileName);
if (!updatesFile.open(QIODevice::ReadOnly)) {
qDebug() << QString::fromLatin1("Could not open Updates.xml for reading: %1").arg(updatesFile
.errorString()) ;
return componentDataHash;
}
QStringList ignoreTagList;
ignoreTagList << QLatin1String("Name");
ignoreTagList << QLatin1String("ReleaseDate");
ignoreTagList << QLatin1String("SHA1");
ignoreTagList << QLatin1String("UpdateFile");
QStringList fileTagList;
fileTagList << QLatin1String("DownloadableArchives");
QDomDocument updatesXml;
QString error;
int line = 0;
int column = 0;
if (!updatesXml.setContent( &updatesFile, &error, &line, &column)) {
qWarning() << QString::fromLatin1("Could not parse component index: %1:%2: %3")
.arg(QString::number(line), QString::number(column), error);
return componentDataHash;
}
QDomNode packageUpdateDomNode = updatesXml.firstChildElement(QLatin1String("Updates")).firstChildElement(
QLatin1String("PackageUpdate"));
while (!packageUpdateDomNode.isNull()) {
if (packageUpdateDomNode.nodeName() == QLatin1String("PackageUpdate")) {
QDomNode packageUpdateEntry = packageUpdateDomNode.firstChild();
QString currentPackageName;
ComponentData currentComponentData;
// creating the package.xml for later use
QDomElement currentNewPackageElement = currentComponentData.m_packageXml.createElement(
QLatin1String("Package"));
while (!packageUpdateEntry.isNull()) {
// do name first before ignore filters the name out
if (packageUpdateEntry.nodeName() == QLatin1String("Name")) {
currentPackageName = packageUpdateEntry.toElement().text();
}
if (ignoreTagList.contains(packageUpdateEntry.nodeName())) {
packageUpdateEntry = packageUpdateEntry.nextSibling();
continue;
}
if (packageUpdateEntry.nodeName() == QLatin1String("Script")) {
currentComponentData.m_script = packageUpdateEntry.toElement().text();
}
if (packageUpdateEntry.nodeName() == QLatin1String("Version")) {
currentComponentData.m_version = packageUpdateEntry.toElement().text();
currentComponentData.m_downloadDownloadableArchives.append(
currentComponentData.m_version + QLatin1String("meta.7z"));
}
if (packageUpdateEntry.nodeName() == QLatin1String("DownloadableArchives")) {
QStringList tDownloadList = packageUpdateEntry.toElement().text().split(
QInstaller::commaRegExp(), QString::SkipEmptyParts);
foreach (const QString &download, tDownloadList) {
currentComponentData.m_downloadDownloadableArchives.append(
currentComponentData.m_version + download);
currentComponentData.m_downloadDownloadableArchives.append(
currentComponentData.m_version + download + QLatin1String(".sha1"));
}
}
currentNewPackageElement.appendChild(packageUpdateEntry.cloneNode(true));
packageUpdateEntry = packageUpdateEntry.nextSibling();
}
currentComponentData.m_packageXml.appendChild(currentNewPackageElement);
Q_ASSERT(!currentComponentData.m_packageXml.toString().isEmpty());
componentDataHash.insert(currentPackageName, currentComponentData);
} else {
qWarning() << QString::fromLatin1("Unknown elment '%1'").arg(packageUpdateDomNode.nodeName(),
QFileInfo(updatesXmlFileName).absoluteFilePath());
}
packageUpdateDomNode = packageUpdateDomNode.nextSibling();
}
QHashIterator<QString, ComponentData> itComponentData(componentDataHash);
while (itComponentData.hasNext()) {
itComponentData.next();
QString componentDirectory = QDir(repositoryTarget).filePath(itComponentData.key());
if (!QDir().mkpath(componentDirectory))
qWarning() << "couldn't create:" << componentDirectory;
foreach (const QString &download, itComponentData.value().m_downloadDownloadableArchives) {
const QString fileTarget(componentDirectory + QDir::separator() + download);
const QUrl downloadUrl(repositoryUrl + QLatin1String("/") + itComponentData.key() + QLatin1String("/") + download);
downloadFile(downloadUrl, fileTarget);
}
}
return componentDataHash;
}
bool extractFile(const QString &source, const QString &target)
{
if (!Lib7z::isSupportedArchive(source)) {
qWarning() << source << "is not a supported archive";
}
QFile archive(source);
if (archive.open(QIODevice::ReadOnly)) {
try {
Lib7z::extractArchive(&archive, target);
} catch (const Lib7z::SevenZipException& e) {
qWarning() << QString::fromLatin1("Error while extracting %1: %2.").arg(source, e.message());
return false;
} catch (...) {
qWarning() << QString::fromLatin1("Unknown exception caught while extracting %1.").arg(source);
return false;
}
} else {
qWarning() << QString::fromLatin1("Could not open %1 for reading: %2.").arg(
target, archive.errorString());
return false;
}
return true;
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// init installer to have the 7z lib initialized
QInstaller::init();
// with the installer messagehandler we need to enable verbose to see QDebugs
QInstaller::setVerbose(true);
QString repositoryUrl;
QString repositoryTarget;
QString packageDirectoryTarget;
bool clean = false;
QStringList args = app.arguments();
QStringList::const_iterator itArgument = args.constBegin();
itArgument++; // ignore the first one
if (itArgument == args.constEnd()) {
printUsage();
return 0;
}
for (; itArgument != args.constEnd(); ++itArgument) {
if (*itArgument == QString::fromLatin1("-h") || *itArgument == QString::fromLatin1("--help")) {
printUsage();
return 0;
} else if (*itArgument == QString::fromLatin1("--clean")) {
clean = true;
} else if (*itArgument == QString::fromLatin1("-u") || *itArgument == QString::fromLatin1("--url")) {
++itArgument;
if (itArgument == args.end()) {
printUsage();
return -1;
} else {
repositoryUrl = *itArgument;
}
} else if (*itArgument == QString::fromLatin1("-r") || *itArgument == QString::fromLatin1("--repository")) {
++itArgument;
if (itArgument == args.end()) {
printUsage();
return -1;
} else {
repositoryTarget = *itArgument;
}
} else if (*itArgument == QString::fromLatin1("-p") || *itArgument == QString::fromLatin1("--packages")) {
++itArgument;
if (itArgument == args.end()) {
printUsage();
return -1;
} else {
packageDirectoryTarget = *itArgument;
}
} else {
qWarning() << QString::fromLatin1("Argument '%1' is unknown").arg(*itArgument);
printUsage();
return 0;
}
}
if (repositoryTarget.isEmpty() || packageDirectoryTarget.isEmpty()) {
printUsage();
return 0;
} else {
// resolve pathes
repositoryTarget = QFileInfo(repositoryTarget).absoluteFilePath();
packageDirectoryTarget = QFileInfo(packageDirectoryTarget).absoluteFilePath();
}
foreach (const QString &target, QStringList() << repositoryTarget << packageDirectoryTarget) {
if (QFileInfo(target).exists()) {
if (clean) {
qDebug() << "removing directory:" << target;
QInstaller::removeDirectory(target, true);
} else if (!QDir(target).entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty()){
qWarning() << QString::fromLatin1("The directory '%1' needs to be empty or just "
"add the --clean argument.").arg(target);
return EXIT_FAILURE;
}
}
while (!QDir().mkpath(target)) {
qWarning() << QString::fromLatin1("Could not create %1").arg(target);
}
}
QHash<QString, ComponentData> componentDataHash;
componentDataHash = downLoadRepository(repositoryUrl, repositoryTarget);
// maybe in that case we should download the meta data to temp and
// get the downdloadable archives information from there later
if (packageDirectoryTarget.isEmpty())
return EXIT_SUCCESS;
QDirIterator itRepositoryFile(repositoryTarget, QDir::Files, QDirIterator::Subdirectories);
while (itRepositoryFile.hasNext()) {
QString currentFile = itRepositoryFile.next();
QString componentSubdirectoryName = itRepositoryFile.filePath();
QString normalizedRepositoryTarget = repositoryTarget;
normalizedRepositoryTarget.replace(QLatin1Char('\\'), QLatin1Char('/'));
componentSubdirectoryName.remove(repositoryTarget);
componentSubdirectoryName.remove(normalizedRepositoryTarget);
QString componentPackageDir = QFileInfo(packageDirectoryTarget + QDir::separator() + componentSubdirectoryName).absolutePath();
QString absoluteSourceFilePath = itRepositoryFile.filePath();
if (currentFile.endsWith(QLatin1String("meta.7z"))) {
QString absolutTargetPath = QFileInfo(
packageDirectoryTarget + QDir::separator()).absolutePath();
extractFile(absoluteSourceFilePath, absolutTargetPath);
QInstaller::moveDirectoryContents(componentPackageDir,
componentPackageDir + QDir::separator() + QLatin1String("meta"));
} else if (!currentFile.endsWith(QLatin1String("Updates.xml")) && !currentFile.endsWith(QLatin1String(".sha1"))){
QString pathToTarget = componentPackageDir + QDir::separator() + QLatin1String("data");
QString target = QDir(pathToTarget).absoluteFilePath(itRepositoryFile.fileName());
QDir().mkpath(pathToTarget);
QFile file;
if (!file.copy(absoluteSourceFilePath, target)) {
qWarning() << QString::fromLatin1("copy file %1 to %2 wasn't working %3").arg(
absoluteSourceFilePath, target, file.errorString());
}
}
}
QHashIterator<QString, ComponentData> itComponentData(componentDataHash);
while (itComponentData.hasNext()) {
itComponentData.next();
if (itComponentData.value().m_script.isEmpty())
continue;
QString componentScript = QFileInfo(QString::fromLatin1("%1/%2/meta/%3").arg(
packageDirectoryTarget, itComponentData.key(), itComponentData.value().m_script)).absoluteFilePath();
QString packagesXml = QFileInfo(QString::fromLatin1("%1/%2/meta/packages.xml").arg(
packageDirectoryTarget, itComponentData.key())).absoluteFilePath();
QFile packagesXmlFile(packagesXml);
if (!packagesXmlFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
qWarning() << QString::fromLatin1("Failed to open '%1' for writing. %2").arg(
packagesXml, packagesXmlFile.errorString());
return EXIT_FAILURE;
}
if (itComponentData.value().m_packageXml.toString().isEmpty()) {
qWarning() << "No xml data found in component:" << itComponentData.key();
return EXIT_FAILURE;
}
QTextStream stream(&packagesXmlFile);
stream << itComponentData.value().m_packageXml.toString(4);
packagesXmlFile.close();
QString dataPackagesPath = QFileInfo(QString::fromLatin1("%1/%2/data").arg(
packageDirectoryTarget, itComponentData.key())).absoluteFilePath();
QDir().mkpath(dataPackagesPath);
QString dataRepositoryPath = QFileInfo(repositoryTarget + QDir::separator() + itComponentData.key()).absoluteFilePath();
QDir().mkpath(dataRepositoryPath);
QFile componentScriptFile(componentScript);
if (!componentScriptFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << QString::fromLatin1("Can not read %1 %2").arg(componentScript, componentScriptFile.errorString());
continue;
}
QString sevenZString;
QTextStream in(&componentScriptFile);
in.setCodec("UTF-8");
while (!in.atEnd()) {
QString line = in.readLine();
if (line.contains(QLatin1String(".7z"))) {
int firstPosition = line.indexOf(QLatin1String("\""));
QString subString = line.right(line.count() - firstPosition - 1); //-1 means "
//qDebug() << subString;
int secondPosition = subString.indexOf(QLatin1String("\""));
sevenZString = subString.left(secondPosition);
QUrl downloadUrl((QStringList() << repositoryUrl << itComponentData.key() << itComponentData.value().m_version + sevenZString).join(QLatin1String("/")));
QString localRepositoryTarget = dataRepositoryPath + QLatin1Char('/') + itComponentData.value().m_version + sevenZString;
downloadFile(downloadUrl, localRepositoryTarget);
downloadFile(downloadUrl.toString() + QLatin1String(".sha1"), localRepositoryTarget + QLatin1String(".sha1"));
QFile::copy(localRepositoryTarget, dataPackagesPath + QLatin1Char('/') + sevenZString);
}
}
}
return 0;
}

View File

@ -1,171 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** 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 Digia Plc 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 = QLatin1String("download");
if (QFile::exists(basename)) {
// already exists, rename the old one
int i = 0;
while (QFile::exists(basename + QLatin1String(".old_") + QString::number(i)))
++i;
QFile::rename(basename, basename + QLatin1String(".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 = QLatin1String("bytes/sec");
} else if (speed < 1024*1024) {
speed /= 1024;
unit = QLatin1String("kB/s");
} else {
speed /= 1024*1024;
unit = QLatin1String("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());
}

View File

@ -1,332 +0,0 @@
/**************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Installer Framework.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
**************************************************************************/
#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 = QLatin1String("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 + QLatin1String("/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(QLatin1String("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 = QLatin1String("Updates.xml");
Q_ASSERT( !updatesXmlPath.isEmpty() );
Q_ASSERT( QFile::exists( updatesXmlPath ) );
QFile updatesFile( updatesXmlPath );
if ( !updatesFile.open( QIODevice::ReadOnly ) ) {
//qDebug() << QString::fromLatin1("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::fromLatin1("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() == QLatin1String("PackageUpdate") ) {
const QDomNodeList c2 = el.childNodes();
for ( int j = 0; j < c2.count(); ++j ) {
if ( c2.at( j ).toElement().tagName() == QLatin1String("Name") )
packageName = c2.at( j ).toElement().text();
else if ( c2.at( j ).toElement().tagName() == QLatin1String("DisplayName") )
packageDisplayName = c2.at( j ).toElement().text();
else if ( c2.at( j ).toElement().tagName() == QLatin1String("Description") )
packageDescription = c2.at( j ).toElement().text();
else if ( c2.at( j ).toElement().tagName() == QLatin1String("UpdateText") )
packageUpdateText = c2.at( j ).toElement().text();
else if ( c2.at( j ).toElement().tagName() == QLatin1String("Version") )
packageVersion = c2.at( j ).toElement().text();
else if ( c2.at( j ).toElement().tagName() == QLatin1String("ReleaseDate") )
packageReleaseDate = c2.at( j ).toElement().text();
else if ( c2.at( j ).toElement().tagName() == QLatin1String("SHA1") )
packageHash = c2.at( j ).toElement().text();
else if ( c2.at( j ).toElement().tagName() == QLatin1String("UserInterfaces") )
packageUserinterfacesAsString = c2.at( j ).toElement().text();
else if ( c2.at( j ).toElement().tagName() == QLatin1String("Script") )
packageScript = c2.at( j ).toElement().text();
else if ( c2.at( j ).toElement().tagName() == QLatin1String("Dependencies") )
packageDependencies = c2.at( j ).toElement().text();
else if ( c2.at( j ).toElement().tagName() == QLatin1String("ForcedInstallation") )
packageForcedInstallation = c2.at( j ).toElement().text();
else if ( c2.at( j ).toElement().tagName() == QLatin1String("InstallPriority") )
packageInstallPriority = c2.at( j ).toElement().text();
else if ( c2.at( j ).toElement().tagName() == QLatin1String("Virtual") && c2.at( j )
.toElement().text() == QLatin1String("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 + QLatin1String("/") + packageName + QLatin1String("/")
+ 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(QLatin1String(".7z"))) {
int firstPosition = line.indexOf(QLatin1String("\""));
QString subString = line.right(line.count() - firstPosition - 1); //-1 means "
//qDebug() << subString;
int secondPosition = subString.indexOf(QLatin1String("\""));
sevenZString = subString.left(secondPosition);
//qDebug() << sevenZString;
break;
}
}
file.remove();
}
QStringList packageUserinterfaces = packageUserinterfacesAsString.split(QLatin1String(","));
packageUserinterfaces.removeAll(QString());
packageUserinterfaces.removeAll(QLatin1String(""));
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() + QLatin1String("/")
+ packageName + QLatin1String(".xml")));
packagesXml.open( QIODevice::WriteOnly );
QTextStream packageAsXmlStream( &packagesXml );
packageAsXmlStream << QLatin1String("<?xml version=\"1.0\"?>" ) << endl;
packageAsXmlStream << QLatin1String("<Package>" ) << endl;
packageAsXmlStream << QString::fromLatin1(" <DisplayName>%1</DisplayName>").arg(packageDisplayName)
<< endl;
if (!packageDescription.isEmpty()) {
packageAsXmlStream << QString::fromLatin1(" <Description>%1</Description>" )
.arg(packageDescription) << endl;
}
if (!packageUpdateText.isEmpty()) {
packageAsXmlStream << QString::fromLatin1(" <UpdateText>%1</UpdateText>" )
.arg(packageUpdateText) << endl;
}
if (!packageVersion.isEmpty()) {
packageAsXmlStream << QString::fromLatin1(" <Version>%1</Version>" )
.arg(packageVersion) << endl;
}
if (!packageReleaseDate.isEmpty()) {
packageAsXmlStream << QString::fromLatin1(" <ReleaseDate>%1</ReleaseDate>" )
.arg(packageReleaseDate) << endl;
}
packageAsXmlStream << QString::fromLatin1(" <Name>%1</Name>" ).arg(packageName) << endl;
if (!packageScript.isEmpty()) {
packageAsXmlStream << QString::fromLatin1(" <Script>%1</Script>" ).arg(packageScript) << endl;
}
if (packageIsVirtual) {
packageAsXmlStream << QString::fromLatin1(" <Virtual>true</Virtual>" ) << endl;
}
if (!packageInstallPriority.isEmpty()) {
packageAsXmlStream << QString::fromLatin1(" <InstallPriority>%1</InstallPriority>" )
.arg(packageInstallPriority) << endl;
}
if (!packageDependencies.isEmpty()) {
packageAsXmlStream << QString::fromLatin1(" <Dependencies>%1</Dependencies>" )
.arg(packageDependencies) << endl;
}
if (!packageForcedInstallation.isEmpty()) {
packageAsXmlStream << QString::fromLatin1(" <ForcedInstallation>%1</ForcedInstallation>" )
.arg(packageForcedInstallation) << endl;
}
if (!packageUserinterfaces.isEmpty()) {
packageAsXmlStream << QString::fromLatin1(" <UserInterfaces>" ) << endl;
foreach(const QString userInterfaceFile, packageUserinterfaces) {
packageAsXmlStream << QString::fromLatin1(" <UserInterface>%1</UserInterface>" )
.arg(userInterfaceFile) << endl;
}
packageAsXmlStream << QString::fromLatin1(" </UserInterfaces>" ) << endl;
}
packageAsXmlStream << QString::fromLatin1("</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;
}

View File

@ -1,19 +0,0 @@
TEMPLATE = app
INCLUDEPATH += . ..
TARGET = repogenfromonlinerepo
include(../../installerfw.pri)
QT -= gui
QT += network
CONFIG += console
CONFIG -= app_bundle
DESTDIR = $$IFW_APP_PATH
SOURCES += main.cpp \
downloadmanager.cpp \
textprogressbar.cpp
HEADERS += downloadmanager.h \
textprogressbar.h

View File

@ -9,7 +9,7 @@ SUBDIRS += \
EXTRASUBDIRS = \
extractbinarydata \
repocompare \
repogenfromonlinerepo
getrepositorycontent
include(../installerfw.pri)