plex-tui 0.4.0__tar.gz → 0.4.2__tar.gz
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.4.0 → plex_tui-0.4.2}/CHANGELOG.md +11 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/PKG-INFO +8 -6
- {plex_tui-0.4.0 → plex_tui-0.4.2}/README.md +7 -5
- {plex_tui-0.4.0 → plex_tui-0.4.2}/ROADMAP.md +8 -1
- {plex_tui-0.4.0 → plex_tui-0.4.2}/config.example.toml +3 -2
- {plex_tui-0.4.0 → plex_tui-0.4.2}/packaging/aur/.SRCINFO +3 -3
- {plex_tui-0.4.0 → plex_tui-0.4.2}/packaging/aur/PKGBUILD +2 -2
- {plex_tui-0.4.0 → plex_tui-0.4.2}/pyproject.toml +1 -1
- {plex_tui-0.4.0 → plex_tui-0.4.2}/src/plextui/__init__.py +1 -1
- {plex_tui-0.4.0 → plex_tui-0.4.2}/src/plextui/artwork.py +12 -4
- {plex_tui-0.4.0 → plex_tui-0.4.2}/src/plextui/plex_service.py +7 -1
- {plex_tui-0.4.0 → plex_tui-0.4.2}/tests/test_artwork.py +28 -5
- {plex_tui-0.4.0 → plex_tui-0.4.2}/tests/test_plex_service.py +48 -1
- {plex_tui-0.4.0 → plex_tui-0.4.2}/.github/workflows/aur.yml +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/.github/workflows/bump.yml +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/.github/workflows/ci.yml +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/.github/workflows/post-release-aur.yml +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/.github/workflows/post-release-homebrew.yml +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/.github/workflows/publish-aur.yml +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/.github/workflows/publish-pypi.yml +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/.github/workflows/publish-testpypi.yml +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/.gitignore +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/AGENTS.md +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/LICENSE +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/Makefile +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/PACKAGING.md +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/RELEASE.md +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/docs/assets/grid-view.png +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/docs/assets/list-view.png +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/docs/plex-integration-research.md +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/packaging/aur/README.md +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/packaging/homebrew/README.md +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/scripts/check_release.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/scripts/stage_release.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/scripts/update_aur_package.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/scripts/update_homebrew_formula.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/src/plextui/__main__.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/src/plextui/app.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/src/plextui/auth.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/src/plextui/config.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/src/plextui/models.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/src/plextui/player.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/src/plextui/smoke.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/tests/test_app_helpers.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/tests/test_app_navigation.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/tests/test_auth.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/tests/test_cli.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/tests/test_config.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/tests/test_player.py +0 -0
- {plex_tui-0.4.0 → plex_tui-0.4.2}/tests/test_release_checks.py +0 -0
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.4.2 - 2026-06-18
|
|
6
|
+
|
|
7
|
+
- Prefer episode stills and season posters for TV artwork while keeping show art
|
|
8
|
+
as the fallback.
|
|
9
|
+
|
|
10
|
+
## 0.4.1 - 2026-06-18
|
|
11
|
+
|
|
12
|
+
- Let explicit `artwork_renderer = "kitty"` try Kitty graphics even when
|
|
13
|
+
Kitty-specific environment variables are absent, and let `auto` enable the
|
|
14
|
+
Kitty graphics path in Ghostty.
|
|
15
|
+
|
|
5
16
|
## 0.4.0 - 2026-06-17
|
|
6
17
|
|
|
7
18
|
- Added native Kitty poster artwork via Unicode placeholders for terminals that
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plex-tui
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: A small standalone Plex terminal UI.
|
|
5
5
|
Project-URL: Homepage, https://github.com/so1omon563/plex-tui
|
|
6
6
|
Project-URL: Issues, https://github.com/so1omon563/plex-tui/issues
|
|
@@ -247,11 +247,13 @@ presets.
|
|
|
247
247
|
## Artwork
|
|
248
248
|
|
|
249
249
|
Poster artwork renders as portable colored block art by default, so it works in
|
|
250
|
-
ordinary terminals without native image support. In Kitty, set
|
|
251
|
-
`artwork_renderer` to `auto`
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
250
|
+
ordinary terminals without native image support. In Kitty and Ghostty, set
|
|
251
|
+
`artwork_renderer` to `auto` to render native terminal images through Kitty
|
|
252
|
+
Unicode placeholders. Set `artwork_renderer` to `kitty` to explicitly try the
|
|
253
|
+
Kitty graphics protocol in other compatible terminals. This keeps Textual in
|
|
254
|
+
charge of layout and redraws while the terminal paints the poster inside those
|
|
255
|
+
cells. Outside detected Kitty-compatible terminals, `auto` falls back to block
|
|
256
|
+
art; `plex-tui --diagnostics` reports the active renderer status.
|
|
255
257
|
|
|
256
258
|
Grid view prefetches artwork for the visible page immediately and, by default,
|
|
257
259
|
prepares three pages ahead in the background. `grid_prefetch_pages` can be set
|
|
@@ -210,11 +210,13 @@ presets.
|
|
|
210
210
|
## Artwork
|
|
211
211
|
|
|
212
212
|
Poster artwork renders as portable colored block art by default, so it works in
|
|
213
|
-
ordinary terminals without native image support. In Kitty, set
|
|
214
|
-
`artwork_renderer` to `auto`
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
213
|
+
ordinary terminals without native image support. In Kitty and Ghostty, set
|
|
214
|
+
`artwork_renderer` to `auto` to render native terminal images through Kitty
|
|
215
|
+
Unicode placeholders. Set `artwork_renderer` to `kitty` to explicitly try the
|
|
216
|
+
Kitty graphics protocol in other compatible terminals. This keeps Textual in
|
|
217
|
+
charge of layout and redraws while the terminal paints the poster inside those
|
|
218
|
+
cells. Outside detected Kitty-compatible terminals, `auto` falls back to block
|
|
219
|
+
art; `plex-tui --diagnostics` reports the active renderer status.
|
|
218
220
|
|
|
219
221
|
Grid view prefetches artwork for the visible page immediately and, by default,
|
|
220
222
|
prepares three pages ahead in the background. `grid_prefetch_pages` can be set
|
|
@@ -65,5 +65,12 @@
|
|
|
65
65
|
artwork, pagination, or detail-loading behavior.
|
|
66
66
|
- Revisit whether verbose `PLEX_TUI_ARTWORK_LOG=1` should expose more structured artwork counters.
|
|
67
67
|
- Continue validating Kitty Unicode-placeholder artwork in real terminals.
|
|
68
|
-
Block art remains the mandatory fallback outside
|
|
68
|
+
Block art remains the mandatory fallback outside known native-image paths.
|
|
69
|
+
- Continue expanding Kitty graphics support beyond Kitty itself after the
|
|
70
|
+
initial Ghostty path. `artwork_renderer = "kitty"` is the explicit "try Kitty
|
|
71
|
+
protocol" override, while `auto` should stay conservative until terminal
|
|
72
|
+
support is verified.
|
|
73
|
+
- Research explicit iTerm inline-image protocol support as a separate renderer
|
|
74
|
+
path rather than assuming iTerm speaks Kitty graphics. Include WezTerm in that
|
|
75
|
+
research because its documented image path follows the iTerm image protocol.
|
|
69
76
|
- Add focused regression tests for any real-world Plex media edge cases discovered during use.
|
|
@@ -40,8 +40,9 @@ client_identifier = "plex-tui-your-stable-client-id"
|
|
|
40
40
|
# Optional artwork settings.
|
|
41
41
|
# artwork_mode can be "on" or "off".
|
|
42
42
|
# artwork_mode = "on"
|
|
43
|
-
# artwork_renderer can be "block", "auto", or "kitty". Auto uses
|
|
44
|
-
#
|
|
43
|
+
# artwork_renderer can be "block", "auto", or "kitty". Auto uses Kitty graphics
|
|
44
|
+
# in detected compatible terminals such as Kitty and Ghostty, otherwise it falls
|
|
45
|
+
# back to block art. "kitty" explicitly tries the Kitty graphics protocol.
|
|
45
46
|
# artwork_renderer = "block"
|
|
46
47
|
# detail_artwork_mode can be "list_only", "on", or "off".
|
|
47
48
|
# detail_artwork_mode = "list_only"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
pkgbase = plex-tui
|
|
2
2
|
pkgdesc = Standalone Plex terminal UI with mpv playback
|
|
3
|
-
pkgver = 0.
|
|
3
|
+
pkgver = 0.4.1
|
|
4
4
|
pkgrel = 1
|
|
5
5
|
url = https://github.com/so1omon563/plex-tui
|
|
6
6
|
arch = any
|
|
@@ -16,7 +16,7 @@ pkgbase = plex-tui
|
|
|
16
16
|
depends = python-plexapi
|
|
17
17
|
depends = python-rich
|
|
18
18
|
depends = python-textual
|
|
19
|
-
source = plex-tui-0.
|
|
20
|
-
sha256sums =
|
|
19
|
+
source = plex-tui-0.4.1.tar.gz::https://github.com/so1omon563/plex-tui/archive/refs/tags/v0.4.1.tar.gz
|
|
20
|
+
sha256sums = 2271c6413ec204ba1250b812e6b9e98af37afaeb44006d5c17fb0f82cf419282
|
|
21
21
|
|
|
22
22
|
pkgname = plex-tui
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Maintainer: so1omon
|
|
2
2
|
pkgname=plex-tui
|
|
3
|
-
pkgver=0.
|
|
3
|
+
pkgver=0.4.1
|
|
4
4
|
pkgrel=1
|
|
5
5
|
pkgdesc="Standalone Plex terminal UI with mpv playback"
|
|
6
6
|
arch=("any")
|
|
@@ -22,7 +22,7 @@ makedepends=(
|
|
|
22
22
|
"python-wheel"
|
|
23
23
|
)
|
|
24
24
|
source=("$pkgname-$pkgver.tar.gz::$url/archive/refs/tags/v$pkgver.tar.gz")
|
|
25
|
-
sha256sums=("
|
|
25
|
+
sha256sums=("2271c6413ec204ba1250b812e6b9e98af37afaeb44006d5c17fb0f82cf419282")
|
|
26
26
|
|
|
27
27
|
build() {
|
|
28
28
|
cd "$pkgname-$pkgver"
|
|
@@ -210,7 +210,7 @@ def render_protocol_artwork(data: bytes, renderer: str, width: int = 28, max_hei
|
|
|
210
210
|
|
|
211
211
|
|
|
212
212
|
def resolve_protocol_renderer(renderer: str) -> str:
|
|
213
|
-
if renderer == "kitty"
|
|
213
|
+
if renderer == "kitty":
|
|
214
214
|
return "kitty"
|
|
215
215
|
if renderer == "auto" and kitty_graphics_supported():
|
|
216
216
|
return "kitty"
|
|
@@ -222,20 +222,28 @@ def protocol_renderer_status(renderer: str) -> str:
|
|
|
222
222
|
if resolved == "kitty":
|
|
223
223
|
return "Kitty native images via Unicode placeholders"
|
|
224
224
|
if renderer == "auto":
|
|
225
|
-
return "Block art; Kitty terminal not detected"
|
|
225
|
+
return "Block art; Kitty-compatible terminal not detected"
|
|
226
226
|
if renderer == "kitty":
|
|
227
|
-
return "
|
|
227
|
+
return "Kitty native images via Unicode placeholders"
|
|
228
228
|
return "Block art"
|
|
229
229
|
|
|
230
230
|
|
|
231
231
|
def kitty_graphics_supported() -> bool:
|
|
232
|
-
return bool(os.environ.get("KITTY_WINDOW_ID") or os.environ.get("KITTY_PID"))
|
|
232
|
+
return bool(os.environ.get("KITTY_WINDOW_ID") or os.environ.get("KITTY_PID") or ghostty_terminal_detected())
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def ghostty_terminal_detected() -> bool:
|
|
236
|
+
term_program = os.environ.get("TERM_PROGRAM", "").lower()
|
|
237
|
+
term = os.environ.get("TERM", "").lower()
|
|
238
|
+
return term_program == "ghostty" or term.startswith("xterm-ghostty")
|
|
233
239
|
|
|
234
240
|
|
|
235
241
|
def kitty_environment_status() -> str:
|
|
236
242
|
fields = [
|
|
237
243
|
f"KITTY_WINDOW_ID={int(bool(os.environ.get('KITTY_WINDOW_ID')))}",
|
|
238
244
|
f"KITTY_PID={int(bool(os.environ.get('KITTY_PID')))}",
|
|
245
|
+
f"TERM_PROGRAM={os.environ.get('TERM_PROGRAM', '')!r}",
|
|
246
|
+
f"TERM_PROGRAM_VERSION={os.environ.get('TERM_PROGRAM_VERSION', '')!r}",
|
|
239
247
|
f"TERM={os.environ.get('TERM', '')!r}",
|
|
240
248
|
f"COLORTERM={os.environ.get('COLORTERM', '')!r}",
|
|
241
249
|
]
|
|
@@ -226,7 +226,13 @@ def media_details(item: MediaItem) -> MediaDetails:
|
|
|
226
226
|
|
|
227
227
|
|
|
228
228
|
def artwork_path(raw: Any) -> str:
|
|
229
|
-
|
|
229
|
+
kind = str(getattr(raw, "TYPE", raw.__class__.__name__)).lower()
|
|
230
|
+
attrs = (
|
|
231
|
+
("thumb", "parentThumb", "grandparentThumb", "art")
|
|
232
|
+
if kind in {"show", "season", "episode"}
|
|
233
|
+
else ("grandparentThumb", "parentThumb", "thumb", "art")
|
|
234
|
+
)
|
|
235
|
+
for attr in attrs:
|
|
230
236
|
value = getattr(raw, attr, None)
|
|
231
237
|
if value:
|
|
232
238
|
return str(value)
|
|
@@ -80,16 +80,20 @@ def test_render_artwork_returns_halfcell_text():
|
|
|
80
80
|
assert rendered.spans
|
|
81
81
|
|
|
82
82
|
|
|
83
|
-
def
|
|
83
|
+
def test_render_protocol_artwork_tries_kitty_when_explicitly_enabled(monkeypatch):
|
|
84
84
|
monkeypatch.delenv("KITTY_WINDOW_ID", raising=False)
|
|
85
85
|
monkeypatch.delenv("KITTY_PID", raising=False)
|
|
86
|
+
monkeypatch.delenv("TERM_PROGRAM", raising=False)
|
|
87
|
+
transmitted = []
|
|
88
|
+
monkeypatch.setattr(artwork, "emit_kitty_graphics_commands", lambda commands: transmitted.extend(commands))
|
|
86
89
|
image = Image.new("RGB", (2, 4), "#00ff00")
|
|
87
90
|
buffer = BytesIO()
|
|
88
91
|
image.save(buffer, format="PNG")
|
|
89
92
|
|
|
90
93
|
rendered = render_protocol_artwork(buffer.getvalue(), "kitty", width=2, max_height=2)
|
|
91
94
|
|
|
92
|
-
assert rendered
|
|
95
|
+
assert isinstance(rendered, KittyImage)
|
|
96
|
+
assert transmitted == list(rendered.commands)
|
|
93
97
|
|
|
94
98
|
|
|
95
99
|
def test_render_protocol_artwork_uses_unicode_placeholders_when_kitty_is_detected(monkeypatch):
|
|
@@ -136,6 +140,7 @@ def test_kitty_graphics_commands_chunks_large_payload(monkeypatch):
|
|
|
136
140
|
def test_auto_protocol_renderer_requires_kitty_terminal(monkeypatch):
|
|
137
141
|
monkeypatch.delenv("KITTY_WINDOW_ID", raising=False)
|
|
138
142
|
monkeypatch.delenv("KITTY_PID", raising=False)
|
|
143
|
+
monkeypatch.delenv("TERM_PROGRAM", raising=False)
|
|
139
144
|
monkeypatch.setenv("TERM", "xterm-256color")
|
|
140
145
|
image = Image.new("RGB", (2, 4), "#00ff00")
|
|
141
146
|
buffer = BytesIO()
|
|
@@ -144,14 +149,32 @@ def test_auto_protocol_renderer_requires_kitty_terminal(monkeypatch):
|
|
|
144
149
|
rendered = render_protocol_artwork(buffer.getvalue(), "auto", width=2, max_height=2)
|
|
145
150
|
|
|
146
151
|
assert rendered is None
|
|
147
|
-
assert protocol_renderer_status("auto") == "Block art; Kitty terminal not detected"
|
|
152
|
+
assert protocol_renderer_status("auto") == "Block art; Kitty-compatible terminal not detected"
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def test_auto_protocol_renderer_uses_kitty_placeholders_in_ghostty(monkeypatch):
|
|
156
|
+
monkeypatch.delenv("KITTY_WINDOW_ID", raising=False)
|
|
157
|
+
monkeypatch.delenv("KITTY_PID", raising=False)
|
|
158
|
+
monkeypatch.setenv("TERM_PROGRAM", "ghostty")
|
|
159
|
+
transmitted = []
|
|
160
|
+
monkeypatch.setattr(artwork, "emit_kitty_graphics_commands", lambda commands: transmitted.extend(commands))
|
|
161
|
+
image = Image.new("RGB", (2, 4), "#00ff00")
|
|
162
|
+
buffer = BytesIO()
|
|
163
|
+
image.save(buffer, format="PNG")
|
|
164
|
+
|
|
165
|
+
rendered = render_protocol_artwork(buffer.getvalue(), "auto", width=2, max_height=2)
|
|
148
166
|
|
|
167
|
+
assert isinstance(rendered, KittyImage)
|
|
168
|
+
assert transmitted == list(rendered.commands)
|
|
169
|
+
assert protocol_renderer_status("auto") == "Kitty native images via Unicode placeholders"
|
|
149
170
|
|
|
150
|
-
|
|
171
|
+
|
|
172
|
+
def test_protocol_renderer_status_explains_explicit_kitty_force(monkeypatch):
|
|
151
173
|
monkeypatch.delenv("KITTY_WINDOW_ID", raising=False)
|
|
152
174
|
monkeypatch.delenv("KITTY_PID", raising=False)
|
|
175
|
+
monkeypatch.delenv("TERM_PROGRAM", raising=False)
|
|
153
176
|
|
|
154
|
-
assert protocol_renderer_status("kitty") == "
|
|
177
|
+
assert protocol_renderer_status("kitty") == "Kitty native images via Unicode placeholders"
|
|
155
178
|
|
|
156
179
|
|
|
157
180
|
def test_kitty_placeholder_lines_encode_row_and_column_cells():
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from plextui.models import LibraryItem, MediaItem
|
|
4
|
-
from plextui.plex_service import
|
|
4
|
+
from plextui.plex_service import (
|
|
5
|
+
PlexService,
|
|
6
|
+
artwork_path,
|
|
7
|
+
kind_label,
|
|
8
|
+
media_details,
|
|
9
|
+
progress_label,
|
|
10
|
+
row_progress_marker,
|
|
11
|
+
to_media_item,
|
|
12
|
+
watched_state,
|
|
13
|
+
)
|
|
5
14
|
|
|
6
15
|
|
|
7
16
|
class RawItem:
|
|
@@ -62,6 +71,18 @@ class DetailedRawItem(RawItem):
|
|
|
62
71
|
return [Part()]
|
|
63
72
|
|
|
64
73
|
|
|
74
|
+
class TvEpisodeRawItem(DetailedRawItem):
|
|
75
|
+
TYPE = "episode"
|
|
76
|
+
title = "Episode"
|
|
77
|
+
thumb = "/library/metadata/episode/thumb"
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class TvSeasonRawItem(DetailedRawItem):
|
|
81
|
+
TYPE = "season"
|
|
82
|
+
title = "Season 1"
|
|
83
|
+
thumb = "/library/metadata/season-own/thumb"
|
|
84
|
+
|
|
85
|
+
|
|
65
86
|
class RawPage(list):
|
|
66
87
|
totalSize = 250
|
|
67
88
|
|
|
@@ -219,6 +240,32 @@ def test_media_details_include_audio_and_subtitle_locations():
|
|
|
219
240
|
assert details.artwork_path == "/library/metadata/show/thumb"
|
|
220
241
|
|
|
221
242
|
|
|
243
|
+
def test_tv_episode_artwork_prefers_episode_still():
|
|
244
|
+
assert artwork_path(TvEpisodeRawItem()) == "/library/metadata/episode/thumb"
|
|
245
|
+
assert to_media_item(TvEpisodeRawItem()).artwork_path == "/library/metadata/episode/thumb"
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def test_tv_season_artwork_prefers_season_poster():
|
|
249
|
+
assert artwork_path(TvSeasonRawItem()) == "/library/metadata/season-own/thumb"
|
|
250
|
+
assert to_media_item(TvSeasonRawItem()).artwork_path == "/library/metadata/season-own/thumb"
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def test_tv_artwork_falls_back_to_parent_then_show_art():
|
|
254
|
+
class EpisodeWithoutStill(TvEpisodeRawItem):
|
|
255
|
+
thumb = ""
|
|
256
|
+
|
|
257
|
+
class SeasonWithoutPoster(TvSeasonRawItem):
|
|
258
|
+
thumb = ""
|
|
259
|
+
|
|
260
|
+
class EpisodeWithoutSeasonArt(TvEpisodeRawItem):
|
|
261
|
+
thumb = ""
|
|
262
|
+
parentThumb = ""
|
|
263
|
+
|
|
264
|
+
assert artwork_path(EpisodeWithoutStill()) == "/library/metadata/season/thumb"
|
|
265
|
+
assert artwork_path(SeasonWithoutPoster()) == "/library/metadata/season/thumb"
|
|
266
|
+
assert artwork_path(EpisodeWithoutSeasonArt()) == "/library/metadata/show/thumb"
|
|
267
|
+
|
|
268
|
+
|
|
222
269
|
def test_kind_label_humanizes_known_and_unknown_media_types():
|
|
223
270
|
assert kind_label("movie") == "Movie"
|
|
224
271
|
assert kind_label("show") == "TV Show"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|