diff --git a/CMakeLists.txt b/CMakeLists.txt index 965657373..ac3681939 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,321 +1,320 @@ cmake_minimum_required(VERSION 2.8.12) project(marble) #################################################### # CMake Settings SET(CMAKE_COLOR_MAKEFILE ON) # SET(CMAKE_SKIP_RPATH ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) # Let CMake find the correct library dir instead of # relying on the obsolete LIB_SUFFIX parameter include(GNUInstallDirs) # Taken from KDECompilerSettings.cmake: # Pick sensible versions of the C and C++ standards. # Note that MSVC does not have equivalent flags; the features are either # supported or they are not. if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") # We use the C89 standard because that is what is common to all our # compilers (in particular, MSVC 2010 does not support C99) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=iso9899:1990") endif() if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel" AND NOT WIN32) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") endif() # Default to hidden visibility for symbols set(CMAKE_C_VISIBILITY_PRESET hidden) set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) if (POLICY CMP0063) cmake_policy(SET CMP0063 NEW) endif() #################################################### # Where to look first for cmake modules, # before ${CMAKE_ROOT}/Modules/ is checked set ( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/cmake_find_rules ${CMAKE_CURRENT_SOURCE_DIR}/cmake_scripts ${CMAKE_MODULE_PATH} ) # add cmake macros include(GenerateExportHeader) include( MarbleMacros ) #################################################### # Generate the tiles with the tilecreator at compile time # if this option is set, srtm.jpg will not be installed but the generated tiles instead option(MOBILE "Create a Marble version optimized for handheld devices") #################################################### # Build a D-Bus interface for the Marble widget # This is disabled by default for all win32, apple and Android if(WIN32 OR APPLE OR CMAKE_SYSTEM_NAME STREQUAL Android) option(BUILD_WITH_DBUS "Build the D-Bus interface for the Marble widget" OFF) else() option(BUILD_WITH_DBUS "Build the D-Bus interface for the Marble widget" ON) endif() ####################################################### # Specific options for building for different platforms if(CMAKE_SYSTEM_NAME STREQUAL Android) add_definitions(-DANDROID) # Minimum Qt version set(QT_REQUIRED_VERSION 5.3.0) SET(QT_QMAKE_EXECUTABLE "$ENV{Qt5_android}/bin/qmake") find_package(Qt5Location REQUIRED) find_package(Qt5Positioning REQUIRED) find_package(Qt5Multimedia REQUIRED) set ( MARBLE_NO_WEBKITWIDGETS TRUE ) else() find_package(Qt5WebKit) find_package(Qt5WebKitWidgets) if ( NOT Qt5WebKitWidgets_FOUND ) set ( MARBLE_NO_WEBKITWIDGETS TRUE ) endif() endif() find_package(Qt5Core REQUIRED) find_package(Qt5Xml REQUIRED) find_package(Qt5Network REQUIRED) find_package(Qt5Test REQUIRED) find_package(Qt5Script REQUIRED) find_package(Qt5Widgets REQUIRED) find_package(Qt5Svg REQUIRED) find_package(Qt5Sql REQUIRED) find_package(Qt5Concurrent REQUIRED) find_package(Qt5Quick REQUIRED) find_package(Qt5PrintSupport REQUIRED) if (BUILD_WITH_DBUS) find_package(Qt5DBus) if (NOT Qt5DBus_FOUND) set(MARBLE_NO_DBUS TRUE) endif() else() set(MARBLE_NO_DBUS TRUE) endif() if(QTONLY) # Forward the old QTONLY=TRUE option to the new WITH_KDE=FALSE # needs to be written to cache and forcefully, otherwise macro_optional_find_package's # option(WITH_${_name} ON) seems to operate on a shadowed variant of the variable set(WITH_KF5 FALSE CACHE BOOL "Search for KF5 package" FORCE) # And unset it quickly. Nobody shall use it anymore anywhere. # to detect if KDE _should_ be used (set by user): WITH_KDE but do not use it within src/lib/ unset(QTONLY) endif() set(MARBLEWIDGET marblewidget-qt5) SET(CMAKE_AUTOMOC TRUE) # Use M_PI under Windows if( WIN32 ) add_definitions( -D_USE_MATH_DEFINES ) endif( WIN32 ) #################################################### # build unit tests INCLUDE (CTest) ENABLE_TESTING() option( BUILD_MARBLE_TESTS "Build unit tests" ON ) add_feature_info("Unit tests" BUILD_MARBLE_TESTS "Build unit tests. Toggle with BUILD_MARBLE_TESTS=YES/NO. 'make test' will run all.") if( BUILD_MARBLE_TESTS ) # SET (TEST_DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/test_data") #where unit test binaries should be installed to and run from # SET (MARBLE_TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/tests) endif( BUILD_MARBLE_TESTS ) #################################################### set (PEDANTIC FALSE CACHE BOOL "Determines if we should compile with -Wall -Werror.") set (ENABLE_TESTS FALSE CACHE BOOL "Build unit tests?") set (WITH_DESIGNER_PLUGIN TRUE CACHE BOOL "Build plugins for Qt Designer") add_feature_info("Qt Designer plugins" WITH_DESIGNER_PLUGIN "Marble widget support in Qt Designer. Toggle with WITH_DESIGNER_PLUGIN=YES/NO") set(EXEC_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE PATH "Base directory for executables and libraries" FORCE) if (NOT QT_PLUGINS_DIR) set(QT_PLUGINS_DIR ${CMAKE_INSTALL_LIBDIR}/plugins) endif() #################################################### # Detect default for the user configurable MARBLE_DATA_PATH option if(WIN32) set(data_dir data) set(plugin_dir plugins) elseif(APPLE) # needed for finding bundle path in e.g. katlasdir.h FIND_LIBRARY(APP_SERVICES_LIBRARY ApplicationServices ) MARK_AS_ADVANCED (APP_SERVICES_LIBRARY) SET(MAC_EXTRA_LIBS ${APP_SERVICES_LIBRARY}) # for Mac OS X, everything is put inside an application bundle SET (CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/) # path for library references SET (CMAKE_INSTALL_NAME_DIR @executable_path/lib) # install the Info.plist file install(FILES src/mac/Info.plist DESTINATION ${CMAKE_INSTALL_PREFIX}/Marble.app/Contents) #SET (lib_dir ${CMAKE_INSTALL_PREFIX}/Marble.app/Contents/MacOS/lib) SET (data_dir ${CMAKE_INSTALL_PREFIX}/Marble.app/Contents/MacOS/resources/data) SET (plugin_dir ${CMAKE_INSTALL_PREFIX}/Marble.app/Contents/MacOS/resources/plugins) elseif(CMAKE_SYSTEM_NAME STREQUAL Android) set(plugin_dir "${CMAKE_INSTALL_PREFIX}/assets/plugins") set(data_dir "${CMAKE_INSTALL_PREFIX}/assets/data") else() # Linux / bsd etc... set(data_dir ${CMAKE_INSTALL_FULL_DATAROOTDIR}/marble/data) set(plugin_dir ${CMAKE_INSTALL_FULL_LIBDIR}/marble/plugins) endif() if(NOT ICON_INSTALL_DIR) set(ICON_INSTALL_DIR ${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons) endif(NOT ICON_INSTALL_DIR) if(NOT APPS_INSTALL_DIR) set(APPS_INSTALL_DIR ${CMAKE_INSTALL_FULL_DATAROOTDIR}/applications) endif(NOT APPS_INSTALL_DIR) if(NOT INCLUDE_INSTALL_DIR) set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include") endif() if (NOT MARBLE_DATA_PATH) set (MARBLE_DATA_PATH ${data_dir}) endif (NOT MARBLE_DATA_PATH) if (NOT MARBLE_PLUGIN_PATH) set (MARBLE_PLUGIN_PATH ${plugin_dir}) endif (NOT MARBLE_PLUGIN_PATH) if (NOT MARBLE_DATA_INSTALL_PATH) set (MARBLE_DATA_INSTALL_PATH ${MARBLE_DATA_PATH}) endif (NOT MARBLE_DATA_INSTALL_PATH) if (NOT MARBLE_PLUGIN_INSTALL_PATH) set (MARBLE_PLUGIN_INSTALL_PATH ${MARBLE_PLUGIN_PATH}) endif (NOT MARBLE_PLUGIN_INSTALL_PATH) #MESSAGE( STATUS, "MARBLE_PLUGIN_INSTALL_PATH: ${MARBLE_PLUGIN_INSTALL_PATH}" ) if(WIN32) set (STATIC_BUILD FALSE CACHE BOOL "Link to static Qt libs (win32 only)?") endif(WIN32) add_definitions( - -DQT_USE_FAST_CONCATENATION - -DQT_USE_FAST_OPERATOR_PLUS + -DQT_USE_QSTRINGBUILDER -DQT_NO_SIGNALS_SLOTS_KEYWORDS -DQT_NO_URL_CAST_FROM_STRING -DQT_STRICT_ITERATORS ) #################################################### # Options for static build if(STATIC_BUILD) add_definitions(-DSTATIC_BUILD=1) endif(STATIC_BUILD) ############################################################# if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER MATCHES "icc") # Its good programming practice to build with no warnings... add_definitions( -Wall -Wextra -Wundef -Wnon-virtual-dtor -Woverloaded-virtual -Wno-long-long -Wchar-subscripts -Wcast-align -Wpointer-arith -Wformat-security ) # In pedantic mode, treat warnings as errors if (PEDANTIC) add_definitions( -Werror ) endif (PEDANTIC) endif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER MATCHES "icc") ############################################################# # Add a compiler def so that we can conditionally compile # code in debug mode only (e.g. extra console messages) IF (CMAKE_BUILD_TYPE MATCHES Debug) IF(NOT MINGW) ADD_DEFINITIONS(-DDEBUG) ELSE(NOT MINGW) REMOVE_DEFINITIONS( -DQT_NO_DEBUG ) ENDIF(NOT MINGW) ENDIF (CMAKE_BUILD_TYPE MATCHES Debug) #################################################### # on Win32 set the debug postfix if(WIN32) # distinguish between debug and release plugin SET(CMAKE_DEBUG_POSTFIX "d") endif(WIN32) #################################################### #################################################### # Add the include directories include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/projections ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/data ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/graphicsitem ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/handlers/dgml ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/parser ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/writer ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/scene ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/graphicsview ${CMAKE_CURRENT_BINARY_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src/lib/marble ) #################################################### # Descend into subdirectories add_subdirectory(doc) add_subdirectory(src) add_subdirectory(data) include(DistTarget) add_subdirectory(tests) option(BUILD_MARBLE_TOOLS "Build various tools related to Marble" OFF) add_feature_info("Marble tools" BUILD_MARBLE_TOOLS "Build various Marble tools for e.g. file format conversion. Toggle with BUILD_MARBLE_TOOLS=YES/NO.") if(BUILD_MARBLE_TOOLS) add_subdirectory(tools) endif() option(BUILD_MARBLE_EXAMPLES "Build C++ examples showing how to use the Marble library" OFF) add_feature_info("Marble library C++ examples" BUILD_MARBLE_EXAMPLES "Build C++ examples showing how to use the Marble library. Toggle with BUILD_MARBLE_EXAMPLES=YES/NO.") if(BUILD_MARBLE_EXAMPLES) add_subdirectory(examples/cpp) endif() #################################################### # Install extra files install(FILES LICENSE.txt DESTINATION ${MARBLE_DATA_INSTALL_PATH}) ############################################################ # Uninstall stuff CONFIGURE_FILE( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") include(MarbleCPackOptions) marble_feature_summary(WHAT ALL) diff --git a/tools/osm-sisyphus/job.cpp b/tools/osm-sisyphus/job.cpp index 09ee4e052..b9ac7fbf9 100644 --- a/tools/osm-sisyphus/job.cpp +++ b/tools/osm-sisyphus/job.cpp @@ -1,321 +1,321 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2011 Dennis Nienhüser // #include "job.h" #include "logger.h" #include "upload.h" #include #include #include Job::Job(const Region ®ion, const JobParameters ¶meters, QObject *parent) : QObject(parent), m_status(Waiting), m_region(region), m_parameters(parameters) { // nothing to do } Job::Status Job::status() const { return m_status; } QString Job::statusMessage() const { return m_statusMessage; } Region Job::region() const { return m_region; } void Job::setTransport(const QString &transport) { m_transport = transport; } QString Job::transport() const { return m_transport; } void Job::setProfile(const QString &profile) { m_profile = profile; } void Job::setMonavSettings(const QString &filename) { m_monavSettings = filename; } bool Job::operator ==(const Job &other) const { return m_transport == other.m_transport && m_region == other.m_region; } void Job::run() { if (download() && monav() && search() && package() && upload()) { // Nothing to do. } cleanup(); emit finished(this); } void Job::changeStatus(Job::Status status, const QString &message) { QString statusType; switch (status) { case Waiting: statusType = "waiting"; break; case Downloading: statusType = "downloading"; break; case Routing: statusType = "routing"; break; case Search: statusType = "search"; break; case Packaging: statusType = "packaging"; break; case Uploading: statusType = "uploading"; break; case Finished: statusType = "finished"; break; case Error: statusType = "error"; break; } Logger::instance().setStatus(m_region.id() + '_' + m_transport, m_region.name() + QLatin1String( " (" ) + m_transport + ')', statusType, message); m_statusMessage = message; m_status = status; } bool Job::download() { changeStatus(Downloading, "Downloading data."); qDebug() << "Saving file to " << osmFile().absoluteFilePath(); if (osmFile().exists()) { QDateTime now = QDateTime::currentDateTime(); if (osmFile().lastModified().daysTo(now) > 7) { qDebug() << "Old file is outdated, re-downloading " << osmFile().absoluteFilePath(); QFile::remove(osmFile().absoluteFilePath()); } else { qDebug() << "Old file is still ok, reusing" << osmFile().absoluteFilePath(); return true; } } QProcess wget; QStringList arguments; QString url = m_region.pbfFile(); arguments << "-O" << osmFile().absoluteFilePath() << url; qDebug() << "Downloading " << url; wget.start("wget", arguments); wget.waitForFinished(1000 * 60 * 60 * 12); // wait up to 12 hours for download to complete if (wget.exitStatus() == QProcess::NormalExit && wget.exitCode() == 0) { return true; } else { qDebug() << "Failed to download " << url; QFile::remove(osmFile().absoluteFilePath()); - changeStatus(Error, "Error downloading .osm.pbf file: " + wget.readAllStandardError()); + changeStatus(Error, QLatin1String("Error downloading .osm.pbf file: ") + wget.readAllStandardError()); return false; } } //bool Job::marble() //{ // changeStatus(Routing, "Extracting bounding box."); // QStringList arguments; // arguments << "--name" << m_region.name(); // arguments << "--version" << "0.2"; // arguments << "--date" << QDateTime::currentDateTime().toString("yyyy/dd/MM"); // arguments << "--transport" << m_transport; // arguments << "--payload" << targetFile().fileName(); // arguments << m_parameters.base().absoluteFilePath("poly/" + m_region.polyFile()); // arguments << monavDir().absoluteFilePath() + "/marble.kml"; // QProcess poly2kml; // poly2kml.start("poly2kml", arguments); // poly2kml.waitForFinished(1000 * 60 * 30); // wait up to half an hour for poly2kml to convert the data // if (poly2kml.exitStatus() == QProcess::NormalExit && poly2kml.exitCode() == 0) { // qDebug() << "Processed kml file for marble"; // return true; // } else { // qDebug() << "poly2kml exiting with status " << poly2kml.exitCode(); // changeStatus(Error, "Error creating marble.kml: " + poly2kml.readAllStandardError()); // return false; // } //} bool Job::monav() { QString const status = QString("Generating offline routing map from %1 (%2).").arg(osmFile().fileName()).arg(Region::fileSize(osmFile())); changeStatus(Routing, status); QStringList arguments; arguments << "-s=" + m_monavSettings; arguments << "-i=" + osmFile().absoluteFilePath(); arguments << "-o=" + monavDir().absoluteFilePath(); arguments << "-pi=OpenStreetMap Importer" << "-pro=Contraction Hierarchies"; arguments << "-pg=GPS Grid" << "-di"; arguments << "-dro=" + m_transport; arguments << "--profile=" + m_profile; arguments << "-dd" /*<< "-dc"*/; QProcess monav; monav.start("monav-preprocessor", arguments); monav.waitForFinished(1000 * 60 * 60 * 6); // wait up to 6 hours for monav to convert the data if (monav.exitStatus() == QProcess::NormalExit && monav.exitCode() == 0) { qDebug() << "Processed osm file for monav"; } else { qDebug() << "monav exiting with status " << monav.exitCode(); - changeStatus(Error, "Routing map conversion failed: " + monav.readAllStandardError()); + changeStatus(Error, QLatin1String("Routing map conversion failed: ") + monav.readAllStandardError()); return false; } QFile pluginsFile(monavDir().absoluteFilePath() + "/plugins.ini"); pluginsFile.open(QFile::WriteOnly | QFile::Truncate); QTextStream pluginsStream(&pluginsFile); pluginsStream << "[General]\nrouter=Contraction Hierarchies\nrenderer=Mapnik Renderer\ngpsLookup=GPS Grid\naddressLookup=Unicode Tournament Trie\n"; pluginsFile.close(); QFileInfo subdir = QFileInfo(monavDir().absoluteFilePath() + "/routing_" + m_transport.toLower()); if (subdir.exists() && subdir.isDir()) { QFileInfoList files = QDir(subdir.absoluteFilePath()).entryInfoList(QDir::Files); foreach(const QFileInfo &file, files) { if (!QFile::rename(file.absoluteFilePath(), monavDir().absoluteFilePath() + '/' + file.fileName())) { changeStatus(Error, "Unable to move monav files to target directory."); return false; } } QDir("/").rmdir(subdir.absoluteFilePath()); } else { changeStatus(Error, "Unable to find files created by monav"); return false; } return true; } bool Job::search() { QString const status = QString("Generating offline search database from %1 (%2).").arg(osmFile().fileName()).arg(Region::fileSize(osmFile())); changeStatus(Search, status); QStringList arguments; arguments << "--name" << m_region.name(); arguments << "--version" << "0.3"; arguments << "--date" << QDateTime::currentDateTime().toString("MM/dd/yy"); arguments << "--transport" << m_transport; arguments << "--payload" << targetFile().fileName(); arguments << osmFile().absoluteFilePath(); arguments << searchFile().absoluteFilePath(); QFileInfo kmlFile(monavDir().absoluteFilePath() + "/marble.kml"); arguments << kmlFile.absoluteFilePath(); QProcess osmAddresses; osmAddresses.start("osm-addresses", arguments); osmAddresses.waitForFinished(1000 * 60 * 60 * 18); // wait up to 18 hours for osm-addresses to convert the data if (osmAddresses.exitStatus() == QProcess::NormalExit && osmAddresses.exitCode() == 0) { searchFile().refresh(); if (!searchFile().exists()) { qDebug() << "osm-addresses did not create the .sqlite file"; changeStatus(Error, "Unknown error when creating the search database"); return false; } else if (searchFile().size() < 8000) { qDebug() << "The .sqlite database has a suspiciously small size."; changeStatus(Error, "Search database is too small. Too little memory?"); return false; } kmlFile.refresh(); if (!kmlFile.exists()) { qDebug() << "File marble.kml has not been generated."; changeStatus(Error, "Failed to generate marble.kml. Too little memory?"); return false; } return true; } else { qDebug() << "osm-addresses exiting with status " << osmAddresses.exitCode(); - changeStatus(Error, "Error creating search database: " + osmAddresses.readAllStandardError()); + changeStatus(Error, QLatin1String("Error creating search database: ") + osmAddresses.readAllStandardError()); return false; } } bool Job::package() { changeStatus(Packaging, "Creating archive."); QStringList arguments; arguments << "czf" << targetFile().absoluteFilePath() << "earth/monav/" << "earth/placemarks"; QProcess tar; tar.setWorkingDirectory(m_parameters.base().absolutePath() + "/data/" + m_region.id()); tar.start("tar", arguments); tar.waitForFinished(1000 * 60 * 60); // wait up to 1 hour for tar to package things if (tar.exitStatus() == QProcess::NormalExit && tar.exitCode() == 0) { qDebug() << "Packaged tar file"; return true; } else { - changeStatus(Error, "Packaging failed: " + tar.readAllStandardError()); + changeStatus(Error, QLatin1String("Packaging failed: ") + tar.readAllStandardError()); return false; } } bool Job::upload() { changeStatus(Uploading, "Uploading file"); if (targetFile().exists()) { Upload::instance().uploadAndDelete(m_region, targetFile(), m_transport); return true; } changeStatus(Error, "Target file does not exist."); return false; } bool Job::cleanup() { if (!m_parameters.cacheData()) { QFile::remove(osmFile().absoluteFilePath()); } QFileInfo subdir = QFileInfo(monavDir().absoluteFilePath()); if (subdir.exists() && subdir.isDir()) { QFileInfoList files = QDir(subdir.absoluteFilePath()).entryInfoList(QDir::Files); foreach(const QFileInfo &file, files) { QFile::remove(file.absoluteFilePath()); } } QFile::remove(searchFile().absoluteFilePath()); return true; } QFileInfo Job::osmFile() { m_parameters.base().mkdir("download"); QFileInfo result(m_parameters.base(), QString("download/") + m_region.id() + ".osm.pbf"); return result; } QFileInfo Job::monavDir() { QString const subdir = "data/" + m_region.id() + "/earth/monav/" + m_transport.toLower() + '/' + m_region.path(); m_parameters.base().mkpath(subdir); QFileInfo result(m_parameters.base(), subdir); return result; } QFileInfo Job::targetFile() { m_parameters.base().mkdir("finished"); QFileInfo result(m_parameters.base(), "finished/" + m_region.id() + '_' + m_transport.toLower() + ".tar.gz"); return result; } QFileInfo Job::searchFile() { QString const subdir = "data/" + m_region.id() + "/earth/placemarks/" + QFileInfo(m_region.path()).path(); m_parameters.base().mkpath(subdir); QFileInfo result(m_parameters.base(), subdir + '/' + m_region.id() + ".sqlite"); return result; } #include "moc_job.cpp" diff --git a/tools/osm-sisyphus/upload.cpp b/tools/osm-sisyphus/upload.cpp index 2e109152a..8de9f6f4e 100644 --- a/tools/osm-sisyphus/upload.cpp +++ b/tools/osm-sisyphus/upload.cpp @@ -1,304 +1,304 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2011 Dennis Nienhüser // #include "upload.h" #include "logger.h" #include #include #include #include #include #include Upload::Upload(QObject *parent) : QObject(parent), m_uploadFiles(true) { // nothing to do } void Upload::changeStatus(const Package &package, const QString &status, const QString &message) { Logger::instance().setStatus( package.region.id() + '_' + package.transport, package.region.name() + QLatin1String( " (" ) + package.transport + ')', status, message); } void Upload::processQueue() { if (m_queue.isEmpty()) { return; } Package const package = m_queue.takeFirst(); if (upload(package)) { QString const message = QString("File %1 (%2) successfully created and uploaded").arg(package.file.fileName()).arg(Region::fileSize(package.file)); changeStatus( package, "finished", message); } deleteFile(package.file); processQueue(); } bool Upload::upload(const Package &package) { if (!m_uploadFiles) { return true; } QProcess ssh; QStringList arguments; QString const auth = "marble@filesmaster.kde.org"; arguments << auth; arguments << "mkdir" << "-p"; QString remoteDir = QString("/home/marble/web/monav/") + targetDir(); arguments << remoteDir; ssh.start("ssh", arguments); ssh.waitForFinished(1000 * 60 * 10); // wait up to 10 minutes for mkdir to complete if (ssh.exitStatus() != QProcess::NormalExit || ssh.exitCode() != 0) { qDebug() << "Failed to create remote directory " << remoteDir; - changeStatus( package, "error", "Failed to create remote directory: " + ssh.readAllStandardError()); + changeStatus(package, "error", QLatin1String("Failed to create remote directory: ") + ssh.readAllStandardError()); return false; } QProcess scp; arguments.clear(); arguments << package.file.absoluteFilePath(); QString target = remoteDir + '/' + package.file.fileName(); arguments << auth + ':' + target; scp.start("scp", arguments); scp.waitForFinished(1000 * 60 * 60 * 12); // wait up to 12 hours for upload to complete if (scp.exitStatus() != QProcess::NormalExit || scp.exitCode() != 0) { qDebug() << "Failed to upload " << target; - changeStatus( package, "error", "Failed to upload file: " + scp.readAllStandardError()); + changeStatus(package, "error", QLatin1String("Failed to upload file: ") + scp.readAllStandardError()); return false; } return adjustNewstuffFile(package); } void Upload::deleteFile(const QFileInfo &file) { if (!m_jobParameters.cacheData()) { QFile::remove(file.absoluteFilePath()); } } bool Upload::adjustNewstuffFile(const Package &package) { if (m_xml.isNull()) { QTemporaryFile tempFile(QDir::tempPath() + "/monav-maps-XXXXXX.xml"); tempFile.setAutoRemove(false); tempFile.open(); QString monavFilename = tempFile.fileName(); tempFile.close(); QProcess wget; QStringList const arguments = QStringList() << "http://filesmaster.kde.org/marble/newstuff/maps-monav.xml" << "-O" << monavFilename; wget.start("wget", arguments); wget.waitForFinished(1000 * 60 * 60 * 12); // wait up to 12 hours for download to complete if (wget.exitStatus() != QProcess::NormalExit || wget.exitCode() != 0) { qDebug() << "Failed to download newstuff file from filesmaster.kde.org"; - changeStatus( package, "error", "Failed to sync newstuff file: " + wget.readAllStandardError()); + changeStatus( package, "error", QLatin1String("Failed to sync newstuff file: ") + wget.readAllStandardError()); return false; } QFile file(monavFilename); if (!file.open(QFile::ReadOnly)) { qDebug() << "Failed to open newstuff file" << monavFilename; changeStatus( package, "error", "Failed to open newstuff file."); return false; } if ( !m_xml.setContent( &file ) ) { qDebug() << "Cannot parse newstuff xml file."; changeStatus( package, "error", "Failed to parse newstuff .xml file."); return false; } QFile::remove(monavFilename); } QDomElement root = m_xml.documentElement(); QDomNodeList regions = root.elementsByTagName( "stuff" ); for ( int i = 0; i < int(regions.length()); ++i ) { QDomNode node = regions.item( i ); if (!node.namedItem("payload").isNull()) { QUrl url(node.namedItem("payload").toElement().text()); QFileInfo fileInfo(url.path()); if (fileInfo.fileName() == package.file.fileName()) { QString removeFile; QDomNode dateNode = node.namedItem("releasedate"); if (!dateNode.isNull()) { dateNode.removeChild(dateNode.firstChild()); dateNode.appendChild(m_xml.createTextNode(releaseDate())); } QDomNode versionNode = node.namedItem("version"); if (!versionNode.isNull()) { double version = versionNode.toElement().text().toDouble(); versionNode.removeChild(versionNode.firstChild()); versionNode.appendChild(m_xml.createTextNode(QString::number(version+0.1, 'f', 1))); } QDomNode payloadNode = node.namedItem("payload"); payloadNode.removeChild(payloadNode.firstChild()); if (fileInfo.dir().dirName() != targetDir()) { removeFile = QString("/home/marble/web/monav/%1/%2").arg(fileInfo.dir().dirName()).arg(package.file.fileName()); qDebug() << "Going to remove the old file " << removeFile; } QString payload = "http://files.kde.org/marble/monav/%1/%2"; payload = payload.arg(targetDir()).arg(package.file.fileName()); payloadNode.appendChild(m_xml.createTextNode(payload)); return removeFile.isEmpty() ? uploadNewstuff() : (uploadNewstuff() && deleteRemoteFile(removeFile)); } } } QDomNode stuff = root.appendChild(m_xml.createElement("stuff")); stuff.toElement().setAttribute("category", "marble/routing/monav"); QDomNode nameNode = stuff.appendChild(m_xml.createElement("name")); nameNode.toElement().setAttribute("lang", "en"); QString name = "%1 / %2 (%3)"; if (package.region.country().isEmpty()) { name = name.arg(package.region.continent()).arg(package.region.name()); name = name.arg(package.transport); } else { name = "%1 / %2 / %3 (%4)"; name = name.arg(package.region.continent()).arg(package.region.country()); name = name.arg(package.region.name()).arg(package.transport); } nameNode.appendChild(m_xml.createTextNode(name)); QDomNode authorNode = stuff.appendChild(m_xml.createElement("author")); authorNode.appendChild(m_xml.createTextNode("Automatically created from map data assembled by the OpenStreetMap community")); QDomNode licenseNode = stuff.appendChild(m_xml.createElement("license")); licenseNode.appendChild(m_xml.createTextNode("Creative Commons by-SA 2.0")); QDomNode summaryNode = stuff.appendChild(m_xml.createElement("summary")); QString summary = "Requires KDE >= 4.6: Offline Routing in %1, %2"; summary = summary.arg(package.region.name()).arg(package.region.continent()); summaryNode.appendChild(m_xml.createTextNode(summary)); QDomNode versionNode = stuff.appendChild(m_xml.createElement("version")); versionNode.appendChild(m_xml.createTextNode("0.1")); QDomNode dateNode = stuff.appendChild(m_xml.createElement("releasedate")); dateNode.appendChild(m_xml.createTextNode(releaseDate())); QDomNode previewNode = stuff.appendChild(m_xml.createElement("preview")); QString preview = "http://files.kde.org/marble/monav/previews/%1-preview.png"; preview = preview.arg(package.region.id()); previewNode.appendChild(m_xml.createTextNode(preview)); QDomNode payloadNode = stuff.appendChild(m_xml.createElement("payload")); payloadNode.toElement().setAttribute("lang", "en"); QString payload = "http://files.kde.org/marble/monav/%1/%2"; payload = payload.arg(targetDir()).arg(package.file.fileName()); payloadNode.appendChild(m_xml.createTextNode(payload)); return uploadNewstuff(); } bool Upload::uploadNewstuff() { QTemporaryFile outFile(QDir::tempPath() + "/monav-maps-out-XXXXXX.xml"); outFile.open(); QTextStream outStream(&outFile); outStream << m_xml.toString(2); outStream.flush(); QProcess scp; QStringList arguments; arguments << outFile.fileName(); arguments << "marble@filesmaster.kde.org:/home/marble/web/newstuff/maps-monav.xml"; scp.start("scp", arguments); scp.waitForFinished(1000 * 60 * 60 * 12); // wait up to 12 hours for upload to complete if (scp.exitStatus() != QProcess::NormalExit || scp.exitCode() != 0) { qDebug() << "Failed to upload " << outFile.fileName() << ": " << scp.readAllStandardError(); return false; } return true; } bool Upload::deleteRemoteFile(const QString &filename) { if (filename.isEmpty()) { return true; } if (!filename.startsWith(QLatin1String( "/home/marble/" ))) { return false; } QProcess ssh; QStringList arguments; arguments << "marble@filesmaster.kde.org" << "rm" << filename; ssh.start("ssh", arguments); ssh.waitForFinished(1000 * 60 * 10); // wait up to 10 minutes for rm to complete if (ssh.exitStatus() != QProcess::NormalExit || ssh.exitCode() != 0) { qDebug() << "Failed to delete remote file " << filename; return false; } return true; } void Upload::uploadAndDelete(const Region ®ion, const QFileInfo &file, const QString &transport) { Package package; package.region = region; package.file = file; package.transport = transport; m_queue.removeAll(package); m_queue << package; processQueue(); } bool Upload::Package::operator ==(const Upload::Package &other) const { return region == other.region; } Upload &Upload::instance() { static Upload m_instance; return m_instance; } bool Upload::uploadFiles() const { return m_uploadFiles; } void Upload::setJobParameters(const JobParameters ¶meters) { m_jobParameters = parameters; } void Upload::setUploadFiles(bool arg) { m_uploadFiles = arg; } QString Upload::targetDir() const { QString targetDir = "%1-w%2"; targetDir = targetDir.arg(QDateTime::currentDateTime().date().year()); targetDir = targetDir.arg(QDateTime::currentDateTime().date().weekNumber()); return targetDir; } QString Upload::releaseDate() const { return QDateTime::currentDateTime().toString("MM/dd/yy"); } #include "moc_upload.cpp"