Skip to content

Commit 39a0ce9

Browse files
Add image preview
1 parent e74b1f0 commit 39a0ce9

File tree

13 files changed

+53
-393
lines changed

13 files changed

+53
-393
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ license = {file = "LICENSE.txt"}
88
readme = "README.md"
99
dependencies = [
1010
"textual>=3.1.1",
11+
"textual-image[textual]>=0.8.2",
1112
"beautifulsoup4>=4.13.4",
1213
"httpx[http2]>=0.28.1",
1314
"pypresence>=4.3.0",

src/gucken/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import warnings
22
warnings.filterwarnings('ignore', message='Using slow pure-python SequenceMatcher. Install python-Levenshtein to remove this warning')
33

4-
__version__ = "0.3.4"
4+
__version__ = "0.3.5"

src/gucken/gucken.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from typing import ClassVar, List, Union
1313
from async_lru import alru_cache
1414
from os import getenv
15+
from io import BytesIO
1516

1617
from fuzzywuzzy import fuzz
1718
from platformdirs import user_config_path, user_log_path
@@ -20,7 +21,7 @@
2021
from textual import events, on, work
2122
from textual.app import App, ComposeResult
2223
from textual.binding import Binding, BindingType
23-
from textual.containers import Center, Container, Horizontal, ScrollableContainer
24+
from textual.containers import Center, Container, Horizontal, ScrollableContainer, Vertical
2425
from textual.reactive import reactive
2526
from textual.screen import ModalScreen
2627
from textual.widgets import (
@@ -40,11 +41,13 @@
4041
TabPane,
4142
)
4243
from textual.worker import get_current_worker
44+
from textual_image.widget import Image
4345
from rich_argparse import RichHelpFormatter
4446
from .aniskip import (
4547
generate_chapters_file,
4648
get_timings_from_search
4749
)
50+
4851
from .custom_widgets import SortableTable
4952
from .hoster._hosters import hoster
5053
from .hoster.common import DirectLink, Hoster
@@ -57,8 +60,10 @@
5760
from .settings import gucken_settings_manager
5861
from .update import check
5962
from .utils import detect_player, is_android, set_default_vlc_interface_cfg, get_vlc_intf_user_path
63+
from .networking import AsyncClient
6064
from . import __version__
6165

66+
6267
def sort_favorite_lang(
6368
language_list: List[Language], pio_list: List[str]
6469
) -> List[Language]:
@@ -275,13 +280,23 @@ def compose(self) -> ComposeResult:
275280
yield ListView(id="results")
276281
with TabPane("Info", id="info", disabled=True): # Info "ℹ"
277282
with ScrollableContainer(id="res_con"):
278-
yield Markdown(id="markdown")
283+
yield Horizontal(
284+
Image(id="image"),
285+
Markdown(id="markdown"),
286+
id="res_con_2"
287+
)
288+
279289
yield ClickableDataTable(id="season_list")
280290
with TabPane("Settings", id="setting"): # Settings "⚙"
281291
# TODO: dont show unneeded on android
282292
with ScrollableContainer(id="settings_container"):
283293
yield SortableTable(id="lang")
284294
yield SortableTable(id="host")
295+
yield RadioButton(
296+
"Image display",
297+
id="image_display",
298+
value=settings["image_display"],
299+
)
285300
yield RadioButton(
286301
"Update checker",
287302
id="update_checker",
@@ -390,6 +405,10 @@ async def radio_button_changed(self, event: RadioButton.Changed):
390405
settings["pip"] = event.value
391406
return
392407

408+
if id == "image_display" and event.value == False:
409+
img: Image = self.query_one("#image", Image)
410+
img.image = None
411+
393412
settings[id] = event.value
394413

395414
if id == "discord_presence":
@@ -616,6 +635,12 @@ async def open_info(self) -> None:
616635
self.current_info = series
617636
await md.update(series.to_markdown())
618637

638+
if gucken_settings_manager.settings["settings"]["image_display"]:
639+
img: Image = self.query_one("#image", Image)
640+
async with AsyncClient(verify=False) as client:
641+
response = await client.get(series.cover)
642+
img.image = BytesIO(response.content)
643+
619644
# make sure to reset colum spacing
620645
table.clear(columns=True)
621646
table.add_columns("FT", "S", "F", "Title", "Hoster", "Sprache")

src/gucken/provider/aniworld.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
from asyncio import gather
23
from dataclasses import dataclass
34
from typing import Union
@@ -228,7 +229,6 @@ async def get_series(search_result: AniWorldSearchResult) -> AniWorldSeries:
228229
feps.append(b)
229230

230231
return AniWorldSeries(
231-
# cover=f"https://{search_result.host}" + soup.find("div", class_="seriesCoverBox").find("img").attrs.get("data-src"),
232232
name=fully_unescape(
233233
soup.find("h1", attrs={"itemprop": "name"}).find("span").text
234234
).strip(),
@@ -249,6 +249,7 @@ async def get_series(search_result: AniWorldSearchResult) -> AniWorldSeries:
249249
# rating_count=int(soup.find("span", attrs={"itemprop": "ratingCount"}).text),
250250
# staffeln=count,
251251
episodes=feps,
252+
cover=f"https://{search_result.host}" + soup.find("img", attrs={"itemprop": "image"}).attrs.get("data-src")
252253
)
253254

254255

src/gucken/provider/common.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ async def process_hoster(self) -> dict[Language, list[Hoster]]:
4040
class Series:
4141
name: str
4242
episodes: list[Episode]
43+
cover: str
4344

4445
# description: str
4546

src/gucken/provider/serienstream.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,6 @@ async def get_series(search_result: SerienStreamSearchResult) -> SerienStreamSer
238238
feps.append(b)
239239

240240
return SerienStreamSeries(
241-
# cover=f"https://{search_result.host}" + soup.find("div", class_="seriesCoverBox").find("img").attrs.get("data-src"),
242241
name=fully_unescape(
243242
soup.find("h1", attrs={"itemprop": "name"}).find("span").text
244243
).strip(),
@@ -259,6 +258,7 @@ async def get_series(search_result: SerienStreamSearchResult) -> SerienStreamSer
259258
# rating_count=int(soup.find("span", attrs={"itemprop": "ratingCount"}).text),
260259
# staffeln=count,
261260
episodes=feps,
261+
cover=f"https://{search_result.host}" + soup.find("img", attrs={"itemprop": "image"}).attrs.get("data-src")
262262
)
263263

264264

src/gucken/resources/default_settings.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Default settings
22
[settings]
3+
image_display = true
34
pip = false
45
fullscreen = true
56
syncplay = false

src/gucken/resources/gucken.css

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,6 @@ Next > Container > Horizontal > Button {
6060
margin: 1 0;
6161
}
6262

63-
#markdown {
64-
margin: 1;
65-
padding: 1;
66-
padding-top: -1;
67-
padding-bottom: 0;
68-
}
69-
7063
/*TODO: make height 100 of what the table needs, so there is only one scroll*/
7164
#season_list {
7265
min-height: 3;
@@ -122,3 +115,22 @@ Tab {
122115
margin-top: 0;
123116
}
124117

118+
#image {
119+
padding-top: 1;
120+
height: 20;
121+
width: auto;
122+
background: $background;
123+
}
124+
125+
#res_con_2 {
126+
height: auto;
127+
}
128+
129+
#markdown {
130+
margin: 1;
131+
padding: 1;
132+
padding-top: -1;
133+
margin-bottom: -1;
134+
height: auto;
135+
width: 1fr;
136+
}

test/img/RichPixels_ChafaSymbols.py

Lines changed: 0 additions & 110 deletions
This file was deleted.

test/img/iterm2_prot.py

Lines changed: 0 additions & 38 deletions
This file was deleted.

0 commit comments

Comments
 (0)