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

Add ability to specify add-on store metadata URL from within NVDA #17099

Merged
merged 34 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
ca63806
Created `addonStoore.network._getBaseUrl` method that currently just …
SaschaCowley Aug 28, 2024
c0aee14
Added a new config item, `addonStore.baseURL`, to store configurable …
SaschaCowley Aug 28, 2024
c4939be
Add mirror option to settings
SaschaCowley Aug 28, 2024
0cd1c06
Start implementation of URL validator for config
SaschaCowley Aug 28, 2024
dd591ab
Refactored DisplayableError calling code into its own private function
SaschaCowley Aug 30, 2024
57a35a1
Update getAllAddons for refactor
SaschaCowley Aug 30, 2024
7336874
Made URL getters more robust
SaschaCowley Aug 30, 2024
23b3b69
Moved helper function down
SaschaCowley Sep 2, 2024
74adc96
Added helpful messages
SaschaCowley Sep 2, 2024
19714c8
Fixed case
SaschaCowley Sep 2, 2024
7e1af57
Merge branch 'master' into addonStoreMirror
SaschaCowley Sep 2, 2024
5eaf961
Added change log entry
SaschaCowley Sep 2, 2024
7e00e7f
Renamed settings controls
SaschaCowley Sep 2, 2024
c31aced
Added documentation
SaschaCowley Sep 2, 2024
0d2a613
Renamed `BASE_URL` to `_DEFAULT_BASE_URL`
SaschaCowley Sep 2, 2024
170464e
Added note to changes for developers
SaschaCowley Sep 2, 2024
3937db0
Apply suggestions from code review
SaschaCowley Sep 3, 2024
c59d7da
Renamed config key to be more descriptive
SaschaCowley Sep 3, 2024
7a5ca61
Removed un-used config.validators file
SaschaCowley Sep 3, 2024
add7e34
Changed mirror url label
SaschaCowley Sep 3, 2024
a409b51
Improved formatting
SaschaCowley Sep 3, 2024
4929e07
Changed wording of error message to exclude 'metadata' and include th…
SaschaCowley Sep 3, 2024
ddd4492
Updated handling of None type for _do_displayError for greater predic…
SaschaCowley Sep 3, 2024
7e3d2e4
Partial implementation of URL validation
SaschaCowley Sep 3, 2024
716dc9d
Updated validation
SaschaCowley Sep 3, 2024
723775d
Removed unused showTip option
SaschaCowley Sep 3, 2024
9c2ffb1
Replaced custom logic with logic from url_normalize
SaschaCowley Sep 3, 2024
70923f1
Simplified generation of Add-on Store URLs now that we have more cert…
SaschaCowley Sep 3, 2024
94fe401
Apply suggestions from code review
SaschaCowley Sep 3, 2024
3ed8206
Moved _stripAccelleratorFromLabel to guiHelper
SaschaCowley Sep 4, 2024
e25076e
Added explicit dependency on url-normalize
SaschaCowley Sep 4, 2024
183a6f6
Removed unused function
SaschaCowley Sep 5, 2024
eb3afba
Updated label of Add-on Store metadata mirror URL box
SaschaCowley Sep 5, 2024
44d9de7
Merge branch 'master' into addonStoreMirror
SaschaCowley Sep 5, 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
20 changes: 12 additions & 8 deletions source/addonStore/dataManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ def _getCachedAddonData(self, cacheFilePath: str) -> Optional[CachedAddonsModel]
_updateFailureMirrorSuggestion = pgettext(
"addonStore",
# Translators: A suggestion of what to do when fetching add-on data from the store fails and a metadata mirror is being used.
"Make sure you are connected to the internet, and the add-on store metadata mirror URL is valid.",
# {url} will be replaced with the mirror URL.
"Make sure you are connected to the internet, and the add-on store mirror URL is valid.\n"
SaschaCowley marked this conversation as resolved.
Show resolved Hide resolved
"Mirror URL: {url}",
)
_updateFailureDefaultSuggestion = pgettext(
"addonStore",
Expand Down Expand Up @@ -295,25 +297,27 @@ def _do_displayError(
self,
onDisplayableError: "DisplayableError.OnDisplayableErrorT | None",
displayMessage: str,
titleMessage: str | None = _updateFailureMessage,
showTip: bool = True,
titleMessage: str | None = None,
):
"""Display a DisplayableMessage if an OnDisplayableError action is given.

See gui.message.DisplayableError for further information.

:param onDisplayableError: The displayable error action.
:param displayMessage: Body of the displayable error.
:param titleMessage: Title of the displayable error, defaults to _updateFailureMessage.
:param showTip: Whether or not to show a suggestion of what to try, defaults to True.
:param titleMessage: Title of the displayable error. If None, _updateFailureMessage will be used. Defaults to None.
"""
if onDisplayableError is None:
return
from gui.message import DisplayableError

if showTip:
displayMessage += f'\n{self._updateFailureMirrorSuggestion if config.conf["addonStore"]["baseURL"] else self._updateFailureDefaultSuggestion}'
displayableError = DisplayableError(displayMessage, titleMessage)
tip = (
self._updateFailureMirrorSuggestion.format(url=url)
if (url := config.conf["addonStore"]["baseServerURL"])
else self._updateFailureDefaultSuggestion
)
displayMessage = f"{displayMessage}\n{tip}"
displayableError = DisplayableError(displayMessage, titleMessage or self._updateFailureMessage)
callLater(delay=0, callable=onDisplayableError.notify, displayableError=displayableError)

def _deleteCacheInstalledAddon(self, addonId: str):
Expand Down
9 changes: 3 additions & 6 deletions source/addonStore/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
)
import os
import pathlib
import posixpath
import shutil
from typing import (
TYPE_CHECKING,
Expand Down Expand Up @@ -51,7 +50,7 @@


def _getBaseURL() -> str:
if url := conf["addonStore"]["baseURL"]:
if url := conf["addonStore"]["baseServerURL"]:
return url
return _DEFAULT_BASE_URL

Expand All @@ -62,13 +61,11 @@ def _getCurrentApiVersionForURL() -> str:


def _getAddonStoreURL(channel: Channel, lang: str, nvdaApiVersion: str) -> str:
# We don't know whether a user-supplied base url will have a trailing slash, so use posixpath.join, which inserts separators as needed.
return posixpath.join(_getBaseURL(), lang, channel.value, f"{nvdaApiVersion}.json")
return f"{_getBaseURL()}/{lang}/{channel.value}/{nvdaApiVersion}.json"


def _getCacheHashURL() -> str:
# We don't know whether a user-supplied base url will have a trailing slash, so use posixpath.join, which inserts separators as needed.
return posixpath.join(_getBaseURL(), "cacheHash.json")
return f"{_getBaseURL()}/cacheHash.json"


class AddonFileDownloader:
Expand Down
2 changes: 1 addition & 1 deletion source/config/configSpec.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@
[addonStore]
showWarning = boolean(default=true)
automaticUpdates = option("notify", "disabled", default="notify")
baseURL = string(default="")
baseServerURL = string(default="")
"""

#: The configuration specification
Expand Down
2 changes: 0 additions & 2 deletions source/config/validators.py

This file was deleted.

4 changes: 4 additions & 0 deletions source/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -949,3 +949,7 @@ def Notify(self):

def _isDebug():
return config.conf["debugLog"]["gui"]


def _stripAcceleratorFromLabel(label: str) -> str:
return label.replace("&", "", 1)
seanbudd marked this conversation as resolved.
Show resolved Hide resolved
31 changes: 11 additions & 20 deletions source/gui/settingsDialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
Set,
cast,
)
from url_normalize import url_normalize
seanbudd marked this conversation as resolved.
Show resolved Hide resolved
import core
import keyboardHandler
import characterProcessing
Expand Down Expand Up @@ -3133,20 +3134,25 @@ def makeSettings(self, settingsSizer: wx.BoxSizer) -> None:
self.automaticUpdatesComboBox.SetSelection(index)

# Translators: This is the label for a text box in the add-on store settings dialog.
addonMetadataMirrorLabel = _("Metadata &mirror")
self.addonMetadataMirrorLabelText = _("&Mirror URL")
self.addonMetadataMirrorTextbox = sHelper.addLabeledControl(
addonMetadataMirrorLabel,
self.addonMetadataMirrorLabelText,
wx.TextCtrl,
)
self.addonMetadataMirrorTextbox.SetValue(config.conf["addonStore"]["baseURL"])
self.addonMetadataMirrorTextbox.SetValue(config.conf["addonStore"]["baseServerURL"])
self.bindHelpEvent("AddonStoreMetadataMirror", self.addonMetadataMirrorTextbox)
SaschaCowley marked this conversation as resolved.
Show resolved Hide resolved
# self.addonUpdateMirrorTextbox.SetValidator(URLValidator)

def isValid(self) -> bool:
self.addonMetadataMirrorTextbox.SetValue(
url_normalize(self.addonMetadataMirrorTextbox.GetValue().strip()).rstrip("/"),
seanbudd marked this conversation as resolved.
Show resolved Hide resolved
)
return True

def onSave(self):
index = self.automaticUpdatesComboBox.GetSelection()
config.conf["addonStore"]["automaticUpdates"] = [x.value for x in AddonsAutomaticUpdate][index]

config.conf["addonStore"]["baseURL"] = self.addonMetadataMirrorTextbox.Value.strip()
config.conf["addonStore"]["baseServerURL"] = self.addonMetadataMirrorTextbox.Value.strip().rstrip("/")


class TouchInteractionPanel(SettingsPanel):
Expand Down Expand Up @@ -5374,18 +5380,3 @@ def onFilterEditTextChange(self, evt):
self.filter(self.filterEdit.Value)
self._refreshVisibleItems()
evt.Skip()


# class URLValidator(wx.Validator):
# def Clone(self):
# return URLValidator()

# def Validate(self, parent):
# from urllib.parse import urlparse
# textControl = self.GetWindow()
# text = textControl.getValue()
# parsed = urlparse(text)
# isValid = all([parsed.scheme, parsed.netloc])
# if not isValid:
# wx.MessageBox("The mirror URL is invalid")
# return isValid
4 changes: 2 additions & 2 deletions user_docs/en/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

* When editing in Microsoft PowerPoint text boxes, you can now move per sentence with `alt+upArrow`/`alt+downArrow`. (#17015, @LeonarddeR)
* In Mozilla Firefox, NVDA will report the highlighted text when a URL containing a text fragment is visited. (#16910, @jcsteh)
* It is now possible to specify a mirror URL to use for the add-on store. (#14974)
* It is now possible to specify a mirror URL to use for the Add-on Store. (#14974)

### Changes

Expand Down Expand Up @@ -37,7 +37,7 @@ These are breaking API changes.
Please open a GitHub issue if your add-on has an issue with updating to the new API.

* The `addonStore.network.BASE_URL` constant has been removed.
As the add-on store base URL is now configurable directly within NVDA, no replacement is planned.
As the Add-on Store base URL is now configurable directly within NVDA, no replacement is planned. (#17099)

#### Deprecations

Expand Down
6 changes: 3 additions & 3 deletions user_docs/en/userGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -3031,10 +3031,10 @@ For example, for installed beta add-ons, you will only be notified of updates wi
|Notify |Notify when updates are available to add-ons within the same channel |
|Disabled |Do not automatically check for updates to add-ons |

##### Metadata Mirror {#AddonStoreMetadataMirror}
##### Mirror URL {#AddonStoreMetadataMirror}

This option allows you to specify an alternative URL to download add-on metadata from.
This may be of use in locations where access to the NV Access Add-on Store server is slow.
This option allows you to specify an alternative URL to download Add-on Store data from.
This may be of use in locations where access to the NV Access Add-on Store server is slow or unavailable.

Leave this blank to use the default NV Access Add-on Store server.

Expand Down