Skip to content

Made portable creation through the installer or tools menu more flexible, by allowing system variables in paths#14681

Merged
seanbudd merged 9 commits into
nvaccess:masterfrom
XLTechie:fix14680
Mar 30, 2023
Merged

Made portable creation through the installer or tools menu more flexible, by allowing system variables in paths#14681
seanbudd merged 9 commits into
nvaccess:masterfrom
XLTechie:fix14680

Conversation

@XLTechie

@XLTechie XLTechie commented Feb 28, 2023

Copy link
Copy Markdown
Collaborator

Link to issue number:

Fixes #14680

Summary of the issue:

While it is possible to use system variables (%appdata%, %userprofile%, %temp%, etc.) in the create portable dialog's "browse" sub-dialog, it was not possible to use them in the Create Portable dialog itself. Therefore, when using the installer or the tools menu portable option, one either had to enter full paths, or use the browse dialog to utilize system variables to minimize typing.
For people who create many portables, that can be unnecessary overhead.

Description of user facing changes

It is now possible to use system variables (such as %tmp% or %homepath%) in the path specification while creating portable copies of NVDA.
Additionally, it is no longer necessary to include a drive letter when entering the absolute path to a portable target.

Description of development approach

In gui.installerGUI, there is a method of PortableCreaterDialog class, called onCreatePortable: The path, as entered in the dialog (self.portableDirectoryEdit.Value), was used in this method three times.

  • Created a local variable, expandedPortableDirectory, containing that value, processed through os.path.expandvars().
  • Used that local value throughout the remainder of the method.
  • Added a note to the error which appears if the user doesn't specify an absolute path, stating that system variables may be used.
  • Rephrased the messages asking for the path, and removed the mention of the required drive letter, per NV Access review comments.
  • Replaced a % substitution with a .format() string formatter, in an error dialog.
  • Edited, reformatted, and added missing translator comments.
  • Miscellaneous linting.
    Additional:
  • In gui.installerGUI.doCreatePortable(): Linting, spelling, added translation comments, replaced substitutions with calls to format

A note regarding no longer checking for drive letter in entered absolute path:

While creating a portable copy, we ask the user for an absolute path. In the os.path module's opinion, a path can be absolute without having a drive letter. Therefore, we previously checked and threw an error if the drive letter was missing.
When @seanbudd suggested removing the drive letter notation from absolute path messages, testing without entering one revealed errors that occurred if there was no drive letter, even though it shouldn't technically matter.

Instead, since os.path.isabs has already determined that the path is absolute, we can just add the drive letter if it's missing.
We can do that by calling os.path.abspath, which absolutizes the (probably mostly) already absolute path, by adding a drive letter if it was missing, and any other path components necessary to have a fully qualified path.

Testing strategy:

  • Created portables using variables in their paths, from both the installer and the tools menu.
  • Tested that badly-named variables cause the same error as invalid paths.
  • Absolute paths with no drive letter work as a user would expect.

Known issues with pull request:

None

Change log entries:

New features
It is now possible to use system variables (such as %temp% or %homepath%) in the path specification while creating portable copies of NVDA.

Bug fixes
gui.installerGUI.PortableCreaterDialog.onCreatePortable now properly checks for system variables used in the entered paths of potential portable copies, instead of automatically showing an invalid path error when system variables are used.

Changes
Portable copy creation no longer requires that a drive letter be entered as part of the absolute path.

Code Review Checklist:

  • Pull Request description:
    • description is up to date
    • change log entries
  • Testing:
    • Unit tests
    • System (end to end) tests
    • Manual testing
  • API is compatible with existing add-ons.
  • Documentation:
    • User Documentation
    • Developer / Technical Documentation
    • Context sensitive help for GUI changes
  • UX of all users considered:
    • Speech
    • Braille
    • Low Vision
    • Different web browsers
    • Localization in other languages / culture than English
  • Security precautions taken.

@XLTechie XLTechie marked this pull request as ready for review February 28, 2023 07:18
@XLTechie XLTechie requested a review from a team as a code owner February 28, 2023 07:18
@XLTechie XLTechie requested a review from seanbudd February 28, 2023 07:18

@seanbudd seanbudd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @XLTechie - generally looks good to me, added some notes.

Comment thread source/gui/installerGui.py Outdated
Comment thread source/gui/installerGui.py Outdated
Comment thread source/gui/installerGui.py
@seanbudd seanbudd marked this pull request as draft March 27, 2023 04:27
@XLTechie XLTechie marked this pull request as ready for review March 27, 2023 07:25
@XLTechie

Copy link
Copy Markdown
Collaborator Author

@seanbudd Think I have covered your wishes here. Note that the drive letter is apparently required, per line 431+. I still removed it from the message as you suggested, as I agree it seems redundant to mention given "absolute path".

Comment thread source/gui/installerGui.py Outdated
return
drv=os.path.splitdrive(self.portableDirectoryEdit.Value)[0]
drv = os.path.splitdrive(expandedPortableDirectory)[0]
if drv and not os.path.isdir(drv):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if drv is false-y than this does not trigger, meaning that if there is no drive this continues

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@seanbudd You're right, of course, but perhaps it shouldn't. Because when it does, this little piece of joy happens:

DEBUGWARNING - installer.tryCopyFile (05:39:19.980) - gui.ExecAndPump(<function createPortableCopy at 0x041EBA98>) (11828):
Unable to copy \\?\C:\Program Files (x86)\NVDA\api-ms-win-core-console-l1-1-0.dll, error 3
DEBUGWARNING - gui.ExecAndPump.run (05:39:19.980) - gui.ExecAndPump(<function createPortableCopy at 0x041EBA98>) (11828):
task had errors
Traceback (most recent call last):
  File "gui\__init__.pyc", line 681, in run
  File "installer.pyc", line 671, in createPortableCopy
  File "installer.pyc", line 142, in copyProgramFiles
  File "installer.pyc", line 595, in tryCopyFile
OSError: error 3 copying \\?\C:\Program Files (x86)\NVDA\api-ms-win-core-console-l1-1-0.dll to \\?\\users\luke\desktop\badport\api-ms-win-core-console-l1-1-0.dll
ERROR - gui.installerGui.doCreatePortable (05:39:20.095) - MainThread (22900):
Failed to create portable copy
Traceback (most recent call last):
  File "gui\installerGui.pyc", line 447, in doCreatePortable
  File "gui\__init__.pyc", line 677, in __init__
  File "gui\__init__.pyc", line 681, in run
  File "installer.pyc", line 671, in createPortableCopy
  File "installer.pyc", line 142, in copyProgramFiles
  File "installer.pyc", line 595, in tryCopyFile
OSError: error 3 copying \\?\C:\Program Files (x86)\NVDA\api-ms-win-core-console-l1-1-0.dll to \\?\\users\luke\desktop\badport\api-ms-win-core-console-l1-1-0.dll
IO - speech.speech.speak (05:39:20.175) - MainThread (22900):
Speaking ['Error', 'dialog', 'Failed to create portable copy: error 3 copying \\\\?\\C:\\Program Files (x86)\\NVDA\\api-ms-win-core-console-l1-1-0.dll to \\\\?\\\\users\\luke\\desktop\\badport\\api-ms-win-core-console-l1-1-0.dll', CancellableSpeech (still valid)]
IO - speech.speech.speak (05:39:20.175) - MainThread (22900):
Speaking ['OK', 'button', CancellableSpeech (still valid)]

I hadn't actually attempted the no drive letter thing before now. I will try to get to the bottom of this later today.
Note that the above was generated from current master, not from this PR.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think handling the falsey case similar to an invalid drive should fix this.

@AppVeyorBot

Copy link
Copy Markdown

See test results for failed build of commit 4faba7320c

Luke Davis added 3 commits March 28, 2023 02:19
…ble, by allowing system variables in paths. (#14681)

In the method PortableCreaterDialog.onCreatePortable:
The path, as entered in the dialog (`self.portableDirectoryEdit.Value`), was used in this method three times.
- Created a local variable, `expandedPortableDirectory`, containing that value, processed through `os.path.expandvars()`.
- Used that local value throughout the remainder of the method.
- Removed the mention of drive letter in absolute path messages, per NV Access suggestion.
- Added a note to the error which appears if the user doesn't specify an absolute path, stating that system variables may be used, and giving examples.
- Reformatted a translation comment for the title of that error dialog.
- Replaced a % substitution with a .format() string formatter, in an error dialog.
- Miscellaneous linting.
- Added a few missing translator comments.
…tion comments, replaced substitutions with calls to format
When creating a portable copy, we ask the user for an absolute path.
Since technically a path can be absolute without having a drive letter, we previously checked and threw an error
if the drive letter was missing, even though Windows doesn't require one to be absolute about the path.
Instead, since os.path.isabs has already determined that the path is absolute, all that remains is to
add the drive letter if it's missing.
We can do that by calling os.path.abspath, which absolutizes the (probably mostly) already absolute path,
by adding a drive letter if it was missing, and any other path components necessary to have a pedantically correct path.
@XLTechie XLTechie requested a review from seanbudd March 28, 2023 08:54
@XLTechie

Copy link
Copy Markdown
Collaborator Author

@seanbudd please see revised development approach section of PR comment to explain what I did here and see if this method meets with your approval.

@AppVeyorBot

Copy link
Copy Markdown

See test results for failed build of commit 55b515fe93

Comment thread source/gui/installerGui.py Outdated

@seanbudd seanbudd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approach generally LGTM, just some feedback on a comment

@XLTechie

XLTechie commented Mar 29, 2023 via email

Copy link
Copy Markdown
Collaborator Author

@XLTechie XLTechie requested a review from seanbudd March 29, 2023 06:41
@seanbudd seanbudd merged commit bd9bb48 into nvaccess:master Mar 30, 2023
@nvaccessAuto nvaccessAuto added this to the 2023.2 milestone Mar 30, 2023
@XLTechie

XLTechie commented Mar 30, 2023 via email

Copy link
Copy Markdown
Collaborator Author

@XLTechie XLTechie deleted the fix14680 branch August 3, 2024 00:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create portable dialog should allow use of system variables, as other path entry dialogs in windows do

4 participants