diff --git a/furios_gallery/albums_view.py b/furios_gallery/albums_view.py index 9ce7c7b..c23af08 100644 --- a/furios_gallery/albums_view.py +++ b/furios_gallery/albums_view.py @@ -12,7 +12,7 @@ gi.require_version('Adw', '1') from gi.repository import Gtk, Adw, Gdk, GdkPixbuf, Pango -from .database_manager import get_album_database_paths, list_database_albums, get_album_media_paths +from .database_manager import cleanup_database, get_album_database_paths, list_database_albums, get_album_last_media_path from .thumbnail_generator import ThumbnailGenerator class Albums(Adw.NavigationPage): @@ -83,6 +83,9 @@ def load_albums(self): # Clear existing items self.flowbox.remove_all() + # Clean up the database to remove files that might of been deleted + cleanup_database(self.app_window.conn) + # Get albums from database albums = list_database_albums(self.app_window.conn) @@ -96,17 +99,15 @@ def load_albums(self): album_box.set_valign(Gtk.Align.CENTER) # Get album media paths - album_paths = get_album_media_paths(self.app_window.conn, album) + album_paths = get_album_last_media_path(self.app_window.conn, album) # Create album thumbnail if album_paths: - for last_media_url in reversed(album_paths): - thumbnail_path = self.thumbnail_generator.generate_thumbnail(last_media_url) - if thumbnail_path: - image = GdkPixbuf.Pixbuf.new_from_file_at_scale(thumbnail_path, width=400, height=400, preserve_aspect_ratio=False) - picture = Gtk.Picture.new_for_pixbuf(image) - picture.set_css_classes(["rounded-image"]) - break + thumbnail_path = self.thumbnail_generator.generate_thumbnail(album_paths) + if thumbnail_path: + image = GdkPixbuf.Pixbuf.new_from_file_at_scale(thumbnail_path, width=400, height=400, preserve_aspect_ratio=False) + picture = Gtk.Picture.new_for_pixbuf(image) + picture.set_css_classes(["rounded-image"]) else: # Default missing album image picture = Gtk.Box() @@ -159,3 +160,4 @@ def on_album_selected(self, flowbox): self.app_window.navigation_view.push(grid_view_page) self.flowbox.unselect_all() + diff --git a/furios_gallery/database_manager.py b/furios_gallery/database_manager.py index 9dff793..1846484 100644 --- a/furios_gallery/database_manager.py +++ b/furios_gallery/database_manager.py @@ -65,6 +65,8 @@ def create_tables(conn): # Create indexes to optimize lookups cursor.execute("CREATE UNIQUE INDEX IF NOT EXISTS idx_files_path ON files(file_path)") cursor.execute("CREATE INDEX IF NOT EXISTS idx_albums_name ON albums(album_name)") + cursor.execute("CREATE INDEX IF NOT EXISTS idx_file_albums_albums ON file_albums(album_id ASC)") + print("Tables and indexes created successfully") except sqlite3.Error as e: print(f"Error creating tables: {e}") @@ -108,6 +110,21 @@ def process_directory(directory, extensions): print(f"Processed {len(media_items)} media files.") +def cleanup_database(conn): + """Return a sorted-by-mtime list of valid file paths in a given album.""" + cur = conn.cursor() + cur.execute(""" + SELECT files.file_path + FROM files + """) + + file_paths = [row[0] for row in cur.fetchall()] + + for path in file_paths: + if not os.path.exists(path): + print(f"File not found, removing from database: {path}") + delete_from_albums(conn, path) + def insert_file_and_albums(conn, file_path, albums): """Insert a single file into the database (if not present) and link it to albums.""" file_type = "picture" if extract_extension(file_path) in PICTURE_EXTENSIONS else "video" @@ -201,19 +218,11 @@ def get_album_database_paths(conn, album_name): , (album_name,)) file_paths = [row[0] for row in cur.fetchall()] - valid_paths = [] - - for path in file_paths: - if os.path.exists(path): - valid_paths.append(path) - else: - print(f"File not found, removing from database: {path}") - delete_from_albums(conn, path) # Sort existing files by last modification time - return sorted(valid_paths, key=lambda p: os.path.getmtime(p)) + return sorted(file_paths, key=lambda p: os.path.getmtime(p)) -def get_album_media_paths(conn, album_name): +def get_album_last_media_path(conn, album_name): """Example of specialized retrieval with fallback logic to pictures/videos.""" try: cur = conn.cursor() @@ -223,26 +232,16 @@ def get_album_media_paths(conn, album_name): JOIN file_albums ON files.file_id = file_albums.file_id JOIN albums ON file_albums.album_id = albums.album_id WHERE albums.album_name = ? + ORDER BY files.file_id DESC + LIMIT 1 """ cur.execute(query, (album_name,)) - rows = cur.fetchall() - - media_paths = [] - for row in rows: - if os.path.exists(row[0]): - media_paths.append(row[0]) - else: - print(f"File not found, removing from database: {row[0]}") - delete_from_albums(conn, row[0]) + row = cur.fetchone() - # Optional logic to include "Pictures" or "Videos" from the "Recents" album - # (If the intention is to unify content between them, fine. Otherwise, remove this logic.) - if album_name.lower() in ['pictures', 'recents']: - media_paths.extend(get_album_database_paths(conn, "Pictures")) - if album_name.lower() in ['videos', 'recents']: - media_paths.extend(get_album_database_paths(conn, "Videos")) + if row: + return row[0] - return media_paths + return [] except Exception as e: print(f"Error retrieving media paths for album {album_name}: {e}") return [] diff --git a/furios_gallery/gallery_window.py b/furios_gallery/gallery_window.py index 051d06c..b3e4485 100644 --- a/furios_gallery/gallery_window.py +++ b/furios_gallery/gallery_window.py @@ -22,7 +22,7 @@ from .thumbnail_generator import ThumbnailGenerator from .media_properties_view import MediaPropertiesView from .database_manager import ( - get_album_database_paths, get_album_media_paths, + cleanup_database, create_tables, create_connection, delete_from_albums, ) @@ -44,14 +44,17 @@ def __init__(self, *args, **kwargs): self.conn = create_connection(str(app_dir / "gallery-albums.db")) if self.conn is not None: create_tables(self.conn) + + # Remove deleted files from database + cleanup_database(self.conn) # Thumbnail generator self.thumbnails = ThumbnailGenerator() # Media management variables self.current_album = "" - self.media_paths = get_album_database_paths(self.conn, "Recents") - self.current_index = len(self.media_paths) - 1 + self.media_paths = [] + self.current_index = 0 # Create toast overlay for notifications self.toast_overlay = Adw.ToastOverlay()