croneter / PlexKodiConnect

Plex integration in Kodi done right
GNU General Public License v2.0
1.17k stars 77 forks source link

Plex ratings from iMDB, TMDB etc. to go to the respective ones in Kodi #1911

Closed thorindwarf closed 1 year ago

thorindwarf commented 1 year ago

Hi :)

Currently all kinds of ratings from iMDB, TMDB etc. go to the main rating field in Kodi (field rating.rating_type = 'default'. Is it possible to make them go to the dedicated metadata for them, like the Kodi add-ons populate them? I guess this kind of information is presented in Plex API... This way various skins will display them in their dedicated positions on different views.

Thanks!

JCalvi commented 1 year ago

Ok, I have made some code for this. The database populates correctly AFAICT but I can't see anything in Estuary. I suspect this skin does not have special rating tags for different sources?

Please try the changes and let us know if it does what you need?

base.py, add at line 356

    def ratingtype(self):
        """
        Returns the kodi rating type after parsing the rating image link from plex
        """
        rtype = self.xml.get('audienceRatingImage',"")
        if "rotten" in rtype:
            rtype = "tomatometerallaudience"
        elif "imdb" in rtype:
            rtype = "imdb" 
        elif "tmdb" in rtype:
            rtype = "themoviedb"           
        elif "tvdb" in rtype:
            rtype = "tvdb"
        elif "trakt" in rtype:
            rtype = "trakt"  
        elif "metacritic" in rtype:
            rtype = "metacritic"            
        else:
            rtype = "default"
        return rtype

tvshows.py and movies.py

replace all instances of:

                                                   v.KODI_TYPE_SHOW,
                                                   "default",
                                                   api.rating(),

with:

                                                   v.KODI_TYPE_SHOW,
                                                   api.ratingtype(),
                                                   api.rating(),

widgets.py, add line 171 'ratingtype': api.ratingtype(), # [str] image location

thorindwarf commented 1 year ago

Thanks, JCalvi for looking into this!

I did a quick test after applying the code to the proper places and the result is below. I did a full repair of the database from inside plexkodiconnect settings and synced only movies and tv shows. TV shows are all "default" in Kodi's database, in Plex interface I can see they are TMDB. Some of the episodes are also defaulted despite that they are TMDB on Plex interface. Actually all TMBDs are defaulted. Anything else I can assist for further investigation?

media_type rating_type count(1) episode default 707 episode tvdb 540 movie imdb 147 tvshow default 21

JCalvi commented 1 year ago

Try a reset database instead of repair. Sometimes fields just won't clear otherwise.

JCalvi commented 1 year ago

plugin.video.plexkodiconnect.zip Here are the modified files in case you missed something, and for reference. They also have the mods I made for HDR type.

JCalvi commented 1 year ago

I made a fork and pull request you can also grab the files from. Its against 3.7 beta but these files are the same for 3.6.14 as for 3.7 (i.e. there were no changes in the main code from 3.6.14 to 3.7).

thorindwarf commented 1 year ago

Try a reset database instead of repair. Sometimes fields just won't clear otherwise.

Indeed, it was reset, not a repair. Sorry for the wrong term. I checked again and I haven't missed anything from the files. Applying it on 3.7.0.

I searched around the net and now I'm starting to wonder if Kodi even supports multiple rating types... as I can't find information on what they should be.

JCalvi commented 1 year ago

It does support them as far as importing/exporting from nfo files etc. I can’t see anything in estuary, but can see the correct rating types imported into the Kodi database from my Plex library.

References to Kodi ratings types here: https://forum.kodi.tv/showthread.php?tid=355057 https://kodi.wiki/view/NFO_files/Movies https://kodi.wiki/view/NFO_files/TV_shows

Make sure your Plex library has audienceRatingImage populated (may need to check using SQLiteStudio for eg.) as this is the only way I can tell what the rating source from Plex was with the Plex python api.

One more thing, my changes won’t get multiple rating types per media item either, just one is grabbed per item. I don’t think Plex supports more than one rating per file (not that I can see via the python api for plexapi.video.Episode at least), whereas Kodi does allow multiple ratings per item.

thorindwarf commented 1 year ago

I'm not sure how to find this audienceRatingImage in Plex database? Do you know where is it or you are seeing this only on API level? Also it's not true that the correct ratings are populated in Kodi's database as I can see TV Shows are with "default" and some of the Episodes are "default" according to the numbers below. I can see those as a TMDB ratings on Plex web interface and all Plex apps: media_type rating_type count(1) episode default 707 episode tvdb 540 movie imdb 147 tvshow default 21

"One more thing, my changes won’t get multiple rating types per media item either, just one is grabbed per item. I don’t think Plex supports more than one rating per file (not that I can see via the python api for plexapi.video.Episode at least), whereas Kodi does allow multiple ratings per item." -- that's fine. I'm expecting one rating per media item.

croneter commented 1 year ago

Should be solved in PKC Beta version 3.7.2. Thanks a ton @JCalvi

croneter commented 1 year ago

Respective commit as the PR got lost: https://github.com/croneter/PlexKodiConnect/commit/664a68c30fe4bca9e191acad2b2aa8850859b0ba

thorindwarf commented 1 year ago

Guys, I still don't see properly populated ratings in Kodi's database. Tested 3.7.2. My TV Shows all get into it with "default" and should be tmdb. Also more than half of the episodes which I guess are tmdb too as I checked a few of them.

select media_type, rating_type, count(1)
from rating
group by rating_type, media_type
order by media_type, rating_type

media_type rating_type count(1) episode default 664 episode tvdb 540 movie imdb 146 tvshow default 20

croneter commented 1 year ago

@thorindwarf did you manually reset the Kodi database in the PKC settings?

thorindwarf commented 1 year ago

Yes. Complete reset before every test.

JCalvi commented 1 year ago

@thorindwarf, yes I see some issues in my test setup as well.

Some items are getting flagged as default when I would expect them to be otherwise.

I'll look into it some more when I get some time.

JCalvi commented 1 year ago

I'm not sure how to find this audienceRatingImage in Plex database? Do you know where is it or you are seeing this only on API level?

Can see at API level, but also if you use SQLiteStudio then its in the extra_data field of metadata_items table in com.plexapp.plugins.library.db file.

Have a look in there and compare to kodi by opening myvideos121.db ratings table.

I have a match for imdb, and tvdb in my databases. I saw a mismatch with rottentomatoes so if I get time tonight I'll dig some more. I suspect default may be sneaking through in some circumstances but not sure yet.

Edit: no, mismatch was just needing to delete and reimport for tomato ratings. themoviedb however is not syncing due to typo in my code.

thorindwarf commented 1 year ago

It looks like some of the items in Plex library (episodes) have metadata_items.audience_rating column populated without existence of audienceRatingImage in extra_data. These I can understand why fail. image

But for all the TV Shows (e.g. Friends) I have audienceRatingImage=themoviedb and it goes as "default" in Kodi:

at%3AaudienceRatingImage=themoviedb%3A%2F%2Fimage%2Erating&ex%3AhasPremiumPrimaryExtra=1&ex%3AprimaryExtraKey=%2Flibrary%2Fmetadata%2F370955&pv%3AaddedAtRestored=1&pv%3AartBlurHash=LEJZl1T0J%2E%25g~Vo~t7OsIpkAW%3Bt6&pv%3AblurHashesChangedAt=29742716&pv%3AthumbBlurHash=TaF%3B%3D%2CW%3BD%2A0fo0%252E%2AbHM%7C%3D%7BWWxa image

image

I hope this helps somehow.

Thanks!

JCalvi commented 1 year ago

Yes it helps.

Typo in base.py.

Line 365 should be:

        elif "themoviedb" in rtype:
            rtype = "themoviedb"

Not elif "tmdb"

JCalvi commented 1 year ago

I have checked the others and am sure tomato, imdb, tvdb and now themoviedb are correct. I don't have any trakt or metacritic items in my plex library so if anyone has these please go ahead and confirm they are ok. Note: I suspect these are not options for Plex anyway as I cannot set my Plex to collect trakt or metacritic ratings. These will just serve as placeholders for the future if this ability gets added to plex

I'll update a pull request to suit. #1927

thorindwarf commented 1 year ago

Better now! :)

media_type rating_type count(1) episode default 121 episode themoviedb 543 episode tvdb 540 movie imdb 146 tvshow default 1 tvshow themoviedb 19

I noticed that those with missing ratings goes in Kodi database like "default" and rating 0.0. Is this correct in general or should they be missing at all?

JCalvi commented 1 year ago

Glad it's working now.

With regards to unrated items, that is what Croneter had as the behavior if no ratings are found in plex.

Do you have thoughts on a better option, eg: putting null in there instead for example?

thorindwarf commented 1 year ago

I'm not sure how Kodi handles zero ratings but I guess it's ok to be zeros because at least Kodi doesn't display any rating for them (Estuary skin). I would assume that it's even fine if they are missing completely in rating table and it's better IMO than having zeros ( I'm db Oracle guy:) ) but anyway I don't see a problem in current situation.

JCalvi commented 1 year ago

I see a new problem. When running a database repair the ratings duplicate in the ratings table.

thorindwarf commented 1 year ago

I tested 3.7.0 - the same with duplicates. Steps:

  1. rollback to 3.7.0
  2. Reset database
  3. Sync - no duplicates
  4. Repair - duplicates
  5. Repair - triplicates
  6. ...

Could this DML failing the replace part somehow?

    def update_ratings(self, *args):
        """
        Feed with media_id, media_type, rating_type, rating, votes, rating_id
        """
        self.cursor.execute('''
            INSERT OR REPLACE INTO
            rating(media_id, media_type, rating_type, rating, votes)
            VALUES (?, ?, ?, ?, ?)
        ''', (args))
        return self.cursor.lastrowid
JCalvi commented 1 year ago

Yes, I have just fixed it. Going to bed now, will post a fix tomorrow after tidying it up. Bug was always there, the update keeps adding items, the replace does not have a unique key to use so it just keeps inserting new rows. Also I'll recommend getting rid of the add function as the update is already insert or replace anyway.

The fix is to just add a removal at the start of the update, and replace calls to add with update.

Note: the “or replace” will never be used so can also be removed from this function.

def update_ratings(self, *args):
    """
    Feed with media_id, media_type, rating_type, rating, votes, rating_id
    """

    self.cursor.execute('DELETE FROM rating WHERE media_id = ? AND media_type = ? AND rating_type = ?',
                        (args[0], args[1], args[2]))

    self.cursor.execute('''
        INSERT OR REPLACE INTO
        rating(media_id, media_type, rating_type, rating, votes)
        VALUES (?, ?, ?, ?, ?)
    ''', (args))
    return self.cursor.lastrowid

@db.catch_operationalerrors

This function can be deleted and calls replaced to the one above (or left as is as I guess it saves calling a delete when not required, although still risks duplicating if called when it shouldn't be)...

def add_ratings(self, *args):
        """
        feed with:
            media_id, media_type, rating_type, rating, votes

        rating_type = 'default'
        """
        self.cursor.execute('''
            INSERT INTO rating(
                media_id,
                media_type,
                rating_type,
                rating,
                votes)
            VALUES (?, ?, ?, ?, ?)
        ''', (args))
        return self.cursor.lastrowid

    @db.catch_operationalerrors
JCalvi commented 1 year ago

I think this issue is now fixed in pull request #1927

JCalvi commented 1 year ago

@thorindwarf , can you test the changes in the pull requests? #1927 and #1928

thorindwarf commented 1 year ago

I confirm no duplications are found after reset and then repair of the database with changes from #1927. Thanks!

croneter commented 1 year ago

Implemented in PKC beta version 3.7.3 - thanks @JCalvi !