Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/movie support #8

Merged
merged 10 commits into from
Feb 19, 2023
Merged

Feature/movie support #8

merged 10 commits into from
Feb 19, 2023

Conversation

danrahn
Copy link
Owner

@danrahn danrahn commented Feb 19, 2023

Movie Support

With the introduction of credits markers, there's a much stronger justification for adding movie support to this editor. This PR does just that. In the UI, movie libraries are now selectable in the dropdown and search results act the ~same as an episode row - the name of the movie and number of existing markers, and clicking on the row shows/hides the marker table, and adding/editing a marker will show thumbnails (if enabled). Movies are also integrated into the purge detection system to allow recovery of markers that Plex wipes out after analysis. Moves are not integrated into bulk actions, and likely won't unless there's a more compelling reason to.

Key technical changes:

  • Generalize the idea of a "base" media item - an item that can have markers attached directly to it, i.e. an episode or movie. Adjust things throughout by changing e.g. episode_id to parent_id, episode to baseItem, etc.
  • Similar to above, generalize the idea of a "top-level" media item - an item that is the root type for a section, i.e. a show or movie.
  • Also similar to above, add intermediate base classes for many structures that were previously specific to episodes/shows (e.g. PurgeTable becomes the base class for MoviePurgeTable and TVPurgeTable, with most of the logic remaining in PurgeTable).
    • Note that the lack of multiple inheritance makes the above points somewhat awkward. It would be great to have generic "base item" interfaces that movies and episodes implement and "top-level" interfaces that movies and shows implement, but a class can only inherit from one base class, which occasionally results in the movie version of an item inheriting from a common show or episode class, but duplicating code for the type that it doesn't inherit from.
  • Deal with different "levels" of section maps. Everything assumed that we have a Section > Show > Season > Episode > Marker hierarchy, but with movies it's just Section > Movie > Markers. Handle this somewhat ungracefully by switching on the library type whenever we're processing a section or "top-level" item (a movie or show).
  • Add a new ResultRow class for movies, which is extremely similar to EpisodeResultRow.
  • Allow marker tables to be lazy-initialized. With episodes, it's usually reasonably fast to iterate over all items in a season and get existing markers (and determine if the underlying file exists if using ffmpeg for thumbnails), but we could potentially have thousands of movies in our search results, and that could be incredibly slow if we need to check the underlying files for each one.
  • Unrelated to movies/credits: Vastly improve startup performance of building our marker cache. Instead of creating a query that combines markers and media items, grab both separately and combine manually, resulting in a ~10x improvement on my own library.

A bunch of changes with the end result being that movie libraries are
selectable and properly load their markers. Many other areas (e.g.
actually adding/editing/deleting markers) do not work, or at least are
completely untested.

For the most part, these changes follow some basic flows:
* For anything marker-related, share/borrow code from episode handling
* For search/initial library population, share/borrow code from shows

There are definitely places that could be generalized further/renamed,
but for now the goal is to just get something that works.

Some more specific changes/patterns:
* Places that used to take an episode id now take a "parent id". No real
  changes, just different naming.
* Add check_thumbs endpoint to check whether a given file has thumbnails
  available. With episodes, checks can be broken down into individual
  seasons, but that can't be done with movies, so make it an individual
  task so we don't try to find potentially thousands of files on disk.
* Add a "lazy init" flow for the marker table so we don't have to load
  markers for every single movie in the library at once.
* Add a MovieResultRow that borrows heavily from EpisodeResultRow
* Significant reworking of PlexQueryManager to return relevant data
  based on the type of media we're searching for (movie vs episode).
* New shared type - MovieData, borrowing (and shared with) ShowData, and
  borrowing from EpisodeData
Verify that (at least in the happy path) we can successfully add, edit,
and delete intro and credits markers for movies just like for episodes.

Key changes:
* Update backup database schema (again) to generalize episode_id and
  episode_guid to parent_id/guid. For movies, set show/season id to -1.
* Add movie support the MarkerCacheManager.
  * With this, remove marker_count from getMovies query.
* Adjust PlexQueries to be okay with operations on movies in addition to
  episodes.

Only two major pieces left:
* Ensure purged markers are handled correctly.
* Fix existing tests. Ideally write some more, but we'll see.
Key changes that were necessary:
* Add new classes off of PurgedGroup and PurgedSection for movies. Make
  use of instanceof to determine how to handle things in PurgeOverlay
* Make PurgeRow and PurgeTable base classes, and move any movie/TV-
  specific logic into derived classes (MoviePurgeTable/MoviePurgeRow).
* Add movie vs TV handling in MarkerBackupManager.

Still need to hook into single-movie purge restore, but that should be
straightforward (in theory).
Instead of joining metadata_items and taggings within the same query,
it is much faster (>10x) to individually grab all relevant markers separate
from all media items, and then do the combining ourselves.

Also fix a bug that would show a random episode title as the purge
show section title.
Replace 'Search for a Show' with 'Search for a Movie' if we've selected
a movie library.
Add an entrypoint for showing the purged markers of a single movie
Grab purged data as soon as a library is selected if we know that things
cached server-side (backup actions and extended marker info enabled).

The main benefit is that we can immediately show the warning markers
when searching instead of waiting for 'Find Purged Markers' to be
clicked, or digging into a single season.
Turns out tests are helpful. In addition to fixing up the tests
themselves to adjust to tweaked APIs, fix several issues they found:
* Replace some 'episode_id's that never were replaced with parent_id
* Fix parameters in getSeasonStats
* More safeguards against invalid API requests (e.g. retrieving data for
  music due to its similar hierarchy).
* Ensure bulk actions cannot be done on movies (yet?)
* Fix invalid ServerErrors in getLibrary
Also fix one bug the new tests caught that prevented us from thinking
final markers were actually final.
When 'Find Purged Markers' is clicked, the first argument sent to
findPurgedMarkers is the MouseEvent, which makes us think it's a
dry-run. Explicitly pass in `false` as the first parameter.
@danrahn danrahn self-assigned this Feb 19, 2023
@danrahn danrahn merged commit 61c5831 into main Feb 19, 2023
@danrahn danrahn deleted the feature/movie_support branch September 25, 2023 04:56
danrahn added a commit that referenced this pull request Mar 10, 2024
To avoid circular dependencies between Show and Season result rows, split
ShowResultRow into three classes:
* ShowResultRowBase - Common show result row functionality
* ShowResultRow - A "real" row that will load seasons when clicked.
* ShowTitleResultRow - A placeholder row displayed when a show/season is already
  active.

Splitting the class up this way allows SeasonResultRow to only need to know
about ShowTitleResultRow, not the "real" ShowResultRow.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant