jrudio / go-plex-client

A Plex.tv and Plex Media Server Go client
130 stars 62 forks source link

json: cannot unmarshal number into Go struct field Metadata.MediaContainer.Metadata.ratingCount of type string #41

Open anatosun opened 3 years ago

anatosun commented 3 years ago

I encountered this issue when using the function GetPlaylist(int). What seems to fix it is to change the field RatingCount of type Metadata from string to int. It appears that #35 does not bring a fix for that though.

jrudio commented 3 years ago

The whole Metadata struct is is getting this error when I run GetPlaylist(int)

Changing RatingCount to int now gives me:

"json: cannot unmarshal number into Go struct field Metadata.MediaContainer.Metadata.librarySectionID of type string"

I change librarySectionID to int

now I get "json: cannot unmarshal number into Go struct field Media.MediaContainer.Metadata.Media.id of type string"

I change that to int and now I get:

"json: cannot unmarshal number into Go struct field Part.MediaContainer.Metadata.Media.Part.id of type string"

I change that now I get "json: cannot unmarshal number into Go struct field Media.MediaContainer.Metadata.Media.optimizedForStreaming of type bool"

I change that to int and it works, but breaks GetSessions() 😅

In #35 I changed the following to satisfy the returned types in GetSessions():

librarySectionID -> int .Metadata.Media.id -> int .Metadata.Media.Part.id -> int Media.optimizedForStreaming -> int

Are you able to test this on your server? Maybe it's just me?

Edit: RatingCount still works under GetSessions(), so yes, you are right, that needs to be changed.

jrudio commented 3 years ago

For clarity, the following two functions (and more) share the same Metadata struct when decoding the response body as json from PMS api:

GetSessions() needs:

Part.ID -> string Metadata.LibrarySectionID -> string Media.OptimizedForStreaming -> bool Media.ID -> string

GetPlaylist(int) needs:

Part.ID -> int Metadata.LibrarySectionID -> int Media.OptimizedForStreaming -> int Media.ID -> int

anatosun commented 3 years ago

We should try this solution first: https://stackoverflow.com/questions/49097385/how-to-decode-json-with-type-convert-from-string-to-integer-in-golang-for-non-lo.

Or maybe we should come up with a custom Unmarshaler by implementing the interface json.Unmarshaler and doing some type conversion when necessary.

I haven't had the chance to test it on my side. My PMS server version is 1.24.5.5173 by the way.

jrudio commented 2 years ago

After changing the appropriate properties to use json.Number, sessions and playlist work fine

The only one that I can't handle is OptimizedForStreaming, which is either:

Custom Unmarshaler may be the best route for this

anatosun commented 2 years ago

I found this solution that could resolve our issue here. I may test it in the future. What should I do to reproduce the issue?

jrudio commented 2 years ago

Good find! This commit did something similar take care of it, but there are possibly some edge cases that are not well thought out with my commit.

To reproduce the issue I was using the commands: ./plex-client playlist <playlist-id> which uses GetPlaylist() and ./plex-client episode <episode-id> which uses GetEpisode() from the cli.

Edit: ./plex-client metadata <id> and ./plex-client playlist <id> should return 0 or 1

./plex-client sessions should return boolean

// plex can return int (GetMetadata(), GetPlaylist()) or boolean (GetSessions())

Not sure if having different media would affect the output of boolean or int on OptimizedForStreaming.

Looking forward to your thoughts or suggestions.

anatosun commented 2 years ago

I've just tested the fix. While the fix itself works for the field OptimizedForStreaming, other issues are unfortunately raised with strings being number, int being float and vice versa. Here is a non exhaustive list of some errors I managed to fix by replacing the type in question with json.Number:

I will work on a separate branch to fix those different issues. I propose to replace very float/int (and some string) fields with json.Number to avoid further issues.

anatosun commented 2 years ago

I came up with a working solution. I still have to make some test to make a PR but it fixes the aforementioned issues. Take a look at my branch type-fix on my profile.

jrudio commented 2 years ago

Really great work! Looked it over and I love the naming conventions the dynamic types. I think your PR will nullify #35, so I am looking forward to that.

I am curious about some of the Size fields that have xml tags but json.Number types as I don't know how it works. Do those still unmarshal as XML, but with json.Number?

Some Size fields still have type string, is that intended?

Good stuff!

anatosun commented 2 years ago

I am curious about some of the Size fields that have xml tags but json.Number types as I don't know how it works. Do those still unmarshal as XML, but with json.Number?

No, it is a mistake on my side. json.Number will only work when unmarshalling json as far as I know.

Some Size fields still have type string, is that intended?

I'm still working on it and making some tests to see what's the best solution. Of course, it's way more sensible to use an integer type for Size.