From d71a36f0ef9b1cc5c11d5c52456b4a8469ccc967 Mon Sep 17 00:00:00 2001 From: Aaron Rainbolt Date: Tue, 30 Jan 2024 13:43:06 -0500 Subject: [PATCH] More do-release-upgrade progress --- CMakeLists.txt | 3 ++ README.md | 5 +++ src/aptmanager.cpp | 10 +---- src/lubuntu-update-backend | 4 +- src/mainwindow.cpp | 17 +++------ src/mainwindow.h | 7 ++-- src/orchestrator.cpp | 72 ++++++++++++++++++++++++++++++++++++ src/orchestrator.h | 3 ++ src/releaseupgradewindow.cpp | 33 +++++++++++++++++ src/releaseupgradewindow.h | 27 ++++++++++++++ src/releaseupgradewindow.ui | 66 +++++++++++++++++++++++++++++++++ 11 files changed, 220 insertions(+), 27 deletions(-) create mode 100644 src/releaseupgradewindow.cpp create mode 100644 src/releaseupgradewindow.h create mode 100644 src/releaseupgradewindow.ui diff --git a/CMakeLists.txt b/CMakeLists.txt index 82ba282..6246a9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,9 @@ set(PROJECT_SOURCES src/conffilehandlerdialog.ui src/ipcfilewatcher.h src/ipcfilewatcher.cpp + src/releaseupgradewindow.h + src/releaseupgradewindow.cpp + src/releaseupgradewindow.ui ${TS_FILES} ) diff --git a/README.md b/README.md index 9585b01..556eb1c 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,11 @@ It is highly recommended that you use a Lubuntu virtual machine for testing and Qt Creator is recommended for editing the code. It is present in Ubuntu's official repos and can be installed using `sudo apt install qtcreator`. +## Config file format: +There's only one field here: + +* nextDoReleaseUpgradeNotify=123456789 - Value is number of seconds since the UNIX epoch. Used to determine when to offer the user an upgrade. + ## Missing features * Double-clicking on a package doesn't show detailed information for it yet. diff --git a/src/aptmanager.cpp b/src/aptmanager.cpp index 1f628d8..171846b 100644 --- a/src/aptmanager.cpp +++ b/src/aptmanager.cpp @@ -144,7 +144,7 @@ void AptManager::handleUpdateProcessBuffer() conffileList.append(confLine); } } - } else if (line == "Lubuntu Update !!! NEW LTS RELEASE") { + } else if (line == "Lubuntu Update !!! NEW RELEASE") { // Same busy-wait technique, but here we're just getting one extra line, the model code. while (!aptProcess->canReadLine()) { QThread::msleep(20); @@ -152,14 +152,6 @@ void AptManager::handleUpdateProcessBuffer() aptProcess->readLine(lineBuf, 2048); QString ltsReleaseCode = QString(lineBuf); emit newLtsRelease(ltsReleaseCode); - } else if (line == "Lubuntu Update !!! NEW STABLE RELEASE") { - // Ditto - while (!aptProcess->canReadLine()) { - QThread::msleep(20); - } - aptProcess->readLine(lineBuf, 2048); - QString stableReleaseCode = QString(lineBuf); - emit newStableRelease(stableReleaseCode); } double percentageDone = (static_cast(internalUpdateProgress) / (((internalUpdateInfo[0].count() + internalUpdateInfo[1].count()) * 4) + internalUpdateInfo[2].count())) * 100; diff --git a/src/lubuntu-update-backend b/src/lubuntu-update-backend index 4c0ba2a..62ffa93 100755 --- a/src/lubuntu-update-backend +++ b/src/lubuntu-update-backend @@ -152,14 +152,14 @@ elif [ "$1" = 'doupdate' ]; then if [ -n "$nextLTSReleaseYear" ]; then if isReleaseSupported "$nextLTSReleaseYear" "$nextLTSReleaseMonth" "$metaReleaseData"; then - echo 'Lubuntu Update !!! NEW LTS RELEASE'; + echo 'Lubuntu Update !!! NEW RELEASE'; echo "$nextLTSReleaseYear.$nextLTSReleaseMonth"; fi fi if ! (((nextReleaseYear == nextLTSReleaseYear) && (nextReleaseMonth == nextLTSReleaseMonth))); then if isReleaseSupported "$nextReleaseYear" "$nextReleaseMonth" "$metaReleaseData"; then - echo 'Lubuntu Update !!! NEW STABLE RELEASE'; + echo 'Lubuntu Update !!! NEW RELEASE'; echo "$nextReleaseYear.$nextReleaseMonth"; fi fi diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b2c23fa..6ecd419 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -25,8 +25,7 @@ MainWindow::MainWindow(QWidget *parent) connect(aptManager, &AptManager::progressUpdated, this, &MainWindow::onProgressUpdate); connect(aptManager, &AptManager::logLineReady, this, &MainWindow::onLogLineReady); connect(aptManager, &AptManager::conffileListReady, this, &MainWindow::onConffileListReady); - connect(aptManager, &AptManager::newLtsRelease, this, &MainWindow::onNewLtsRelease); - connect(aptManager, &AptManager::newStableRelease, this, &MainWindow::onNewStableRelease); + connect(aptManager, &AptManager::newLtsRelease, this, &MainWindow::onNewRelease); } MainWindow::~MainWindow() @@ -179,19 +178,13 @@ void MainWindow::onConffileListReady(QStringList conffileList) aptManager->doneWithConffiles(); } -void MainWindow::onNewLtsRelease(QString code) +void MainWindow::onNewRelease(QString code) { - newLtsReleaseAvailable = true; -} - -void MainWindow::onNewStableRelease(QString code) -{ - newStableReleaseAvailable = true; + releaseCodes.append(code); } void MainWindow::handleNewReleases() { - // TODO: Write code that informs the user when a new release is available here - newLtsReleaseAvailable = false; - newStableReleaseAvailable = false; + emit newReleaseAvailable(releaseCodes); + releaseCodes.clear(); } diff --git a/src/mainwindow.h b/src/mainwindow.h index 5748b1c..8055f46 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -26,6 +26,7 @@ public: signals: void updatesInstalled(); void updatesRefreshed(); + void newReleaseAvailable(QStringList releaseCodes); protected slots: void closeEvent(QCloseEvent *event) override; @@ -39,14 +40,12 @@ private slots: void onProgressUpdate(int progress); void onLogLineReady(QString logLine); void onConffileListReady(QStringList conffileList); - void onNewLtsRelease(QString code); - void onNewStableRelease(QString code); + void onNewRelease(QString code); private: Ui::MainWindow *ui; AptManager *aptManager; - bool newLtsReleaseAvailable = false; - bool newStableReleaseAvailable = false; + QStringList releaseCodes; void handleNewReleases(); }; diff --git a/src/orchestrator.cpp b/src/orchestrator.cpp index 21e359f..07353bf 100644 --- a/src/orchestrator.cpp +++ b/src/orchestrator.cpp @@ -2,6 +2,9 @@ #include "mainwindow.h" #include "aptmanager.h" +#include +#include +#include #include #include #include @@ -12,6 +15,32 @@ Orchestrator::Orchestrator(QObject *parent) checkTimer = new QTimer(); // every time this triggers, the apt database is checked for new updates trayIcon = new QSystemTrayIcon(); // this is shown to the user to offer updates + /* + * Parse the Lubuntu Update config file. It contains two critical pieces + * of info - when the system last offered the user a release upgrade, + * and whether the user has disabled release upgrade notifications. + */ + QFile configFile(QDir::homePath() + "/.config/lubuntu-update.conf"); + bool success = configFile.open(QFile::ReadOnly); + if (success) { + char lineBuf[2048]; + while (configFile.canReadLine()) { + configFile.readLine(lineBuf, 2048); + QString line(lineBuf); + line = line.trimmed(); + QStringList lineParts = line.split("="); + if (lineParts.count() == 2) { + if (lineParts[0] == "nextDoReleaseUpgradeNotify") { + nextUpgradeCheck = QDateTime::fromSecsSinceEpoch(lineParts[1].toLongLong()); + } else { + qWarning() << "Unrecognized config line: " << line; + } + } else { + qWarning() << "Wrong number of fields in line: " << line; + } + } + } + connect(checkTimer, &QTimer::timeout, this, &Orchestrator::checkForUpdates); connect(trayIcon, &QSystemTrayIcon::activated, this, &Orchestrator::displayUpdater); connect(&updaterWindow, &MainWindow::updatesInstalled, this, &Orchestrator::handleUpdatesInstalled); @@ -65,3 +94,46 @@ void Orchestrator::handleUpdatesRefreshed() checkForUpdates(); displayUpdater(); } + +void Orchestrator::onNewReleaseAvailable(QStringList releaseCodes) +{ + // First, determine what kinds of releases the user wants to see. + QFile druTypeFile("/etc/update-manager/release-upgrades"); + bool success = druTypeFile.open(QFile::ReadOnly); + QString druType; + if (success) { + char lineBuf[2048]; + while (druTypeFile.canReadLine()) { + druTypeFile.readLine(lineBuf, 2048); + QString line(lineBuf); + line = line.trimmed(); + if (line == "Prompt=lts") { + druType="lts"; + druTypeFile.close(); + break; + } else if (line == "Prompt=none") { + // The user has disabled all upgrade prompts. + druTypeFile.close(); + return; + } else if (line == "Prompt=normal") { + druType="normal"; + druTypeFile.close(); + break; + } + } + } + + for (int i = 0;i < releaseCodes.count();i++) { + QStringList releaseCodeParts = releaseCodes[i].split('.'); + if (releaseCodeParts.count() >= 2) { + int releaseYear = releaseCodeParts[0].toInt(); + int releaseMonth = releaseCodeParts[1].toInt(); + if (((releaseYear % 2 == 0) && (releaseMonth == 4)) || druType == "normal") { + QDateTime now = QDateTime::currentDateTime(); + if (nextUpgradeCheck < now) { + // TODO: attempt to show window here + } + } + } + } +} diff --git a/src/orchestrator.h b/src/orchestrator.h index e9eb690..974c5ee 100644 --- a/src/orchestrator.h +++ b/src/orchestrator.h @@ -3,6 +3,7 @@ #include "mainwindow.h" +#include #include #include @@ -22,12 +23,14 @@ private slots: void checkForUpdates(); void handleUpdatesInstalled(); void handleUpdatesRefreshed(); + void onNewReleaseAvailable(QStringList releaseCodes); private: QTimer *checkTimer; QSystemTrayIcon *trayIcon; QList updateInfo; MainWindow updaterWindow; + QDateTime nextUpgradeCheck; }; #endif // ORCHESTRATOR_H diff --git a/src/releaseupgradewindow.cpp b/src/releaseupgradewindow.cpp new file mode 100644 index 0000000..42acf6f --- /dev/null +++ b/src/releaseupgradewindow.cpp @@ -0,0 +1,33 @@ +#include "releaseupgradewindow.h" +#include "ui_releaseupgradewindow.h" + +ReleaseUpgradeWindow::ReleaseUpgradeWindow(QString releaseCode, QWidget *parent) : + QDialog(parent), + ui(new Ui::ReleaseUpgradeWindow) +{ + ui->setupUi(this); + ui->upgradeLabel->setText(tr("An upgrade to Lubuntu %1 is available! Would you like to install this upgrade now?").arg(releaseCode)); + connect(ui->upgradeButton, &QPushButton::clicked, this, &ReleaseUpgradeWindow::onUpgradeClicked); + connect(ui->remindButton, &QPushButton::clicked, this, &ReleaseUpgradeWindow::onRemindClicked); + connect(ui->declineButton, &QPushButton::clicked, this, &ReleaseUpgradeWindow::onDeclineClicked); +} + +ReleaseUpgradeWindow::~ReleaseUpgradeWindow() +{ + delete ui; +} + +void ReleaseUpgradeWindow::onUpgradeClicked() +{ + +} + +void ReleaseUpgradeWindow::onRemindClicked() +{ + +} + +void ReleaseUpgradeWindow::onDeclineClicked() +{ + +} diff --git a/src/releaseupgradewindow.h b/src/releaseupgradewindow.h new file mode 100644 index 0000000..2788665 --- /dev/null +++ b/src/releaseupgradewindow.h @@ -0,0 +1,27 @@ +#ifndef RELEASEUPGRADEWINDOW_H +#define RELEASEUPGRADEWINDOW_H + +#include + +namespace Ui { +class ReleaseUpgradeWindow; +} + +class ReleaseUpgradeWindow : public QDialog +{ + Q_OBJECT + +public: + explicit ReleaseUpgradeWindow(QString releaseCode, QWidget *parent = nullptr); + ~ReleaseUpgradeWindow(); + +private slots: + void onUpgradeClicked(); + void onRemindClicked(); + void onDeclineClicked(); + +private: + Ui::ReleaseUpgradeWindow *ui; +}; + +#endif // RELEASEUPGRADEWINDOW_H diff --git a/src/releaseupgradewindow.ui b/src/releaseupgradewindow.ui new file mode 100644 index 0000000..ae49945 --- /dev/null +++ b/src/releaseupgradewindow.ui @@ -0,0 +1,66 @@ + + + ReleaseUpgradeWindow + + + + 0 + 0 + 393 + 74 + + + + Dialog + + + + + + upgrade available + + + + + + + Qt::Vertical + + + + 20 + 6 + + + + + + + + + + Upgrade Now + + + + + + + Remind me later + + + + + + + Decline Upgrade + + + + + + + + + +