Skip to content

Commit 92d62bb

Browse files
Work on streamlining main functions
1 parent f2b5b40 commit 92d62bb

23 files changed

Lines changed: 461 additions & 1607 deletions

mediux_posters/__main__.py

Lines changed: 152 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
from collections.abc import Generator
3+
from enum import Enum
34
from pathlib import Path
45
from platform import python_version
56
from typing import Annotated, Protocol, TypeVar
@@ -17,11 +18,6 @@
1718

1819
app = Typer()
1920
LOGGER = logging.getLogger("mediux-posters")
20-
T = TypeVar("T", bound="HasUsername")
21-
22-
23-
class HasUsername(Protocol):
24-
username: str
2521

2622

2723
@app.callback(invoke_without_command=True)
@@ -71,6 +67,13 @@ def setup(
7167
return settings, mediux, service_list
7268

7369

70+
T = TypeVar("T", bound="MediuxSet")
71+
72+
73+
class MediuxSet(Protocol):
74+
username: str
75+
76+
7477
def filter_sets(
7578
set_list: list[T], priority_usernames: list[str], only_priority_usernames: bool
7679
) -> Generator[T]:
@@ -86,6 +89,93 @@ def filter_sets(
8689
yield from [x for x in set_list if x.username not in priority_usernames]
8790

8891

92+
class MediaTypeChoice(str, Enum):
93+
SHOW = MediaType.SHOW.value
94+
COLLECTION = MediaType.COLLECTION.value
95+
MOVIE = MediaType.MOVIE.value
96+
97+
98+
@app.command(
99+
name="sync", help="Synchronize posters by fetching data from Mediux and updating your services."
100+
)
101+
def sync_posters(
102+
skip_mediatypes: Annotated[
103+
list[MediaTypeChoice],
104+
Option(
105+
"--skip-type",
106+
"-T",
107+
show_default=False,
108+
case_sensitive=False,
109+
default_factory=list,
110+
help="List of MediaTypes to skip. "
111+
"Specify this option multiple times for skipping multiple types.",
112+
),
113+
],
114+
skip_libraries: Annotated[
115+
list[str],
116+
Option(
117+
"--skip-library",
118+
"-L",
119+
show_default=False,
120+
default_factory=list,
121+
help="List of libraries to skip. "
122+
"Specify this option multiple times for skipping multiple libraries. ",
123+
),
124+
],
125+
start: Annotated[
126+
int, Option("--start", "-s", help="The starting index for processing media.")
127+
] = 0,
128+
end: Annotated[
129+
int, Option("--end", "-e", help="The ending index for processing media.")
130+
] = 100_000,
131+
full_clean: Annotated[
132+
bool,
133+
Option(
134+
"--full-clean", "-C", show_default=False, help="Delete the whole cache before starting."
135+
),
136+
] = False,
137+
debug: Annotated[
138+
bool,
139+
Option(
140+
"--debug",
141+
help="Enable debug mode to show extra logging information for troubleshooting.",
142+
),
143+
] = False,
144+
) -> None:
145+
settings, mediux, service_list = setup(full_clean=full_clean, debug=debug)
146+
skip_mediatypes = [x.value for x in skip_mediatypes]
147+
148+
for idx, service in enumerate(service_list):
149+
CONSOLE.rule(
150+
f"[{idx + 1}/{len(service_list)}] {type(service).__name__} Service",
151+
align="left",
152+
style="title",
153+
)
154+
for media_type in MediaType:
155+
if media_type.value in skip_mediatypes:
156+
continue
157+
with CONSOLE.status(
158+
f"[{type(service).__name__}] Fetching {media_type.name.lower().capitalize()} media"
159+
):
160+
entries = service.list(media_type=media_type, skip_libraries=skip_libraries)[
161+
start:end
162+
]
163+
for index, entry in enumerate(entries):
164+
CONSOLE.rule(
165+
f"[{index + 1}/{len(entries)}] {entry.display_name} [tmdb-{entry.tmdb_id}]",
166+
align="left",
167+
style="subtitle",
168+
)
169+
LOGGER.info(
170+
"[%s] Searching Mediux for '%s' sets",
171+
type(service).__name__,
172+
entry.display_name,
173+
)
174+
set_list = mediux.list_sets(media_type=media_type, tmdb_id=entry.tmdb_id)
175+
for set_data in filter_sets(set_list=set_list, settings=settings, mediux=mediux):
176+
LOGGER.info("Downloading '%s' by '%s'", set_data.set_title, set_data.username)
177+
178+
89179
@app.command(
90180
name="manual", help="Manually set posters for specific Mediux media using a file or URLs."
91181
)
@@ -144,6 +234,16 @@ def manual_posters(
144234
)
145235
url_list = [x.strip() for x in file.read_text().splitlines()] if file else urls
146236
for index, entry in enumerate(url_list):
237+
if entry.startswith(f"{Mediux.WEB_URL}/sets"):
238+
set_posters(
239+
settings=settings,
240+
mediux=mediux,
241+
service=service,
242+
url=entry,
243+
simple_clean=simple_clean,
244+
debug=debug,
245+
)
246+
continue
147247
media_type = (
148248
MediaType.SHOW
149249
if entry.startswith(f"{Mediux.WEB_URL}/{MediaType.SHOW}s")
@@ -157,15 +257,7 @@ def manual_posters(
157257
continue
158258
tmdb_id = int(entry.split("/")[-1])
159259
with CONSOLE.status(f"Searching {type(service).__name__} for TMDB id: '{tmdb_id}'"):
160-
obj = (
161-
service.get_show(tmdb_id=tmdb_id)
162-
if media_type is MediaType.SHOW
163-
else service.get_collection(tmdb_id=tmdb_id)
164-
if media_type is MediaType.COLLECTION
165-
else service.get_movie(tmdb_id=tmdb_id)
166-
if media_type is MediaType.MOVIE
167-
else None
168-
)
260+
obj = service.get(media_type=media_type, tmdb_id=tmdb_id)
169261
if not obj:
170262
LOGGER.warning(
171263
"[%s] Unable to find a %s with a Tmdb Id of '%d'",
@@ -196,20 +288,10 @@ def manual_posters(
196288
/ slugify(movie.display_name)
197289
)
198290
try:
199-
set_list = (
200-
mediux.list_show_sets(
201-
tmdb_id=tmdb_id, exclude_usernames=settings.exclude_usernames
202-
)
203-
if media_type is MediaType.SHOW
204-
else mediux.list_collection_sets(
205-
tmdb_id=tmdb_id, exclude_usernames=settings.exclude_usernames
206-
)
207-
if media_type is MediaType.COLLECTION
208-
else mediux.list_movie_sets(
209-
tmdb_id=tmdb_id, exclude_usernames=settings.exclude_usernames
210-
)
211-
if media_type is MediaType.MOVIE
212-
else None
291+
set_list = mediux.list_sets(
292+
media_type=media_type,
293+
tmdb_id=tmdb_id,
294+
exclude_usernames=settings.exclude_usernames,
213295
)
214296
except ServiceError as err:
215297
LOGGER.error(err)
@@ -222,113 +304,57 @@ def manual_posters(
222304
LOGGER.info("Downloading '%s' by '%s'", set_data.set_title, set_data.username)
223305

224306

225-
@app.command(name="set", help="Manually set posters for specific Mediux sets using a file or URLs.")
226307
def set_posters(
227-
file: Annotated[
228-
Path | None,
229-
Option(
230-
dir_okay=False,
231-
exists=True,
232-
show_default=False,
233-
help="Path to a file containing URLs of Mediux sets, one per line. "
234-
"If set, the file must exist and cannot be a directory.",
235-
),
236-
] = None,
237-
urls: Annotated[
238-
list[str] | None,
239-
Option(
240-
"--url",
241-
"-u",
242-
show_default=False,
243-
help="List of URLs of Mediux sets to process. "
244-
"Specify this option multiple times for multiple URLs.",
245-
),
246-
] = None,
247-
full_clean: Annotated[
248-
bool,
249-
Option(
250-
"--full-clean", "-C", show_default=False, help="Delete the whole cache before starting."
251-
),
252-
] = False,
253-
simple_clean: Annotated[
254-
bool,
255-
Option(
256-
"--simple-clean",
257-
"-c",
258-
show_default=False,
259-
help="Delete the cache of each media instead of the whole cache.",
260-
),
261-
] = False,
262-
debug: Annotated[
263-
bool,
264-
Option(
265-
"--debug",
266-
help="Enable debug mode to show extra logging information for troubleshooting.",
267-
),
268-
] = False,
308+
settings: Settings, # noqa: ARG001
309+
mediux: Mediux,
310+
service: BaseService,
311+
url: str,
312+
simple_clean: bool = False,
313+
debug: bool = False, # noqa: ARG001
269314
) -> None:
270-
settings, mediux, service_list = setup(full_clean=full_clean, debug=debug)
315+
set_id = int(url.split("/")[-1])
316+
set_data = (
317+
mediux.get_show_set(set_id=set_id)
318+
or mediux.get_collection_set(set_id=set_id)
319+
or mediux.get_movie_set(set_id=set_id)
320+
)
321+
if tmdb_id := (
322+
set_data.show.tmdb_id
323+
if isinstance(set_data, ShowSet)
324+
else set_data.collection.tmdb_id
325+
if isinstance(set_data, CollectionSet)
326+
else set_data.movie.tmdb_id
327+
if isinstance(set_data, MovieSet)
328+
else None
329+
):
330+
return
271331

272-
for idx, service in enumerate(service_list):
273-
CONSOLE.rule(
274-
f"[{idx + 1}/{len(service_list)}] {type(service).__name__} Service",
275-
align="left",
276-
style="title",
277-
)
278-
url_list = [x.strip() for x in file.read_text().splitlines()] if file else urls
279-
for index, entry in enumerate(url_list):
280-
if not entry.startswith(f"{Mediux.WEB_URL}/sets"):
281-
continue
282-
set_id = int(entry.split("/")[-1])
283-
set_data = (
284-
mediux.get_show_set(set_id=set_id)
285-
or mediux.get_collection_set(set_id=set_id)
286-
or mediux.get_movie_set(set_id=set_id)
332+
with CONSOLE.status(
333+
f"Searching {type(service).__name__} for '{set_data.set_title} [{tmdb_id}]'"
334+
):
335+
obj = service.find(tmdb_id=tmdb_id)
336+
if not obj:
337+
LOGGER.warning(
338+
"[%s] Unable to find any media with a Tmdb Id of '%d'",
339+
type(service).__name__,
340+
tmdb_id,
287341
)
288-
if tmdb_id := (
289-
set_data.show.tmdb_id
290-
if isinstance(set_data, ShowSet)
291-
else set_data.collection.tmdb_id
292-
if isinstance(set_data, CollectionSet)
293-
else set_data.movie.tmdb_id
294-
if isinstance(set_data, MovieSet)
295-
else None
296-
):
297-
continue
342+
return
298343

299-
with CONSOLE.status(
300-
f"Searching {type(service).__name__} for '{set_data.get('set_name')} [{tmdb_id}]'"
301-
):
302-
obj = service.find(tmdb_id=tmdb_id)
303-
if not obj:
304-
LOGGER.warning(
305-
"[%s] Unable to find any media with a Tmdb Id of '%d'",
306-
type(service).__name__,
307-
tmdb_id,
308-
)
309-
continue
310-
CONSOLE.rule(
311-
f"[{index + 1}/{len(url_list)}] {obj.display_name} [tmdb-{obj.tmdb_id}]",
312-
align="left",
313-
style="subtitle",
314-
)
315-
if simple_clean:
316-
LOGGER.info("Cleaning %s cache", obj.display_name)
344+
if simple_clean:
345+
LOGGER.info("Cleaning %s cache", obj.display_name)
346+
delete_folder(
347+
folder=get_cache_root() / "covers" / obj.mediatype.value / slugify(obj.display_name)
348+
)
349+
if isinstance(obj, Collection):
350+
for movie in obj.movies:
317351
delete_folder(
318352
folder=get_cache_root()
319353
/ "covers"
320-
/ obj.mediatype.value
321-
/ slugify(obj.display_name)
354+
/ movie.mediatype.value
355+
/ slugify(movie.display_name)
322356
)
323-
if isinstance(obj, Collection):
324-
for movie in obj.movies:
325-
delete_folder(
326-
folder=get_cache_root()
327-
/ "covers"
328-
/ movie.mediatype.value
329-
/ slugify(movie.display_name)
330-
)
331-
LOGGER.info("Downloading '%s' by '%s'", set_data.set_title, set_data.username)
357+
LOGGER.info("Downloading '%s' by '%s'", set_data.set_title, set_data.username)
332358

333359

334360
if __name__ == "__main__":

0 commit comments

Comments
 (0)