Compare commits
4 Commits
ubuntu/nob
...
ubuntu/jam
Author | SHA1 | Date | |
---|---|---|---|
549b3a4c48 | |||
536429aacd | |||
|
7b0c65e522 | ||
|
366d4ad7ac |
34
debian/changelog
vendored
34
debian/changelog
vendored
@ -1,3 +1,37 @@
|
||||
lubuntu-update-notifier (0.5.1~22.04.4) jammy; urgency=medium
|
||||
|
||||
* Add support for release upgrading, when all updates are applied (LP: #2038958).
|
||||
|
||||
-- Simon Quigley <tsimonq2@ubuntu.com> Tue, 10 Oct 2023 14:06:19 -0500
|
||||
|
||||
lubuntu-update-notifier (0.5.1~22.04.3) jammy; urgency=medium
|
||||
|
||||
* Don't try to pass a string to QTreeWidgetItem when it expects an
|
||||
Iterable[str]. (LP: #2012823)
|
||||
|
||||
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Sun, 26 Mar 2023 12:21:33 -0500
|
||||
|
||||
lubuntu-update-notifier (0.5.1~22.04.2) jammy; urgency=medium
|
||||
|
||||
* SRU backport of 0.5.1 to the Jammy stable release.
|
||||
|
||||
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Sun, 08 Jan 2023 17:56:49 -0600
|
||||
|
||||
lubuntu-update-notifier (0.5.1) lunar; urgency=medium
|
||||
|
||||
* Added functionality for repairing an interrupted upgrade. (LP: #2002255)
|
||||
* Fixed an assumption in the config-file-conflict frontend.
|
||||
* Bumped version number in lubuntu-upgrader.
|
||||
|
||||
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Wed, 14 Dec 2022 12:32:48 -0600
|
||||
|
||||
lubuntu-update-notifier (0.5) lunar; urgency=medium
|
||||
|
||||
* Add a frontend for config-file-conflict.
|
||||
* Update Standards-version to 4.6.1, no changes needed.
|
||||
|
||||
-- Simon Quigley <tsimonq2@ubuntu.com> Wed, 07 Dec 2022 13:26:39 -0600
|
||||
|
||||
lubuntu-update-notifier (0.4) hirsute; urgency=medium
|
||||
|
||||
* Added internationalization support.
|
||||
|
6
debian/control
vendored
6
debian/control
vendored
@ -2,13 +2,13 @@ Source: lubuntu-update-notifier
|
||||
Section: admin
|
||||
Priority: optional
|
||||
Maintainer: Hans P Möller <hmollercl@lubuntu.me>
|
||||
Build-Depends: debhelper-compat (=13),
|
||||
Build-Depends: debhelper-compat (= 13),
|
||||
dh-python,
|
||||
gettext,
|
||||
python3-all,
|
||||
python3-apt,
|
||||
python3-setuptools
|
||||
Standards-Version: 4.5.0
|
||||
Standards-Version: 4.6.1
|
||||
Rules-Requires-Root: no
|
||||
Testsuite: autopkgtest-pkg-python
|
||||
|
||||
@ -19,8 +19,10 @@ Depends: aptdaemon,
|
||||
lxqt-sudo,
|
||||
python3,
|
||||
python3-aptdaemon (>= 0.6.20ubuntu16),
|
||||
python3-launchpadlib,
|
||||
python3-pyqt5,
|
||||
update-notifier-common,
|
||||
ubuntu-release-upgrader-qt,
|
||||
${misc:Depends},
|
||||
${python3:Depends},
|
||||
${shlibs:Depends}
|
||||
|
5
debian/copyright
vendored
5
debian/copyright
vendored
@ -2,8 +2,9 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Source: https://phab.lubuntu.me/source/lubuntu-update-notifier/
|
||||
|
||||
Files: *
|
||||
Copyright: © 2019 Lubuntu Team.
|
||||
© 2019 Hans P Möller <hmollercl@lubuntu.me>
|
||||
Copyright: 2019-2022 Lubuntu Team <lubuntu-devel@lists.ubuntu.com>
|
||||
2019 Hans P Möller <hmollercl@lubuntu.me>
|
||||
2022 Simon Quigley <tsimonq2@lubuntu.me>
|
||||
License: GPL-3+
|
||||
|
||||
License: GPL-3+
|
||||
|
@ -2,6 +2,7 @@
|
||||
# coding=utf-8
|
||||
|
||||
# Copyright (C) 2019 Hans P. Möller <hmollercl@lubuntu.me>
|
||||
# Copyright (C) 2023 Simon Quigley <tsimonq2@lubuntu.me>
|
||||
#
|
||||
# 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
|
||||
@ -28,8 +29,10 @@ import gettext
|
||||
from PyQt5.QtWidgets import (QWidget, QApplication, QLabel, QDialogButtonBox,
|
||||
QHBoxLayout, QVBoxLayout, QTreeWidget,
|
||||
QTreeWidgetItem, QHeaderView)
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtCore import Qt, QThread, pyqtSignal
|
||||
from PyQt5.QtGui import QIcon
|
||||
from launchpadlib.launchpad import Launchpad
|
||||
|
||||
import importlib.util
|
||||
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
@ -37,16 +40,35 @@ spec = importlib.util.spec_from_file_location(
|
||||
apt_check = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(apt_check)
|
||||
|
||||
class RunUpgradeThread(QThread):
|
||||
finished = pyqtSignal()
|
||||
|
||||
def __init__(self, cmd):
|
||||
super().__init__()
|
||||
self.cmd = cmd
|
||||
|
||||
def run(self):
|
||||
process = subprocess.Popen(self.cmd)
|
||||
process.wait()
|
||||
self.finished.emit()
|
||||
|
||||
class Dialog(QWidget):
|
||||
''' UI '''
|
||||
|
||||
def __init__(self, upgrades, security_upgrades, reboot_required, upg_path):
|
||||
def __init__(self, upgrades, security_upgrades, release_upgrade, version, reboot_required, upg_path):
|
||||
QWidget.__init__(self)
|
||||
self.upgrades = upgrades
|
||||
self.security_upgrades = security_upgrades
|
||||
self.release_upgrade = release_upgrade
|
||||
self.version = version
|
||||
self.upg_path = upg_path
|
||||
self.reboot_required = reboot_required
|
||||
|
||||
try:
|
||||
self.launchpad = Launchpad.login_anonymously("lubuntu-update-notifier", "production", version="devel")
|
||||
except:
|
||||
self.launchpad = None
|
||||
|
||||
apt_pkg.init()
|
||||
try:
|
||||
self.cache = apt_pkg.Cache()
|
||||
@ -64,6 +86,8 @@ class Dialog(QWidget):
|
||||
''' UI initialization '''
|
||||
self.label = QLabel()
|
||||
self.label.setAlignment(Qt.AlignHCenter)
|
||||
self.label.setTextFormat(Qt.RichText)
|
||||
self.label.setOpenExternalLinks(True)
|
||||
|
||||
self.tw = QTreeWidget()
|
||||
if self.security_upgrades > 0:
|
||||
@ -93,7 +117,7 @@ class Dialog(QWidget):
|
||||
|
||||
self.tw.setVisible(False)
|
||||
|
||||
if self.upg_path is None:
|
||||
if self.upg_path is None and not self.release_upgrade:
|
||||
self.buttonBox.button(QDialogButtonBox.Apply).setVisible(False)
|
||||
|
||||
self.setLayout(vbox)
|
||||
@ -129,7 +153,7 @@ class Dialog(QWidget):
|
||||
if len(pkg_delete) > 0:
|
||||
toDelete = QTreeWidgetItem([_('Remove')])
|
||||
for p in pkg_delete:
|
||||
td_child = QTreeWidgetItem(p.name)
|
||||
td_child = QTreeWidgetItem([p.name])
|
||||
toDelete.addChild(td_child)
|
||||
toDelete.setIcon(0, QIcon.fromTheme("edit-delete"))
|
||||
self.tw.addTopLevelItem(toDelete)
|
||||
@ -163,6 +187,10 @@ class Dialog(QWidget):
|
||||
td_child.addChild(short)
|
||||
toUpgrade.setIcon(0, QIcon.fromTheme("system-software-update"))
|
||||
self.tw.addTopLevelItem(toUpgrade)
|
||||
elif self.release_upgrade:
|
||||
self.setWindowTitle("Upgrade Lubuntu")
|
||||
text = self.new_version_text()
|
||||
self.buttonBox.clicked.connect(self.call_release_upgrader)
|
||||
|
||||
if self.reboot_required:
|
||||
if text == "":
|
||||
@ -192,43 +220,83 @@ class Dialog(QWidget):
|
||||
QDialogButtonBox.ApplyRole):
|
||||
''' starts upgrade process '''
|
||||
self.label.setText(_("Upgrading..."))
|
||||
# TODO maybe open another thread so notifier won't freeze
|
||||
cmd = ['lxqt-sudo', self.upg_path, '--full-upgrade']
|
||||
self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
|
||||
self.buttonBox.button(QDialogButtonBox.Apply).setVisible(False)
|
||||
self.tw.setVisible(False)
|
||||
process = subprocess.Popen(cmd)
|
||||
process.wait()
|
||||
|
||||
if self.upg_path == "terminal":
|
||||
text = _("Upgrade finished")
|
||||
cmd = ["lxqt-sudo", self.upg_path, "--full-upgrade"]
|
||||
self.thread = RunUpgradeThread(cmd)
|
||||
self.thread.finished.connect(self.on_upgrade_finished)
|
||||
self.thread.start()
|
||||
|
||||
reboot_required_path = Path("/var/run/reboot-required")
|
||||
if reboot_required_path.exists():
|
||||
text += "\n" + _("Reboot required")
|
||||
self.label.setText(text)
|
||||
self.closeBtn.setVisible(True)
|
||||
self.closeBtn.setEnabled(True)
|
||||
def on_upgrade_finished(self):
|
||||
if self.upg_path == "terminal":
|
||||
text = _("Upgrade finished")
|
||||
|
||||
else:
|
||||
app.quit()
|
||||
reboot_required_path = Path("/var/run/reboot-required")
|
||||
if reboot_required_path.exists():
|
||||
text += "\n" + _("Reboot required")
|
||||
self.label.setText(text)
|
||||
self.closeBtn.setVisible(True)
|
||||
self.closeBtn.setEnabled(True)
|
||||
elif self.release_upgrade:
|
||||
self.setWindowTitle("Upgrade Lubuntu")
|
||||
self.label.setText(self.new_version_text())
|
||||
self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
|
||||
self.buttonBox.button(QDialogButtonBox.Apply).setVisible(True)
|
||||
self.buttonBox.clicked.disconnect(self.call_upgrade)
|
||||
self.buttonBox.clicked.connect(self.call_release_upgrader)
|
||||
else:
|
||||
app.quit()
|
||||
|
||||
def call_release_upgrader(self, btnClicked):
|
||||
if self.buttonBox.buttonRole(btnClicked) == QDialogButtonBox.ApplyRole:
|
||||
cmd = ["lxqt-sudo", "do-release-upgrade", "-m", "desktop", "-f", "DistUpgradeViewKDE"]
|
||||
self.thread2 = RunUpgradeThread(cmd)
|
||||
self.thread2.finished.connect(self.call_reject)
|
||||
self.thread2.start()
|
||||
elif self.buttonBox.buttonRole(btnClicked) == QDialogButtonBox.RejectRole:
|
||||
self.call_reject()
|
||||
|
||||
def new_version_text(self):
|
||||
try:
|
||||
main_version = '.'.join(self.version.split()[0].split('.')[:2])
|
||||
codename = self.launchpad.distributions["ubuntu"].getSeries(name_or_version=main_version).name
|
||||
except:
|
||||
codename = None
|
||||
|
||||
if codename:
|
||||
url_suffix = ""
|
||||
point_release = self.version.split(".")[2].split(" ")[0] if "." in self.version[4:] else "0"
|
||||
if point_release != "0":
|
||||
url_suffix = f"-{int(point_release)}"
|
||||
url_suffix += "-released"
|
||||
|
||||
text = f"<a href='https://lubuntu.me/{codename}{url_suffix}/'>"
|
||||
text += _("A new version of Lubuntu") + "</a> "
|
||||
text += _("is available. Would you like to install it?")
|
||||
else:
|
||||
text = _("A new version of Lubuntu is available. Would you like to install it?")
|
||||
|
||||
return text
|
||||
|
||||
|
||||
class App(QApplication):
|
||||
'''application'''
|
||||
|
||||
def __init__(self, upgrades, security_upgrades, reboot_required, upg_path,
|
||||
def __init__(self, upgrades, security_upgrades, release_upgrade, version, reboot_required, upg_path,
|
||||
*args):
|
||||
QApplication.__init__(self, *args)
|
||||
self.dialog = Dialog(upgrades, security_upgrades, reboot_required,
|
||||
self.dialog = Dialog(upgrades, security_upgrades, release_upgrade, version, reboot_required,
|
||||
upg_path)
|
||||
self.dialog.show()
|
||||
|
||||
|
||||
def main(args, upgrades, security_upgrades, reboot_required, upg_path):
|
||||
|
||||
def main(args, upgrades, security_upgrades, release_upgrade, version, reboot_required, upg_path):
|
||||
'''main'''
|
||||
global app
|
||||
app = App(upgrades, security_upgrades, reboot_required, upg_path, args)
|
||||
app = App(upgrades, security_upgrades, release_upgrade, version, reboot_required, upg_path, args)
|
||||
app.setWindowIcon(QIcon.fromTheme("system-software-update"))
|
||||
app.exec_()
|
||||
|
||||
@ -256,12 +324,29 @@ if __name__ == "__main__":
|
||||
dest="security_upgrades",
|
||||
help=_("How many security upgrades are available"),
|
||||
metavar="APP")
|
||||
parser.add_argument("-r",
|
||||
"--release-upgrade",
|
||||
dest="release_upgrade",
|
||||
help=_("Whether a release upgrade is required"),
|
||||
type=str,
|
||||
metavar="APP")
|
||||
parser.add_argument("-v",
|
||||
"--release-upgrade-version",
|
||||
dest="version",
|
||||
help=_("If a release upgrade is available, provide the version"),
|
||||
type=str,
|
||||
metavar="APP")
|
||||
|
||||
options = parser.parse_args()
|
||||
|
||||
reboot_required_path = Path("/var/run/reboot-required")
|
||||
reboot_required = reboot_required_path.exists()
|
||||
|
||||
if int(options.upgrades) > 0 or reboot_required:
|
||||
if int(options.release_upgrade) == 0:
|
||||
options.release_upgrade = True
|
||||
else:
|
||||
options.release_upgrade = False
|
||||
|
||||
if int(options.upgrades) > 0 or reboot_required or options.release_upgrade:
|
||||
main(sys.argv, int(options.upgrades), int(options.security_upgrades),
|
||||
reboot_required, options.upg_path)
|
||||
options.release_upgrade, options.version, reboot_required, options.upg_path)
|
||||
|
@ -32,6 +32,12 @@ while true;
|
||||
j=`expr $j + 1`
|
||||
done
|
||||
IFS=$oldIFS
|
||||
/usr/libexec/lubuntu-update-notifier/lubuntu-notifier.py -u $UPG -s $SEC -p /usr/bin/lubuntu-upgrader
|
||||
|
||||
NEWREL_CHECK=`/usr/bin/do-release-upgrade -c 2>&1`
|
||||
NEWREL=$?
|
||||
if [ "$NEWREL" -eq 0 ]; then
|
||||
VERSION=`echo $NEWREL_CHECK | awk -F\' '/available/{print $2}'`
|
||||
fi
|
||||
/usr/libexec/lubuntu-update-notifier/lubuntu-notifier.py -u $UPG -s $SEC -r $NEWREL -v $VERSION -p /usr/bin/lubuntu-upgrader
|
||||
sleep 86400
|
||||
done;
|
||||
|
@ -2,6 +2,7 @@
|
||||
# coding=utf-8
|
||||
|
||||
# Copyright (C) 2019 Hans P. Möller <hmollercl@lubuntu.me>
|
||||
# Copyright (C) 2022 Simon Quigley <tsimonq2@lubuntu.me>
|
||||
#
|
||||
# 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
|
||||
@ -64,6 +65,8 @@ class DialogUpg(QWidget):
|
||||
#stderr=subprocess.PIPE
|
||||
stderr=self.slave)'''
|
||||
|
||||
self.trans3 = self.apt_client.fix_incomplete_install()
|
||||
self.repair_install()
|
||||
if options.fullUpgrade:
|
||||
self.trans2 = self.apt_client.upgrade_system(safe_mode=False)
|
||||
self.setWindowTitle('Full Upgrade')
|
||||
@ -128,6 +131,12 @@ class DialogUpg(QWidget):
|
||||
self.progressBar.setValue(progress)
|
||||
self.label.setText(_("Updating cache..."))
|
||||
|
||||
def repair_progress(self, transaction, progress):
|
||||
'''upgrade progressbar during update'''
|
||||
self.progressBar.setVisible(True)
|
||||
self.progressBar.setValue(progress)
|
||||
self.label.setText(_("Repairing interrupted upgrade if necessary..."))
|
||||
|
||||
def update_progress_download(self, transaction, uri, status, short_desc,
|
||||
total_size, current_size, msg):
|
||||
'''print update info'''
|
||||
@ -312,6 +321,29 @@ class DialogUpg(QWidget):
|
||||
# print("PTY:" + str(self.slave))
|
||||
print("Status Details:" + details)
|
||||
|
||||
def config_file_conflict(self, transaction, cur, new):
|
||||
title = "Conflicting Configuration"
|
||||
text = "Updating the system will result in the following file being "
|
||||
text += "overwritten: " + cur + "\n\nWhat would you like to do?"
|
||||
query = QMessageBox()
|
||||
query.setWindowTitle(title)
|
||||
query.setText(text)
|
||||
query.setIcon(QMessageBox.Question)
|
||||
query.setStandardButtons(QMessageBox.Yes|QMessageBox.No)
|
||||
yes = query.button(QMessageBox.Yes)
|
||||
yes.setText("Overwrite")
|
||||
no = query.button(QMessageBox.No)
|
||||
no.setText("Keep Existing")
|
||||
query.setDefaultButton(no)
|
||||
query.exec_()
|
||||
|
||||
if query.clickedButton() == yes:
|
||||
answer = "replace"
|
||||
elif query.clickedButton() == no:
|
||||
answer = "keep"
|
||||
|
||||
transaction.resolve_config_file_conflict(config=cur, answer=answer)
|
||||
|
||||
def upgrade(self):
|
||||
'''runs upgrade'''
|
||||
try:
|
||||
@ -327,6 +359,8 @@ class DialogUpg(QWidget):
|
||||
self.trans2.connect("status-details-changed",
|
||||
self.status_details_changed)
|
||||
self.trans2.connect("status-changed", self.status_changed)
|
||||
self.trans2.connect("config-file-conflict",
|
||||
self.config_file_conflict)
|
||||
|
||||
# TODO make a terminal work to see more info
|
||||
# self.trans2.set_terminal(os.ttyname(self.slave))
|
||||
@ -334,8 +368,6 @@ class DialogUpg(QWidget):
|
||||
'''
|
||||
# TODO implement this
|
||||
self.trans2.connect("medium-required", self._on_medium_required)
|
||||
self.trans2.connect("config-file-conflict",
|
||||
self._on_config_file_conflict)
|
||||
remove_obsoleted_depends
|
||||
'''
|
||||
self.trans2.set_debconf_frontend('kde')
|
||||
@ -349,6 +381,35 @@ class DialogUpg(QWidget):
|
||||
'''when close button is pushed, quit'''
|
||||
app.quit()
|
||||
|
||||
def repair_install(self):
|
||||
self.closeBtn.setVisible(False)
|
||||
try:
|
||||
self.trans3.connect('progress-changed', self.repair_progress)
|
||||
self.trans3.connect('status-changed', self.status_changed)
|
||||
self.trans3.connect('status-details-changed',
|
||||
self.status_details_changed)
|
||||
self.trans3.connect('finished', self.repair_finish)
|
||||
self.trans3.connect('error', self.upgrade_error)
|
||||
self.trans3.set_debconf_frontend('kde')
|
||||
self.trans3.run()
|
||||
|
||||
except (NotAuthorizedError, TransactionFailed) as e:
|
||||
print("Warning: install transaction not completed successfully:"
|
||||
+ "{}".format(e))
|
||||
|
||||
def repair_finish(self, transaction, exit_state):
|
||||
'''when repair finish'''
|
||||
self.label.setText(_("Repair Finished (if repair was needed)"))
|
||||
if exit_state == EXIT_FAILED:
|
||||
error_string = get_error_string_from_enum(transaction.error.code)
|
||||
error_desc = get_error_description_from_enum(
|
||||
transaction.error.code)
|
||||
self.plainTextEdit.setEnabled(False)
|
||||
self.plainTextEdit.moveCursor(QTextCursor.End)
|
||||
self.plainTextEdit.insertPlainText(error_string + "\n")
|
||||
self.plainTextEdit.insertPlainText(error_desc + "\n")
|
||||
self.plainTextEdit.moveCursor(QTextCursor.End)
|
||||
self.plainTextEdit.setEnabled(True)
|
||||
|
||||
class App(QApplication):
|
||||
'''app'''
|
||||
@ -396,7 +457,7 @@ if __name__ == "__main__":
|
||||
help=_("Full upgrade same as dist-upgrade"))
|
||||
parser.add_argument('--version',
|
||||
action='version',
|
||||
version='%(prog)s 0.4')
|
||||
version='%(prog)s 0.5.1')
|
||||
options = parser.parse_args()
|
||||
|
||||
# run it
|
||||
|
Loading…
x
Reference in New Issue
Block a user