wilmardo / migrate-plex-to-jellyfin

Migrate watched status from Plex to Jellyfin
96 stars 21 forks source link

No matches #17

Open JulioQc opened 3 years ago

JulioQc commented 3 years ago

Tweaked the hardcoded library names but all I get is "No provider match" and "No matches" for all the items. Any ideas what's wrong here?

wilmardo commented 3 years ago

When there is no provider match then it can't find the item in Jellyfin. I tries to extract the TVDB or IMDB id from the episode or movie. Are your files linked to one of those? https://github.com/wilmardo/migrate-plex-to-jellyfin/blob/dev/migrate.py#L134

JulioQc commented 3 years ago

My Plex uses the "Plex Movies" or "Plex TV" agents instead of TVDB/IMDB; could be why it aint matching?

wilmardo commented 3 years ago

Yes that 100% is the case. It currently uses the TVDB or IMDB id to match it from the Plex side to the JellyFin side since they both have this ID available. This avoids matching on titles or other possible duplicate attributes,

For now I will mark this issue as an enhancement, if I start refactoring this script I will check if matching with the Plex Movies and Plex TV IDs is in some way possible :) I currently have no Plex server anymore so I can't check and fix this quickly, sorry about that.

JulioQc commented 3 years ago

No worries I changed the agent to Movie DB and TVDB in my Plex libraries. No harm in doing so :) I did a full metadata refresh and tried the script again. However I get this error now:

Traceback (most recent call last): File "migrate.py", line 148, in migrate() File "/home/media/migrate-plex-to-jellyfin-dev/venv/lib/python3.7/site-packages/click/core.py", line 1137, in call return self.main(args, kwargs) File "/home/media/migrate-plex-to-jellyfin-dev/venv/lib/python3.7/site-packages/click/core.py", line 1062, in main rv = self.invoke(ctx) File "/home/media/migrate-plex-to-jellyfin-dev/venv/lib/python3.7/site-packages/click/core.py", line 1404, in invoke return ctx.invoke(self.callback, ctx.params) File "/home/media/migrate-plex-to-jellyfin-dev/venv/lib/python3.7/site-packages/click/core.py", line 763, in invoke return __callback(args, **kwargs) File "migrate.py", line 44, in migrate plex = PlexServer(plex_url, plex_token, session=session) File "/home/media/migrate-plex-to-jellyfin-dev/venv/lib/python3.7/site-packages/plexapi/server.py", line 113, in init data = self.query(self.key, timeout=timeout) File "/home/media/migrate-plex-to-jellyfin-dev/venv/lib/python3.7/site-packages/plexapi/server.py", line 535, in query return ElementTree.fromstring(data) if data.strip() else None File "/usr/lib/python3.7/xml/etree/ElementTree.py", line 1315, in XML parser.feed(text) xml.etree.ElementTree.ParseError: syntax error: line 1, column 0

That looks more like a problem with the plexapi library than your code.

JulioQc commented 3 years ago

Disregard that previous comment; that was from my partition being full! So now the provider are matching the regex once extracted from Plex (except a handful that dont have a provider in their GUID for some reason -- plex://movie/5d776838151a60001f24e81b -- odd but whatever)

But when trying to match Plex watched and JF library, everything returns to "No matches". After some digging, I found out the stored providers ID from plex when using "the movie database agent" is as follow:

{'com.plexapp.agents.themoviedb://628534?lang=en'} Provider parsed: {'Moviedb'}

and from jellyfin library when using TheMovieDb:

        "ProviderIds": {
            "Tmdb": "640",
            "Imdb": "tt0264464"
        },

The provider name mismatch here will never return anything!

data['ProviderIds'].get(item['provider'])

Therefore the "if"clause is always false and the the search always fails.

So change this:

'provider': match.group(1).replace('the', '').capitalize(),

by this:

'provider': match.group(1).replace('themoviedb', 'Tmdb'),

and it works again, at least for movies. Ill give it a try for Shows later.

wilmardo commented 3 years ago

Good progress! This seems indeed different from when I did my migration last year, there was no MovieDB so that is a good one too add.

Thanks for debugging this and nice to know that the script at least moved somethings over now :)

JulioQc commented 3 years ago

No problem :)

For shows Plex uses TVDB or TheMovieDatabase but when I check what comes out from JellyFin it's all over the place between TVDB, TMDB or IMDB with no consistency. Plus I dunno why its like this when JF doesn't even offer TVDB or IMDB as agents... this one is gonna be tricky.

        "ProviderIds": {
            "Tvdb": "295311",
            "Imdb": "tt0563000"

        "ProviderIds": {},
        "IsFolder": false,
        "Type": "Movie",

        "ProviderIds": {
            "Tvdb": "5077977",
            "Imdb": "tt4109672",

        "ProviderIds": {
            "Imdb": "tt11826778"
        },

        "ProviderIds": {
            "Tmdb": "10881",
            "Imdb": "tt0267287"

        "ProviderIds": {
            "Tvdb": "179541",
            "Imdb": "tt0705981",

        "ProviderIds": {},
        "IsFolder": false,
        "Type": "Movie",

        "ProviderIds": {
            "Tvdb": "6512671",
            "Imdb": "tt6819686"

        "ProviderIds": {
            "Imdb": "tt7801022"
        },

        "ProviderIds": {
            "Tvdb": "6933996",
            "Imdb": "tt7640050"

        "ProviderIds": {
            "Tvdb": "55588",
            "Imdb": "tt0701182",

        "ProviderIds": {},
        "IsFolder": false,
        "Type": "Movie",

        "ProviderIds": {
            "Tmdb": "10497",
            "Imdb": "tt0104779"

        "ProviderIds": {},
        "IsFolder": false,
        "Type": "Episode",
JulioQc commented 3 years ago

Ok so for similar reasons on the "if" clause is always going to be false

data['ProviderIds'].get(item['provider']) == item['item_id']

because we can't match plex item IDs:

{'com.plexapp.agents.thetvdb://7241874/2/2?lang=en'} Provider parsed: {'Tvdb'} Item id: {'7241874/2/2'}

To the JellyFin data structure since ProviderID value doesn't include the season nor the episode:

{ "Name": "Dark Matter", "ServerId": "4e944ff43a9445929ba2bf6060bc2c90", "Id": "bfeb5bdfc55bc8c921e07539a9692072", "HasSubtitles": true, "Container": "mkv,webm", "PremiereDate": "2019-06-21T00:00:00.0000000Z", "ChannelId": null, "CommunityRating": 9, "RunTimeTicks": 32986130432, "ProductionYear": 2019, "IndexNumber": 2, "ParentIndexNumber": 2, "ProviderIds": { "Tvdb": "7241874", "Imdb": "tt10454716" }, "IsFolder": false, "Type": "Episode", "ParentBackdropItemId": "b84bb880c88dcd9730de05b366128f4e", "ParentBackdropImageTags": [ "6f347d6c1235a5a65704321f377b31b3" ], "UserData": { "PlaybackPositionTicks": 0, "PlayCount": 0, "IsFavorite": false, "Played": false, "Key": "334824002002" }, "SeriesName": "Dark", "SeriesId": "b84bb880c88dcd9730de05b366128f4e", "SeasonId": "bbfbaaeda3de2377629473b9e61b19a6", "SeriesPrimaryImageTag": "8757706117cfb55c29ea70283b4e522a", "SeasonName": "Season 2", "VideoType": "VideoFile", "ImageTags": { "Primary": "d39c953f1f72859929f5222e3d91433e" }, "BackdropImageTags": [], "ImageBlurHashes": { "Primary": { "d39c953f1f72859929f5222e3d91433e": "W01yh0kC8_M|p0x]%zx[H@Mzodbb_Lt6ICMyWAj=?ux]DjMyofkC", "8757706117cfb55c29ea70283b4e522a": "dD7eYRtRIUWC?wogM{WB%hkCadf5%gkCWBayoxfiRkWB" }, "Backdrop": { "6f347d6c1235a5a65704321f377b31b3": "WK8X,-ozn$j[-;xu?^oft7fk%gxu%gj[t7j[xut7tRbHxtofaej[" } }, "LocationType": "FileSystem", "MediaType": "Video" }

I think we could match the "key" field under "UserData" but that would require changing your regex and formatting the leading zeros to construct a match.

Change the regex:

match = re.match('com.plexapp.agents.(.):\/\/(\d)(?:\/(\d)\/(\d)\?|\?)', data)

Format the ID to the Key format:

result = { 'provider': match.group(1).replace('thetvdb', 'Tvdb'), 'item_id': match.group(2) + match.group(3).zfill(3) + match.group(4).zfill(3) }

Search on that instead:

if data['UserData'].get("Key") == item['item_id']:

Obviously doesn't work for movies anymore but itll work for series now! (Worked for 80% of my entries, 20% dont have a Tvdb entry in JF for some reason -- only Tmdb or Imdb)

wilmardo commented 3 years ago

Thanks for the troubleshooting! I will look into this when I am reworking the script, hopefully with some tests or at least an easy test setup for me since I have no Plex anymore.

Keep you posted (could take a while though ;))

TheLion commented 1 year ago

Hi. It has been a while, but is there any update on this?

antifuchs commented 1 year ago

I migrated from Plex to JF and reworked this tool's logic entirely, to support my use case. The PR for that rework is #24, if anyone else wants to try it.