Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Notifying users of available add-on updates #16636

Merged
merged 34 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
4b97d4a
Create message dialog notifying users of an add-on update
seanbudd May 31, 2024
c236af8
Only notify updates from the same channel
seanbudd May 31, 2024
de9ee50
Update requirements.txt
seanbudd May 31, 2024
3dfc807
minor fixup
seanbudd Jun 3, 2024
0201b1c
Add settings and docs
seanbudd Jun 3, 2024
8e71cc0
Merge branch 'updateAddons' of https://github.com/nvaccess/nvda into …
seanbudd Jun 3, 2024
b45ba3f
Fix up name for AddonsAutomaticUpdate
seanbudd Jun 3, 2024
b5b504c
make scheduling safer
seanbudd Jun 3, 2024
fe10315
fixup typing
seanbudd Jun 3, 2024
7d33064
add unit tests for scheduler
seanbudd Jun 3, 2024
4b959a2
add add-on list to dialog
seanbudd Jun 3, 2024
479122f
implement updating add-ons
seanbudd Jun 3, 2024
dfebaa7
fix up headings
seanbudd Jun 3, 2024
6680653
simplify message dialog
seanbudd Jun 3, 2024
7b71bbe
add to release blurb
seanbudd Jun 3, 2024
ca5b985
disable in secure mode
seanbudd Jun 3, 2024
7dab8aa
improve the scheduleThread module and functionality
seanbudd Jun 4, 2024
a7ef961
review feedback
seanbudd Jun 4, 2024
c097f39
minor fixups
seanbudd Jun 4, 2024
1780d8b
set focus and raise
seanbudd Jun 4, 2024
aa3f742
fix lint
seanbudd Jun 4, 2024
4ba66cc
remove double handling of tracking jobs
seanbudd Jun 4, 2024
f9742b1
handle review comments
seanbudd Jun 5, 2024
25f0f29
review docs
seanbudd Jun 5, 2024
3218654
fix lint
seanbudd Jun 5, 2024
7a82c93
address review comments
seanbudd Jun 5, 2024
a92789a
address review comments
seanbudd Jun 5, 2024
23cee9c
fix lint and focus
seanbudd Jun 6, 2024
2a67d7d
Apply suggestions from code review
seanbudd Jun 6, 2024
1f15ac4
improve test plan docs
seanbudd Jun 6, 2024
c6e8e39
do not announce profile change
seanbudd Jun 6, 2024
8211187
remove default from label
seanbudd Jun 6, 2024
2677215
Update source/config/configFlags.py
seanbudd Jun 11, 2024
9f58dd6
add script to update add-on files
seanbudd Jun 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ pyserial==3.5
./miscDeps/python/wxPython-4.2.2a1-cp311-cp311-win32.whl
git+https://github.com/DiffSK/configobj@e2ba4457c4651fa54f8d59d8dcdd3da950e956b8#egg=configobj
requests==2.32.0
schedule==1.2.1
# Pillow is an implicit dependency and requires zlib and jpeg by default, but we don't need it
Pillow==10.3.0 -C "zlib=disable" -C "jpeg=disable"

#NVDA_DMP requires diff-match-patch
fast-diff-match-patch==2.1.0

# typing_extensions are required for specifying default value for `TypeVar`, which is not yet possible with any released version of Python (see PEP 696)
typing-extensions==4.9.0
typing-extensions==4.9.0

# pycaw is a Core Audio Windows Library used for sound split
pycaw==20240210
pycaw==20240210

# Packaging NVDA
git+https://github.com/py2exe/py2exe@4e7b2b2c60face592e67cb1bc935172a20fa371d#egg=py2exe
Expand Down
20 changes: 18 additions & 2 deletions source/addonStore/dataManager.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2022-2023 NV Access Limited
# Copyright (C) 2022-2024 NV Access Limited
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.

Expand Down Expand Up @@ -37,6 +37,7 @@
_createStoreCollectionFromJson,
)
from .models.channel import Channel
from .models.status import AvailableAddonStatus, getStatus, _StatusFilterKey
from .network import (
_getCurrentApiVersionForURL,
_getAddonStoreURL,
Expand All @@ -47,7 +48,7 @@
if TYPE_CHECKING:
from addonHandler import Addon as AddonHandlerModel # noqa: F401
# AddonGUICollectionT must only be imported when TYPE_CHECKING
from .models.addon import AddonGUICollectionT, _AddonStoreModel # noqa: F401
from .models.addon import AddonGUICollectionT, _AddonGUIModel, _AddonStoreModel # noqa: F401
from gui.addonStoreGui.viewModels.addonList import AddonListItemVM # noqa: F401
from gui.message import DisplayableError # noqa: F401

Expand Down Expand Up @@ -308,6 +309,21 @@ def _getCachedInstalledAddonData(self, addonId: str) -> Optional[InstalledAddonS
return None
return _createInstalledStoreModelFromData(cacheData)

def _addonsPendingUpdate(self) -> list["_AddonGUIModel"]:
addonsPendingUpdate: list["_AddonGUIModel"] = []
compatibleAddons = self.getLatestCompatibleAddons()
for channel in compatibleAddons:
for addon in compatibleAddons[channel].values():
if (
getStatus(addon, _StatusFilterKey.UPDATE) == AvailableAddonStatus.UPDATE
# Only consider add-ons that have been installed through the Add-on Store
and addon._addonHandlerModel._addonStoreData is not None
):
# Only consider add-on updates for the same channel
if addon.channel == addon._addonHandlerModel._addonStoreData.channel:
addonsPendingUpdate.append(addon)
return addonsPendingUpdate


class _InstalledAddonsCache(AutoPropertyObject):
cachePropertiesByDefault = True
Expand Down
13 changes: 7 additions & 6 deletions source/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,12 +506,13 @@ class ConfigManager(object):

#: Sections that only apply to the base configuration;
#: i.e. they cannot be overridden in profiles.
BASE_ONLY_SECTIONS = {
"general",
"update",
"upgrade",
"development",
}
BASE_ONLY_SECTIONS = frozenset({
"general",
"update",
"upgrade",
"development",
"addonStore",
})

def __init__(self):
self.spec = confspec
Expand Down
20 changes: 19 additions & 1 deletion source/config/configFlags.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2022-2023 NV Access Limited, Cyrille Bougot
# Copyright (C) 2022-2024 NV Access Limited, Cyrille Bougot
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.

Expand Down Expand Up @@ -202,3 +202,21 @@ def _displayStringLabels(self):
# document formatting settings panel.
ReportCellBorders.COLOR_AND_STYLE: _("Both Colors and Styles"),
}


class AddonsAutomaticUpdate(DisplayStringStrEnum):
NOTIFY = "notify"
# TODO: uncomment when implementing #3208
# UPDATE = "update"
DISABLED = "disabled"

@property
def _displayStringLabels(self):
return {
# Translators: This is a label for the automatic update behaviour for add-ons.
# It will notify the user when updates are available.
self.NOTIFY: _("Notify"),
# self.UPDATE: _("Update Automatically"),
# Translators: This is a label for the automatic update behaviour for add-ons.
self.DISABLED: _("Disabled"),
}
3 changes: 2 additions & 1 deletion source/config/configSpec.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2006-2023 NV Access Limited, Babbage B.V., Davy Kager, Bill Dengler, Julien Cochuyt,
# Copyright (C) 2006-2024 NV Access Limited, Babbage B.V., Davy Kager, Bill Dengler, Julien Cochuyt,
# Joseph Lee, Dawid Pieper, mltony, Bram Duvigneau, Cyrille Bougot, Rob Meredith,
# Burman's Computer and Education Ltd., Leonard de Ruijter, Łukasz Golonka
# This file is covered by the GNU General Public License.
Expand Down Expand Up @@ -324,6 +324,7 @@

[addonStore]
showWarning = boolean(default=true)
automaticUpdates = option("notify", "disabled", default="notify")
"""

#: The configuration specification
Expand Down
5 changes: 5 additions & 0 deletions source/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,8 @@ def main():
log.info(f"Windows version: {winVersion.getWinVer()}")
log.info("Using Python version %s"%sys.version)
log.info("Using comtypes version %s"%comtypes.__version__)
from utils import schedule
schedule.initialize()
import configobj
log.info("Using configobj version %s with validate version %s"%(configobj.__version__,configobj.validate.__version__))
# Set a reasonable timeout for any socket connections NVDA makes.
Expand All @@ -670,6 +672,8 @@ def main():
from addonStore import dataManager
dataManager.initialize()
addonHandler.initialize()
from gui import addonStoreGui
addonStoreGui.initialize()
if globalVars.appArgs.disableAddons:
log.info("Add-ons are disabled. Restart NVDA to enable them.")
import appModuleHandler
Expand Down Expand Up @@ -959,6 +963,7 @@ def _doPostNvdaStartupAction():
_terminate(addonHandler)
_terminate(dataManager, name="addon dataManager")
_terminate(garbageHandler)
_terminate(schedule, name="task scheduler")
# DMP is only started if needed.
# Terminate manually (and let it write to the log if necessary)
# as core._terminate always writes an entry.
Expand Down
17 changes: 16 additions & 1 deletion source/gui/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: UTF-8 -*-
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2006-2023 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Mesar Hameed, Joseph Lee,
# Copyright (C) 2006-2024 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Mesar Hameed, Joseph Lee,
# Thomas Stivers, Babbage B.V., Accessolutions, Julien Cochuyt, Cyrille Bougot, Luke Davis
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.
Expand Down Expand Up @@ -408,6 +408,21 @@ def onAddonStoreCommand(self, evt: wx.MenuEvent):
_storeVM.refresh()
self.popupSettingsDialog(AddonStoreDialog, _storeVM)

@blockAction.when(
blockAction.Context.SECURE_MODE,
blockAction.Context.MODAL_DIALOG_OPEN,
blockAction.Context.WINDOWS_LOCKED,
blockAction.Context.WINDOWS_STORE_VERSION,
blockAction.Context.RUNNING_LAUNCHER,
)
def onAddonStoreUpdatableCommand(self, evt: wx.MenuEvent | None):
from .addonStoreGui import AddonStoreDialog
from .addonStoreGui.viewModels.store import AddonStoreVM
from addonStore.models.status import _StatusFilterKey
_storeVM = AddonStoreVM()
_storeVM.refresh()
self.popupSettingsDialog(AddonStoreDialog, _storeVM, openToTab=_StatusFilterKey.UPDATE)

def onReloadPluginsCommand(self, evt):
import appModuleHandler, globalPluginHandler
from NVDAObjects import NVDAObject
Expand Down
13 changes: 12 additions & 1 deletion source/gui/addonStoreGui/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2022 NV Access Limited
# Copyright (C) 2022-2024 NV Access Limited
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.

from utils.schedule import scheduleThread, ThreadTarget

from .controls.storeDialog import AddonStoreDialog
from .controls.messageDialogs import UpdatableAddonsDialog

__all__ = [
"AddonStoreDialog",
"initialize",
]


def initialize():
scheduleThread.scheduleDailyJobAtStartUp(
UpdatableAddonsDialog._checkForUpdatableAddons,
queueToThread=ThreadTarget.GUI,
)
Loading