-
-
Notifications
You must be signed in to change notification settings - Fork 532
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cae7f46
commit 28e6fff
Showing
8 changed files
with
540 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import panel as pn\n", | ||
"pn.extension()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"The ``FileSelector`` widget allows browsing the filesystem on the server and selecting one or more files in a directory.\n", | ||
"\n", | ||
"For more information about listening to widget events and laying out widgets refer to the [widgets user guide](../../user_guide/Widgets.ipynb). Alternatively you can learn how to build GUIs by declaring parameters independently of any specific widgets in the [param user guide](../../user_guide/Param.ipynb). To express interactivity entirely using Javascript without the need for a Python server take a look at the [links user guide](../../user_guide/Param.ipynb).\n", | ||
"\n", | ||
"#### Parameters:\n", | ||
"\n", | ||
"For layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb).\n", | ||
"\n", | ||
"##### Core\n", | ||
"\n", | ||
"* **``directory``** (str): The directory to browse (cannot access files above this directory).\n", | ||
"* **``file_pattern``** (str, default='*'): A glob-like query expression to limit the displayed files.\n", | ||
"* **``only_files``** (bool, default=False): Whether to only allow selecting files.\n", | ||
"* **``show_hidden``** (bool, default=False): Whether to show hidden files and directories (starting with a period).\n", | ||
"* **``value``** (list[str]): A list of file names.\n", | ||
"\n", | ||
"##### Display\n", | ||
"\n", | ||
"* **``name``** (str): The title of the widget\n", | ||
"\n", | ||
"___" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"The ``FileSelector`` widget allows exploring the specified directory on the server's filesystem and any directories contained within it. The widget consists of the navigation bar with a number of buttons and the address bar:\n", | ||
"\n", | ||
"* Back (`◀`): Goes to the previous directory\n", | ||
"* Forward (`▶`): Returns to the last directory after navigating back\n", | ||
"* Up (`⬆`): Goes one directory up\n", | ||
"* Address bar: Display the directory to navigate to\n", | ||
"* Enter (`⬇`): Navigates to the directory in the address bar\n", | ||
"\n", | ||
"The actual file selector displays the contents of the current directory, to navigate to a subfolder click on a directory in the file selector and then hit the down arrow (`⬇`) in the navigation bar. Files and folders may be selected by selecting them in the browser on the left and moving them to the right with the arrow buttons:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"files = pn.widgets.FileSelector('~')\n", | ||
"\n", | ||
"files" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"To get the currently selected files simply access the `value` parameter:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"files.value" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.7.5" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 4 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
from __future__ import absolute_import, division, unicode_literals | ||
|
||
import os | ||
import shutil | ||
|
||
from collections import OrderedDict | ||
|
||
import pytest | ||
|
||
from panel.widgets import FileSelector | ||
|
||
@pytest.yield_fixture | ||
def test_dir(): | ||
test_dir = os.path.expanduser('~/test_dir') | ||
os.mkdir(test_dir) | ||
os.mkdir(os.path.expanduser('~/test_dir/subdir1')) | ||
with open(os.path.expanduser('~/test_dir/subdir1/a'), 'a'): | ||
pass | ||
with open(os.path.expanduser('~/test_dir/subdir1/b'), 'a'): | ||
pass | ||
os.mkdir(os.path.expanduser('~/test_dir/subdir2')) | ||
yield test_dir | ||
shutil.rmtree(os.path.expanduser('~/test_dir')) | ||
|
||
|
||
def test_file_selector_init(test_dir): | ||
selector = FileSelector(test_dir) | ||
|
||
assert selector._selector.options == { | ||
'\U0001f4c1subdir1': os.path.join(test_dir, 'subdir1'), | ||
'\U0001f4c1subdir2': os.path.join(test_dir, 'subdir2') | ||
} | ||
|
||
|
||
def test_file_selector_address_bar(test_dir): | ||
selector = FileSelector(test_dir) | ||
|
||
selector._directory.value = os.path.join(test_dir, 'subdir1') | ||
|
||
assert not selector._go.disabled | ||
|
||
selector._go.clicks = 1 | ||
|
||
assert selector._cwd == os.path.join(test_dir, 'subdir1') | ||
assert selector._go.disabled | ||
assert selector._forward.disabled | ||
assert not selector._back.disabled | ||
assert selector._selector.options == { | ||
'a': os.path.join(test_dir, 'subdir1', 'a'), | ||
'b': os.path.join(test_dir, 'subdir1', 'b') | ||
} | ||
|
||
selector._up.clicks = 1 | ||
|
||
selector._selector._lists[False].value = ['subdir1'] | ||
|
||
assert selector._directory.value == os.path.join(test_dir, 'subdir1') | ||
|
||
selector._selector._lists[False].value = [] | ||
|
||
assert selector._directory.value == test_dir | ||
|
||
|
||
def test_file_selector_back_and_forward(test_dir): | ||
selector = FileSelector(test_dir) | ||
|
||
selector._directory.value = os.path.join(test_dir, 'subdir1') | ||
selector._go.clicks = 1 | ||
|
||
assert selector._cwd == os.path.join(test_dir, 'subdir1') | ||
assert not selector._back.disabled | ||
assert selector._forward.disabled | ||
|
||
selector._back.clicks = 1 | ||
|
||
assert selector._cwd == test_dir | ||
assert selector._back.disabled | ||
assert not selector._forward.disabled | ||
|
||
selector._forward.clicks = 1 | ||
|
||
assert selector._cwd == os.path.join(test_dir, 'subdir1') | ||
|
||
|
||
def test_file_selector_up(test_dir): | ||
selector = FileSelector(test_dir) | ||
|
||
selector._directory.value = os.path.join(test_dir, 'subdir1') | ||
selector._go.clicks = 1 | ||
|
||
assert selector._cwd == os.path.join(test_dir, 'subdir1') | ||
|
||
selector._up.clicks = 1 | ||
|
||
assert selector._cwd == test_dir | ||
|
||
|
||
def test_file_selector_select_files(test_dir): | ||
selector = FileSelector(test_dir) | ||
|
||
selector._directory.value = os.path.join(test_dir, 'subdir1') | ||
selector._go.clicks = 1 | ||
|
||
selector._selector._lists[False].value = ['a'] | ||
selector._selector._buttons[True].clicks = 1 | ||
|
||
assert selector.value == [os.path.join(test_dir, 'subdir1', 'a')] | ||
|
||
selector._selector._lists[False].value = ['b'] | ||
selector._selector._buttons[True].clicks = 2 | ||
|
||
assert selector.value == [ | ||
os.path.join(test_dir, 'subdir1', 'a'), | ||
os.path.join(test_dir, 'subdir1', 'b') | ||
] | ||
|
||
selector._selector._lists[True].value = ['a', 'b'] | ||
selector._selector._buttons[False].clicks = 2 | ||
|
||
assert selector.value == [] | ||
|
||
|
||
def test_file_selector_only_files(test_dir): | ||
selector = FileSelector(test_dir, only_files=True) | ||
|
||
selector._selector._lists[False].value = ['\U0001f4c1subdir1'] | ||
selector._selector._buttons[True].clicks = 1 | ||
|
||
assert selector.value == [] | ||
assert selector._selector._lists[False].options == ['\U0001f4c1subdir1', '\U0001f4c1subdir2'] | ||
|
||
|
||
def test_file_selector_file_pattern(test_dir): | ||
selector = FileSelector(test_dir, file_pattern='a') | ||
|
||
selector._directory.value = os.path.join(test_dir, 'subdir1') | ||
selector._go.clicks = 1 | ||
|
||
assert selector._selector._lists[False].options == ['a'] | ||
|
||
|
||
def test_file_selector_multiple_across_dirs(test_dir): | ||
selector = FileSelector(test_dir) | ||
|
||
selector._selector._lists[False].value = ['\U0001f4c1subdir2'] | ||
selector._selector._buttons[True].clicks = 1 | ||
|
||
assert selector.value == [os.path.join(test_dir, 'subdir2')] | ||
|
||
selector._directory.value = os.path.join(test_dir, 'subdir1') | ||
selector._go.clicks = 1 | ||
|
||
selector._selector._lists[False].value = ['a'] | ||
selector._selector._buttons[True].clicks = 2 | ||
|
||
assert selector.value == [os.path.join(test_dir, 'subdir2'), | ||
os.path.join(test_dir, 'subdir1', 'a')] | ||
|
||
selector._selector._lists[True].value = ['\U0001f4c1'+os.path.join('..', 'subdir2')] | ||
selector._selector._buttons[False].clicks = 1 | ||
|
||
assert selector._selector.options == OrderedDict([ | ||
('a', os.path.join(test_dir, 'subdir1', 'a')), | ||
('b', os.path.join(test_dir, 'subdir1', 'b')) | ||
]) | ||
assert selector._selector._lists[False].options == ['b'] | ||
assert selector.value == [os.path.join(test_dir, 'subdir1', 'a')] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.