mirror of
https://github.com/cmclark00/retro-imager.git
synced 2025-05-18 07:55:21 +01:00
Enable telemetry
- Phone back home image downloaded for image popularity research. Only in case image comes from our repository (NOT for custom images)
This commit is contained in:
parent
f6a8c4d943
commit
95ce718d41
9 changed files with 111 additions and 9 deletions
|
@ -20,7 +20,7 @@ set(CMAKE_AUTORCC ON)
|
|||
|
||||
# Adding headers explicity so they are displayed in Qt Creator
|
||||
set(HEADERS config.h imagewriter.h networkaccessmanagerfactory.h nan.h drivelistitem.h drivelistmodel.h drivelistmodelpollthread.h driveformatthread.h powersaveblocker.h
|
||||
downloadthread.h downloadextractthread.h localfileextractthread.h dependencies/mountutils/src/mountutils.hpp)
|
||||
downloadthread.h downloadextractthread.h localfileextractthread.h downloadstatstelemetry.h dependencies/mountutils/src/mountutils.hpp)
|
||||
|
||||
# Add dependencies
|
||||
if (APPLE)
|
||||
|
@ -68,7 +68,7 @@ endif()
|
|||
|
||||
set(SOURCES "main.cpp" "imagewriter.cpp" "networkaccessmanagerfactory.cpp"
|
||||
"drivelistitem.cpp" "drivelistmodel.cpp" "drivelistmodelpollthread.cpp" "downloadthread.cpp" "downloadextractthread.cpp"
|
||||
"driveformatthread.cpp" "localfileextractthread.cpp" "powersaveblocker.cpp" "qml.qrc")
|
||||
"driveformatthread.cpp" "localfileextractthread.cpp" "powersaveblocker.cpp" "downloadstatstelemetry.cpp" "qml.qrc")
|
||||
|
||||
find_package(Qt5 COMPONENTS Core Quick LinguistTools Svg OPTIONAL_COMPONENTS Widgets)
|
||||
if (Qt5Widgets_FOUND)
|
||||
|
|
8
config.h
8
config.h
|
@ -8,10 +8,14 @@
|
|||
|
||||
|
||||
/* Repository URL */
|
||||
#define OSLIST_URL "https://downloads.raspberrypi.org/os_list_imagingutility.json"
|
||||
#define OSLIST_URL "https://downloads.raspberrypi.org/os_list_imagingutility_v2.json"
|
||||
|
||||
/* Time synchronization URL (only used on eglfs QPA platform, URL must be HTTP) */
|
||||
#define TIME_URL "http://downloads.raspberrypi.org/os_list_imagingutility.json?time_synchronization"
|
||||
#define TIME_URL "http://downloads.raspberrypi.org/os_list_imagingutility_v2.json?time_synchronization"
|
||||
|
||||
/* Phone home the name of images downloaded for image popularity ranking */
|
||||
#define TELEMETRY_URL "https://rpi-imager-stats.raspberrypi.org/downloads?url=$imageurl&os=$parentcategory&image=$osname"
|
||||
#define TELEMETRY_ENABLED_DEFAULT true
|
||||
|
||||
/* Hash algorithm for verifying (uncompressed image) checksum */
|
||||
#define OSLIST_HASH_ALGORITHM QCryptographicHash::Sha256
|
||||
|
|
2
debian/changelog
vendored
2
debian/changelog
vendored
|
@ -8,6 +8,8 @@ rpi-imager (1.5) unstable; urgency=medium
|
|||
* Add update notification support
|
||||
* Allow translators to specify external .qm file for testing
|
||||
* Remove dependency on qml-module-qt-labs-settings
|
||||
* Enables telemetry collecting information about which images from
|
||||
repository are most popular
|
||||
|
||||
-- Floris Bos <bos@je-eigen-domein.nl> Tue, 24 Nov 2020 10:38:21 +0100
|
||||
|
||||
|
|
53
downloadstatstelemetry.cpp
Normal file
53
downloadstatstelemetry.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#include "downloadstatstelemetry.h"
|
||||
#include "config.h"
|
||||
#include <QSettings>
|
||||
#include <QDebug>
|
||||
#include <QUrl>
|
||||
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2020 Raspberry Pi (Trading) Limited
|
||||
*/
|
||||
|
||||
DownloadStatsTelemetry::DownloadStatsTelemetry(const QByteArray &url, const QByteArray &parentcategory, const QByteArray &osname, QObject *parent)
|
||||
: QThread(parent)
|
||||
{
|
||||
_url = QByteArray(TELEMETRY_URL).replace("$imageurl", QUrl::toPercentEncoding(url)).replace("$parentcategory", QUrl::toPercentEncoding(parentcategory)).replace("$osname", QUrl::toPercentEncoding(osname));
|
||||
_useragent = "Mozilla/5.0 rpi-imager/" IMAGER_VERSION_STR;
|
||||
}
|
||||
|
||||
void DownloadStatsTelemetry::run()
|
||||
{
|
||||
QSettings settings;
|
||||
if (!settings.value("telemetry", TELEMETRY_ENABLED_DEFAULT).toBool())
|
||||
return;
|
||||
|
||||
_c = curl_easy_init();
|
||||
curl_easy_setopt(_c, CURLOPT_NOSIGNAL, 1);
|
||||
curl_easy_setopt(_c, CURLOPT_WRITEFUNCTION, &DownloadStatsTelemetry::_curl_write_callback);
|
||||
curl_easy_setopt(_c, CURLOPT_HEADERFUNCTION, &DownloadStatsTelemetry::_curl_header_callback);
|
||||
curl_easy_setopt(_c, CURLOPT_URL, _url.constData());
|
||||
curl_easy_setopt(_c, CURLOPT_USERAGENT, _useragent.constData());
|
||||
curl_easy_setopt(_c, CURLOPT_CONNECTTIMEOUT, 10);
|
||||
curl_easy_setopt(_c, CURLOPT_LOW_SPEED_TIME, 10);
|
||||
curl_easy_setopt(_c, CURLOPT_LOW_SPEED_LIMIT, 10);
|
||||
|
||||
CURLcode ret = curl_easy_perform(_c);
|
||||
curl_easy_cleanup(_c);
|
||||
|
||||
qDebug() << "Telemetry done. cURL status code =" << ret;
|
||||
}
|
||||
|
||||
/* /dev/null write handler */
|
||||
size_t DownloadStatsTelemetry::_curl_write_callback(char *, size_t size, size_t nmemb, void *)
|
||||
{
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
size_t DownloadStatsTelemetry::_curl_header_callback( void *ptr, size_t size, size_t nmemb, void *)
|
||||
{
|
||||
int len = size*nmemb;
|
||||
QByteArray headerstr((char *) ptr, len);
|
||||
//qDebug() << "Received telemetry header:" << headerstr;
|
||||
return len;
|
||||
}
|
31
downloadstatstelemetry.h
Normal file
31
downloadstatstelemetry.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef DOWNLOADSTATSTELEMETRY_H
|
||||
#define DOWNLOADSTATSTELEMETRY_H
|
||||
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2020 Raspberry Pi (Trading) Limited
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <curl/curl.h>
|
||||
|
||||
class DownloadStatsTelemetry : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DownloadStatsTelemetry(const QByteArray &url, const QByteArray &parentcategory, const QByteArray &osname, QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
CURL *_c;
|
||||
QByteArray _url, _useragent;
|
||||
virtual void run();
|
||||
static size_t _curl_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);
|
||||
static size_t _curl_header_callback( void *ptr, size_t size, size_t nmemb, void *userdata);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
||||
#endif // DOWNLOADSTATSTELEMETRY_H
|
|
@ -9,6 +9,7 @@
|
|||
#include "dependencies/drivelist/src/drivelist.hpp"
|
||||
#include "driveformatthread.h"
|
||||
#include "localfileextractthread.h"
|
||||
#include "downloadstatstelemetry.h"
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
#include <QFileInfo>
|
||||
|
@ -112,13 +113,15 @@ void ImageWriter::setEngine(QQmlApplicationEngine *engine)
|
|||
}
|
||||
|
||||
/* Set URL to download from */
|
||||
void ImageWriter::setSrc(const QUrl &url, quint64 downloadLen, quint64 extrLen, QByteArray expectedHash, bool multifilesinzip)
|
||||
void ImageWriter::setSrc(const QUrl &url, quint64 downloadLen, quint64 extrLen, QByteArray expectedHash, bool multifilesinzip, QString parentcategory, QString osname)
|
||||
{
|
||||
_src = url;
|
||||
_downloadLen = downloadLen;
|
||||
_extrLen = extrLen;
|
||||
_expectedHash = expectedHash;
|
||||
_multipleFilesInZip = multifilesinzip;
|
||||
_parentCategory = parentcategory;
|
||||
_osName = osname;
|
||||
|
||||
if (!_downloadLen && url.isLocalFile())
|
||||
{
|
||||
|
@ -191,6 +194,9 @@ void ImageWriter::startWrite()
|
|||
else if (compressed)
|
||||
{
|
||||
_thread = new DownloadExtractThread(urlstr, _dst.toLatin1(), _expectedHash, this);
|
||||
DownloadStatsTelemetry *tele = new DownloadStatsTelemetry(urlstr, _parentCategory.toLatin1(), _osName.toLatin1(), this);
|
||||
connect(tele, SIGNAL(finished()), tele, SLOT(deleteLater()));
|
||||
tele->start();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
void setEngine(QQmlApplicationEngine *engine);
|
||||
|
||||
/* Set URL to download from, and if known download length and uncompressed length */
|
||||
Q_INVOKABLE void setSrc(const QUrl &url, quint64 downloadLen = 0, quint64 extrLen = 0, QByteArray expectedHash = "", bool multifilesinzip = false);
|
||||
Q_INVOKABLE void setSrc(const QUrl &url, quint64 downloadLen = 0, quint64 extrLen = 0, QByteArray expectedHash = "", bool multifilesinzip = false, QString parentcategory = "", QString osname = "");
|
||||
|
||||
/* Set device to write to */
|
||||
Q_INVOKABLE void setDst(const QString &device, quint64 deviceSize = 0);
|
||||
|
@ -120,7 +120,7 @@ protected slots:
|
|||
|
||||
protected:
|
||||
QUrl _src, _repo;
|
||||
QString _dst, _cacheFileName;
|
||||
QString _dst, _cacheFileName, _parentCategory, _osName;
|
||||
QByteArray _expectedHash, _cachedFileHash;
|
||||
quint64 _downloadLen, _extrLen, _devLen, _dlnow, _verifynow;
|
||||
DriveListModel _drivelist;
|
||||
|
|
|
@ -57,5 +57,7 @@
|
|||
<releases>
|
||||
<release version="@IMAGER_VERSION_STR@" />
|
||||
</releases>
|
||||
<content_rating type="oars-1.1" />
|
||||
<content_rating type="oars-1.1">
|
||||
<content_attribute id="social-info">moderate</content_attribute>
|
||||
</content_rating>
|
||||
</component>
|
||||
|
|
6
main.qml
6
main.qml
|
@ -261,6 +261,7 @@ ApplicationWindow {
|
|||
height: parent.height-50
|
||||
padding: 0
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
property string categorySelected : ""
|
||||
|
||||
// background of title
|
||||
Rectangle {
|
||||
|
@ -936,13 +937,16 @@ ApplicationWindow {
|
|||
else
|
||||
suboslist.currentIndex = -1
|
||||
osswipeview.setCurrentIndex(1)
|
||||
ospopup.categorySelected = d.name
|
||||
} else if (typeof(d.subitems_url) == "string" && d.subitems_url !== "") {
|
||||
if (d.subitems_url === "internal://back")
|
||||
{
|
||||
osswipeview.setCurrentIndex(0)
|
||||
ospopup.categorySelected = ""
|
||||
}
|
||||
else
|
||||
{
|
||||
ospopup.categorySelected = d.name
|
||||
var suburl = d.subitems_url
|
||||
if (subosmodel.count>1)
|
||||
{
|
||||
|
@ -994,7 +998,7 @@ ApplicationWindow {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
imageWriter.setSrc(d.url, d.image_download_size, d.extract_size, typeof(d.extract_sha256) != "undefined" ? d.extract_sha256 : "", typeof(d.contains_multiple_files) != "undefined" ? d.contains_multiple_files : false)
|
||||
imageWriter.setSrc(d.url, d.image_download_size, d.extract_size, typeof(d.extract_sha256) != "undefined" ? d.extract_sha256 : "", typeof(d.contains_multiple_files) != "undefined" ? d.contains_multiple_files : false, ospopup.categorySelected, d.name)
|
||||
osbutton.text = d.name
|
||||
ospopup.close()
|
||||
if (imageWriter.readyToWrite()) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue