first commit

This commit is contained in:
2024-09-05 18:34:12 +02:00
commit d175ce4944
18 changed files with 514 additions and 0 deletions

Binary file not shown.

View File

@@ -0,0 +1,28 @@
from tkinter import Listbox, SINGLE
from services.file_utils import clean_filename
import os
class MovieListbox(Listbox):
def __init__(self, master, movies, on_select_callback):
super().__init__(master, selectmode=SINGLE, bg='#23272a', fg='white',
selectbackground='#7289da', width=50)
self.movies = movies
self.on_select_callback = on_select_callback
self.populate_listbox()
self.bind("<<ListboxSelect>>", self.on_movie_select)
def populate_listbox(self):
for index, row in self.movies.iterrows():
movie_title = f"{row['Name']} ({row['Year']})"
safe_title = clean_filename(f"{row['Name']}_{row['Year']}")
poster_path = os.path.join('posters', f"{safe_title}.jpg")
self.insert(index, movie_title)
if os.path.exists(poster_path):
self.itemconfig(index, {'fg': 'green'})
def on_movie_select(self, event):
selected_index = self.curselection()
if selected_index:
selected_movie = self.movies.iloc[selected_index[0]]
self.on_select_callback(selected_movie)

View File

@@ -0,0 +1,144 @@
from tkinter import Frame, Label, Canvas, NW, StringVar, messagebox
from tkinter.ttk import Progressbar
from PIL import ImageTk
from threading import Thread
from concurrent.futures import ThreadPoolExecutor
import os
from src.services.image_service import ImageService
from services.file_utils import clean_filename
class PosterFrame(Frame):
def __init__(self, master):
super().__init__(master, bg='#2c2f33')
self.canvas = Canvas(self, bg='#2c2f33', highlightthickness=0)
self.canvas.pack(side="right", fill="both", expand=True)
self.poster_frame = Frame(self.canvas, bg='#2c2f33')
self.canvas.create_window((0, 0), window=self.poster_frame, anchor=NW)
self.poster_frame.bind("<Configure>", self.on_frame_configure)
self.master.bind("<Configure>", self.on_window_resize)
self.master.bind_all("<MouseWheel>", self.on_mouse_wheel)
self.loading_label = None
self.progress_bar = None
self.resizing = False
self.current_movie = None
self.initial_message = Label(self.poster_frame, text="Aucun poster à afficher. Veuillez sélectionner un film.", bg='#2c2f33', fg='white')
self.initial_message.pack(pady=20)
def show_posters(self, posters, movie, image_service):
self.clear_poster_frame()
self.current_movie = movie
self.loading_label = Label(self.poster_frame, text="Chargement des posters...",
bg='#2c2f33', fg='white')
self.loading_label.grid(row=0, column=0, pady=20)
self.progress_bar = Progressbar(self.poster_frame, orient="horizontal",
mode="determinate", length=400)
self.progress_bar.grid(row=1, column=0, pady=10)
Thread(target=self.download_and_display_posters,
args=(posters, image_service)).start()
def download_and_display_posters(self, posters, image_service):
max_columns = max(1, self.canvas.winfo_width() // 200)
images = []
with ThreadPoolExecutor(max_workers=10) as executor:
future_to_url = {executor.submit(image_service.download_image,
f"https://image.tmdb.org/t/p/w200{poster['file_path']}"):
poster['file_path'] for poster in posters}
total = len(future_to_url)
for i, future in enumerate(future_to_url):
image = future.result()
if image:
images.append(image)
self.update_progress_bar(i + 1, total)
self.display_posters(images, max_columns)
def display_posters(self, images, max_columns):
self.clear_poster_frame()
for idx, image in enumerate(images):
image.thumbnail((200, 300))
photo = ImageTk.PhotoImage(image)
label = Label(self.poster_frame, image=photo, bg='#2c2f33')
label.image = photo
row = idx // max_columns
col = idx % max_columns
label.grid(row=row, column=col, padx=5, pady=5)
label.bind("<Button-1>", lambda e, idx=idx: self.download_selected_poster(idx))
def download_selected_poster(self, idx):
poster = self.posters[idx]
poster_path = poster['file_path']
poster_url = f"https://image.tmdb.org/t/p/original{poster_path}"
title = self.current_movie['Name']
year = self.current_movie['Year']
safe_title = clean_filename(f"{title}_{year}")
output_folder = 'posters'
os.makedirs(output_folder, exist_ok=True)
save_path = os.path.join(output_folder, f"{safe_title}.jpg")
if os.path.exists(save_path):
response = messagebox.askyesno("Poster déjà existant",
f"Le poster pour {title} ({year}) existe déjà. Voulez-vous l'écraser?")
if not response:
return
# Téléchargement du poster en haute qualité
image = self.image_service.download_image(poster_url, save_path)
if image:
messagebox.showinfo("Téléchargement réussi", f"Poster téléchargé et enregistré : {save_path}")
# Mettre à jour la liste des films pour refléter le nouveau téléchargement
self.master.movie_listbox.populate_listbox()
else:
messagebox.showerror("Erreur", "Échec du téléchargement du poster.")
def update_progress_bar(self, value, total):
if self.progress_bar:
progress = (value / total) * 100
self.master.after(0, lambda: self.safe_update_progress(progress))
def safe_update_progress(self, progress):
if self.progress_bar and self.progress_bar.winfo_exists():
self.progress_bar['value'] = progress
self.update_idletasks()
def clear_poster_frame(self):
for widget in self.poster_frame.winfo_children():
widget.destroy()
def on_frame_configure(self, event):
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def on_window_resize(self, event):
if not self.resizing:
self.resizing = True
self.after(100, self.resize_done)
def resize_done(self):
self.resizing = False
self.update_poster_layout()
def update_poster_layout(self):
for widget in self.poster_frame.winfo_children():
widget.grid_forget()
max_columns = max(1, self.poster_frame.winfo_width() // 200)
for idx, widget in enumerate(self.poster_frame.winfo_children()):
row = idx // max_columns
col = idx % max_columns
widget.grid(row=row, column=col, padx=5, pady=5)
def on_mouse_wheel(self, event):
self.canvas.yview_scroll(-1 * (event.delta // 120), "units")

View File

@@ -0,0 +1,28 @@
from tkinter import Tk, Frame
from .components.movie_listbox import MovieListbox
from .components.poster_frame import PosterFrame
from src.services.tmdb_service import TMDBService
from src.services.image_service import ImageService
class PosterSelector(Tk):
def __init__(self, movies):
super().__init__()
self.movies = movies
self.tmdb_service = TMDBService()
self.image_service = ImageService()
self.title("Sélectionnez un Poster")
self.geometry("1200x600")
self.configure(bg='#2c2f33')
self.movie_listbox = MovieListbox(self, movies, self.on_movie_select)
self.poster_frame = PosterFrame(self)
self.movie_listbox.pack(side="left", fill="y")
self.poster_frame.pack(side="right", fill="both", expand=True)
def on_movie_select(self, selected_movie):
movie = self.tmdb_service.search_movie(selected_movie['Name'], selected_movie['Year'])
if movie:
posters = self.tmdb_service.get_movie_posters(movie['id'])
self.poster_frame.show_posters(posters, selected_movie, self.image_service)