Merge branch 'issue-1287' into calamares
Major update to the 'tracking' module with improved wording, functionality, QML-preparation, and a working kuserfeedback mode. FIXES #1287
This commit is contained in:
commit
0305476f8a
@ -26,6 +26,7 @@ ReflowComments: "false"
|
||||
SortIncludes: "true"
|
||||
SpaceAfterCStyleCast: "false"
|
||||
SpacesBeforeTrailingComments: "2"
|
||||
# SpaceInEmptyBlock: "true"
|
||||
SpacesInAngles: "true"
|
||||
SpacesInParentheses: "true"
|
||||
SpacesInSquareBrackets: "true"
|
||||
|
3
CHANGES
3
CHANGES
@ -6,6 +6,7 @@ website will have to do for older versions.
|
||||
# 3.2.26 (unreleased) #
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Anke Boersma
|
||||
- Gaël PORTAY
|
||||
- Pablo Ovelleiro Corral
|
||||
- Philip Müller
|
||||
@ -26,6 +27,8 @@ This release contains contributions from (alphabetically by first name):
|
||||
UTC+11, but Calamares still showed it in a zone separate from UTC+11.
|
||||
- *packages* gained support for the Void Linux package manager,
|
||||
*xbps*. (thanks Pablo)
|
||||
- *tracking* now supports kuserfeedback configuration.
|
||||
|
||||
|
||||
# 3.2.25 (2020-06-06) #
|
||||
|
||||
|
@ -13,7 +13,7 @@ export LANG LC_ALL LC_NUMERIC
|
||||
|
||||
AS=$( which astyle )
|
||||
|
||||
CF_VERSIONS="clang-format-7 clang-format-8 clang-format70 clang-format80 clang-format"
|
||||
CF_VERSIONS="clang-format-7 clang-format-8 clang-format70 clang-format80 clang-format-9.0.1 clang-format"
|
||||
for _cf in $CF_VERSIONS
|
||||
do
|
||||
# Not an error if this particular clang-format isn't found
|
||||
@ -26,6 +26,8 @@ test -n "$CF" || { echo "! No clang-format ($CF_VERSIONS) found in PATH"; exit 1
|
||||
test -x "$AS" || { echo "! $AS is not executable."; exit 1 ; }
|
||||
test -x "$CF" || { echo "! $CF is not executable."; exit 1 ; }
|
||||
|
||||
expr `"$CF" --version | tr -dc '[^.0-9]' | cut -d . -f 1` '<' 10 > /dev/null || { echo "! $CF is version 10 or later, needs different .clang-format" ; exit 1 ; }
|
||||
|
||||
set -e
|
||||
|
||||
any_dirs=no
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2013-2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-FileCopyrightText: 2018 Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
@ -65,6 +65,20 @@ getString( const QVariantMap& map, const QString& key )
|
||||
return QString();
|
||||
}
|
||||
|
||||
QStringList
|
||||
getStringList( const QVariantMap& map, const QString& key )
|
||||
{
|
||||
if ( map.contains( key ) )
|
||||
{
|
||||
auto v = map.value( key );
|
||||
if ( v.type() == QVariant::StringList )
|
||||
{
|
||||
return v.toStringList();
|
||||
}
|
||||
}
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
qint64
|
||||
getInteger( const QVariantMap& map, const QString& key, qint64 d )
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2013-2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-FileCopyrightText: 2018 Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
@ -43,6 +43,11 @@ DLLEXPORT bool getBool( const QVariantMap& map, const QString& key, bool d );
|
||||
*/
|
||||
DLLEXPORT QString getString( const QVariantMap& map, const QString& key );
|
||||
|
||||
/**
|
||||
* Get a string list from a mapping; returns empty list if no value.
|
||||
*/
|
||||
DLLEXPORT QStringList getStringList( const QVariantMap& map, const QString& key );
|
||||
|
||||
/**
|
||||
* Get an integer value from a mapping; returns @p d if no value.
|
||||
*/
|
||||
|
@ -2,6 +2,7 @@ calamares_add_plugin( tracking
|
||||
TYPE viewmodule
|
||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||
SOURCES
|
||||
Config.cpp
|
||||
TrackingJobs.cpp
|
||||
TrackingPage.cpp
|
||||
TrackingViewStep.cpp
|
||||
|
256
src/modules/tracking/Config.cpp
Normal file
256
src/modules/tracking/Config.cpp
Normal file
@ -0,0 +1,256 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2020, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#include "TrackingType.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
#include <QUrl>
|
||||
|
||||
const NamedEnumTable< TrackingType >&
|
||||
trackingNames()
|
||||
{
|
||||
// *INDENT-OFF*
|
||||
// clang-format off
|
||||
static const NamedEnumTable< TrackingType > names {
|
||||
{ QStringLiteral( "none" ), TrackingType::NoTracking },
|
||||
{ QStringLiteral( "install" ), TrackingType::InstallTracking },
|
||||
{ QStringLiteral( "machine" ), TrackingType::MachineTracking },
|
||||
{ QStringLiteral( "user" ), TrackingType::UserTracking }
|
||||
};
|
||||
// clang-format on
|
||||
// *INDENT-ON*
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
TrackingStyleConfig::TrackingStyleConfig( QObject* parent )
|
||||
: QObject( parent )
|
||||
{
|
||||
}
|
||||
|
||||
TrackingStyleConfig::~TrackingStyleConfig() {}
|
||||
|
||||
void
|
||||
TrackingStyleConfig::setTracking( bool enabled )
|
||||
{
|
||||
setTracking( enabled ? EnabledByUser : DisabledByUser );
|
||||
}
|
||||
|
||||
void
|
||||
TrackingStyleConfig::setTracking( TrackingStyleConfig::TrackingState state )
|
||||
{
|
||||
if ( m_state != TrackingState::DisabledByConfig )
|
||||
{
|
||||
m_state = state;
|
||||
}
|
||||
emit trackingChanged();
|
||||
}
|
||||
|
||||
void
|
||||
TrackingStyleConfig::validate( QString& s, std::function< bool( const QString& ) >&& pred )
|
||||
{
|
||||
if ( !pred( s ) )
|
||||
{
|
||||
if ( m_state != DisabledByConfig )
|
||||
{
|
||||
cError() << "Configuration string" << s << "is not valid; disabling this tracking type.";
|
||||
m_state = DisabledByConfig;
|
||||
emit trackingChanged();
|
||||
}
|
||||
s = QString();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TrackingStyleConfig::validateUrl( QString& urlString )
|
||||
{
|
||||
if ( !QUrl( urlString ).isValid() )
|
||||
{
|
||||
if ( m_state != DisabledByConfig )
|
||||
{
|
||||
cError() << "URL" << urlString << "is not valid; disabling tracking type" << objectName();
|
||||
m_state = DisabledByConfig;
|
||||
emit trackingChanged();
|
||||
}
|
||||
urlString = QString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackingStyleConfig::setConfigurationMap( const QVariantMap& config )
|
||||
{
|
||||
m_state = CalamaresUtils::getBool( config, "enabled", false ) ? DisabledByUser : DisabledByConfig;
|
||||
m_policy = CalamaresUtils::getString( config, "policy" );
|
||||
validateUrl( m_policy );
|
||||
emit policyChanged( m_policy );
|
||||
emit trackingChanged();
|
||||
}
|
||||
|
||||
InstallTrackingConfig::InstallTrackingConfig( QObject* parent )
|
||||
: TrackingStyleConfig( parent )
|
||||
{
|
||||
setObjectName( "InstallTrackingConfig" );
|
||||
}
|
||||
|
||||
void
|
||||
InstallTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
TrackingStyleConfig::setConfigurationMap( configurationMap );
|
||||
|
||||
m_installTrackingUrl = CalamaresUtils::getString( configurationMap, "url" );
|
||||
validateUrl( m_installTrackingUrl );
|
||||
}
|
||||
|
||||
MachineTrackingConfig::MachineTrackingConfig( QObject* parent )
|
||||
: TrackingStyleConfig( parent )
|
||||
{
|
||||
setObjectName( "MachineTrackingConfig" );
|
||||
}
|
||||
|
||||
/** @brief Is @p s a valid machine-tracking style. */
|
||||
static bool
|
||||
isValidMachineTrackingStyle( const QString& s )
|
||||
{
|
||||
static QStringList knownStyles { "updatemanager" };
|
||||
return knownStyles.contains( s );
|
||||
}
|
||||
|
||||
void
|
||||
MachineTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
TrackingStyleConfig::setConfigurationMap( configurationMap );
|
||||
|
||||
m_machineTrackingStyle = CalamaresUtils::getString( configurationMap, "style" );
|
||||
validate( m_machineTrackingStyle, isValidMachineTrackingStyle );
|
||||
}
|
||||
|
||||
|
||||
UserTrackingConfig::UserTrackingConfig( QObject* parent )
|
||||
: TrackingStyleConfig( parent )
|
||||
{
|
||||
setObjectName( "UserTrackingConfig" );
|
||||
}
|
||||
|
||||
static bool
|
||||
isValidUserTrackingStyle( const QString& s )
|
||||
{
|
||||
static QStringList knownStyles { "kuserfeedback" };
|
||||
return knownStyles.contains( s );
|
||||
}
|
||||
|
||||
void
|
||||
UserTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
TrackingStyleConfig::setConfigurationMap( configurationMap );
|
||||
|
||||
m_userTrackingStyle = CalamaresUtils::getString( configurationMap, "style" );
|
||||
validate( m_userTrackingStyle, isValidUserTrackingStyle );
|
||||
|
||||
m_userTrackingAreas = CalamaresUtils::getStringList( configurationMap, "areas" );
|
||||
}
|
||||
|
||||
|
||||
Config::Config( QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_installTracking( new InstallTrackingConfig( this ) )
|
||||
, m_machineTracking( new MachineTrackingConfig( this ) )
|
||||
, m_userTracking( new UserTrackingConfig( this ) )
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
enableLevelsBelow( Config* config, TrackingType level )
|
||||
{
|
||||
switch ( level )
|
||||
{
|
||||
case TrackingType::UserTracking:
|
||||
config->userTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser );
|
||||
FALLTHRU;
|
||||
case TrackingType::MachineTracking:
|
||||
config->machineTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser );
|
||||
FALLTHRU;
|
||||
case TrackingType::InstallTracking:
|
||||
config->installTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser );
|
||||
break;
|
||||
case TrackingType::NoTracking:
|
||||
config->noTracking( true );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Config::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
m_generalPolicy = CalamaresUtils::getString( configurationMap, "policy" );
|
||||
|
||||
if ( !QUrl( m_generalPolicy ).isValid() )
|
||||
{
|
||||
m_generalPolicy = QString();
|
||||
}
|
||||
emit generalPolicyChanged( m_generalPolicy );
|
||||
|
||||
bool success = false;
|
||||
auto subconfig = CalamaresUtils::getSubMap( configurationMap, "install", success );
|
||||
if ( success )
|
||||
{
|
||||
m_installTracking->setConfigurationMap( subconfig );
|
||||
}
|
||||
|
||||
subconfig = CalamaresUtils::getSubMap( configurationMap, "machine", success );
|
||||
if ( success )
|
||||
{
|
||||
m_machineTracking->setConfigurationMap( subconfig );
|
||||
}
|
||||
|
||||
subconfig = CalamaresUtils::getSubMap( configurationMap, "user", success );
|
||||
if ( success )
|
||||
{
|
||||
m_userTracking->setConfigurationMap( subconfig );
|
||||
}
|
||||
|
||||
auto level = trackingNames().find( CalamaresUtils::getString( configurationMap, "default" ), success );
|
||||
if ( !success )
|
||||
{
|
||||
cWarning() << "Default tracking level unknown:" << CalamaresUtils::getString( configurationMap, "default" );
|
||||
level = TrackingType::NoTracking;
|
||||
}
|
||||
enableLevelsBelow( this, level );
|
||||
}
|
||||
|
||||
QString
|
||||
Config::generalPolicy() const
|
||||
{
|
||||
return m_generalPolicy;
|
||||
}
|
||||
|
||||
void
|
||||
Config::noTracking( bool switchOffAllTracking )
|
||||
{
|
||||
if ( !switchOffAllTracking )
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_installTracking->setTracking( TrackingStyleConfig::TrackingState::DisabledByUser );
|
||||
m_machineTracking->setTracking( TrackingStyleConfig::TrackingState::DisabledByUser );
|
||||
m_userTracking->setTracking( TrackingStyleConfig::TrackingState::DisabledByUser );
|
||||
}
|
192
src/modules/tracking/Config.h
Normal file
192
src/modules/tracking/Config.h
Normal file
@ -0,0 +1,192 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2020, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TRACKING_CONFIG_H
|
||||
#define TRACKING_CONFIG_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QVariantMap>
|
||||
|
||||
/** @brief Base class for configuring a specific kind of tracking.
|
||||
*
|
||||
* All tracking types have a policy URL, which is used to explain what
|
||||
* kind of tracking is involved, what data is sent, etc. The content
|
||||
* of that URL is the responsibility of the distro.
|
||||
*
|
||||
* A tracking type is disabled by default: if it isn't specifically
|
||||
* enabled (for configuration) in the config file, it will always be disabled.
|
||||
* If it is enabled (for configuration) in the config file, it still
|
||||
* defaults to disabled, but the user can choose to enable it.
|
||||
*/
|
||||
class TrackingStyleConfig : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY( TrackingState trackingStatus READ tracking WRITE setTracking NOTIFY trackingChanged FINAL )
|
||||
Q_PROPERTY( bool isEnabled READ isEnabled NOTIFY trackingChanged FINAL )
|
||||
Q_PROPERTY( bool isConfigurable READ isConfigurable NOTIFY trackingChanged FINAL )
|
||||
Q_PROPERTY( QString policy READ policy NOTIFY policyChanged FINAL )
|
||||
|
||||
public:
|
||||
TrackingStyleConfig( QObject* parent );
|
||||
virtual ~TrackingStyleConfig();
|
||||
|
||||
void setConfigurationMap( const QVariantMap& );
|
||||
|
||||
enum TrackingState
|
||||
{
|
||||
DisabledByConfig,
|
||||
DisabledByUser,
|
||||
EnabledByUser
|
||||
};
|
||||
Q_ENUM( TrackingState );
|
||||
|
||||
public Q_SLOTS:
|
||||
TrackingState tracking() const { return m_state; }
|
||||
/// @brief Has the user specifically enabled this kind of tracking?
|
||||
bool isEnabled() const { return m_state == EnabledByUser; }
|
||||
/// @brief Is this tracking enabled for configuration?
|
||||
bool isConfigurable() const { return m_state != DisabledByConfig; }
|
||||
/** @brief Sets the tracking state
|
||||
*
|
||||
* Unless the tracking is enabled for configuration, it always
|
||||
* remains disabled.
|
||||
*/
|
||||
void setTracking( TrackingState );
|
||||
/** @brief Sets the tracking state
|
||||
*
|
||||
* Use @c true for @c EnabledByUser, @c false for DisabledByUser,
|
||||
* but keep in mind that if the tracking is not enabled for
|
||||
* configuration, it will always remain disabled.
|
||||
*/
|
||||
void setTracking( bool );
|
||||
|
||||
/// @brief URL for the policy explaining this tracking
|
||||
QString policy() const { return m_policy; }
|
||||
|
||||
signals:
|
||||
void trackingChanged();
|
||||
void policyChanged( QString );
|
||||
|
||||
protected:
|
||||
/// @brief Validates the @p urlString, disables tracking if invalid
|
||||
void validateUrl( QString& urlString );
|
||||
/// @brief Validates the @p string, disables tracking if invalid
|
||||
void validate( QString& s, std::function< bool( const QString& s ) >&& pred );
|
||||
|
||||
private:
|
||||
TrackingState m_state = DisabledByConfig;
|
||||
QString m_policy; // URL
|
||||
};
|
||||
|
||||
/** @brief Install tracking pings a URL at the end of installation
|
||||
*
|
||||
* Install tracking will do a single GET on the given URL at
|
||||
* the end of installation. The information included in the GET
|
||||
* request depends on the URL configuration, see also the tracking
|
||||
* jobs.
|
||||
*/
|
||||
class InstallTrackingConfig : public TrackingStyleConfig
|
||||
{
|
||||
public:
|
||||
InstallTrackingConfig( QObject* parent );
|
||||
void setConfigurationMap( const QVariantMap& configurationMap );
|
||||
|
||||
QString installTrackingUrl() { return m_installTrackingUrl; }
|
||||
|
||||
private:
|
||||
QString m_installTrackingUrl;
|
||||
};
|
||||
|
||||
/** @brief Machine tracking reports from the installed system
|
||||
*
|
||||
* When machine tracking is on, the installed system will report
|
||||
* back ("call home") at some point. This can mean Debian pop-con,
|
||||
* or updatemanager maching tracking, or something else. The kind
|
||||
* of configuration depends on the style of tracking that is enabled.
|
||||
*/
|
||||
class MachineTrackingConfig : public TrackingStyleConfig
|
||||
{
|
||||
public:
|
||||
MachineTrackingConfig( QObject* parent );
|
||||
void setConfigurationMap( const QVariantMap& configurationMap );
|
||||
|
||||
QString machineTrackingStyle() { return m_machineTrackingStyle; }
|
||||
|
||||
private:
|
||||
QString m_machineTrackingStyle;
|
||||
};
|
||||
|
||||
/** @brief User tracking reports user actions
|
||||
*
|
||||
* When user tracking is on, it is enabled for the user configured
|
||||
* in Calamares -- not for users created afterwards in the target
|
||||
* system, unless the target system defaults to tracking them.
|
||||
* The kind of user tracking depends on the target system and
|
||||
* environment; KDE user tracking is one example, which can be
|
||||
* configured in a fine-grained way and defaults to off.
|
||||
*/
|
||||
class UserTrackingConfig : public TrackingStyleConfig
|
||||
{
|
||||
public:
|
||||
UserTrackingConfig( QObject* parent );
|
||||
void setConfigurationMap( const QVariantMap& configurationMap );
|
||||
|
||||
QString userTrackingStyle() { return m_userTrackingStyle; }
|
||||
QStringList userTrackingAreas() const { return m_userTrackingAreas; }
|
||||
|
||||
private:
|
||||
QString m_userTrackingStyle;
|
||||
QStringList m_userTrackingAreas; // fine-grained areas
|
||||
};
|
||||
|
||||
class Config : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY( QString generalPolicy READ generalPolicy NOTIFY generalPolicyChanged FINAL )
|
||||
Q_PROPERTY( TrackingStyleConfig* installTracking READ installTracking FINAL )
|
||||
Q_PROPERTY( TrackingStyleConfig* machineTracking READ machineTracking FINAL )
|
||||
Q_PROPERTY( TrackingStyleConfig* userTracking READ userTracking FINAL )
|
||||
|
||||
public:
|
||||
Config( QObject* parent = nullptr );
|
||||
void setConfigurationMap( const QVariantMap& );
|
||||
|
||||
public Q_SLOTS:
|
||||
QString generalPolicy() const;
|
||||
|
||||
InstallTrackingConfig* installTracking() const { return m_installTracking; }
|
||||
MachineTrackingConfig* machineTracking() const { return m_machineTracking; }
|
||||
UserTrackingConfig* userTracking() const { return m_userTracking; }
|
||||
|
||||
/// @brief Call with @c true to turn off all the trackings
|
||||
void noTracking( bool );
|
||||
|
||||
signals:
|
||||
void generalPolicyChanged( QString );
|
||||
|
||||
private:
|
||||
QString m_generalPolicy;
|
||||
|
||||
InstallTrackingConfig* m_installTracking;
|
||||
MachineTrackingConfig* m_machineTracking;
|
||||
UserTrackingConfig* m_userTracking;
|
||||
};
|
||||
|
||||
#endif
|
@ -18,10 +18,16 @@
|
||||
|
||||
#include "TrackingJobs.h"
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include "network/Manager.h"
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <KMacroExpander>
|
||||
|
||||
#include <QSemaphore>
|
||||
#include <QTimer>
|
||||
|
||||
@ -32,7 +38,7 @@ TrackingInstallJob::TrackingInstallJob( const QString& url )
|
||||
{
|
||||
}
|
||||
|
||||
TrackingInstallJob::~TrackingInstallJob() { }
|
||||
TrackingInstallJob::~TrackingInstallJob() {}
|
||||
|
||||
QString
|
||||
TrackingInstallJob::prettyName() const
|
||||
@ -72,38 +78,72 @@ TrackingInstallJob::exec()
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
void
|
||||
TrackingInstallJob::addJob( Calamares::JobList& list, InstallTrackingConfig* config )
|
||||
{
|
||||
if ( config->isEnabled() )
|
||||
{
|
||||
const auto* s = CalamaresUtils::System::instance();
|
||||
QHash< QString, QString > map { std::initializer_list< std::pair< QString, QString > > {
|
||||
{ QStringLiteral( "CPU" ), s->getCpuDescription() },
|
||||
{ QStringLiteral( "MEMORY" ), QString::number( s->getTotalMemoryB().first ) },
|
||||
{ QStringLiteral( "DISK" ), QString::number( s->getTotalDiskB() ) } } };
|
||||
QString installUrl = KMacroExpander::expandMacros( config->installTrackingUrl(), map );
|
||||
|
||||
cDebug() << Logger::SubEntry << "install-tracking URL" << installUrl;
|
||||
|
||||
list.append( Calamares::job_ptr( new TrackingInstallJob( installUrl ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TrackingMachineJob::addJob( Calamares::JobList& list, MachineTrackingConfig* config )
|
||||
{
|
||||
if ( config->isEnabled() )
|
||||
{
|
||||
const auto style = config->machineTrackingStyle();
|
||||
if ( style == "updatemanager" )
|
||||
{
|
||||
list.append( Calamares::job_ptr( new TrackingMachineUpdateManagerJob() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "Unsupported machine tracking style" << style;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
TrackingMachineNeonJob::prettyName() const
|
||||
TrackingMachineUpdateManagerJob::prettyName() const
|
||||
{
|
||||
return tr( "Machine feedback" );
|
||||
}
|
||||
|
||||
QString
|
||||
TrackingMachineNeonJob::prettyDescription() const
|
||||
TrackingMachineUpdateManagerJob::prettyDescription() const
|
||||
{
|
||||
return prettyName();
|
||||
}
|
||||
|
||||
QString
|
||||
TrackingMachineNeonJob::prettyStatusMessage() const
|
||||
TrackingMachineUpdateManagerJob::prettyStatusMessage() const
|
||||
{
|
||||
return tr( "Configuring machine feedback." );
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
TrackingMachineNeonJob::exec()
|
||||
TrackingMachineUpdateManagerJob::exec()
|
||||
{
|
||||
static const auto script = QStringLiteral(
|
||||
R"x(
|
||||
MACHINE_ID=`cat /etc/machine-id`
|
||||
sed -i "s,URI =.*,URI = http://releases.neon.kde.org/meta-release/${MACHINE_ID}," /etc/update-manager/meta-release
|
||||
sed -i "s,URI_LTS =.*,URI_LTS = http://releases.neon.kde.org/meta-release-lts/${MACHINE_ID}," /etc/update-manager/meta-release
|
||||
true
|
||||
)x" );
|
||||
int r = CalamaresUtils::System::instance()->targetEnvCall( "/bin/sh",
|
||||
"sed -i '/^URI/s,${MACHINE_ID},'`cat /etc/machine-id`',' /etc/update-manager/meta-release || true" );
|
||||
|
||||
auto res = CalamaresUtils::System::instance()->runCommand( CalamaresUtils::System::RunLocation::RunInTarget,
|
||||
QStringList { QStringLiteral( "/bin/sh" ) },
|
||||
QString(), // Working dir
|
||||
script,
|
||||
script, // standard input
|
||||
std::chrono::seconds( 1 ) );
|
||||
int r = res.first;
|
||||
|
||||
if ( r == 0 )
|
||||
{
|
||||
@ -122,3 +162,87 @@ true
|
||||
tr( "Could not configure machine feedback correctly, Calamares error %1." ).arg( r ) );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TrackingUserJob::addJob( Calamares::JobList& list, UserTrackingConfig* config )
|
||||
{
|
||||
if ( config->isEnabled() )
|
||||
{
|
||||
const auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
static const auto key = QStringLiteral( "username" );
|
||||
QString username = ( gs && gs->contains( key ) ) ? gs->value( key ).toString() : QString();
|
||||
|
||||
if ( username.isEmpty() )
|
||||
{
|
||||
cWarning() << "No username is set in GlobalStorage, skipping user-tracking.";
|
||||
return;
|
||||
}
|
||||
|
||||
const auto style = config->userTrackingStyle();
|
||||
if ( style == "kuserfeedback" )
|
||||
{
|
||||
list.append( Calamares::job_ptr( new TrackingKUserFeedbackJob( username, config->userTrackingAreas() ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "Unsupported user tracking style" << style;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TrackingKUserFeedbackJob::TrackingKUserFeedbackJob( const QString& username, const QStringList& areas )
|
||||
: m_username( username )
|
||||
, m_areas( areas )
|
||||
{
|
||||
}
|
||||
|
||||
QString
|
||||
TrackingKUserFeedbackJob::prettyName() const
|
||||
{
|
||||
return tr( "KDE user feedback" );
|
||||
}
|
||||
|
||||
QString
|
||||
TrackingKUserFeedbackJob::prettyDescription() const
|
||||
{
|
||||
return prettyName();
|
||||
}
|
||||
|
||||
QString
|
||||
TrackingKUserFeedbackJob::prettyStatusMessage() const
|
||||
{
|
||||
return tr( "Configuring KDE user feedback." );
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
TrackingKUserFeedbackJob::exec()
|
||||
{
|
||||
// This is the contents of a config file to turn on some kind
|
||||
// of KUserFeedback tracking; the level (16) is chosen for minimal
|
||||
// but not zero tracking.
|
||||
static const char config[] = R"x([Global]
|
||||
FeedbackLevel=16
|
||||
)x";
|
||||
|
||||
for ( const QString& area : m_areas )
|
||||
{
|
||||
QString path = QStringLiteral( "/home/%1/.config/%2" ).arg( m_username, area );
|
||||
cDebug() << "Configuring KUserFeedback" << path;
|
||||
|
||||
int r = CalamaresUtils::System::instance()->createTargetFile( path, config );
|
||||
if ( r > 0 )
|
||||
{
|
||||
return Calamares::JobResult::error(
|
||||
tr( "Error in KDE user feedback configuration." ),
|
||||
tr( "Could not configure KDE user feedback correctly, script error %1." ).arg( r ) );
|
||||
}
|
||||
else if ( r < 0 )
|
||||
{
|
||||
return Calamares::JobResult::error(
|
||||
tr( "Error in KDE user feedback configuration." ),
|
||||
tr( "Could not configure KDE user feedback correctly, Calamares error %1." ).arg( r ) );
|
||||
}
|
||||
}
|
||||
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
@ -16,13 +16,36 @@
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TRACKINGJOBS
|
||||
#define TRACKINGJOBS
|
||||
#ifndef TRACKING_TRACKINGJOBS_H
|
||||
#define TRACKING_TRACKINGJOBS_H
|
||||
|
||||
#include "Job.h"
|
||||
|
||||
class InstallTrackingConfig;
|
||||
class MachineTrackingConfig;
|
||||
class UserTrackingConfig;
|
||||
|
||||
class QSemaphore;
|
||||
|
||||
/** @section Tracking Jobs
|
||||
*
|
||||
* The tracking jobs do the actual work of configuring tracking on the
|
||||
* target machine. Tracking jobs may have *styles*, variations depending
|
||||
* on the distro or environment of the target system. At the root of
|
||||
* each family of tracking jobs (installation, machine, user) there is
|
||||
* a class with static method `addJob()` that takes the configuration
|
||||
* information from the relevant Config sub-object and optionally
|
||||
* adds the right job (subclass!) to the list of jobs.
|
||||
*/
|
||||
|
||||
/** @brief Install-tracking job (gets a URL)
|
||||
*
|
||||
* The install-tracking job (there is only one kind) does a GET
|
||||
* on a configured URL with some additional information about
|
||||
* the machine (if configured into the URL).
|
||||
*
|
||||
* No persistent tracking is done.
|
||||
*/
|
||||
class TrackingInstallJob : public Calamares::Job
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -35,11 +58,31 @@ public:
|
||||
QString prettyStatusMessage() const override;
|
||||
Calamares::JobResult exec() override;
|
||||
|
||||
static void addJob( Calamares::JobList& list, InstallTrackingConfig* config );
|
||||
|
||||
private:
|
||||
const QString m_url;
|
||||
};
|
||||
|
||||
class TrackingMachineNeonJob : public Calamares::Job
|
||||
/** @brief Base class for machine-tracking jobs
|
||||
*
|
||||
* Machine-tracking configuraiton depends on the distro / style of machine
|
||||
* being tracked, so it has subclasses to switch on the relevant kind
|
||||
* of tracking. A machine is tracked persistently.
|
||||
*/
|
||||
class TrackingMachineJob : public Calamares::Job
|
||||
{
|
||||
public:
|
||||
static void addJob( Calamares::JobList& list, MachineTrackingConfig* config );
|
||||
};
|
||||
|
||||
/** @brief Tracking machines, update-manager style
|
||||
*
|
||||
* The machine has a machine-id, and this is sed(1)'ed into the
|
||||
* update-manager configuration, to report the machine-id back
|
||||
* to distro servers.
|
||||
*/
|
||||
class TrackingMachineUpdateManagerJob : public TrackingMachineJob
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -49,5 +92,38 @@ public:
|
||||
Calamares::JobResult exec() override;
|
||||
};
|
||||
|
||||
/** @brief Base class for user-tracking jobs
|
||||
*
|
||||
* User-tracking configuration depends on the distro / style of user
|
||||
* tracking being implemented, so there are subclasses to switch on the
|
||||
* relevant kind of tracking. Users are tracked persistently (the user
|
||||
* can of course configure the tracking again once the system is restarted).
|
||||
*/
|
||||
class TrackingUserJob : public Calamares::Job
|
||||
{
|
||||
public:
|
||||
static void addJob( Calamares::JobList& list, UserTrackingConfig* config );
|
||||
};
|
||||
|
||||
/** @brief Turn on KUserFeedback in target system
|
||||
*
|
||||
* This writes suitable files for turning on KUserFeedback for the
|
||||
* normal user configured in Calamares. The feedback can be reconfigured
|
||||
* by the user through Plasma's user-feedback dialog.
|
||||
*/
|
||||
class TrackingKUserFeedbackJob : public Calamares::Job
|
||||
{
|
||||
public:
|
||||
TrackingKUserFeedbackJob( const QString& username, const QStringList& areas );
|
||||
|
||||
QString prettyName() const override;
|
||||
QString prettyDescription() const override;
|
||||
QString prettyStatusMessage() const override;
|
||||
Calamares::JobResult exec() override;
|
||||
|
||||
private:
|
||||
QString m_username;
|
||||
QStringList m_areas;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "TrackingPage.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include "ui_page_trackingstep.h"
|
||||
|
||||
#include "Branding.h"
|
||||
@ -28,178 +29,128 @@
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Retranslator.h"
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QDesktopServices>
|
||||
#include <QLabel>
|
||||
|
||||
TrackingPage::TrackingPage( QWidget* parent )
|
||||
TrackingPage::TrackingPage( Config* config, QWidget* parent )
|
||||
: QWidget( parent )
|
||||
, ui( new Ui::TrackingPage )
|
||||
{
|
||||
ui->setupUi( this );
|
||||
CALAMARES_RETRANSLATE(
|
||||
QString product = Calamares::Branding::instance()->shortProductName(); ui->retranslateUi( this );
|
||||
ui->generalExplanation->setText(
|
||||
tr( "Install tracking helps %1 to see how many users they have, what hardware they install %1 to and (with "
|
||||
"the last two options below), get continuous information about preferred applications. To see what "
|
||||
"will be sent, please click the help icon next to each area." )
|
||||
.arg( product ) );
|
||||
ui->installExplanation->setText(
|
||||
tr( "By selecting this you will send information about your installation and hardware. This information "
|
||||
"will <b>only be sent once</b> after the installation finishes." ) );
|
||||
ui->machineExplanation->setText( tr( "By selecting this you will <b>periodically</b> send information about "
|
||||
"your installation, hardware and applications, to %1." )
|
||||
.arg( product ) );
|
||||
ui->userExplanation->setText( tr( "By selecting this you will <b>regularly</b> send information about your "
|
||||
"installation, hardware, applications and usage patterns, to %1." )
|
||||
.arg( product ) ); )
|
||||
CALAMARES_RETRANSLATE_SLOT( &TrackingPage::retranslate );
|
||||
|
||||
QButtonGroup* group = new QButtonGroup( this );
|
||||
group->setExclusive( true );
|
||||
group->addButton( ui->noneRadio );
|
||||
group->addButton( ui->installRadio );
|
||||
group->addButton( ui->machineRadio );
|
||||
group->addButton( ui->userRadio );
|
||||
ui->noneRadio->setChecked( true );
|
||||
ui->noneCheckBox->setChecked( true );
|
||||
ui->noneCheckBox->setEnabled( false );
|
||||
connect( ui->noneCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonNoneChecked );
|
||||
|
||||
// Each "panel" of configuration has the same kind of setup,
|
||||
// where the xButton and xCheckBox is connected to the xTracking
|
||||
// configuration object; that takes macro-trickery, unfortunately.
|
||||
#define trackingSetup( x ) \
|
||||
do \
|
||||
{ \
|
||||
connect( ui->x##CheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonChecked ); \
|
||||
connect( ui->x##CheckBox, \
|
||||
&QCheckBox::stateChanged, \
|
||||
config->x##Tracking(), \
|
||||
QOverload< bool >::of( &TrackingStyleConfig::setTracking ) ); \
|
||||
connect( config->x##Tracking(), &TrackingStyleConfig::trackingChanged, this, [this, config]() { \
|
||||
this->trackerChanged( config->x##Tracking(), this->ui->x##Group, this->ui->x##CheckBox ); \
|
||||
} ); \
|
||||
connect( ui->x##PolicyButton, &QAbstractButton::clicked, config, [config] { \
|
||||
QString url( config->x##Tracking()->policy() ); \
|
||||
if ( !url.isEmpty() ) \
|
||||
{ \
|
||||
QDesktopServices::openUrl( url ); \
|
||||
} \
|
||||
} ); \
|
||||
} while ( false )
|
||||
|
||||
trackingSetup( install );
|
||||
trackingSetup( machine );
|
||||
trackingSetup( user );
|
||||
|
||||
#undef trackingSetup
|
||||
|
||||
connect( config, &Config::generalPolicyChanged, [this]( const QString& url ) {
|
||||
this->ui->generalPolicyLabel->setVisible( !url.isEmpty() );
|
||||
} );
|
||||
connect( ui->generalPolicyLabel, &QLabel::linkActivated, [config] {
|
||||
QString url( config->generalPolicy() );
|
||||
if ( !url.isEmpty() )
|
||||
{
|
||||
QDesktopServices::openUrl( url );
|
||||
}
|
||||
} );
|
||||
|
||||
retranslate();
|
||||
}
|
||||
|
||||
void
|
||||
TrackingPage::enableTrackingOption( TrackingType t, bool enabled )
|
||||
TrackingPage::retranslate()
|
||||
{
|
||||
QWidget* group = nullptr;
|
||||
|
||||
switch ( t )
|
||||
{
|
||||
case TrackingType::InstallTracking:
|
||||
group = ui->installGroup;
|
||||
break;
|
||||
case TrackingType::MachineTracking:
|
||||
group = ui->machineGroup;
|
||||
break;
|
||||
case TrackingType::UserTracking:
|
||||
group = ui->userGroup;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( group != nullptr )
|
||||
{
|
||||
if ( enabled )
|
||||
{
|
||||
group->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
group->hide();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "unknown tracking option" << int( t );
|
||||
}
|
||||
QString product = Calamares::Branding::instance()->shortProductName();
|
||||
ui->retranslateUi( this );
|
||||
ui->generalExplanation->setText(
|
||||
tr( "Tracking helps %1 to see how often it is installed, what hardware it is installed on and "
|
||||
"which applications are used. To see what "
|
||||
"will be sent, please click the help icon next to each area." )
|
||||
.arg( product ) );
|
||||
ui->installExplanation->setText(
|
||||
tr( "By selecting this you will send information about your installation and hardware. This information "
|
||||
"will only be sent <b>once</b> after the installation finishes." ) );
|
||||
ui->machineExplanation->setText(
|
||||
tr( "By selecting this you will periodically send information about your <b>machine</b> installation, "
|
||||
"hardware and applications, to %1." )
|
||||
.arg( product ) );
|
||||
ui->userExplanation->setText(
|
||||
tr( "By selecting this you will regularly send information about your "
|
||||
"<b>user</b> installation, hardware, applications and application usage patterns, to %1." )
|
||||
.arg( product ) );
|
||||
}
|
||||
|
||||
bool
|
||||
TrackingPage::getTrackingOption( TrackingType t )
|
||||
TrackingPage::anyOtherChecked() const
|
||||
{
|
||||
bool enabled = false;
|
||||
return ui->installCheckBox->isChecked() || ui->machineCheckBox->isChecked() || ui->userCheckBox->isChecked();
|
||||
}
|
||||
|
||||
// A tracking type is enabled if it is checked, or
|
||||
// any higher level is checked.
|
||||
#define ch( x ) ui->x->isChecked()
|
||||
switch ( t )
|
||||
|
||||
void
|
||||
TrackingPage::buttonNoneChecked( int state )
|
||||
{
|
||||
if ( state )
|
||||
{
|
||||
case TrackingType::InstallTracking:
|
||||
enabled = ch( installRadio ) || ch( machineRadio ) || ch( userRadio );
|
||||
break;
|
||||
case TrackingType::MachineTracking:
|
||||
enabled = ch( machineRadio ) || ch( userRadio );
|
||||
break;
|
||||
case TrackingType::UserTracking:
|
||||
enabled = ch( userRadio );
|
||||
break;
|
||||
cDebug() << "Unchecking all other buttons because 'None' was checked";
|
||||
ui->installCheckBox->setChecked( false );
|
||||
ui->machineCheckBox->setChecked( false );
|
||||
ui->userCheckBox->setChecked( false );
|
||||
ui->noneCheckBox->setEnabled( false );
|
||||
}
|
||||
#undef ch
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void
|
||||
TrackingPage::setTrackingPolicy( TrackingType t, QString url )
|
||||
TrackingPage::buttonChecked( int state )
|
||||
{
|
||||
QToolButton* button = nullptr;
|
||||
switch ( t )
|
||||
if ( state )
|
||||
{
|
||||
case TrackingType::InstallTracking:
|
||||
button = ui->installPolicyButton;
|
||||
break;
|
||||
case TrackingType::MachineTracking:
|
||||
button = ui->machinePolicyButton;
|
||||
break;
|
||||
case TrackingType::UserTracking:
|
||||
button = ui->userPolicyButton;
|
||||
break;
|
||||
// Can't have none checked, if another one is
|
||||
ui->noneCheckBox->setEnabled( true );
|
||||
ui->noneCheckBox->setChecked( false );
|
||||
}
|
||||
|
||||
if ( button != nullptr )
|
||||
if ( url.isEmpty() )
|
||||
else
|
||||
{
|
||||
if ( !anyOtherChecked() )
|
||||
{
|
||||
button->hide();
|
||||
ui->noneCheckBox->setChecked( true );
|
||||
ui->noneCheckBox->setEnabled( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
connect( button, &QToolButton::clicked, [ url ] { QDesktopServices::openUrl( url ); } );
|
||||
cDebug() << "Tracking policy" << int( t ) << "set to" << url;
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "unknown tracking option" << int( t );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TrackingPage::setGeneralPolicy( QString url )
|
||||
TrackingPage::trackerChanged( TrackingStyleConfig* config, QWidget* panel, QCheckBox* check )
|
||||
{
|
||||
if ( url.isEmpty() )
|
||||
{
|
||||
ui->generalPolicyLabel->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->generalPolicyLabel->show();
|
||||
ui->generalPolicyLabel->setTextInteractionFlags( Qt::TextBrowserInteraction );
|
||||
ui->generalPolicyLabel->show();
|
||||
connect( ui->generalPolicyLabel, &QLabel::linkActivated, [ url ] { QDesktopServices::openUrl( url ); } );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TrackingPage::setTrackingLevel( const QString& l )
|
||||
{
|
||||
QString level = l.toLower();
|
||||
QRadioButton* button = nullptr;
|
||||
|
||||
if ( level.isEmpty() || level == "none" )
|
||||
{
|
||||
button = ui->noneRadio;
|
||||
}
|
||||
else if ( level == "install" )
|
||||
{
|
||||
button = ui->installRadio;
|
||||
}
|
||||
else if ( level == "machine" )
|
||||
{
|
||||
button = ui->machineRadio;
|
||||
}
|
||||
else if ( level == "user" )
|
||||
{
|
||||
button = ui->userRadio;
|
||||
}
|
||||
|
||||
if ( button != nullptr )
|
||||
{
|
||||
button->setChecked( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "unknown default tracking level" << l;
|
||||
}
|
||||
panel->setVisible( config->isConfigurable() );
|
||||
check->setChecked( config->isEnabled() );
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "TrackingType.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QUrl>
|
||||
#include <QWidget>
|
||||
|
||||
@ -29,35 +30,48 @@ namespace Ui
|
||||
class TrackingPage;
|
||||
}
|
||||
|
||||
class Config;
|
||||
class TrackingStyleConfig;
|
||||
|
||||
class TrackingPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TrackingPage( QWidget* parent = nullptr );
|
||||
explicit TrackingPage( Config* config, QWidget* parent = nullptr );
|
||||
|
||||
/**
|
||||
* Enables or disables the tracking-option block for the given
|
||||
* tracking option @p t, and sets the initial state of the
|
||||
* checkbox to the @p user default.
|
||||
/** @brief is any of the enable-tracking buttons checked?
|
||||
*
|
||||
* Call this in ascending order of tracking type.
|
||||
* Returns true if any one or more of install, machine or user
|
||||
* tracking is enabled.
|
||||
*/
|
||||
void enableTrackingOption( TrackingType t, bool enabled );
|
||||
/**
|
||||
* Returns whether tracking type @p is selected by the user
|
||||
* (i.e. is the radio button for that level, or for a higher
|
||||
* tracking level, enabled).
|
||||
*/
|
||||
bool getTrackingOption( TrackingType t );
|
||||
bool anyOtherChecked() const;
|
||||
|
||||
/* URL for given level @p t */
|
||||
void setTrackingPolicy( TrackingType t, QString url );
|
||||
/* URL for the global link */
|
||||
void setGeneralPolicy( QString url );
|
||||
/* Select one of the four levels by name */
|
||||
void setTrackingLevel( const QString& level );
|
||||
public Q_SLOTS:
|
||||
void retranslate();
|
||||
|
||||
/** @brief When the *no tracking* checkbox is changed
|
||||
*
|
||||
* @p state will be non-zero when the box is checked; this
|
||||
* **unchecks** all the other boxes.
|
||||
*/
|
||||
void buttonNoneChecked( int state );
|
||||
|
||||
/** @brief Some other checkbox changed
|
||||
*
|
||||
* This may check the *none* button if all the others are
|
||||
* now unchecked.
|
||||
*/
|
||||
void buttonChecked( int state );
|
||||
|
||||
private:
|
||||
/** @brief Apply the tracking configuration to the UI
|
||||
*
|
||||
* If the config cannot be changed (disabled in config) then
|
||||
* hide the UI parts on the @p panel; otherwise show it
|
||||
* and set @p check state to whether the user has enabled it.
|
||||
*/
|
||||
void trackerChanged( TrackingStyleConfig* subconfig, QWidget* panel, QCheckBox* check );
|
||||
|
||||
Ui::TrackingPage* ui;
|
||||
};
|
||||
|
||||
|
@ -19,11 +19,17 @@
|
||||
#ifndef TRACKINGTYPE_H
|
||||
#define TRACKINGTYPE_H
|
||||
|
||||
#include "utils/NamedEnum.h"
|
||||
|
||||
enum class TrackingType
|
||||
{
|
||||
InstallTracking,
|
||||
MachineTracking,
|
||||
UserTracking
|
||||
NoTracking, // Do not enable tracking at all
|
||||
InstallTracking, // Track that *this* install has happened
|
||||
MachineTracking, // Track the machine, ongoing
|
||||
UserTracking // Track the user, ongoing
|
||||
};
|
||||
|
||||
// Implemented in Config.cpp
|
||||
const NamedEnumTable< TrackingType >& trackingNames();
|
||||
|
||||
#endif //TRACKINGTYPE_H
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "TrackingViewStep.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include "TrackingJobs.h"
|
||||
#include "TrackingPage.h"
|
||||
|
||||
@ -33,17 +34,10 @@
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( TrackingViewStepFactory, registerPlugin< TrackingViewStep >(); )
|
||||
|
||||
/** @brief Is @p s a valid machine-tracking style. */
|
||||
static bool
|
||||
isValidStyle( const QString& s )
|
||||
{
|
||||
static QStringList knownStyles { "neon" };
|
||||
return knownStyles.contains( s );
|
||||
}
|
||||
|
||||
TrackingViewStep::TrackingViewStep( QObject* parent )
|
||||
: Calamares::ViewStep( parent )
|
||||
, m_widget( new TrackingPage )
|
||||
, m_config( new Config( this ) )
|
||||
, m_widget( new TrackingPage( m_config ) )
|
||||
{
|
||||
emit nextStatusChanged( false );
|
||||
}
|
||||
@ -103,89 +97,28 @@ TrackingViewStep::isAtEnd() const
|
||||
void
|
||||
TrackingViewStep::onLeave()
|
||||
{
|
||||
m_installTracking.userEnabled = m_widget->getTrackingOption( TrackingType::InstallTracking );
|
||||
m_machineTracking.userEnabled = m_widget->getTrackingOption( TrackingType::MachineTracking );
|
||||
m_userTracking.userEnabled = m_widget->getTrackingOption( TrackingType::UserTracking );
|
||||
cDebug() << "Install tracking:" << m_installTracking.enabled();
|
||||
cDebug() << "Machine tracking:" << m_machineTracking.enabled();
|
||||
cDebug() << " User tracking:" << m_userTracking.enabled();
|
||||
cDebug() << "Install tracking:" << m_config->installTracking()->isEnabled();
|
||||
cDebug() << Logger::SubEntry << "Machine tracking:" << m_config->machineTracking()->isEnabled();
|
||||
cDebug() << Logger::SubEntry << " User tracking:" << m_config->userTracking()->isEnabled();
|
||||
}
|
||||
|
||||
|
||||
Calamares::JobList
|
||||
TrackingViewStep::jobs() const
|
||||
{
|
||||
Calamares::JobList l;
|
||||
|
||||
cDebug() << "Creating tracking jobs ..";
|
||||
if ( m_installTracking.enabled() && !m_installTrackingUrl.isEmpty() )
|
||||
{
|
||||
QString installUrl = m_installTrackingUrl;
|
||||
const auto s = CalamaresUtils::System::instance();
|
||||
|
||||
QString memory, disk;
|
||||
memory.setNum( s->getTotalMemoryB().first );
|
||||
disk.setNum( s->getTotalDiskB() );
|
||||
|
||||
installUrl.replace( "$CPU", s->getCpuDescription() ).replace( "$MEMORY", memory ).replace( "$DISK", disk );
|
||||
|
||||
cDebug() << Logger::SubEntry << "install-tracking URL" << installUrl;
|
||||
|
||||
l.append( Calamares::job_ptr( new TrackingInstallJob( installUrl ) ) );
|
||||
}
|
||||
|
||||
if ( m_machineTracking.enabled() && !m_machineTrackingStyle.isEmpty() )
|
||||
{
|
||||
Q_ASSERT( isValidStyle( m_machineTrackingStyle ) );
|
||||
if ( m_machineTrackingStyle == "neon" )
|
||||
{
|
||||
l.append( Calamares::job_ptr( new TrackingMachineNeonJob() ) );
|
||||
}
|
||||
}
|
||||
Calamares::JobList l;
|
||||
TrackingInstallJob::addJob( l, m_config->installTracking() );
|
||||
TrackingMachineJob::addJob( l, m_config->machineTracking() );
|
||||
TrackingUserJob::addJob( l, m_config->userTracking() );
|
||||
cDebug() << Logger::SubEntry << l.count() << "jobs queued.";
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
QVariantMap
|
||||
TrackingViewStep::setTrackingOption( const QVariantMap& configurationMap, const QString& key, TrackingType t )
|
||||
{
|
||||
bool settingEnabled = false;
|
||||
|
||||
bool success = false;
|
||||
auto config = CalamaresUtils::getSubMap( configurationMap, key, success );
|
||||
|
||||
if ( success )
|
||||
{
|
||||
settingEnabled = CalamaresUtils::getBool( config, "enabled", false );
|
||||
}
|
||||
|
||||
TrackingEnabled& trackingConfiguration = tracking( t );
|
||||
trackingConfiguration.settingEnabled = settingEnabled;
|
||||
trackingConfiguration.userEnabled = false;
|
||||
|
||||
m_widget->enableTrackingOption( t, settingEnabled );
|
||||
m_widget->setTrackingPolicy( t, CalamaresUtils::getString( config, "policy" ) );
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
void
|
||||
TrackingViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
QVariantMap config;
|
||||
|
||||
config = setTrackingOption( configurationMap, "install", TrackingType::InstallTracking );
|
||||
m_installTrackingUrl = CalamaresUtils::getString( config, "url" );
|
||||
|
||||
config = setTrackingOption( configurationMap, "machine", TrackingType::MachineTracking );
|
||||
auto s = CalamaresUtils::getString( config, "style" );
|
||||
if ( isValidStyle( s ) )
|
||||
{
|
||||
m_machineTrackingStyle = s;
|
||||
}
|
||||
|
||||
setTrackingOption( configurationMap, "user", TrackingType::UserTracking );
|
||||
|
||||
m_widget->setGeneralPolicy( CalamaresUtils::getString( configurationMap, "policy" ) );
|
||||
m_widget->setTrackingLevel( CalamaresUtils::getString( configurationMap, "default" ) );
|
||||
m_config->setConfigurationMap( configurationMap );
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <QUrl>
|
||||
#include <QVariantMap>
|
||||
|
||||
class Config;
|
||||
class TrackingPage;
|
||||
|
||||
class PLUGINDLLEXPORT TrackingViewStep : public Calamares::ViewStep
|
||||
@ -56,42 +57,8 @@ public:
|
||||
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||
|
||||
private:
|
||||
QVariantMap setTrackingOption( const QVariantMap& configurationMap, const QString& key, TrackingType t );
|
||||
|
||||
Config* m_config;
|
||||
TrackingPage* m_widget;
|
||||
QString m_installTrackingUrl;
|
||||
QString m_machineTrackingStyle;
|
||||
|
||||
struct TrackingEnabled
|
||||
{
|
||||
bool settingEnabled; // Enabled in config file
|
||||
bool userEnabled; // User checked "yes"
|
||||
|
||||
TrackingEnabled()
|
||||
: settingEnabled( false )
|
||||
, userEnabled( false )
|
||||
{
|
||||
}
|
||||
|
||||
bool enabled() const { return settingEnabled && userEnabled; }
|
||||
};
|
||||
TrackingEnabled m_installTracking, m_machineTracking, m_userTracking;
|
||||
|
||||
inline TrackingEnabled& tracking( TrackingType t )
|
||||
{
|
||||
if ( t == TrackingType::UserTracking )
|
||||
{
|
||||
return m_userTracking;
|
||||
}
|
||||
else if ( t == TrackingType::MachineTracking )
|
||||
{
|
||||
return m_machineTracking;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_installTracking;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( TrackingViewStepFactory )
|
||||
|
@ -32,7 +32,7 @@ margin-left: 2em;</string>
|
||||
<widget class="QWidget" name="noneGroup" native="true">
|
||||
<layout class="QHBoxLayout" name="noneLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="noneRadio">
|
||||
<widget class="QCheckBox" name="noneCheckBox">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
@ -69,7 +69,7 @@ margin-left: 2em;</string>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>By selecting this, you will send <span style=" font-weight:600;">no information at all</span> about your installation.</p></body></html></string>
|
||||
<string><html><head/><body><p>Click here to send <span style=" font-weight:600;">no information at all</span> about your installation.</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@ -83,7 +83,7 @@ margin-left: 2em;</string>
|
||||
<widget class="QWidget" name="installGroup" native="true">
|
||||
<layout class="QHBoxLayout" name="installLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="installRadio">
|
||||
<widget class="QCheckBox" name="installCheckBox">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
@ -145,7 +145,7 @@ margin-left: 2em;</string>
|
||||
<widget class="QWidget" name="machineGroup" native="true">
|
||||
<layout class="QHBoxLayout" name="machineLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="machineRadio">
|
||||
<widget class="QCheckBox" name="machineCheckBox">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
@ -207,7 +207,7 @@ margin-left: 2em;</string>
|
||||
<widget class="QWidget" name="userGroup" native="true">
|
||||
<layout class="QHBoxLayout" name="userLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="userRadio">
|
||||
<widget class="QCheckBox" name="userCheckBox">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
@ -279,6 +279,9 @@ margin-left: 2em;</string>
|
||||
<property name="openExternalLinks">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextBrowserInteraction</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -28,14 +28,16 @@
|
||||
# policy applies.
|
||||
#
|
||||
# Each area has a key *enabled*. If the area is enabled, it is shown to
|
||||
# the user. This defaults to off, which means no tracking would be
|
||||
# the user. This defaults to false, which means no tracking would be
|
||||
# configured or enabled by Calamares.
|
||||
#
|
||||
# Each area has a key *policy*, which is a Url to be opened when
|
||||
# the user clicks on the corresponding Help button for an explanation
|
||||
# of the details of that particular kind of tracking. If no policy
|
||||
# is set, the help button is hidden. The example policy links
|
||||
# go to Calamares' generic user manual.
|
||||
# is set, that tracking style is disabled. The example policy links
|
||||
# go to Calamares' generic user manual (which is a terrible idea
|
||||
# for distro's: you have GDPR obligations under most of these tracking
|
||||
# styles, so do your homework).
|
||||
#
|
||||
# Each area may have other configuration keys, depending on the
|
||||
# area and how it needs to be configured.
|
||||
@ -48,13 +50,14 @@
|
||||
---
|
||||
# This is the global policy; it is displayed as a link on the page.
|
||||
# If blank or commented out, no link is displayed on the tracking
|
||||
# page. It is recommended to either provide policy URLs for each
|
||||
# area, *or* one general link, and not to mix them.
|
||||
# page. You **must** provide policy links per-area as well.
|
||||
policy: "https://github.com/calamares/calamares/wiki/Use-Guide#installation-tracking"
|
||||
|
||||
# This is the default level to enable for tracking. If commented out,
|
||||
# This is the default area to enable for tracking. If commented out,
|
||||
# empty, or otherwise invalid, "none" is used, so no tracking by default.
|
||||
default: user
|
||||
# Setting an area here also checks the areas before it (install, machine,
|
||||
# then user) by default -- subject to those areas being enabled at all.
|
||||
# default: user
|
||||
|
||||
# The install area has one specific configuration key:
|
||||
# url: this URL (remember to include the protocol, and prefer https)
|
||||
@ -72,17 +75,28 @@ default: user
|
||||
install:
|
||||
enabled: false
|
||||
policy: "https://github.com/calamares/calamares/wiki/Use-Guide#installation-tracking"
|
||||
# url: "https://example.com/install.php?c=$CPU&m=$MEMORY"
|
||||
url: "https://example.com/install.php?c=$CPU&m=$MEMORY"
|
||||
|
||||
# The machine area has one specific configuration key:
|
||||
# style: This string specifies what kind of tracking configuration
|
||||
# needs to be done. There is currently only one valid
|
||||
# style, "neon", which edits two files in the installed
|
||||
# system to enable system-tracking.
|
||||
# needs to be done. See below for valid styles.
|
||||
#
|
||||
# Available styles:
|
||||
# - *updatemanager* replaces the literal string "${MACHINE_ID}" with the contents of
|
||||
# /etc/machine-id, in lines starting with "URI" in the file /etc/update-manager/meta-release
|
||||
machine:
|
||||
enabled: false
|
||||
style: neon
|
||||
style: updatemanager
|
||||
policy: "https://github.com/calamares/calamares/wiki/Use-Guide#machine-tracking"
|
||||
|
||||
# The user area is not yet implemented, and has no specific configuration.
|
||||
# The user area has one specific configuration key:
|
||||
# style: This string specifies what kind of tracking configuration
|
||||
# needs to be done. See below for valid styles.
|
||||
#
|
||||
# Available styles:
|
||||
# - *kuserfeedback* sets up KUserFeedback tracking (applicable to the KDE
|
||||
# Plasma Desktop) for each KUserFeedback area listed in *areas*.
|
||||
user:
|
||||
enabled: false
|
||||
style: kuserfeedback
|
||||
areas: [ PlasmaUserFeedback ]
|
||||
|
Loading…
Reference in New Issue
Block a user