plex-tui 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- plex_tui-0.2.0.dist-info/METADATA +226 -0
- plex_tui-0.2.0.dist-info/RECORD +15 -0
- plex_tui-0.2.0.dist-info/WHEEL +4 -0
- plex_tui-0.2.0.dist-info/entry_points.txt +2 -0
- plex_tui-0.2.0.dist-info/licenses/LICENSE +21 -0
- plextui/__init__.py +3 -0
- plextui/__main__.py +40 -0
- plextui/app.py +2248 -0
- plextui/artwork.py +158 -0
- plextui/auth.py +93 -0
- plextui/config.py +200 -0
- plextui/models.py +36 -0
- plextui/player.py +519 -0
- plextui/plex_service.py +344 -0
- plextui/smoke.py +18 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: plex-tui
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A small standalone Plex terminal UI.
|
|
5
|
+
Project-URL: Homepage, https://github.com/so1omon563/plex-tui
|
|
6
|
+
Project-URL: Issues, https://github.com/so1omon563/plex-tui/issues
|
|
7
|
+
Project-URL: Repository, https://github.com/so1omon563/plex-tui
|
|
8
|
+
Author: so1omon
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: mpv,plex,textual,tui
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Topic :: Multimedia :: Video
|
|
24
|
+
Classifier: Topic :: Terminals
|
|
25
|
+
Requires-Python: >=3.11
|
|
26
|
+
Requires-Dist: pillow>=10.0
|
|
27
|
+
Requires-Dist: platformdirs>=4.2
|
|
28
|
+
Requires-Dist: plexapi>=4.15
|
|
29
|
+
Requires-Dist: textual>=0.86
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
32
|
+
Requires-Dist: hatchling>=1.25; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: twine>=5.0; extra == 'dev'
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# plex-tui
|
|
38
|
+
|
|
39
|
+
A standalone Python/Textual terminal UI for browsing Plex and launching playback
|
|
40
|
+
through `mpv`.
|
|
41
|
+
|
|
42
|
+
plex-tui is currently an early release. It supports Plex login, server
|
|
43
|
+
selection, paged library browsing, search, list/grid views, stream preferences,
|
|
44
|
+
terminal poster artwork, and playback progress reporting.
|
|
45
|
+
|
|
46
|
+
## Screenshots
|
|
47
|
+
|
|
48
|
+
### Grid view
|
|
49
|
+
|
|
50
|
+

|
|
51
|
+
|
|
52
|
+
### List view
|
|
53
|
+
|
|
54
|
+

|
|
55
|
+
|
|
56
|
+
## Requirements
|
|
57
|
+
|
|
58
|
+
- Python 3.11 or newer
|
|
59
|
+
- `mpv` available on `PATH`
|
|
60
|
+
- A Plex account/server
|
|
61
|
+
|
|
62
|
+
Install `mpv` with your platform package manager:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# macOS
|
|
66
|
+
brew install mpv
|
|
67
|
+
|
|
68
|
+
# Debian / Ubuntu
|
|
69
|
+
sudo apt install mpv
|
|
70
|
+
|
|
71
|
+
# Fedora
|
|
72
|
+
sudo dnf install mpv
|
|
73
|
+
|
|
74
|
+
# Arch Linux / Manjaro
|
|
75
|
+
sudo pacman -S mpv
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Install
|
|
79
|
+
|
|
80
|
+
The README tracks the current `main` branch. Tagged releases are available on
|
|
81
|
+
the GitHub Releases page.
|
|
82
|
+
|
|
83
|
+
The recommended install path for the latest `main` branch is `pipx`:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pipx install "git+https://github.com/so1omon563/plex-tui.git"
|
|
87
|
+
plex-tui --smoke
|
|
88
|
+
plex-tui
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
To install the latest tagged release instead:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pipx install "git+https://github.com/so1omon563/plex-tui.git@v0.2.0"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Useful CLI checks:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
plex-tui --version
|
|
101
|
+
plex-tui --config-path
|
|
102
|
+
plex-tui --debug-log-path
|
|
103
|
+
plex-tui --smoke
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
For local development:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
git clone https://github.com/so1omon563/plex-tui.git
|
|
110
|
+
cd plex-tui
|
|
111
|
+
python3 -m venv .venv
|
|
112
|
+
source .venv/bin/activate
|
|
113
|
+
make install-dev
|
|
114
|
+
make run
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## First Run & Configuration
|
|
118
|
+
|
|
119
|
+
On first run, plex-tui starts a Plex browser login and asks which server
|
|
120
|
+
connection to save. If a browser cannot be opened, use the login URL shown in
|
|
121
|
+
the terminal.
|
|
122
|
+
|
|
123
|
+
You can also configure a server manually. macOS config path:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
mkdir -p "$HOME/Library/Application Support/plex-tui"
|
|
127
|
+
$EDITOR "$HOME/Library/Application Support/plex-tui/config.toml"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Linux config path:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
mkdir -p "$HOME/.config/plex-tui"
|
|
134
|
+
$EDITOR "$HOME/.config/plex-tui/config.toml"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Minimal config:
|
|
138
|
+
|
|
139
|
+
```toml
|
|
140
|
+
base_url = "http://127.0.0.1:32400"
|
|
141
|
+
token = "your-plex-token"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Environment variables also work:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
export PLEX_TUI_BASE_URL="http://127.0.0.1:32400"
|
|
148
|
+
export PLEX_TUI_TOKEN="your-plex-token"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
See `config.example.toml` for optional settings.
|
|
152
|
+
|
|
153
|
+
## Key Bindings
|
|
154
|
+
|
|
155
|
+
| Key | Action |
|
|
156
|
+
| --- | --- |
|
|
157
|
+
| `q` | Quit |
|
|
158
|
+
| `r` | Reload Plex connection |
|
|
159
|
+
| `/` | Search current library |
|
|
160
|
+
| `g` | Search all libraries |
|
|
161
|
+
| `?` | Show help |
|
|
162
|
+
| `tab` / `shift+tab` | Move focus |
|
|
163
|
+
| `l` | Focus libraries |
|
|
164
|
+
| `m` | Focus media |
|
|
165
|
+
| `v` | Toggle list/grid view |
|
|
166
|
+
| `pageup` / `pagedown` | Move one page in grid view |
|
|
167
|
+
| `,` | Show settings |
|
|
168
|
+
| `escape` | Clear search, go back, or close current view |
|
|
169
|
+
| `enter` | Open selected item |
|
|
170
|
+
| `p` | Play selected item with `mpv` |
|
|
171
|
+
| `a` / `s` | Choose audio / subtitle preference |
|
|
172
|
+
| `A` / `S` | Clear audio preference / cycle subtitle mode |
|
|
173
|
+
| `x` | Stop launched `mpv` |
|
|
174
|
+
|
|
175
|
+
## Features
|
|
176
|
+
|
|
177
|
+
- Plex PIN login and server selection.
|
|
178
|
+
- Paged library browsing with automatic loading near the end of loaded items.
|
|
179
|
+
- Current-library search and bounded global search.
|
|
180
|
+
- List view plus configurable-density grid view with terminal poster artwork.
|
|
181
|
+
- External subtitle support and direct playback for embedded PGS/VOBSUB tracks.
|
|
182
|
+
- Audio and subtitle pickers with saved language preferences.
|
|
183
|
+
- Plex resume support and playback progress reporting.
|
|
184
|
+
- Settings screen for stream preferences, artwork modes, grid density, page
|
|
185
|
+
size, auto-load threshold, media view, and `mpv` window size.
|
|
186
|
+
|
|
187
|
+
## Artwork
|
|
188
|
+
|
|
189
|
+
Poster artwork renders as portable colored block art, so it works in ordinary
|
|
190
|
+
terminals without Kitty, iTerm2, or Sixel support. Native terminal image output
|
|
191
|
+
is disabled for now because Kitty protocol rendering conflicts with Textual's
|
|
192
|
+
screen renderer in practice.
|
|
193
|
+
|
|
194
|
+
Grid view prefetches artwork for the visible page immediately and the next page
|
|
195
|
+
after selection settles. Compact, comfortable, and large density modes adjust
|
|
196
|
+
card and poster sizing. The artwork cache is bounded and stored in the app cache
|
|
197
|
+
directory shown in Settings.
|
|
198
|
+
|
|
199
|
+
## Diagnostics
|
|
200
|
+
|
|
201
|
+
Playback diagnostics are written to `debug.log` in the app config directory.
|
|
202
|
+
Tokens are redacted from logged `mpv` arguments.
|
|
203
|
+
|
|
204
|
+
Enable browsing performance timings before launch:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
PLEX_TUI_PERF_LOG=1 plex-tui
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Development
|
|
211
|
+
|
|
212
|
+
Common commands:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
make smoke # app construction and helper sanity check
|
|
216
|
+
make test # pytest suite
|
|
217
|
+
make compile # compile src and tests
|
|
218
|
+
make check-package # build and validate package metadata
|
|
219
|
+
make check # smoke, tests, compile, package validation
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Packaging and release docs:
|
|
223
|
+
|
|
224
|
+
- `PACKAGING.md`: PyPI/pipx, Homebrew, AUR, and standalone packaging options.
|
|
225
|
+
- `RELEASE.md`: release validation and tagging checklist.
|
|
226
|
+
- `ROADMAP.md`: planned follow-up work.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
plextui/__init__.py,sha256=KoIxqoEZUN29iwAW7enbscYOmShn1940xgrMYzuoYys,49
|
|
2
|
+
plextui/__main__.py,sha256=njeqVaS4cJgkE38PkVvElncRnZ_ZRnaYQVHHaGIIZ2k,1204
|
|
3
|
+
plextui/app.py,sha256=wRmleQIdTqmJ2ksdBWfYAQinbdN-Trft71xVWJU_0CI,86456
|
|
4
|
+
plextui/artwork.py,sha256=51lJ32BpSnxab_EO16Q6iPDTRGSudKLk59X2_1CG4JQ,4894
|
|
5
|
+
plextui/auth.py,sha256=01RFv7ZYLTJ00THG0MClEKlanwpD8RulixXLpFVUOOI,3082
|
|
6
|
+
plextui/config.py,sha256=l7sYUo5yMlDBqhmA4Pl6Yu2nnC8QAt2OKMtVw3CNjjU,7827
|
|
7
|
+
plextui/models.py,sha256=1AAuLb8Rq_OGAP9OLGzGYr44feOXhvh9MI7Qo9aXghM,596
|
|
8
|
+
plextui/player.py,sha256=JiB9oxBLwjSXNc0RH8--Sg5rru4n-JN1n4omHOAyAHE,16732
|
|
9
|
+
plextui/plex_service.py,sha256=9dYdANWvuH0y43o_vzYYgSJjCF_-qrjxL8zpcc7aYgg,11075
|
|
10
|
+
plextui/smoke.py,sha256=wupF_h1XbhY_2f6MYySpO8XWqM5o-xJ-bgGbxEVUhdQ,464
|
|
11
|
+
plex_tui-0.2.0.dist-info/METADATA,sha256=CpgDp0xJiHuyYUI6ONwyccX-FB8yq_Ngv4KLw2SWzyY,6155
|
|
12
|
+
plex_tui-0.2.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
13
|
+
plex_tui-0.2.0.dist-info/entry_points.txt,sha256=hAfV65WPB5vSNKjaeczIx3FeNBVibUU5-VW9wClsESo,51
|
|
14
|
+
plex_tui-0.2.0.dist-info/licenses/LICENSE,sha256=swDfS5Q2963nh1oznYcj1-V20ni6fSjnAwRjZx7ULyY,1064
|
|
15
|
+
plex_tui-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 so1omon
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
plextui/__init__.py
ADDED
plextui/__main__.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
from collections.abc import Sequence
|
|
5
|
+
|
|
6
|
+
from . import __version__
|
|
7
|
+
from .config import config_path, debug_log_path
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
11
|
+
parser = argparse.ArgumentParser(description="Browse Plex from a terminal UI.")
|
|
12
|
+
parser.add_argument("--version", action="version", version=f"plex-tui {__version__}")
|
|
13
|
+
parser.add_argument("--config-path", action="store_true", help="print the active config file path and exit")
|
|
14
|
+
parser.add_argument("--debug-log-path", action="store_true", help="print the debug log path and exit")
|
|
15
|
+
parser.add_argument("--smoke", action="store_true", help="run the built-in smoke check and exit")
|
|
16
|
+
return parser
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def main(argv: Sequence[str] | None = None) -> int:
|
|
20
|
+
args = build_parser().parse_args(argv)
|
|
21
|
+
if args.config_path:
|
|
22
|
+
print(config_path())
|
|
23
|
+
return 0
|
|
24
|
+
if args.debug_log_path:
|
|
25
|
+
print(debug_log_path())
|
|
26
|
+
return 0
|
|
27
|
+
if args.smoke:
|
|
28
|
+
from .smoke import main as smoke_main
|
|
29
|
+
|
|
30
|
+
smoke_main()
|
|
31
|
+
return 0
|
|
32
|
+
|
|
33
|
+
from .app import PlexTuiApp
|
|
34
|
+
|
|
35
|
+
PlexTuiApp().run()
|
|
36
|
+
return 0
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
if __name__ == "__main__":
|
|
40
|
+
raise SystemExit(main())
|