I've been considering building a Python application for personal use and built a conceptual project outline to guide development. If you don't mind reviewing the outline, I'd be interested to get your perspective, starting with the conceptual approach I used?

# Media Manager Application Outline

## **Core Concept**

A desktop application for personal use that allows users to select folders of video files and display them in a virtual folder structure, with the option for the user to add tags for studio, title, actor, or content tags

## **User Interface: **

### **Menu Bar:** 

A `QMenuBar` object with a "Folder Monitoring", "Resync Database", "Clear Database" & "Exit" options.

### **Toolbar:** 

A tool bar at the top with an "Add Folder", "Create Playlist" & "Activity" buttons

### **Search Bar:** 

A bar allowing the user to search for video content in the library. It should include the following items:
- A text entry field for the user's search term
- A "Search Options" button that when clicked displays a menu with checkboxes allowing the user to select whether they want to include file name, category, studio, title, actor tags, or content tags in their search, allowing for any combination of metadata. The user should also be able to limit searches to the currently selected virtual folder.
- A "Search Now" button
- A "Clear Search" button to clear out the search term and Main Window (if it was showing search results)

### **Main Window:** 

This would be the central section of the user interface with a scrollable `QTableView` item that shows videos based on the selected virtual folder or search results. 

- The video items should contain the following data:
	* Thumbnail
	* File Name
	* Title (if set by the user)
	* Dimensions/Frame Rate of the video file (e.g. 1920x1080, 29.97fps)
	* Duration of the video in hour:minute:second format
- The user should have a context menu available when right-clicking with the following options:
	* "Play Video" - This would launch the video in the system default media player
	* "Add to Folder" - This would be an expandable option allowing the user to select the virtual folder associated with the video - this would be flexible and work whether the user has a single item or multiple items selected.
	* "Add to Playlist" - This would add the video to the items in the playlist window, opening it if it was not already visible. This would be flexible and work whether the user has a single item or multiple items selected.
	* "Change Thumbnail" - This would present a popup menu allowing the user to select a different timestamp from the source video to use for the thumbnail (and would validate to ensure the timestamp entered is within the duration of the video)
	* "Remove Video" - This would remove the video from the database and delete its associated thumbnail. this would be flexible and work whether the user has a single item or multiple items selected.

### **Virtual Folders:** 

This would be a panel to the left of the main window, allowing the user to create virtual folders to use in organizing video files.
- A video file would be associated with a single virtual folder. 
- By default, only an "Unsorted" folder would be present, which would be used as the default for any newly-added videos, unless specified otherwise during the scan process
- The panel would list folders in a tree structure, allowing the user to create nested folders. 
- At the top should be a "Create Folder" button
- The user should be nest folders by dragging and dropping (e.g. If the user has "Folder A" created at the top level and wants to create "Folder B" as a subfolder, they would click "Create Folder" to create "Folder B" at the top level, then drag "Folder B" on top of "Folder A" to make it a subfolder.) 
- The user should be able to right click a folder to rename it.

### **Details Panel:** 

This would be a panel to the right of the main window, allowing the user to view additional file details and metadata, as well as set tags for the file content based on the currently selected video in the Main Window. The Details Panel should include the following items:
- Video File Path
- Video File Name
- Category (editable metadata)
- Title (editable metadata)
- Studio (editable metadata)
- Actors (editable metadata - would use a "pill" format with a small "x" on the right side of the pill to remove the metadata)
- Content Tags (editable metadata - would use a "pill" format with a small "x" on the right side of the pill to remove the metadata)
- A "Save Changes" button to save user updates - changes would be discarded when clicking another file unless explicitly saved.

### **Playlist Management:** 

This would be a pop out window triggered by the user clicking the "Create Playlist" button. This would have the following items:
- A toolbar with "Save Playlist" & "Clear Playlist" buttons
- A main window containing the playlist itself. The user can drag and drop items within the playlist window itself to reorder the playlist.

### **Folder Monitoring:**

This would be a pop out window that allows the user to edit watched folder information.
- The main element of this window would be a table view listing folders that had previously been added, including the following data:
	* The path for each folder the user added
	* An editable selection for the default virtual folder to use for newly-discovered items
	* An editable selection for the default category to use for newly-discovered items
	* An editable selection for the default studio to use for newly-discovered items
	* An editable selection for the default content tags to use for newly-discovered items
	* A "Remove Folder" button
	* A "Scan Now" button
- Below the table view should be the following items that would act globally:
	* A text input for the number of minutes to wait between background scans (Default 120 minutes)
	* A "Save Changes" button

### **Activity Panel:**

This would be a pop out window triggered by the user clicking the "Activity" button. It would have two list items:
- "Running Processes" : This would show any currently running background workers and their progress
- "Task Results" : A list of tasks processed by background workers, as well as whether they were successful or failed

## **User Workflow**

### **Launch and Initial State:** 

- The application would validate that `ffmpeg` is available, and abort loading if not found.
- if `ffmpeg` is found, the application would launch to an empty main window with no items selected.

### **Adding Videos:** 

- The user can select the "Add Folder" items from the toolbar to add content to the library.
- The user would see a popup window with the following options:
- A folder selector allowing the user to pick the folder to add
- Fields allowing the user to select default metadata tags for Category, Studio, Content Tags
- An option to allow the user to select the default virtual folder to assign media to (Default is "Unsorted")
- An "Add to Library"  button
- A "Cancel" button. 
- Clicking "Cancel" would close the popup dialog with no changes made. 
- Clicking "Add to Library" would close the popup dialog and replace it with the application status bar showing per-file progress as the application adds the selected content. During the import process, the application would be doing the following:
	* Identifying potentially valid files based on file type (.mp4, .m4v)
	* Scanning the files found for metadata (duration, dimensions, frames per second) using `ffprobe` - if the application is unable to retrieve metadata, the file should be skipped and displayed to the user on completion of the scan. 
	* Capture the file size and last modified date.
	* Create a thumbnail for each file with valid metadata, using the database uuid for the video to avoid potential issues with multiple files having the same name. Errors with thumbnail creation should be non-blocking and would result in a gray default thumbnail for the source video. The thumbnail should be captured 10 seconds into the video (or the first frame if the video length is less than 10 seconds) using `ffmpeg`.
	* Caching the thumbnail to disk and updating the application database with the found metadata.
	* Note: Metadata and virtual folder selections made here would become the defaults for any additional media found from the source folder using the "Folder Monitoring" feature.
- Upon completion of the scan, the modal dialog box should update to one of the following three states, with a "Close" button
	* "No valid video files found" - When no videos matching the supported file types are found.
	* "Errors during import" This message would also show a list of any files that matched the supported file types, but metadata could not be retrieved.
	* "Import Successful" - All files matching the supported file types were loaded into the database.

### **Organizing Videos Into Virtual Folders:** 

- All newly-added videos will be added to the "Unsorted" virtual folder by default. 
- Videos can only be assigned to a single virtual folder.
- From the "Virtual Folders" panel on the left, the user can create new folders via the "Create Folder" button, and drag a folder on top of an existing folder to nest virtual folders inside each other
- If a user attempts to create a circular relationship by dragging a parent folder into a subfolder, the request should be ignored. 
- If the user clicks on a virtual folder, the Main Window will clear any current items, then update and display the files in the virtual folder alphabetically. 
- Lazy loading should be used to keep the UI responsive when loading a large virtual folder of videos via a background worker thread. Metadata should be prioritized when loading, followed by thumbnails. 
- If one or more files are not found when updating the Main Window, the items should be added in a disabled state with a "File Not Found" placeholder as the thumbnail. 
- The user can right click on a virtual folder to delete it via a context menu. If the virtual folder has any videos associated with it when this happens - including in any subfolders - they would be reassigned to the "Unsorted" virtual folder.
- To avoid edge cases, the "Unsorted" virtual folder should not have the ability to be renamed or to have folders nested underneath it.

### **Searching for Videos:** 

From the search bar, the user would search using the following process:
- Enter the search term/phrase in the search bar above the Main Window.
- The user would select what fields they want the search term to include from the "Search Options" menu. If no options are selected, the application should assume the user wants to use any available field for the search.
- The user clicks "Search Now" to begin the search. This should trigger a modal dialog with an indeterminate progress bar and a "Cancel" button. The search process should do the following:
	* Clear any current items in the Main Window list
	* Search the application database for any items matching the search term. Searching should be case insensitive.
	* Validate the video file exists in the stored path, omitting any search results where the video file is not found.
	* Update the Main Window list as items are found (ordering is not important for a search) using a background worker
	* If the user clicks the "Cancel" button, the application should abort the search process and clear any current items in the Main Window list
	* Once the search is complete, the modal dialog should close, allowing the user to see the search results.

### **Editing Metadata:** 
- With a video selected in the Main Window, the Details Panel should update showing the following items:
	* Video File Path
	* Video File Name
	* Category (editable metadata)
	* Title (editable metadata)
	* Studio (editable metadata)
	* Actors (editable metadata - would use a "pill" format with a small "x" on the right side of the pill to remove the metadata)
	* Content Tags (editable metadata - would use a "pill" format with a small "x" on the right side of the pill to remove the metadata)
- The Title and Studio fields should be text input fields allowing the user to freely enter updated information.
- The Actors & Content Tags should use a "pill" format with the option to add multiple items - to add a tag, the user would enter the text for the tag, followed by the "Enter" button to save it - changes would also be saved if the user changed focus by clicking on another field or another item in the user interface. 
- Changes made in the Details Panel should update the database entries for video files through a queued background worker thread. 
- If the user attempts to close the application with unsaved changes, they should receive a popup with the message "You have unsaved changes. Do you want to save them before quitting?" and a "Yes" and "No" button. If the user selects "No" the application should close with unsaved changes being discarded, and if the user selects "Yes" the changes should be saved before the application closes. 
- Actor/Studio/Tag names should be trimmed and normalized with the first letter of every word being capitalized if entered as lowercase.
- The user would click the "Save Changes" button to save metadata updates - changes would be discarded when clicking another file unless explicitly saved. The user should see a warning message if attempting to select another item with unsaved changes.

### **Creating a Playlist:** 

- If the user clicks the "Create Playlist" button, the Playlist Management window will open as a second window. 
- The user can right click videos in the main window to add them to a playlist via a context menu. 
- The user can drag and drop within the Playlist Management window to reorder items. 
- If the user clicks the "Clear Playlist" button at the top of the Playlist Management window, all items should be cleared. 
- If the user clicks the "Save Playlist" button, the user should see a pop up dialog asking for the location the playlist should be saved to, then the playlist items should be saved in the order displayed as an `xspf` VLC Media Player playlist. Any items in the Playlist Management Window should be cleared if the window is closed.

### **Resync Database:** 

- This menu item would rescan all items added to ensure they still exist in the original location. 
- When the user selects this item, they should receive an initial popup warning that has the text "Warning! This operation will scan your entire library and may take an extended period. The process will run in the background, and you can continue to use the application. Are you sure you want to proceed?" with "Proceed" and "Cancel" options. 
- If the user selects "Cancel" the popup window should close with no changes made. If the user selects "Proceed" they should see the application status bar showing per-file progress of the scan process. The scan process would do the following:
- Confirm each file in the database still exists in its current location. 
	* If the file is found and the file size and last modified date match the database it should be considered verified. The thumbnail should be regenerated if not found to account for edge cases where a cached thumbnail was deleted.
	* If the file is found but the file size and/or last modified date do not match the database, it should be updated and a new thumbnail generated.
	* If the file is not found, it should be removed from the database and any cached thumbnails removed.
- Check for new files in monitored folders. If a video is found in a monitored folder that doesn't exist in the database, it should be added with metadata based on the folder settings and a thumbnail generated.
- At the end of the process the user should receive a popup notification to show the scan was completed, with a count of total files scanned and the number of files added, updated and removed.

### **Clear Database:** 

- This menu item would remove all items from the database and clear all thumbnails in the cache. 
- When the user selects this item, they should receive an initial popup warning that has the text "Warning! This operation will clear all items from the database during which the application will not be usable. Please do not close the application while this process is running. This option is not reversible. Are you sure you want to proceed?" with "Proceed" and "Cancel" options. 
	* If the user selects "Cancel" the popup window should close with no changes made. 
	* If the user selects "Proceed" a modal dialog should appear advising the user the database is being cleared, with a "Continue" button visible to close the dialog once the process has cleared.

### **Folder Monitoring:**

- A background worker should periodically scan for new or updated content in added folders using the following process:
- The background worker iterates through files in added folders to find valid media files
- The background worker validates whether a media file found matches the path and checksum of an item in the database and updates based on one of these states:
	* The media file already exists in the database based on path with the same checksum: No action taken
	* The media file already exists in the database based on path, but checksums do not match: Retrieve updated metadata, generate a new thumbnail, and update database values - if metadata retrieval or thumbnail update processes fail, do nothing and move to the next item
	* The media file does not exist in the database: Retrieve metadata, generate a thumbnail, and add media information to the database
	* To mitigate database issues if the application closes unexpectedly, metadata updates should be batched for a file and the database updated with a single transaction per file scanned
	* Files added or updated via the background process should not trigger a refresh of the view in the main window to prevent unexpected behavior if the user was viewing search results or had selected a specific virtual folder
- The background worker should only process a single folder or file at a time to keep file operations relatively lightweight.
- In the "Folder Monitoring" menu, the user should have the option to set default metadata values for newly added files. By default these metadata values would be set to the ones the user selected during the initial process of adding a folder and scanning for media files.
- The user can also change the default interval minutes between scans 
- After changing folder metadata or scan interval values, the user would click the "Save Changes" button to confirm.
- The user can click on the "Scan Now" button for any folder to begin a one-time background scan of the folder for new items. If the user clicks the "Scan Now" button for a folder while an existing scan is being run. While a single-folder scan is being run, the "Scan Now" buttons for other folders should be disabled.
- The user can click the "Remove Folder" button to remove it. When the user clicks the "Remove Folder" button, they should see a warning message with the text "This action will remove the folder from background scanning. Would you also like to remove any media from this folder?" with a "Stop Scanning", "Remove Media" and "Cancel" buttons.
- "Stop Scanning" - Removes the folder from background scanning, but preserves any media already added
- "Remove Media" - Removes the folder from background scanning and also deletes any media contained in it from the database
- "Cancel" - Closes the warning message with no changes made.

## **Data Storage:**

- Video Metadata: Preference is to use SQLite & SQLAlchemy (with SQLite FTS5 enabled for searching) to manage database entries for video items. Ideally the database structure should be similar to the outline below, and use association tables to map linking between the different base tables:
- Video Table:
	* id (UUID, Primary Key)
	* filepath (The full, absolute path to the video file)
	* filename
	* title (User-editable)
	* date_added (timestamp)
	* date_modified (timestamp)
	* file_size
	* last_modified_date
	* thumbnail_path (The path to the thumbnail for the item - if blank a default gray placeholder would be used)
- Actor Table:
	* id (UUID, Primary Key)
	* name (Unique)
- Tag Table:
	* id (UUID, Primary Key)
	* name (Unique)
- Studio Table:
	* id (UUID, Primary Key)
	* name (Unique)
- Category Table:
	* id (UUID, Primary Key)
	* name (Unique)
- Virtual Folder Table:
	* id (Primary Key)
	* name
	* parent_folder_id (foreign key to the parent folder's id, blank for root folders)
- Watched Folder Table:
	* id (UUID, Primary Key)
	* folder_path (TEXT)
	* last_scan_time (DATETIME)
- Job Queue Table:
	* id (UUID, Primary Key)
	* filepath (TEXT)
	* task_type (TEXT: 'ADD', 'RESYNC','BACKGROUND')
	* status (TEXT: 'PENDING', 'PROCESSING', 'DONE', 'FAILED')
	* attempts (INTEGER)
	* last_error (TEXT)
- Thumbnails: Thumbnails should be cached on disk to the application folder as the database will likely have 10000+ items in different locations on a network share.
- Database Operations: These should be handled by a single dedicated worker thread with database requests being added to a queue to prevent database locking issues.
- Thumbnails and the database should be stored in dedicated subfolders to keep the main application folder tidy

## **System Specifications:**

- OS: Windows 11 Pro
- CPU: Intel i9-13900K
- RAM: 64GB (~42GB available under normal circumstances)
- GPU: NVIDIA RTX 4080 with 16GB of VRAM (~13GB available under normal circumstances)
- Storage: ~2TB available.
- Python: 3.11.1
- Primary Monitor Resolution: 2560x1440

## **Additional Requirements/Preferences:**

1. **Modularity:** The project should be structured with smaller Python files, each implementing a single class. Large files (such as the main interface controls) should be abstracted into smaller files to avoid monolithic files that become difficult to maintain.
2. **Simplicity:** Coding approaches should favor simpler approaches that accomplish the goal over more complex approaches that may offer little benefit for the amount of complexity they add.
3. **Development Approach:** A "walking skeleton" approach is preferred, following the order of the user workflow for easy testing.
4. **UI Framework:** PyQt6 is the required library for the user interface.
5. **Code Quality:** Code must be well-commented. Type hints should be used for clarity and maintainability.
6. **Testing:** After each component is implemented, it should be tested to ensure it functions correctly before moving on.
7. **Error Handling & Logging:**
	- Use the Python `logging` module to capture errors and informational messages to a file in a `logs` subfolder. Use `logging.handlers.RotatingFileHandler` with a max size of 1MB.
	- User-facing errors (e.g., "Video file not found") should be displayed in a non-blocking `QMessageBox`. They should also be logged to the "Activity" window allowing the user to review later.
8. **Responsiveness:** 
	- All long-running tasks **must** be executed in background worker threads (`QThread`) to keep the UI responsive. Use Qt's signal and slot mechanism for thread-safe communication.
	- When a worker (either when adding media or resyncing the database) runs, it should do the following:
		* If the file path is associated with a folder on a network share (UNC path structure) it should initially perform a check to see if the path is accessible with a timeout to prevent the process from hanging indefinitely. If the operation times out, the user should be notified and the folder skipped. For an operation like "Resync Database" a subsequent failure should result in the operation being aborted.
		* Create a job queue - In the case of a file or folder being added this would be handled via a "discovery" phase where files with a supported extension (.mp4, .m4v) are identified and added to the job queue table with an `ADD` task type. For the "Resync Database" action, all files in the database would be added with a `RESYNC` task type.
		* Process job queue - Once the queue is populated, a "processing" phase starts that sequentially processes the items in the queue, processing any needed tasks for a given file (metadata extraction, checksum generation, thumbnail creation) before moving to the next item. In the event of a failure, the `attempts` field in the database will be incremented by one and the job moved to the bottom of the queue to be retried - after three retries the queue item should be considered failed (with the process aborted and an entry added to the "Activity" window.)
9 **Configuration Management:**
	- A JSON file should be saved in the root folder of the application to store items like background scan interval, database location, thumbnail location, and log file settings

## **Future Considerations (Currently Out of Scope):**

- **Smart Folders:** Dynamic virtual folders based on user-defined tags
- **“Recently Watched” / “Most Played” Playlists** - Dynamically-created playlists that would track which videos were most often launched or most recently launched in an external player.
- **Application State Saving:** Persist the application state from the last session when launching the application
- **Thumbnail Changing:** Add a preview of the new thumbnail based on the timestamp the user selected, allowing them to decide whether to keep the change or not.
- **Live Searches:** Remove the "Search Now" button and show results to the user as they are found while typing
- **Onboarding:** A brief welcome message with suggested initial steps if the application is launched with no items in the database
- **Keyboard Shortcuts:** Keyboard shortcuts for commonly used operations, like adding a folder, selecting all items in the main window, creating virtual folders or editing their names
- **Undo Functionality:** Allow the user to undo the last change made (such as deleting/renaming virtual folders or removing items)
- **Worker Optimization:** Potentially use `QThreadPool` to allow for multithreading some worker operations - need will be dependent on performance

## **Input/Output Specifications:**

- **Input Videos:** Standard video containers like (.mp4, .m4v) Input videos will likely have a maximum resolution of 1920x1080
- **Database Size:** The database should be able to handle 10000+ video sources
- **Video Sources:** Most videos will be stored on a network share, so the application will need to ensure it supports UNC path formatting and increased latency when accessing files/file data.