Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare sailjail integration #270

Merged
merged 10 commits into from Sep 30, 2021
Prev Previous commit
Next Next commit
add code for data migration
  • Loading branch information
Karry committed Sep 29, 2021
commit c4c4211e2c5f273a306ae5fd58cccbe3fe277e16
2 changes: 2 additions & 0 deletions CMakeLists.txt
Expand Up @@ -314,6 +314,7 @@ set(HEADER_FILES
src/IconProvider.h
src/LocFile.h
src/MemoryManager.h
src/Migration.h
src/NearWaypointModel.h
src/Tracker.h
src/SearchHistoryModel.h
Expand Down Expand Up @@ -394,6 +395,7 @@ set(SOURCE_FILES
src/AppSettings.cpp
src/LocFile.cpp
src/MemoryManager.cpp
src/Migration.cpp
src/OSMScout.cpp
src/Storage.cpp
src/CollectionModel.cpp
Expand Down
1 change: 0 additions & 1 deletion harbour-osmscout.desktop
Expand Up @@ -28,7 +28,6 @@ Name[hu]=OSMScout
BackupPathList=.local/share/cz.karry.osmscout/OSMScout:.config/cz.karry.osmscout/OSMScout.conf

[X-Sailjail]
# TODO: solve access to ~/Maps directory and migration of .cache, .share, .config
Permissions=Sharing;Internet;Audio;Location;RemovableMedia;Documents;Downloads
OrganizationName=cz.karry.osmscout
ApplicationName=OSMScout
3 changes: 3 additions & 0 deletions rpm/harbour-osmscout.changes.in
Expand Up @@ -495,3 +495,6 @@

* 2021-xx-xx Lukáš Karas <lukas.karas@centrum.cz> 2.17
- show warning on search or navigation where there is no offline database
- prepare for Sailjail sandboxing, process data migration on first startup:
-- application data and configuration migrated to new location
-- downloaded maps from ~/Maps are moved from ~/Downloads/Maps
121 changes: 121 additions & 0 deletions src/Migration.cpp
@@ -0,0 +1,121 @@
/*
OSMScout for SFOS
Copyright (C) 2021 Lukáš Karas

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include "Migration.h"

#include <QDebug>
#include <QDir>
#include <QCoreApplication>
#include <QStandardPaths>

#include <cassert>

Migration::Migration(const QString &home,
const QString &oldOrganization,
const QString &oldAppName,
const QString &newOrganization,
const QString &newAppName):
home(home),
oldOrganization(oldOrganization),
oldAppName(oldAppName),
newOrganization(newOrganization),
newAppName(newAppName)
{}

Migration::Migration(const QString &oldOrganization,
const QString &oldAppName):
Migration(QStandardPaths::writableLocation(QStandardPaths::HomeLocation),
oldOrganization,
oldAppName,
QCoreApplication::organizationName(),
QCoreApplication::applicationName())
{}

QString Migration::cacheDir(const QString &organization, const QString &appName) const
{
return home.absolutePath() + QDir::separator() +
".cache" + QDir::separator() +
(organization.isEmpty() ? appName : organization) + QDir::separator() +
appName;
}

QString Migration::configFile(const QString &organization, const QString &appName) const
{
return home.absolutePath() + QDir::separator() +
".config" + QDir::separator() +
(organization.isEmpty() ? appName : organization) + QDir::separator() +
appName + ".conf";
}

QString Migration::localDir(const QString &organization, const QString &appName) const
{
return home.absolutePath() + QDir::separator() +
".local" + QDir::separator() +
"share" + QDir::separator() +
(organization.isEmpty() ? appName : organization) + QDir::separator() +
appName;
}

bool Migration::migrate(const QString &oldLocation, const QString &newLocation) const
{
qDebug() << "Considering migration" << oldLocation << "to" << newLocation;
QFileInfo oldInfo(oldLocation);
QFileInfo newInfo(newLocation);
if (oldInfo.exists() && !newInfo.exists()){
QDir parent = newInfo.dir();
if (!parent.mkpath(parent.absolutePath())){
qWarning() << "Failed to create path" << parent.absolutePath();
return false;
}
if (!QFile::rename(oldLocation, newLocation)){
qWarning() << "Failed to move" << oldLocation << "to" << newLocation;
return false;
}
qDebug() << "Migrate" << oldLocation << "to" << newLocation;
return true;
}
return false;
}

bool Migration::migrateConfig() const
{
return migrate(configFile(oldOrganization, oldAppName),
configFile(newOrganization, newAppName));
}

bool Migration::migrateLocal() const
{
return migrate(localDir(oldOrganization, oldAppName),
localDir(newOrganization, newAppName));
}

bool Migration::wipeOldCache() const
{
QString cache = cacheDir(oldOrganization, oldAppName);
qDebug() << "Considering cache wipe" << cache;
assert(!cache.isEmpty());
assert(cache != "/");
assert(cache != ".");
assert(cache != home.absolutePath());
if (QFileInfo(cache).exists()) {
qDebug() << "Wiping old application cache" << cache;
return QDir(cache).removeRecursively();
}
return false;
}
64 changes: 64 additions & 0 deletions src/Migration.h
@@ -0,0 +1,64 @@
/*
OSMScout for SFOS
Copyright (C) 2021 Lukáš Karas

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#pragma once

#include <QString>
#include <QDir>

/**
* Linux specific utility for migrating Qt directories after change application name or organization.
*/
class Migration {
private:
QDir home;
QString oldOrganization;
QString oldAppName;
QString newOrganization;
QString newAppName;

public:
Migration(const QString &home,
const QString &oldOrganization,
const QString &oldAppName,
const QString &newOrganization,
const QString &newAppName);

Migration(const QString &oldOrganization,
const QString &oldAppName);

virtual ~Migration() = default;

QString cacheDir(const QString &organization, const QString &appName) const;

/**
* config file used by QSettings
* @param organization
* @param appName
* @return
*/
QString configFile(const QString &organization, const QString &appName) const;

QString localDir(const QString &organization, const QString &appName) const;

bool migrate(const QString &oldLocation, const QString &newLocation) const;
bool migrateConfig() const;
bool migrateLocal() const;
bool wipeOldCache() const;
};
30 changes: 17 additions & 13 deletions src/OSMScout.cpp
Expand Up @@ -25,6 +25,7 @@
#include "IconProvider.h" // IconProvider
#include "Arguments.h"
#include "MemoryManager.h"
#include "Migration.h"
#include "LocFile.h"

// collections
Expand Down Expand Up @@ -196,24 +197,27 @@ Q_DECL_EXPORT int main(int argc, char* argv[])
QString home = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
QString docs = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
QString cache = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
QString download = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);

QStringList databaseLookupDirectories;

// TODO: migrate to new path used with Sailjail:
// ~/.config/harbour-osmscout/harbour-osmscout.conf -> ~/.config/cz.karry.osmscout/OSMScout.conf
// ~/.local/share/harbour-osmscout/harbour-osmscout -> ~/.local/share/cz.karry.osmscout/OSMScout
// ~/Maps -> ~/Downloads/Maps
// wipe ~/.cache/harbour-osmscout/harbour-osmscout/

// if user has Maps directory in "Documents" already, we will use it
// for compatibility reasons
if (QFile::exists(docs + QDir::separator() + "Maps")) {
databaseLookupDirectories << docs + QDir::separator() + "Maps";
}else{
// we will use Maps in "Home" directory otherwise
databaseLookupDirectories << home + QDir::separator() + "Maps";
{ // TODO: remove this migration when Sailjail will be really enabled (old paths will be unavailable)
Migration migration("", "harbour-osmscout");
// migrate to new path used with Sailjail:
migration.migrateConfig(); // ~/.config/harbour-osmscout/harbour-osmscout.conf -> ~/.config/cz.karry.osmscout/OSMScout.conf
migration.migrateLocal(); // ~/.local/share/harbour-osmscout/harbour-osmscout -> ~/.local/share/cz.karry.osmscout/OSMScout
migration.wipeOldCache(); // wipe ~/.cache/harbour-osmscout/harbour-osmscout/
// ~/Maps -> ~/Downloads/Maps
if (!migration.migrate(home + QDir::separator() + "Maps", download + QDir::separator() + "Maps")) {
// possibly ~/Documents/Maps -> ~/Downloads/Maps
migration.migrate(docs + QDir::separator() + "Maps", download + QDir::separator() + "Maps");
}
}

// lookup Maps in "Downloads" directory
databaseLookupDirectories << download + QDir::separator() + "Maps";

// and in SD card root / Maps directory
for (const QStorageInfo &storage : QStorageInfo::mountedVolumes()) {

QString mountPoint = storage.rootPath();
Expand Down