Skip to content

[GSoC] videodb:// and musicdb:// URL extensions #1150

Merged
merged 18 commits into from Aug 5, 2012

2 participants

@Montellese
Team Kodi member

This is more of an RFC for now because I have only discussed the idea with @jmarshallnz in the context of my GSoC work. There are two "problems" that this work tries (and succeeds) to solve:

  1. When e.g. making a smartplaylist with the rule "Director contains James Cameron" and the user has a "Terminator Collection" set (as provided by TMDb) containing all four Terminator movies, the resulting list will show the "Terminator Collection" set in the list (and not the individual movies). When entering the set it will show all 4 movies even though only the first two Terminator movies were directed by James Cameron while the last two were not. The same result can be achieved by going to Videos -> Library -> Movies -> Directors -> James Cameron. The problem is that when retrieving the movies in the set we don't know about the previously applied filter(s) and simply ignore them and retrieve all movies belonging to the set.
  2. In my GSoC work for advanced filtering I use a smartplaylist which contains all the filters specified by the user. This works great for movies, tvshows and musicvideos but doesn't really work for episodes because in the GUI they are "pre-filtered" by tvshow and season. But the advanced filter has no clue about this pre-filtering because it's only really visible in the videodb:// URL of those items (which is used by CVideoDatabaseDirectory et. al.) and nowhere else.

To solve these two problems (which also apply to the music database, but I started with the video database as a proof-of-concept) I have added two classes CDbUrl and CVideoDbUrl (derived from CDbUrl) which are meant to handle and extend a videodb:// URL with additional information about the current context. The current URL schema is not changed but in addition GET options are added so when e.g. viewing all movies directed by James Cameron through Videos -> Library -> Movies -> Directors -> James Cameron the resulting URL will look like this: videodb://1/5/1234/?directorid=1234. When the user then enters the "Terminator Collection" set, that CFileItem will have the URL videodb://1/7/5678/?directorid=1234 and therefore knows that it also has to filter by the director with ID 1234 (which is James Cameron in this example). Adding those options is done in CVideoDatabase::GetFooNav() etc and the handling of those options is done in CVideoDatabase::GetFooByWhere() etc by first parsing the videodb:// URL using CVideoDbUrl::FromString and then calling CVideoDatabase::GetFilter() which will put together all the JOIN/WHERE SQL clauses necessary to do the proper filtering.
To also cover filtering by a smartplaylist, the smartplaylist is converted into a CVariant object and then serialized as a JSON object and that JSON object (or rather its string representation) is then added as an option to the videodb:// URL. I went with a JSON representation because it is less verbose than XML and a lot easier to read (although this might only come in handy during debugging).

The disadvantages of this approach are that the URLs can get rather long (but we never output them to the user) and that it is more crucial to actually provide to correct base path when calling CVideoDatabase::GetFooNav(). The second disadvantage might however actually be an advantage because it will make it easier to hunt down incorrectly provided base paths (e.g. videodb://1/1/ instead of videodb://1/2/ for the retrieval of all movie titles).

@jmarshallnz
Team Kodi member

I guess the only thing that needs to be thought through is whether we can get rid of the path + filter combination. ATM GetNav() calls GetByWhere using the path only, whilst smartplaylists call it using the filter only (basically).

Does it make sense to move towards using CVideoDbUrl() to pass stuff into the db from smartplaylists (and thus everything else?) The bonus being that the SQL stuff is then isolated somewhat.

@Montellese
Team Kodi member

If you look at the changes made to CSmartPlaylistDirectory in this PR you'll notice that the Filter object being passed to CVideoDatabase::GetSortedVideos is an empty object. The whole smartplaylist filter is passed in using the path and then CVideoDatabase deserializes the smartplaylist filter from the path/URL and calls CSmartPlaylist::GetWhereClause() to retrieve the actual SQL WHERE clause for that specific filter.

What I don't like about this approach is that CVideoDatabase needs to call/use CSmartPlaylist. Ideally all the SQL stuff would be located in CFooDatabase but then again CSmartPlaylist::GetWhereClause is rather complex and deserves its own method.

@Montellese
Team Kodi member

OK I have made some fixes based on the comments and I've added a new utility class CUrlOptions from which CDbUrl now derives to do the URL options handling. It is also used in VIDEODATABASEDIRECTORY::CDirectoryNode and could probably be used in other places as well but that's outside of the scope of this PR.

@Montellese Montellese was assigned Jul 19, 2012
@Montellese
Team Kodi member

I have extended this PR by adding the same functionality for musicdb:// URLs that were already present for videodb:// URLs. For that I also had to include the commits from #1151 into this PR as the musicdb:// changes need those. Generally it's exactly the same for musicdb:// as for videodb://.

Montellese added some commits Jun 20, 2012
@Montellese Montellese merged commit 5abd62b into xbmc:master Aug 5, 2012
@Montellese Montellese deleted the Montellese:gsoc_videodb_ext_urls branch Apr 4, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.