From 22499c913949c1da5476653e1d832c328bc968c3 Mon Sep 17 00:00:00 2001 From: "Bess L. Walker" Date: Sat, 25 Apr 2020 17:07:50 -0600 Subject: [PATCH] Fix Issue 553: Handle Windows volume labels correctly in MultiDirChooser. If running on a Windows system, strips volume labels from directory path to leave only the drive letter. This path can then be ingested by other functionality that expects valid paths. --- gooey/gui/components/widgets/core/chooser.py | 21 ++++++++++---- gooey/tests/test_chooser_results.py | 29 ++++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 gooey/tests/test_chooser_results.py diff --git a/gooey/gui/components/widgets/core/chooser.py b/gooey/gui/components/widgets/core/chooser.py index e3fc022..fea5db6 100644 --- a/gooey/gui/components/widgets/core/chooser.py +++ b/gooey/gui/components/widgets/core/chooser.py @@ -1,6 +1,8 @@ import wx import wx.lib.agw.multidirdialog as MDD import os +import pathlib +import re from gooey.gui.components.widgets.core.text_input import TextInput from gooey.gui.components.widgets.dialogs.calender_dialog import CalendarDlg @@ -82,7 +84,7 @@ class MultiFileChooser(Chooser): wildcard=options.get('wildcard', wx.FileSelectorDefaultWildcardStr)) def getResult(self, dialog): - return os.pathsep.join(dialog.GetPaths()) + return os.pathsep.join(dialog.GetPaths()) class FileSaver(Chooser): @@ -107,7 +109,7 @@ class DirChooser(Chooser): defaultPath=options.get('default_path', os.getcwd())) class MultiDirChooser(Chooser): - """ Retrieve an multiple directories from the system """ + """ Retrieve multiple directories from the system """ def getDialog(self): options = self.Parent._options return MDD.MultiDirDialog(self, @@ -116,7 +118,18 @@ class MultiDirChooser(Chooser): defaultPath=options.get('default_path', os.getcwd()), agwStyle=MDD.DD_MULTIPLE | MDD.DD_DIR_MUST_EXIST) def getResult(self, dialog): - return os.pathsep.join(dialog.GetPaths()) + paths = dialog.GetPaths() + # Remove volume labels from Windows paths + if 'nt' == os.name: + for i, path in enumerate(paths): + if path: + purepath = pathlib.PurePath(path) + parts = purepath.parts + vol = parts[0] + drives = re.match(r'.*\((?P\w:)\)', vol) + paths[i] = os.sep.join((drives.group('drive'),) + parts[1:]) + + return os.pathsep.join(paths) class DateChooser(Chooser): @@ -154,5 +167,3 @@ class ColourChooser(Chooser): def getDialog(self): return wx.ColourDialog(self) - - diff --git a/gooey/tests/test_chooser_results.py b/gooey/tests/test_chooser_results.py new file mode 100644 index 0000000..b59e083 --- /dev/null +++ b/gooey/tests/test_chooser_results.py @@ -0,0 +1,29 @@ +import argparse +import os +import unittest + +from unittest.mock import patch +from gooey.gui.components.widgets.core import chooser + +class TestChooserResults(unittest.TestCase): + + @patch('gooey.gui.components.widgets.core.chooser.MDD') + def test_multiDirChooserGetResult(self, mockWxMDD): + + expected_outputs = [ + (None, "", [""]), + + # Windows + ('nt', "C:", ["OS and System (C:)"]), + ('nt', "D:\\A Folder\\Yep Another One", + ["Other Stuff (D:)\\A Folder\\Yep Another One"]), + ('nt', "A:\\Wow Remember Floppy Drives;E:\\Righto Then", + ["Flipflop (A:)\\Wow Remember Floppy Drives", + "Elephants Only (E:)\\Righto Then"]) + ] + + for osname, expected, pathsoutput in expected_outputs: + if osname and osname == os.name: + mockWxMDD.GetPaths.return_value = pathsoutput + result = chooser.MultiDirChooser.getResult(None, mockWxMDD) + self.assertEqual(result, expected)