Skip to content

Commit

Permalink
✨ path kwargs (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
juftin committed Sep 7, 2023
1 parent 78ac32f commit 05cae3e
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 5 deletions.
23 changes: 22 additions & 1 deletion browsr/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

import math
import pathlib
from copy import copy
from dataclasses import dataclass
from os import PathLike
from textwrap import dedent
from typing import Any, ClassVar, Dict, List, Optional, Union

Expand All @@ -24,11 +26,26 @@
from textual.reactive import reactive, var
from textual.widget import Widget
from textual.widgets import Button, DataTable, Static
from upath import UPath

from browsr._config import favorite_themes
from browsr._utils import FileInfo, handle_github_url


class BrowsrPath(UPath):
"""
A UPath object that can be extended with persisted kwargs
"""

__path_kwargs__: ClassVar[Dict[str, Any]] = {}

def __new__(cls, *args: str | PathLike[Any], **kwargs: Any) -> "BrowsrPath":
"""
Create a new BrowsrPath object
"""
return super().__new__(cls, *args, **kwargs, **cls.__path_kwargs__)


@dataclass
class TextualAppContext:
"""
Expand All @@ -39,6 +56,7 @@ class TextualAppContext:
config: Optional[Dict[str, Any]] = None
debug: bool = False
max_file_size: int = 20
kwargs: Optional[Dict[str, Any]] = None

@property
def path(self) -> pathlib.Path:
Expand All @@ -56,8 +74,11 @@ def path(self) -> pathlib.Path:
self.file_path = file_path
if str(self.file_path).endswith("/"):
self.file_path = str(self.file_path)[:-1]
kwargs = self.kwargs or {}
PathClass = copy(BrowsrPath)
PathClass.__path_kwargs__ = kwargs
return (
upath.UPath(self.file_path).resolve()
PathClass(self.file_path).resolve()
if self.file_path
else pathlib.Path.cwd().resolve()
)
Expand Down
32 changes: 30 additions & 2 deletions browsr/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
browsr command line interface
"""

from typing import Optional
from typing import Optional, Tuple

import click
import rich_click
Expand Down Expand Up @@ -43,10 +43,14 @@
help="Enable extra debugging output",
type=click.BOOL,
)
@click.option(
"-k", "--kwargs", multiple=True, help="Key=Value pairs to pass to the filesystem"
)
def browsr(
path: Optional[str],
debug: bool,
max_file_size: int,
kwargs: Tuple[str, ...],
) -> None:
"""
browsr 🗂️ a pleasant file explorer in your terminal
Expand Down Expand Up @@ -107,6 +111,17 @@ def browsr(
browsr az://bucket-name
```
#### Pass Extra Arguments to Cloud Storage
Some cloud storage providers require extra arguments to be passed to the
filesystem. For example, to browse an anonymous S3 bucket, you need to pass
the `anon=True` argument to the filesystem. This can be done with the `-k/--kwargs`
argument.
```shell
browsr s3://anonymous-bucket -k anon=True
```
### GitHub
#### Browse a GitHub repository
Expand Down Expand Up @@ -160,7 +175,20 @@ def browsr(
- **`D`** - Toggle dark mode for the application
- **`X`** - Download the file from cloud storage
"""
config = TextualAppContext(file_path=path, debug=debug, max_file_size=max_file_size)
extra_kwargs = {}
if kwargs:
for kwarg in kwargs:
try:
key, value = kwarg.split("=")
extra_kwargs[key] = value
except ValueError as ve:
raise click.BadParameter(
message=f"Invalid Key/Value pair: `{kwarg}` - must be in the format Key=Value",
param_hint="kwargs",
) from ve
config = TextualAppContext(
file_path=path, debug=debug, max_file_size=max_file_size, kwargs=extra_kwargs
)
app = Browsr(config_object=config)
app.run()

Expand Down
6 changes: 4 additions & 2 deletions browsr/universal_directory_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@

from __future__ import annotations

from typing import ClassVar, Iterable, List, Optional
from typing import ClassVar, Iterable, List, Optional, Type

from textual.binding import BindingType
from textual.widgets._directory_tree import DirEntry
from textual.widgets._tree import TreeNode
from textual_universal_directorytree import UniversalDirectoryTree
from upath import UPath as Path

from browsr._base import vim_cursor_bindings
from browsr._base import BrowsrPath, vim_cursor_bindings


class BrowsrDirectoryTree(UniversalDirectoryTree):
"""
A DirectoryTree that can handle any filesystem.
"""

PATH: Type[BrowsrPath] = BrowsrPath

BINDINGS: ClassVar[List[BindingType]] = [
*UniversalDirectoryTree.BINDINGS,
*vim_cursor_bindings,
Expand Down

0 comments on commit 05cae3e

Please sign in to comment.